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: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.webservices.builder;
017:
018: import java.io.IOException;
019: import java.io.InputStream;
020: import java.net.URI;
021: import java.net.URISyntaxException;
022: import java.util.ArrayList;
023: import java.util.Collection;
024: import java.util.HashMap;
025: import java.util.Iterator;
026: import java.util.List;
027: import java.util.Map;
028: import java.util.Stack;
029: import java.util.jar.JarFile;
030: import java.util.zip.ZipEntry;
031: import javax.wsdl.Definition;
032: import javax.wsdl.Import;
033: import javax.wsdl.Service;
034: import javax.wsdl.Types;
035: import javax.wsdl.WSDLException;
036: import javax.wsdl.extensions.ExtensibilityElement;
037: import javax.wsdl.extensions.ExtensionRegistry;
038: import javax.wsdl.extensions.UnknownExtensibilityElement;
039: import javax.wsdl.extensions.schema.Schema;
040: import javax.wsdl.factory.WSDLFactory;
041: import javax.wsdl.xml.WSDLLocator;
042: import javax.wsdl.xml.WSDLReader;
043: import javax.xml.namespace.QName;
044:
045: import com.ibm.wsdl.extensions.PopulatedExtensionRegistry;
046: import com.ibm.wsdl.extensions.schema.SchemaConstants;
047: import org.apache.commons.logging.Log;
048: import org.apache.commons.logging.LogFactory;
049: import org.apache.geronimo.webservices.WebServiceContainer;
050: import org.apache.geronimo.common.DeploymentException;
051: import org.apache.geronimo.xbeans.wsdl.DefinitionsDocument;
052: import org.apache.geronimo.xbeans.wsdl.TDefinitions;
053: import org.apache.geronimo.xbeans.wsdl.TPort;
054: import org.apache.geronimo.xbeans.wsdl.TService;
055: import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
056: import org.apache.xmlbeans.SchemaField;
057: import org.apache.xmlbeans.SchemaGlobalElement;
058: import org.apache.xmlbeans.SchemaParticle;
059: import org.apache.xmlbeans.SchemaType;
060: import org.apache.xmlbeans.SchemaTypeSystem;
061: import org.apache.xmlbeans.XmlBeans;
062: import org.apache.xmlbeans.XmlCursor;
063: import org.apache.xmlbeans.XmlError;
064: import org.apache.xmlbeans.XmlException;
065: import org.apache.xmlbeans.XmlObject;
066: import org.apache.xmlbeans.XmlOptions;
067: import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument;
068: import org.w3c.dom.Element;
069: import org.xml.sax.EntityResolver;
070: import org.xml.sax.InputSource;
071: import org.xml.sax.SAXException;
072:
073: /**
074: * @version $Rev: 561958 $ $Date: 2007-08-01 14:20:09 -0700 (Wed, 01 Aug 2007) $
075: */
076: public class SchemaInfoBuilder {
077: private static final Log log = LogFactory
078: .getLog(SchemaInfoBuilder.class);
079: private static final SchemaTypeSystem basicTypeSystem;
080: // private static final String[] errorNames = {"Error", "Warning", "Info"};
081: private static final String SOAP_NS = "http://schemas.xmlsoap.org/wsdl/soap/";
082: private static final QName ADDRESS_QNAME = new QName(SOAP_NS,
083: "address");
084: private static final QName LOCATION_QNAME = new QName("",
085: "location");
086:
087: static {
088: InputStream is = WSDescriptorParser.class.getClassLoader()
089: .getResourceAsStream(
090: "META-INF/schema/soap_encoding_1_1.xsd");
091: if (is == null) {
092: throw new RuntimeException(
093: "Could not locate soap encoding schema");
094: }
095: ArrayList errors = new ArrayList();
096: XmlOptions xmlOptions = XmlBeansUtil.createXmlOptions(errors);
097: try {
098: SchemaDocument parsed = SchemaDocument.Factory.parse(is,
099: xmlOptions);
100: if (errors.size() != 0) {
101: throw new XmlException(errors.toArray().toString());
102: }
103:
104: basicTypeSystem = XmlBeans.compileXsd(
105: new XmlObject[] { parsed }, XmlBeans
106: .getBuiltinTypeSystem(), xmlOptions);
107: if (errors.size() > 0) {
108: throw new RuntimeException(
109: "Could not compile schema type system: errors: "
110: + errors);
111: }
112: } catch (XmlException e) {
113: throw new RuntimeException(
114: "Could not compile schema type system", e);
115: } catch (IOException e) {
116: throw new RuntimeException(
117: "Could not compile schema type system", e);
118: } finally {
119: try {
120: is.close();
121: } catch (IOException ignore) {
122: // ignore
123: }
124: }
125: }
126:
127: private final JarFile moduleFile;
128: private final Definition definition;
129: private final Stack uris = new Stack();
130: private final Map wsdlMap = new HashMap();
131: private final Map schemaTypeKeyToSchemaTypeMap;
132: private final Map complexTypeMap;
133: private final Map elementMap;
134: private final Map simpleTypeMap;
135: private final Map portMap;
136:
137: public SchemaInfoBuilder(JarFile moduleFile, URI wsdlUri)
138: throws DeploymentException {
139: this (moduleFile, wsdlUri, null, null);
140: }
141:
142: public SchemaInfoBuilder(JarFile moduleFile, Definition definition)
143: throws DeploymentException {
144: this (moduleFile, null, definition, null);
145: }
146:
147: SchemaInfoBuilder(JarFile moduleFile, URI uri,
148: SchemaTypeSystem schemaTypeSystem)
149: throws DeploymentException {
150: this (moduleFile, uri, null, schemaTypeSystem);
151: }
152:
153: SchemaInfoBuilder(JarFile moduleFile, URI uri,
154: Definition definition, SchemaTypeSystem schemaTypeSystem)
155: throws DeploymentException {
156: this .moduleFile = moduleFile;
157: if (uri != null) {
158: uris.push(uri);
159: if (definition == null && schemaTypeSystem == null) {
160: definition = readWsdl(moduleFile, uri);
161: }
162: } else if (definition != null) {
163: try {
164: uri = new URI(definition.getDocumentBaseURI());
165: uris.push(uri);
166: } catch (URISyntaxException e) {
167: throw new DeploymentException(
168: "Could not locate definition", e);
169: }
170: } else {
171: throw new DeploymentException(
172: "You must supply uri or definition");
173: }
174: if (schemaTypeSystem == null) {
175: schemaTypeSystem = compileSchemaTypeSystem(definition);
176: }
177: this .definition = definition;
178: schemaTypeKeyToSchemaTypeMap = buildSchemaTypeKeyToSchemaTypeMap(schemaTypeSystem);
179: complexTypeMap = buildComplexTypeMap();
180: simpleTypeMap = buildSimpleTypeMap();
181: elementMap = buildElementMap();
182: portMap = buildPortMap();
183: }
184:
185: public Map getSchemaTypeKeyToSchemaTypeMap() {
186: return schemaTypeKeyToSchemaTypeMap;
187: }
188:
189: public Definition getDefinition() {
190: return definition;
191: }
192:
193: public Map getWsdlMap() {
194: return wsdlMap;
195: }
196:
197: /**
198: * Find all the complex types in the previously constructed schema analysis.
199: * Put them in a map from complex type QName to schema fragment.
200: *
201: * @return map of complexType QName to schema fragment
202: */
203: public Map getComplexTypesInWsdl() {
204: return complexTypeMap;
205: }
206:
207: private Map buildComplexTypeMap() {
208: Map complexTypeMap = new HashMap();
209: for (Iterator iterator = schemaTypeKeyToSchemaTypeMap
210: .entrySet().iterator(); iterator.hasNext();) {
211: Map.Entry entry = (Map.Entry) iterator.next();
212: SchemaTypeKey key = (SchemaTypeKey) entry.getKey();
213: if (!key.isSimpleType() && !key.isAnonymous()) {
214: QName qName = key.getqName();
215: SchemaType schemaType = (SchemaType) entry.getValue();
216: complexTypeMap.put(qName, schemaType);
217: }
218: }
219: return complexTypeMap;
220: }
221:
222: public Map getElementToTypeMap() {
223: return elementMap;
224: }
225:
226: private Map buildElementMap() {
227: Map elementToTypeMap = new HashMap();
228: for (Iterator iterator = schemaTypeKeyToSchemaTypeMap
229: .entrySet().iterator(); iterator.hasNext();) {
230: Map.Entry entry = (Map.Entry) iterator.next();
231: SchemaTypeKey key = (SchemaTypeKey) entry.getKey();
232: if (key.isElement()) {
233: QName elementQName = key.getqName();
234: SchemaType schemaType = (SchemaType) entry.getValue();
235: QName typeQName = schemaType.getName();
236: elementToTypeMap.put(elementQName, typeQName);
237: }
238: }
239: return elementToTypeMap;
240: }
241:
242: /**
243: * Gets a map of all the javax.wsdl.Port instance in the WSDL definition keyed by the port's QName
244: * <p/>
245: * WSDL 1.1 spec: 2.6 "The name attribute provides a unique name among all ports defined within in the enclosing WSDL document."
246: *
247: * @return Map of port QName to javax.wsdl.Port for that QName.
248: */
249:
250: public Map getPortMap() {
251: return portMap;
252: }
253:
254: private Map buildPortMap() {
255: HashMap ports = new HashMap();
256: if (definition != null) {
257: Collection services = definition.getServices().values();
258: for (Iterator iterator = services.iterator(); iterator
259: .hasNext();) {
260: Service service = (Service) iterator.next();
261: ports.putAll(service.getPorts());
262: }
263: }
264: return ports;
265: }
266:
267: public Map getSimpleTypeMap() {
268: return simpleTypeMap;
269: }
270:
271: private Map buildSimpleTypeMap() {
272: Map simpleTypeMap = new HashMap();
273: for (Iterator iterator = schemaTypeKeyToSchemaTypeMap
274: .entrySet().iterator(); iterator.hasNext();) {
275: Map.Entry entry = (Map.Entry) iterator.next();
276: SchemaTypeKey key = (SchemaTypeKey) entry.getKey();
277: if (key.isSimpleType() && !key.isAnonymous()) {
278: QName qName = key.getqName();
279: SchemaType schemaType = (SchemaType) entry.getValue();
280: simpleTypeMap.put(qName, schemaType);
281: }
282: }
283: return simpleTypeMap;
284: }
285:
286: public SchemaTypeSystem compileSchemaTypeSystem(
287: Definition definition) throws DeploymentException {
288: List schemaList = new ArrayList();
289: addImportsFromDefinition(definition, schemaList);
290: // System.out.println("Schemas: " + schemaList);
291: Collection errors = new ArrayList();
292: XmlOptions xmlOptions = new XmlOptions();
293: xmlOptions.setErrorListener(errors);
294: xmlOptions.setEntityResolver(new JarEntityResolver());
295: XmlObject[] schemas = (XmlObject[]) schemaList
296: .toArray(new XmlObject[schemaList.size()]);
297: try {
298: SchemaTypeSystem schemaTypeSystem = XmlBeans.compileXsd(
299: schemas, basicTypeSystem, xmlOptions);
300: if (errors.size() > 0) {
301: boolean wasError = false;
302: for (Iterator iterator = errors.iterator(); iterator
303: .hasNext();) {
304: XmlError xmlError = (XmlError) iterator.next();
305: if (xmlError.getSeverity() == XmlError.SEVERITY_ERROR) {
306: log.error(xmlError);
307: wasError = true;
308: } else if (xmlError.getSeverity() == XmlError.SEVERITY_WARNING) {
309: log.warn(xmlError);
310: } else if (xmlError.getSeverity() == XmlError.SEVERITY_INFO) {
311: log.debug(xmlError);
312: }
313: }
314: if (wasError) {
315: throw new DeploymentException(
316: "Could not compile schema type system, see log for errors");
317: }
318: }
319: return schemaTypeSystem;
320: } catch (XmlException e) {
321: throw new DeploymentException(
322: "Could not compile schema type system: "
323: + schemaList, e);
324: }
325: }
326:
327: private void addImportsFromDefinition(Definition definition,
328: List schemaList) throws DeploymentException {
329: Map namespaceMap = definition.getNamespaces();
330: Types types = definition.getTypes();
331: if (types != null) {
332: List schemas = types.getExtensibilityElements();
333: for (Iterator iterator = schemas.iterator(); iterator
334: .hasNext();) {
335: Object o = iterator.next();
336: if (o instanceof Schema) {
337: Schema unknownExtensibilityElement = (Schema) o;
338: QName elementType = unknownExtensibilityElement
339: .getElementType();
340: if (new QName("http://www.w3.org/2001/XMLSchema",
341: "schema").equals(elementType)) {
342: Element element = unknownExtensibilityElement
343: .getElement();
344: addSchemaElement(element, namespaceMap,
345: schemaList);
346: }
347: } else if (o instanceof UnknownExtensibilityElement) {
348: //This is allegedly obsolete as of axis-wsdl4j-1.2-RC3.jar which includes the Schema extension above.
349: //The change notes imply that imported schemas should end up in Schema elements. They don't, so this is still needed.
350: UnknownExtensibilityElement unknownExtensibilityElement = (UnknownExtensibilityElement) o;
351: Element element = unknownExtensibilityElement
352: .getElement();
353: String elementNamespace = element.getNamespaceURI();
354: String elementLocalName = element.getNodeName();
355: if ("http://www.w3.org/2001/XMLSchema"
356: .equals(elementNamespace)
357: && "schema".equals(elementLocalName)) {
358: addSchemaElement(element, namespaceMap,
359: schemaList);
360: }
361: }
362: }
363: }
364: Map imports = definition.getImports();
365: if (imports != null) {
366: for (Iterator iterator = imports.entrySet().iterator(); iterator
367: .hasNext();) {
368: Map.Entry entry = (Map.Entry) iterator.next();
369: String namespaceURI = (String) entry.getKey();
370: List importList = (List) entry.getValue();
371: for (Iterator iterator1 = importList.iterator(); iterator1
372: .hasNext();) {
373: Import anImport = (Import) iterator1.next();
374: //according to the 1.1 jwsdl mr shcema imports are supposed to show up here,
375: //but according to the 1.0 spec there is supposed to be no Definition.
376: Definition definition1 = anImport.getDefinition();
377: if (definition1 != null) {
378: try {
379: URI uri = new URI(definition1
380: .getDocumentBaseURI());
381: uris.push(uri);
382: } catch (URISyntaxException e) {
383: throw new DeploymentException(
384: "Could not locate definition", e);
385: }
386: try {
387: addImportsFromDefinition(definition1,
388: schemaList);
389: } finally {
390: uris.pop();
391: }
392: } else {
393: log
394: .warn("Missing definition in import for namespace "
395: + namespaceURI);
396: }
397: }
398: }
399: }
400: }
401:
402: private void addSchemaElement(Element element, Map namespaceMap,
403: List schemaList) throws DeploymentException {
404: try {
405: XmlObject xmlObject = parseWithNamespaces(element,
406: namespaceMap);
407: schemaList.add(xmlObject);
408: } catch (XmlException e) {
409: throw new DeploymentException(
410: "Could not parse schema element", e);
411: }
412: }
413:
414: static XmlObject parseWithNamespaces(Element element,
415: Map namespaceMap) throws XmlException {
416: ArrayList errors = new ArrayList();
417: XmlOptions xmlOptions = XmlBeansUtil.createXmlOptions(errors);
418: SchemaDocument parsed = SchemaDocument.Factory.parse(element,
419: xmlOptions);
420: if (errors.size() != 0) {
421: throw new XmlException(errors.toArray().toString());
422: }
423: XmlCursor cursor = parsed.newCursor();
424: try {
425: cursor.toFirstContentToken();
426: for (Iterator namespaces = namespaceMap.entrySet()
427: .iterator(); namespaces.hasNext();) {
428: Map.Entry entry = (Map.Entry) namespaces.next();
429: cursor.insertNamespace((String) entry.getKey(),
430: (String) entry.getValue());
431: }
432: } finally {
433: cursor.dispose();
434: }
435: return parsed;
436: }
437:
438: /**
439: * builds a map of SchemaTypeKey containing jaxrpc-style fake QName and context info to xmlbeans SchemaType object.
440: *
441: * @param schemaTypeSystem
442: * @return Map of SchemaTypeKey to xmlbeans SchemaType object.
443: */
444: private Map buildSchemaTypeKeyToSchemaTypeMap(
445: SchemaTypeSystem schemaTypeSystem) {
446: Map qnameMap = new HashMap();
447: SchemaType[] globalTypes = schemaTypeSystem.globalTypes();
448: for (int i = 0; i < globalTypes.length; i++) {
449: SchemaType globalType = globalTypes[i];
450: QName typeQName = globalType.getName();
451: addSchemaType(typeQName, globalType, false, qnameMap);
452: }
453: SchemaGlobalElement[] globalElements = schemaTypeSystem
454: .globalElements();
455: for (int i = 0; i < globalElements.length; i++) {
456: SchemaGlobalElement globalElement = globalElements[i];
457: addElement(globalElement, null, qnameMap);
458: }
459: return qnameMap;
460: }
461:
462: private void addElement(SchemaField element, SchemaTypeKey key,
463: Map qnameMap) {
464: //TODO is this null if element is a ref?
465: QName elementName = element.getName();
466: String elementNamespace = elementName.getNamespaceURI();
467: //"" namespace means local element with elementFormDefault="unqualified"
468: if (elementNamespace == null || elementNamespace.equals("")) {
469: elementNamespace = key.getqName().getNamespaceURI();
470: }
471: String elementQNameLocalName;
472: SchemaTypeKey elementKey;
473: if (key == null) {
474: //top level. rule 2.a,
475: elementQNameLocalName = elementName.getLocalPart();
476: elementKey = new SchemaTypeKey(elementName, true, false,
477: false, elementName);
478: } else {
479: //not top level. rule 2.b, key will be for enclosing Type.
480: QName enclosingTypeQName = key.getqName();
481: String enclosingTypeLocalName = enclosingTypeQName
482: .getLocalPart();
483: elementQNameLocalName = enclosingTypeLocalName + ">"
484: + elementName.getLocalPart();
485: QName subElementName = new QName(elementNamespace,
486: elementQNameLocalName);
487: elementKey = new SchemaTypeKey(subElementName, true, false,
488: true, elementName);
489: }
490: SchemaType schemaType = element.getType();
491: qnameMap.put(elementKey, schemaType);
492: // new Exception("Adding: " + elementKey.getqName().getLocalPart()).printStackTrace();
493: //check if it's an array. maxOccurs is null if unbounded
494: //element should always be a SchemaParticle... this is a workaround for XMLBEANS-137
495: if (element instanceof SchemaParticle) {
496: addArrayForms((SchemaParticle) element, elementKey
497: .getqName(), qnameMap, schemaType);
498: } else {
499: log.warn("element is not a schemaParticle! " + element);
500: }
501: //now, name for type. Rule 1.b, type inside an element
502: String typeQNameLocalPart = ">" + elementQNameLocalName;
503: QName typeQName = new QName(elementNamespace,
504: typeQNameLocalPart);
505: boolean isAnonymous = true;
506: addSchemaType(typeQName, schemaType, isAnonymous, qnameMap);
507: }
508:
509: private void addSchemaType(QName typeQName, SchemaType schemaType,
510: boolean anonymous, Map qnameMap) {
511: SchemaTypeKey typeKey = new SchemaTypeKey(typeQName, false,
512: schemaType.isSimpleType(), anonymous, null);
513: qnameMap.put(typeKey, schemaType);
514: // new Exception("Adding: " + typeKey.getqName().getLocalPart()).printStackTrace();
515: //TODO xmlbeans recommends using summary info from getElementProperties and getAttributeProperties instead of traversing the content model by hand.
516: SchemaParticle schemaParticle = schemaType.getContentModel();
517: if (schemaParticle != null) {
518: addSchemaParticle(schemaParticle, typeKey, qnameMap);
519: }
520: }
521:
522: private void addSchemaParticle(SchemaParticle schemaParticle,
523: SchemaTypeKey key, Map qnameMap) {
524: if (schemaParticle.getParticleType() == SchemaParticle.ELEMENT) {
525: SchemaType elementType = schemaParticle.getType();
526: SchemaField element = elementType.getContainerField();
527: //element will be null if the type is defined elsewhere, such as a built in type.
528: if (element != null) {
529: addElement(element, key, qnameMap);
530: } else {
531: QName keyQName = key.getqName();
532: //TODO I can't distinguish between 3.a and 3.b, so generate names both ways.
533: //3.b
534: String localPart = schemaParticle.getName()
535: .getLocalPart();
536: QName elementName = new QName(keyQName
537: .getNamespaceURI(), localPart);
538: addArrayForms(schemaParticle, elementName, qnameMap,
539: elementType);
540: //3.a
541: localPart = keyQName.getLocalPart() + ">"
542: + schemaParticle.getName().getLocalPart();
543: elementName = new QName(keyQName.getNamespaceURI(),
544: localPart);
545: addArrayForms(schemaParticle, elementName, qnameMap,
546: elementType);
547: }
548: } else {
549: try {
550: SchemaParticle[] children = schemaParticle
551: .getParticleChildren();
552: for (int i = 0; i < children.length; i++) {
553: SchemaParticle child = children[i];
554: addSchemaParticle(child, key, qnameMap);
555: }
556: } catch (NullPointerException e) {
557: //ignore xmlbeans bug
558: }
559: }
560: }
561:
562: private void addArrayForms(SchemaParticle schemaParticle,
563: QName keyName, Map qnameMap, SchemaType elementType) {
564: //it may be a ref or a built in type. If it's an array (maxOccurs >1) form a type for it.
565: if (schemaParticle.getIntMaxOccurs() > 1) {
566: String maxOccurs = schemaParticle.getMaxOccurs() == null ? "unbounded"
567: : "" + schemaParticle.getIntMaxOccurs();
568: int minOccurs = schemaParticle.getIntMinOccurs();
569: QName elementName = schemaParticle.getName();
570: String arrayQNameLocalName = keyName.getLocalPart() + "["
571: + minOccurs + "," + maxOccurs + "]";
572: String elementNamespace = elementName.getNamespaceURI();
573: if (elementNamespace == null || elementNamespace.equals("")) {
574: elementNamespace = keyName.getNamespaceURI();
575: }
576: QName arrayName = new QName(elementNamespace,
577: arrayQNameLocalName);
578: SchemaTypeKey arrayKey = new SchemaTypeKey(arrayName,
579: false, false, true, elementName);
580: //TODO not clear we want the schemaType as the value
581: qnameMap.put(arrayKey, elementType);
582: // new Exception("Adding: " + arrayKey.getqName().getLocalPart()).printStackTrace();
583: if (minOccurs == 1) {
584: arrayQNameLocalName = keyName.getLocalPart() + "[,"
585: + maxOccurs + "]";
586: arrayName = new QName(elementNamespace,
587: arrayQNameLocalName);
588: arrayKey = new SchemaTypeKey(arrayName, false, false,
589: true, elementName);
590: //TODO not clear we want the schemaType as the value
591: qnameMap.put(arrayKey, elementType);
592: }
593: }
594: }
595:
596: public Definition readWsdl(JarFile moduleFile, URI wsdlURI)
597: throws DeploymentException {
598: Definition definition;
599: WSDLFactory wsdlFactory;
600: try {
601: wsdlFactory = WSDLFactory.newInstance();
602: } catch (WSDLException e) {
603: throw new DeploymentException(
604: "Could not create WSDLFactory", e);
605: }
606: WSDLReader wsdlReaderNoImport = wsdlFactory.newWSDLReader();
607: wsdlReaderNoImport.setFeature("javax.wsdl.importDocuments",
608: false);
609: ExtensionRegistry extensionRegistry = new PopulatedExtensionRegistry();
610: extensionRegistry.mapExtensionTypes(Types.class,
611: SchemaConstants.Q_ELEM_XSD_1999,
612: UnknownExtensibilityElement.class);
613: extensionRegistry.registerDeserializer(Types.class,
614: SchemaConstants.Q_ELEM_XSD_1999, extensionRegistry
615: .getDefaultDeserializer());
616: extensionRegistry.registerSerializer(Types.class,
617: SchemaConstants.Q_ELEM_XSD_1999, extensionRegistry
618: .getDefaultSerializer());
619:
620: extensionRegistry.mapExtensionTypes(Types.class,
621: SchemaConstants.Q_ELEM_XSD_2000,
622: UnknownExtensibilityElement.class);
623: extensionRegistry.registerDeserializer(Types.class,
624: SchemaConstants.Q_ELEM_XSD_2000, extensionRegistry
625: .getDefaultDeserializer());
626: extensionRegistry.registerSerializer(Types.class,
627: SchemaConstants.Q_ELEM_XSD_2000, extensionRegistry
628: .getDefaultSerializer());
629:
630: extensionRegistry.mapExtensionTypes(Types.class,
631: SchemaConstants.Q_ELEM_XSD_2001,
632: UnknownExtensibilityElement.class);
633: extensionRegistry.registerDeserializer(Types.class,
634: SchemaConstants.Q_ELEM_XSD_2001, extensionRegistry
635: .getDefaultDeserializer());
636: extensionRegistry.registerSerializer(Types.class,
637: SchemaConstants.Q_ELEM_XSD_2001, extensionRegistry
638: .getDefaultSerializer());
639: wsdlReaderNoImport.setExtensionRegistry(extensionRegistry);
640:
641: JarWSDLLocator wsdlLocator = new JarWSDLLocator(wsdlURI);
642: WSDLReader wsdlReader = wsdlFactory.newWSDLReader();
643:
644: Thread thread = Thread.currentThread();
645: ClassLoader oldCl = thread.getContextClassLoader();
646: thread.setContextClassLoader(this .getClass().getClassLoader());
647: try {
648: try {
649: definition = wsdlReader.readWSDL(wsdlLocator);
650: } catch (WSDLException e) {
651: throw new DeploymentException(
652: "Failed to read wsdl document", e);
653: } catch (RuntimeException e) {
654: throw new DeploymentException(e.getMessage(), e);
655: }
656: } finally {
657: thread.setContextClassLoader(oldCl);
658: }
659:
660: return definition;
661: }
662:
663: public static ExtensibilityElement getExtensibilityElement(
664: Class clazz, List extensibilityElements)
665: throws DeploymentException {
666: for (Iterator iterator = extensibilityElements.iterator(); iterator
667: .hasNext();) {
668: ExtensibilityElement extensibilityElement = (ExtensibilityElement) iterator
669: .next();
670: if (clazz.isAssignableFrom(extensibilityElement.getClass())) {
671: return extensibilityElement;
672: }
673: }
674: throw new DeploymentException("No element of class "
675: + clazz.getName() + " found");
676: }
677:
678: public String movePortLocation(String portComponentName,
679: String servletLocation) throws DeploymentException {
680: DefinitionsDocument doc = (DefinitionsDocument) wsdlMap
681: .get(uris.get(0));
682: TDefinitions definitions = doc.getDefinitions();
683: TService[] services = definitions.getServiceArray();
684: for (int i = 0; i < services.length; i++) {
685: TService service = services[i];
686: TPort[] ports = service.getPortArray();
687: for (int j = 0; j < ports.length; j++) {
688: TPort port = ports[j];
689: if (port.getName().trim().equals(portComponentName)) {
690: XmlCursor portCursor = port.newCursor();
691: try {
692: if (portCursor.toChild(ADDRESS_QNAME)) {
693: if (servletLocation == null) {
694: String original = portCursor
695: .getAttributeText(LOCATION_QNAME);
696: URI originalURI = new URI(original);
697: servletLocation = originalURI.getPath();
698: }
699: portCursor
700: .setAttributeText(
701: LOCATION_QNAME,
702: WebServiceContainer.LOCATION_REPLACEMENT_TOKEN
703: + servletLocation);
704: return servletLocation;
705: }
706: } catch (URISyntaxException e) {
707: throw new DeploymentException(
708: "Could not construct URI for ejb location in wsdl",
709: e);
710: } finally {
711: portCursor.dispose();
712: }
713: }
714: }
715: }
716: throw new DeploymentException("No port found with name "
717: + portComponentName + " expected at " + servletLocation);
718: }
719:
720: private class JarEntityResolver implements EntityResolver {
721:
722: private final static String PROJECT_URL_PREFIX = "project://local/";
723:
724: public InputSource resolveEntity(String publicId,
725: String systemId) throws SAXException, IOException {
726: //seems like this must be a bug in xmlbeans...
727: if (systemId.indexOf(PROJECT_URL_PREFIX) > -1) {
728: systemId = systemId.substring(PROJECT_URL_PREFIX
729: .length());
730: }
731: URI location = ((URI) uris.peek()).resolve(systemId);
732: InputStream wsdlInputStream;
733: try {
734: ZipEntry entry = moduleFile.getEntry(location
735: .toString());
736: wsdlInputStream = moduleFile.getInputStream(entry);
737: XmlObject xmlObject = SchemaDocument.Factory
738: .parse(wsdlInputStream);
739: wsdlMap.put(location, xmlObject);
740: wsdlInputStream.close();
741: wsdlInputStream = moduleFile.getInputStream(entry);
742: } catch (XmlException e) {
743: throw (IOException) new IOException(
744: "Could not parse schema document").initCause(e);
745: }
746: return new InputSource(wsdlInputStream);
747: }
748: }
749:
750: class JarWSDLLocator implements WSDLLocator {
751:
752: private final List streams = new ArrayList();
753: private final URI wsdlURI;
754: private URI latestImportURI;
755:
756: public JarWSDLLocator(URI wsdlURI) {
757: this .wsdlURI = wsdlURI;
758: }
759:
760: public InputSource getBaseInputSource() {
761: InputStream wsdlInputStream;
762: ZipEntry entry = moduleFile.getEntry(wsdlURI.toString());
763: if (entry == null) {
764: throw new RuntimeException(
765: "The webservices.xml file points to a non-existant WSDL file "
766: + wsdlURI.toString());
767: }
768: try {
769: wsdlInputStream = moduleFile.getInputStream(entry);
770: DefinitionsDocument definition = DefinitionsDocument.Factory
771: .parse(wsdlInputStream);
772: wsdlMap.put(wsdlURI, definition);
773: wsdlInputStream.close();
774: wsdlInputStream = moduleFile.getInputStream(entry);
775: streams.add(wsdlInputStream);
776: } catch (Exception e) {
777: throw new RuntimeException(
778: "Could not open stream to wsdl file", e);
779: }
780: return new InputSource(wsdlInputStream);
781: }
782:
783: public String getBaseURI() {
784: return wsdlURI.toString();
785: }
786:
787: public InputSource getImportInputSource(String parentLocation,
788: String relativeLocation) {
789: URI parentURI = URI.create(parentLocation);
790: latestImportURI = parentURI.resolve(relativeLocation);
791: InputStream importInputStream;
792: try {
793: ZipEntry entry = moduleFile.getEntry(latestImportURI
794: .toString());
795: importInputStream = moduleFile.getInputStream(entry);
796: try {
797: DefinitionsDocument definition = DefinitionsDocument.Factory
798: .parse(importInputStream);
799: importInputStream.close();
800: wsdlMap.put(latestImportURI, definition);
801: importInputStream.close();
802: } catch (XmlException e) {
803: //probably was a schema rather than wsdl. If there are real problems they will show up later.
804: }
805: importInputStream = moduleFile.getInputStream(entry);
806: streams.add(importInputStream);
807: } catch (Exception e) {
808: throw new RuntimeException(
809: "Could not open stream to import file", e);
810: }
811: InputSource inputSource = new InputSource(importInputStream);
812: inputSource.setSystemId(getLatestImportURI());
813: return inputSource;
814: }
815:
816: public String getLatestImportURI() {
817: return latestImportURI.toString();
818: }
819:
820: public void close() {
821: for (Iterator iterator = streams.iterator(); iterator
822: .hasNext();) {
823: InputStream inputStream = (InputStream) iterator.next();
824: try {
825: inputStream.close();
826: } catch (IOException e) {
827: //ignore
828: }
829: }
830: streams.clear();
831: }
832: }
833: }
|