in modules/binding-ws-wsdlgen/src/main/java/org/apache/tuscany/sca/binding/ws/wsdlgen/Interface2WSDLGenerator.java [328:557]
public Definition generate(Interface interfaze, WSDLDefinition wsdlDefinition) throws WSDLException {
if (interfaze == null) {
return null;
}
if (interfaze instanceof WSDLInterface) {
return ((WSDLInterface)interfaze).getWsdlDefinition().getDefinition();
}
JavaInterface iface = (JavaInterface)interfaze;
if (!interfaze.isRemotable()) {
fatal("InterfaceNotRemotable", interfaze, iface.getName());
}
QName name = getQName(iface);
Definition definition = factory.newDefinition();
if (requiresSOAP12) {
definition.addNamespace("SOAP12", "http://schemas.xmlsoap.org/wsdl/soap12/");
} else {
definition.addNamespace("SOAP", "http://schemas.xmlsoap.org/wsdl/soap/");
}
definition.addNamespace("wsdl", "http://schemas.xmlsoap.org/wsdl/");
definition.addNamespace("xs", SCHEMA_NS);
String namespaceURI = name.getNamespaceURI();
definition.setTargetNamespace(namespaceURI);
definition.setQName(new QName(namespaceURI, name.getLocalPart() + "Service", name.getPrefix()));
definition.addNamespace(name.getPrefix(), namespaceURI);
PortType portType = definition.createPortType();
portType.setQName(name);
Binding binding = definitionGenerator.createBinding(definition, portType);
Map<String, XMLTypeHelper> helpers = new HashMap<String, XMLTypeHelper>();
Map<QName, List<ElementInfo>> wrappers = new HashMap<QName, List<ElementInfo>>();
for (Operation op : interfaze.getOperations()) {
javax.wsdl.Operation operation = generateOperation(definition, op, helpers, wrappers);
portType.addOperation(operation);
String action = ((JavaOperation)op).getAction();
// Removed improper defaulting of SOAP action when using doc/lit BARE.
// The correct default is "" (empty string).
if (action == null) {
action = "";
}
BindingOperation bindingOp = definitionGenerator.createBindingOperation(definition, operation, action);
binding.addBindingOperation(bindingOp);
}
portType.setUndefined(false);
definition.addPortType(portType);
binding.setUndefined(false);
definition.addBinding(binding);
wsdlDefinition.setBinding(binding);
// call each helper in turn to populate the wsdl.types element
XmlSchemaCollection schemaCollection = new XmlSchemaCollection();
// TUSCANY-3283 - "true" here means also generate the wrapper types using JAXB
Map<XMLTypeHelper, List<DataType>> dataTypes = getDataTypes(interfaze, true, helpers);
for (Map.Entry<XMLTypeHelper, List<DataType>> en: dataTypes.entrySet()) {
XMLTypeHelper helper = en.getKey();
if (helper == null) {
continue;
}
List<XSDefinition> xsDefinitions = helper.getSchemaDefinitions(xsdFactory, resolver, en.getValue());
// TUSCANY-3283 - move the nonamespace types into the namespace of the interface
// as per JAXWS
mergeNoNamespaceSchema(namespaceURI, xsDefinitions);
for (XSDefinition xsDef: xsDefinitions) {
//addSchemaExtension(xsDef, schemaCollection, wsdlDefinition, definition);
loadXSD(schemaCollection, xsDef);
wsdlDefinition.getXmlSchemas().add(xsDef);
}
}
// remove global wrapper elements with schema definitions from generation list
for (QName wrapperName: new HashSet<QName>(wrappers.keySet())) {
if (wsdlDefinition.getXmlSchemaElement(wrapperName) != null) {
wrappers.remove(wrapperName);
}
}
// below we might generate wrapper schema into a DOM. If the schema are in a namespace
// that is already been loaded then we need to throw away the schema collection and reload
// it because you can't load a DOM into a schema collection if the schema for the namespace
// has already been loaded
boolean reloadSchema = false;
// generate schema elements for wrappers that aren't defined in the schemas
// TUSCANY-3283 - as we're generating wrappers with JAXB it won't
// go through here for all wrappers. It will just have to do the ones
// where there is no JAXB mapping for the child types, e.g. SDO DataObject
if (wrappers.size() > 0) {
int i = 0;
int index = 0;
Map<String, XSDefinition> wrapperXSDs = new HashMap<String, XSDefinition>();
Map<Element, Map<String, String>> prefixMaps = new HashMap<Element, Map<String, String>>();
for (Map.Entry<QName, List<ElementInfo>> entry: wrappers.entrySet()) {
String targetNS = entry.getKey().getNamespaceURI();
Document schemaDoc = null;
Element schema = null;
XSDefinition xsDef = wrapperXSDs.get(targetNS);
if (xsDef != null) {
schemaDoc = xsDef.getDocument();
schema = schemaDoc.getDocumentElement();
} else {
// TUSCANY-3283 - if we have to generate a new schema check to see if the
// WSDL doc already has a schema in this namespace
xsDef = wsdlDefinition.getSchema(targetNS);
if (xsDef != null) {
schemaDoc = xsDef.getDocument();
schema = schemaDoc.getDocumentElement();
//wrapperXSDs.put(targetNS, xsDef);
Map<String, String> prefixMap = prefixMaps.get(schema);
if (prefixMap == null){
prefixMap = new HashMap<String, String>();
prefixMaps.put(schema, prefixMap);
String [] prefixes = xsDef.getSchema().getNamespaceContext().getDeclaredPrefixes();
for (int j = 0; j < prefixes.length; j++){
prefixMap.put(xsDef.getSchema().getNamespaceContext().getNamespaceURI(prefixes[j]),
prefixes[j]);
}
}
reloadSchema = true;
} else {
schemaDoc = createDocument();
schema = schemaDoc.createElementNS(SCHEMA_NS, "xs:schema");
// The elementFormDefault should be set to unqualified, see TUSCANY-2388
schema.setAttribute("elementFormDefault", "unqualified");
schema.setAttribute("attributeFormDefault", "qualified");
schema.setAttribute("targetNamespace", targetNS);
schema.setAttributeNS(XMLNS_NS, "xmlns:xs", SCHEMA_NS);
schemaDoc.appendChild(schema);
// TUSCANY-3283 - the extension is created at the bottom
//Schema schemaExt = createSchemaExt(definition);
//schemaExt.setElement(schema);
prefixMaps.put(schema, new HashMap<String, String>());
xsDef = xsdFactory.createXSDefinition();
xsDef.setUnresolved(true);
xsDef.setNamespace(targetNS);
xsDef.setDocument(schemaDoc);
// TUSCANY-2465: Set the system id to avoid schema conflict
xsDef.setLocation(URI.create("xsd_" + index + ".xsd"));
index++;
wrapperXSDs.put(targetNS, xsDef);
wsdlDefinition.getXmlSchemas().add(xsDef);
}
}
Element wrapper = schemaDoc.createElementNS(SCHEMA_NS, "xs:element");
schema.appendChild(wrapper);
wrapper.setAttribute("name", entry.getKey().getLocalPart());
if (entry.getValue().size() == 1 && entry.getValue().get(0).getQName() == null) {
// special case for global fault element
QName typeName = entry.getValue().get(0).getType().getQName();
String nsURI = typeName.getNamespaceURI();
if ("".equals(nsURI)) {
wrapper.setAttribute("type", typeName.getLocalPart());
addSchemaImport(schema, "", schemaDoc);
} else if (targetNS.equals(nsURI)) {
wrapper.setAttribute("type", typeName.getLocalPart());
} else if (SCHEMA_NS.equals(nsURI)) {
wrapper.setAttribute("type", "xs:" + typeName.getLocalPart());
} else {
Map<String, String> prefixMap = prefixMaps.get(schema);
String prefix = prefixMap.get(nsURI);
if (prefix == null) {
prefix = "ns" + i++;
prefixMap.put(nsURI, prefix);
schema.setAttributeNS(XMLNS_NS, "xmlns:" + prefix, nsURI);
addSchemaImport(schema, nsURI, schemaDoc);
}
wrapper.setAttribute("type", prefix + ":" + typeName.getLocalPart());
}
} else {
// normal wrapper containing type definition inline
Element complexType = schemaDoc.createElementNS(SCHEMA_NS, "xs:complexType");
wrapper.appendChild(complexType);
if (entry.getValue().size() > 0) {
Element sequence = schemaDoc.createElementNS(SCHEMA_NS, "xs:sequence");
complexType.appendChild(sequence);
for (ElementInfo element: entry.getValue()) {
Element xsElement = schemaDoc.createElementNS(SCHEMA_NS, "xs:element");
if (element.isMany()) {
xsElement.setAttribute("maxOccurs", "unbounded");
}
xsElement.setAttribute("minOccurs", "0");
xsElement.setAttribute("name", element.getQName().getLocalPart());
if (element.isNillable()) {
xsElement.setAttribute("nillable", "true");
}
QName typeName = element.getType().getQName();
String nsURI = typeName.getNamespaceURI();
if ("".equals(nsURI)) {
xsElement.setAttribute("type", typeName.getLocalPart());
addSchemaImport(schema, "", schemaDoc);
} else if (SCHEMA_NS.equals(nsURI)) {
xsElement.setAttribute("type", "xs:" + typeName.getLocalPart());
} else {
Map<String, String> prefixMap = prefixMaps.get(schema);
String prefix = prefixMap.get(nsURI);
if (prefix == null) {
if (targetNS.equals(nsURI)) {
prefix = "tns";
} else {
prefix = "ns" + i++;
addSchemaImport(schema, nsURI, schemaDoc);
}
prefixMap.put(nsURI, prefix);
schema.setAttributeNS(XMLNS_NS, "xmlns:" + prefix, nsURI);
}
xsElement.setAttribute("type", prefix + ":" + typeName.getLocalPart());
}
sequence.appendChild(xsElement);
}
}
}
}
}
if (reloadSchema){
schemaCollection = new XmlSchemaCollection();
for (XSDefinition xsDef: wsdlDefinition.getXmlSchemas()){
xsDef.setSchema(null);
xsDef.setSchemaCollection(null);
}
}
for (XSDefinition xsDef: wsdlDefinition.getXmlSchemas()){
addSchemaExtension(xsDef, schemaCollection, wsdlDefinition, definition);
}
return definition;
}