[DOSGI-229] Make CXF handlers only depend on API
Project: http://git-wip-us.apache.org/repos/asf/cxf-dosgi/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf-dosgi/commit/f54fb69b Tree: http://git-wip-us.apache.org/repos/asf/cxf-dosgi/tree/f54fb69b Diff: http://git-wip-us.apache.org/repos/asf/cxf-dosgi/diff/f54fb69b Branch: refs/heads/master Commit: f54fb69b9b7a25b2c423301c926caa4ee4b01aeb Parents: b5f02ff Author: Christian Schneider <[email protected]> Authored: Fri Mar 4 11:55:54 2016 +0100 Committer: Christian Schneider <[email protected]> Committed: Fri Mar 4 11:55:54 2016 +0100 ---------------------------------------------------------------------- .../org/apache/cxf/dosgi/dsw/Activator.java | 41 ++--- .../cxf/dosgi/dsw/api/DistributionProvider.java | 25 ++- .../AbstractPojoConfigurationTypeHandler.java | 10 +- .../dsw/handlers/CXFDistributionProvider.java | 177 +++++++++++++++++++ .../cxf/dosgi/dsw/handlers/ClassUtils.java | 142 +++++++++++++++ .../dsw/handlers/ConfigTypeHandlerFactory.java | 168 ------------------ .../JaxRSPojoConfigurationTypeHandler.java | 10 +- .../cxf/dosgi/dsw/handlers/JaxRSUtils.java | 1 - .../handlers/PojoConfigurationTypeHandler.java | 8 +- .../handlers/WsdlConfigurationTypeHandler.java | 5 +- .../apache/cxf/dosgi/dsw/qos/IntentUtils.java | 4 +- .../dosgi/dsw/service/ClientServiceFactory.java | 2 +- .../dsw/service/ConfigTypeHandlerFinder.java | 36 ---- .../cxf/dosgi/dsw/service/EventAdminHelper.java | 8 +- .../cxf/dosgi/dsw/service/PackageFinder.java | 47 +++++ .../dsw/service/RemoteServiceAdminCore.java | 150 ++++++++++------ .../dsw/service/RemoteServiceAdminInstance.java | 14 +- .../cxf/dosgi/dsw/service/StringPlus.java | 72 ++++++++ .../apache/cxf/dosgi/dsw/util/ClassUtils.java | 142 --------------- .../apache/cxf/dosgi/dsw/util/OsgiUtils.java | 65 ------- .../apache/cxf/dosgi/dsw/util/StringPlus.java | 72 ++++++++ .../org/apache/cxf/dosgi/dsw/util/Utils.java | 101 ----------- .../org/apache/cxf/dosgi/dsw/ActivatorTest.java | 3 + .../handlers/CXFDistributionProviderTest.java | 118 +++++++++++++ .../dsw/handlers/ClientServiceFactoryTest.java | 7 +- .../handlers/ConfigTypeHandlerFactoryTest.java | 116 ------------ .../PojoConfigurationTypeHandlerTest.java | 24 +-- .../cxf/dosgi/dsw/qos/IntentUtilsTest.java | 1 + .../dsw/service/ImportRegistrationImplTest.java | 1 + .../dsw/service/RemoteServiceAdminCoreTest.java | 59 +++++-- .../apache/cxf/dosgi/dsw/service/UtilsTest.java | 25 ++- .../cxf/dosgi/dsw/util/ClassUtilsTest.java | 1 + .../cxf/dosgi/dsw/util/OsgiUtilsTest.java | 44 ----- 33 files changed, 858 insertions(+), 841 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java index 166bc13..c2383aa 100644 --- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/Activator.java @@ -18,29 +18,24 @@ */ package org.apache.cxf.dosgi.dsw; -import java.util.ArrayList; import java.util.Dictionary; -import java.util.HashMap; import java.util.Hashtable; -import java.util.List; -import java.util.Map; import org.apache.cxf.Bus; import org.apache.cxf.BusFactory; +import org.apache.cxf.dosgi.dsw.api.DistributionProvider; import org.apache.cxf.dosgi.dsw.decorator.ServiceDecorator; import org.apache.cxf.dosgi.dsw.decorator.ServiceDecoratorBundleListener; import org.apache.cxf.dosgi.dsw.decorator.ServiceDecoratorImpl; -import org.apache.cxf.dosgi.dsw.handlers.ConfigTypeHandlerFactory; +import org.apache.cxf.dosgi.dsw.handlers.CXFDistributionProvider; import org.apache.cxf.dosgi.dsw.handlers.HttpServiceManager; import org.apache.cxf.dosgi.dsw.qos.DefaultIntentMapFactory; import org.apache.cxf.dosgi.dsw.qos.IntentManager; import org.apache.cxf.dosgi.dsw.qos.IntentManagerImpl; import org.apache.cxf.dosgi.dsw.qos.IntentMap; import org.apache.cxf.dosgi.dsw.qos.IntentTracker; -import org.apache.cxf.dosgi.dsw.service.ConfigTypeHandlerFinder; import org.apache.cxf.dosgi.dsw.service.RemoteServiceAdminCore; import org.apache.cxf.dosgi.dsw.service.RemoteServiceadminFactory; -import org.apache.cxf.dosgi.dsw.util.Utils; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleListener; @@ -64,7 +59,7 @@ public class Activator implements ManagedService, BundleActivator { private HttpServiceManager httpServiceManager; private BundleContext bc; private BundleListener bundleListener; - private Map<String, Object> curConfiguration; + private Dictionary<String, Object> curConfiguration; private Bus bus; public void start(BundleContext bundlecontext) throws Exception { @@ -77,11 +72,11 @@ public class Activator implements ManagedService, BundleActivator { registerManagedService(bc); } - private Map<String, Object> getDefaultConfig() { - return new HashMap<String, Object>(); + private Dictionary<String, Object> getDefaultConfig() { + return new Hashtable<String, Object>(); } - private synchronized void init(Map<String, Object> config) { + private synchronized void init(Dictionary<String, Object> config) { bus = BusFactory.newInstance().createBus(); String httpBase = (String) config.get(org.apache.cxf.dosgi.dsw.Constants.HTTP_BASE); @@ -92,15 +87,14 @@ public class Activator implements ManagedService, BundleActivator { intentTracker.open(); IntentManager intentManager = new IntentManagerImpl(intentMap, DEFAULT_INTENT_TIMEOUT); httpServiceManager = new HttpServiceManager(bc, httpBase, cxfServletAlias); - ConfigTypeHandlerFinder configTypeHandlerFactory - = new ConfigTypeHandlerFactory(bc, intentManager, httpServiceManager); - RemoteServiceAdminCore rsaCore = new RemoteServiceAdminCore(bc, configTypeHandlerFactory); + DistributionProvider cxfProvider + = new CXFDistributionProvider(bc, intentManager, httpServiceManager); + RemoteServiceAdminCore rsaCore = new RemoteServiceAdminCore(bc, cxfProvider); RemoteServiceadminFactory rsaf = new RemoteServiceadminFactory(rsaCore); Dictionary<String, Object> props = new Hashtable<String, Object>(); String[] supportedIntents = intentMap.keySet().toArray(new String[] {}); props.put("remote.intents.supported", supportedIntents); - props.put("remote.configs.supported", - obtainSupportedConfigTypes(configTypeHandlerFactory.getSupportedConfigurationTypes())); + props.put("remote.configs.supported", cxfProvider.getSupportedTypes()); LOG.info("Registering RemoteServiceAdminFactory..."); rsaFactoryReg = bc.registerService(RemoteServiceAdmin.class.getName(), rsaf, props); ServiceDecoratorImpl serviceDecorator = new ServiceDecoratorImpl(); @@ -133,19 +127,6 @@ public class Activator implements ManagedService, BundleActivator { } } - // The CT sometimes uses the first element returned to register a service, but - // does not provide any additional configuration. - // Return the configuration type that works without additional configuration as the first in the list. - private String[] obtainSupportedConfigTypes(List<String> types) { - List<String> l = new ArrayList<String>(types); - if (l.contains(org.apache.cxf.dosgi.dsw.Constants.WS_CONFIG_TYPE)) { - // make sure its the first element... - l.remove(org.apache.cxf.dosgi.dsw.Constants.WS_CONFIG_TYPE); - l.add(0, org.apache.cxf.dosgi.dsw.Constants.WS_CONFIG_TYPE); - } - return l.toArray(new String[] {}); - } - private void registerManagedService(BundleContext bundlecontext) { Dictionary<String, String> props = new Hashtable<String, String>(); props.put(Constants.SERVICE_PID, CONFIG_SERVICE_PID); @@ -174,7 +155,7 @@ public class Activator implements ManagedService, BundleActivator { LOG.debug("RemoteServiceAdmin Implementation configuration is updated with {}", config); // config is null if it doesn't exist, is being deleted or has not yet been loaded // in which case we run with defaults (just like we do manually when bundle is first started) - Map<String, Object> configMap = config == null ? getDefaultConfig() : Utils.toMap(config); + Dictionary<String, Object> configMap = config == null ? getDefaultConfig() : config; if (!configMap.equals(curConfiguration)) { // only if something actually changed curConfiguration = configMap; uninit(); http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/api/DistributionProvider.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/api/DistributionProvider.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/api/DistributionProvider.java index a16f2bd..ec804be 100644 --- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/api/DistributionProvider.java +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/api/DistributionProvider.java @@ -20,6 +20,7 @@ package org.apache.cxf.dosgi.dsw.api; import java.util.Map; +import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.service.remoteserviceadmin.EndpointDescription; @@ -28,25 +29,31 @@ public interface DistributionProvider { String[] getSupportedTypes(); /** - * * @param sref reference of the service to be exported * @param effectiveProperties combined properties of the service and additional properties from rsa * @param exportedInterface name of the interface to be exported * @return */ - Endpoint createServer(ServiceReference<?> sref, - Map<String, Object> effectiveProperties, - String exportedInterface); + Endpoint exportService(ServiceReference<?> sref, + Map<String, Object> effectiveProperties, + String exportedInterface); /** - * * @param sref reference of the service offered to the requesting bundle - * @param iClass + * @param iClass interface of the service to proxy * @param endpoint description of the remote endpoint * @return service proxy to be given to the requesting bundle * @throws IntentUnsatisfiedException */ - Object createProxy(ServiceReference<?> sref, - Class<?> iClass, - EndpointDescription endpoint) throws IntentUnsatisfiedException; + Object importEndpoint(BundleContext consumerContext, + Class<?> iClass, + EndpointDescription endpoint) + throws IntentUnsatisfiedException; + + /** + * + * @param endpoint + * @return if the provider can handle any of the config types of the endpoint + */ + boolean canHandle(EndpointDescription endpoint); } http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/AbstractPojoConfigurationTypeHandler.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/AbstractPojoConfigurationTypeHandler.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/AbstractPojoConfigurationTypeHandler.java index b1dffff..60f8222 100644 --- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/AbstractPojoConfigurationTypeHandler.java +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/AbstractPojoConfigurationTypeHandler.java @@ -35,7 +35,6 @@ import org.apache.cxf.dosgi.dsw.api.DistributionProvider; import org.apache.cxf.dosgi.dsw.api.Endpoint; import org.apache.cxf.dosgi.dsw.qos.IntentManager; import org.apache.cxf.dosgi.dsw.qos.IntentUtils; -import org.apache.cxf.dosgi.dsw.util.ClassUtils; import org.apache.cxf.dosgi.dsw.util.OsgiUtils; import org.apache.cxf.endpoint.AbstractEndpointFactory; import org.apache.cxf.endpoint.Server; @@ -86,7 +85,8 @@ public abstract class AbstractPojoConfigurationTypeHandler implements Distributi props.remove(org.osgi.framework.Constants.SERVICE_ID); props.put(org.osgi.framework.Constants.OBJECTCLASS, sa); props.put(RemoteConstants.ENDPOINT_SERVICE_ID, sd.get(org.osgi.framework.Constants.SERVICE_ID)); - props.put(RemoteConstants.ENDPOINT_FRAMEWORK_UUID, OsgiUtils.getUUID(bundleContext)); + String frameworkUUID = bundleContext.getProperty(org.osgi.framework.Constants.FRAMEWORK_UUID); + props.put(RemoteConstants.ENDPOINT_FRAMEWORK_UUID, frameworkUUID); props.put(RemoteConstants.SERVICE_IMPORTED_CONFIGS, importedConfigs); props.put(RemoteConstants.ENDPOINT_PACKAGE_VERSION_ + pkg, OsgiUtils.getVersion(iClass, bundleContext)); @@ -275,4 +275,10 @@ public abstract class AbstractPojoConfigurationTypeHandler implements Distributi factory.getProperties(true).putAll(props); } } + + @Override + public boolean canHandle(EndpointDescription endpoint) { + // Will be handled by CXFDistributionProvider at the moment + throw new IllegalStateException(); + } } http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/CXFDistributionProvider.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/CXFDistributionProvider.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/CXFDistributionProvider.java new file mode 100644 index 0000000..27aff63 --- /dev/null +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/CXFDistributionProvider.java @@ -0,0 +1,177 @@ +/** + * 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.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.cxf.dosgi.dsw.Constants; +import org.apache.cxf.dosgi.dsw.api.DistributionProvider; +import org.apache.cxf.dosgi.dsw.api.Endpoint; +import org.apache.cxf.dosgi.dsw.api.IntentUnsatisfiedException; +import org.apache.cxf.dosgi.dsw.qos.IntentManager; +import org.apache.cxf.dosgi.dsw.util.OsgiUtils; +import org.apache.cxf.dosgi.dsw.util.StringPlus; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.service.remoteserviceadmin.EndpointDescription; +import org.osgi.service.remoteserviceadmin.RemoteConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CXFDistributionProvider implements DistributionProvider { + + protected static final String DEFAULT_CONFIGURATION_TYPE = Constants.WS_CONFIG_TYPE; + private static final Logger LOG = LoggerFactory.getLogger(CXFDistributionProvider.class); + + // protected because of tests + protected final String[] supportedConfigurationTypes; + + private IntentManager intentManager; + private PojoConfigurationTypeHandler pojoConfigurationTypeHandler; + private JaxRSPojoConfigurationTypeHandler jaxRsPojoConfigurationTypeHandler; + private WsdlConfigurationTypeHandler wsdlConfigurationTypeHandler; + private Set<String> configTypesSet; + + public CXFDistributionProvider(BundleContext bc, IntentManager intentManager, + HttpServiceManager httpServiceManager) { + this.intentManager = intentManager; + this.pojoConfigurationTypeHandler = new PojoConfigurationTypeHandler(bc, intentManager, httpServiceManager); + this.jaxRsPojoConfigurationTypeHandler = new JaxRSPojoConfigurationTypeHandler(bc, + intentManager, + httpServiceManager); + this.wsdlConfigurationTypeHandler = new WsdlConfigurationTypeHandler(bc, intentManager, httpServiceManager); + supportedConfigurationTypes = new String[] {Constants.WS_CONFIG_TYPE, + Constants.WSDL_CONFIG_TYPE, + Constants.RS_CONFIG_TYPE, + Constants.WS_CONFIG_TYPE_OLD}; + configTypesSet = new HashSet<>(Arrays.asList(supportedConfigurationTypes)); + } + + @Override + public Endpoint exportService(ServiceReference<?> sref, Map<String, Object> effectiveProperties, + String exportedInterface) { + List<String> configurationTypes = determineConfigurationTypes(effectiveProperties); + DistributionProvider handler = getHandler(configurationTypes, effectiveProperties); + return handler != null ? handler.exportService(sref, effectiveProperties, exportedInterface) : null; + } + + @Override + public Object importEndpoint(BundleContext consumerContext, Class<?> iClass, EndpointDescription endpoint) + throws IntentUnsatisfiedException { + List<String> configurationTypes = determineConfigTypesForImport(endpoint); + DistributionProvider handler = getHandler(configurationTypes, endpoint.getProperties()); + return handler != null ? handler.importEndpoint(consumerContext, iClass, endpoint) : null; + } + + DistributionProvider getHandler(List<String> configurationTypes, + Map<String, Object> serviceProperties) { + intentManager.assertAllIntentsSupported(serviceProperties); + if (configurationTypes.contains(Constants.WS_CONFIG_TYPE) + || configurationTypes.contains(Constants.WS_CONFIG_TYPE_OLD) + || configurationTypes.contains(Constants.RS_CONFIG_TYPE)) { + boolean jaxrs = isJaxrsRequested(configurationTypes, serviceProperties); + return jaxrs ? jaxRsPojoConfigurationTypeHandler : pojoConfigurationTypeHandler; + } else if (configurationTypes.contains(Constants.WSDL_CONFIG_TYPE)) { + return wsdlConfigurationTypeHandler; + } + LOG.info("None of the configuration types in " + configurationTypes + " is supported."); + return null; + } + + private boolean isJaxrsRequested(Collection<String> types, Map<String, Object> serviceProperties) { + if (types == null) { + return false; + } + + if (types.contains(Constants.RS_CONFIG_TYPE)) { + Collection<String> intentsProperty + = OsgiUtils.getMultiValueProperty(serviceProperties.get(RemoteConstants.SERVICE_EXPORTED_INTENTS)); + boolean hasHttpIntent = false; + boolean hasSoapIntent = false; + if (intentsProperty != null) { + for (String intent : intentsProperty) { + if (intent.contains("SOAP")) { + hasSoapIntent = true; + break; + } + + if (intent.contains("HTTP")) { + hasHttpIntent = true; + } + } + } + if ((hasHttpIntent && !hasSoapIntent) || intentsProperty == null) { + return true; + } + } + return false; + } + + /** + * determine which configuration types should be used / if the requested are + * supported + */ + List<String> determineConfigurationTypes(Map<String, Object> serviceProperties) { + String[] requestedConfigurationTypes = StringPlus.normalize(serviceProperties + .get(RemoteConstants.SERVICE_EXPORTED_CONFIGS)); + if (requestedConfigurationTypes == null || requestedConfigurationTypes.length == 0) { + return Collections.singletonList(DEFAULT_CONFIGURATION_TYPE); + } + + List<String> configurationTypes = new ArrayList<String>(); + for (String rct : requestedConfigurationTypes) { + if (configTypesSet.contains(rct)) { + configurationTypes.add(rct); + } + } + LOG.info("Configuration types selected for export: {}.", configurationTypes); + return configurationTypes; + } + + private List<String> determineConfigTypesForImport(EndpointDescription endpoint) { + List<String> remoteConfigurationTypes = endpoint.getConfigurationTypes(); + + List<String> usableConfigurationTypes = new ArrayList<String>(); + for (String ct : supportedConfigurationTypes) { + if (remoteConfigurationTypes.contains(ct)) { + usableConfigurationTypes.add(ct); + } + } + + LOG.info("Ignoring endpoint {} as it has no compatible configuration types: {}.", + endpoint.getId(), remoteConfigurationTypes); + return usableConfigurationTypes; + } + + public String[] getSupportedTypes() { + return supportedConfigurationTypes; + } + + @Override + public boolean canHandle(EndpointDescription endpoint) { + return determineConfigTypesForImport(endpoint).size() > 0; + } +} http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/ClassUtils.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/ClassUtils.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/ClassUtils.java new file mode 100644 index 0000000..cae19bd --- /dev/null +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/ClassUtils.java @@ -0,0 +1,142 @@ +/** + * 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.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.apache.cxf.helpers.CastUtils; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class ClassUtils { + + private static final Logger LOG = LoggerFactory.getLogger(ClassUtils.class); + + private ClassUtils() { + } + + public static Class<?> getInterfaceClass(Object service, String interfaceName) { + return getInterfaceClass(service.getClass(), interfaceName); + } + + private static Class<?> getInterfaceClass(Class<?> serviceClass, String interfaceName) { + for (Class<?> iClass : serviceClass.getInterfaces()) { + if (iClass.getName().equals(interfaceName)) { + return iClass; + } + Class<?> intf = getInterfaceClass(iClass, interfaceName); + if (intf != null) { + return intf; + } + } + + if (serviceClass.getName().equals(interfaceName)) { + return serviceClass; + } + + Class<?> interfaceOnProxiedClass = getInterfaceClassOnSuperClasses(serviceClass, interfaceName); + if (interfaceOnProxiedClass != null) { + return interfaceOnProxiedClass; + } + + return null; + } + + /** + * This method tries to deal specifically with classes that might have been proxied + * eg. CGLIB proxies of which there might be a chain of proxies as different osgi frameworks + * might be proxying the original service class that has been registered and then proxying the proxy. + * + * @param serviceClass + * @param interfaceName + * @return + */ + private static Class<?> getInterfaceClassOnSuperClasses(Class<?> serviceClass, String interfaceName) { + Class<?> superClass = serviceClass.getSuperclass(); + if (superClass != null) { + for (Class<?> iClass : superClass.getInterfaces()) { + if (iClass.getName().equals(interfaceName)) { + return iClass; + } + Class<?> intf = getInterfaceClass(iClass, interfaceName); + if (intf != null) { + return intf; + } + } + Class<?> foundOnSuperclass = getInterfaceClassOnSuperClasses(superClass, interfaceName); + if (foundOnSuperclass != null) { + return foundOnSuperclass; + } + } + return null; + } + + public static List<Object> loadProviderClasses(BundleContext callingContext, + Map<String, Object> sd, String propName) { + Object serviceProviders = sd.get(propName); + if (serviceProviders != null) { + if (serviceProviders.getClass().isArray()) { + if (serviceProviders.getClass().getComponentType() == String.class) { + return loadProviders(callingContext, (String[])serviceProviders); + } else { + return Arrays.asList((Object[])serviceProviders); + } + } else if (serviceProviders.getClass() == String.class) { + String[] classNames = serviceProviders.toString().split(","); + return loadProviders(callingContext, classNames); + } else if (serviceProviders instanceof List) { + List<Object> list = CastUtils.cast((List<?>)serviceProviders); + if (!list.isEmpty()) { + List<Object> providers; + if (list.get(0).getClass() == String.class) { + providers = loadProviders(callingContext, list.toArray(new String[]{})); + } else { + providers = list; + } + return providers; + } + } else { + return Arrays.asList(serviceProviders); + } + } + return Collections.emptyList(); + + } + + private static List<Object> loadProviders(BundleContext callingContext, String[] classNames) { + List<Object> providers = new ArrayList<Object>(); + for (String className : classNames) { + try { + String realName = className.trim(); + if (!realName.isEmpty()) { + Class<?> pClass = callingContext.getBundle().loadClass(realName); + providers.add(pClass.newInstance()); + } + } catch (Exception ex) { + LOG.warn("Provider " + className.trim() + " can not be loaded or created " + ex.getMessage(), ex); + } + } + return providers; + } +} http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/ConfigTypeHandlerFactory.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/ConfigTypeHandlerFactory.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/ConfigTypeHandlerFactory.java deleted file mode 100644 index 5d92eeb..0000000 --- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/ConfigTypeHandlerFactory.java +++ /dev/null @@ -1,168 +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.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.apache.cxf.dosgi.dsw.Constants; -import org.apache.cxf.dosgi.dsw.api.DistributionProvider; -import org.apache.cxf.dosgi.dsw.qos.IntentManager; -import org.apache.cxf.dosgi.dsw.service.ConfigTypeHandlerFinder; -import org.apache.cxf.dosgi.dsw.util.OsgiUtils; -import org.apache.cxf.dosgi.dsw.util.Utils; -import org.osgi.framework.BundleContext; -import org.osgi.service.remoteserviceadmin.EndpointDescription; -import org.osgi.service.remoteserviceadmin.RemoteConstants; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ConfigTypeHandlerFactory implements ConfigTypeHandlerFinder { - - protected static final String DEFAULT_CONFIGURATION_TYPE = Constants.WS_CONFIG_TYPE; - private static final Logger LOG = LoggerFactory.getLogger(ConfigTypeHandlerFactory.class); - - // protected because of tests - protected final List<String> supportedConfigurationTypes; - - private IntentManager intentManager; - private PojoConfigurationTypeHandler pojoConfigurationTypeHandler; - private JaxRSPojoConfigurationTypeHandler jaxRsPojoConfigurationTypeHandler; - private WsdlConfigurationTypeHandler wsdlConfigurationTypeHandler; - - public ConfigTypeHandlerFactory(BundleContext bc, IntentManager intentManager, - HttpServiceManager httpServiceManager) { - this.intentManager = intentManager; - this.pojoConfigurationTypeHandler = new PojoConfigurationTypeHandler(bc, intentManager, httpServiceManager); - this.jaxRsPojoConfigurationTypeHandler = new JaxRSPojoConfigurationTypeHandler(bc, - intentManager, - httpServiceManager); - this.wsdlConfigurationTypeHandler = new WsdlConfigurationTypeHandler(bc, intentManager, httpServiceManager); - supportedConfigurationTypes = new ArrayList<String>(); - supportedConfigurationTypes.add(Constants.WSDL_CONFIG_TYPE); - supportedConfigurationTypes.add(Constants.RS_CONFIG_TYPE); - supportedConfigurationTypes.add(Constants.WS_CONFIG_TYPE); - supportedConfigurationTypes.add(Constants.WS_CONFIG_TYPE_OLD); - } - - @Override - public DistributionProvider getHandler(BundleContext dswBC, - Map<String, Object> serviceProperties) { - List<String> configurationTypes = determineConfigurationTypes(serviceProperties); - return getHandler(dswBC, configurationTypes, serviceProperties); - } - - @Override - public DistributionProvider getHandler(BundleContext dswBC, EndpointDescription endpoint) { - List<String> configurationTypes = determineConfigTypesForImport(endpoint); - return getHandler(dswBC, configurationTypes, endpoint.getProperties()); - } - - private DistributionProvider getHandler(BundleContext dswBC, - List<String> configurationTypes, - Map<String, Object> serviceProperties) { - intentManager.assertAllIntentsSupported(serviceProperties); - if (configurationTypes.contains(Constants.WS_CONFIG_TYPE) - || configurationTypes.contains(Constants.WS_CONFIG_TYPE_OLD) - || configurationTypes.contains(Constants.RS_CONFIG_TYPE)) { - boolean jaxrs = isJaxrsRequested(configurationTypes, serviceProperties); - return jaxrs ? jaxRsPojoConfigurationTypeHandler : pojoConfigurationTypeHandler; - } else if (configurationTypes.contains(Constants.WSDL_CONFIG_TYPE)) { - return wsdlConfigurationTypeHandler; - } - LOG.info("None of the configuration types in " + configurationTypes + " is supported."); - return null; - } - - private boolean isJaxrsRequested(Collection<String> types, Map<String, Object> serviceProperties) { - if (types == null) { - return false; - } - - if (types.contains(Constants.RS_CONFIG_TYPE)) { - Collection<String> intentsProperty - = OsgiUtils.getMultiValueProperty(serviceProperties.get(RemoteConstants.SERVICE_EXPORTED_INTENTS)); - boolean hasHttpIntent = false; - boolean hasSoapIntent = false; - if (intentsProperty != null) { - for (String intent : intentsProperty) { - if (intent.contains("SOAP")) { - hasSoapIntent = true; - break; - } - - if (intent.contains("HTTP")) { - hasHttpIntent = true; - } - } - } - if ((hasHttpIntent && !hasSoapIntent) || intentsProperty == null) { - return true; - } - } - return false; - } - - /** - * determine which configuration types should be used / if the requested are - * supported - */ - private List<String> determineConfigurationTypes(Map<String, Object> serviceProperties) { - String[] requestedConfigurationTypes = Utils.normalizeStringPlus(serviceProperties - .get(RemoteConstants.SERVICE_EXPORTED_CONFIGS)); - if (requestedConfigurationTypes == null || requestedConfigurationTypes.length == 0) { - return Collections.singletonList(DEFAULT_CONFIGURATION_TYPE); - } - - List<String> configurationTypes = new ArrayList<String>(); - for (String rct : requestedConfigurationTypes) { - if (supportedConfigurationTypes.contains(rct)) { - configurationTypes.add(rct); - } - } - LOG.info("Configuration types selected for export: {}.", configurationTypes); - return configurationTypes; - } - - private List<String> determineConfigTypesForImport(EndpointDescription endpoint) { - List<String> remoteConfigurationTypes = endpoint.getConfigurationTypes(); - - List<String> usableConfigurationTypes = new ArrayList<String>(); - for (String ct : supportedConfigurationTypes) { - if (remoteConfigurationTypes.contains(ct)) { - usableConfigurationTypes.add(ct); - } - } - - LOG.info("Ignoring endpoint {} as it has no compatible configuration types: {}.", - endpoint.getId(), remoteConfigurationTypes); - return usableConfigurationTypes; - } - - /* (non-Javadoc) - * @see org.apache.cxf.dosgi.dsw.handlers.ConfigTypeHandlerFinder#getSupportedConfigurationTypes() - */ - @Override - public List<String> getSupportedConfigurationTypes() { - return supportedConfigurationTypes; - } -} http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/JaxRSPojoConfigurationTypeHandler.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/JaxRSPojoConfigurationTypeHandler.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/JaxRSPojoConfigurationTypeHandler.java index 7fc5956..3c95200 100644 --- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/JaxRSPojoConfigurationTypeHandler.java +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/JaxRSPojoConfigurationTypeHandler.java @@ -28,7 +28,6 @@ import org.apache.cxf.dosgi.dsw.Constants; import org.apache.cxf.dosgi.dsw.api.Endpoint; import org.apache.cxf.dosgi.dsw.api.IntentUnsatisfiedException; import org.apache.cxf.dosgi.dsw.qos.IntentManager; -import org.apache.cxf.dosgi.dsw.util.ClassUtils; import org.apache.cxf.dosgi.dsw.util.OsgiUtils; import org.apache.cxf.endpoint.Server; import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; @@ -56,10 +55,9 @@ public class JaxRSPojoConfigurationTypeHandler extends AbstractPojoConfiguration return new String[] {Constants.RS_CONFIG_TYPE}; } - public Object createProxy(ServiceReference<?> sref, + public Object importEndpoint(BundleContext consumerContext, Class<?> iClass, EndpointDescription endpoint) { - BundleContext callingContext = sref.getBundle().getBundleContext(); String address = getPojoAddress(endpoint, iClass); if (address == null) { LOG.warn("Remote address is unavailable"); @@ -67,7 +65,7 @@ public class JaxRSPojoConfigurationTypeHandler extends AbstractPojoConfiguration } ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); try { - return createJaxrsProxy(address, callingContext, iClass, null, endpoint); + return createJaxrsProxy(address, consumerContext, iClass, null, endpoint); } catch (Throwable e) { Thread.currentThread().setContextClassLoader(oldClassLoader); } @@ -75,7 +73,7 @@ public class JaxRSPojoConfigurationTypeHandler extends AbstractPojoConfiguration try { ProxyClassLoader cl = new ProxyClassLoader(iClass.getClassLoader()); cl.addLoader(Client.class.getClassLoader()); - return createJaxrsProxy(address, callingContext, iClass, cl, endpoint); + return createJaxrsProxy(address, consumerContext, iClass, cl, endpoint); } catch (Throwable e) { LOG.warn("proxy creation failed", e); } @@ -110,7 +108,7 @@ public class JaxRSPojoConfigurationTypeHandler extends AbstractPojoConfiguration return getProxy(bean.create(), iClass); } - public Endpoint createServer(ServiceReference<?> sref, + public Endpoint exportService(ServiceReference<?> sref, Map<String, Object> sd, String exportedInterface) throws IntentUnsatisfiedException { BundleContext callingContext = sref.getBundle().getBundleContext(); http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/JaxRSUtils.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/JaxRSUtils.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/JaxRSUtils.java index a7fe503..6e78744 100644 --- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/JaxRSUtils.java +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/JaxRSUtils.java @@ -24,7 +24,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import org.apache.cxf.dosgi.dsw.util.ClassUtils; import org.apache.cxf.dosgi.dsw.util.OsgiUtils; import org.apache.cxf.jaxrs.model.UserResource; import org.apache.cxf.jaxrs.provider.aegis.AegisElementProvider; http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/PojoConfigurationTypeHandler.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/PojoConfigurationTypeHandler.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/PojoConfigurationTypeHandler.java index f57fcf3..fefa0ee 100644 --- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/PojoConfigurationTypeHandler.java +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/PojoConfigurationTypeHandler.java @@ -29,7 +29,6 @@ import org.apache.cxf.dosgi.dsw.Constants; import org.apache.cxf.dosgi.dsw.api.Endpoint; import org.apache.cxf.dosgi.dsw.api.IntentUnsatisfiedException; import org.apache.cxf.dosgi.dsw.qos.IntentManager; -import org.apache.cxf.dosgi.dsw.util.ClassUtils; import org.apache.cxf.frontend.ClientProxyFactoryBean; import org.apache.cxf.frontend.ServerFactoryBean; import org.apache.cxf.jaxb.JAXBDataBinding; @@ -55,7 +54,7 @@ public class PojoConfigurationTypeHandler extends AbstractPojoConfigurationTypeH return new String[] {Constants.WS_CONFIG_TYPE, Constants.WS_CONFIG_TYPE_OLD}; } - public Object createProxy(ServiceReference<?> sref, + public Object importEndpoint(BundleContext consumerContext, Class<?> iClass, EndpointDescription endpoint) throws IntentUnsatisfiedException { Map<String, Object> sd = endpoint.getProperties(); @@ -74,8 +73,7 @@ public class PojoConfigurationTypeHandler extends AbstractPojoConfigurationTypeH factory.getServiceFactory().setDataBinding(getDataBinding(sd, iClass)); factory.setServiceClass(iClass); factory.setAddress(address); - BundleContext callingContext = sref.getBundle().getBundleContext(); - addWsInterceptorsFeaturesProps(factory.getClientFactoryBean(), callingContext, sd); + addWsInterceptorsFeaturesProps(factory.getClientFactoryBean(), consumerContext, sd); setClientWsdlProperties(factory.getClientFactoryBean(), bundleContext, sd, false); intentManager.applyIntents(factory.getFeatures(), factory.getClientFactoryBean(), sd); @@ -90,7 +88,7 @@ public class PojoConfigurationTypeHandler extends AbstractPojoConfigurationTypeH return null; } - public Endpoint createServer(ServiceReference<?> sref, + public Endpoint exportService(ServiceReference<?> sref, Map<String, Object> sd, String exportedInterface) throws IntentUnsatisfiedException { BundleContext callingContext = sref.getBundle().getBundleContext(); http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/WsdlConfigurationTypeHandler.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/WsdlConfigurationTypeHandler.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/WsdlConfigurationTypeHandler.java index 3c5e80e..ec0f638 100644 --- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/WsdlConfigurationTypeHandler.java +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/handlers/WsdlConfigurationTypeHandler.java @@ -31,7 +31,6 @@ import org.apache.cxf.databinding.DataBinding; import org.apache.cxf.dosgi.dsw.Constants; import org.apache.cxf.dosgi.dsw.api.Endpoint; import org.apache.cxf.dosgi.dsw.qos.IntentManager; -import org.apache.cxf.dosgi.dsw.util.ClassUtils; import org.apache.cxf.dosgi.dsw.util.OsgiUtils; import org.apache.cxf.jaxb.JAXBDataBinding; import org.apache.cxf.jaxws.JaxWsServerFactoryBean; @@ -55,7 +54,7 @@ public class WsdlConfigurationTypeHandler extends AbstractPojoConfigurationTypeH return new String[] {Constants.WSDL_CONFIG_TYPE}; } - public Object createProxy(ServiceReference<?> serviceReference, + public Object importEndpoint(BundleContext consumerContext, Class<?> iClass, EndpointDescription endpoint) { String wsdlAddressProp = getWsdlAddress(endpoint, iClass); @@ -100,7 +99,7 @@ public class WsdlConfigurationTypeHandler extends AbstractPojoConfigurationTypeH return Service.create(wsdlAddress, serviceQname); } - public Endpoint createServer(ServiceReference<?> sref, + public Endpoint exportService(ServiceReference<?> sref, Map<String, Object> sd, String exportedInterface) { BundleContext callingContext = sref.getBundle().getBundleContext(); http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/qos/IntentUtils.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/qos/IntentUtils.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/qos/IntentUtils.java index 407b2c3..e41dadc 100644 --- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/qos/IntentUtils.java +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/qos/IntentUtils.java @@ -29,7 +29,7 @@ import java.util.Set; import org.apache.cxf.dosgi.dsw.Constants; import org.apache.cxf.dosgi.dsw.util.OsgiUtils; -import org.apache.cxf.dosgi.dsw.util.Utils; +import org.apache.cxf.dosgi.dsw.util.StringPlus; import org.osgi.service.remoteserviceadmin.RemoteConstants; public final class IntentUtils { @@ -40,7 +40,7 @@ public final class IntentUtils { public static String[] getIntentsImplementedByTheService(Map<String, Object> serviceProperties) { // Get the Intents that are implemented by the service - return Utils.normalizeStringPlus(serviceProperties.get(RemoteConstants.SERVICE_INTENTS)); + return StringPlus.normalize(serviceProperties.get(RemoteConstants.SERVICE_INTENTS)); } public static String[] mergeArrays(String[] a1, String[] a2) { http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ClientServiceFactory.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ClientServiceFactory.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ClientServiceFactory.java index df62627..343c406 100644 --- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ClientServiceFactory.java +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ClientServiceFactory.java @@ -59,7 +59,7 @@ public class ClientServiceFactory implements ServiceFactory { final Class<?> iClass = requestingBundle.loadClass(interfaceName); Object proxy = AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { - return handler.createProxy(sreg.getReference(), iClass, endpoint); + return handler.importEndpoint(requestingBundle.getBundleContext(), iClass, endpoint); } }); http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ConfigTypeHandlerFinder.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ConfigTypeHandlerFinder.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ConfigTypeHandlerFinder.java deleted file mode 100644 index 11e9514..0000000 --- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/ConfigTypeHandlerFinder.java +++ /dev/null @@ -1,36 +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.service; - -import java.util.List; -import java.util.Map; - -import org.apache.cxf.dosgi.dsw.api.DistributionProvider; -import org.osgi.framework.BundleContext; -import org.osgi.service.remoteserviceadmin.EndpointDescription; - -public interface ConfigTypeHandlerFinder { - - DistributionProvider getHandler(BundleContext dswBC, Map<String, Object> serviceProperties); - - DistributionProvider getHandler(BundleContext dswBC, EndpointDescription endpoint); - - List<String> getSupportedConfigurationTypes(); - -} http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/EventAdminHelper.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/EventAdminHelper.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/EventAdminHelper.java index ed89389..4868efa 100644 --- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/EventAdminHelper.java +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/EventAdminHelper.java @@ -32,8 +32,6 @@ import org.osgi.service.remoteserviceadmin.RemoteServiceAdminEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static org.apache.cxf.dosgi.dsw.util.Utils.setIfNotNull; - public class EventAdminHelper { private static final Logger LOG = LoggerFactory.getLogger(EventAdminHelper.class); @@ -112,6 +110,12 @@ public class EventAdminHelper { } } + private <K, V> void setIfNotNull(Map<K, V> map, K key, V val) { + if (val != null) { + map.put(key, val); + } + } + private static String remoteServiceAdminEventTypeToString(int type) { String retval; switch (type) { http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/PackageFinder.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/PackageFinder.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/PackageFinder.java new file mode 100644 index 0000000..cc7d4f8 --- /dev/null +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/PackageFinder.java @@ -0,0 +1,47 @@ +/** + * 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.service; + +import java.util.List; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.Version; +import org.osgi.framework.wiring.BundleCapability; +import org.osgi.framework.wiring.BundleWiring; +import org.osgi.service.remoteserviceadmin.EndpointDescription; + +public class PackageFinder { + private BundleContext context; + + public PackageFinder(BundleContext context) { + this.context = context; + } + + public void findPackageFor(String interfaceName, EndpointDescription epd) { + BundleWiring wiring = context.getBundle().adapt(BundleWiring.class); + List<BundleCapability> caps = wiring.getCapabilities("osgi.wiring.package"); + Version version = epd.getPackageVersion(getPackageName(interfaceName)); + } + + + private String getPackageName(String interfaceName) { + return interfaceName.substring(0, interfaceName.lastIndexOf(".")); + } + +} http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminCore.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminCore.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminCore.java index d561079..55a53aa 100644 --- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminCore.java +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminCore.java @@ -34,8 +34,6 @@ import java.util.Set; import org.apache.cxf.dosgi.dsw.api.DistributionProvider; import org.apache.cxf.dosgi.dsw.api.Endpoint; -import org.apache.cxf.dosgi.dsw.util.OsgiUtils; -import org.apache.cxf.dosgi.dsw.util.Utils; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; @@ -67,13 +65,13 @@ public class RemoteServiceAdminCore implements RemoteServiceAdmin { private final BundleContext bctx; private final EventProducer eventProducer; - private final ConfigTypeHandlerFinder configTypeHandlerFinder; private final ServiceListener exportedServiceListener; + private DistributionProvider provider; - public RemoteServiceAdminCore(BundleContext bc, ConfigTypeHandlerFinder configTypeHandlerFinder) { + public RemoteServiceAdminCore(BundleContext bc, DistributionProvider provider) { this.bctx = bc; this.eventProducer = new EventProducer(bctx); - this.configTypeHandlerFinder = configTypeHandlerFinder; + this.provider = provider; // listen for exported services being unregistered so we can close the export this.exportedServiceListener = new ServiceListener() { public void serviceChanged(ServiceEvent event) { @@ -94,20 +92,45 @@ public class RemoteServiceAdminCore implements RemoteServiceAdmin { @SuppressWarnings({ "rawtypes", "unchecked" }) public List<ExportRegistration> exportService(ServiceReference serviceReference, Map additionalProperties) throws IllegalArgumentException, UnsupportedOperationException { - Map<String, Object> serviceProperties = OsgiUtils.getProperties(serviceReference); + Map<String, Object> serviceProperties = getProperties(serviceReference); if (additionalProperties != null) { - OsgiUtils.overlayProperties(serviceProperties, additionalProperties); + overlayProperties(serviceProperties, additionalProperties); } Map<String, Object> key = makeKey(serviceProperties); List<String> interfaces = getInterfaces(serviceProperties); - if (isCreatedByThisRSA(serviceReference)) { - LOG.debug("Skipping export of this service as we created it ourselves as a proxy {}", interfaces); - // TODO: publish error event? Not sure + if (isImportedService(serviceReference)) { return Collections.emptyList(); } + List<ExportRegistration> exportRegs = getExistingRegs(key, interfaces); + if (exportRegs != null) { + return exportRegs; + } + + try { + // do the export + exportRegs = exportInterfaces(interfaces, serviceReference, serviceProperties); + if (!exportRegs.isEmpty()) { + // enlist initial export registrations in global list of exportRegistrations + synchronized (exportedServices) { + exportedServices.put(key, new ArrayList<ExportRegistration>(exportRegs)); + } + eventProducer.publishNotification(exportRegs); + } + return exportRegs; + } finally { + synchronized (exportedServices) { + if (exportedServices.get(key) == exportInProgress) { + exportedServices.remove(key); + } + exportedServices.notifyAll(); // in any case, always notify waiting threads + } + } + } + + private List<ExportRegistration> getExistingRegs(Map<String, Object> key, List<String> interfaces) { synchronized (exportedServices) { // check if it is already exported... Collection<ExportRegistration> existingRegs = exportedServices.get(key); @@ -132,44 +155,18 @@ public class RemoteServiceAdminCore implements RemoteServiceAdmin { // mark export as being in progress exportedServices.put(key, exportInProgress); } - - try { - // do the export - List<ExportRegistration> exportRegs = exportInterfaces(interfaces, serviceReference, serviceProperties); - if (!exportRegs.isEmpty()) { - // enlist initial export registrations in global list of exportRegistrations - synchronized (exportedServices) { - exportedServices.put(key, new ArrayList<ExportRegistration>(exportRegs)); - } - eventProducer.publishNotification(exportRegs); - } - return exportRegs; - } finally { - synchronized (exportedServices) { - if (exportedServices.get(key) == exportInProgress) { - exportedServices.remove(key); - } - exportedServices.notifyAll(); // in any case, always notify waiting threads - } - } + return null; } private List<ExportRegistration> exportInterfaces(List<String> interfaces, ServiceReference<?> serviceReference, Map<String, Object> serviceProperties) { LOG.info("interfaces selected for export: " + interfaces); - DistributionProvider handler; - try { - handler = configTypeHandlerFinder.getHandler(bctx, serviceProperties); - } catch (RuntimeException e) { - LOG.error(e.getMessage(), e); - return Collections.emptyList(); - } List<ExportRegistration> exportRegs = new ArrayList<ExportRegistration>(1); for (String iface : interfaces) { ExportRegistrationImpl exportRegistration; try { LOG.info("creating server for interface " + iface); - Endpoint endpoint = handler.createServer(serviceReference, serviceProperties, iface); + Endpoint endpoint = provider.exportService(serviceReference, serviceProperties, iface); exportRegistration = new ExportRegistrationImpl(serviceReference, endpoint, this); LOG.info("created server for interface " + iface); } catch (Exception e) { @@ -199,27 +196,27 @@ public class RemoteServiceAdminCore implements RemoteServiceAdmin { throw new IllegalArgumentException("service is missing the objectClass property"); } - String[] allowedInterfaces - = Utils.normalizeStringPlus(serviceProperties.get(RemoteConstants.SERVICE_EXPORTED_INTERFACES)); - if (allowedInterfaces == null || allowedInterfaces.length == 0) { + String[] exportedInterfaces + = StringPlus.normalize(serviceProperties.get(RemoteConstants.SERVICE_EXPORTED_INTERFACES)); + if (exportedInterfaces == null || exportedInterfaces.length == 0) { throw new IllegalArgumentException("service is missing the service.exported.interfaces property"); } List<String> interfaces = new ArrayList<String>(1); - if (allowedInterfaces.length == 1 && "*".equals(allowedInterfaces[0])) { + if (exportedInterfaces.length == 1 && "*".equals(exportedInterfaces[0])) { // FIXME: according to the spec, this should only return the interfaces, and not // non-interface classes (which are valid OBJECTCLASS values, even if discouraged) Collections.addAll(interfaces, providedInterfaces); } else { List<String> providedList = Arrays.asList(providedInterfaces); - List<String> allowedList = Arrays.asList(allowedInterfaces); + List<String> allowedList = Arrays.asList(exportedInterfaces); if (!providedList.containsAll(allowedList)) { throw new IllegalArgumentException(String.format( "exported interfaces %s must be a subset of the service's registered types %s", allowedList, providedList)); } - Collections.addAll(interfaces, allowedInterfaces); + Collections.addAll(interfaces, exportedInterfaces); } return interfaces; } @@ -270,8 +267,8 @@ public class RemoteServiceAdminCore implements RemoteServiceAdmin { return copy; } - private boolean isCreatedByThisRSA(ServiceReference<?> sref) { - return bctx.getBundle().equals(sref.getBundle()); // sref bundle can be null + private boolean isImportedService(ServiceReference<?> sref) { + return sref.getProperty(RemoteConstants.SERVICE_IMPORTED) != null; } @Override @@ -318,15 +315,14 @@ public class RemoteServiceAdminCore implements RemoteServiceAdmin { return ir; } - DistributionProvider handler = configTypeHandlerFinder.getHandler(bctx, endpoint); - - // TODO: somehow select the interfaces that should be imported ---> job of the TopologyManager? - List<String> matchingInterfaces = endpoint.getInterfaces(); - - if (handler == null) { + if (!provider.canHandle(endpoint)) { LOG.info("No matching handler can be found for remote endpoint {}.", endpoint.getId()); return null; } + + // TODO: somehow select the interfaces that should be imported ---> job of the TopologyManager? + List<String> matchingInterfaces = endpoint.getInterfaces(); + if (matchingInterfaces.size() == 0) { LOG.info("No matching interfaces found for remote endpoint {}.", endpoint.getId()); return null; @@ -337,11 +333,11 @@ public class RemoteServiceAdminCore implements RemoteServiceAdmin { endpoint.getId()); return null; } - + LOG.info("Importing service {} with interfaces {} using handler {}.", - endpoint.getId(), endpoint.getInterfaces(), handler.getClass()); + endpoint.getId(), endpoint.getInterfaces(), provider.getClass()); - ImportRegistrationImpl imReg = exposeServiceFactory(matchingInterfaces.get(0), endpoint, handler); + ImportRegistrationImpl imReg = exposeServiceFactory(matchingInterfaces.get(0), endpoint, provider); if (imRegs == null) { imRegs = new ArrayList<ImportRegistrationImpl>(); importedServices.put(endpoint, imRegs); @@ -489,4 +485,48 @@ public class RemoteServiceAdminCore implements RemoteServiceAdmin { removeImportRegistrations(); bctx.removeServiceListener(exportedServiceListener); } + + static void overlayProperties(Map<String, Object> serviceProperties, + Map<String, Object> additionalProperties) { + Map<String, String> keysLowerCase = new HashMap<String, String>(); + for (String key : serviceProperties.keySet()) { + keysLowerCase.put(key.toLowerCase(), key); + } + + for (Map.Entry<String, Object> e : additionalProperties.entrySet()) { + String key = e.getKey(); + String lowerKey = key.toLowerCase(); + if (org.osgi.framework.Constants.SERVICE_ID.toLowerCase().equals(lowerKey) + || org.osgi.framework.Constants.OBJECTCLASS.toLowerCase().equals(lowerKey)) { + // objectClass and service.id must not be overwritten + LOG.info("exportService called with additional properties map that contained illegal key: " + + key + ", the key is ignored"); + } else { + String origKey = keysLowerCase.get(lowerKey); + if (origKey != null) { + LOG.debug("Overwriting property [{}] with value [{}]", origKey, e.getValue()); + } else { + origKey = key; + keysLowerCase.put(lowerKey, origKey); + } + serviceProperties.put(origKey, e.getValue()); + } + } + } + + /** + * Returns a service's properties as a map. + * + * @param serviceReference a service reference + * @return the service's properties as a map + */ + private Map<String, Object> getProperties(ServiceReference<?> serviceReference) { + String[] keys = serviceReference.getPropertyKeys(); + Map<String, Object> props = new HashMap<String, Object>(keys.length); + for (String key : keys) { + Object val = serviceReference.getProperty(key); + props.put(key, val); + } + return props; + } } http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminInstance.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminInstance.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminInstance.java index 286ce54..fc3a67e 100644 --- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminInstance.java +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/RemoteServiceAdminInstance.java @@ -25,8 +25,8 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import org.apache.cxf.dosgi.dsw.util.OsgiUtils; import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; import org.osgi.framework.ServiceReference; import org.osgi.service.remoteserviceadmin.EndpointDescription; import org.osgi.service.remoteserviceadmin.EndpointPermission; @@ -36,8 +36,6 @@ import org.osgi.service.remoteserviceadmin.ImportReference; import org.osgi.service.remoteserviceadmin.ImportRegistration; import org.osgi.service.remoteserviceadmin.RemoteServiceAdmin; -import static org.apache.cxf.dosgi.dsw.util.OsgiUtils.checkPermission; - public class RemoteServiceAdminInstance implements RemoteServiceAdmin { private final BundleContext bctx; @@ -75,7 +73,8 @@ public class RemoteServiceAdminInstance implements RemoteServiceAdmin { @Override public ImportRegistration importService(final EndpointDescription endpoint) { - checkPermission(new EndpointPermission(endpoint, OsgiUtils.getUUID(bctx), EndpointPermission.IMPORT)); + String frameworkUUID = bctx.getProperty(Constants.FRAMEWORK_UUID); + checkPermission(new EndpointPermission(endpoint, frameworkUUID, EndpointPermission.IMPORT)); return AccessController.doPrivileged(new PrivilegedAction<ImportRegistration>() { public ImportRegistration run() { return closed ? null : rsaCore.importService(endpoint); @@ -90,4 +89,11 @@ public class RemoteServiceAdminInstance implements RemoteServiceAdmin { rsaCore.close(); } } + + private void checkPermission(EndpointPermission permission) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(permission); + } + } } http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/StringPlus.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/StringPlus.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/StringPlus.java new file mode 100644 index 0000000..e449f1d --- /dev/null +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/service/StringPlus.java @@ -0,0 +1,72 @@ +/** + * 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.service; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class StringPlus { + + private static final Logger LOG = LoggerFactory.getLogger(StringPlus.class); + + private StringPlus() { + // never constructed + } + + @SuppressWarnings("rawtypes") + public static String[] normalize(Object object) { + if (object instanceof String) { + String s = (String)object; + String[] values = s.split(","); + List<String> list = new ArrayList<String>(); + for (String val : values) { + String actualValue = val.trim(); + if (!actualValue.isEmpty()) { + list.add(actualValue); + } + } + return list.toArray(new String[list.size()]); + } + + if (object instanceof String[]) { + return (String[])object; + } + + if (object instanceof Collection) { + Collection col = (Collection)object; + List<String> ar = new ArrayList<String>(col.size()); + for (Object o : col) { + if (o instanceof String) { + String s = (String)o; + ar.add(s); + } else { + LOG.warn("stringPlus contained non string element in list! Element was skipped"); + } + } + return ar.toArray(new String[ar.size()]); + } + + return null; + } + +} http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/util/ClassUtils.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/util/ClassUtils.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/util/ClassUtils.java deleted file mode 100644 index d51527b..0000000 --- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/util/ClassUtils.java +++ /dev/null @@ -1,142 +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.util; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.apache.cxf.helpers.CastUtils; -import org.osgi.framework.BundleContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class ClassUtils { - - private static final Logger LOG = LoggerFactory.getLogger(ClassUtils.class); - - private ClassUtils() { - } - - public static Class<?> getInterfaceClass(Object service, String interfaceName) { - return getInterfaceClass(service.getClass(), interfaceName); - } - - private static Class<?> getInterfaceClass(Class<?> serviceClass, String interfaceName) { - for (Class<?> iClass : serviceClass.getInterfaces()) { - if (iClass.getName().equals(interfaceName)) { - return iClass; - } - Class<?> intf = getInterfaceClass(iClass, interfaceName); - if (intf != null) { - return intf; - } - } - - if (serviceClass.getName().equals(interfaceName)) { - return serviceClass; - } - - Class<?> interfaceOnProxiedClass = getInterfaceClassOnSuperClasses(serviceClass, interfaceName); - if (interfaceOnProxiedClass != null) { - return interfaceOnProxiedClass; - } - - return null; - } - - /** - * This method tries to deal specifically with classes that might have been proxied - * eg. CGLIB proxies of which there might be a chain of proxies as different osgi frameworks - * might be proxying the original service class that has been registered and then proxying the proxy. - * - * @param serviceClass - * @param interfaceName - * @return - */ - private static Class<?> getInterfaceClassOnSuperClasses(Class<?> serviceClass, String interfaceName) { - Class<?> superClass = serviceClass.getSuperclass(); - if (superClass != null) { - for (Class<?> iClass : superClass.getInterfaces()) { - if (iClass.getName().equals(interfaceName)) { - return iClass; - } - Class<?> intf = getInterfaceClass(iClass, interfaceName); - if (intf != null) { - return intf; - } - } - Class<?> foundOnSuperclass = getInterfaceClassOnSuperClasses(superClass, interfaceName); - if (foundOnSuperclass != null) { - return foundOnSuperclass; - } - } - return null; - } - - public static List<Object> loadProviderClasses(BundleContext callingContext, - Map<String, Object> sd, String propName) { - Object serviceProviders = sd.get(propName); - if (serviceProviders != null) { - if (serviceProviders.getClass().isArray()) { - if (serviceProviders.getClass().getComponentType() == String.class) { - return loadProviders(callingContext, (String[])serviceProviders); - } else { - return Arrays.asList((Object[])serviceProviders); - } - } else if (serviceProviders.getClass() == String.class) { - String[] classNames = serviceProviders.toString().split(","); - return loadProviders(callingContext, classNames); - } else if (serviceProviders instanceof List) { - List<Object> list = CastUtils.cast((List<?>)serviceProviders); - if (!list.isEmpty()) { - List<Object> providers; - if (list.get(0).getClass() == String.class) { - providers = loadProviders(callingContext, list.toArray(new String[]{})); - } else { - providers = list; - } - return providers; - } - } else { - return Arrays.asList(serviceProviders); - } - } - return Collections.emptyList(); - - } - - private static List<Object> loadProviders(BundleContext callingContext, String[] classNames) { - List<Object> providers = new ArrayList<Object>(); - for (String className : classNames) { - try { - String realName = className.trim(); - if (!realName.isEmpty()) { - Class<?> pClass = callingContext.getBundle().loadClass(realName); - providers.add(pClass.newInstance()); - } - } catch (Exception ex) { - LOG.warn("Provider " + className.trim() + " can not be loaded or created " + ex.getMessage(), ex); - } - } - return providers; - } -} http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/util/OsgiUtils.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/util/OsgiUtils.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/util/OsgiUtils.java index 61f2e1e..9acd0f0 100644 --- a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/util/OsgiUtils.java +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/util/OsgiUtils.java @@ -21,9 +21,7 @@ package org.apache.cxf.dosgi.dsw.util; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.Map; -import java.util.UUID; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; @@ -31,7 +29,6 @@ import org.osgi.framework.ServiceReference; import org.osgi.service.packageadmin.ExportedPackage; import org.osgi.service.packageadmin.PackageAdmin; import org.osgi.service.remoteserviceadmin.EndpointDescription; -import org.osgi.service.remoteserviceadmin.EndpointPermission; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -132,66 +129,4 @@ public final class OsgiUtils { + ". Falling back to 0.0.0"); return "0.0.0"; } - - public static String getUUID(BundleContext bc) { - synchronized ("org.osgi.framework.uuid") { - String uuid = bc.getProperty("org.osgi.framework.uuid"); - if (uuid == null) { - uuid = UUID.randomUUID().toString(); - System.setProperty("org.osgi.framework.uuid", uuid); - } - return uuid; - } - } - - public static void overlayProperties(Map<String, Object> serviceProperties, - Map<String, Object> additionalProperties) { - Map<String, String> keysLowerCase = new HashMap<String, String>(); - for (String key : serviceProperties.keySet()) { - keysLowerCase.put(key.toLowerCase(), key); - } - - for (Map.Entry<String, Object> e : additionalProperties.entrySet()) { - String key = e.getKey(); - String lowerKey = key.toLowerCase(); - if (org.osgi.framework.Constants.SERVICE_ID.toLowerCase().equals(lowerKey) - || org.osgi.framework.Constants.OBJECTCLASS.toLowerCase().equals(lowerKey)) { - // objectClass and service.id must not be overwritten - LOG.info("exportService called with additional properties map that contained illegal key: " - + key + ", the key is ignored"); - } else { - String origKey = keysLowerCase.get(lowerKey); - if (origKey != null) { - LOG.debug("Overwriting property [{}] with value [{}]", origKey, e.getValue()); - } else { - origKey = key; - keysLowerCase.put(lowerKey, origKey); - } - serviceProperties.put(origKey, e.getValue()); - } - } - } - - /** - * Returns a service's properties as a map. - * - * @param serviceReference a service reference - * @return the service's properties as a map - */ - public static Map<String, Object> getProperties(ServiceReference<?> serviceReference) { - String[] keys = serviceReference.getPropertyKeys(); - Map<String, Object> props = new HashMap<String, Object>(keys.length); - for (String key : keys) { - Object val = serviceReference.getProperty(key); - props.put(key, val); - } - return props; - } - - public static void checkPermission(EndpointPermission permission) { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(permission); - } - } } http://git-wip-us.apache.org/repos/asf/cxf-dosgi/blob/f54fb69b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/util/StringPlus.java ---------------------------------------------------------------------- diff --git a/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/util/StringPlus.java b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/util/StringPlus.java new file mode 100644 index 0000000..dbb4cda --- /dev/null +++ b/dsw/cxf-dsw/src/main/java/org/apache/cxf/dosgi/dsw/util/StringPlus.java @@ -0,0 +1,72 @@ +/** + * 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.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class StringPlus { + + private static final Logger LOG = LoggerFactory.getLogger(StringPlus.class); + + private StringPlus() { + // never constructed + } + + @SuppressWarnings("rawtypes") + public static String[] normalize(Object object) { + if (object instanceof String) { + String s = (String)object; + String[] values = s.split(","); + List<String> list = new ArrayList<String>(); + for (String val : values) { + String actualValue = val.trim(); + if (!actualValue.isEmpty()) { + list.add(actualValue); + } + } + return list.toArray(new String[list.size()]); + } + + if (object instanceof String[]) { + return (String[])object; + } + + if (object instanceof Collection) { + Collection col = (Collection)object; + List<String> ar = new ArrayList<String>(col.size()); + for (Object o : col) { + if (o instanceof String) { + String s = (String)o; + ar.add(s); + } else { + LOG.warn("stringPlus contained non string element in list! Element was skipped"); + } + } + return ar.toArray(new String[ar.size()]); + } + + return null; + } + +}
