package com.xmlit.project.engine.xsd;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.events.Namespace;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
import com.xmlit.project.engine.Utils;
import com.xmlit.project.engine.struct.Struct;
import com.xmlit.project.engine.struct.StructChoice;
import com.xmlit.project.engine.struct.StructSequence;
import com.xmlit.project.engine.struct.StructSimple;
import com.xmlit.project.engine.struct.impl.CalcContext;
import com.xmlit.project.engine.struct.impl.StructImpl;
import com.xmlit.project.engine.struct.impl.StructSequenceImpl;
import com.xmlit.project.engine.struct.impl.StructSimpleImpl;
public class Struct2XSD {
public static final String xsdNamespace = "http://www.w3.org/2001/XMLSchema";
static DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
static DocumentBuilder db = null;// dbf.newDocumentBuilder();
static {
try {
db = dbf.newDocumentBuilder();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static String struct2XSD(Struct struct) {
Document doc = db.newDocument();
Element root = doc.createElementNS(xsdNamespace, "schema");
doc.appendChild(root);
// root.setAttribute("xmlns", "http://www.w3.org/2001/XMLSchema");
root.setAttribute("targetNamespace", "http://www.xml-it.com/xsd");
root.setAttribute("xmlns:tns", "http://www.xml-it.com/xsd");
root.setAttribute("elementFormDefault", "qualified");
doStruct2XSD(root, doc, struct);
return Utils.dom2String(doc);
}
private static void doStruct2XSD(Element root, Document doc, Struct struct) {
Element current = doc.createElementNS(xsdNamespace, "element");
current.setAttribute("name", struct.getName());
String delimiter = null;
String lookahead = null;
boolean not = false;
String prefix = struct.getPrefix();
String suffix = struct.getSuffix();
String allowedChars = null;
int maxLength = -1;
int minLength = -1;
if (struct instanceof StructSequence) {
delimiter = ((StructSequence) struct).getDelimiter();
lookahead = ((StructSequence) struct).getLookahead();
not = ((StructSequence) struct).isNegative();
} else if (struct instanceof StructSimple) {
allowedChars = ((StructSimple) struct).getAllowedChars();
maxLength = ((StructSimple) struct).getMaxLength();
minLength = ((StructSimple) struct).getMinLength();
}
handleAnnotation(doc, current, delimiter, prefix, suffix, lookahead,
not, allowedChars, maxLength, minLength);
if (1 != struct.getMinOccurrences())
current.setAttribute("minOccurs", "" + struct.getMinOccurrences());
if (1 != struct.getMaxOccurrences())
current.setAttribute("maxOccurs", "" + struct.getMaxOccurrences());
root.appendChild(current);
if (struct instanceof StructSimple) {
String regex = ((StructSimple) struct).getSimplePattern();
String allowedVals = ((StructSimple) struct).getAllowedValues();
Element restriction = (Element) current.appendChild(
doc.createElementNS(xsdNamespace, "simpleType"))
.appendChild(
doc.createElementNS(xsdNamespace, "restriction"));
restriction.setAttribute("base", "string");
if (regex != null) {
Element pattern = (Element) restriction.appendChild(doc
.createElementNS(xsdNamespace, "pattern"));
pattern.setAttribute("value", regex);
} else if (allowedVals != null) {
for (String val : allowedVals.split("\n")) {
Element pattern = (Element) restriction.appendChild(doc
.createElementNS(xsdNamespace, "enumeration"));
pattern.setAttribute("value", val.trim());
}
}
} else {
String type = (struct instanceof StructChoice) ? "choice"
: "sequence";
Element typeElement = (Element) current.appendChild(
doc.createElementNS(xsdNamespace, "complexType"))
.appendChild(doc.createElementNS(xsdNamespace, type));
if (struct.getChildren() != null)
for (Struct child : struct.getChildren()) {
doStruct2XSD(typeElement, doc, child);
}
else {
Element any = doc.createElementNS(xsdNamespace, "any");
any.setAttribute("minOccurs", "0");
typeElement.appendChild(any);
}
}
}
private static void handleAnnotation(Document doc, Element current,
String delimiter, String prefix, String suffix, String lookahead,
boolean not, String allowedChars, int maxLength, int minLength) {
if (delimiter != null || prefix != null || suffix != null
|| lookahead != null || allowedChars != null) {
Element xmlitdata = (Element) current
.appendChild(
doc.createElementNS(xsdNamespace, "annotation"))
.appendChild(doc.createElementNS(xsdNamespace, "appinfo"))
.appendChild(doc.createElement("tns:xmlitdata"));
if (delimiter != null)
xmlitdata.setAttribute("delimiter", delimiter);
if (prefix != null)
xmlitdata.setAttribute("prefix", prefix);
if (suffix != null)
xmlitdata.setAttribute("suffix", suffix);
if (lookahead != null)
xmlitdata.setAttribute("lookahead", lookahead);
if (not)
xmlitdata.setAttribute("not", "" + not);
if (allowedChars != null)
xmlitdata.setAttribute("allowedChars", allowedChars);
if (maxLength != -1)
xmlitdata.setAttribute("maxLength", maxLength + "");
if (minLength != -1)
xmlitdata.setAttribute("minLength", minLength + "");
}
}
public static void main(String[] args) throws SAXException,
ParserConfigurationException, Exception {
StructSequenceImpl root = new StructSequenceImpl("root");
root.addChild(((StructSimple) new StructSimpleImpl("NewElement"))
.setSimplePattern("/"));
System.out.println(Struct2XSD.struct2XSD(XSD2Struct
.xsd2Struct(Struct2XSD.struct2XSD(root))));
}
}