///
/// Copyright © 2003-2008 JetBrains s.r.o.
/// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder).
///
using System;
using JetBrains.Omea.OpenAPI;
namespace JetBrains.Omea.OpenApiEx
{
///
/// Represents a list of resource objects, accessibly by index, Resource ID, and name.
///
/// The resource object type.
public class ResourceObjectsListByName : ResourceObjectsList, IResourceObjectsListByName where T : class, IResourceObject
{
///
/// ID for the property that holds the object name.
///
protected int _nNamePropId;
///
/// A handler for creating new objects and adding them to the list.
///
protected readonly EventHandler> _handlerCreate;
///
/// Creates a list from a resource list, a factory that wraps the raw resources into resource objects, and the name property ID.
///
/// The list of available resources, live or dead.
/// The factory for wrapping the raw Omea resources into resource objects.
/// ID of the property that should be looked for when getting resources by name.
/// A handler for adding new resources to the list. May be Null.
/// A handler for adding new resources to the list. May be Null.
/// A handler for creating new resources and including them into the list. May be Null.
public ResourceObjectsListByName(IResourceList resources, IResourceObjectFactory factory, int nNamePropId, EventHandler handlerAdd, EventHandler handlerRemove, EventHandler> handlerCreate)
: base(resources, factory, handlerAdd, handlerRemove)
{
_nNamePropId = nNamePropId;
_handlerCreate = handlerCreate;
}
///
/// Creates a list from a resource list, a factory that wraps the raw resources into resource objects, and the name property ID.
///
/// The list of available resources, live or dead.
/// The factory for wrapping the raw Omea resources into resource objects.
/// ID of the property that should be looked for when getting resources by name.
public ResourceObjectsListByName(IResourceList resources, IResourceObjectFactory factory, int nNamePropId)
: this(resources, factory, nNamePropId, null, null, null)
{
}
///
/// Creates a list from a resource list, a factory that wraps the raw resources into resource objects, and the name property name.
///
/// The list of available resources, live or dead.
/// The factory for wrapping the raw Omea resources into resource objects.
/// Name of the property that should be looked for when getting resources by name.
public ResourceObjectsListByName(IResourceList resources, IResourceObjectFactory factory, string sNamePropName)
: this(resources, factory, Core.ResourceStore.PropTypes[sNamePropName].Id)
{
}
///
/// Creates a list from a resource list and a factory that wraps the raw resources into resource objects.
/// The standard Name property is used when looking for resources by their name.
///
/// The list of available resources, live or dead.
/// The factory for wrapping the raw Omea resources into resource objects.
public ResourceObjectsListByName(IResourceList resources, IResourceObjectFactory factory)
: this(resources, factory, Core.Props.Name)
{
}
#region IResourceObjectsListByName Members
///
/// Gets a resource object by its name.
/// Throws if there is no such resource in the list.
/// If there's more than one, returns any (undefined behavior).
///
/// Name of the resource to look up.
/// The resource object.
public T GetByName(string name)
{
IResourceList resNamed = Core.ResourceStore.FindResources(null, _nNamePropId, name).Intersect(_resources, true);
if(resNamed.Count == 0)
throw new ArgumentOutOfRangeException("name", name, "There is no such a named resource in the list.");
return _factory.CreateResourceObject(resNamed[0]); // Ignore multiple resources.
}
///
/// Gets a resource object by its name.
/// Returns Null there is no such resource in the list.
/// If there's more than one, returns any (undefined behavior).
///
/// Name of the resource to look up.
/// The resource object, or Null if not found.
public T TryGetByName(string name)
{
IResourceList resNamed = Core.ResourceStore.FindResources(null, _nNamePropId, name).Intersect(_resources, true);
if(resNamed.Count == 0)
return null;
return _factory.CreateResourceObject(resNamed[0]); // Ignore multiple resources.
}
///
/// Gets a resource object by its name, same as .
/// Throws if there is no such resource in the list.
/// If there's more than one, returns any (undefined behavior).
///
/// Name of the resource to look up.
/// The resource object.
public T this[string name]
{
get
{
return GetByName(name);
}
}
///
/// Gets the list of all the resources with such a name in the collection.
/// If there are none such found, returns an empty list.
///
/// Name of the resources to look up.
/// The list of matching resources.
public IResourceObjectsList GetAllByName(string name)
{
IResourceList resNamed = Core.ResourceStore.FindResources(null, _nNamePropId, name).Intersect(_resources, true);
return new ResourceObjectsList(resNamed, _factory);
}
///
/// Creates a new item and adds it to the list.
/// May be unsupported by a particular list, in which case a will be thrown.
///
/// The name for the new object.
/// The newly-created object.
public T Create(string name)
{
if(name == null)
throw new ArgumentNullException("name");
if(_handlerCreate == null)
throw new NotSupportedException(IsReadOnly ? "The list is read-only." : "This operation is not supported by the list.");
ResourceObjectOutByNameEventArgs args = new ResourceObjectOutByNameEventArgs(name);
_handlerCreate(this, args);
if(args.ResourceObject == null)
throw new InvalidOperationException(string.Format("The handler has failed to create a resource object named “{0}”.", name));
return args.ResourceObject;
}
#endregion
///
///Gets a value indicating whether the is read-only.
///
///
///
///true if the is read-only; otherwise, false.
///
///
public override bool IsReadOnly
{
get
{
return (base.IsReadOnly) && (_handlerCreate == null);
}
}
}
}