Author: remm Date: Wed Apr 4 08:18:32 2007 New Revision: 525530 URL: http://svn.apache.org/viewvc?view=rev&rev=525530 Log: - Add the factories for ws. - Submitted by Fabien Carrion.
Added: tomcat/tc6.0.x/trunk/java/org/apache/naming/factory/webservices/ tomcat/tc6.0.x/trunk/java/org/apache/naming/factory/webservices/ServiceProxy.java (with props) tomcat/tc6.0.x/trunk/java/org/apache/naming/factory/webservices/ServiceRefFactory.java (with props) Modified: tomcat/tc6.0.x/trunk/java/org/apache/naming/factory/Constants.java Modified: tomcat/tc6.0.x/trunk/java/org/apache/naming/factory/Constants.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/naming/factory/Constants.java?view=diff&rev=525530&r1=525529&r2=525530 ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/naming/factory/Constants.java (original) +++ tomcat/tc6.0.x/trunk/java/org/apache/naming/factory/Constants.java Wed Apr 4 08:18:32 2007 @@ -43,7 +43,7 @@ Package + ".EjbFactory"; public static final String DEFAULT_SERVICE_FACTORY = - Package + ".ServiceRefFactory"; + Package + ".webservices.ServiceRefFactory"; public static final String DEFAULT_HANDLER_FACTORY = Package + ".HandlerFactory"; Added: tomcat/tc6.0.x/trunk/java/org/apache/naming/factory/webservices/ServiceProxy.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/naming/factory/webservices/ServiceProxy.java?view=auto&rev=525530 ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/naming/factory/webservices/ServiceProxy.java (added) +++ tomcat/tc6.0.x/trunk/java/org/apache/naming/factory/webservices/ServiceProxy.java Wed Apr 4 08:18:32 2007 @@ -0,0 +1,147 @@ +/* + * 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.naming.factory.webservices; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.rmi.Remote; +import java.util.Hashtable; +import java.util.Iterator; + +import javax.xml.namespace.QName; +import javax.xml.rpc.Service; +import javax.xml.rpc.ServiceException; + +/** + * Object proxy for Web Services. + * + * @author Fabien Carrion + */ + +public class ServiceProxy + implements InvocationHandler { + + /** + * Service object. + * used for delegation + */ + private Service service = null; + + /** + * changing behavior to method : Service.getPort(QName, Class) + */ + private static Method portQNameClass = null; + + /** + * changing behavior to method : Service.getPort(Class) + */ + private static Method portClass = null; + + /** + * PortComponentRef list + */ + private Hashtable portComponentRef = null; + + /** + * Constructs a new ServiceProxy wrapping given Service instance. + * @param service the wrapped Service instance + * @throws ServiceException should be never thrown + */ + public ServiceProxy(Service service) throws ServiceException { + this.service = service; + try { + portQNameClass = Service.class.getDeclaredMethod("getPort", new Class[]{QName.class, Class.class}); + portClass = Service.class.getDeclaredMethod("getPort", new Class[]{Class.class}); + } catch (Exception e) { + throw new ServiceException(e); + } + } + + /** + * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) + */ + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + + if (portQNameClass.equals(method)) { + return getProxyPortQNameClass(args); + } + + if (portClass.equals(method)) { + return getProxyPortClass(args); + } + + try { + return method.invoke(service, args); + } catch (InvocationTargetException ite) { + throw ite.getTargetException(); + } + } + + /** + * @param args Method call arguments + * @return Returns the correct Port + * @throws ServiceException if port's QName is an unknown Port (not defined in WSDL). + */ + private Object getProxyPortQNameClass(Object[] args) + throws ServiceException { + QName name = (QName) args[0]; + String nameString = name.getLocalPart(); + Class serviceendpointClass = (Class) args[1]; + + for (Iterator ports = service.getPorts(); ports.hasNext();) { + QName portName = (QName) ports.next(); + String portnameString = portName.getLocalPart(); + if (portnameString.equals(nameString)) { + return service.getPort(name, serviceendpointClass); + } + } + + // no ports have been found + throw new ServiceException("Port-component-ref : " + name + " not found"); + } + + /** + * @param portComponentRef List + */ + public void setPortComponentRef(Hashtable portComponentRef) { + this.portComponentRef = portComponentRef; + } + + /** + * @param args Method call arguments + * @return Returns the correct Port + * @throws ServiceException if port's QName is an unknown Port + */ + private Remote getProxyPortClass(Object[] args) + throws ServiceException { + Class serviceendpointClass = (Class) args[0]; + + if (this.portComponentRef == null) + return service.getPort(serviceendpointClass); + + QName portname = (QName) this.portComponentRef.get(serviceendpointClass.getName()); + if (portname != null) { + return service.getPort(portname, serviceendpointClass); + } else { + return service.getPort(serviceendpointClass); + } + } + +} Propchange: tomcat/tc6.0.x/trunk/java/org/apache/naming/factory/webservices/ServiceProxy.java ------------------------------------------------------------------------------ svn:eol-style = native Added: tomcat/tc6.0.x/trunk/java/org/apache/naming/factory/webservices/ServiceRefFactory.java URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/naming/factory/webservices/ServiceRefFactory.java?view=auto&rev=525530 ============================================================================== --- tomcat/tc6.0.x/trunk/java/org/apache/naming/factory/webservices/ServiceRefFactory.java (added) +++ tomcat/tc6.0.x/trunk/java/org/apache/naming/factory/webservices/ServiceRefFactory.java Wed Apr 4 08:18:32 2007 @@ -0,0 +1,369 @@ +/* + * 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.naming.factory.webservices; + +import java.net.URL; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Properties; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.Name; +import javax.naming.NamingException; +import javax.naming.spi.ObjectFactory; +import javax.naming.Reference; +import javax.naming.RefAddr; + +import javax.wsdl.Definition; +import javax.wsdl.Port; +import javax.wsdl.extensions.ExtensibilityElement; +import javax.wsdl.extensions.soap.SOAPAddress; +import javax.wsdl.factory.WSDLFactory; +import javax.wsdl.xml.WSDLReader; + +import javax.xml.namespace.QName; +import javax.xml.rpc.handler.HandlerChain; +import javax.xml.rpc.handler.HandlerInfo; +import javax.xml.rpc.handler.HandlerRegistry; +import javax.xml.rpc.Service; +import javax.xml.rpc.ServiceFactory; + +import org.apache.naming.HandlerRef; +import org.apache.naming.ServiceRef; + +/** + * Object factory for Web Services. + * + * @author Fabien Carrion + */ + +public class ServiceRefFactory + implements ObjectFactory { + + + // ----------------------------------------------------------- Constructors + + + // -------------------------------------------------------------- Constants + + + // ----------------------------------------------------- Instance Variables + + + // --------------------------------------------------------- Public Methods + + + // -------------------------------------------------- ObjectFactory Methods + + + /** + * Crete a new serviceref instance. + * + * @param obj The reference object describing the webservice + */ + public Object getObjectInstance(Object obj, Name name, Context nameCtx, + Hashtable environment) + throws Exception { + + if (obj instanceof ServiceRef) { + Reference ref = (Reference) obj; + + // ClassLoader + ClassLoader tcl = + Thread.currentThread().getContextClassLoader(); + if (tcl == null) + tcl = this.getClass().getClassLoader(); + ServiceFactory factory = ServiceFactory.newInstance(); + javax.xml.rpc.Service service = null; + + // Service Interface + RefAddr tmp = ref.get(ServiceRef.SERVICE_INTERFACE); + String serviceInterface = null; + if (tmp != null) + serviceInterface = (String) tmp.getContent(); + + // WSDL + tmp = ref.get(ServiceRef.WSDL); + String wsdlRefAddr = null; + if (tmp != null) + wsdlRefAddr = (String) tmp.getContent(); + + // PortComponent + Hashtable portComponentRef = new Hashtable(); + + // Create QName object + QName serviceQname = null; + tmp = ref.get(ServiceRef.SERVICE_LOCAL_PART); + if (tmp != null) { + String serviceLocalPart = (String) tmp.getContent(); + tmp = ref.get(ServiceRef.SERVICE_NAMESPACE); + if (tmp == null) { + serviceQname = new QName(serviceLocalPart); + } else { + String serviceNamespace = (String) tmp.getContent(); + serviceQname = new QName(serviceNamespace, + serviceLocalPart); + } + } + Class serviceInterfaceClass = null; + + // Create service object + if (serviceInterface == null) { + if (serviceQname == null) { + throw new NamingException + ("Could not create service-ref instance"); + } + try { + if (wsdlRefAddr == null) { + service = factory.createService( serviceQname ); + } else { + service = factory.createService( new URL(wsdlRefAddr), + serviceQname ); + } + } catch (Throwable t) { + NamingException ex = new NamingException + ("Could not create service"); + ex.initCause(t); + throw ex; + } + } else { + // Loading service Interface + try { + serviceInterfaceClass = tcl.loadClass(serviceInterface); + } catch(ClassNotFoundException e) { + NamingException ex = new NamingException + ("Could not load service Interface"); + ex.initCause(e); + throw ex; + } + if (serviceInterfaceClass == null) { + throw new NamingException + ("Could not load service Interface"); + } + try { + if (wsdlRefAddr == null) { + if (!Service.class.isAssignableFrom(serviceInterfaceClass)) { + throw new NamingException + ("service Interface should extend javax.xml.rpc.Service"); + } + service = factory.loadService( serviceInterfaceClass ); + } else { + service = factory.loadService( new URL(wsdlRefAddr), + serviceInterfaceClass, + new Properties() ); + } + } catch (Throwable t) { + NamingException ex = new NamingException + ("Could not create service"); + ex.initCause(t); + throw ex; + } + } + if (service == null) { + throw new NamingException + ("Cannot create service object"); + } + serviceQname = service.getServiceName(); + serviceInterfaceClass = service.getClass(); + if (wsdlRefAddr != null) { + try { + WSDLFactory wsdlfactory = WSDLFactory.newInstance(); + WSDLReader reader = wsdlfactory.newWSDLReader(); + reader.setFeature("javax.wsdl.importDocuments", true); + Definition def = reader.readWSDL((new URL(wsdlRefAddr)).toExternalForm()); + + javax.wsdl.Service wsdlservice = def.getService(serviceQname); + Map ports = wsdlservice.getPorts(); + Method m = serviceInterfaceClass.getMethod("setEndpointAddress", + new Class[] { java.lang.String.class, + java.lang.String.class }); + for (Iterator i = ports.keySet().iterator(); i.hasNext();) { + String portName = (String) i.next(); + Port port = wsdlservice.getPort(portName); + String endpoint = getSOAPLocation(port); + m.invoke(service, new Object[] {port.getName(), endpoint }); + portComponentRef.put(endpoint, new QName(port.getName())); + } + } catch (Throwable t) { + // Wsdl File not available + } + } + + ServiceProxy proxy = new ServiceProxy(service); + + // Use port-component-ref + for (int i = 0; i < ref.size(); i++) + if (ServiceRef.SERVICEENDPOINTINTERFACE.equals(ref.get(i).getType())) { + String serviceendpoint = ""; + String portlink = ""; + serviceendpoint = (String) ref.get(i).getContent(); + if (ServiceRef.PORTCOMPONENTLINK.equals(ref.get(i + 1).getType())) { + i++; + portlink = (String) ref.get(i).getContent(); + } + portComponentRef.put(serviceendpoint, new QName(portlink)); + + } + proxy.setPortComponentRef(portComponentRef); + + // Instantiate service with proxy class + Class[] interfaces = null; + Class[] serviceInterfaces = serviceInterfaceClass.getInterfaces(); + if (serviceInterfaceClass != null) { + interfaces = new Class[serviceInterfaces.length + 1]; + for (int i = 0; i < serviceInterfaces.length; i++) { + interfaces[i] = serviceInterfaces[i]; + } + } else { + interfaces = new Class[1]; + } + interfaces[interfaces.length - 1] = javax.xml.rpc.Service.class; + Object proxyInstance = null; + try { + proxyInstance = Proxy.newProxyInstance(tcl, interfaces, proxy); + } catch (IllegalArgumentException e) { + proxyInstance = Proxy.newProxyInstance(tcl, serviceInterfaces, proxy); + } + + // Use handler + if (((ServiceRef) ref).getHandlersSize() > 0) { + + HandlerRegistry handlerRegistry = service.getHandlerRegistry(); + ArrayList soaproles = new ArrayList(); + + while (((ServiceRef) ref).getHandlersSize() > 0) { + HandlerRef handler = ((ServiceRef) ref).getHandler(); + HandlerInfo handlerref = new HandlerInfo(); + + // Loading handler Class + tmp = handler.get(HandlerRef.HANDLER_CLASS); + if ((tmp == null) || (tmp.getContent() == null)) + break; + Class handlerClass = null; + try { + handlerClass = tcl.loadClass((String) tmp.getContent()); + } catch(ClassNotFoundException e) { + break; + } + + // Load all datas relative to the handler : SOAPHeaders, config init element, + // portNames to be set on + ArrayList headers = new ArrayList(); + Hashtable config = new Hashtable(); + ArrayList portNames = new ArrayList(); + for (int i = 0; i < handler.size(); i++) + if (HandlerRef.HANDLER_LOCALPART.equals(handler.get(i).getType())) { + String localpart = ""; + String namespace = ""; + localpart = (String) handler.get(i).getContent(); + if (HandlerRef.HANDLER_NAMESPACE.equals(handler.get(i + 1).getType())) { + i++; + namespace = (String) handler.get(i).getContent(); + } + QName header = new QName(namespace, localpart); + headers.add(header); + } else if (HandlerRef.HANDLER_PARAMNAME.equals(handler.get(i).getType())) { + String paramName = ""; + String paramValue = ""; + paramName = (String) handler.get(i).getContent(); + if (HandlerRef.HANDLER_PARAMVALUE.equals(handler.get(i + 1).getType())) { + i++; + paramValue = (String) handler.get(i).getContent(); + } + config.put(paramName, paramValue); + } else if (HandlerRef.HANDLER_SOAPROLE.equals(handler.get(i).getType())) { + String soaprole = ""; + soaprole = (String) handler.get(i).getContent(); + soaproles.add(soaprole); + } else if (HandlerRef.HANDLER_PORTNAME.equals(handler.get(i).getType())) { + String portName = ""; + portName = (String) handler.get(i).getContent(); + portNames.add(portName); + } + + // Set the handlers informations + handlerref.setHandlerClass(handlerClass); + handlerref.setHeaders((QName []) headers.toArray(new QName[headers.size()])); + handlerref.setHandlerConfig(config); + + if (!portNames.isEmpty()) { + Iterator iter = portNames.iterator(); + while (iter.hasNext()) + initHandlerChain(new QName((String) iter.next()), handlerRegistry, + handlerref, soaproles); + } else { + Enumeration e = portComponentRef.elements(); + while(e.hasMoreElements()) + initHandlerChain((QName) e.nextElement(), handlerRegistry, + handlerref, soaproles); + } + } + } + + return proxyInstance; + + } + + return null; + + } + + /** + * @param port analyzed port + * @return Returns the endpoint URL of the given Port + */ + private String getSOAPLocation(Port port) { + String endpoint = null; + List extensions = port.getExtensibilityElements(); + for (Iterator i = extensions.iterator(); i.hasNext();) { + ExtensibilityElement ext = (ExtensibilityElement) i.next(); + if (ext instanceof SOAPAddress) { + SOAPAddress addr = (SOAPAddress) ext; + endpoint = addr.getLocationURI(); + } + } + return endpoint; + } + + + private void initHandlerChain(QName portName, HandlerRegistry handlerRegistry, + HandlerInfo handlerref, ArrayList soaprolesToAdd) { + HandlerChain handlerList = (HandlerChain) handlerRegistry.getHandlerChain(portName); + handlerList.add(handlerref); + String[] soaprolesRegistered = handlerList.getRoles(); + String [] soaproles = new String[soaprolesRegistered.length + soaprolesToAdd.size()]; + int i; + for (i = 0;i < soaprolesRegistered.length; i++) + soaproles[i] = soaprolesRegistered[i]; + for (int j = 0; j < soaprolesToAdd.size(); j++) + soaproles[i+j] = (String) soaprolesToAdd.get(j); + handlerList.setRoles(soaproles); + handlerRegistry.setHandlerChain(portName, handlerList); + } + + +} Propchange: tomcat/tc6.0.x/trunk/java/org/apache/naming/factory/webservices/ServiceRefFactory.java ------------------------------------------------------------------------------ svn:eol-style = native --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]