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