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);