// Copyright 2003-2004 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace Apache.Avalon.Castle.ManagementExtensions.Default
{
using System;
///
/// Default (and simple) implementation of .
/// TODO: Implement a lyfecycle for registering managed components.
///
[ManagedComponent]
public class MDefaultRegistry : MarshalByRefObject, MRegistry
{
protected DomainCollection domains = new DomainCollection();
protected MServer server;
public MDefaultRegistry(MServer server)
{
if (server == null)
{
throw new ArgumentNullException("server");
}
this.server = server;
}
#region MRegistry Members
///
/// Registers an instance if its not already registered.
///
/// Instance to be register - can't be null.
/// Instance's name - can't be null.
/// A ManagedInstance representing the instance data.
[ManagedOperation]
public ManagedInstance RegisterManagedObject(Object instance, ManagedObjectName name)
{
if (name == null)
{
throw new ArgumentNullException("name");
}
if (instance == null)
{
throw new ArgumentNullException("instance");
}
ComponentType cType = MInspector.Inspect(instance);
MDynamicSupport dynamic = null;
if (cType == ComponentType.None)
{
throw new InvalidComponentException("Component is not a managed component.");
}
if (cType == ComponentType.Standard)
{
dynamic = MDynamicSupportFactory.Create(instance);
}
else if (cType == ComponentType.Dynamic)
{
dynamic = (MDynamicSupport) instance;
}
String domainName = name.Domain;
Domain domain = null;
lock(domains)
{
domain = domains[domainName];
if (domain == null)
{
domain = new Domain(domainName);
domains.Add(domain);
}
}
Entry entry = new Entry(instance, dynamic);
try
{
MRegistrationListener registration = instance as MRegistrationListener;
InvokeBeforeRegister(registration, name);
lock(domain)
{
if (domain.Contains(name))
{
throw new InstanceAlreadyRegistredException(name.ToString());
}
domain.Add(name, entry);
}
InvokeAfterRegister(registration);
}
catch(Exception e)
{
domain.Remove(name);
throw e;
}
return new ManagedInstance(instance.GetType().FullName, name);
}
///
/// Returns
/// of specified .
///
/// The name to be located.
/// A ManagedInstance representing the instance data.
[ManagedOperation]
public ManagedInstance GetManagedInstance(ManagedObjectName name)
{
if (name == null)
{
throw new ArgumentNullException("name");
}
return new ManagedInstance(GetEntry(name).Instance.GetType().FullName, name);
}
///
/// Unregisters the specified object.
///
/// The name to be located.
[ManagedOperation]
public void UnregisterManagedObject(ManagedObjectName name)
{
if (name == null)
{
throw new ArgumentNullException("name");
}
String domainName = name.Domain;
try
{
Domain domain = FindDomain(domainName);
Entry entry = domain[name];
if (entry != null)
{
MRegistrationListener listener = entry.Instance as MRegistrationListener;
InvokeBeforeDeregister(listener);
domain.Remove(name);
InvokeAfterDeregister(listener);
}
}
catch(InvalidDomainException)
{
}
}
///
/// Returns true if the Registry contains the specified object.
///
/// The name to be located.
/// true if the object could be found
[ManagedOperation]
public bool Contains(ManagedObjectName name)
{
if (name == null)
{
throw new ArgumentNullException("name");
}
String domainName = name.Domain;
Domain domain = FindDomain(domainName);
return domain.Contains(name);
}
///
/// Returns the number of currently registered objects.
///
[ManagedAttribute]
public int Count
{
get
{
int total = 0;
foreach(Domain domain in domains)
{
total += domain.Count;
}
return total;
}
}
///
/// Indexer for registered objects.
///
public Object this[ManagedObjectName name]
{
get
{
if (name == null)
{
throw new ArgumentNullException("name");
}
return GetEntry(name).Instance;
}
}
///
/// Invokes an action in managed object
///
///
///
///
///
///
/// If domain name is not found.
public Object Invoke(ManagedObjectName name, String action, Object[] args, Type[] signature)
{
return GetEntry(name).Invoker.Invoke(action, args, signature);
}
///
/// Returns the info (attributes and operations) about the specified object.
///
///
///
/// If domain name is not found.
public ManagementInfo GetManagementInfo(ManagedObjectName name)
{
return GetEntry(name).Invoker.Info;
}
///
/// Gets an attribute value of the specified managed object.
///
///
///
///
/// If domain name is not found.
public Object GetAttributeValue(ManagedObjectName name, String attributeName)
{
return GetEntry(name).Invoker.GetAttributeValue(attributeName);
}
///
/// Sets an attribute value of the specified managed object.
///
///
///
///
/// If domain name is not found.
public void SetAttributeValue(ManagedObjectName name, String attributeName, Object attributeValue)
{
GetEntry(name).Invoker.SetAttributeValue(attributeName, attributeValue);
}
///
/// Returns an array of registered domains.
///
/// a list of domains
public String[] GetDomains()
{
return domains.ToArray();
}
///
/// Queries the registerd components.
///
///
public ManagedObjectName[] Query(ManagedObjectName query)
{
// TODO: several queries...
if (query.LiteralProperties.Equals("*"))
{
return FindAllFromDomain(query.Domain);
}
return null;
}
#endregion
///
/// Helper to locate the domain.
///
///
///
private Domain FindDomain(String domainName)
{
Domain domain = domains[domainName];
if (domain == null)
{
throw new InvalidDomainException(domainName);
}
return domain;
}
///
/// Helper to locate Entries.
///
///
///
private Entry GetEntry(ManagedObjectName name)
{
Domain domain = FindDomain(name.Domain);
Entry entry = domain[name];
if (entry == null)
{
throw new ManagedObjectNotFoundException(name.ToString());
}
return entry;
}
private void InvokeBeforeRegister(MRegistrationListener listener, ManagedObjectName name)
{
if (listener != null)
{
listener.BeforeRegister(server, name);
}
}
private void InvokeAfterRegister(MRegistrationListener listener)
{
if (listener != null)
{
listener.AfterRegister();
}
}
private void InvokeBeforeDeregister(MRegistrationListener listener)
{
if (listener != null)
{
try
{
listener.BeforeDeregister();
}
catch(Exception)
{
// An exception here shall not stop us from continue
}
}
}
private void InvokeAfterDeregister(MRegistrationListener listener)
{
if (listener != null)
{
try
{
listener.AfterDeregister();
}
catch(Exception)
{
// An exception here shall not stop us from continue
}
}
}
private ManagedObjectName[] FindAllFromDomain(String domainName)
{
try
{
Domain domain = FindDomain(domainName);
return domain.ToArray();
}
catch(InvalidDomainException)
{
}
return null;
}
}
}