/******************************************************************************* * Copyright (c) 2011 - 2014 Red Hat, Inc. and others. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.ws.ui.utils; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.Collection; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import java.util.Vector; import javax.wsdl.Binding; import javax.wsdl.BindingInput; import javax.wsdl.BindingOperation; import javax.wsdl.Definition; import javax.wsdl.Import; import javax.wsdl.Message; import javax.wsdl.Operation; import javax.wsdl.Part; import javax.wsdl.Port; import javax.wsdl.PortType; import javax.wsdl.Service; import javax.wsdl.Types; import javax.wsdl.WSDLException; import javax.wsdl.extensions.UnknownExtensibilityElement; import javax.wsdl.extensions.schema.Schema; import javax.wsdl.extensions.soap.SOAPHeader; import javax.wsdl.factory.WSDLFactory; import javax.wsdl.xml.WSDLReader; import javax.xml.namespace.QName; import org.eclipse.emf.common.util.EList; import org.eclipse.xsd.XSDDiagnostic; import org.eclipse.xsd.XSDDiagnosticSeverity; import org.eclipse.xsd.XSDNamedComponent; import org.eclipse.xsd.XSDSchema; import org.eclipse.xsd.XSDSchemaContent; import org.eclipse.xsd.XSDSchemaDirective; import org.eclipse.xsd.impl.XSDSchemaImpl; import org.eclipse.xsd.util.XSDParser; import org.jdom.Element; import org.jdom.input.DOMBuilder; import com.ibm.wsdl.Constants; /** * Some of this code was borrowed from the org.eclipse.wst.ws.explorer Web Services Explorer * view from WTP. * @author bfitzpat * */ public class SchemaUtils { private static final String SIMPLE_TYPE_NAME = "simpleType"; //$NON-NLS-1$ private static final String DOUBLE_TYPE_NAME = "double"; //$NON-NLS-1$ private static final String INT_TYPE_NAME = "int"; //$NON-NLS-1$ private static final String STRING_TYPE_NAME = "string"; //$NON-NLS-1$ private static final String BOOLEAN_TYPE_NAME = "boolean"; //$NON-NLS-1$ private static final String DECIMAL_TYPE_NAME = "decimal"; //$NON-NLS-1$ private static final String PRECISION_DECIMAL_TYPE_NAME = "precisionDecimal"; //$NON-NLS-1$ private static final String FLOAT_TYPE_NAME = "float"; //$NON-NLS-1$ private static final String DURATION_TYPE_NAME = "duration"; //$NON-NLS-1$ private static final String DATETIME_TYPE_NAME = "dateTime"; //$NON-NLS-1$ private static final String DATE_TYPE_NAME = "date"; //$NON-NLS-1$ private static final String TIME_TYPE_NAME = "time"; //$NON-NLS-1$ private static final String GYEARMONTH_TYPE_NAME = "gYearMonth"; //$NON-NLS-1$ private static final String GYEAR_TYPE_NAME = "gYear"; //$NON-NLS-1$ private static final String GMONTHDAY_TYPE_NAME = "gMonthDay"; //$NON-NLS-1$ private static final String GDAY_TYPE_NAME = "gDay"; //$NON-NLS-1$ private static final String GMONTH_TYPE_NAME = "gMonth"; //$NON-NLS-1$ private static final String HEXBINARY_TYPE_NAME = "hexBinary"; //$NON-NLS-1$ private static final String BASE64BINARY_TYPE_NAME = "base64Binary"; //$NON-NLS-1$ private static final String ANYURI_TYPE_NAME = "anyURI"; //$NON-NLS-1$ private static final String NOTATION_TYPE_NAME = "NOTATION"; //$NON-NLS-1$ private static Vector<XSDSchema> schemaList_; private static Vector<QName> w3SchemaQNameList_; private static Vector<XSDSchema> constantSchemaList_; private static HashMap<String, String> namespacesAndPrefixes_; private static String wsdlUrl_; private static Vector<String> schemaURI_; private static Definition definition_; private static boolean rootIsQualified_ = false; private static String rootURI_ = null; private final static String DEF_FACTORY_PROPERTY_NAME = "javax.wsdl.factory.DefinitionFactory"; //$NON-NLS-1$ private final static String PRIVATE_DEF_FACTORY_CLASS = "org.apache.wsif.wsdl.WSIFWSDLFactoryImpl"; //$NON-NLS-1$ public final static String SOAP_NS_URI = "http://schemas.xmlsoap.org/soap/envelope/"; //$NON-NLS-1$ public final static String SOAP12_ENVELOPE_NS_URI = "http://www.w3.org/2003/05/soap-envelope"; //$NON-NLS-1$ public final static String SOAP12_NS_URI = "http://schemas.xmlsoap.org/wsdl/soap12/"; //$NON-NLS-1$ public final static String SOAP12_PREFIX = "soap12"; //$NON-NLS-1$ public final static String SOAP_PREFIX = "soap"; //$NON-NLS-1$ static { // w3 schema URI list: // http://www.w3.org/2001/XMLSchema // http://www.w3.org/2000/10/XMLSchema // http://www.w3.org/1999/XMLSchema w3SchemaQNameList_ = new Vector<QName>(); w3SchemaQNameList_.addElement(new QName(FragmentConstants.NS_URI_CURRENT_SCHEMA_XSD,"schema")); //$NON-NLS-1$ w3SchemaQNameList_.addElement(new QName(FragmentConstants.NS_URI_2000_SCHEMA_XSD,"schema")); //$NON-NLS-1$ w3SchemaQNameList_.addElement(new QName(FragmentConstants.NS_URI_1999_SCHEMA_XSD,"schema")); //$NON-NLS-1$ // Constant schema URI list: // http://www.w3.org/2001/XMLSchema // http://www.w3.org/2000/10/XMLSchema // http://www.w3.org/1999/XMLSchema // http://schemas.xmlsoap.org/soap/encoding/ // http://schemas.xmlsoap.org/wsdl/ constantSchemaList_ = new Vector<XSDSchema>(); constantSchemaList_.addElement(XSDSchemaImpl.getSchemaForSchema(FragmentConstants.NS_URI_CURRENT_SCHEMA_XSD)); constantSchemaList_.addElement(XSDSchemaImpl.getSchemaForSchema(FragmentConstants.NS_URI_2000_SCHEMA_XSD)); constantSchemaList_.addElement(XSDSchemaImpl.getSchemaForSchema(FragmentConstants.NS_URI_1999_SCHEMA_XSD)); constantSchemaList_.addElement(XSDSchemaImpl.getSchemaForSchema(FragmentConstants.NS_URI_SOAP_ENC)); constantSchemaList_.addElement(XSDSchemaImpl.getSchemaForSchema(FragmentConstants.URI_WSDL)); namespacesAndPrefixes_ = new HashMap<String, String>(); } public static Vector<String> loadWSDL(Definition wsdlDefinition ) throws WSDLException { Vector<String> errorMessages = new Vector<String>(); definition_ = wsdlDefinition; schemaList_ = new Vector<XSDSchema>(); if (definition_ != null) { wsdlUrl_ = wsdlDefinition.getDocumentBaseURI(); gatherSchemas(definition_, wsdlUrl_); // Validate the schemas. for (int i=0;i<schemaList_.size();i++) { XSDSchema xsdSchema = (XSDSchema)schemaList_.elementAt(i); // xsdSchema.clearDiagnostics(); // xsdSchema.validate(); if (xsdSchema == null) continue; EList<XSDDiagnostic> errors = xsdSchema.getAllDiagnostics(); if (!errors.isEmpty()) { for (ListIterator<XSDDiagnostic> li = errors.listIterator();li.hasNext();) { XSDDiagnostic xd = (XSDDiagnostic)li.next(); String msg = xd.getMessage(); // do not report low severity diagnostics or erroneous array reference errors. if (xd.getSeverity().getValue() == XSDDiagnosticSeverity.FATAL_LITERAL.getValue() || (msg != null && msg.length() > 0 && msg.toLowerCase().indexOf("#array") != -1)) //$NON-NLS-1$ li.remove(); else { if (msg != null && msg.length() > 0) errorMessages.addElement(xd.getMessage()); } } } } for (int i=0;i<constantSchemaList_.size();i++) schemaList_.addElement(constantSchemaList_.elementAt(i)); } return errorMessages; } public static String getSampleSOAPInputMessage ( Definition wsdlDefinition, String serviceName, String portName, String bindingName, String opName ) { try { loadWSDL (wsdlDefinition); } catch (WSDLException e) { e.printStackTrace(); } namespacesAndPrefixes_ = new HashMap<String, String>(); Map<?, ?> services = wsdlDefinition.getServices(); Set<?> serviceKeys = services.keySet(); for( Iterator<?> it = serviceKeys.iterator(); it.hasNext(); ) { QName serviceKey = (QName) it.next(); if (serviceName != null && serviceKey.getLocalPart().contentEquals(serviceName)) { Service service = (Service) services.get( serviceKey ); Map<?, ?> ports = service.getPorts(); Set<?> portKeys = ports.keySet(); for( Iterator<?> it2 = portKeys.iterator(); it2.hasNext(); ) { String portKey = (String) it2.next(); if (portName != null && portKey.contentEquals(portName)) { Port port = (Port) ports.get( portKey ); Binding wsdlBinding = port.getBinding(); PortType portType = wsdlBinding.getPortType(); List<?> operations = portType.getOperations(); for (Iterator<?> it3 = operations.iterator(); it3.hasNext();){ Operation operation = (Operation) it3.next(); if (opName != null && operation.getName().contentEquals(opName)) { Message inputMsg = operation.getInput().getMessage(); Collection<?> parts = inputMsg.getParts().values(); StringBuffer buf = new StringBuffer(); for( Iterator<?> it4 = parts.iterator(); it4.hasNext(); ) { Part part = (Part) it4.next(); if (part.getName().equalsIgnoreCase("header")) { //$NON-NLS-1$ continue; } WSDLPartsToXSDTypeMapper mapper = new WSDLPartsToXSDTypeMapper(); mapper.addSchemas(schemaList_); buf.append(startProcessingPartXML(wsdlDefinition, part)); } return buf.toString(); } } } } } } return null; } public static Definition readWSDLURL(URL contextURL) throws WSDLException, NullPointerException { Properties props = System.getProperties(); String oldPropValue = props.getProperty(DEF_FACTORY_PROPERTY_NAME); wsdlUrl_ = contextURL.toExternalForm(); props.setProperty(DEF_FACTORY_PROPERTY_NAME, PRIVATE_DEF_FACTORY_CLASS); WSDLFactory factory = WSDLFactory.newInstance(); WSDLReader wsdlReader = factory.newWSDLReader(); wsdlReader.setFeature(Constants.FEATURE_VERBOSE, false); wsdlReader.setFeature("javax.wsdl.importDocuments", true); //$NON-NLS-1$ String context = null; if (contextURL != null) context = contextURL.toString(); Definition def = wsdlReader.readWSDL(context); if (oldPropValue != null) { props.setProperty(DEF_FACTORY_PROPERTY_NAME, oldPropValue); } else { props.remove(DEF_FACTORY_PROPERTY_NAME); } return def; } public static String getSampleSOAPMessageHeader ( Definition wsdlDefinition, String serviceName, String portName, String bindingName, String opName ) { try { loadWSDL (wsdlDefinition); } catch (WSDLException e) { e.printStackTrace(); } namespacesAndPrefixes_ = new HashMap<String, String>(); Map<?, ?> services = wsdlDefinition.getServices(); Set<?> serviceKeys = services.keySet(); for( Iterator<?> it = serviceKeys.iterator(); it.hasNext(); ) { QName serviceKey = (QName) it.next(); if (serviceName != null && serviceKey.getLocalPart().contentEquals(serviceName)) { Service service = (Service) services.get( serviceKey ); Map<?, ?> ports = service.getPorts(); Set<?> portKeys = ports.keySet(); for( Iterator<?> it2 = portKeys.iterator(); it2.hasNext(); ) { String portKey = (String) it2.next(); if (portName != null && portKey.contentEquals(portName)) { Port port = (Port) ports.get( portKey ); Binding wsdlBinding = port.getBinding(); List<?> operations = wsdlBinding.getBindingOperations(); for (Iterator<?> it3 = operations.iterator(); it3.hasNext();){ BindingOperation operation = (BindingOperation) it3.next(); if (opName != null && operation.getName().contentEquals(opName)) { BindingInput input = operation.getBindingInput(); List<?> extensions = input.getExtensibilityElements(); for (Iterator<?> extIter = extensions.iterator(); extIter.hasNext();) { Object extension = extIter.next(); if (extension instanceof SOAPHeader) { SOAPHeader header = (SOAPHeader) extension; String part = header.getPart(); StringBuffer buf = new StringBuffer(); WSDLPartsToXSDTypeMapper mapper = new WSDLPartsToXSDTypeMapper(); mapper.addSchemas(schemaList_); buf.append(startProcessingPartXML(wsdlDefinition, part, header.getMessage().getNamespaceURI())); return buf.toString(); } } } } } } } } return null; } private static XSDSchema getSchemaForNamespace ( String namespaceURI ) { Iterator<XSDSchema> iter = schemaList_.iterator(); while (iter.hasNext()) { XSDSchema schema = (XSDSchema)iter.next(); if (schema != null && schema.getTargetNamespace() != null && schema.getTargetNamespace().equals(namespaceURI)) { return schema; } } return null; } private static String getURIForNamespacePrefix ( String nsPrefix ) { Iterator<XSDSchema> iter = schemaList_.iterator(); while (iter.hasNext()) { XSDSchema schema = (XSDSchema)iter.next(); String nsURI = schema.getQNamePrefixToNamespaceMap().get(nsPrefix); if (nsURI != null) { return nsURI; } } return null; } private final static void gatherSchemas(Definition definition, String definitionURL) { Types types = definition.getTypes(); if (types != null) { List<?> extTypes = types.getExtensibilityElements(); if (extTypes != null) { // org.eclipse.emf.common.util.URI uri = org.eclipse.emf.common.util.URI.createURI(definitionURL); // Resource resource = resourceSet.createResource(uri); for (int i=0;i<extTypes.size();i++) { XSDSchema xsdSchema = null; Object obj = extTypes.get(i); if (obj instanceof Schema) { Schema schemaElement = (Schema) obj; if (isW3SchemaElementType(schemaElement.getElementType())) { xsdSchema = XSDSchemaImpl.createSchema(schemaElement.getElement()); if (xsdSchema != null) { xsdSchema.update(); xsdSchema.updateElement(); if(!checkSchemaURI(definitionURL)){ schemaList_.addElement(xsdSchema); gatherSchemaDirective(xsdSchema, definitionURL); } } } } else if (obj instanceof UnknownExtensibilityElement) { UnknownExtensibilityElement schemaElement = (UnknownExtensibilityElement)obj; if (isW3SchemaElementType(schemaElement.getElementType())) { xsdSchema = XSDSchemaImpl.createSchema(schemaElement.getElement()); if(!checkSchemaURI(definitionURL)){ schemaList_.addElement(xsdSchema); gatherSchemaDirective(xsdSchema, definitionURL); } //Add the Schema to the resource // boolean success = resource.getContents().add(xsdSchema); // System.out.println(success + "Added schema " + xsdSchema.getTargetNamespace() + " to wsdl resource " + uri.toString()); } } } } } Map<?, ?> imports = definition.getImports(); if (imports != null) gatherImportedSchemas(definition,imports); } private final static boolean isW3SchemaElementType(QName qname) { for (int i=0;i<w3SchemaQNameList_.size();i++) { QName w3SchemaQName = (QName)w3SchemaQNameList_.elementAt(i); if (w3SchemaQName.equals(qname)) return true; } return false; } private static boolean checkSchemaURI(String schemaURI){ boolean found = false; if (schemaURI != null) { schemaURI = normalize(schemaURI); if(schemaURI != null) { if (schemaURI.equals(normalize(wsdlUrl_))) return false; if (schemaURI_ == null) return false; Enumeration<String> e = schemaURI_.elements(); while(e.hasMoreElements()){ String uri = (String)e.nextElement(); if(schemaURI.equals(uri)){ found = true; break; } } if (!found){ schemaURI_.addElement(schemaURI); } } } return found; } private static String normalize(String uri ) { try { String encodedURI = URIEncoder.encode(uri,"UTF-8"); //$NON-NLS-1$ URI normalizedURI = new URI(encodedURI); normalizedURI = normalizedURI.normalize(); return normalizedURI.toString(); } catch (URISyntaxException e) { return uri; } catch (UnsupportedEncodingException e) { return uri; } } private final static void gatherSchemaDirective(XSDSchema xsdSchema, String xsdSchemaURL) { if (xsdSchema != null) { EList<XSDSchemaContent> xsdSchemaContents = xsdSchema.getContents(); for (Iterator<XSDSchemaContent> it = xsdSchemaContents.iterator(); it.hasNext();) { Object content = it.next(); if (content instanceof XSDSchemaDirective) { XSDSchemaDirective xsdSchemaDirective = (XSDSchemaDirective)content; StringBuffer xsdSchemaDirectiveURL = new StringBuffer(); String xsdSchemaDirectiveLocation = xsdSchemaDirective.getSchemaLocation(); if (xsdSchemaDirectiveLocation != null && xsdSchemaDirectiveLocation.indexOf(':') == -1 && xsdSchemaURL != null && xsdSchemaURL.indexOf(':') != -1) { // relative URL int index = xsdSchemaURL.lastIndexOf('/'); if (index != -1) xsdSchemaDirectiveURL.append(xsdSchemaURL.substring(0, index+1)); else { xsdSchemaDirectiveURL.append(xsdSchemaURL); xsdSchemaDirectiveURL.append('/'); } } xsdSchemaDirectiveURL.append(xsdSchemaDirectiveLocation); //encode the URL so that Schemas with non-ASCII filenames can be resolved String xsdSchemaDirectiveURLString = URLUtils.encodeURLString(xsdSchemaDirectiveURL.toString()); // resolve schema directive XSDSchema resolvedSchema = xsdSchemaDirective.getResolvedSchema(); if (resolvedSchema == null && xsdSchemaDirectiveURLString.length() > 0) resolvedSchema = getSchema(xsdSchemaDirectiveURLString); if (resolvedSchema != null) { if(!checkSchemaURI(xsdSchemaDirectiveURLString)){ schemaList_.addElement(resolvedSchema); gatherSchemaDirective(resolvedSchema, xsdSchemaDirectiveURLString); } } } } } } private final static XSDSchema getSchema(String locURI) { locURI = URLUtils.encodeURLString(locURI); XSDSchema xsdSchema = XSDSchemaImpl.getSchemaForSchema(locURI); if (xsdSchema == null) { @SuppressWarnings("deprecation") XSDParser p = new XSDParser(); InputStream is = NetUtils.getURLInputStream(locURI); if (is != null) { p.parse(is); xsdSchema = p.getSchema(); } } return xsdSchema; } private final static void gatherImportedSchemas(Definition definition,Map<?, ?> imports) { for (Iterator<?> iterator = imports.keySet().iterator();iterator.hasNext();) { List<?> importList = (List<?>)imports.get(iterator.next()); for (int i=0;i<importList.size();i++) { Import imp = (Import)importList.get(i); StringBuffer locURI = new StringBuffer(imp.getLocationURI()); if (!Validator.validateURL(locURI.toString())) { String base = definition.getDocumentBaseURI(); locURI.insert(0,base.substring(0,base.lastIndexOf('/')+1)); } try { URL tryURL = new URL ( locURI.toString()); Definition importDef = readWSDLURL( tryURL ); gatherSchemas(importDef, locURI.toString()); } catch (WSDLException e) { // May be an XSD file. gatherSchema(locURI.toString()); } catch (MalformedURLException e) { e.printStackTrace(); } } } } private final static void gatherSchema(String locURI) { XSDSchema xsdSchema = getSchema(locURI); if (xsdSchema != null) { schemaList_.addElement(xsdSchema); gatherSchemaDirective(xsdSchema, locURI); } } private static XSDSchema findFirstSchemaWithPartNameAsChild ( String partName ) { for (Iterator<XSDSchema> schemaIter = schemaList_.iterator(); schemaIter.hasNext(); ) { XSDSchema schema = schemaIter.next(); DOMBuilder domBuilder = new DOMBuilder(); org.jdom.Element jdomSchemaElement = domBuilder.build(schema.getElement()); List<?> kids = jdomSchemaElement.getChildren(); for (Iterator<?> kidIter = kids.iterator(); kidIter.hasNext(); ) { Object kid = kidIter.next(); if (kid instanceof org.jdom.Element) { org.jdom.Element kidElement = (org.jdom.Element) kid; if (kidElement.getAttribute("name") != null) { //$NON-NLS-1$ if (kidElement.getAttributeValue("name").equals(partName)) { //$NON-NLS-1$ return schema; } } } } } return null; } private static org.jdom.Element findFirstElementWithPartNameInSchema( XSDSchema schema, String partName ) { DOMBuilder domBuilder = new DOMBuilder(); org.jdom.Element jdomSchemaElement = domBuilder.build(schema.getElement()); List<?> kids = jdomSchemaElement.getChildren(); for (Iterator<?> kidIter = kids.iterator(); kidIter.hasNext(); ) { Object kid = kidIter.next(); if (kid instanceof org.jdom.Element) { org.jdom.Element kidElement = (org.jdom.Element) kid; if (kidElement.getAttribute("name") != null) { //$NON-NLS-1$ if (kidElement.getAttributeValue("name").equals(partName)) { //$NON-NLS-1$ return kidElement; } } } } return null; } private static String startProcessingPartXML ( Definition wsdlDefinition, String partName, String partUri ) { XSDSchema schema = findFirstSchemaWithPartNameAsChild(partName); DOMBuilder domBuilder = new DOMBuilder(); org.jdom.Element jdomSchemaElement = domBuilder.build(schema.getElement()); org.jdom.Element jdomElement = findFirstElementWithPartNameInSchema(schema, partName); String typeAttr = jdomElement.getAttributeValue("type"); //$NON-NLS-1$ String nsprefix = null; String nstypename = typeAttr; if (typeAttr.indexOf(':') > 0) { nsprefix = typeAttr.substring(0, typeAttr.indexOf(':')); nstypename = typeAttr.substring(typeAttr.indexOf(':') + 1, typeAttr.length()); } String uri = schema.getTargetNamespace(); if (nsprefix != null && !nsprefix.equalsIgnoreCase("tns")) { //$NON-NLS-1$ uri = getNSURI(nsprefix, wsdlDefinition); } StringBuffer buf = new StringBuffer(); if (nsprefix != null && !nsprefix.equalsIgnoreCase("tns")) { //$NON-NLS-1$ if (schema.getTargetNamespace().equals(uri)) { // cool, we're good buf.append(createXMLForJDOMElement2( jdomSchemaElement, jdomElement )); } else { XSDSchema importXSD = getSchemaForNamespace(uri); if (importXSD != null) { importXSD.updateElement(true); org.jdom.Element jdomSchemaElement2 = domBuilder.build(importXSD.getElement()); Element child = jdomSchemaElement2.getChild(nstypename); buf.append(createXMLForJDOMElement2( jdomSchemaElement2, child )); } } } else { buf.append(createXMLForJDOMElement2( jdomSchemaElement, jdomElement )); } return buf.toString(); } private static String startProcessingPartXML ( Definition wsdlDefinition, Part part ) { DOMBuilder domBuilder = new DOMBuilder(); WSDLPartsToXSDTypeMapper mapper = new WSDLPartsToXSDTypeMapper(); mapper.addSchemas(schemaList_); XSDNamedComponent xsdComponent = mapper.getXSDTypeFromSchema(part); if (xsdComponent == null) { return "<error>Generating sample SOAP request</error>"; //$NON-NLS-1$ } xsdComponent.updateElement(true); XSDSchema schema = xsdComponent.getSchema(); schema.updateElement(true); if (!schema.getTargetNamespace().equals(FragmentConstants.NS_URI_CURRENT_SCHEMA_XSD)) { rootIsQualified_ = true; rootURI_ = schema.getTargetNamespace(); } org.jdom.Element jdomSchemaElement = domBuilder.build(schema.getElement()); org.jdom.Element jdomElement = domBuilder.build(xsdComponent.getElement()); String typeAttr = xsdComponent.getElement().getAttribute("type"); //$NON-NLS-1$ String nsprefix = null; String nstypename = typeAttr; if (typeAttr.indexOf(':') > 0) { nsprefix = typeAttr.substring(0, typeAttr.indexOf(':')); nstypename = typeAttr.substring(typeAttr.indexOf(':') + 1, typeAttr.length()); } String uri = schema.getTargetNamespace(); if (nsprefix != null && !nsprefix.equalsIgnoreCase("tns")) { //$NON-NLS-1$ uri = getNSURI(nsprefix, wsdlDefinition); } StringBuffer buf = new StringBuffer(); if (nsprefix != null && !nsprefix.equalsIgnoreCase("tns")) { //$NON-NLS-1$ if (schema.getTargetNamespace().equals(uri)) { // cool, we're good org.jdom.Element jdomSchemaElement2 = domBuilder.build(xsdComponent.getElement()); buf.append(createXMLForJDOMElement2( jdomSchemaElement, jdomSchemaElement2 )); } else { XSDSchema importXSD = getSchemaForNamespace(uri); if (importXSD != null) { importXSD.updateElement(true); org.jdom.Element jdomSchemaElement2 = domBuilder.build(importXSD.getElement()); Element child = jdomSchemaElement2.getChild(nstypename); buf.append(createXMLForJDOMElement2( jdomSchemaElement2, child )); } } } else if (part.getTypeName() != null && isTypeBaseXSDOrSimple(part.getTypeName().getNamespaceURI(), part.getTypeName().getLocalPart())) { buf.append('<' + part.getName() + ">?</" + part.getName() + '>'); //$NON-NLS-1$ } else { buf.append(createXMLForJDOMElement2( jdomSchemaElement, jdomElement )); } return buf.toString(); } private static org.jdom.Element findJDOMTypeInSchema ( org.jdom.Element schemaElement, String typeName ) { if (schemaElement != null) { String nstypename = null; if (typeName.indexOf(':') > -1) { nstypename = typeName.substring(typeName.indexOf(':') + 1, typeName.length()); } else { nstypename = typeName; } List<?> kids = schemaElement.getChildren(); for (Iterator<?> kidsIter = kids.iterator(); kidsIter.hasNext(); ) { Object kid = kidsIter.next(); if (kid instanceof org.jdom.Element) { org.jdom.Element kidelement = (org.jdom.Element)kid; if (kidelement.getName().equals("complexType")) { //$NON-NLS-1$ if (kidelement.getAttributeValue("name").equals(nstypename)) //$NON-NLS-1$ return kidelement; } if (kidelement.getName().equals("simpleType")) { //$NON-NLS-1$ if (kidelement.getAttributeValue("name").equals(nstypename)) //$NON-NLS-1$ return kidelement; } if (kidelement.getName().equals("attribute")) { //$NON-NLS-1$ if (kidelement.getAttributeValue("name").equals(nstypename)) //$NON-NLS-1$ return kidelement; } } } } return null; } private static org.jdom.Element findJDOMTypeInSchemaByNameAttr ( org.jdom.Element schemaElement, String name ) { if (schemaElement != null) { List<?> kids = schemaElement.getChildren(); for (Iterator<?> kidsIter = kids.iterator(); kidsIter.hasNext(); ) { Object kid = kidsIter.next(); if (kid instanceof org.jdom.Element) { org.jdom.Element kidelement = (org.jdom.Element)kid; if (kidelement.getName().equals("complexType")) { //$NON-NLS-1$ if (kidelement.getAttributeValue("name").equals(name)) //$NON-NLS-1$ return kidelement; } if (kidelement.getName().equals("simpleType")) { //$NON-NLS-1$ if (kidelement.getAttributeValue("name").equals(name)) //$NON-NLS-1$ return kidelement; } if (kidelement.getName().equals("attribute")) { //$NON-NLS-1$ if (kidelement.getAttributeValue("name").equals(name)) //$NON-NLS-1$ return kidelement; } if (kidelement.getName().equals("element")) { //$NON-NLS-1$ if (kidelement.getAttributeValue("name").equals(name)) //$NON-NLS-1$ return kidelement; } } } } return null; } private static org.jdom.Element findJDOMElementInSchema ( org.jdom.Element schemaElement, String typeName ) { if (schemaElement != null) { List<?> kids = schemaElement.getChildren(); for (Iterator<?> kidsIter = kids.iterator(); kidsIter.hasNext(); ) { Object kid = kidsIter.next(); if (kid instanceof org.jdom.Element) { org.jdom.Element kidelement = (org.jdom.Element)kid; if (kidelement.getName().equals("element")) { //$NON-NLS-1$ String attrvalue = kidelement.getAttributeValue("type"); //$NON-NLS-1$ if (attrvalue != null && attrvalue.equals(typeName)) { kidelement = findJDOMTypeInSchema(schemaElement, typeName); return kidelement; } } } } } return null; } private static org.jdom.Element findJDOMElementInSchemaByName ( org.jdom.Element schemaElement, String typeName ) { if (schemaElement != null) { List<?> kids = schemaElement.getChildren(); for (Iterator<?> kidsIter = kids.iterator(); kidsIter.hasNext(); ) { Object kid = kidsIter.next(); if (kid instanceof org.jdom.Element) { org.jdom.Element kidelement = (org.jdom.Element)kid; if (kidelement.getName().equals("element")) { //$NON-NLS-1$ String attrvalue = kidelement.getAttributeValue("name"); //$NON-NLS-1$ if (attrvalue != null && attrvalue.equals(typeName)) { String elemType = kidelement.getAttributeValue("type"); //$NON-NLS-1$ if (elemType != null) { String nsprefix = elemType.substring(0, elemType.indexOf(':')); String testUri = getURIForNamespacePrefix(nsprefix); XSDSchema importXSD = getSchemaForNamespace(testUri); if (importXSD != null) { DOMBuilder domBuilder = new DOMBuilder(); importXSD.updateElement(true); org.jdom.Element importXSDSchema = domBuilder.build(importXSD.getElement()); org.jdom.Element element2 = findJDOMTypeInSchema(importXSDSchema, elemType); if (element2 != null) { return element2; } else { element2 = findJDOMElementInSchema(importXSDSchema, elemType); if (element2 != null) { return element2; } } } } } } } } } return null; } private static String handleAttributes ( org.jdom.Element element ) { StringBuffer buf = new StringBuffer(); List<?> kids = element.getChildren(); boolean isQualified = false; for (Iterator<?> kidIter = kids.iterator(); kidIter.hasNext(); ) { Element kid = (Element) kidIter.next(); if (kid.getName().equals("attribute") ) {//$NON-NLS-1$ // <xs:attribute ref="ns3:C" use="required" /> if (kid.getAttribute("ref") != null) {//$NON-NLS-1$ String elemType = kid.getAttributeValue("ref");//$NON-NLS-1$ String nsprefix = elemType.substring(0, elemType.indexOf(':')); String typename = elemType.substring(elemType.indexOf(':') + 1, elemType.length()); if (elemType.indexOf(':') > -1) { if (!(elemType.startsWith("xs:") || elemType.startsWith("xsd:"))) //$NON-NLS-1$ //$NON-NLS-2$ isQualified = true; } String testUri = getURIForNamespacePrefix(nsprefix); XSDSchema importXSD = getSchemaForNamespace(testUri); if (importXSD != null) { DOMBuilder domBuilder = new DOMBuilder(); importXSD.updateElement(true); org.jdom.Element importXSDSchema = domBuilder.build(importXSD.getElement()); org.jdom.Element element2 = findJDOMTypeInSchema(importXSDSchema, typename); if (element2 != null) { element = element2; } else { element2 = findJDOMElementInSchema(importXSDSchema, typename); if (element2 != null) { element = element2; } } if (element != null) { if (isQualified) { String prefix = makePrefixFromURI(testUri); // xmlns:ns1="http://schemas.xmlsoap.org/soap/http" if (!namespacesAndPrefixes_.containsKey(prefix)) { buf.append(" xmlns:" + prefix + "=\"" + testUri + "\""); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ namespacesAndPrefixes_.put(prefix, testUri); } buf.append(' ' + prefix + ':'); } String name = element.getAttributeValue("name"); //$NON-NLS-1$ buf.append(name + "=\"?\" "); //$NON-NLS-1$ } } } } } return buf.toString(); } private static boolean namespacePrefixListContainsURI ( String uri ) { if (namespacesAndPrefixes_ != null) { if (namespacesAndPrefixes_.containsValue(uri)) { return true; } } return false; } private static String makePrefixFromURI ( String uri ) { if (namespacePrefixListContainsURI(uri)) { Iterator<Entry<String, String>> iter = namespacesAndPrefixes_.entrySet().iterator(); while (iter.hasNext()) { Map.Entry<String, String> entry = iter.next(); if (entry.getValue().equals(uri)) { return entry.getKey(); } } } String tnsprefix = uri.substring(uri.indexOf("://") + 3, uri.length()); //$NON-NLS-1$ if (tnsprefix.contains(":")) {//$NON-NLS-1$ tnsprefix = uri.substring(0, uri.indexOf(':')); } if (tnsprefix.length() > 4) { if (tnsprefix.endsWith("/")) { //$NON-NLS-1$ tnsprefix = tnsprefix.substring(0, tnsprefix.length() - 1); } if (tnsprefix.lastIndexOf('/') > -1) { tnsprefix = tnsprefix.substring(tnsprefix.lastIndexOf('/') + 1, tnsprefix.length()); } if (tnsprefix.length() > 4) { tnsprefix = tnsprefix.substring(0, 4); } tnsprefix = tnsprefix.toLowerCase(); if (namespacesAndPrefixes_.containsKey(tnsprefix)) { int i = 1; String test = tnsprefix + i; while (namespacesAndPrefixes_.containsKey(test)) { i++; test = tnsprefix + i; } tnsprefix = test; } } return tnsprefix; } private static boolean elementHasChildren ( org.jdom.Element element ) { boolean rtnflag = false; if (element.getChildren() != null && element.getChildren().size() > 0) { List<?> kids = element.getChildren(); for (Iterator<?> kidIter = kids.iterator(); kidIter.hasNext(); ) { Element kid = (Element) kidIter.next(); if (kid.getName().equals("element")) { //$NON-NLS-1$ rtnflag = true; } boolean kidflag = elementHasChildren(kid); if (kidflag) rtnflag = true; } } return rtnflag; } private static String createXMLForJDOMElement2 ( org.jdom.Element schemaElement, org.jdom.Element element ) { StringBuffer buf = new StringBuffer(); String nstypename = null; String tns = null; String tnsprefix = null; if (schemaElement.getNamespace("tns") != null) {//$NON-NLS-1$ tns = schemaElement.getNamespace("tns").getURI();//$NON-NLS-1$ tnsprefix = makePrefixFromURI(tns); } boolean isQualified = false; if (element.getAttribute("name") != null) {//$NON-NLS-1$ nstypename = element.getAttributeValue("name");//$NON-NLS-1$ } if (element.getAttribute("type") != null) {//$NON-NLS-1$ String type2FindName = element.getAttributeValue("type");//$NON-NLS-1$ if (type2FindName.indexOf(':') > -1) { if (!(type2FindName.startsWith("xs:") || type2FindName.startsWith("xsd:"))) //$NON-NLS-1$ //$NON-NLS-2$ isQualified = true; } org.jdom.Element element2 = findJDOMTypeInSchema(schemaElement, type2FindName); if (element2 != null) { element = element2; if (element.getParentElement() != null) { org.jdom.Element parent = element.getParentElement(); if (parent.getNamespace("tns") != null) {//$NON-NLS-1$ tns = parent.getNamespace("tns").getURI();//$NON-NLS-1$ tnsprefix = makePrefixFromURI(tns); } } } } if (element.getAttribute("ref") != null) {//$NON-NLS-1$ String ref2FindName = element.getAttributeValue("ref");//$NON-NLS-1$ if (ref2FindName.indexOf(':') > -1) { if (!(ref2FindName.startsWith("xs:") || ref2FindName.startsWith("xsd:"))) //$NON-NLS-1$ //$NON-NLS-2$ isQualified = true; } org.jdom.Element element2 = findJDOMTypeInSchema(schemaElement, ref2FindName); if (element2 != null) { element = element2; if (element.getParentElement() != null) { org.jdom.Element parent = element.getParentElement(); if (parent.getNamespace("tns") != null) {//$NON-NLS-1$ tns = parent.getNamespace("tns").getURI();//$NON-NLS-1$ tnsprefix = makePrefixFromURI(tns); } } } else { element2 = findJDOMElementInSchema(schemaElement, ref2FindName); if (element2 != null) { element = element2; if (element.getParentElement() != null) { org.jdom.Element parent = element.getParentElement(); if (parent.getNamespace("tns") != null) {//$NON-NLS-1$ tns = parent.getNamespace("tns").getURI();//$NON-NLS-1$ tnsprefix = makePrefixFromURI(tns); } } } } } Integer minOccurs = 1; String elemType = null; if (element.getAttributes().size() > 0) { if (element.getAttribute("minOccurs") != null) {//$NON-NLS-1$ String value = element.getAttributeValue("minOccurs");//$NON-NLS-1$ minOccurs = Integer.decode(value); } if (element.getAttribute("type") != null) {//$NON-NLS-1$ elemType = element.getAttributeValue("type");//$NON-NLS-1$ String nsprefix = ""; //$NON-NLS-1$ try { nsprefix = elemType.substring(0, elemType.indexOf(':')); } catch (StringIndexOutOfBoundsException e) { // ignore } String testUri = getURIfromSchemaPrefix(element, nsprefix); if (elemType.indexOf(':') > -1) { if (!(elemType.startsWith("xs:") || elemType.startsWith("xsd:"))){ //$NON-NLS-1$ //$NON-NLS-2$ isQualified = true; } } XSDSchema importXSD = getSchemaForNamespace(testUri); if (importXSD != null) { DOMBuilder domBuilder = new DOMBuilder(); importXSD.updateElement(true); org.jdom.Element importXSDSchema = domBuilder.build(importXSD.getElement()); org.jdom.Element element2 = findJDOMTypeInSchema(importXSDSchema, elemType); if (element2 != null) { element = element2; } else { element2 = findJDOMElementInSchema(importXSDSchema, elemType); if (element2 != null) { element = element2; } else { element2 = findJDOMElementInSchemaByName(schemaElement, nstypename); if (element2 != null) { element = element2; } } } } else if (schemaElement != null) { org.jdom.Element element2 = findJDOMTypeInSchema(schemaElement, elemType); if (element2 != null) { element = element2; } else { element2 = findJDOMElementInSchema(schemaElement, elemType); if (element2 != null) { element = element2; } else { element2 = findJDOMElementInSchemaByName(schemaElement, nstypename); if (element2 != null) { element = element2; } } } } } if (element.getAttribute("ref") != null) {//$NON-NLS-1$ elemType = element.getAttributeValue("ref");//$NON-NLS-1$ String nsprefix = elemType.substring(0, elemType.indexOf(':')); String typename = elemType.substring(elemType.indexOf(':') + 1, elemType.length()); nstypename = typename; String testUri = getURIfromSchemaPrefix(element, nsprefix); if (elemType.indexOf(':') > -1) { if (!elemType.startsWith("xs:")) { //$NON-NLS-1$ isQualified = true; tns = testUri; tnsprefix = makePrefixFromURI(tns); } } XSDSchema importXSD = getSchemaForNamespace(testUri); if (importXSD != null) { DOMBuilder domBuilder = new DOMBuilder(); importXSD.updateElement(true); org.jdom.Element importXSDSchema = domBuilder.build(importXSD.getElement()); org.jdom.Element element2 = findJDOMTypeInSchema(importXSDSchema, elemType); if (element2 != null) { element = element2; } else { element2 = findJDOMElementInSchema(importXSDSchema, elemType); if (element2 != null) { element = element2; } else { element2 = findJDOMElementInSchemaByName(importXSDSchema, nstypename); if (element2 != null) { element = element2; } } } } } } boolean hasKids = false; if (elementHasChildren(element)) { hasKids = true; } boolean isSimpleType = false; if (elemType != null && isTypeBaseXSDOrSimple(tns, elemType)) { isSimpleType = true; } boolean hasEnums = false; if (element.getName().equals("simpleType")) { //$NON-NLS-1$ String enums = getEnumerations(element); if (enums != null && enums.trim().length() > 0) { hasEnums = true; } } boolean includeTNSInRoot = false; if (rootIsQualified_ && !isQualified) { includeTNSInRoot = true; isQualified = true; tnsprefix = "tns"; //$NON-NLS-1$ } else if (isQualified) { rootIsQualified_ = false; if (tnsprefix == null) { tnsprefix = "tns"; //$NON-NLS-1$ } } boolean isSequence = element.getName().equals("sequence"); //$NON-NLS-1$ if (!isSequence) { // open tag if (minOccurs.intValue() == 0) { buf.append("<!-- optional -->\n");//$NON-NLS-1$ } buf.append('<'); if (isQualified) { buf.append(tnsprefix + ':'); } buf.append(nstypename); String attributes = handleAttributes(element); if (attributes != null && attributes.trim().length() > 0) { buf.append(' '); buf.append(attributes); } if (isQualified) { // xmlns:ns1="http://schemas.xmlsoap.org/soap/http" if (includeTNSInRoot && !namespacePrefixListContainsURI(rootURI_)) { buf.append(" xmlns:tns=\"" + rootURI_ + "\""); //$NON-NLS-1$ //$NON-NLS-2$ namespacesAndPrefixes_.put(tnsprefix, rootURI_); } else if (!namespacesAndPrefixes_.containsKey(tnsprefix)) { buf.append(" xmlns:" + tnsprefix + "=\"" + tns + "\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ namespacesAndPrefixes_.put(tnsprefix, tns); } } if (hasKids || isSimpleType || hasEnums ) buf.append(">"); //$NON-NLS-1$ else buf.append("/>");//$NON-NLS-1$ } if (hasKids) { if (!isSequence) { buf.append('\n'); } List<?> kids = element.getChildren(); for (Iterator<?> kidIter = kids.iterator(); kidIter.hasNext(); ) { Element kid = (Element) kidIter.next(); if (kid.getName().equals("complexType") || kid.getName().equals("sequence") || //$NON-NLS-1$//$NON-NLS-2$ kid.getName().equals("simpleType") || kid.getName().equals("restriction")) { //$NON-NLS-1$ //$NON-NLS-2$ List<?> innerkids = kid.getChildren(); for (Iterator<?> kidIter2 = innerkids.iterator(); kidIter2.hasNext(); ) { Element innerkid = (Element) kidIter2.next(); String out = createXMLForJDOMElement2 ( schemaElement, innerkid ); buf.append(out); } } else if (kid.getName().equals("element")) {//$NON-NLS-1$ String out = createXMLForJDOMElement2 (schemaElement, kid); buf.append(out); } } } if (!isSequence && ( hasKids || isSimpleType || hasEnums )) { // add ? for value if (!hasKids || isSimpleType || hasEnums ) buf.append('?'); // close tag buf.append("</");//$NON-NLS-1$ if (isQualified) { buf.append(tnsprefix + ':'); } buf.append(nstypename); buf.append(">\n"); //$NON-NLS-1$ } return buf.toString(); } private static String getEnumerations ( org.jdom.Element element ) { StringBuffer buf = new StringBuffer(); List<?> kids = element.getChildren(); for (Iterator<?> kidIter = kids.iterator(); kidIter.hasNext(); ) { Element kid = (Element) kidIter.next(); if (kid.getChildren() != null && kid.getChildren().size() > 0) { buf.append(getEnumerations(kid)); } if (kid.getName().equals("enumeration")) { //$NON-NLS-1$ String value = kid.getAttributeValue("value"); //$NON-NLS-1$ buf.append(value + '|'); } } return buf.toString(); } private static HashMap<String, String> getDefinitionNamespaces ( Definition wsdlDefinition) { HashMap<String, String> namespaceMap = new HashMap<String, String>(); namespaceMap.put(SOAP_NS_URI, SOAP_PREFIX); namespaceMap.put(SOAP12_ENVELOPE_NS_URI, SOAP12_PREFIX); namespaceMap.put("http://www.w3.org/2001/XMLSchema-instance", "xsi"); //$NON-NLS-1$//$NON-NLS-2$ namespaceMap.put("http://www.w3.org/2001/XMLSchema", "xsd"); //$NON-NLS-1$//$NON-NLS-2$ Map<?,?> namespaces = wsdlDefinition.getNamespaces(); Set<?> namespaceKeys = namespaces.keySet(); int i = 1; for ( Iterator<?> it = namespaceKeys.iterator(); it.hasNext(); ) { String prefix = (String) it.next(); String url = wsdlDefinition.getNamespace(prefix); if (!namespaceMap.containsKey(url)) { String newprefix = "ns" + i++; //$NON-NLS-1$ namespaceMap.put(url, newprefix); } } return namespaceMap; } private static String getNSURI ( String inPrefix, Definition wsdlDefinition) { HashMap<String, String> map = getDefinitionNamespaces(wsdlDefinition); if (map.containsValue(inPrefix)) { for (Iterator<Entry<String, String>> mapIter = map.entrySet().iterator(); mapIter.hasNext(); ) { Map.Entry<String, String> test = (Entry<String, String>) mapIter.next(); if (test.getValue().equals(inPrefix)) return test.getKey(); } } return null; } private static String getURIfromSchemaPrefix(Element el, String prefix) { Element e = el; while (e.getParentElement() != null) { e = e.getParentElement(); } if (e.getNamespace(prefix) != null) { return e.getNamespace(prefix).getURI(); } return null; } private static boolean isTypeBaseXSDOrSimple ( String uri, String type ) { if (uri != null) { XSDSchema schema = getSchemaForNamespace(uri); DOMBuilder domBuilder = new DOMBuilder(); schema.updateElement(true); org.jdom.Element importXSDSchema = domBuilder.build(schema.getElement()); if (type != null && type.indexOf(':') > -1) { String typename = type.substring(type.indexOf(':') + 1, type.length()); org.jdom.Element element = findJDOMTypeInSchemaByNameAttr(importXSDSchema, typename); if (element != null) { if (element.getAttribute("type") != null) { //$NON-NLS-1$ type = element.getAttributeValue("type"); //$NON-NLS-1$ } } } } // typically the type starts with a namespace prefix, so // we want to compare the end of the string with the actual // type name if (type != null && type.endsWith(STRING_TYPE_NAME) || type.endsWith(BOOLEAN_TYPE_NAME) || type.endsWith(DECIMAL_TYPE_NAME) || type.endsWith(INT_TYPE_NAME) || type.endsWith(DOUBLE_TYPE_NAME) || type.endsWith(FLOAT_TYPE_NAME) || type.endsWith(DURATION_TYPE_NAME) || type.endsWith(DATE_TYPE_NAME) || type.endsWith(TIME_TYPE_NAME) || type.endsWith(DATETIME_TYPE_NAME) || type.endsWith(ANYURI_TYPE_NAME) || type.endsWith(BASE64BINARY_TYPE_NAME) || type.endsWith(GDAY_TYPE_NAME) || type.endsWith(GMONTH_TYPE_NAME) || type.endsWith(GMONTHDAY_TYPE_NAME) || type.endsWith(GYEAR_TYPE_NAME) || type.endsWith(GYEARMONTH_TYPE_NAME) || type.endsWith(HEXBINARY_TYPE_NAME) || type.endsWith(NOTATION_TYPE_NAME) || type.endsWith(PRECISION_DECIMAL_TYPE_NAME) ) { return true; } else if (type != null && type.contains(SIMPLE_TYPE_NAME)) { return true; } return false; } }