KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > webservices > builder > WSDescriptorParser


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17 package org.apache.geronimo.webservices.builder;
18
19 import java.io.IOException JavaDoc;
20 import java.io.InputStream JavaDoc;
21 import java.lang.reflect.Method JavaDoc;
22 import java.math.BigDecimal JavaDoc;
23 import java.math.BigInteger JavaDoc;
24 import java.net.URI JavaDoc;
25 import java.net.URISyntaxException JavaDoc;
26 import java.net.URL JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Calendar JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Map JavaDoc;
32 import java.util.jar.JarFile JavaDoc;
33 import java.util.zip.ZipEntry JavaDoc;
34
35 import javax.wsdl.Definition;
36 import javax.wsdl.Operation;
37 import javax.wsdl.Port;
38 import javax.xml.namespace.QName JavaDoc;
39 import javax.xml.rpc.handler.HandlerInfo JavaDoc;
40 import javax.xml.rpc.holders.BigDecimalHolder JavaDoc;
41 import javax.xml.rpc.holders.BigIntegerHolder JavaDoc;
42 import javax.xml.rpc.holders.BooleanHolder JavaDoc;
43 import javax.xml.rpc.holders.BooleanWrapperHolder JavaDoc;
44 import javax.xml.rpc.holders.ByteArrayHolder JavaDoc;
45 import javax.xml.rpc.holders.ByteHolder JavaDoc;
46 import javax.xml.rpc.holders.ByteWrapperHolder JavaDoc;
47 import javax.xml.rpc.holders.CalendarHolder JavaDoc;
48 import javax.xml.rpc.holders.DoubleHolder JavaDoc;
49 import javax.xml.rpc.holders.DoubleWrapperHolder JavaDoc;
50 import javax.xml.rpc.holders.FloatHolder JavaDoc;
51 import javax.xml.rpc.holders.FloatWrapperHolder JavaDoc;
52 import javax.xml.rpc.holders.IntHolder JavaDoc;
53 import javax.xml.rpc.holders.IntegerWrapperHolder JavaDoc;
54 import javax.xml.rpc.holders.LongHolder JavaDoc;
55 import javax.xml.rpc.holders.LongWrapperHolder JavaDoc;
56 import javax.xml.rpc.holders.ObjectHolder JavaDoc;
57 import javax.xml.rpc.holders.QNameHolder JavaDoc;
58 import javax.xml.rpc.holders.ShortHolder JavaDoc;
59 import javax.xml.rpc.holders.ShortWrapperHolder JavaDoc;
60 import javax.xml.rpc.holders.StringHolder JavaDoc;
61
62 import org.apache.geronimo.common.DeploymentException;
63 import org.apache.geronimo.kernel.ClassLoading;
64 import org.apache.geronimo.xbeans.j2ee.ExceptionMappingType;
65 import org.apache.geronimo.xbeans.j2ee.JavaWsdlMappingDocument;
66 import org.apache.geronimo.xbeans.j2ee.JavaWsdlMappingType;
67 import org.apache.geronimo.xbeans.j2ee.PackageMappingType;
68 import org.apache.geronimo.xbeans.j2ee.ParamValueType;
69 import org.apache.geronimo.xbeans.j2ee.PortComponentHandlerType;
70 import org.apache.geronimo.xbeans.j2ee.PortComponentType;
71 import org.apache.geronimo.xbeans.j2ee.ServiceEndpointInterfaceMappingType;
72 import org.apache.geronimo.xbeans.j2ee.ServiceEndpointMethodMappingType;
73 import org.apache.geronimo.xbeans.j2ee.ServiceImplBeanType;
74 import org.apache.geronimo.xbeans.j2ee.WebserviceDescriptionType;
75 import org.apache.geronimo.xbeans.j2ee.WebservicesDocument;
76 import org.apache.geronimo.xbeans.j2ee.WebservicesType;
77 import org.apache.geronimo.xbeans.j2ee.XsdQNameType;
78 import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
79 import org.apache.geronimo.webservices.builder.PortInfo;
80 import org.apache.geronimo.webservices.builder.SchemaInfoBuilder;
81 import org.apache.xmlbeans.XmlException;
82
83 /**
84  * @version $Rev: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $
85  */

