mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-02 17:35:18 +00:00
svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4252 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4294 . svn revert root\common\common.xml svn resolved root\projects\repository\config\alfresco\script-services-context.xml git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4634 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
214 lines
6.6 KiB
Java
214 lines
6.6 KiB
Java
/*
|
|
* Copyright (C) 2005 Alfresco, Inc.
|
|
*
|
|
* Licensed under the Mozilla Public License version 1.1
|
|
* with a permitted attribution clause. You may obtain a
|
|
* copy of the License at
|
|
*
|
|
* http://www.alfresco.org/legal/license.txt
|
|
*
|
|
* 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.
|
|
*/
|
|
package org.alfresco.repo.policy;
|
|
|
|
import java.lang.reflect.InvocationHandler;
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.lang.reflect.Method;
|
|
import java.lang.reflect.Proxy;
|
|
|
|
import org.alfresco.util.ParameterCheck;
|
|
|
|
|
|
/**
|
|
* Java based Behaviour.
|
|
*
|
|
* A behavior acts like a delegate (a method pointer). The pointer is
|
|
* represented by an instance object and method name.
|
|
*
|
|
* @author David Caruana
|
|
*
|
|
*/
|
|
public class JavaBehaviour extends BaseBehaviour
|
|
{
|
|
// The object instance holding the method
|
|
Object instance;
|
|
|
|
// The method name
|
|
String method;
|
|
|
|
/**
|
|
* Construct.
|
|
*
|
|
* @param instance the object instance holding the method
|
|
* @param method the method name
|
|
*/
|
|
public JavaBehaviour(Object instance, String method)
|
|
{
|
|
this(instance, method, NotificationFrequency.EVERY_EVENT);
|
|
}
|
|
|
|
/**
|
|
* Construct.
|
|
*
|
|
* @param instance the object instance holding the method
|
|
* @param method the method name
|
|
*/
|
|
public JavaBehaviour(Object instance, String method, NotificationFrequency frequency)
|
|
{
|
|
super(frequency);
|
|
ParameterCheck.mandatory("Instance", instance);
|
|
ParameterCheck.mandatory("Method", method);
|
|
this.method = method;
|
|
this.instance = instance;
|
|
}
|
|
|
|
|
|
@Override
|
|
public String toString()
|
|
{
|
|
return "Java method[class=" + instance.getClass().getName() + ", method=" + method + "]";
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
public synchronized <T> T getInterface(Class<T> policy)
|
|
{
|
|
ParameterCheck.mandatory("Policy class", policy);
|
|
Object proxy = proxies.get(policy);
|
|
if (proxy == null)
|
|
{
|
|
InvocationHandler handler = getInvocationHandler(instance, method, policy);
|
|
proxy = Proxy.newProxyInstance(policy.getClassLoader(), new Class[]{policy}, handler);
|
|
proxies.put(policy, proxy);
|
|
}
|
|
return (T)proxy;
|
|
}
|
|
|
|
/**
|
|
* Gets the Invocation Handler.
|
|
*
|
|
* @param <T> the policy interface class
|
|
* @param instance the object instance
|
|
* @param method the method name
|
|
* @param policyIF the policy interface class
|
|
* @return the invocation handler
|
|
*/
|
|
<T> InvocationHandler getInvocationHandler(Object instance, String method, Class<T> policyIF)
|
|
{
|
|
Method[] policyIFMethods = policyIF.getMethods();
|
|
if (policyIFMethods.length != 1)
|
|
{
|
|
throw new PolicyException("Policy interface " + policyIF.getCanonicalName() + " must have only one method");
|
|
}
|
|
|
|
try
|
|
{
|
|
Class instanceClass = instance.getClass();
|
|
Method delegateMethod = instanceClass.getMethod(method, (Class[])policyIFMethods[0].getParameterTypes());
|
|
return new JavaMethodInvocationHandler(this, delegateMethod);
|
|
}
|
|
catch (NoSuchMethodException e)
|
|
{
|
|
throw new PolicyException("Method " + method + " not found or accessible on " + instance.getClass(), e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Java Method Invocation Handler
|
|
*
|
|
* @author David Caruana
|
|
*/
|
|
private static class JavaMethodInvocationHandler implements InvocationHandler
|
|
{
|
|
private JavaBehaviour behaviour;
|
|
private Method delegateMethod;
|
|
|
|
/**
|
|
* Constuct.
|
|
*
|
|
* @param instance the object instance holding the method
|
|
* @param delegateMethod the method to invoke
|
|
*/
|
|
private JavaMethodInvocationHandler(JavaBehaviour behaviour, Method delegateMethod)
|
|
{
|
|
this.behaviour = behaviour;
|
|
this.delegateMethod = delegateMethod;
|
|
}
|
|
|
|
/* (non-Javadoc)
|
|
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
|
|
*/
|
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
|
|
{
|
|
// Handle Object level methods
|
|
if (method.getName().equals("toString"))
|
|
{
|
|
return toString();
|
|
}
|
|
else if (method.getName().equals("hashCode"))
|
|
{
|
|
return hashCode();
|
|
}
|
|
else if (method.getName().equals("equals"))
|
|
{
|
|
if (Proxy.isProxyClass(args[0].getClass()))
|
|
{
|
|
return equals(Proxy.getInvocationHandler(args[0]));
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Delegate to designated method pointer
|
|
if (behaviour.isEnabled())
|
|
{
|
|
try
|
|
{
|
|
behaviour.disable();
|
|
return delegateMethod.invoke(behaviour.instance, args);
|
|
}
|
|
catch (InvocationTargetException e)
|
|
{
|
|
throw e.getTargetException();
|
|
}
|
|
finally
|
|
{
|
|
behaviour.enable();
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object obj)
|
|
{
|
|
if (obj == this)
|
|
{
|
|
return true;
|
|
}
|
|
else if (obj == null || !(obj instanceof JavaMethodInvocationHandler))
|
|
{
|
|
return false;
|
|
}
|
|
JavaMethodInvocationHandler other = (JavaMethodInvocationHandler)obj;
|
|
return behaviour.instance.equals(other.behaviour.instance) && delegateMethod.equals(other.delegateMethod);
|
|
}
|
|
|
|
@Override
|
|
public int hashCode()
|
|
{
|
|
return 37 * behaviour.instance.hashCode() + delegateMethod.hashCode();
|
|
}
|
|
|
|
@Override
|
|
public String toString()
|
|
{
|
|
return "JavaBehaviour[instance=" + behaviour.instance.hashCode() + ", method=" + delegateMethod.toString() + "]";
|
|
}
|
|
}
|
|
|
|
}
|