
org.ow2.easywsdl.tooling.xsd2xml.XSD2XMLImpl Maven / Gradle / Ivy
The newest version!
/**
* Copyright (c) 2008-2012 EBM WebSourcing, 2012-2018 Linagora
*
* This program/library is free software: you can redistribute it and/or modify
* it under the terms of the New BSD License (3-clause license).
*
* This program/library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the New BSD License (3-clause license)
* for more details.
*
* You should have received a copy of the New BSD License (3-clause license)
* along with this program/library; If not, see http://directory.fsf.org/wiki/License:BSD_3Clause/
* for the New BSD License (3-clause license).
*/
package org.ow2.easywsdl.tooling.xsd2xml;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jdom.Attribute;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.ow2.easywsdl.schema.api.ComplexType;
import org.ow2.easywsdl.schema.api.SchemaException;
import org.ow2.easywsdl.schema.api.SimpleType;
import org.ow2.easywsdl.schema.api.Type;
import org.ow2.easywsdl.schema.api.absItf.AbsItfAttribute;
import org.ow2.easywsdl.schema.api.absItf.AbsItfAttribute.Use;
import org.ow2.easywsdl.schema.api.absItf.AbsItfComplexType;
import org.ow2.easywsdl.schema.api.absItf.AbsItfElement;
import org.ow2.easywsdl.schema.api.absItf.AbsItfSchema;
import org.ow2.easywsdl.schema.api.absItf.AbsItfType;
import org.ow2.easywsdl.schema.api.abstractElmt.AbstractAttributeImpl;
import org.ow2.easywsdl.schema.api.abstractElmt.AbstractElementImpl;
import org.ow2.easywsdl.schema.api.abstractElmt.AbstractSchemaElementImpl;
import org.ow2.easywsdl.schema.org.w3._2001.xmlschema.FormChoice;
/**
* @author Nicolas Salatge - EBM WebSourcing
* @author Vincent Zurczak - Linagora
*/
public class XSD2XMLImpl extends XSD2XML {
// FIXME VZ: final static are in upper case!
private final Namespace xsi = Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
private final static Map TYPED_DEFAULT_VALUES = new HashMap ();
private final static Map TYPED_SHORTEN_DEFAULT_VALUES = new HashMap ();
static {
TYPED_DEFAULT_VALUES.put( "Any Simple Type", "" );
TYPED_DEFAULT_VALUES.put( "Any URI", "http://google.fr" );
TYPED_DEFAULT_VALUES.put( "Base64 Binary", "" );
TYPED_DEFAULT_VALUES.put( "Boolean", "true" );
TYPED_DEFAULT_VALUES.put( "Byte", "" );
TYPED_DEFAULT_VALUES.put( "Date", "2002-10-10-05:00" );
TYPED_DEFAULT_VALUES.put( "Date Time", "2002-10-10T17:00:00Z" );
TYPED_DEFAULT_VALUES.put( "Decimal", "12.54" );
TYPED_DEFAULT_VALUES.put( "Double", "12.78e-2" );
TYPED_DEFAULT_VALUES.put( "Duration", "P1Y2MT2H" );
TYPED_DEFAULT_VALUES.put( "Float", "12.54E12" );
TYPED_DEFAULT_VALUES.put( "gDay", "---21" );
TYPED_DEFAULT_VALUES.put( "gMonth", "--11" );
TYPED_DEFAULT_VALUES.put( "gMonthDay", "--05-01" );
TYPED_DEFAULT_VALUES.put( "gYear", "1999" );
TYPED_DEFAULT_VALUES.put( "gYearMonth", "1999-05" );
TYPED_DEFAULT_VALUES.put( "HexBinary", "FF" );
TYPED_DEFAULT_VALUES.put( "Int", "5" );
TYPED_DEFAULT_VALUES.put( "Integer", "5" );
TYPED_DEFAULT_VALUES.put( "Language", "fr-FR" );
TYPED_DEFAULT_VALUES.put( "Long", "5" );
TYPED_DEFAULT_VALUES.put( "Name", "" );
TYPED_DEFAULT_VALUES.put( "NCName", "" );
TYPED_DEFAULT_VALUES.put( "Negative Integer", "-1" );
TYPED_DEFAULT_VALUES.put( "Non Negative Integer", "1" );
TYPED_DEFAULT_VALUES.put( "Non Positive Integer", "-1" );
TYPED_DEFAULT_VALUES.put( "Normalized String", "" );
TYPED_DEFAULT_VALUES.put( "Positive Integer", "1" );
TYPED_DEFAULT_VALUES.put( "QName", "" );
TYPED_DEFAULT_VALUES.put( "Short", "5" );
TYPED_DEFAULT_VALUES.put( "String", "" );
TYPED_DEFAULT_VALUES.put( "Time", "13:20:00-05:00" );
TYPED_DEFAULT_VALUES.put( "Token", "" );
TYPED_DEFAULT_VALUES.put( "Unsigned Byte", "255" );
TYPED_DEFAULT_VALUES.put( "Unsigned Int", "255" );
TYPED_DEFAULT_VALUES.put( "Unsigned Long", "255" );
TYPED_DEFAULT_VALUES.put( "Unsigned Short", "255" );
for( String key : TYPED_DEFAULT_VALUES.keySet()) {
String newKey = key.toLowerCase().replace( " ", "" );
TYPED_SHORTEN_DEFAULT_VALUES.put( newKey, key );
}
}
@Override
public Element generateElement(AbsItfElement eIn, Object value) throws SchemaException {
Element res = null;
if(eIn != null) {
Map values = null;
if(value == null) {
values = XSD2XML.createDefaultMap("");
} else {
values = XSD2XML.createDefaultMap(value);
}
res = this.generateElement(eIn, values, ((AbstractElementImpl) eIn).getSchema().getElementFormDefault(), 1, false, false);
}
return res;
}
@Override
public Element generateElement(AbsItfElement eIn, Map values, FormChoice form, int minOccurs, boolean createOptionalElement, boolean createOptionalAttribute)
throws SchemaException {
if(values == null) {
values = this.createDefaultMap("");
}
// create element
org.jdom.Element eOut = null;
if(minOccurs > 0) {
Namespace ns = org.jdom.Namespace.getNamespace(eIn.getQName().getPrefix(),
eIn.getQName().getNamespaceURI());
if (((AbstractSchemaElementImpl) eIn).getParent() instanceof AbsItfSchema) {
// top level element
eOut = new org.jdom.Element(eIn.getQName().getLocalPart(), eIn.getQName().getPrefix(), eIn.getQName().getNamespaceURI());
} else {
eOut = new org.jdom.Element(eIn.getQName().getLocalPart());
}
if(form == FormChoice.QUALIFIED) {
eOut.setNamespace(org.jdom.Namespace.getNamespace(eIn.getQName().getPrefix(),
eIn.getQName().getNamespaceURI()));
}
// Complex type => generate child elements
if (((AbstractElementImpl) eIn).getType() instanceof ComplexType) {
if ((((org.ow2.easywsdl.schema.impl.ComplexTypeImpl) ((AbstractElementImpl) eIn)
.getType()).getModel()) != null) {
List items = null;
if ((((org.ow2.easywsdl.schema.impl.ComplexTypeImpl) ((AbstractElementImpl) eIn)
.getType())).getSequence() != null) {
// if sequence
items = (((org.ow2.easywsdl.schema.impl.ComplexTypeImpl) ((AbstractElementImpl) eIn)
.getType())).getSequence().getElements();
} else if ((((org.ow2.easywsdl.schema.impl.ComplexTypeImpl) ((AbstractElementImpl) eIn)
.getType())).getAll() != null) {
// if all
items = (((org.ow2.easywsdl.schema.impl.ComplexTypeImpl) ((AbstractElementImpl) eIn)
.getType())).getAll().getElements();
} else if((((org.ow2.easywsdl.schema.impl.ComplexTypeImpl) ((AbstractElementImpl) eIn)
.getType())).getComplexContent() != null && (((org.ow2.easywsdl.schema.impl.ComplexTypeImpl) ((AbstractElementImpl) eIn)
.getType())).getComplexContent().getExtension() != null) {
// TODO: generate all inherited elements
items = getAllElementFindInAllInheritedParent((((org.ow2.easywsdl.schema.impl.ComplexTypeImpl) ((AbstractElementImpl) eIn)
.getType())).getComplexContent().getExtension().getBase());
// generate elements in extension
if((((org.ow2.easywsdl.schema.impl.ComplexTypeImpl) ((AbstractElementImpl) eIn)
.getType())).getComplexContent().getExtension().getSequence() != null) {
items.addAll((((org.ow2.easywsdl.schema.impl.ComplexTypeImpl) ((AbstractElementImpl) eIn)
.getType())).getComplexContent().getExtension().getSequence().getElements());
}
}
if (items != null) {
for (final org.ow2.easywsdl.schema.api.Element item : items) {
// is element
if (item.getRef() == null) {
// is an element
final AbsItfElement e = item;
FormChoice elmtFrom = null;
//System.out.println("e.getQName() = " + e.getQName());
//System.out.println("e.getForm() = " + e.getForm());
if(e.getForm() != null) {
elmtFrom = e.getForm();
} else {
elmtFrom = form;
}
int minOccursChildElmt = e.getMinOccurs();
if(createOptionalElement == true && minOccursChildElmt == 0) {
minOccursChildElmt = 1;
}
Element child = this.generateElement(e,
values, elmtFrom, minOccursChildElmt, createOptionalElement, createOptionalAttribute);
if(child != null) {
// Add a comment
if( e.getType() instanceof SimpleType ) {
final String comment = buildComment( e );
if( comment != null )
eOut.addContent( new org.jdom.Comment( comment ));
}
// Add the element
eOut.addContent(child.detach());
}
} else {
// is a ref on an element
final List listE = ((AbstractElementImpl) eIn).getParent().getSchema()
.findElementsInAllSchema(item.getRef());
if(listE != null && listE.size() > 0) {
AbsItfElement e = listE.get(0);
FormChoice elmtFrom = null;
if(e.getForm() != null) {
elmtFrom = e.getForm();
} else {
elmtFrom = form;
}
int minOccursChildElmt = e.getMinOccurs();
if(createOptionalElement == true && minOccursChildElmt == 0) {
minOccursChildElmt = 1;
}
Element child = this.generateElement(e,
values, elmtFrom, minOccursChildElmt, createOptionalElement, createOptionalAttribute);
if(child != null) {
// Add a comment
if( e.getType() instanceof SimpleType ) {
final String comment = buildComment( e );
if( comment != null )
eOut.addContent( new org.jdom.Comment( comment ));
}
// Add the element
eOut.addContent(child.detach());
}
} else {
throw new SchemaException("Impossible to find element corresponding to this reference: " + item.getRef());
}
}
}
// handle attribute
for (final AbsItfAttribute attr : ((ComplexType) ((AbstractElementImpl) eIn)
.getType()).getAttributes()) {
org.jdom.Attribute a = null;
if(Use.REQUIRED.equals(attr.getUse())) {
a = this.generateAttribute(
eIn, attr, values);
} else if(createOptionalAttribute == true){
a = this.generateAttribute(
eIn, attr, values);
}
if(a != null) {
eOut.setAttribute(a);
}
}
}
}
} else {
// add value on the simple type
final String val = findValue(eIn.getType(), values);
if( val != null && ! eIn.isNillable())
eOut.setText(val);
}
// add attribute to element
List attrs = generateAttributes(eIn, values, ((AbstractElementImpl) eIn).getSchema().getAttributeFormDefault(), createOptionalAttribute);
// add type attribute on element
Attribute typeAttr = null;
if (((AbstractElementImpl) eIn).getType() != null) {
String type = null;
// if not a anonymous type
if (((AbstractElementImpl) eIn).getType().getQName() != null) {
String prefix = ((AbstractElementImpl) eIn).getParent().getSchema().getAllNamespaces().getPrefix(
((AbstractElementImpl) eIn).getType().getQName().getNamespaceURI());
if (prefix != null) {
type = prefix
+ ":"
+ ((AbstractElementImpl) eIn).getType().getQName().getLocalPart();
Namespace typeNs = Namespace.getNamespace(prefix, ((AbstractElementImpl) eIn).getParent().getSchema().getAllNamespaces().getNamespaceURI(prefix));
eOut.addNamespaceDeclaration(typeNs);
eOut.addNamespaceDeclaration(this.xsi);
typeAttr = new Attribute("type", type, this.xsi);
} else {
type = ((AbstractElementImpl) eIn).getType().getQName().getLocalPart();
eOut.addNamespaceDeclaration(this.xsi);
typeAttr = new Attribute("type", type, this.xsi);
}
}
}
if(typeAttr != null) {
attrs.add(typeAttr);
}
eOut.setAttributes(attrs);
//Document doc = new Document(eOut);
}
return eOut;
}
private List getAllElementFindInAllInheritedParent(
Type base) {
List res = new ArrayList();
if(base instanceof ComplexType) {
ComplexType ct = (ComplexType)base;
if(ct.getAll() != null) {
res.addAll(ct.getAll().getElements());
} else if(ct.getSequence() != null) {
res.addAll(ct.getSequence().getElements());
} else if(ct.getComplexContent() != null && ct.getComplexContent().getExtension() != null) {
res.addAll(getAllElementFindInAllInheritedParent(ct.getComplexContent().getExtension().getBase()));
}
}
return res;
}
private List generateAttributes(AbsItfElement eIn, Map values,
FormChoice attributeFormDefault, boolean createOptionalAttribute) {
List res = new ArrayList();
if(eIn.getType() instanceof ComplexType) {
ComplexType ct = (ComplexType) eIn.getType();
for(org.ow2.easywsdl.schema.api.Attribute attr: ct.getAttributes()) {
if(Use.REQUIRED.equals(attr.getUse()) || createOptionalAttribute==true) {
Attribute a = null;
String prefix = ((AbstractElementImpl) eIn).getSchema().getAllNamespaces().getPrefix(attr.getNamespaceUri());
if((prefix != null)&& !(attr.getNamespaceUri().equals(eIn.getQName().getNamespaceURI())) && (attributeFormDefault == FormChoice.QUALIFIED)) {
a = new Attribute(attr.getName(),findValue(attr.getType(), values), Namespace.getNamespace(prefix, attr.getNamespaceUri()));
} else {
a = new Attribute(attr.getName(),findValue(attr.getType(), values));
}
res.add(a);
}
}
}
return res;
}
/**
* Finds the default value for a simple type.
* @param key the element's type
* @param values a map of default values
* @return a string value representing the element value
*/
private String findValue( AbsItfType key, final Map values ) {
String res = null;
if( values.get(key) != null )
res = values.get( key ).toString();
if( res == null || res.trim().length() == 0 ) {
String type = key.toString().toLowerCase();
type = type.startsWith( "{http://www.w3.org/2001/xmlschema}" ) ? type.substring( 34 ) : null;
if( type == null ) {
if( key instanceof SimpleType ) {
SimpleType st = (SimpleType) key;
if( st.getRestriction() != null
&& st.getRestriction().getEnumerations() != null
&& ! st.getRestriction().getEnumerations().isEmpty())
res = st.getRestriction().getEnumerations().get( 0 ).getValue();
}
} else {
String typeName = TYPED_SHORTEN_DEFAULT_VALUES.get( type );
res = typeName == null ? "" : TYPED_DEFAULT_VALUES.get( typeName );
}
}
return res;
}
/**
* Builds a comment to display above a XML element.
* @param element an interface element whose type is a Simple Type
* @return a string value to use as a XML comment (not null)
*/
private String buildComment( AbsItfElement> element ) {
// The XML type first
AbsItfType key = element.getType();
String type = key.toString().toLowerCase();
type = type.startsWith( "{http://www.w3.org/2001/xmlschema}" ) ? type.substring( 34 ) : null;
String res;
if( type == null ) {
res = "Unknown";
if( key instanceof SimpleType
&& ((SimpleType) key).getRestriction() != null
&& ((SimpleType) key).getRestriction().getEnumerations() != null)
res = "Enumeration";
} else {
String typeName = TYPED_SHORTEN_DEFAULT_VALUES.get( type );
res = typeName == null ? "Unknown Type" : typeName;
}
// Other information
StringBuilder sb = new StringBuilder( res );
sb.append( ", card: [ " );
sb.append( element.getMinOccurs());
sb.append( ", " );
sb.append( element.getMaxOccurs());
sb.append( " ]" );
if( element.isNillable())
sb.append( ", Nillable (xsi:nil=\"true\") " );
else
sb.append( " " );
// Format it
sb.insert( 0, " " );
return sb.toString();
}
public org.jdom.Attribute generateAttribute(final AbsItfElement eIn, final AbsItfAttribute aIn, final Map value) {
org.jdom.Attribute attr = null;
if (aIn.getName() != null) {
String prefix = null;
org.jdom.Namespace ns = null;
if (!aIn.getNamespaceUri().equals(eIn.getQName().getNamespaceURI())) {
if (((AbstractElementImpl) eIn).getParent().getSchema().getAllNamespaces().getPrefix(
aIn.getNamespaceUri()) != null) {
prefix = ((AbstractElementImpl) eIn).getParent().getSchema().getAllNamespaces().getPrefix(
aIn.getNamespaceUri());
ns = org.jdom.Namespace.getNamespace(prefix, aIn.getNamespaceUri());
}
}
if(((AbstractAttributeImpl)aIn).getSchema().getAttributeFormDefault() == FormChoice.QUALIFIED) {
attr = new org.jdom.Attribute(aIn.getName(), findValue(aIn.getType(), value), ns);
} else {
attr = new org.jdom.Attribute(aIn.getName(), findValue(aIn.getType(), value), null);
}
}
return attr;
}
@Override
public String printXml(AbsItfElement e, Object value)
throws SchemaException {
final org.jdom.Element eOut = this.generateElement(e, value);
return new XMLOutputter(Format.getPrettyFormat()).outputString(eOut);
}
/*
* (non-Javadoc)
* @see org.ow2.easywsdl.tooling.xsd2xml.XSD2XML
* #printXml(org.jdom.Element, org.jdom.output.Format)
*/
@Override
public String printXml( org.jdom.Element element, Format formatter ) {
// Remove duplicate name space declarations
Map prefixToUri = new HashMap ();
for( Object o : element.getAdditionalNamespaces()) {
if( o instanceof Namespace )
prefixToUri.put(((Namespace) o).getPrefix(), ((Namespace) o).getURI());
}
List toProcess = new ArrayList ();
toProcess.add( element );
while( ! toProcess.isEmpty()) {
org.jdom.Element current = toProcess.remove( 0 );
for( Object o : current.getChildren()) {
if( !( o instanceof org.jdom.Element ))
continue;
org.jdom.Element child = (org.jdom.Element) o;
toProcess.add( child );
// Organize name space declarations by checking descendants
List toRemove = new ArrayList ();
for( Object oo : child.getAdditionalNamespaces()) {
if( !( oo instanceof Namespace ))
continue;
Namespace ns = (Namespace) oo;
if( ns.getURI() == null )
toRemove.add( ns );
else {
String currentUri = prefixToUri.get( ns.getPrefix());
// The namespace was not declared: move it to the top element
if( currentUri == null ) {
element.addNamespaceDeclaration( ns );
toRemove.add( ns );
}
// Already declared, no need to add it again
else if( ns.getURI().equals( currentUri ))
toRemove.add( ns );
}
}
for( Namespace ns : toRemove )
child.removeNamespaceDeclaration( ns );
}
}
// Write it down
String result = new XMLOutputter( formatter ).outputString( element );
return result;
}
/*
* (non-Javadoc)
* @see org.ow2.easywsdl.tooling.xsd2xml.XSD2XML
* #printXml(org.jdom.Element)
*/
@Override
public String printXml( org.jdom.Element element ) {
Format formatter = Format.getPrettyFormat().setIndent( "\t" ).setExpandEmptyElements( true ).setEncoding( "UTF-8" );
return printXml( element, formatter );
}
@Override
public Element addMinOccursEqual0OrArrayElement(AbsItfElement childDefinition,
Element parentElement) throws SchemaException {
// verif if child is nillable or an array element
String maxOccurs = childDefinition.getMaxOccurs();
int maxOcc = -1;
if(maxOccurs == null) {
maxOcc = 1;
} else if(maxOccurs.toUpperCase().equals("UNBOUNDED")) {
maxOcc = 10;
} else {
maxOcc = Integer.parseInt(maxOccurs);
}
// System.out.println("childDefinition.getQName() = " + childDefinition.getQName());
// System.out.println("maxOcc = " + maxOcc);
// System.out.println("childDefinition.getMinOccurs() = " + childDefinition.getMinOccurs());
Element child = null;
if(childDefinition.getMinOccurs() == 0 || maxOcc > 1) {
child = generateElement(childDefinition, this.createDefaultMap(""), ((AbstractElementImpl) childDefinition).getSchema().getElementFormDefault(), 1, false, true);
// System.out.println("MY CHILD: \n" + new XMLOutputter(Format.getPrettyFormat()).outputString(child));
// find parent complex type definition
ComplexType parentType = this.findParentType((AbstractSchemaElementImpl) childDefinition);
if(parentType.getSequence() != null) {
addChildInGoodPlace(childDefinition, parentElement, child,
parentType);
} else if(parentType.getAll() != null) {
addChildInGoodPlace(childDefinition, parentElement, child,
parentType);
} else {
parentElement.addContent(child.detach());
}
} else {
throw new SchemaException("this element (" + childDefinition.getQName() + ") is not an array or not minOccurs = 0");
}
return child;
}
private void addChildInGoodPlace(AbsItfElement childDefinition,
Element parentElement, Element child, ComplexType parentType) {
int index = 0;
Element elmtInP = null;
for(org.ow2.easywsdl.schema.api.Element elmt: parentType.getSequence().getElements()) {
if(elmt.getQName().equals(childDefinition.getQName())) {
List arrayElmts = parentElement.getChildren(childDefinition.getQName().getLocalPart());
if(arrayElmts == null || arrayElmts.size() == 0) {
arrayElmts = parentElement.getChildren(childDefinition.getQName().getLocalPart(), Namespace.getNamespace(childDefinition.getQName().getNamespaceURI()));
}
if(arrayElmts != null && arrayElmts.size() > 0) {
arrayElmts.add((Element) child.detach());
} else {
parentElement.addContent(index, child.detach());
}
break;
}
elmtInP = parentElement.getChild(elmt.getQName().getLocalPart());
if(elmtInP == null) {
elmtInP = parentElement.getChild(elmt.getQName().getLocalPart(), Namespace.getNamespace(elmt.getQName().getNamespaceURI()));
}
if(elmtInP != null) {
index++;
}
}
}
private ComplexType findParentType(AbstractSchemaElementImpl childDefinition) {
ComplexType parentType = null;
AbstractSchemaElementImpl parent = childDefinition.getParent();
if(parent != null) {
if(parent instanceof AbsItfElement) {
parentType = (ComplexType) ((AbsItfElement)parent).getType();
} else if(parent instanceof AbsItfComplexType) {
parentType = (ComplexType) ((AbsItfComplexType)parent);
} else {
parentType = this.findParentType(parent);
}
}
return parentType;
}
@Override
public String printXml(AbsItfElement eIn, Map values,
boolean createOptionalElement, boolean createOptionalAttribute) throws SchemaException {
final org.jdom.Element eOut = this.generateElement(eIn, values, ((AbstractElementImpl) eIn).getSchema().getElementFormDefault(), 1, createOptionalElement, createOptionalAttribute);
return new XMLOutputter(Format.getPrettyFormat()).outputString(eOut);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy