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