| /** |
| * 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.Proxy; |
| import java.net.URL; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javax.xml.namespace.QName; |
| |
| import org.apache.cxf.Bus; |
| import org.apache.cxf.BusFactory; |
| import org.apache.cxf.common.util.PackageUtils; |
| 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.qos.IntentManager; |
| import org.apache.cxf.dosgi.dsw.qos.IntentUtils; |
| import org.apache.cxf.dosgi.dsw.util.OsgiUtils; |
| 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.framework.ServiceReference; |
| import org.osgi.service.remoteserviceadmin.EndpointDescription; |
| import org.osgi.service.remoteserviceadmin.RemoteConstants; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| public abstract class AbstractPojoConfigurationTypeHandler implements DistributionProvider { |
| |
| private static final Logger LOG = LoggerFactory.getLogger(AbstractPojoConfigurationTypeHandler.class); |
| protected BundleContext bundleContext; |
| protected IntentManager intentManager; |
| protected HttpServiceManager httpServiceManager; |
| |
| public AbstractPojoConfigurationTypeHandler(BundleContext dswBC, IntentManager intentManager, |
| HttpServiceManager httpServiceManager) { |
| this.bundleContext = dswBC; |
| this.intentManager = intentManager; |
| this.httpServiceManager = httpServiceManager; |
| } |
| |
| protected Object getProxy(Object serviceProxy, Class<?> iType) { |
| return Proxy.newProxyInstance(iType.getClassLoader(), new Class[] { |
| iType |
| }, new ServiceInvocationHandler(serviceProxy, iType)); |
| } |
| |
| protected Map<String, Object> createEndpointProps(Map<String, Object> sd, Class<?> iClass, |
| String[] importedConfigs, String address, String[] intents) { |
| Map<String, Object> props = new HashMap<String, Object>(); |
| |
| copyEndpointProperties(sd, props); |
| |
| String[] sa = new String[] { |
| iClass.getName() |
| }; |
| String pkg = iClass.getPackage().getName(); |
| |
| 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)); |
| 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)); |
| |
| 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); |
| } |
| } |
| |
| String[] allIntents = IntentUtils.mergeArrays(intents, IntentUtils.getIntentsImplementedByTheService(sd)); |
| props.put(RemoteConstants.SERVICE_INTENTS, allIntents); |
| props.put(RemoteConstants.ENDPOINT_ID, address); |
| return props; |
| } |
| |
| private void copyEndpointProperties(Map<String, Object> sd, Map<String, Object> endpointProps) { |
| Set<Map.Entry<String, Object>> keys = sd.entrySet(); |
| for (Map.Entry<String, Object> entry : keys) { |
| try { |
| String skey = entry.getKey(); |
| if (!skey.startsWith(".")) { |
| endpointProps.put(skey, entry.getValue()); |
| } |
| } catch (ClassCastException e) { |
| LOG.warn("ServiceProperties Map contained non String key. Skipped " + entry + " " |
| + e.getLocalizedMessage()); |
| } |
| } |
| } |
| |
| 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, |
| Constants.WS_ADDRESS_PROPERTY_OLD, |
| Constants.RS_ADDRESS_PROPERTY); |
| } |
| |
| protected String getServerAddress(Map<String, Object> sd, Class<?> iClass) { |
| String address = getClientAddress(sd); |
| return address == null ? httpServiceManager.getDefaultAddress(iClass) : address; |
| } |
| |
| public String getServletContextRoot(Map<String, Object> sd) { |
| return OsgiUtils.getFirstNonEmptyStringProperty(sd, |
| Constants.WS_HTTP_SERVICE_CONTEXT, |
| Constants.WS_HTTP_SERVICE_CONTEXT_OLD, |
| Constants.WSDL_HTTP_SERVICE_CONTEXT, |
| Constants.RS_HTTP_SERVICE_CONTEXT); |
| } |
| |
| |
| protected Bus createBus(ServiceReference<?> sref, BundleContext callingContext, String contextRoot) { |
| Bus bus = BusFactory.newInstance().createBus(); |
| if (contextRoot != null) { |
| httpServiceManager.registerServlet(bus, contextRoot, callingContext, sref); |
| } |
| return bus; |
| } |
| |
| protected Endpoint createServerFromFactory(ServerFactoryBean factory, Map<String, Object> endpointProps) { |
| ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); |
| try { |
| Thread.currentThread().setContextClassLoader(ServerFactoryBean.class.getClassLoader()); |
| Server server = factory.create(); |
| EndpointDescription epd = new EndpointDescription(endpointProps); |
| return new ServerWrapper(epd, server); |
| } finally { |
| Thread.currentThread().setContextClassLoader(oldClassLoader); |
| } |
| } |
| |
| 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); |
| addContextProperties(factory, sd, Constants.WS_CONTEXT_PROPS_PROP_KEY); |
| } |
| |
| 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); |
| if (props != null) { |
| factory.getProperties(true).putAll(props); |
| } |
| } |
| |
| @Override |
| public boolean canHandle(EndpointDescription endpoint) { |
| // Will be handled by CXFDistributionProvider at the moment |
| throw new IllegalStateException(); |
| } |
| } |