xenadmin/XenAdmin/Commands/SelectedItemCollection.cs

443 lines
14 KiB
C#
Raw Normal View History

/* Copyright (c) Cloud Software Group, Inc.
*
* 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
{
/// <summary>
/// A read-only collection of <see cref="SelectedItem"/>s.
/// </summary>
public class SelectedItemCollection : ReadOnlyCollection<SelectedItem>
{
/// <summary>
/// Initializes a new instance of the <see cref="SelectedItemCollection"/> class.
/// The collection has no contents.
/// </summary>
public SelectedItemCollection()
: base(new List<SelectedItem>())
{
}
/// <summary>
/// Initializes a new instance of the <see cref="SelectedItemCollection"/> class with one item
/// </summary>
/// <param name="item">The itemsthat will populate the collection.</param>
public SelectedItemCollection(SelectedItem item)
: base(new List<SelectedItem> {item})
{
}
/// <summary>
/// Initializes a new instance of the <see cref="SelectedItemCollection"/> class.
/// </summary>
/// <param name="items">The items that will populate the collection.</param>
public SelectedItemCollection(IEnumerable<SelectedItem> items)
: base(new List<SelectedItem>(items))
{
}
/// <summary>
/// Returns a list of GroupingTags and IXenObjects that
/// this collection represents.
/// </summary>
/// <returns></returns>
public List<object> AsObjects()
{
return new List<SelectedItem>(this).ConvertAll(s => s.Value);
}
/// <summary>
/// Gets a list of GroupingTags that this collection represents.
/// </summary>
public List<GroupingTag> AsGroupingTags()
{
List<GroupingTag> output = new List<GroupingTag>();
foreach (SelectedItem item in this)
{
output.Add(item.GroupingTag);
}
return output;
}
/// <summary>
/// Gets a list of IXenObjects that this collection represents.
/// </summary>
public List<IXenObject> AsXenObjects()
{
return AsXenObjects<IXenObject>();
}
/// <summary>
/// Gets a list of IXenObjects that this collection represents.
/// </summary>
public List<T> AsXenObjects<T>() where T : IXenObject
{
List<T> output = new List<T>();
foreach (SelectedItem item in this)
{
if (item.XenObject is T)
output.Add((T)item.XenObject);
}
return output;
}
/// <summary>
/// Gets a list of IXenObjects that this collection represents.
/// </summary>
/// <param name="filter">A Predicate for filtering the list.</param>
public List<T> AsXenObjects<T>(Predicate<T> filter) where T : IXenObject
{
List<T> output = new List<T>();
foreach (SelectedItem item in this)
{
if (item.XenObject is T)
{
T obj = (T)item.XenObject;
if (filter(obj))
output.Add(obj);
}
}
return output;
}
/// <summary>
/// Determines whether this collection contains only one item of the specified type. T
/// can either be IXenObject or GroupingTag.
/// </summary>
/// <param name="predicate">A Predicate that must be satisfied.</param>
public bool ContainsOneItemOfType<T>(Predicate<T> predicate) where T : class
{
if (ContainsOneItemOfType<T>())
{
object item = (this[0].XenObject as T) ?? (this[0].GroupingTag as T);
return item != null && predicate((T)item);
}
return false;
}
/// <summary>
/// Determines whether this collection contains only one item of the specified type. T
/// can either be IXenObject or GroupingTag.
/// </summary>
public bool ContainsOneItemOfType<T>() where T : class
{
return Count == 1 && ItemIs<T>(0);
}
/// <summary>
/// Determines whether the item at the specified index is of the specified type. T
/// can either be IXenObject or GroupingTag.
/// </summary>
private bool ItemIs<T>(int index) where T : class
{
return Count >= index && (this[index].XenObject is T || this[index].GroupingTag is T);
}
/// <summary>
/// Determines whether all items of the collection are of the specified type. T
/// can either be IXenObject or GroupingTag.
/// </summary>
public bool AllItemsAre<T>() where T : class
{
if (Count == 0)
{
return false;
}
for (int i = 0; i < Count; i++)
{
if (!ItemIs<T>(i))
{
return false;
}
}
return true;
}
/// <summary>
/// Determines whether all items of the collection are of the specified type. T
/// can either be IXenObject or GroupingTag.
/// </summary>
/// <param name="predicate">A predicate that must be satisfied.</param>
public bool AllItemsAre<T>(Predicate<T> 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<T>(i) || !predicate((T)item))
{
return false;
}
}
return true;
}
/// <summary>
/// Determines if at least one item in the collection satisfies the specified condition. T
/// is a type the implements IXenObject.
/// </summary>
/// <param name="doThis">The condition to be satisfied.</param>
public bool AtLeastOneXenObjectCan<T>(Predicate<T> doThis) where T : IXenObject
{
Util.ThrowIfParameterNull(doThis, "doThis");
foreach (SelectedItem item in this)
{
if (doThis((T)item.XenObject))
{
return true;
}
}
return false;
}
/// <summary>
/// Gets the first item whether it be either a IXenObject or a GroupingTag. Returns null if the collection is empty.
/// </summary>
public object First
{
get
{
return Count == 0 ? null : this[0].Value;
}
}
/// <summary>
/// Gets the first item and casts it to an IXenObject. Can return null.
/// </summary>
public IXenObject FirstAsXenObject
{
get
{
return First as IXenObject;
}
}
/// <summary>
/// Gets a value indicating whether the first item is a T.
/// </summary>
public bool FirstIs<T>() where T : IXenObject
{
return First is T;
}
/// <summary>
/// Gets a value indicating whether the first item is a live host.
/// </summary>
public bool FirstIsLiveHost
{
get
{
return FirstIs<Host>() && ((Host)this[0].XenObject).IsLive();
}
}
/// <summary>
/// Gets a value indicating whether the first item is a real VM (not a template).
/// </summary>
public bool FirstIsRealVM
{
get
{
return FirstIs<VM>() && !((VM)this[0].XenObject).is_a_template;
}
}
/// <summary>
/// Gets a value indicating whether the first item is a template.
/// </summary>
public bool FirstIsTemplate
{
get
{
return FirstIs<VM>() && ((VM)this[0].XenObject).is_a_template && !((VM)this[0].XenObject).is_a_snapshot;
}
}
/// <summary>
/// Gets the connection of first item. If the collection is empty then null is returned.
/// </summary>
public IXenConnection GetConnectionOfFirstItem()
{
if (Count > 0)
{
return this[0].Connection;
}
return null;
}
/// <summary>
/// Gets the common host ancestor for the selection. If the selected items have different host ancestors then null is returned.
/// </summary>
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;
}
}
/// <summary>
/// Gets the common pool ancestor for the selection. If the selected items have different pool ancestors then null is returned.
/// </summary>
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;
}
}
/// <summary>
/// Gets the common group ancestor for the selection. If the selected
/// items have different group ancestors then null is returned.
/// </summary>
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;
}
}
/// <summary>
/// Gets the common host ancestor for the selection without using the individual objects' HostAncestor.
/// </summary>
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;
}
}
/// <summary>
/// Gets the common pool ancestor for the selection without using the individual objects' PoolAncestor.
/// </summary>
public Pool PooAncestorFromConnection
{
get
{
var connection = GetConnectionOfAllItems();
return connection == null ? null : Helpers.GetPoolOfOne(connection);
}
}
/// <summary>
/// Gets the selected items connection. If the selection is cross-pool then null is returned.
/// </summary>
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;
}
}
}
}