/* 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.Text;
using System.Collections.ObjectModel;
using XenAdmin.Controls;
using XenAPI;
using XenAdmin.Core;
using XenAdmin.Network;
using XenAdmin.Network.StorageLink;
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.
///
/// 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 pool.
///
public bool FirstIsPool
{
get
{
return First is Pool;
}
}
///
/// Gets a value indicating whether the first item is a host.
///
public bool FirstIsHost
{
get
{
return First is Host;
}
}
///
/// Gets a value indicating whether the first item is a live host.
///
public bool FirstIsLiveHost
{
get
{
return FirstIsHost && ((Host)this[0].XenObject).IsLive;
}
}
///
/// Gets a value indicating whether the first item is a VM.
///
public bool FirstIsVM
{
get
{
return First is VM;
}
}
///
/// Gets a value indicating whether the first item is a SR.
///
public bool FirstIsSR
{
get
{
return First is SR;
}
}
///
/// Gets a value indicating whether the first item is a real VM (not a template).
///
public bool FirstIsRealVM
{
get
{
return FirstIsVM && !((VM)this[0].XenObject).is_a_template;
}
}
///
/// Gets a value indicating whether the first item is a template.
///
public bool FirstIsTemplate
{
get
{
return FirstIsVM && ((VM)this[0].XenObject).is_a_template && !((VM)this[0].XenObject).is_a_snapshot;
}
}
///
/// Gets a value indicating whether the first item is a VM_appliance.
///
public bool FirstIsVMappliance
{
get
{
return First is VM_appliance;
}
}
///
/// Gets a value indicating whether the first item is a GroupingTag.
///
public bool FirstIsGroup
{
get
{
return First is GroupingTag;
}
}
///
/// Gets a value indicating whether the first item is a StorageLink object.
///
public bool FirstIsStorageLink
{
get
{
return First is IStorageLinkObject;
}
}
///
/// 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;
}
}
}
}