diff options
Diffstat (limited to '')
-rw-r--r-- | sca-java-2.x/branches/2.0-Beta2/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKInvocationHandler.java | 390 |
1 files changed, 0 insertions, 390 deletions
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKInvocationHandler.java b/sca-java-2.x/branches/2.0-Beta2/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKInvocationHandler.java deleted file mode 100644 index afdad37e2d..0000000000 --- a/sca-java-2.x/branches/2.0-Beta2/modules/core/src/main/java/org/apache/tuscany/sca/core/invocation/impl/JDKInvocationHandler.java +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. - */ - -package org.apache.tuscany.sca.core.invocation.impl; - -import java.io.Serializable; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.IdentityHashMap; -import java.util.List; -import java.util.Map; - -import javax.xml.ws.Holder; - -import org.apache.tuscany.sca.assembly.Endpoint; -import org.apache.tuscany.sca.context.ThreadMessageContext; -import org.apache.tuscany.sca.core.context.ServiceReferenceExt; -import org.apache.tuscany.sca.interfacedef.DataType; -import org.apache.tuscany.sca.interfacedef.Operation; -import org.apache.tuscany.sca.interfacedef.java.JavaOperation; -import org.apache.tuscany.sca.invocation.InvocationChain; -import org.apache.tuscany.sca.invocation.Invoker; -import org.apache.tuscany.sca.invocation.Message; -import org.apache.tuscany.sca.invocation.MessageFactory; -import org.apache.tuscany.sca.runtime.Invocable; -import org.apache.tuscany.sca.runtime.RuntimeEndpoint; -import org.apache.tuscany.sca.runtime.RuntimeEndpointReference; -import org.oasisopen.sca.ServiceReference; -import org.oasisopen.sca.ServiceRuntimeException; - -/** - * @version $Rev$ $Date$ - */ -public class JDKInvocationHandler implements InvocationHandler, Serializable { - private static final long serialVersionUID = -3366410500152201371L; - - protected MessageFactory messageFactory; - protected Endpoint target; - protected Invocable source; - protected ServiceReferenceExt<?> callableReference; - protected Class<?> businessInterface; - - protected boolean fixedWire = true; - - protected transient Map<Method, InvocationChain> chains = new IdentityHashMap<Method, InvocationChain>(); - - public JDKInvocationHandler(MessageFactory messageFactory, Class<?> businessInterface, Invocable source) { - this.messageFactory = messageFactory; - this.source = source; - this.businessInterface = businessInterface; - } - - public JDKInvocationHandler(MessageFactory messageFactory, ServiceReference<?> callableReference) { - this.messageFactory = messageFactory; - this.callableReference = (ServiceReferenceExt<?>)callableReference; - if (callableReference != null) { - this.businessInterface = callableReference.getBusinessInterface(); - this.source = (RuntimeEndpointReference) this.callableReference.getEndpointReference(); - } - } - - - public Class<?> getBusinessInterface() { - return businessInterface; - } - - protected Object getCallbackID() { - return null; - } - - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - if (Object.class == method.getDeclaringClass()) { - return invokeObjectMethod(method, args); - } - if (source == null) { - throw new ServiceRuntimeException("No runtime source is available"); - } - - if (source instanceof RuntimeEndpointReference) { - RuntimeEndpointReference epr = (RuntimeEndpointReference)source; - if (epr.isOutOfDate()) { - epr.rebuild(); - chains.clear(); - } - } - - InvocationChain chain = getInvocationChain(method, source); - - if (chain == null) { - throw new IllegalArgumentException("No matching operation is found: " + method); - } - - // Holder pattern. Items stored in a Holder<T> are promoted to T. - // After the invoke, the returned data <T> are placed back in Holder<T>. - Object [] promotedArgs = promoteHolderArgs( args ); - - Object result = invoke(chain, promotedArgs, source); - - // Returned Holder data <T> are placed back in Holder<T>. - boolean holderPattern = false; - Class [] parameters = method.getParameterTypes(); - if ( parameters != null ) { - for ( int i = 0, resultIdx = 0; i < parameters.length; i++ ) { - Class parameterType = parameters[ i ]; - if ( isHolder( parameterType ) ) { - holderPattern = true; - // Pop results and place in holder (demote). - Holder holder = (Holder) args[ i ]; - - Object[] results = (Object[])result; - if ( result != null ) { - holder.value = results[++resultIdx]; - } - } - } - } - if ( holderPattern && result != null) - return ((Object[])result)[0]; - else - return result; - } - - /** - * Handle the methods on the Object.class - * @param method - * @param args - */ - protected Object invokeObjectMethod(Method method, Object[] args) throws Throwable { - String name = method.getName(); - if ("toString".equals(name)) { - return "[Proxy - " + toString() + "]"; - } else if ("equals".equals(name)) { - Object obj = args[0]; - if (obj == null) { - return false; - } - if (!Proxy.isProxyClass(obj.getClass())) { - return false; - } - return equals(Proxy.getInvocationHandler(obj)); - } else if ("hashCode".equals(name)) { - return hashCode(); - } else { - return method.invoke(this); - } - } - - /** - * Determines if the given operation matches the given method - * - * @return true if the operation matches, false if does not - */ - // FIXME: Should it be in the InterfaceContractMapper? - @SuppressWarnings("unchecked") - private static boolean match(Operation operation, Method method) { - if (operation instanceof JavaOperation) { - JavaOperation javaOp = (JavaOperation)operation; - Method m = javaOp.getJavaMethod(); - if (!method.getName().equals(m.getName())) { - return false; - } - if (method.equals(m)) { - return true; - } - } else { - if (!method.getName().equals(operation.getName())) { - return false; - } - } - - // For remotable interface, operation is not overloaded. - if (operation.getInterface().isRemotable()) { - return true; - } - - Class<?>[] params = method.getParameterTypes(); - - DataType<List<DataType>> inputType = null; - if (operation.isWrapperStyle()) { - inputType = operation.getWrapper().getUnwrappedInputType(); - } else { - inputType = operation.getInputType(); - } - List<DataType> types = inputType.getLogical(); - boolean matched = true; - if (types.size() == params.length && method.getName().equals(operation.getName())) { - for (int i = 0; i < params.length; i++) { - Class<?> clazz = params[i]; - Class<?> type = types.get(i).getPhysical(); - // Object.class.isAssignableFrom(int.class) returns false - if (type != Object.class && (!type.isAssignableFrom(clazz))) { - matched = false; - } - } - } else { - matched = false; - } - return matched; - - } - - protected synchronized InvocationChain getInvocationChain(Method method, Invocable source) { - if (source instanceof RuntimeEndpoint) { - InvocationChain invocationChain = source.getBindingInvocationChain(); - for (InvocationChain chain : source.getInvocationChains()) { - Operation operation = chain.getTargetOperation(); - if (method.getName().equals(operation.getName())) { - invocationChain.setTargetOperation(operation); - } - } - return source.getBindingInvocationChain(); - } - if (fixedWire && chains.containsKey(method)) { - return chains.get(method); - } - InvocationChain found = null; - for (InvocationChain chain : source.getInvocationChains()) { - Operation operation = chain.getSourceOperation(); - if (operation.isDynamic()) { - operation.setName(method.getName()); - found = chain; - break; - } else if (match(operation, method)) { - found = chain; - break; - } - } - if (fixedWire) { - chains.put(method, found); - } - return found; - } - - protected void setEndpoint(Endpoint endpoint) { - this.target = endpoint; - } - - protected Object invoke(InvocationChain chain, Object[] args, Invocable source) - throws Throwable { - return invoke( chain, args, source, null ); - } - - /** - * Invoke the chain - * @param chain - the chain - * @param args - arguments to the invocation as an array of Objects - * @param source - the Endpoint or EndpointReference to which the chain relates - * @param msgID - an ID for the message being sent, may be null - * @return - the Response message from the invocation - * @throws Throwable - if any exception occurs during the invocation - */ - protected Object invoke(InvocationChain chain, Object[] args, Invocable source, String msgID) - throws Throwable { - Message msg = messageFactory.createMessage(); - if (source instanceof RuntimeEndpointReference) { - msg.setFrom((RuntimeEndpointReference)source); - } - if (target != null) { - msg.setTo(target); - } else { - if (source instanceof RuntimeEndpointReference) { - msg.setTo(((RuntimeEndpointReference)source).getTargetEndpoint()); - } - } - Invoker headInvoker = chain.getHeadInvoker(); - Operation operation = chain.getTargetOperation(); - msg.setOperation(operation); - msg.setBody(args); - - Message msgContext = ThreadMessageContext.getMessageContext(); - - // Deal with header information that needs to be copied from the message context to the new message... - transferMessageHeaders( msg, msgContext); - - ThreadMessageContext.setMessageContext(msg); - - // If there is a supplied message ID, place its value into the Message Header under "MESSAGE_ID" - if( msgID != null ){ - msg.getHeaders().put("MESSAGE_ID", msgID); - } // end if - - try { - // dispatch the source down the chain and get the response - Message resp = headInvoker.invoke(msg); - Object body = resp.getBody(); - if (resp.isFault()) { - throw (Throwable)body; - } - return body; - } finally { - ThreadMessageContext.setMessageContext(msgContext); - } - } - - /** - * Transfer relevant header information from the old message (incoming) to the new message (outgoing) - * @param newMsg - * @param oldMsg - */ - private void transferMessageHeaders( Message newMsg, Message oldMsg ) { - if( oldMsg == null ) return; - // For the present, simply copy all the headers - if( !oldMsg.getHeaders().isEmpty() ) newMsg.getHeaders().putAll( oldMsg.getHeaders() ); - } // end transferMessageHeaders - - /** - * @return the callableReference - */ - public ServiceReference<?> getCallableReference() { - return callableReference; - } - - /** - * @param callableReference the callableReference to set - */ - public void setCallableReference(ServiceReference<?> callableReference) { - this.callableReference = (ServiceReferenceExt<?>)callableReference; - } - - /** - * Creates a copy of arguments. Holder<T> values are promoted to T. - * Note. It is essential that arg Holders not be destroyed here. - * PromotedArgs should not destroy holders. They are used on response return. - * @param args containing Holders and other objects. - * @return Object [] - */ - protected static Object [] promoteHolderArgs( Object [] args ) { - if ( args == null ) - return args; - Object [] promotedArgs = new Object[ args.length ]; - - for ( int i = 0; i < args.length; i++ ) { - Object argument = args[ i ]; - if ( argument != null ) { - if ( isHolder( argument ) ) { - promotedArgs[ i ] = ((Holder)argument).value; - } else { - promotedArgs[ i ] = args[ i ]; - } - - } - } - return promotedArgs; - } - - /** - * Given a Class, tells if it is a Holder by comparing to "javax.xml.ws.Holder" - * @param testClass - * @return boolean whether class is Holder type. - */ - protected static boolean isHolder( Class testClass ) { - if ( testClass.getName().startsWith( "javax.xml.ws.Holder" )) { - return true; - } - return false; - } - - - /** - * Given an Object, tells if it is a Holder by comparing to "javax.xml.ws.Holder" - * @param testClass - * @return boolean stating whether Object is a Holder type. - * @author DOB - */ - protected static boolean isHolder( Object object ) { - String objectName = object.getClass().getName(); - if ( object instanceof javax.xml.ws.Holder ) { - return true; - } - return false; - } - -} |