Repository: cxf-dosgi Updated Branches: refs/heads/master 951f7c8db -> ccf5a7a73
[DOSGI-242] Prepare split of jaxws and jaxrs support Project: http://git-wip-us.apache.org/repos/asf/cxf-dosgi/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf-dosgi/commit/ccf5a7a7 Tree: http://git-wip-us.apache.org/repos/asf/cxf-dosgi/tree/ccf5a7a7 Diff: http://git-wip-us.apache.org/repos/asf/cxf-dosgi/diff/ccf5a7a7 Branch: refs/heads/master Commit: ccf5a7a73be73c8549c2e199ac104b2d81f7260c Parents: 951f7c8 Author: Christian Schneider <[email protected]> Authored: Mon Jul 4 09:32:59 2016 +0200 Committer: Christian Schneider <[email protected]> Committed: Mon Jul 4 09:32:59 2016 +0200 ---------------------------------------------------------------------- common/bnd.bnd | 3 +- common/pom.xml | 20 +-- .../cxf/dosgi/common/proxy/ProxyFactory.java | 32 +++++ .../common/proxy/ServiceInvocationHandler.java | 102 +++++++++++++++ .../proxy/ServiceInvocationHandlerTest.java | 75 +++++++++++ .../AbstractPojoConfigurationTypeHandler.java | 125 +------------------ .../dsw/handlers/pojo/InterceptorSupport.java | 63 ++++++++++ .../pojo/PojoConfigurationTypeHandler.java | 7 +- .../handlers/pojo/ServiceInvocationHandler.java | 100 --------------- .../pojo/WsdlConfigurationTypeHandler.java | 11 +- .../dosgi/dsw/handlers/pojo/WsdlSupport.java | 83 ++++++++++++ .../rest/JaxRSPojoConfigurationTypeHandler.java | 75 +++++++++-- .../handlers/ServiceInvocationHandlerTest.java | 77 ------------ 13 files changed, 441 insertions(+), 332 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/ccf5a7a7/common/bnd.bnd ---------------------------------------------------------------------- diff --git a/common/bnd.bnd b/common/bnd.bnd index b5ec91c..5bee711 100644 --- a/common/bnd.bnd +++ b/common/bnd.bnd @@ -2,5 +2,6 @@ Import-Package: javax.servlet;version='[2,4)', javax.servlet.http;version='[2,4) Export-Package: \ org.apache.cxf.dosgi.common.httpservice,\ org.apache.cxf.dosgi.common.util,\ - org.apache.cxf.dosgi.common.intent + org.apache.cxf.dosgi.common.intent,\ + org.apache.cxf.dosgi.common.proxy http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/ccf5a7a7/common/pom.xml ---------------------------------------------------------------------- diff --git a/common/pom.xml b/common/pom.xml index dd5ea46..952f2c1 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -44,30 +44,14 @@ </dependency> <dependency> <groupId>org.apache.cxf</groupId> - <artifactId>cxf-rt-frontend-jaxws</artifactId> - <version>${cxf.version}</version> - </dependency> - <dependency> - <groupId>org.apache.cxf</groupId> - <artifactId>cxf-rt-frontend-jaxrs</artifactId> - <version>${cxf.version}</version> - </dependency> - <dependency> - <groupId>org.apache.cxf</groupId> - <artifactId>cxf-rt-rs-client</artifactId> + <artifactId>cxf-rt-transports-http</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> - <artifactId>cxf-rt-databinding-aegis</artifactId> - <version>${cxf.version}</version> - </dependency> - <dependency> - <groupId>org.apache.cxf</groupId> - <artifactId>cxf-rt-rs-extension-providers</artifactId> + <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>${cxf.version}</version> </dependency> - <dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-servlet_${servlet.version}_spec</artifactId> http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/ccf5a7a7/common/src/main/java/org/apache/cxf/dosgi/common/proxy/ProxyFactory.java ---------------------------------------------------------------------- diff --git a/common/src/main/java/org/apache/cxf/dosgi/common/proxy/ProxyFactory.java b/common/src/main/java/org/apache/cxf/dosgi/common/proxy/ProxyFactory.java new file mode 100644 index 0000000..ec10f6e --- /dev/null +++ b/common/src/main/java/org/apache/cxf/dosgi/common/proxy/ProxyFactory.java @@ -0,0 +1,32 @@ +/** + * 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.cxf.dosgi.common.proxy; + +import java.lang.reflect.Proxy; + +public final class ProxyFactory { + private ProxyFactory() { + } + + public static Object create(Object serviceProxy, Class<?> iType) { + return Proxy.newProxyInstance(iType.getClassLoader(), new Class[] { + iType + }, new ServiceInvocationHandler(serviceProxy, iType)); + } +} http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/ccf5a7a7/common/src/main/java/org/apache/cxf/dosgi/common/proxy/ServiceInvocationHandler.java ---------------------------------------------------------------------- diff --git a/common/src/main/java/org/apache/cxf/dosgi/common/proxy/ServiceInvocationHandler.java b/common/src/main/java/org/apache/cxf/dosgi/common/proxy/ServiceInvocationHandler.java new file mode 100644 index 0000000..c86b700 --- /dev/null +++ b/common/src/main/java/org/apache/cxf/dosgi/common/proxy/ServiceInvocationHandler.java @@ -0,0 +1,102 @@ +/** + * 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.cxf.dosgi.common.proxy; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.security.AccessController; +import java.security.PrivilegedExceptionAction; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.osgi.framework.ServiceException; + +public class ServiceInvocationHandler implements InvocationHandler { + + private static final String REMOTE_EXCEPTION_TYPE = "REMOTE"; + private static final Collection<Method> OBJECT_METHODS = Arrays.asList(Object.class.getMethods()); + + private Map<Method, List<Class<?>>> exceptionsMap = new HashMap<Method, List<Class<?>>>(); + private Object serviceObject; + + ServiceInvocationHandler(Object serviceObject, Class<?> iType) { + this.serviceObject = serviceObject; + introspectType(iType); + } + + + + public Object invoke(Object proxy, final Method m, Object[] params) throws Throwable { + if (OBJECT_METHODS.contains(m)) { + if (m.getName().equals("equals")) { + params = new Object[] {Proxy.getInvocationHandler(params[0])}; + } + return m.invoke(this, params); + } + + ClassLoader oldCl = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); + final Object[] paramsFinal = params; + return AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { + public Object run() throws Exception { + return m.invoke(serviceObject, paramsFinal); + } + }); + } catch (Throwable ex) { + Throwable theCause = ex.getCause() == null ? ex : ex.getCause(); + Throwable theCauseCause = theCause.getCause() == null ? theCause : theCause.getCause(); + List<Class<?>> excTypes = exceptionsMap.get(m); + if (excTypes != null) { + for (Class<?> type : excTypes) { + if (type.isAssignableFrom(theCause.getClass())) { + throw theCause; + } + if (type.isAssignableFrom(theCauseCause.getClass())) { + throw theCauseCause; + } + } + } + + throw new ServiceException(REMOTE_EXCEPTION_TYPE, theCause); + } finally { + Thread.currentThread().setContextClassLoader(oldCl); + } + } + + private void introspectType(Class<?> iType) { + for (Method m : iType.getDeclaredMethods()) { + for (Class<?> excType : m.getExceptionTypes()) { + if (Exception.class.isAssignableFrom(excType)) { + List<Class<?>> types = exceptionsMap.get(m); + if (types == null) { + types = new ArrayList<Class<?>>(); + exceptionsMap.put(m, types); + } + types.add(excType); + } + } + } + } +} http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/ccf5a7a7/common/src/test/java/org/apache/cxf/dosgi/common/proxy/ServiceInvocationHandlerTest.java ---------------------------------------------------------------------- diff --git a/common/src/test/java/org/apache/cxf/dosgi/common/proxy/ServiceInvocationHandlerTest.java b/common/src/test/java/org/apache/cxf/dosgi/common/proxy/ServiceInvocationHandlerTest.java new file mode 100644 index 0000000..92cdc75 --- /dev/null +++ b/common/src/test/java/org/apache/cxf/dosgi/common/proxy/ServiceInvocationHandlerTest.java @@ -0,0 +1,75 @@ +/** + * 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.cxf.dosgi.common.proxy; + +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +public class ServiceInvocationHandlerTest extends TestCase { + + private static final Map<String, Method> OBJECT_METHODS = new HashMap<String, Method>(); { + for (Method m : Object.class.getMethods()) { + OBJECT_METHODS.put(m.getName(), m); + } + } + + public void testInvoke() throws Throwable { + ServiceInvocationHandler sih = new ServiceInvocationHandler("hello", String.class); + Method m = String.class.getMethod("length", new Class[] {}); + assertEquals(5, sih.invoke(null, m, new Object[] {})); + } + + public void testInvokeObjectMethod() throws Throwable { + final List<String> called = new ArrayList<String>(); + ServiceInvocationHandler sih = new ServiceInvocationHandler("hi", String.class) { + public boolean equals(Object obj) { + called.add("equals"); + return super.equals(obj); + } + + public int hashCode() { + called.add("hashCode"); + return super.hashCode(); + } + + public String toString() { + called.add("toString"); + return "somestring"; + } + }; + + Object proxy = Proxy.newProxyInstance( + getClass().getClassLoader(), new Class[] {Runnable.class}, sih); + + assertEquals(true, + sih.invoke(null, OBJECT_METHODS.get("equals"), new Object[] {proxy})); + assertEquals(System.identityHashCode(sih), + sih.invoke(null, OBJECT_METHODS.get("hashCode"), new Object[] {})); + assertEquals("somestring", + sih.invoke(null, OBJECT_METHODS.get("toString"), new Object[] {})); + assertEquals(Arrays.asList("equals", "hashCode", "toString"), called); + } +} http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/ccf5a7a7/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/AbstractPojoConfigurationTypeHandler.java ---------------------------------------------------------------------- diff --git a/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/AbstractPojoConfigurationTypeHandler.java b/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/AbstractPojoConfigurationTypeHandler.java index 50baf0a..363b843 100644 --- a/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/AbstractPojoConfigurationTypeHandler.java +++ b/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/AbstractPojoConfigurationTypeHandler.java @@ -18,35 +18,24 @@ */ package org.apache.cxf.dosgi.dsw.handlers.pojo; -import java.lang.reflect.Proxy; -import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; -import javax.xml.namespace.QName; - import org.apache.aries.rsa.spi.DistributionProvider; import org.apache.aries.rsa.spi.Endpoint; import org.apache.cxf.Bus; import org.apache.cxf.BusFactory; -import org.apache.cxf.common.util.PackageUtils; import org.apache.cxf.dosgi.common.httpservice.HttpServiceManager; import org.apache.cxf.dosgi.common.intent.IntentManager; -import org.apache.cxf.dosgi.common.util.ClassUtils; import org.apache.cxf.dosgi.common.util.OsgiUtils; import org.apache.cxf.dosgi.common.util.ServerWrapper; import org.apache.cxf.dosgi.common.util.StringPlus; import org.apache.cxf.dosgi.dsw.osgi.Constants; import org.apache.cxf.endpoint.AbstractEndpointFactory; import org.apache.cxf.endpoint.Server; -import org.apache.cxf.feature.AbstractFeature; -import org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory; -import org.apache.cxf.frontend.ClientFactoryBean; import org.apache.cxf.frontend.ServerFactoryBean; -import org.apache.cxf.helpers.CastUtils; -import org.apache.cxf.interceptor.Interceptor; import org.osgi.framework.BundleContext; import org.osgi.service.remoteserviceadmin.EndpointDescription; import org.osgi.service.remoteserviceadmin.RemoteConstants; @@ -63,12 +52,6 @@ public abstract class AbstractPojoConfigurationTypeHandler implements Distributi this.httpServiceManager = httpServiceManager; } - protected Object getProxy(Object serviceProxy, Class<?> iType) { - return Proxy.newProxyInstance(iType.getClassLoader(), new Class[] { - iType - }, new ServiceInvocationHandler(serviceProxy, iType)); - } - protected EndpointDescription createEndpointDesc(Map<String, Object> props, String[] importedConfigs, String address, @@ -77,8 +60,6 @@ public abstract class AbstractPojoConfigurationTypeHandler implements Distributi for (String configurationType : importedConfigs) { if (Constants.WS_CONFIG_TYPE.equals(configurationType)) { props.put(Constants.WS_ADDRESS_PROPERTY, address); - } else if (Constants.RS_CONFIG_TYPE.equals(configurationType)) { - props.put(Constants.RS_ADDRESS_PROPERTY, address); } else if (Constants.WS_CONFIG_TYPE_OLD.equals(configurationType)) { props.put(Constants.WS_ADDRESS_PROPERTY_OLD, address); props.put(Constants.WS_ADDRESS_PROPERTY, address); @@ -110,62 +91,6 @@ public abstract class AbstractPojoConfigurationTypeHandler implements Distributi return list.toArray(new String[list.size()]); } - protected void setCommonWsdlProperties(AbstractWSDLBasedEndpointFactory factory, BundleContext context, - Map<String, Object> sd, boolean wsdlType) { - String location = OsgiUtils.getProperty(sd, wsdlType ? Constants.WSDL_LOCATION : Constants.WS_WSDL_LOCATION); - if (location != null) { - URL wsdlURL = context.getBundle().getResource(location); - if (wsdlURL != null) { - factory.setWsdlURL(wsdlURL.toString()); - } - QName serviceName = getServiceQName(null, sd, - wsdlType ? Constants.WSDL_SERVICE_NAMESPACE : Constants.WS_WSDL_SERVICE_NAMESPACE, - wsdlType ? Constants.WSDL_SERVICE_NAME : Constants.WS_WSDL_SERVICE_NAME); - if (serviceName != null) { - factory.setServiceName(serviceName); - QName portName = getPortQName(serviceName.getNamespaceURI(), sd, - wsdlType ? Constants.WSDL_PORT_NAME : Constants.WS_WSDL_PORT_NAME); - if (portName != null) { - factory.setEndpointName(portName); - } - } - } - } - - protected void setWsdlProperties(ServerFactoryBean factory, BundleContext callingContext, Map<String, Object> sd, - boolean wsdlType) { - setCommonWsdlProperties(factory, callingContext, sd, wsdlType); - } - - protected void setClientWsdlProperties(ClientFactoryBean factory, BundleContext dswContext, Map<String, Object> sd, - boolean wsdlType) { - setCommonWsdlProperties(factory, dswContext, sd, wsdlType); - } - - protected static QName getServiceQName(Class<?> iClass, Map<String, Object> sd, String nsPropName, - String namePropName) { - String serviceNs = OsgiUtils.getProperty(sd, nsPropName); - String serviceName = OsgiUtils.getProperty(sd, namePropName); - if (iClass == null && (serviceNs == null || serviceName == null)) { - return null; - } - if (serviceNs == null) { - serviceNs = PackageUtils.getNamespace(PackageUtils.getPackageName(iClass)); - } - if (serviceName == null) { - serviceName = iClass.getSimpleName(); - } - return new QName(serviceNs, serviceName); - } - - protected static QName getPortQName(String ns, Map<String, Object> sd, String propName) { - String portName = OsgiUtils.getProperty(sd, propName); - if (portName == null) { - return null; - } - return new QName(ns, portName); - } - protected String getClientAddress(Map<String, Object> sd) { return OsgiUtils.getFirstNonEmptyStringProperty(sd, RemoteConstants.ENDPOINT_ID, Constants.WS_ADDRESS_PROPERTY, @@ -185,7 +110,6 @@ public abstract class AbstractPojoConfigurationTypeHandler implements Distributi Constants.WSDL_HTTP_SERVICE_CONTEXT, Constants.RS_HTTP_SERVICE_CONTEXT); } - protected Bus createBus(Long sid, BundleContext callingContext, String contextRoot) { Bus bus = BusFactory.newInstance().createBus(); @@ -208,53 +132,14 @@ public abstract class AbstractPojoConfigurationTypeHandler implements Distributi protected static void addWsInterceptorsFeaturesProps(AbstractEndpointFactory factory, BundleContext callingContext, Map<String, Object> sd) { - addInterceptors(factory, callingContext, sd, Constants.WS_IN_INTERCEPTORS_PROP_KEY); - addInterceptors(factory, callingContext, sd, Constants.WS_OUT_INTERCEPTORS_PROP_KEY); - addInterceptors(factory, callingContext, sd, Constants.WS_OUT_FAULT_INTERCEPTORS_PROP_KEY); - addInterceptors(factory, callingContext, sd, Constants.WS_IN_FAULT_INTERCEPTORS_PROP_KEY); - addFeatures(factory, callingContext, sd, Constants.WS_FEATURES_PROP_KEY); + InterceptorSupport.addInterceptors(factory, callingContext, sd, Constants.WS_IN_INTERCEPTORS_PROP_KEY); + InterceptorSupport.addInterceptors(factory, callingContext, sd, Constants.WS_OUT_INTERCEPTORS_PROP_KEY); + InterceptorSupport.addInterceptors(factory, callingContext, sd, Constants.WS_OUT_FAULT_INTERCEPTORS_PROP_KEY); + InterceptorSupport.addInterceptors(factory, callingContext, sd, Constants.WS_IN_FAULT_INTERCEPTORS_PROP_KEY); + InterceptorSupport.addFeatures(factory, callingContext, sd, Constants.WS_FEATURES_PROP_KEY); addContextProperties(factory, sd, Constants.WS_CONTEXT_PROPS_PROP_KEY); } - protected static void addRsInterceptorsFeaturesProps(AbstractEndpointFactory factory, BundleContext callingContext, - Map<String, Object> sd) { - addInterceptors(factory, callingContext, sd, Constants.RS_IN_INTERCEPTORS_PROP_KEY); - addInterceptors(factory, callingContext, sd, Constants.RS_OUT_INTERCEPTORS_PROP_KEY); - addInterceptors(factory, callingContext, sd, Constants.RS_OUT_FAULT_INTERCEPTORS_PROP_KEY); - addInterceptors(factory, callingContext, sd, Constants.RS_IN_FAULT_INTERCEPTORS_PROP_KEY); - addFeatures(factory, callingContext, sd, Constants.RS_FEATURES_PROP_KEY); - addContextProperties(factory, sd, Constants.RS_CONTEXT_PROPS_PROP_KEY); - } - - private static void addInterceptors(AbstractEndpointFactory factory, BundleContext callingContext, - Map<String, Object> sd, String propName) { - List<Object> providers = ClassUtils.loadProviderClasses(callingContext, sd, propName); - boolean in = propName.contains("in.interceptors"); - boolean out = propName.contains("out.interceptors"); - boolean inFault = propName.contains("in.fault.interceptors"); - boolean outFault = propName.contains("out.fault.interceptors"); - for (Object provider : providers) { - Interceptor<?> interceptor = (Interceptor<?>) provider; - if (in) { - factory.getInInterceptors().add(interceptor); - } else if (out) { - factory.getOutInterceptors().add(interceptor); - } else if (inFault) { - factory.getInFaultInterceptors().add(interceptor); - } else if (outFault) { - factory.getOutFaultInterceptors().add(interceptor); - } - } - } - - private static void addFeatures(AbstractEndpointFactory factory, BundleContext callingContext, - Map<String, Object> sd, String propName) { - List<Object> providers = ClassUtils.loadProviderClasses(callingContext, sd, propName); - if (!providers.isEmpty()) { - factory.getFeatures().addAll(CastUtils.cast(providers, AbstractFeature.class)); - } - } - private static void addContextProperties(AbstractEndpointFactory factory, Map<String, Object> sd, String propName) { @SuppressWarnings("unchecked") Map<String, Object> props = (Map<String, Object>)sd.get(propName); http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/ccf5a7a7/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/InterceptorSupport.java ---------------------------------------------------------------------- diff --git a/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/InterceptorSupport.java b/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/InterceptorSupport.java new file mode 100644 index 0000000..1965157 --- /dev/null +++ b/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/InterceptorSupport.java @@ -0,0 +1,63 @@ +/** + * 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.cxf.dosgi.dsw.handlers.pojo; + +import java.util.List; +import java.util.Map; + +import org.apache.cxf.dosgi.common.util.ClassUtils; +import org.apache.cxf.endpoint.AbstractEndpointFactory; +import org.apache.cxf.feature.AbstractFeature; +import org.apache.cxf.helpers.CastUtils; +import org.apache.cxf.interceptor.Interceptor; +import org.osgi.framework.BundleContext; + +public final class InterceptorSupport { + private InterceptorSupport() { + } + + public static void addInterceptors(AbstractEndpointFactory factory, BundleContext callingContext, + Map<String, Object> sd, String propName) { + List<Object> providers = ClassUtils.loadProviderClasses(callingContext, sd, propName); + boolean in = propName.contains("in.interceptors"); + boolean out = propName.contains("out.interceptors"); + boolean inFault = propName.contains("in.fault.interceptors"); + boolean outFault = propName.contains("out.fault.interceptors"); + for (Object provider : providers) { + Interceptor<?> interceptor = (Interceptor<?>) provider; + if (in) { + factory.getInInterceptors().add(interceptor); + } else if (out) { + factory.getOutInterceptors().add(interceptor); + } else if (inFault) { + factory.getInFaultInterceptors().add(interceptor); + } else if (outFault) { + factory.getOutFaultInterceptors().add(interceptor); + } + } + } + + public static void addFeatures(AbstractEndpointFactory factory, BundleContext callingContext, + Map<String, Object> sd, String propName) { + List<Object> providers = ClassUtils.loadProviderClasses(callingContext, sd, propName); + if (!providers.isEmpty()) { + factory.getFeatures().addAll(CastUtils.cast(providers, AbstractFeature.class)); + } + } +} http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/ccf5a7a7/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/PojoConfigurationTypeHandler.java ---------------------------------------------------------------------- diff --git a/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/PojoConfigurationTypeHandler.java b/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/PojoConfigurationTypeHandler.java index aa49f99..2a57c91 100644 --- a/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/PojoConfigurationTypeHandler.java +++ b/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/PojoConfigurationTypeHandler.java @@ -29,6 +29,7 @@ import org.apache.cxf.aegis.databinding.AegisDatabinding; import org.apache.cxf.databinding.DataBinding; import org.apache.cxf.dosgi.common.httpservice.HttpServiceManager; import org.apache.cxf.dosgi.common.intent.IntentManager; +import org.apache.cxf.dosgi.common.proxy.ProxyFactory; import org.apache.cxf.dosgi.dsw.osgi.Constants; import org.apache.cxf.frontend.ClientProxyFactoryBean; import org.apache.cxf.frontend.ServerFactoryBean; @@ -78,12 +79,12 @@ public class PojoConfigurationTypeHandler extends AbstractPojoConfigurationTypeH factory.setServiceClass(iClass); factory.setAddress(address); addWsInterceptorsFeaturesProps(factory.getClientFactoryBean(), consumerContext, sd); - setClientWsdlProperties(factory.getClientFactoryBean(), bundleContext, sd, false); + WsdlSupport.setWsdlProperties(factory.getClientFactoryBean(), bundleContext, sd, false); intentManager.applyIntents(factory.getFeatures(), factory.getClientFactoryBean(), sd); Thread.currentThread().setContextClassLoader(ClientProxyFactoryBean.class.getClassLoader()); - return getProxy(factory.create(), iClass); + return ProxyFactory.create(factory.create(), iClass); } catch (Exception e) { LOG.warn("proxy creation failed", e); } finally { @@ -111,7 +112,7 @@ public class PojoConfigurationTypeHandler extends AbstractPojoConfigurationTypeH factory.setServiceBean(serviceO); addWsInterceptorsFeaturesProps(factory, serviceContext, endpointProps); - setWsdlProperties(factory, serviceContext, endpointProps, false); + WsdlSupport.setWsdlProperties(factory, serviceContext, endpointProps, false); String[] intents = intentManager.applyIntents(factory.getFeatures(), factory, endpointProps); String completeEndpointAddress = httpServiceManager.getAbsoluteAddress(contextRoot, address); http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/ccf5a7a7/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/ServiceInvocationHandler.java ---------------------------------------------------------------------- diff --git a/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/ServiceInvocationHandler.java b/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/ServiceInvocationHandler.java deleted file mode 100644 index 3928c7d..0000000 --- a/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/ServiceInvocationHandler.java +++ /dev/null @@ -1,100 +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.cxf.dosgi.dsw.handlers.pojo; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.security.AccessController; -import java.security.PrivilegedExceptionAction; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.osgi.framework.ServiceException; - -public class ServiceInvocationHandler implements InvocationHandler { - - private static final String REMOTE_EXCEPTION_TYPE = "REMOTE"; - private static final Collection<Method> OBJECT_METHODS = Arrays.asList(Object.class.getMethods()); - - private Map<Method, List<Class<?>>> exceptionsMap = new HashMap<Method, List<Class<?>>>(); - private Object serviceObject; - - public ServiceInvocationHandler(Object serviceObject, Class<?> iType) { - this.serviceObject = serviceObject; - introspectType(iType); - } - - public Object invoke(Object proxy, final Method m, Object[] params) throws Throwable { - if (OBJECT_METHODS.contains(m)) { - if (m.getName().equals("equals")) { - params = new Object[] {Proxy.getInvocationHandler(params[0])}; - } - return m.invoke(this, params); - } - - ClassLoader oldCl = Thread.currentThread().getContextClassLoader(); - try { - Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); - final Object[] paramsFinal = params; - return AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { - public Object run() throws Exception { - return m.invoke(serviceObject, paramsFinal); - } - }); - } catch (Throwable ex) { - Throwable theCause = ex.getCause() == null ? ex : ex.getCause(); - Throwable theCauseCause = theCause.getCause() == null ? theCause : theCause.getCause(); - List<Class<?>> excTypes = exceptionsMap.get(m); - if (excTypes != null) { - for (Class<?> type : excTypes) { - if (type.isAssignableFrom(theCause.getClass())) { - throw theCause; - } - if (type.isAssignableFrom(theCauseCause.getClass())) { - throw theCauseCause; - } - } - } - - throw new ServiceException(REMOTE_EXCEPTION_TYPE, theCause); - } finally { - Thread.currentThread().setContextClassLoader(oldCl); - } - } - - private void introspectType(Class<?> iType) { - for (Method m : iType.getDeclaredMethods()) { - for (Class<?> excType : m.getExceptionTypes()) { - if (Exception.class.isAssignableFrom(excType)) { - List<Class<?>> types = exceptionsMap.get(m); - if (types == null) { - types = new ArrayList<Class<?>>(); - exceptionsMap.put(m, types); - } - types.add(excType); - } - } - } - } -} http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/ccf5a7a7/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/WsdlConfigurationTypeHandler.java ---------------------------------------------------------------------- diff --git a/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/WsdlConfigurationTypeHandler.java b/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/WsdlConfigurationTypeHandler.java index 7e7ad44..d3bca3e 100644 --- a/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/WsdlConfigurationTypeHandler.java +++ b/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/WsdlConfigurationTypeHandler.java @@ -31,6 +31,7 @@ import org.apache.cxf.common.util.PackageUtils; import org.apache.cxf.databinding.DataBinding; import org.apache.cxf.dosgi.common.httpservice.HttpServiceManager; import org.apache.cxf.dosgi.common.intent.IntentManager; +import org.apache.cxf.dosgi.common.proxy.ProxyFactory; import org.apache.cxf.dosgi.common.util.OsgiUtils; import org.apache.cxf.dosgi.dsw.osgi.Constants; import org.apache.cxf.jaxb.JAXBDataBinding; @@ -86,14 +87,14 @@ public class WsdlConfigurationTypeHandler extends AbstractPojoConfigurationTypeH if (serviceName == null) { serviceName = iClass.getSimpleName(); } - QName serviceQname = getServiceQName(iClass, endpoint.getProperties(), + QName serviceQname = WsdlSupport.getServiceQName(iClass, endpoint.getProperties(), Constants.WSDL_SERVICE_NAMESPACE, Constants.WSDL_SERVICE_NAME); - QName portQname = getPortQName(serviceQname.getNamespaceURI(), + QName portQname = WsdlSupport.getPortQName(serviceQname.getNamespaceURI(), endpoint.getProperties(), Constants.WSDL_PORT_NAME); Service service = createWebService(wsdlAddress, serviceQname); - Object proxy = getProxy(portQname == null ? service.getPort(iClass) : service.getPort(portQname, iClass), - iClass); + Object port = portQname == null ? service.getPort(iClass) : service.getPort(portQname, iClass); + Object proxy = ProxyFactory.create(port, iClass); // MARC: FIXME!!!! getDistributionProvider().addRemoteService(serviceReference); return proxy; } @@ -138,7 +139,7 @@ public class WsdlConfigurationTypeHandler extends AbstractPojoConfigurationTypeH addWsInterceptorsFeaturesProps(factory, serviceContext, sd); - setWsdlProperties(factory, serviceContext, sd, true); + WsdlSupport.setWsdlProperties(factory, serviceContext, sd, true); String[] intents = intentManager.applyIntents(factory.getFeatures(), factory, sd); http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/ccf5a7a7/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/WsdlSupport.java ---------------------------------------------------------------------- diff --git a/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/WsdlSupport.java b/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/WsdlSupport.java new file mode 100644 index 0000000..2118b33 --- /dev/null +++ b/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/pojo/WsdlSupport.java @@ -0,0 +1,83 @@ +/** + * 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.cxf.dosgi.dsw.handlers.pojo; + +import java.net.URL; +import java.util.Map; + +import javax.xml.namespace.QName; + +import org.apache.cxf.common.util.PackageUtils; +import org.apache.cxf.dosgi.common.util.OsgiUtils; +import org.apache.cxf.dosgi.dsw.osgi.Constants; +import org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory; +import org.osgi.framework.BundleContext; + +public final class WsdlSupport { + + private WsdlSupport() { + } + + public static void setWsdlProperties(AbstractWSDLBasedEndpointFactory factory, BundleContext context, + Map<String, Object> sd, + boolean wsdlType) { + String location = OsgiUtils.getProperty(sd, wsdlType ? Constants.WSDL_LOCATION : Constants.WS_WSDL_LOCATION); + if (location != null) { + URL wsdlURL = context.getBundle().getResource(location); + if (wsdlURL != null) { + factory.setWsdlURL(wsdlURL.toString()); + } + QName serviceName = getServiceQName(null, sd, + wsdlType ? Constants.WSDL_SERVICE_NAMESPACE : Constants.WS_WSDL_SERVICE_NAMESPACE, + wsdlType ? Constants.WSDL_SERVICE_NAME : Constants.WS_WSDL_SERVICE_NAME); + if (serviceName != null) { + factory.setServiceName(serviceName); + QName portName = getPortQName(serviceName.getNamespaceURI(), sd, + wsdlType ? Constants.WSDL_PORT_NAME : Constants.WS_WSDL_PORT_NAME); + if (portName != null) { + factory.setEndpointName(portName); + } + } + } + } + + protected static QName getServiceQName(Class<?> iClass, Map<String, Object> sd, String nsPropName, + String namePropName) { + String serviceNs = OsgiUtils.getProperty(sd, nsPropName); + String serviceName = OsgiUtils.getProperty(sd, namePropName); + if (iClass == null && (serviceNs == null || serviceName == null)) { + return null; + } + if (serviceNs == null) { + serviceNs = PackageUtils.getNamespace(PackageUtils.getPackageName(iClass)); + } + if (serviceName == null) { + serviceName = iClass.getSimpleName(); + } + return new QName(serviceNs, serviceName); + } + + protected static QName getPortQName(String ns, Map<String, Object> sd, String propName) { + String portName = OsgiUtils.getProperty(sd, propName); + if (portName == null) { + return null; + } + return new QName(ns, portName); + } +} http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/ccf5a7a7/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/rest/JaxRSPojoConfigurationTypeHandler.java ---------------------------------------------------------------------- diff --git a/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/rest/JaxRSPojoConfigurationTypeHandler.java b/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/rest/JaxRSPojoConfigurationTypeHandler.java index 385993d..9befacf 100644 --- a/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/rest/JaxRSPojoConfigurationTypeHandler.java +++ b/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/rest/JaxRSPojoConfigurationTypeHandler.java @@ -22,16 +22,20 @@ import java.net.URL; import java.util.List; import java.util.Map; +import org.apache.aries.rsa.spi.DistributionProvider; import org.apache.aries.rsa.spi.Endpoint; import org.apache.aries.rsa.spi.IntentUnsatisfiedException; import org.apache.cxf.Bus; +import org.apache.cxf.BusFactory; import org.apache.cxf.common.util.ProxyClassLoader; import org.apache.cxf.dosgi.common.httpservice.HttpServiceManager; import org.apache.cxf.dosgi.common.intent.IntentManager; +import org.apache.cxf.dosgi.common.proxy.ProxyFactory; import org.apache.cxf.dosgi.common.util.OsgiUtils; import org.apache.cxf.dosgi.common.util.ServerWrapper; -import org.apache.cxf.dosgi.dsw.handlers.pojo.AbstractPojoConfigurationTypeHandler; +import org.apache.cxf.dosgi.dsw.handlers.pojo.InterceptorSupport; import org.apache.cxf.dosgi.dsw.osgi.Constants; +import org.apache.cxf.endpoint.AbstractEndpointFactory; import org.apache.cxf.endpoint.Server; import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; import org.apache.cxf.jaxrs.client.Client; @@ -44,19 +48,37 @@ import org.osgi.service.remoteserviceadmin.RemoteConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class JaxRSPojoConfigurationTypeHandler extends AbstractPojoConfigurationTypeHandler { - +public class JaxRSPojoConfigurationTypeHandler implements DistributionProvider { private static final Logger LOG = LoggerFactory.getLogger(JaxRSPojoConfigurationTypeHandler.class); + protected BundleContext bundleContext; + protected IntentManager intentManager; + protected HttpServiceManager httpServiceManager; - public JaxRSPojoConfigurationTypeHandler(BundleContext dswBC, - IntentManager intentManager, + public JaxRSPojoConfigurationTypeHandler(BundleContext dswBC, IntentManager intentManager, HttpServiceManager httpServiceManager) { - super(dswBC, intentManager, httpServiceManager); + this.bundleContext = dswBC; + this.intentManager = intentManager; + this.httpServiceManager = httpServiceManager; } public String[] getSupportedTypes() { return new String[] {Constants.RS_CONFIG_TYPE}; } + + protected EndpointDescription createEndpointDesc(Map<String, Object> props, + String[] importedConfigs, + String address, + String[] intents) { + props.put(RemoteConstants.SERVICE_IMPORTED_CONFIGS, importedConfigs); + for (String configurationType : importedConfigs) { + if (Constants.RS_CONFIG_TYPE.equals(configurationType)) { + props.put(Constants.RS_ADDRESS_PROPERTY, address); + } + } + props.put(RemoteConstants.SERVICE_INTENTS, intents); + props.put(RemoteConstants.ENDPOINT_ID, address); + return new EndpointDescription(props); + } @SuppressWarnings("rawtypes") public Object importEndpoint(ClassLoader consumerLoader, @@ -111,7 +133,7 @@ public class JaxRSPojoConfigurationTypeHandler extends AbstractPojoConfiguration bean.setProviders(providers); } Thread.currentThread().setContextClassLoader(JAXRSClientFactoryBean.class.getClassLoader()); - return getProxy(bean.create(), iClass); + return ProxyFactory.create(bean.create(), iClass); } @SuppressWarnings("rawtypes") @@ -119,7 +141,7 @@ public class JaxRSPojoConfigurationTypeHandler extends AbstractPojoConfiguration BundleContext callingContext, Map<String, Object> endpointProps, Class[] exportedInterfaces) throws IntentUnsatisfiedException { - String contextRoot = getServletContextRoot(endpointProps); + String contextRoot = OsgiUtils.getProperty(endpointProps, Constants.RS_HTTP_SERVICE_CONTEXT); String address; Class<?> iClass = exportedInterfaces[0]; if (contextRoot == null) { @@ -145,6 +167,24 @@ public class JaxRSPojoConfigurationTypeHandler extends AbstractPojoConfiguration return createServerFromFactory(factory, epd); } + + protected String getClientAddress(Map<String, Object> sd) { + return OsgiUtils.getFirstNonEmptyStringProperty(sd, RemoteConstants.ENDPOINT_ID, + Constants.RS_ADDRESS_PROPERTY); + } + + protected String getServerAddress(Map<String, Object> sd, Class<?> iClass) { + String address = OsgiUtils.getProperty(sd, Constants.RS_ADDRESS_PROPERTY); + return address == null ? httpServiceManager.getDefaultAddress(iClass) : address; + } + + protected Bus createBus(Long sid, BundleContext callingContext, String contextRoot) { + Bus bus = BusFactory.newInstance().createBus(); + if (contextRoot != null) { + httpServiceManager.registerServlet(bus, contextRoot, callingContext, sid); + } + return bus; + } private Endpoint createServerFromFactory(JAXRSServerFactoryBean factory, EndpointDescription epd) { @@ -201,4 +241,23 @@ public class JaxRSPojoConfigurationTypeHandler extends AbstractPojoConfiguration } return address; } + + protected void addRsInterceptorsFeaturesProps(AbstractEndpointFactory factory, + BundleContext callingContext, + Map<String, Object> sd) { + InterceptorSupport.addInterceptors(factory, callingContext, sd, Constants.RS_IN_INTERCEPTORS_PROP_KEY); + InterceptorSupport.addInterceptors(factory, callingContext, sd, Constants.RS_OUT_INTERCEPTORS_PROP_KEY); + InterceptorSupport.addInterceptors(factory, callingContext, sd, Constants.RS_OUT_FAULT_INTERCEPTORS_PROP_KEY); + InterceptorSupport.addInterceptors(factory, callingContext, sd, Constants.RS_IN_FAULT_INTERCEPTORS_PROP_KEY); + InterceptorSupport.addFeatures(factory, callingContext, sd, Constants.RS_FEATURES_PROP_KEY); + addContextProperties(factory, sd, Constants.RS_CONTEXT_PROPS_PROP_KEY); + } + + private void addContextProperties(AbstractEndpointFactory factory, Map<String, Object> sd, String propName) { + @SuppressWarnings("unchecked") + Map<String, Object> props = (Map<String, Object>)sd.get(propName); + if (props != null) { + factory.getProperties(true).putAll(props); + } + } } http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/ccf5a7a7/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/handlers/ServiceInvocationHandlerTest.java ---------------------------------------------------------------------- diff --git a/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/handlers/ServiceInvocationHandlerTest.java b/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/handlers/ServiceInvocationHandlerTest.java deleted file mode 100644 index 3b909d6..0000000 --- a/cxf-dsw/src/test/java/org/apache/cxf/dosgi/dsw/handlers/ServiceInvocationHandlerTest.java +++ /dev/null @@ -1,77 +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.cxf.dosgi.dsw.handlers; - -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.cxf.dosgi.dsw.handlers.pojo.ServiceInvocationHandler; - -import junit.framework.TestCase; - -public class ServiceInvocationHandlerTest extends TestCase { - - private static final Map<String, Method> OBJECT_METHODS = new HashMap<String, Method>(); { - for (Method m : Object.class.getMethods()) { - OBJECT_METHODS.put(m.getName(), m); - } - } - - public void testInvoke() throws Throwable { - ServiceInvocationHandler sih = new ServiceInvocationHandler("hello", String.class); - Method m = String.class.getMethod("length", new Class[] {}); - assertEquals(5, sih.invoke(null, m, new Object[] {})); - } - - public void testInvokeObjectMethod() throws Throwable { - final List<String> called = new ArrayList<String>(); - ServiceInvocationHandler sih = new ServiceInvocationHandler("hi", String.class) { - public boolean equals(Object obj) { - called.add("equals"); - return super.equals(obj); - } - - public int hashCode() { - called.add("hashCode"); - return super.hashCode(); - } - - public String toString() { - called.add("toString"); - return "somestring"; - } - }; - - Object proxy = Proxy.newProxyInstance( - getClass().getClassLoader(), new Class[] {Runnable.class}, sih); - - assertEquals(true, - sih.invoke(null, OBJECT_METHODS.get("equals"), new Object[] {proxy})); - assertEquals(System.identityHashCode(sih), - sih.invoke(null, OBJECT_METHODS.get("hashCode"), new Object[] {})); - assertEquals("somestring", - sih.invoke(null, OBJECT_METHODS.get("toString"), new Object[] {})); - assertEquals(Arrays.asList("equals", "hashCode", "toString"), called); - } -}