86 public class WSDescriptorParser {
87
88
89     public static JavaWsdlMappingType readJaxrpcMapping(JarFile JavaDoc moduleFile, URI JavaDoc jaxrpcMappingURI) throws DeploymentException {
90         String JavaDoc jaxrpcMappingPath = jaxrpcMappingURI.toString();
91         return readJaxrpcMapping(moduleFile, jaxrpcMappingPath);
92     }
93
94     public static JavaWsdlMappingType readJaxrpcMapping(JarFile JavaDoc moduleFile, String JavaDoc jaxrpcMappingPath) throws DeploymentException {
95         JavaWsdlMappingType mapping;
96         InputStream JavaDoc jaxrpcInputStream = null;
97         try {
98             ZipEntry JavaDoc zipEntry = moduleFile.getEntry(jaxrpcMappingPath);
99             if(zipEntry == null){
100                 throw new DeploymentException("The JAX-RPC mapping file "+jaxrpcMappingPath+" specified in webservices.xml for the ejb module could not be found.");
101             }
102             jaxrpcInputStream = moduleFile.getInputStream(zipEntry);
103         } catch (IOException JavaDoc e) {
104             throw new DeploymentException("Could not open stream to jaxrpc mapping document", e);
105         }
106         JavaWsdlMappingDocument mappingDocument = null;
107         try {
108             mappingDocument = JavaWsdlMappingDocument.Factory.parse(jaxrpcInputStream);
109         } catch (XmlException e) {
110             throw new DeploymentException("Could not parse jaxrpc mapping document", e);
111         } catch (IOException JavaDoc e) {
112             throw new DeploymentException("Could not read jaxrpc mapping document", e);
113         }
114         mapping = mappingDocument.getJavaWsdlMapping();
115         return mapping;
116     }
117
118
119     public static Map JavaDoc getExceptionMap(JavaWsdlMappingType mapping) {
120         Map JavaDoc exceptionMap = new HashMap JavaDoc();
121         if (mapping != null) {
122             ExceptionMappingType[] exceptionMappings = mapping.getExceptionMappingArray();
123             for (int i = 0; i < exceptionMappings.length; i++) {
124                 ExceptionMappingType exceptionMapping = exceptionMappings[i];
125                 QName JavaDoc exceptionMessageQName = exceptionMapping.getWsdlMessage().getQNameValue();
126                 exceptionMap.put(exceptionMessageQName, exceptionMapping);
127             }
128         }
129         return exceptionMap;
130     }
131
132     public static String JavaDoc getPackageFromNamespace(String JavaDoc namespace, JavaWsdlMappingType mapping) throws DeploymentException {
133         PackageMappingType[] packageMappings = mapping.getPackageMappingArray();
134         for (int i = 0; i < packageMappings.length; i++) {
135             PackageMappingType packageMapping = packageMappings[i];
136             if (namespace.equals(packageMapping.getNamespaceURI().getStringValue().trim())) {
137                 return packageMapping.getPackageType().getStringValue().trim();
138             }
139         }
140         throw new DeploymentException("Namespace " + namespace + " was not mapped in jaxrpc mapping file");
141     }
142
143     private static final Map JavaDoc rpcHolderClasses = new HashMap JavaDoc();
144
145     static {
146         rpcHolderClasses.put(BigDecimal JavaDoc.class, BigDecimalHolder JavaDoc.class);
147         rpcHolderClasses.put(BigInteger JavaDoc.class, BigIntegerHolder JavaDoc.class);
148         rpcHolderClasses.put(boolean.class, BooleanHolder JavaDoc.class);
149         rpcHolderClasses.put(Boolean JavaDoc.class, BooleanWrapperHolder JavaDoc.class);
150         rpcHolderClasses.put(byte[].class, ByteArrayHolder JavaDoc.class);
151         rpcHolderClasses.put(byte.class, ByteHolder JavaDoc.class);
152         rpcHolderClasses.put(Byte JavaDoc.class, ByteWrapperHolder JavaDoc.class);
153         rpcHolderClasses.put(Calendar JavaDoc.class, CalendarHolder JavaDoc.class);
154         rpcHolderClasses.put(double.class, DoubleHolder JavaDoc.class);
155         rpcHolderClasses.put(Double JavaDoc.class, DoubleWrapperHolder JavaDoc.class);
156         rpcHolderClasses.put(float.class, FloatHolder JavaDoc.class);
157         rpcHolderClasses.put(Float JavaDoc.class, FloatWrapperHolder JavaDoc.class);
158         rpcHolderClasses.put(int.class, IntHolder JavaDoc.class);
159         rpcHolderClasses.put(Integer JavaDoc.class, IntegerWrapperHolder JavaDoc.class);
160         rpcHolderClasses.put(long.class, LongHolder JavaDoc.class);
161         rpcHolderClasses.put(Long JavaDoc.class, LongWrapperHolder JavaDoc.class);
162         rpcHolderClasses.put(Object JavaDoc.class, ObjectHolder JavaDoc.class);
163         rpcHolderClasses.put(QName JavaDoc.class, QNameHolder JavaDoc.class);
164         rpcHolderClasses.put(short.class, ShortHolder JavaDoc.class);
165         rpcHolderClasses.put(Short JavaDoc.class, ShortWrapperHolder JavaDoc.class);
166         rpcHolderClasses.put(String JavaDoc.class, StringHolder JavaDoc.class);
167     }
168
169     public static Class JavaDoc getHolderType(String JavaDoc paramJavaTypeName, boolean isInOnly, QName JavaDoc typeQName, boolean isComplexType, JavaWsdlMappingType mapping, ClassLoader JavaDoc classLoader) throws DeploymentException {
170         Class JavaDoc paramJavaType = null;
171         if (isInOnly) {
172             //IN parameters just use their own type
173
try {
174                 paramJavaType = ClassLoading.loadClass(paramJavaTypeName, classLoader);
175             } catch (ClassNotFoundException JavaDoc e) {
176                 throw new DeploymentException("could not load parameter type", e);
177             }
178             return paramJavaType;
179         } else {
180             //INOUT and OUT parameters use holders. See jaxrpc spec 4.3.5
181
String JavaDoc holderName;
182             if (isComplexType) {
183                 //complex types get mapped:
184
//package is determined from the namespace to package map + ".holders"
185
//class name is the complex type QNMAne local part + "Holder", with the initial character uppercased.
186
String JavaDoc namespace = typeQName.getNamespaceURI();
187                 String JavaDoc packageName = WSDescriptorParser.getPackageFromNamespace(namespace, mapping);
188                 StringBuffer JavaDoc buf = new StringBuffer JavaDoc(packageName.length() + typeQName.getLocalPart().length() + 14);
189                 buf.append(packageName).append(".holders.").append(typeQName.getLocalPart()).append("Holder");
190                 buf.setCharAt(packageName.length() + 9, Character.toUpperCase(typeQName.getLocalPart().charAt(0)));
191                 holderName = buf.toString();
192             } else {
193                 //see if it is in the primitive type and simple type mapping
194
try {
195                     paramJavaType = ClassLoading.loadClass(paramJavaTypeName, classLoader);
196                 } catch (ClassNotFoundException JavaDoc e) {
197                     throw new DeploymentException("could not load parameter type", e);
198                 }
199                 Class JavaDoc holder = (Class JavaDoc) rpcHolderClasses.get(paramJavaType);
200                 if (holder != null) {
201                     try {
202                         //TODO use class names in map or make sure we are in the correct classloader to start with.
203
holder = ClassLoading.loadClass(holder.getName(), classLoader);
204                     } catch (ClassNotFoundException JavaDoc e) {
205                         throw new DeploymentException("could not load holder type in correct classloader", e);
206                     }
207                     return holder;
208                 }
209                 //Otherwise, the holder must be in:
210
//package same as type's package + ".holders"
211
//class name same as type name + "Holder"
212
String JavaDoc paramTypeName = paramJavaType.getName();
213                 StringBuffer JavaDoc buf = new StringBuffer JavaDoc(paramTypeName.length() + 14);
214                 int dot = paramTypeName.lastIndexOf(".");
215                 //foo.Bar >>> foo.holders.BarHolder
216
buf.append(paramTypeName.substring(0, dot)).append(".holders").append(paramTypeName.substring(dot)).append("Holder");
217                 holderName = buf.toString();
218             }
219             try {
220                 Class JavaDoc holder = ClassLoading.loadClass(holderName, classLoader);
221                 return holder;
222             } catch (ClassNotFoundException JavaDoc e) {
223                 throw new DeploymentException("Could not load holder class", e);
224             }
225         }
226     }
227
228     public static ServiceEndpointMethodMappingType getMethodMappingForOperation(String JavaDoc operationName, ServiceEndpointMethodMappingType[] methodMappings) throws DeploymentException {
229         for (int i = 0; i < methodMappings.length; i++) {
230             ServiceEndpointMethodMappingType methodMapping = methodMappings[i];
231             if (operationName.equals(methodMapping.getWsdlOperation().getStringValue())) {
232                 return methodMapping;
233             }
234         }
235         // Build list of available operations for exception
236
StringBuffer JavaDoc availOps = new StringBuffer JavaDoc(128);
237         for (int i = 0; i < methodMappings.length; i++) {
238             if (i != 0) availOps.append(",");
239             availOps.append(methodMappings[i].getWsdlOperation().getStringValue());
240         }
241         throw new DeploymentException("No method found for operation named '" + operationName + "'. Available operations: " + availOps);
242     }
243
244     public static ServiceEndpointInterfaceMappingType getServiceEndpointInterfaceMapping(ServiceEndpointInterfaceMappingType[] endpointMappings, QName JavaDoc portTypeQName) throws DeploymentException {
245         for (int i = 0; i < endpointMappings.length; i++) {
246             ServiceEndpointInterfaceMappingType endpointMapping = endpointMappings[i];
247             QName JavaDoc testPortQName = endpointMapping.getWsdlPortType().getQNameValue();
248             if (portTypeQName.equals(testPortQName)) {
249                 return endpointMapping;
250             }
251         }
252         throw new DeploymentException("Could not find service endpoint interface for port named " + portTypeQName);
253     }
254
255     public static javax.wsdl.Service getService(QName JavaDoc serviceQName, Definition definition) throws DeploymentException {
256         javax.wsdl.Service service;
257         if (serviceQName != null) {
258             service = definition.getService(serviceQName);
259         } else {
260             Map JavaDoc services = definition.getServices();
261             if (services.size() != 1) {
262                 throw new DeploymentException("no serviceQName supplied, and there are " + services.size() + " services");
263             }
264             service = (javax.wsdl.Service) services.values().iterator().next();
265         }
266         if (service == null) {
267             throw new DeploymentException("No service wsdl for supplied service qname " + serviceQName);
268         }
269         return service;
270     }
271
272     public static Method JavaDoc getMethodForOperation(Class JavaDoc serviceEndpointInterface, Operation operation) throws DeploymentException {
273         Method JavaDoc[] methods = serviceEndpointInterface.getMethods();
274         String JavaDoc opName = operation.getName();
275         Method JavaDoc found = null;
276         for (int i = 0; i < methods.length; i++) {
277             Method JavaDoc method = methods[i];
278             if (method.getName().equals(opName)) {
279                 if (found != null) {
280                     throw new DeploymentException("Overloaded methods are not allowed in lightweight mappings");
281                 }
282                 found = method;
283             }
284         }
285         if (found == null) {
286             throw new DeploymentException("No method found for operation named " + opName);
287         }
288         return found;
289     }
290
291     /**
292      * Parses a webservice.xml file and returns a map PortInfo instances indexed by the
293      * corresponding ejb-link or servlet-link element .
294      *
295      * @param webservicesType
296      * @param moduleFile
297      * @param isEJB
298      * @param servletLocations
299      * @return
300      * @throws org.apache.geronimo.common.DeploymentException
301      */

302     public static Map JavaDoc parseWebServiceDescriptor(WebservicesType webservicesType, JarFile JavaDoc moduleFile, boolean isEJB, Map JavaDoc servletLocations) throws DeploymentException {
303         Map JavaDoc portMap = new HashMap JavaDoc();
304         WebserviceDescriptionType[] webserviceDescriptions = webservicesType.getWebserviceDescriptionArray();
305         for (int i = 0; i < webserviceDescriptions.length; i++) {
306             WebserviceDescriptionType webserviceDescription = webserviceDescriptions[i];
307             URI JavaDoc wsdlURI = null;
308             try {
309                 wsdlURI = new URI JavaDoc(webserviceDescription.getWsdlFile().getStringValue().trim());
310             } catch (URISyntaxException JavaDoc e) {
311                 throw new DeploymentException("could not construct wsdl uri from " + webserviceDescription.getWsdlFile().getStringValue(), e);
312             }
313             URI JavaDoc jaxrpcMappingURI = null;
314             try {
315                 jaxrpcMappingURI = new URI JavaDoc(webserviceDescription.getJaxrpcMappingFile().getStringValue().trim());
316             } catch (URISyntaxException JavaDoc e) {
317                 throw new DeploymentException("Could not construct jaxrpc mapping uri from " + webserviceDescription.getJaxrpcMappingFile(), e);
318             }
319             SchemaInfoBuilder schemaInfoBuilder = new SchemaInfoBuilder(moduleFile, wsdlURI);
320             Map JavaDoc wsdlPortMap = schemaInfoBuilder.getPortMap();
321
322             JavaWsdlMappingType javaWsdlMapping = readJaxrpcMapping(moduleFile, jaxrpcMappingURI);
323             HashMap JavaDoc seiMappings = new HashMap JavaDoc();
324             ServiceEndpointInterfaceMappingType[] mappings = javaWsdlMapping.getServiceEndpointInterfaceMappingArray();
325             for (int j = 0; j < mappings.length; j++) {
326                 ServiceEndpointInterfaceMappingType seiMapping = mappings[j];
327                 seiMappings.put(seiMapping.getServiceEndpointInterface().getStringValue(), seiMapping);
328             }
329
330             PortComponentType[] portComponents = webserviceDescription.getPortComponentArray();
331             for (int j = 0; j < portComponents.length; j++) {
332                 PortComponentType portComponent = portComponents[j];
333                 String JavaDoc portComponentName = portComponent.getPortComponentName().getStringValue().trim();
334                 QName JavaDoc portQName = portComponent.getWsdlPort().getQNameValue();
335                 String JavaDoc seiInterfaceName = portComponent.getServiceEndpointInterface().getStringValue().trim();
336                 ServiceImplBeanType serviceImplBeanType = portComponent.getServiceImplBean();
337                 if (isEJB == serviceImplBeanType.isSetServletLink()) {
338                     throw new DeploymentException("Wrong kind of web service described in web service descriptor: expected " + (isEJB ? "EJB" : "POJO(Servlet)"));
339                 }
340                 String JavaDoc linkName;
341                 String JavaDoc servletLocation;
342                 if (serviceImplBeanType.isSetServletLink()) {
343                     linkName = serviceImplBeanType.getServletLink().getStringValue().trim();
344                     servletLocation = (String JavaDoc) servletLocations.get(linkName);
345                     if (servletLocation == null) {
346                         throw new DeploymentException("No servlet mapping for port " + portQName);
347                     }
348                     schemaInfoBuilder.movePortLocation(portQName.getLocalPart(), servletLocation);
349                 } else {
350                     linkName = serviceImplBeanType.getEjbLink().getStringValue().trim();
351                     servletLocation = (String JavaDoc) servletLocations.get(linkName);
352                     servletLocation = schemaInfoBuilder.movePortLocation(portQName.getLocalPart(), servletLocation);
353                 }
354                 PortComponentHandlerType[] handlers = portComponent.getHandlerArray();
355
356                 Port port = (Port) wsdlPortMap.get(portQName.getLocalPart());
357                 if (port == null) {
358                     throw new DeploymentException("No WSDL Port definition for port-component " + portComponentName);
359                 }
360
361                 ServiceEndpointInterfaceMappingType seiMapping = (ServiceEndpointInterfaceMappingType) seiMappings.get(seiInterfaceName);
362
363                 String JavaDoc wsdlLocation = webserviceDescription.getWsdlFile().getStringValue().trim();
364                 URI JavaDoc contextURI = null;
365                 try {
366                     contextURI = new URI JavaDoc(servletLocation);
367                 } catch (URISyntaxException JavaDoc e) {
368                     throw new DeploymentException("Could not construct URI for web service location", e);
369                 }
370
371                 PortInfo portInfo = new PortInfo(portComponentName, portQName, schemaInfoBuilder, javaWsdlMapping, seiInterfaceName, handlers, port, seiMapping, wsdlLocation, contextURI);
372
373                 if (portMap.put(linkName, portInfo) != null) {
374                     throw new DeploymentException("Ambiguous description of port associated with j2ee component " + linkName);
375                 }
376             }
377         }
378         return portMap;
379     }
380
381     public static Map JavaDoc parseWebServiceDescriptor(URL JavaDoc wsDDUrl, JarFile JavaDoc moduleFile, boolean isEJB, Map JavaDoc servletLocations) throws DeploymentException {
382         try {
383             WebservicesDocument webservicesDocument = WebservicesDocument.Factory.parse(wsDDUrl);
384             XmlBeansUtil.validateDD(webservicesDocument);
385             WebservicesType webservicesType = webservicesDocument.getWebservices();
386             return parseWebServiceDescriptor(webservicesType, moduleFile, isEJB, servletLocations);
387         } catch (XmlException e) {
388             throw new DeploymentException("Could not read descriptor document", e);
389         } catch (IOException JavaDoc e) {
390             return null;
391         }
392
393     }
394
395     public static List JavaDoc createHandlerInfoList(PortComponentHandlerType[] handlers, ClassLoader JavaDoc classLoader) throws DeploymentException {
396         List JavaDoc list = new ArrayList JavaDoc();
397         for (int i = 0; i < handlers.length; i++) {
398             PortComponentHandlerType handler = handlers[i];
399
400             // Get handler class
401
Class JavaDoc handlerClass = null;
402             String JavaDoc className = handler.getHandlerClass().getStringValue().trim();
403             try {
404                 handlerClass = classLoader.loadClass(className);
405             } catch (ClassNotFoundException JavaDoc e) {
406                 throw new DeploymentException("Unable to load handler class: " + className, e);
407             }
408
409             // config data for the handler
410
Map JavaDoc config = new HashMap JavaDoc();
411             ParamValueType[] paramValues = handler.getInitParamArray();
412             for (int j = 0; j < paramValues.length; j++) {
413                 ParamValueType paramValue = paramValues[j];
414                 String JavaDoc paramName = paramValue.getParamName().getStringValue().trim();
415                 String JavaDoc paramStringValue = paramValue.getParamValue().getStringValue().trim();
416                 config.put(paramName, paramStringValue);
417             }
418
419             // QName array of headers it processes
420
XsdQNameType[] soapHeaderQNames = handler.getSoapHeaderArray();
421             QName JavaDoc[] headers = new QName JavaDoc[soapHeaderQNames.length];
422             for (int j = 0; j < soapHeaderQNames.length; j++) {
423                 XsdQNameType soapHeaderQName = soapHeaderQNames[j];
424                 headers[j] = soapHeaderQName.getQNameValue();
425             }
426
427             list.add(new HandlerInfo JavaDoc(handlerClass, config, headers));
428         }
429         return list;
430     }
431 }
432
Popular Tags