001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: package org.apache.naming.factory.webservices;
020:
021: import java.net.URL;
022: import java.lang.reflect.Method;
023: import java.lang.reflect.Proxy;
024: import java.util.ArrayList;
025: import java.util.Enumeration;
026: import java.util.Properties;
027: import java.util.Hashtable;
028: import java.util.Iterator;
029: import java.util.List;
030: import java.util.Map;
031:
032: import javax.naming.Context;
033: import javax.naming.InitialContext;
034: import javax.naming.Name;
035: import javax.naming.NamingException;
036: import javax.naming.spi.ObjectFactory;
037: import javax.naming.Reference;
038: import javax.naming.RefAddr;
039:
040: import javax.wsdl.Definition;
041: import javax.wsdl.Port;
042: import javax.wsdl.extensions.ExtensibilityElement;
043: import javax.wsdl.extensions.soap.SOAPAddress;
044: import javax.wsdl.factory.WSDLFactory;
045: import javax.wsdl.xml.WSDLReader;
046:
047: import javax.xml.namespace.QName;
048: import javax.xml.rpc.handler.HandlerChain;
049: import javax.xml.rpc.handler.HandlerInfo;
050: import javax.xml.rpc.handler.HandlerRegistry;
051: import javax.xml.rpc.Service;
052: import javax.xml.rpc.ServiceFactory;
053:
054: import org.apache.naming.HandlerRef;
055: import org.apache.naming.ServiceRef;
056:
057: /**
058: * Object factory for Web Services.
059: *
060: * @author Fabien Carrion
061: */
062:
063: public class ServiceRefFactory implements ObjectFactory {
064:
065: // ----------------------------------------------------------- Constructors
066:
067: // -------------------------------------------------------------- Constants
068:
069: // ----------------------------------------------------- Instance Variables
070:
071: // --------------------------------------------------------- Public Methods
072:
073: // -------------------------------------------------- ObjectFactory Methods
074:
075: /**
076: * Crete a new serviceref instance.
077: *
078: * @param obj The reference object describing the webservice
079: */
080: public Object getObjectInstance(Object obj, Name name,
081: Context nameCtx, Hashtable environment) throws Exception {
082:
083: if (obj instanceof ServiceRef) {
084: Reference ref = (Reference) obj;
085:
086: // ClassLoader
087: ClassLoader tcl = Thread.currentThread()
088: .getContextClassLoader();
089: if (tcl == null)
090: tcl = this .getClass().getClassLoader();
091: ServiceFactory factory = ServiceFactory.newInstance();
092: javax.xml.rpc.Service service = null;
093:
094: // Service Interface
095: RefAddr tmp = ref.get(ServiceRef.SERVICE_INTERFACE);
096: String serviceInterface = null;
097: if (tmp != null)
098: serviceInterface = (String) tmp.getContent();
099:
100: // WSDL
101: tmp = ref.get(ServiceRef.WSDL);
102: String wsdlRefAddr = null;
103: if (tmp != null)
104: wsdlRefAddr = (String) tmp.getContent();
105:
106: // PortComponent
107: Hashtable portComponentRef = new Hashtable();
108:
109: // Create QName object
110: QName serviceQname = null;
111: tmp = ref.get(ServiceRef.SERVICE_LOCAL_PART);
112: if (tmp != null) {
113: String serviceLocalPart = (String) tmp.getContent();
114: tmp = ref.get(ServiceRef.SERVICE_NAMESPACE);
115: if (tmp == null) {
116: serviceQname = new QName(serviceLocalPart);
117: } else {
118: String serviceNamespace = (String) tmp.getContent();
119: serviceQname = new QName(serviceNamespace,
120: serviceLocalPart);
121: }
122: }
123: Class serviceInterfaceClass = null;
124:
125: // Create service object
126: if (serviceInterface == null) {
127: if (serviceQname == null) {
128: throw new NamingException(
129: "Could not create service-ref instance");
130: }
131: try {
132: if (wsdlRefAddr == null) {
133: service = factory.createService(serviceQname);
134: } else {
135: service = factory.createService(new URL(
136: wsdlRefAddr), serviceQname);
137: }
138: } catch (Throwable t) {
139: NamingException ex = new NamingException(
140: "Could not create service");
141: ex.initCause(t);
142: throw ex;
143: }
144: } else {
145: // Loading service Interface
146: try {
147: serviceInterfaceClass = tcl
148: .loadClass(serviceInterface);
149: } catch (ClassNotFoundException e) {
150: NamingException ex = new NamingException(
151: "Could not load service Interface");
152: ex.initCause(e);
153: throw ex;
154: }
155: if (serviceInterfaceClass == null) {
156: throw new NamingException(
157: "Could not load service Interface");
158: }
159: try {
160: if (wsdlRefAddr == null) {
161: if (!Service.class
162: .isAssignableFrom(serviceInterfaceClass)) {
163: throw new NamingException(
164: "service Interface should extend javax.xml.rpc.Service");
165: }
166: service = factory
167: .loadService(serviceInterfaceClass);
168: } else {
169: service = factory.loadService(new URL(
170: wsdlRefAddr), serviceInterfaceClass,
171: new Properties());
172: }
173: } catch (Throwable t) {
174: NamingException ex = new NamingException(
175: "Could not create service");
176: ex.initCause(t);
177: throw ex;
178: }
179: }
180: if (service == null) {
181: throw new NamingException(
182: "Cannot create service object");
183: }
184: serviceQname = service.getServiceName();
185: serviceInterfaceClass = service.getClass();
186: if (wsdlRefAddr != null) {
187: try {
188: WSDLFactory wsdlfactory = WSDLFactory.newInstance();
189: WSDLReader reader = wsdlfactory.newWSDLReader();
190: reader.setFeature("javax.wsdl.importDocuments",
191: true);
192: Definition def = reader.readWSDL((new URL(
193: wsdlRefAddr)).toExternalForm());
194:
195: javax.wsdl.Service wsdlservice = def
196: .getService(serviceQname);
197: Map ports = wsdlservice.getPorts();
198: Method m = serviceInterfaceClass.getMethod(
199: "setEndpointAddress", new Class[] {
200: java.lang.String.class,
201: java.lang.String.class });
202: for (Iterator i = ports.keySet().iterator(); i
203: .hasNext();) {
204: String portName = (String) i.next();
205: Port port = wsdlservice.getPort(portName);
206: String endpoint = getSOAPLocation(port);
207: m.invoke(service, new Object[] {
208: port.getName(), endpoint });
209: portComponentRef.put(endpoint, new QName(port
210: .getName()));
211: }
212: } catch (Throwable t) {
213: NamingException ex = new NamingException(
214: "Error while reading Wsdl File");
215: ex.initCause(t);
216: throw ex;
217: }
218: }
219:
220: ServiceProxy proxy = new ServiceProxy(service);
221:
222: // Use port-component-ref
223: for (int i = 0; i < ref.size(); i++)
224: if (ServiceRef.SERVICEENDPOINTINTERFACE.equals(ref.get(
225: i).getType())) {
226: String serviceendpoint = "";
227: String portlink = "";
228: serviceendpoint = (String) ref.get(i).getContent();
229: if (ServiceRef.PORTCOMPONENTLINK.equals(ref.get(
230: i + 1).getType())) {
231: i++;
232: portlink = (String) ref.get(i).getContent();
233: }
234: portComponentRef.put(serviceendpoint, new QName(
235: portlink));
236:
237: }
238: proxy.setPortComponentRef(portComponentRef);
239:
240: // Instantiate service with proxy class
241: Class[] interfaces = null;
242: Class[] serviceInterfaces = serviceInterfaceClass
243: .getInterfaces();
244: if (serviceInterfaceClass != null) {
245: interfaces = new Class[serviceInterfaces.length + 1];
246: for (int i = 0; i < serviceInterfaces.length; i++) {
247: interfaces[i] = serviceInterfaces[i];
248: }
249: } else {
250: interfaces = new Class[1];
251: }
252: interfaces[interfaces.length - 1] = javax.xml.rpc.Service.class;
253: Object proxyInstance = null;
254: try {
255: proxyInstance = Proxy.newProxyInstance(tcl, interfaces,
256: proxy);
257: } catch (IllegalArgumentException e) {
258: proxyInstance = Proxy.newProxyInstance(tcl,
259: serviceInterfaces, proxy);
260: }
261:
262: // Use handler
263: if (((ServiceRef) ref).getHandlersSize() > 0) {
264:
265: HandlerRegistry handlerRegistry = service
266: .getHandlerRegistry();
267: ArrayList soaproles = new ArrayList();
268:
269: while (((ServiceRef) ref).getHandlersSize() > 0) {
270: HandlerRef handler = ((ServiceRef) ref)
271: .getHandler();
272: HandlerInfo handlerref = new HandlerInfo();
273:
274: // Loading handler Class
275: tmp = handler.get(HandlerRef.HANDLER_CLASS);
276: if ((tmp == null) || (tmp.getContent() == null))
277: break;
278: Class handlerClass = null;
279: try {
280: handlerClass = tcl.loadClass((String) tmp
281: .getContent());
282: } catch (ClassNotFoundException e) {
283: break;
284: }
285:
286: // Load all datas relative to the handler : SOAPHeaders, config init element,
287: // portNames to be set on
288: ArrayList headers = new ArrayList();
289: Hashtable config = new Hashtable();
290: ArrayList portNames = new ArrayList();
291: for (int i = 0; i < handler.size(); i++)
292: if (HandlerRef.HANDLER_LOCALPART.equals(handler
293: .get(i).getType())) {
294: String localpart = "";
295: String namespace = "";
296: localpart = (String) handler.get(i)
297: .getContent();
298: if (HandlerRef.HANDLER_NAMESPACE
299: .equals(handler.get(i + 1)
300: .getType())) {
301: i++;
302: namespace = (String) handler.get(i)
303: .getContent();
304: }
305: QName header = new QName(namespace,
306: localpart);
307: headers.add(header);
308: } else if (HandlerRef.HANDLER_PARAMNAME
309: .equals(handler.get(i).getType())) {
310: String paramName = "";
311: String paramValue = "";
312: paramName = (String) handler.get(i)
313: .getContent();
314: if (HandlerRef.HANDLER_PARAMVALUE
315: .equals(handler.get(i + 1)
316: .getType())) {
317: i++;
318: paramValue = (String) handler.get(i)
319: .getContent();
320: }
321: config.put(paramName, paramValue);
322: } else if (HandlerRef.HANDLER_SOAPROLE
323: .equals(handler.get(i).getType())) {
324: String soaprole = "";
325: soaprole = (String) handler.get(i)
326: .getContent();
327: soaproles.add(soaprole);
328: } else if (HandlerRef.HANDLER_PORTNAME
329: .equals(handler.get(i).getType())) {
330: String portName = "";
331: portName = (String) handler.get(i)
332: .getContent();
333: portNames.add(portName);
334: }
335:
336: // Set the handlers informations
337: handlerref.setHandlerClass(handlerClass);
338: handlerref.setHeaders((QName[]) headers
339: .toArray(new QName[headers.size()]));
340: handlerref.setHandlerConfig(config);
341:
342: if (!portNames.isEmpty()) {
343: Iterator iter = portNames.iterator();
344: while (iter.hasNext())
345: initHandlerChain(new QName((String) iter
346: .next()), handlerRegistry,
347: handlerref, soaproles);
348: } else {
349: Enumeration e = portComponentRef.elements();
350: while (e.hasMoreElements())
351: initHandlerChain((QName) e.nextElement(),
352: handlerRegistry, handlerref,
353: soaproles);
354: }
355: }
356: }
357:
358: return proxyInstance;
359:
360: }
361:
362: return null;
363:
364: }
365:
366: /**
367: * @param port analyzed port
368: * @return Returns the endpoint URL of the given Port
369: */
370: private String getSOAPLocation(Port port) {
371: String endpoint = null;
372: List extensions = port.getExtensibilityElements();
373: for (Iterator i = extensions.iterator(); i.hasNext();) {
374: ExtensibilityElement ext = (ExtensibilityElement) i.next();
375: if (ext instanceof SOAPAddress) {
376: SOAPAddress addr = (SOAPAddress) ext;
377: endpoint = addr.getLocationURI();
378: }
379: }
380: return endpoint;
381: }
382:
383: private void initHandlerChain(QName portName,
384: HandlerRegistry handlerRegistry, HandlerInfo handlerref,
385: ArrayList soaprolesToAdd) {
386: HandlerChain handlerList = (HandlerChain) handlerRegistry
387: .getHandlerChain(portName);
388: handlerList.add(handlerref);
389: String[] soaprolesRegistered = handlerList.getRoles();
390: String[] soaproles = new String[soaprolesRegistered.length
391: + soaprolesToAdd.size()];
392: int i;
393: for (i = 0; i < soaprolesRegistered.length; i++)
394: soaproles[i] = soaprolesRegistered[i];
395: for (int j = 0; j < soaprolesToAdd.size(); j++)
396: soaproles[i + j] = (String) soaprolesToAdd.get(j);
397: handlerList.setRoles(soaproles);
398: handlerRegistry.setHandlerChain(portName, handlerList);
399: }
400:
401: }
|