/**************************************************************************************
* Copyright (c) Jonas Bon�r, Alexandre Vasseur. All rights reserved. *
* http://aspectwerkz.codehaus.org *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the QPL license *
* a copy of which has been included with this distribution in the license.txt file. *
**************************************************************************************/
package org.codehaus.aspectwerkz.xmldef;
import java.util.Set;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Collections;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.WeakHashMap;
import java.util.Properties;
import java.lang.reflect.Method;
import java.io.FileInputStream;
import org.codehaus.aspectwerkz.xmldef.advice.Advice;
import org.codehaus.aspectwerkz.xmldef.advice.AbstractAdvice;
import org.codehaus.aspectwerkz.xmldef.introduction.Introduction;
import org.codehaus.aspectwerkz.xmldef.definition.StartupManager;
import org.codehaus.aspectwerkz.xmldef.definition.AspectWerkzDefinitionImpl;
import org.codehaus.aspectwerkz.regexp.CompiledPatternTuple;
import org.codehaus.aspectwerkz.regexp.CallerSidePattern;
import org.codehaus.aspectwerkz.metadata.MethodMetaData;
import org.codehaus.aspectwerkz.metadata.FieldMetaData;
import org.codehaus.aspectwerkz.metadata.ClassNameMethodMetaDataTuple;
import org.codehaus.aspectwerkz.metadata.ClassMetaData;
import org.codehaus.aspectwerkz.transform.TransformationUtil;
import org.codehaus.aspectwerkz.exception.DefinitionException;
import org.codehaus.aspectwerkz.exception.WrappedRuntimeException;
import org.codehaus.aspectwerkz.definition.AspectWerkzDefinition;
import org.codehaus.aspectwerkz.util.SequencedHashMap;
import org.codehaus.aspectwerkz.util.Util;
import org.codehaus.aspectwerkz.connectivity.RemoteProxyServer;
import org.codehaus.aspectwerkz.connectivity.Invoker;
import org.codehaus.aspectwerkz.connectivity.RemoteProxy;
import org.codehaus.aspectwerkz.ContextClassLoader;
import org.codehaus.aspectwerkz.DeploymentModel;
import org.codehaus.aspectwerkz.MethodComparator;
import org.codehaus.aspectwerkz.AspectMetaData;
import org.codehaus.aspectwerkz.IndexTuple;
import org.codehaus.aspectwerkz.Mixin;
import org.codehaus.aspectwerkz.System;
/**
* Manages the aspects in the AspectWerkz system.
* <p/>Handles the initialization and configuration of the system.
* <p/>Stores and indexes the aspects defined in the system.
* <p/>Stores and indexes the advised methods.
* <p/>Stores and indexes the introduced methods.
*
* @author <a href="mailto:jboner@codehaus.org">Jonas Bon�r</a>
*/
public final class XmlDefSystem implements System {
/**
* Holds references to all the the aspects in the system.
*/
private final Map m_aspects = new SequencedHashMap();
/**
* Cache for the execution pointcuts.
*
* @todo when unweaving (and reordering) of aspects is supported then this cache must have a way of being invalidated.
*/
private final Map m_executionPointcutCache = new WeakHashMap();
/**
* Cache for the get pointcuts.
*
* @todo when unweaving (and reordering) of aspects is supported then this cache must have a way of being invalidated.
*/
private final Map m_getPointcutCache = new WeakHashMap();
/**
* Cache for the set pointcuts.
*
* @todo when unweaving (and reordering) of aspects is supported then this cache must have a way of being invalidated.
*/
private final Map m_setPointcutCache = new WeakHashMap();
/**
* Cache for the throws pointcuts.
*
* @todo when unweaving (and reordering) of aspects is supported then this cache must have a way of being invalidated.
*/
private final Map m_throwsPointcutCache = new WeakHashMap();
/**
* Cache for the call pointcuts.
*
* @todo when unweaving (and reordering) of aspects is supported then this cache must have a way of being invalidated.
*/
private final Map m_callPointcutCache = new WeakHashMap();
/**
* Cache for the cflow pointcuts.
*
* @todo when unweaving (and reordering) of aspects is supported then this cache must have a way of being invalidated.
*/
private final Map m_cflowPointcutCache = new WeakHashMap();
/**
* Holds references to all the the advised methods in the system.
*/
private final Map m_methods = new HashMap();
/**
* Holds references to all the the advices in the system.
*/
private Advice[] m_advices = new Advice[0];
/**
* Holds the indexes for the advices.
*/
private final Map m_adviceIndexes = new HashMap();
/**
* Holds references to all the the introductions in the system.
*/
private Introduction[] m_introductions = new Introduction[0];
/**
* Marks the system as initialized.
*/
private boolean m_initialized = false;
/**
* The UUID for the system.
*/
private final String m_uuid;
/**
* The definition.
*/
private AspectWerkzDefinitionImpl m_definition;
/**
* Holds a list of the cflow join points passed by the control flow of the current thread.
*/
private final ThreadLocal m_controlFlowLog = new ThreadLocal();
/**
* The remote proxy server instance.
*/
private RemoteProxyServer m_remoteProxyServer = null;
/**
* Creates a new AspectWerkz system instance.
* Sets the UUID for the system.
* Is set to private since the instance should be retrieved using the getSystem(..) method.
*
* @param uuid the UUID for the system
* @param definition the definition for the system
*/
private XmlDefSystem(final String uuid, final AspectWerkzDefinition definition) {
if (uuid == null) throw new IllegalArgumentException("uuid can not be null");
if (definition == null) throw new IllegalArgumentException("definition can not be null");
m_uuid = uuid;
m_definition = (AspectWerkzDefinitionImpl)definition;
if (START_REMOTE_PROXY_SERVER) {
startRemoteProxyServer();
}
}
/**
* Initializes the system.
*/
public synchronized void initialize() {
if (m_initialized) return;
m_initialized = true;
StartupManager.initializeSystem(m_uuid, m_definition);
}
/**
* Checks if the definition is of type attribute definition.
*
* @return returns false for this system
*/
public boolean isAttribDef() {
return false;
}
/**
* Checks if the definition is of type XML definition.
*
* @return returns true for this system
*/
public boolean isXmlDef() {
return true;
}
/**
* Registers a new aspect for a specific class.
*
* @param aspect the aspect to register
*/
public void register(final AspectMetaData aspect) {
if (aspect == null) throw new IllegalArgumentException("aspect can not be null");
if (aspect.getName() == null) throw new IllegalArgumentException("aspect name can not be null");
synchronized (m_aspects) {
m_aspects.put(aspect.getName(), aspect);
}
}
/**
* Registers a new advice and maps it to a name.
*
* @param name the name to map the advice to
* @param advice the advice to register
*/
public void register(final String name, final Advice advice) {
if (name == null) throw new IllegalArgumentException("advice name can not be null");
if (advice == null) throw new IllegalArgumentException("advice can not be null");
synchronized (m_adviceIndexes) {
synchronized (m_advices) {
final int index = m_advices.length + 1;
m_adviceIndexes.put(name, new IndexTuple(index, -1));
final Advice[] tmp = new Advice[m_advices.length + 1];
java.lang.System.arraycopy(m_advices, 0, tmp, 0, m_advices.length);
tmp[m_advices.length] = advice;
m_advices = new Advice[m_advices.length + 1];
java.lang.System.arraycopy(tmp, 0, m_advices, 0, tmp.length);
}
}
}
/**
* Registers an introduction and maps it to a name.
* At the moment it is not possible to add new introductions at runtime (don't know
* if it makes sense).
*
* @param name the name to map the introduction to
* @param introduction the introduction to register
*/
public void register(final String name, final Introduction introduction) {
if (name == null) throw new IllegalArgumentException("introduction name can not be null");
if (introduction == null) throw new IllegalArgumentException("introduction can not be null");
synchronized (m_introductions) {
int nrOfIntroductions = m_definition.getIntroductionIndexes().size();
if (m_introductions.length == 0) {
m_introductions = new Introduction[nrOfIntroductions];
}
int index = m_definition.getIntroductionIndex(name) - 1;
m_introductions[index] = introduction;
}
}
/**
* Registers entering of a control flow join point.
*
* @param metaData the classname:methodMetaData metaData
*/
public void enteringControlFlow(final ClassNameMethodMetaDataTuple metaData) {
if (metaData == null) throw new IllegalArgumentException("classname:methodMetaData tuple can not be null");
Set cflowSet = (Set)m_controlFlowLog.get();
if (cflowSet == null) {
cflowSet = new HashSet();
}
cflowSet.add(metaData);
m_controlFlowLog.set(cflowSet);
}
/**
* Registers exiting from a control flow join point.
*
* @param metaData the classname:methodMetaData metaData
*/
public void exitingControlFlow(final ClassNameMethodMetaDataTuple metaData) {
if (metaData == null) throw new IllegalArgumentException("classname:methodMetaData tuple can not be null");
Set cflowSet = (Set)m_controlFlowLog.get();
if (cflowSet == null) {
return;
}
cflowSet.remove(metaData);
m_controlFlowLog.set(cflowSet);
}
/**
* Checks if we are in the control flow of a specific cflow pointcut.
*
* @param patternTuple the compiled tuple with the class pattern and the method pattern of the cflow pointcut
* @return boolean
*/
public boolean isInControlFlowOf(final CompiledPatternTuple patternTuple) {
if (patternTuple == null) throw new IllegalArgumentException("class:method pattern tuple can not be null");
Set cflowSet = (Set)m_controlFlowLog.get();
if (cflowSet == null || cflowSet.isEmpty()) {
return false;
}
else {
for (Iterator it = cflowSet.iterator(); it.hasNext();) {
ClassNameMethodMetaDataTuple tuple = (ClassNameMethodMetaDataTuple)it.next();
CallerSidePattern callerSidePattern = ((CallerSidePattern)patternTuple.getPattern());
if (callerSidePattern.matches(tuple.getClassName(), tuple.getMethodMetaData())) {
return true;
}
}
}
return false;
}
/**
* Creates and registers new advice at runtime.
*
* @param name the name of the advice
* @param className the class name of the advice
* @param deploymentModel the deployment model for the advice
* @param loader an optional class loader (if null it uses the context classloader)
*/
public void createAdvice(final String name,
final String className,
final String deploymentModel,
final ClassLoader loader) {
if (name == null) throw new IllegalArgumentException("advice name can not be null");
if (className == null) throw new IllegalArgumentException("class name can not be null");
if (deploymentModel == null) throw new IllegalArgumentException("deployment model can not be null");
AbstractAdvice prototype = null;
Class adviceClass = null;
try {
if (loader == null) {
adviceClass = ContextClassLoader.loadClass(className);
}
else {
adviceClass = loader.loadClass(className);
}
prototype = (AbstractAdvice)adviceClass.newInstance();
}
catch (Exception e) {
StringBuffer cause = new StringBuffer();
cause.append("could not deploy new prototype with name ");
cause.append(name);
cause.append(" and class ");
cause.append(className);
cause.append(" due to: ");
cause.append(e);
throw new RuntimeException(cause.toString());
}
prototype.setDeploymentModel(DeploymentModel.getDeploymentModelAsInt(deploymentModel));
prototype.setName(name);
prototype.setAdviceClass(prototype.getClass());
prototype.setContainer(StartupManager.createAdviceContainer(prototype));
// register the advice
register(name, prototype);
}
/**
* Returns the aspect for the name specified.
*
* @param name the name of the aspect
* @return the aspect
*/
public AspectMetaData getAspectMetaData(final String name) {
if (name == null) throw new IllegalArgumentException("aspect name can not be null");
if (m_aspects.containsKey(name)) {
return (AspectMetaData)m_aspects.get(name);
}
else {
initialize();
if (m_aspects.containsKey(name)) {
return (AspectMetaData)m_aspects.get(name);
}
else {
throw new DefinitionException("aspect " + name + " is not properly defined");
}
}
}
/**
* Returns a list with all the aspects.
*
* @return the aspects
*/
public Collection getAspectsMetaData() {
initialize();
return m_aspects.values();
}
/**
* Returns the method pointcut list for the class and method specified.
* Caches the list, needed since the actual method call is expensive
* and is made each time a new instance of an advised class is created.
*
* @param classMetaData the meta-data for the class
* @param methodMetaData meta-data for the method
* @return the pointcuts for this join point
*/
public List getExecutionPointcuts(final ClassMetaData classMetaData,
final MethodMetaData methodMetaData) {
if (classMetaData == null) throw new IllegalArgumentException("class meta-data can not be null");
if (methodMetaData == null) throw new IllegalArgumentException("method meta-data can not be null");
initialize();
Integer hashKey = Util.calculateHash(classMetaData.getName(), methodMetaData);
// if cached; return the cached list
if (m_executionPointcutCache.containsKey(hashKey)) {
return (List)m_executionPointcutCache.get(hashKey);
}
List pointcuts = new ArrayList();
for (Iterator it = m_aspects.values().iterator(); it.hasNext();) {
AspectMetaData aspect = (AspectMetaData)it.next();
List executionPointcuts = aspect.getExecutionPointcuts(classMetaData, methodMetaData);
pointcuts.addAll(executionPointcuts);
}
synchronized (m_executionPointcutCache) {
m_executionPointcutCache.put(hashKey, pointcuts);
}
return pointcuts;
}
/**
* Returns the get field pointcut list for the class and field specified.
* Caches the list, needed since the actual method call is expensive
* and is made each time a new instance of an advised class is created.
*
* @param classMetaData the meta-data for the class
* @param fieldMetaData meta-data for the field
* @return the pointcuts for this join point
*/
public List getGetPointcuts(final ClassMetaData classMetaData,
final FieldMetaData fieldMetaData) {
if (classMetaData == null) throw new IllegalArgumentException("class meta-data can not be null");
if (fieldMetaData == null) throw new IllegalArgumentException("field meta-data can not be null");
initialize();
Integer hashKey = Util.calculateHash(classMetaData.getName(), fieldMetaData);
// if cached; return the cached list
if (m_getPointcutCache.containsKey(hashKey)) {
return (List)m_getPointcutCache.get(hashKey);
}
List pointcuts = new ArrayList();
for (Iterator it = m_aspects.values().iterator(); it.hasNext();) {
AspectMetaData aspect = (AspectMetaData)it.next();
pointcuts.addAll(aspect.getGetPointcuts(classMetaData, fieldMetaData));
}
synchronized (m_getPointcutCache) {
m_getPointcutCache.put(hashKey, pointcuts);
}
return pointcuts;
}
/**
* Returns the set field pointcut list for the class and field specified.
* Caches the list, needed since the actual method call is expensive
* and is made each time a new instance of an advised class is created.
*
* @param classMetaData the meta-data for the class
* @param fieldMetaData meta-data for the field
* @return the pointcuts for this join point
*/
public List getSetPointcuts(final ClassMetaData classMetaData,
final FieldMetaData fieldMetaData) {
if (classMetaData == null) throw new IllegalArgumentException("class meta-data can not be null");
if (fieldMetaData == null) throw new IllegalArgumentException("field meta-data can not be null");
initialize();
Integer hashKey = Util.calculateHash(classMetaData.getName(), fieldMetaData);
// if cached; return the cached list
if (m_setPointcutCache.containsKey(hashKey)) {
return (List)m_setPointcutCache.get(hashKey);
}
List pointcuts = new ArrayList();
for (Iterator it = m_aspects.values().iterator(); it.hasNext();) {
AspectMetaData aspect = (AspectMetaData)it.next();
pointcuts.addAll(aspect.getSetPointcuts(classMetaData, fieldMetaData));
}
synchronized (m_setPointcutCache) {
m_setPointcutCache.put(hashKey, pointcuts);
}
return pointcuts;
}
/**
* Returns the throws pointcut list for the class and method specified.
* Caches the list, needed since the actual method call is expensive
* and is made each time a new instance of an advised class is created.
*
* @param classMetaData the meta-data for the class
* @param methodMetaData meta-data for the method
* @return the pointcuts for this join point
*/
public List getThrowsPointcuts(final ClassMetaData classMetaData,
final MethodMetaData methodMetaData) {
if (classMetaData == null) throw new IllegalArgumentException("class meta-data can not be null");
if (methodMetaData == null) throw new IllegalArgumentException("method meta-data can not be null");
initialize();
Integer hashKey = Util.calculateHash(classMetaData.getName(), methodMetaData);
// if cached; return the cached list
if (m_throwsPointcutCache.containsKey(hashKey)) {
return (List)m_throwsPointcutCache.get(hashKey);
}
List pointcuts = new ArrayList();
for (Iterator it = m_aspects.values().iterator(); it.hasNext();) {
AspectMetaData aspect = (AspectMetaData)it.next();
pointcuts.addAll(aspect.getThrowsPointcuts(classMetaData, methodMetaData));
}
synchronized (m_throwsPointcutCache) {
m_throwsPointcutCache.put(hashKey, pointcuts);
}
return pointcuts;
}
/**
* Returns the caller side pointcut list for the class and method specified.
* Caches the list, needed since the actual method call is expensive
* and is made each time a new instance of an advised class is created.
*
* @param classMetaData the meta-data for the class
* @param methodMetaData meta-data for the method
* @return the pointcuts for this join point
*/
public List getCallPointcuts(final ClassMetaData classMetaData,
final MethodMetaData methodMetaData) {
if (classMetaData == null) throw new IllegalArgumentException("class meta-data can not be null");
if (methodMetaData == null) throw new IllegalArgumentException("method meta-data can not be null");
initialize();
Integer hashKey = Util.calculateHash(classMetaData.getName(), methodMetaData);
// if cached; return the cached list
if (m_callPointcutCache.containsKey(hashKey)) {
return (List)m_callPointcutCache.get(hashKey);
}
List pointcuts = new ArrayList();
for (Iterator it = m_aspects.values().iterator(); it.hasNext();) {
AspectMetaData aspect = (AspectMetaData)it.next();
pointcuts.addAll(aspect.getCallPointcuts(classMetaData, methodMetaData));
}
synchronized (m_callPointcutCache) {
m_callPointcutCache.put(hashKey, pointcuts);
}
return pointcuts;
}
/**
* Returns a list with the cflow pointcuts that affects the join point with the
* class name and the method name specified.
*
* @param className the name of the class for the join point
* @param methodMetaData the meta-data for the method for the join point
* @return a list with the cflow pointcuts
*/
public List getCFlowPointcuts(final String className,
final MethodMetaData methodMetaData) {
if (className == null) throw new IllegalArgumentException("class name can not be null");
if (methodMetaData == null) throw new IllegalArgumentException("method meta-data can not be null");
initialize();
Integer hashKey = Util.calculateHash(className, methodMetaData);
// if cached; return the cached list
if (m_cflowPointcutCache.containsKey(hashKey)) {
return (List)m_cflowPointcutCache.get(hashKey);
}
List pointcuts = new ArrayList();
for (Iterator it = m_aspects.values().iterator(); it.hasNext();) {
AspectMetaData aspect = (AspectMetaData)it.next();
pointcuts.addAll(aspect.getCFlowPointcuts(className, methodMetaData));
}
synchronized (m_cflowPointcutCache) {
m_cflowPointcutCache.put(hashKey, pointcuts);
}
return pointcuts;
}
/**
* Returns the index for a specific name to advice mapping.
*
* @param name the name of the advice
* @return the index of the advice
*/
public IndexTuple getAdviceIndexFor(final String name) {
if (name == null) throw new IllegalArgumentException("advice name can not be null");
return (IndexTuple)m_adviceIndexes.get(name);
}
/**
* Retrieves a specific advice based setfield's index.
*
* @param index the index of the advice
* @return the advice
*/
public Advice getAdvice(final IndexTuple index) {
Advice advice;
try {
advice = m_advices[index.getAspectIndex() - 1];
}
catch (Throwable e) {
initialize();
try {
advice = m_advices[index.getAspectIndex() - 1];
}
catch (ArrayIndexOutOfBoundsException e1) {
throw new DefinitionException("no advice with index " + index);
}
}
return advice;
}
/**
* Returns the advice for a specific name.
*
* @param name the name of the advice
* @return the the advice
*/
public Advice getAdvice(final String name) {
Advice advice;
try {
advice = m_advices[((IndexTuple)m_adviceIndexes.get(name)).getAspectIndex() - 1];
}
catch (Throwable e1) {
initialize();
try {
advice = m_advices[((IndexTuple)m_adviceIndexes.get(name)).getAspectIndex() - 1];
}
catch (ArrayIndexOutOfBoundsException e2) {
throw new DefinitionException("advice " + name + " is not properly defined");
}
}
return advice;
}
/**
* Returns an array with all the introductions in the system.
*
* @return the introductions
*/
public Introduction[] getIntroductions() {
return m_introductions;
}
/**
* Returns the index for a specific name to introduction mapping.
*
* @param name the name of the introduction
* @return the index of the introduction
*/
public int getIntroductionIndex(final String name) {
if (name == null) throw new IllegalArgumentException("introduction name can not be null");
final int index = m_definition.getIntroductionIndex(name);
if (index == 0) throw new DefinitionException("introduction " + name + " is not properly defined");
return index;
}
/**
* Retrieves a specific introduction based it's index.
*
* @param index the index of the introduction
* @return the introduction
*/
public Mixin getMixin(final int index) {
Mixin introduction;
try {
introduction = m_introductions[index - 1];
}
catch (Throwable e1) {
initialize();
try {
introduction = m_introductions[index - 1];
}
catch (ArrayIndexOutOfBoundsException e2) {
throw new DefinitionException("no introduction with index " + index);
}
}
return introduction;
}
/**
* Returns the introduction for a specific name.
*
* @param name the name of the introduction
* @return the the introduction
*/
public Mixin getMixin(final String name) {
if (name == null) throw new IllegalArgumentException("introduction name can not be null");
Mixin introduction;
try {
introduction = m_introductions[m_definition.getIntroductionIndex(name) - 1];
}
catch (Throwable e1) {
initialize();
try {
introduction = m_introductions[m_definition.getIntroductionIndex(name) - 1];
}
catch (ArrayIndexOutOfBoundsException e2) {
throw new DefinitionException("no introduction with name " + name);
}
}
return introduction;
}
/**
* Checks if a specific class has an aspect defined.
*
* @param name the name of the aspect
* @return boolean true if the class has an aspect defined
*/
public boolean hasAspect(final String name) {
if (name == null) throw new IllegalArgumentException("aspect name can not be null");
initialize();
if (m_aspects.containsKey(name)) {
return true;
}
else {
return false;
}
}
/**
* Returns a specific method by the class and the method index.
*
* @param klass the class housing the method
* @param index the method index
* @return the method
*/
public Method getMethod(final Class klass, final int index) {
if (klass == null) throw new IllegalArgumentException("class can not be null");
if (index < 0) throw new IllegalArgumentException("method index can not be less than 0");
try {
// create the method repository lazily
if (!m_methods.containsKey(klass)) {
createMethodRepository(klass);
}
}
catch (Exception e) {
throw new WrappedRuntimeException(e);
}
Method method;
try {
method = ((Method[])m_methods.get(klass))[index];
}
catch (Throwable e1) {
initialize();
try {
method = ((Method[])m_methods.get(klass))[index];
}
catch (Exception e) {
throw new WrappedRuntimeException(e);
}
}
return method;
}
/**
* Creates a new method repository for the class specified.
*
* @param klass the class
*/
private void createMethodRepository(final Class klass) {
if (klass == null) throw new IllegalArgumentException("class can not be null");
final List methods = new ArrayList();
collectMethods(klass, methods);
Collections.sort(methods, MethodComparator.getInstance(MethodComparator.PREFIXED_METHOD));
final Method[] sortedMethods = new Method[methods.size()];
for (int i = 0; i < sortedMethods.length; i++) {
sortedMethods[i] = (Method)methods.get(i);
}
synchronized (m_methods) {
m_methods.put(klass, sortedMethods);
}
}
/**
* Collects all methods for the class specified, calls itself recursively with
* the class' super class as argument to collect all methods.
*
* @param klass the class
* @param methods the method list
*/
private void collectMethods(final Class klass, final List methods) {
final Method[] declaredMethods = klass.getDeclaredMethods();
for (int i = 0; i < declaredMethods.length; i++) {
// add only the advised original methods to the lookup table,
// method pairs that consists of original:proxy
if (declaredMethods[i].getName().startsWith(
TransformationUtil.ORIGINAL_METHOD_PREFIX)) {
methods.add(declaredMethods[i]);
}
}
}
/**
* Starts up the remote proxy server.
*/
private void startRemoteProxyServer() {
Invoker invoker = getInvoker();
m_remoteProxyServer = new RemoteProxyServer(ContextClassLoader.getLoader(), invoker);
m_remoteProxyServer.start();
}
/**
* Returns the Invoker instance to use.
*
* @return the Invoker
*/
private Invoker getInvoker() {
Invoker invoker = null;
try {
Properties properties = new Properties();
properties.load(new FileInputStream(
java.lang.System.getProperty("aspectwerkz.resource.bundle")
));
String className = properties.getProperty("remote.server.invoker.classname");
invoker = (Invoker)ContextClassLoader.getLoader().loadClass(className).newInstance();
}
catch (Exception e) {
invoker = getDefaultInvoker();
}
return invoker;
}
/**
* Returns the default Invoker.
*
* @return the default invoker
*/
private Invoker getDefaultInvoker() {
return new Invoker() {
public Object invoke(final String handle,
final String methodName,
final Class[] paramTypes,
final Object[] args,
final Object context) {
Object result = null;
try {
final Object instance = RemoteProxy.getWrappedInstance(handle);
final Method method = instance.getClass().getMethod(methodName, paramTypes);
result = method.invoke(instance, args);
}
catch (Exception e) {
throw new WrappedRuntimeException(e);
}
return result;
}
};
}
}