[jboss-svn-commits] JBoss Common SVN: r4212 - invokablecontainer/trunk/api/src/main/java/org/jboss/invokable.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Wed Mar 31 23:08:39 EDT 2010
Author: david.lloyd at jboss.com
Date: 2010-03-31 23:08:38 -0400 (Wed, 31 Mar 2010)
New Revision: 4212
Added:
invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/InvocationProcessorFactory.java
invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/InvocationProcessors.java
invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/MethodIdentifier.java
Modified:
invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/Invocation.java
invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/InvocationProperties.java
invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/InvocationReply.java
invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/Keys.java
invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/ProcessingInvocationDispatcher.java
invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/ProxyInvocationHandler.java
Log:
More changes: add method identifier type which can be used as a hash key; invocation processor factory for assembly of interceptor chains
Modified: invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/Invocation.java
===================================================================
--- invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/Invocation.java 2010-03-30 21:51:51 UTC (rev 4211)
+++ invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/Invocation.java 2010-04-01 03:08:38 UTC (rev 4212)
@@ -43,75 +43,128 @@
/**
* This field contains the method-call arguments.
*/
- private transient final Object[] args;
-
+ private final Object[] args;
/**
- * This field specifies the target method.
+ * This field contains the declaring class of the method that was invoked.
*/
- private transient final Method targetMethod;
-
+ private final Class<?> declaringClass;
/**
- * This field contains the invocation context. As a special case, if the context is empty at serialization
+ * This field contains the identifier of the method which was invoked.
+ */
+ private final MethodIdentifier methodIdentifier;
+ /**
+ * This field contains the invocation properties. As a special case, if the properties is empty at serialization
* time, it is written as {@code null} to conserve bandwidth.
*/
private transient volatile InvocationProperties properties;
+ /**
+ * This field contains the target method of the invocation.
+ */
+ private transient final Method targetMethod;
private static final Object[] NO_OBJECTS = new Object[0];
- private static final Class<?>[] NO_CLASSES = new Class[0];
- private static final FieldSetter<Invocation> argsSetter = FieldSetter.forField(Invocation.class, "args");
private static final FieldSetter<Invocation> targetMethodSetter = FieldSetter.forField(Invocation.class, "targetMethod");
- private static final FieldSetter<Invocation> propertiesSetter = FieldSetter.forField(Invocation.class, "properties");
+ private Invocation(final InvocationProperties properties, final Class<?> declaringClass, final MethodIdentifier methodIdentifier, final Method targetMethod, final Object[] args) {
+ if (declaringClass == null) {
+ throw new IllegalArgumentException("declaringClass is null");
+ }
+ if (methodIdentifier == null) {
+ throw new IllegalArgumentException("methodIdentifier is null");
+ }
+ this.args = defaulted(args, NO_OBJECTS);
+ this.declaringClass = declaringClass;
+ this.methodIdentifier = methodIdentifier;
+ this.properties = defaulted(properties, InvocationProperties.EMPTY);
+ this.targetMethod = targetMethod;
+ }
+
+ private static Method methodFor(MethodIdentifier methodIdentifier, Class<?> declaringClass) throws IllegalArgumentException {
+ try {
+ return methodIdentifier.getPublicMethod(declaringClass);
+ } catch (NoSuchMethodException e) {
+ throw new IllegalArgumentException("Cannot find " + methodIdentifier + " on " + declaringClass);
+ }
+ }
+
/**
* Construct a new instance.
*
- * @param properties the invocation context to use
- * @param targetMethod the method being invoked
- * @param args the arguments
+ * @param properties the initial invocation properties
+ * @param declaringClass the declaring class of the invoked method
+ * @param methodIdentifier the identifier of the invoked method
+ * @param args the arguments of the original invocation
*/
- public Invocation(final InvocationProperties properties, final Method targetMethod, final Object... args) {
- if (targetMethod == null) {
- throw new IllegalArgumentException("targetMethod is null");
- }
- this.targetMethod = targetMethod;
- this.args = defaulted(args, NO_OBJECTS);
- this.properties = defaulted(properties, InvocationProperties.EMPTY);
+ public Invocation(final InvocationProperties properties, final Class<?> declaringClass, final MethodIdentifier methodIdentifier, final Object... args) {
+ this(properties, declaringClass, methodIdentifier, methodFor(methodIdentifier, declaringClass), args);
}
/**
* Construct a new instance.
*
- * @param targetMethod the method being invoked
- * @param args the arguments
+ * @param declaringClass the declaring class of the invoked method
+ * @param methodIdentifier the identifier of the invoked method
+ * @param args the arguments of the original invocation
*/
- public Invocation(final Method targetMethod, final Object... args) {
- this(InvocationProperties.EMPTY, targetMethod, args);
+ public Invocation(final Class<?> declaringClass, final MethodIdentifier methodIdentifier, final Object... args) {
+ this(null, declaringClass, methodIdentifier, (Object[]) args);
}
/**
* Construct a new instance with no arguments.
*
- * @param targetMethod the method being invoked
+ * @param declaringClass the declaring class of the invoked method
+ * @param methodIdentifier the identifier of the invoked method
*/
- public Invocation(final Method targetMethod) {
- this(InvocationProperties.EMPTY, targetMethod, NO_OBJECTS);
+ public Invocation(final Class<?> declaringClass, final MethodIdentifier methodIdentifier) {
+ this(null, declaringClass, methodIdentifier, (Object[]) null);
}
+ /**
+ * Construct a new instance.
+ *
+ * @param properties the initial invocation properties
+ * @param method the method which was invoked
+ * @param args the arguments of the original invocation
+ */
+ public Invocation(final InvocationProperties properties, final Method method, final Object... args) {
+ this(properties, method.getDeclaringClass(), MethodIdentifier.getIdentifierForMethod(method), method, args);
+ }
+
+ /**
+ * Construct a new instance.
+ *
+ * @param method the method which was invoked
+ * @param args the arguments of the original invocation
+ */
+ public Invocation(final Method method, final Object... args) {
+ this(null, method.getDeclaringClass(), MethodIdentifier.getIdentifierForMethod(method), method, args);
+ }
+
//-------------------------------------------------------------------------------------||
// Contracts --------------------------------------------------------------------------||
//-------------------------------------------------------------------------------------||
/**
- * Obtains the target method requested of the invocation.
+ * Get the declaring class of the method which was invoked.
*
- * @return the target method
+ * @return the declaring class
*/
- public Method getTargetMethod() {
- return targetMethod;
+ public Class<?> getDeclaringClass() {
+ return declaringClass;
}
/**
+ * Get the identifier of the method which was invoked.
+ *
+ * @return the identifier
+ */
+ public MethodIdentifier getMethodIdentifier() {
+ return methodIdentifier;
+ }
+
+ /**
* Returns the arguments to be passed along to this method invocation
*
* @return the method call arguments
@@ -139,48 +192,66 @@
this.properties = properties;
}
+ /**
+ * Get the target method which was invoked upon.
+ *
+ * @return the target method
+ */
+ public Method getTargetMethod() {
+ return targetMethod;
+ }
+
+ /**
+ * Get a string representation of this object.
+ *
+ * @return the string
+ */
+ public String toString() {
+ final StringBuilder b = new StringBuilder();
+ b.append("Invocation of ").append(methodIdentifier.toString()).append(" of ").append(declaringClass);
+ b.append(" with arguments (");
+ for (int i = 0; i < args.length; i++) {
+ b.append(args[i]);
+ if (i < args.length - 1) {
+ b.append(',');
+ }
+ }
+ b.append(')');
+ return b.toString();
+ }
+
//-------------------------------------------------------------------------------------||
// Serialization ----------------------------------------------------------------------||
//-------------------------------------------------------------------------------------||
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
- final Method targetMethod = this.targetMethod;
- oos.writeObject(targetMethod.getDeclaringClass());
- oos.writeUTF(targetMethod.getName());
- final Class<?>[] parameterTypes = targetMethod.getParameterTypes();
- oos.writeObject(parameterTypes.length == 0 ? null : parameterTypes);
- final Object[] args = this.args;
- oos.writeObject(args.length == 0 ? null : args);
final InvocationProperties properties = this.properties;
oos.writeObject(properties.isEmpty() ? null : properties);
}
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
ois.defaultReadObject();
- final Class<?> declaringClass = nonNull((Class<?>) ois.readObject());
- final String name = ois.readUTF();
- final Class<?>[] parameterTypes = defaulted((Class<?>[]) ois.readObject(), NO_CLASSES);
- final Method targetMethod;
+ if (properties == null) {
+ throw new InvalidObjectException("properties is null");
+ }
+ if (args == null) {
+ throw new InvalidObjectException("args is null");
+ }
+ if (methodIdentifier == null) {
+ throw new InvalidObjectException("methodIdentifier is null");
+ }
+ if (declaringClass == null) {
+ throw new InvalidObjectException("declaringClass is null");
+ }
+ properties = defaulted((InvocationProperties) ois.readObject(), InvocationProperties.EMPTY);
try {
- targetMethod = declaringClass.getMethod(name, parameterTypes);
+ targetMethodSetter.set(this, methodIdentifier.getPublicMethod(declaringClass));
} catch (NoSuchMethodException e) {
- throw new InvalidObjectException("Invocation references a missing method");
+ throw new InvalidObjectException("Cannot find " + methodIdentifier + " on " + declaringClass);
}
- targetMethodSetter.set(this, targetMethod);
- final Object[] args = defaulted((Object[]) ois.readObject(), NO_OBJECTS);
- argsSetter.set(this, args);
- final InvocationProperties properties = defaulted((InvocationProperties) ois.readObject(), InvocationProperties.EMPTY);
- propertiesSetter.set(this, properties);
}
- private static <T> T nonNull(T value) throws InvalidObjectException {
- if (value == null) {
- throw new InvalidObjectException("unexpected null value");
- }
- return value;
- }
-
private static <T> T defaulted(T value, T defaultValue) {
return value == null ? defaultValue : value;
}
Added: invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/InvocationProcessorFactory.java
===================================================================
--- invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/InvocationProcessorFactory.java (rev 0)
+++ invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/InvocationProcessorFactory.java 2010-04-01 03:08:38 UTC (rev 4212)
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt 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.invokable;
+
+/**
+ * A factory for invocation processors, used for assembling interceptor chains.
+ *
+ * @author <a href="mailto:david.lloyd at redhat.com">David M. Lloyd</a>
+ */
+public interface InvocationProcessorFactory {
+
+ /**
+ * Create an invocation processor.
+ *
+ * @param next the next-in-line processor
+ * @return the new invocation processor
+ */
+ InvocationProcessor createProcessor(InvocationProcessor next);
+}
Added: invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/InvocationProcessors.java
===================================================================
--- invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/InvocationProcessors.java (rev 0)
+++ invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/InvocationProcessors.java 2010-04-01 03:08:38 UTC (rev 4212)
@@ -0,0 +1,85 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt 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.invokable;
+
+import java.util.Iterator;
+
+/**
+ * Invocation processor utilities.
+ *
+ * @author <a href="mailto:david.lloyd at redhat.com">David M. Lloyd</a>
+ */
+public final class InvocationProcessors {
+
+ private InvocationProcessors() {
+ }
+
+ /**
+ * Create an invocation processor chain from a collection of factories. The last processor in the chain is always
+ * {@link org.jboss.invokable.InvocationProcessor#DISPATCHING}, and need not be specified.
+ *
+ * @param factories the factories
+ * @return the invocation processor
+ */
+ public static InvocationProcessor createInvocationProcessor(final Iterable<InvocationProcessorFactory> factories) {
+ return createInvocationProcessor(factories.iterator());
+ }
+
+ /**
+ * Create an invocation processor chain from a collection of factories.
+ *
+ * @param factories the factories
+ * @param last the last processor in the chain
+ * @return the invocation processor
+ */
+ public static InvocationProcessor createInvocationProcessor(final Iterable<InvocationProcessorFactory> factories, final InvocationProcessor last) {
+ return createInvocationProcessor(factories.iterator(), last);
+ }
+
+ /**
+ * Create an invocation processor chain from an iterator of factories. The last processor in the chain is always
+ * {@link org.jboss.invokable.InvocationProcessor#DISPATCHING}, and need not be specified.
+ *
+ * @param factories the factories
+ * @return the invocation processor
+ */
+ public static InvocationProcessor createInvocationProcessor(final Iterator<InvocationProcessorFactory> factories) {
+ return createInvocationProcessor(factories, InvocationProcessor.DISPATCHING);
+ }
+
+ /**
+ * Create an invocation processor chain from an iterator of factories.
+ *
+ * @param factories the factories
+ * @param last the last dispatcher in the chain
+ * @return the invocation processor
+ */
+ public static InvocationProcessor createInvocationProcessor(final Iterator<InvocationProcessorFactory> factories, final InvocationProcessor last) {
+ if (factories.hasNext()) {
+ final InvocationProcessorFactory factory = factories.next();
+ return factory.createProcessor(createInvocationProcessor(factories, last));
+ } else {
+ return last;
+ }
+ }
+}
Modified: invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/InvocationProperties.java
===================================================================
--- invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/InvocationProperties.java 2010-03-30 21:51:51 UTC (rev 4211)
+++ invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/InvocationProperties.java 2010-04-01 03:08:38 UTC (rev 4212)
@@ -54,12 +54,13 @@
private InvocationProperties(final Map<Object, Object> backingMap) {
this.backingMap = backingMap;
}
+
//-------------------------------------------------------------------------------------||
// Contracts --------------------------------------------------------------------------||
//-------------------------------------------------------------------------------------||
/**
- * Obtains the context property associated with the specified key, or null if not found
+ * Obtains the context property associated with the specified key, or {@code null} if not found
*
* @param key
*
@@ -75,7 +76,7 @@
}
/**
- * Obtains the context property associated with the specified key, or null if not found
+ * Obtains the context property associated with the specified key, or {@code null} if not found
*
* @param <T> Type of the object to be returned
* @param key
Modified: invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/InvocationReply.java
===================================================================
--- invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/InvocationReply.java 2010-03-30 21:51:51 UTC (rev 4211)
+++ invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/InvocationReply.java 2010-04-01 03:08:38 UTC (rev 4212)
@@ -26,39 +26,82 @@
import java.io.ObjectInputStream;
import java.io.Serializable;
+/**
+ * An invocation reply. Includes the return value, along with any attachments that may have been set along the way.
+ */
public final class InvocationReply implements Serializable {
private static final long serialVersionUID = 4330152364952496586L;
- private static final FieldSetter<InvocationReply> replySetter = FieldSetter.forField(InvocationReply.class, "reply");
-
- private transient final Object reply;
+ /**
+ * The method return value.
+ *
+ * @serial
+ */
+ private final Object reply;
+ /**
+ * The invocation properties.
+ */
private transient volatile InvocationProperties properties;
+ /**
+ * Construct a new instance.
+ *
+ * @param reply the reply
+ */
public InvocationReply(final Object reply) {
this.reply = reply;
}
+ /**
+ * Construct a new instance.
+ *
+ * @param reply the reply
+ * @param properties the initial invocation properties
+ */
public InvocationReply(final Object reply, final InvocationProperties properties) {
this.reply = reply;
this.properties = properties;
}
+ /**
+ * Get the reply.
+ *
+ * @return the reply
+ */
public Object getReply() {
return reply;
}
+ /**
+ * Get the invocation properties.
+ *
+ * @return the invocation properties
+ */
public InvocationProperties getProperties() {
return properties;
}
+ /**
+ * Replace the invocation properties.
+ *
+ * @param properties the invocation properties
+ */
public void setProperties(final InvocationProperties properties) {
this.properties = properties;
}
+ /**
+ * Get the string representation of this object.
+ *
+ * @return the string representation
+ */
+ public String toString() {
+ return "Invocation reply with value (" + reply + ")";
+ }
+
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
ois.defaultReadObject();
- replySetter.set(this, ois.readObject());
properties = defaulted((InvocationProperties) ois.readObject(), InvocationProperties.EMPTY);
}
Modified: invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/Keys.java
===================================================================
--- invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/Keys.java 2010-03-30 21:51:51 UTC (rev 4211)
+++ invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/Keys.java 2010-04-01 03:08:38 UTC (rev 4212)
@@ -30,12 +30,11 @@
public enum Keys {
/**
- * The security principal associated with the invocation. Should yield a value
- * of type {@link java.security.Principal}.
+ * The security principal associated with the invocation.
*/
PRINCIPAL,
/**
- * The transaction associated with this invocation. Should yield a {@link javax.transaction.Transaction} (?).
+ * The transaction associated with this invocation.
*/
TRANSACTION,
/**
Added: invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/MethodIdentifier.java
===================================================================
--- invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/MethodIdentifier.java (rev 0)
+++ invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/MethodIdentifier.java 2010-04-01 03:08:38 UTC (rev 4212)
@@ -0,0 +1,140 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt 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.invokable;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+/**
+ * A unique identification of a method within some class or interface. Suitable for usage as a hash table key.
+ *
+ * @author <a href="mailto:david.lloyd at redhat.com">David M. Lloyd</a>
+ */
+public final class MethodIdentifier implements Serializable {
+
+ private static final long serialVersionUID = -4303462176794600579L;
+
+ private static final FieldSetter<MethodIdentifier> hashCodeSetter = FieldSetter.forField(MethodIdentifier.class, "hashCode");
+
+ private final String name;
+ private final Class<?>[] parameterTypes;
+ private final transient int hashCode;
+
+ private static final Class<?>[] NO_CLASSES = new Class<?>[0];
+
+ private MethodIdentifier(final String name, final Class<?>... parameterTypes) {
+ if (name == null) {
+ throw new IllegalArgumentException("name is null");
+ }
+ if (parameterTypes == null) {
+ throw new IllegalArgumentException("parameterTypes is null");
+ }
+ this.name = name;
+ this.parameterTypes = parameterTypes == null || parameterTypes.length == 0 ? NO_CLASSES : parameterTypes.clone();
+ hashCode = calculateHash(name, parameterTypes);
+ }
+
+ private MethodIdentifier(final Method method) {
+ final String name = (this.name = method.getName());
+ final Class<?>[] methodParameterTypes = method.getParameterTypes();
+ final Class<?>[] parameterTypes = (this.parameterTypes = methodParameterTypes.length == 0 ? NO_CLASSES : methodParameterTypes);
+ hashCode = calculateHash(name, parameterTypes);
+ }
+
+ private static int calculateHash(final String name, final Class<?>[] parameterTypes) {
+ return name.hashCode() * 7 + Arrays.hashCode(parameterTypes);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Class<?>[] getParameterTypes() {
+ return parameterTypes.clone();
+ }
+
+ public boolean equals(final Object o) {
+ return o instanceof MethodIdentifier && equals((MethodIdentifier) o);
+ }
+
+ public boolean equals(final MethodIdentifier o) {
+ return o == this || o != null && name.equals(o.name) && Arrays.equals(parameterTypes, o.parameterTypes);
+ }
+
+ public int hashCode() {
+ return hashCode;
+ }
+
+ public Method getPublicMethod(final Class<?> clazz) throws NoSuchMethodException {
+ return clazz.getMethod(name, parameterTypes);
+ }
+
+ private static void appendType(final Class<?> type, final StringBuilder b) {
+ if (type.isPrimitive()) {
+ b.append(type.getName());
+ } else if (type.isArray()) {
+ b.append('[');
+ appendType(type, b);
+ } else {
+ b.append('L').append(type.getName().replace('.', '/')).append(';');
+ }
+ }
+
+ public String toString() {
+ final StringBuilder b = new StringBuilder();
+ b.append("Method ").append(name).append('(');
+ for (Class<?> type : parameterTypes) {
+ appendType(type, b);
+ }
+ return b.append(')').toString();
+ }
+
+ private void readObject(final ObjectInputStream ois) throws ClassNotFoundException, IOException {
+ ois.defaultReadObject();
+ hashCodeSetter.setInt(this, calculateHash(name, parameterTypes));
+ }
+
+ public static MethodIdentifier getIdentifierForMethod(final Method method) throws IllegalArgumentException {
+ return new MethodIdentifier(method);
+ }
+
+ public static MethodIdentifier getIdentifier(final String name, final Class<?>... parameterTypes) {
+ return new MethodIdentifier(name, parameterTypes);
+ }
+
+ /**
+ * The method identifier for {@code Object.equals()}.
+ */
+ public static final MethodIdentifier EQUALS = getIdentifier("equals", Object.class);
+ /**
+ * The method identifier for {@code Object.hashCode()}.
+ */
+ public static final MethodIdentifier HASH_CODE = getIdentifier("hashCode");
+ /**
+ * The method identifier for {@code Object.toString()}.
+ */
+ public static final MethodIdentifier TO_STRING = getIdentifier("toString");
+}
Modified: invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/ProcessingInvocationDispatcher.java
===================================================================
--- invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/ProcessingInvocationDispatcher.java 2010-03-30 21:51:51 UTC (rev 4211)
+++ invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/ProcessingInvocationDispatcher.java 2010-04-01 03:08:38 UTC (rev 4212)
@@ -71,6 +71,7 @@
return processor.processInvocation(dispatcher, invocation);
}
+ /** {@inheritDoc} */
public <I> void accept(final Visitor<InvocationDispatcher, I> visitor, final I param) {
visitor.visit(this, param);
dispatcher.accept(visitor, param);
Modified: invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/ProxyInvocationHandler.java
===================================================================
--- invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/ProxyInvocationHandler.java 2010-03-30 21:51:51 UTC (rev 4211)
+++ invokablecontainer/trunk/api/src/main/java/org/jboss/invokable/ProxyInvocationHandler.java 2010-04-01 03:08:38 UTC (rev 4212)
@@ -72,14 +72,21 @@
* @throws Throwable the exception to thrown from the method invocation on the proxy instance, if any
*/
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
- try {
- return processor.processInvocation(dispatcher, new Invocation(method, args));
+ final MethodIdentifier id = MethodIdentifier.getIdentifierForMethod(method);
+ if (id.equals(MethodIdentifier.EQUALS)) {
+ return Boolean.valueOf(proxy.equals(args[0]));
+ } else if (id.equals(MethodIdentifier.HASH_CODE)) {
+ return Integer.valueOf(System.identityHashCode(proxy));
+ } else if (id.equals(MethodIdentifier.TO_STRING)) {
+ return "Proxy via " + dispatcher;
+ } else try {
+ return processor.processInvocation(dispatcher, new Invocation(method.getDeclaringClass(), id, (Object[]) args));
} catch (InvocationException e) {
throw e.getCause();
}
}
- private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
+ private void readObject(final ObjectInputStream ois) throws ClassNotFoundException, IOException {
ois.defaultReadObject();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
More information about the jboss-svn-commits
mailing list