/* Copyright (c) Citrix Systems, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the * following disclaimer in the documentation and/or other * materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using XenAdmin.Controls; using XenAPI; using XenAdmin.Core; using XenAdmin.Network; namespace XenAdmin.Commands { /// /// A read-only collection of s. /// public class SelectedItemCollection : ReadOnlyCollection { /// /// Initializes a new instance of the class. /// The collection has no contents. /// public SelectedItemCollection() : base(new List()) { } /// /// Initializes a new instance of the class with one item /// /// The itemsthat will populate the collection. public SelectedItemCollection(SelectedItem item) : base(new List {item}) { } /// /// Initializes a new instance of the class. /// /// The items that will populate the collection. public SelectedItemCollection(IEnumerable items) : base(new List(items)) { } /// /// Returns a list of GroupingTags and IXenObjects that /// this collection represents. /// /// public List AsObjects() { return new List(this).ConvertAll(s => s.Value); } /// /// Gets a list of GroupingTags that this collection represents. /// public List AsGroupingTags() { List output = new List(); foreach (SelectedItem item in this) { output.Add(item.GroupingTag); } return output; } /// /// Gets a list of IXenObjects that this collection represents. /// public List AsXenObjects() { return AsXenObjects(); } /// /// Gets a list of IXenObjects that this collection represents. /// public List AsXenObjects() where T : IXenObject { List output = new List(); foreach (SelectedItem item in this) { if (item.XenObject is T) output.Add((T)item.XenObject); } return output; } /// /// Gets a list of IXenObjects that this collection represents. /// /// A Predicate for filtering the list. public List AsXenObjects(Predicate filter) where T : IXenObject { List output = new List(); foreach (SelectedItem item in this) { if (item.XenObject is T) { T obj = (T)item.XenObject; if (filter(obj)) output.Add(obj); } } return output; } /// /// Determines whether this collection contains only one item of the specified type. T /// can either be IXenObject or GroupingTag. /// /// A Predicate that must be satisfied. public bool ContainsOneItemOfType(Predicate predicate) where T : class { if (ContainsOneItemOfType()) { object item = (this[0].XenObject as T) ?? (this[0].GroupingTag as T); return item != null && predicate((T)item); } return false; } /// /// Determines whether this collection contains only one item of the specified type. T /// can either be IXenObject or GroupingTag. /// public bool ContainsOneItemOfType() where T : class { return Count == 1 && ItemIs(0); } /// /// Determines whether the item at the specified index is of the specified type. T /// can either be IXenObject or GroupingTag. /// private bool ItemIs(int index) where T : class { return Count >= index && (this[index].XenObject is T || this[index].GroupingTag is T); } /// /// Determines whether all items of the collection are of the specified type. T /// can either be IXenObject or GroupingTag. /// public bool AllItemsAre() where T : class { if (Count == 0) { return false; } for (int i = 0; i < Count; i++) { if (!ItemIs(i)) { return false; } } return true; } /// /// Determines whether all items of the collection are of the specified type. T /// can either be IXenObject or GroupingTag. /// /// A predicate that must be satisfied. public bool AllItemsAre(Predicate predicate) where T : class { if (Count == 0) { return false; } for (int i = 0; i < Count; i++) { object item = (this[i].XenObject as T) ?? (this[i].GroupingTag as T); if (!ItemIs(i) || !predicate((T)item)) { return false; } } return true; } /// /// Determines if at least one item in the collection satisfies the specified condition. T /// is a type the implements IXenObject. /// /// The condition to be satisfied. public bool AtLeastOneXenObjectCan(Predicate doThis) where T : IXenObject { Util.ThrowIfParameterNull(doThis, "doThis"); foreach (SelectedItem item in this) { if (doThis((T)item.XenObject)) { return true; } } return false; } /// /// Gets the first item whether it be either a IXenObject or a GroupingTag. Returns null if the collection is empty. /// public object First { get { return Count == 0 ? null : this[0].Value; } } /// /// Gets the first item and casts it to an IXenObject. Can return null. /// public IXenObject FirstAsXenObject { get { return First as IXenObject; } } /// /// Gets a value indicating whether the first item is a T. /// public bool FirstIs() where T : IXenObject { return First is T; } /// /// Gets a value indicating whether the first item is a live host. /// public bool FirstIsLiveHost { get { return FirstIs() && ((Host)this[0].XenObject).IsLive(); } } /// /// Gets a value indicating whether the first item is a real VM (not a template). /// public bool FirstIsRealVM { get { return FirstIs() && !((VM)this[0].XenObject).is_a_template; } } /// /// Gets a value indicating whether the first item is a template. /// public bool FirstIsTemplate { get { return FirstIs() && ((VM)this[0].XenObject).is_a_template && !((VM)this[0].XenObject).is_a_snapshot; } } /// /// Gets the connection of first item. If the collection is empty then null is returned. /// public IXenConnection GetConnectionOfFirstItem() { if (Count > 0) { return this[0].Connection; } return null; } /// /// Gets the common host ancestor for the selection. If the selected items have different host ancestors then null is returned. /// public Host HostAncestor { get { Host hostAncestor = null; for (int i = 0; i < Count; i++) { if (this[i].HostAncestor == null) { return null; } else if (i > 0 && this[i].HostAncestor != hostAncestor) { return null; } hostAncestor = this[i].HostAncestor; } return hostAncestor; } } /// /// Gets the common pool ancestor for the selection. If the selected items have different pool ancestors then null is returned. /// public Pool PoolAncestor { get { Pool poolAncestor = null; for (int i = 0; i < Count; i++) { if (this[i].PoolAncestor == null) { return null; } else if (i > 0 && this[i].PoolAncestor != poolAncestor) { return null; } poolAncestor = this[i].PoolAncestor; } return poolAncestor; } } /// /// Gets the common group ancestor for the selection. If the selected /// items have different group ancestors then null is returned. /// public GroupingTag GroupAncestor { get { GroupingTag groupAncestor = null; for (int i = 0; i < Count; i++) { if (this[i].GroupAncestor == null) return null; if (i > 0 && this[i].GroupAncestor != groupAncestor) return null; groupAncestor = this[i].GroupAncestor; } return groupAncestor; } } /// /// Gets the common host ancestor for the selection without using the individual objects' HostAncestor. /// public Host HostAncestorFromConnection { get { Host hostAncestor = Helpers.GetHostAncestor(First as IXenObject); foreach (var item in AsXenObjects()) { if (hostAncestor != Helpers.GetHostAncestor(item)) return null; } return hostAncestor; } } /// /// Gets the common pool ancestor for the selection without using the individual objects' PoolAncestor. /// public Pool PooAncestorFromConnection { get { var connection = GetConnectionOfAllItems(); return connection == null ? null : Helpers.GetPoolOfOne(connection); } } /// /// Gets the selected items connection. If the selection is cross-pool then null is returned. /// public IXenConnection GetConnectionOfAllItems() { IXenConnection connection = GetConnectionOfFirstItem(); foreach (var item in this) { if (connection != item.Connection) return null; } return connection; } public VirtualTreeNode RootNode { get { return Items.Count > 0 ? Items[0].RootNode : null; } } } }