/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.profileservice.management;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import org.jboss.aop.Dispatcher;
import org.jboss.aop.advice.Interceptor;
import org.jboss.aspects.remoting.InvokeRemoteInterceptor;
import org.jboss.aspects.remoting.MergeMetaDataInterceptor;
import org.jboss.aspects.remoting.Remoting;
import org.jboss.aspects.security.SecurityClientInterceptor;
import org.jboss.deployers.spi.management.DelegatingComponentDispatcher;
import org.jboss.deployers.spi.management.RuntimeComponentDispatcher;
import org.jboss.managed.api.ManagedOperation;
import org.jboss.managed.api.ManagedProperty;
import org.jboss.managed.api.MutableManagedComponent;
import org.jboss.profileservice.management.DelegatingComponentDispatcherImpl.ProxyRegistry;
import org.jboss.profileservice.management.client.ManagedComponentDelegate;
import org.jboss.profileservice.management.client.ManagedOperationDelegate;
import org.jboss.profileservice.management.client.ManagedPropertyDelegate;
import org.jboss.remoting.InvokerLocator;
import org.jboss.util.collection.ConcurrentReferenceHashMap;
import org.jboss.util.collection.ConcurrentReferenceHashMap.ReferenceType;
/**
* Factory generating managed operations and properties delegating
* requests to a RuntimeComponentDispatcher proxy.
*
* @author <a href="mailto:emuckenh@redhat.com">Emanuel Muckenhuber</a>
* @version $Revision$
*/
public class ManagedOperationProxyFactory implements Serializable, ProxyRegistry
{
/** The serialVersionUID */
private static final long serialVersionUID = 1343224268002757169L;
private AtomicLong operationID = new AtomicLong(0);
private AtomicLong propertyID = new AtomicLong(0);
private RuntimeComponentDispatcher dispatcher;
private InvokerLocator locator;
private Map<Long, ManagedProperty> properties = new ConcurrentReferenceHashMap<Long, ManagedProperty>(ReferenceType.STRONG, ReferenceType.WEAK);
private Map<Long, ManagedOperation> operations = new ConcurrentReferenceHashMap<Long, ManagedOperation>(ReferenceType.STRONG, ReferenceType.WEAK);
/** The runtime component dispatcher proxy. */
private DelegatingComponentDispatcher dispatcherProxy;
/** The dispatch name. */
private String dispatchName;
public String getDispatchName()
{
return dispatchName;
}
public void setDispatchName(String dispatchName)
{
this.dispatchName = dispatchName;
}
public RuntimeComponentDispatcher getDispatcher()
{
return dispatcher;
}
public void setDispatcher(RuntimeComponentDispatcher dispatcher)
{
this.dispatcher = dispatcher;
}
public InvokerLocator getLocator()
{
return locator;
}
public void setLocator(InvokerLocator locator)
{
this.locator = locator;
}
public DelegatingComponentDispatcher getDispatcherProxy()
{
return dispatcherProxy;
}
public void start() throws Exception
{
if(this.dispatcher == null)
throw new IllegalStateException("Null dispatcher.");
if(this.locator == null)
throw new IllegalStateException("Null locator.");
this.dispatcherProxy = createDispatcherProxy();
}
public void clear()
{
//
}
/**
* Get the managed operation delegate
*
* @param the operation id
* @return the operation
* @throws IllegalStateException if the operation is not registered
*/
public ManagedOperation getManagedOperation(Long opID)
{
ManagedOperation op = this.operations.get(opID);
if(op == null)
throw new IllegalStateException("operation not found for id " + opID);
return op;
}
/**
* Get the managed property delegate
*
* @param the property id
* @return the property
* @throws IllegalStateException if the property is not registered
*/
public ManagedProperty getManagedProperty(Long propID)
{
ManagedProperty prop = this.properties.get(propID);
if(prop == null)
throw new IllegalStateException("property not found for id " + propID);
return prop;
}
/**
* Create a delegating managed component.
*
* @param comp the managed component
* @return the delegating managed component
*/
public MutableManagedComponent createComponentProxy(MutableManagedComponent comp)
{
//
if(comp.getComponentName() == null)
return comp;
// Check if this is a delegate component already
if(comp instanceof ManagedComponentDelegate)
return comp;
return new ManagedComponentDelegate(comp.getComponentName(), comp, dispatcherProxy);
}
/**
* Create a delegating managed property. This is used for ViewUse.STATISTIC properties,
* delegating the getValue() request to the dispatcher proxy.
*
* @param delegate the original property
* @param componentName the component name
* @return the delegate managed property
*/
public ManagedProperty createPropertyProxy(ManagedProperty delegate, Object componentName)
{
if(delegate instanceof ManagedPropertyDelegate)
{
// Ignore ManagedPropertyDelegate
return delegate;
}
else
{
long propID = propertyID.incrementAndGet();
ManagedPropertyDelegate proxy = new ManagedPropertyDelegate(propID, delegate, componentName, dispatcherProxy);
this.properties.put(propID, proxy);
return proxy;
}
}
/**
* Create managed operations for runtime components, where the invoke() can
* be invoked on the client side.
*
* @param ops the managed operations
* @param componentName the component name
* @return a set of runtime operations
* @throws Exception
*/
public Set<ManagedOperation> createOperationProxies(Set<ManagedOperation> ops, Object componentName)
throws Exception
{
HashSet<ManagedOperation> opProxies = new HashSet<ManagedOperation>();
for (ManagedOperation op : ops)
{
if(op instanceof ManagedOperationDelegate)
{
// Ignore ManagedOperationDelegate
opProxies.add(op);
continue;
}
else
{
long opID = operationID.incrementAndGet();
ManagedOperationDelegate proxy = new ManagedOperationDelegate(opID, op, componentName, dispatcherProxy);
this.operations.put(opID, proxy);
opProxies.add(proxy);
}
}
return opProxies;
}
/**
* Create a remoting DelegatingComponentDispatcher proxy.
*
* @return the proxy
* @throws Exception
*/
protected DelegatingComponentDispatcher createDispatcherProxy() throws Exception
{
// The interceptors
ArrayList<Interceptor> interceptors = new ArrayList<Interceptor>();
interceptors.add(SecurityClientInterceptor.singleton);
interceptors.add(MergeMetaDataInterceptor.singleton);
interceptors.add(InvokeRemoteInterceptor.singleton);
Class<?>[] ifaces = {DelegatingComponentDispatcher.class};
DelegatingComponentDispatcher delegate = new DelegatingComponentDispatcherImpl(this, this.dispatcher);
String dispatchName = "ProfileService-" + this.dispatchName;
Dispatcher.singleton.registerTarget(dispatchName, delegate);
return (DelegatingComponentDispatcher) Remoting.createRemoteProxy(dispatchName,
getClass().getClassLoader(), ifaces, locator, interceptors, "ProfileService");
}
}