/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenFlexo 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
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.wsdl;
import java.io.File;
import java.util.Hashtable;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.namespace.QName;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
public class XMLTypeMapper {
private static final Logger logger = Logger.getLogger(XMLTypeMapper.class.getPackage().getName());
/**
*
* @param type
* @param extractor
* @return a 2 String array composed of 1. java name of the type. 2 the cardinality of the type. (SINGLE, VECTOR)
*/
public static String[] getFullJavaNameForType(SchemaType type, SchemaTypeExtractor extractor, Hashtable simpleTypes) {
// Test an Array
if (type == null) {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("Type is NULL. Cannot find java Name for a NULL Type");
}
return new String[] { null, "SINGLE" };
}
// System.out.println("attributeModel:"+ type.getAttributeModel());
SchemaType baseType = type.getBaseType();
if (baseType != null && baseType.getName().getLocalPart().equals("Array")
&& baseType.getName().getNamespaceURI().equals("http://schemas.xmlsoap.org/soap/encoding/")) {
System.out.println("This is an array");
String innerType = getArrayType(type, extractor, simpleTypes);
return new String[] { innerType, "VECTOR" };
}
// Handle the simple Types. We are just interested in their base type.
if (type.isAnonymousType() && type.isSimpleType()) {
type = type.getBaseType();
} else if (!type.isAnonymousType() && type.isSimpleType() && !type.isBuiltinType()) {
// || ! type.isAnonymousType() && ! type.isSimpleType() && type.getContentType()==SchemaType.SIMPLE_CONTENT) {
type = (SchemaType) simpleTypes.get(type);
} else if (type.isAnonymousType() && !type.isSimpleType()) {
// handle the complex types here ??
} else {
}
// try a primitive type
String typeString = null;
if (type.isBuiltinType()) {
typeString = XMLTypeMapper.getJavaTypeForBuiltInType(type.getBuiltinTypeCode());
} else {
// ATTENTION
// get java Type For NOT BUILTIN type
// TODO....
// look for the package
typeString = type.getFullJavaName();
}
return new String[] { typeString, "SINGLE" };
}
public static String getArrayType(SchemaType type, SchemaTypeExtractor extractor, Hashtable simpleTypes) {
try {
// 1. Get Xml fragment of Schemas. Either uses schemas in extractor or get them with XmlObject.
// With extractor, the wsdl namespace is changed...
boolean useSchemaFromExtractor = false;
XmlObject[] schemas = null;
String wsdlUrl = extractor.getWsdlUrl();
XmlOptions options = new XmlOptions();
options.setCompileNoValidation();
options.setCompileDownloadUrls();
options.setCompileNoUpaRule();
options.setSaveUseOpenFrag();
options.setSaveSyntheticDocumentElement(new QName("http://www.w3.org/2001/XMLSchema", "schema"));
XmlObject wsdlObject = XmlObject.Factory.parse(new File(wsdlUrl)/* new URL(wsdlUrl) */, options);
// a. get schema with XMLObject
if (!useSchemaFromExtractor) {
schemas = wsdlObject.selectPath("declare namespace s='http://www.w3.org/2001/XMLSchema' .//s:schema");
}
// b. get schema with Extractor.
else {
List schemaList = extractor.getSchemaList();
schemas = (XmlObject[]) schemaList.toArray();
}
// 2. Find attribute: find the name of the object contained in the array.
for (int i = 0; i < schemas.length; i++) {
XmlObject schema = schemas[i];// schemas.get(i);
System.out.println("anonymous:" + type.isAnonymousType());
System.out.println("document:" + type.isDocumentType());
String typeName = null;
if (type.isDocumentType()) {
// a DocumentType is associated to an element. But has no QName ! The element has the QName.
// to get it, take the contentModel of the documentType (element)
typeName = type.getContentModel().getName().getLocalPart();
} else if (type.isAnonymousType()) {
// recup�rer le element Name car non topLevel type with no QNAME
typeName = type.getOuterType().getContentModel().getName().getLocalPart();
// typeName = type.getName().getLocalPart();
} else {
// type with a QNAME
typeName = type.getName().getLocalPart();
}
XmlObject[] attributes = null;
// When parsed With WSDL2Java the wsdl namespace http://schemas.xmlsoap.org/wsdl/ is subsituted...
String wsdlNS = "http://schemas.xmlsoap.org/wsdl/";
if (useSchemaFromExtractor) {
wsdlNS = "http://www.apache.org/internal/xmlbeans/wsdlsubst";
}
// Find Elements of with correct name
if (type.isAnonymousType() || type.isDocumentType()) {
attributes = schema.selectPath("declare namespace s='http://www.w3.org/2001/XMLSchema' declare namespace wsdl='"
+ wsdlNS + "' .//s:element[@name='" + typeName + "']//s:attribute[@wsdl:arrayType]");
}
// Or Find ComplexTypes with correct name
else {
attributes = schema.selectPath("declare namespace s='http://www.w3.org/2001/XMLSchema' declare namespace wsdl='"
+ wsdlNS + "' .//s:complexType[@name='" + typeName + "']//s:attribute[@wsdl:arrayType]");
}
if (attributes.length > 0) {
XmlObject attribut = attributes[0];
NamedNodeMap map = attribut.getDomNode().getAttributes();
Node s = map.getNamedItemNS(wsdlNS, "arrayType");
System.out.println("s:" + s.getNodeValue());
// now we have something like "tns:MyObject[]"
// we need to separate tns and MyObject. And get the value of tns.
// for (int j = 0; j < map.getLength(); j++) {
// Node n = map.item(j);
// System.out.println("node name:"+n.getNodeName()+" value:"+n.getNodeValue() );
//
// }
String value = s.getNodeValue();
String tns = value.substring(0, value.indexOf(":"));
String obj = value.substring(value.indexOf(":") + 1, value.indexOf("["));
// resovle tns
// find xmlns:tns1="http://DefaultNamespace" qui est un attribut de wsdl !!!
// with xmlsn = xmlns="http://schemas.xmlsoap.org/
XmlObject[] wsdlDef = wsdlObject.selectPath("declare namespace s='http://schemas.xmlsoap.org/wsdl/' .//s:definitions");
XmlObject def = wsdlDef[0];
// Try nr O: returns null.
// XmlObject defXmlns = def.selectAttribute("http://schemas.xmlsoap.org/wsdl/", "xmlns");
Node defNode = def.getDomNode();
NamedNodeMap defmap = defNode.getAttributes();
// for (int j = 0; j < defmap.getLength(); j++) {
// Node n = defmap.item(j);
// System.out.println("node name:"+n.getNodeName()+" value:"+n.getNodeValue() );
//
// }
// Try nr 1:
// Node xmlnsNode = defmap.getNamedItem("xmlns");
// String xmlNS = xmlnsNode.getNodeValue();
// Node tnsNode = defmap.getNamedItemNS(xmlNS,tns); returns null...
// Try nr 2:
String nodeName = "xmlns:" + tns;
Node tnsNode = defmap.getNamedItem(nodeName);
String tnsNS = tnsNode.getNodeValue();
// now we have: tnsNS= http://something/something
// find the correct Type:
SchemaType objectOfTableType = extractor.schemaTypeLoader().findType(new QName(tnsNS, obj));
String[] javaType = getFullJavaNameForType(objectOfTableType, extractor, simpleTypes);
String toReturn = javaType[0];
return toReturn;
}
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
return "java.lang.Object";
}
// see: http://xmlbeans.apache.org/docs/2.0.0/guide/conXMLBeansSupportBuiltInSchemaTypes.html
public static String getJavaTypeForBuiltInType(int typeCode) {
switch (typeCode) {
case SchemaType.BTC_ANY_TYPE:
return "java.lang.Object";
case SchemaType.BTC_ANY_SIMPLE:
return "java.lang.String";
case SchemaType.BTC_BOOLEAN:
return "boolean";
case SchemaType.BTC_BASE_64_BINARY:
return "byte[]";
case SchemaType.BTC_HEX_BINARY:
return "byte[]";
case SchemaType.BTC_ANY_URI:
return "java.lang.String";// "anyURI", "org.apache.xmlbeans.XmlAnyURI");
case SchemaType.BTC_QNAME:
return "javax.xml.namespace.QName";// "QName", "org.apache.xmlbeans.XmlQName");
case SchemaType.BTC_NOTATION:
return "java.lang.Object";// "NOTATION", "org.apache.xmlbeans.XmlNOTATION");
case SchemaType.BTC_FLOAT:
return "float";// "float", "org.apache.xmlbeans.XmlFloat");
case SchemaType.BTC_DOUBLE:
return "double";// "double", "org.apache.xmlbeans.XmlDouble");
// case SchemaType.BTC_DECIMAL:
// return "java.math.BigDecimal";// , "decimal", "org.apache.xmlbeans.XmlDecimal");
case SchemaType.BTC_DECIMAL:
return "long";
case SchemaType.BTC_STRING:
return "java.lang.String";// "string", "org.apache.xmlbeans.XmlString");
case SchemaType.BTC_DURATION:
return "java.lang.String";// "org.apache.xmlbeans.XmlDuration";// , "duration", "org.apache.xmlbeans.XmlDuration");
case SchemaType.BTC_DATE_TIME:
return "java.util.Calendar";// "dateTime", "org.apache.xmlbeans.XmlDateTime");
case SchemaType.BTC_TIME:
return "java.util.Calendar";// "time", "org.apache.xmlbeans.XmlTime");
case SchemaType.BTC_DATE:
return "java.util.Calendar";// "date", "org.apache.xmlbeans.XmlDate");
case SchemaType.BTC_G_YEAR_MONTH:
return "java.util.Calendar";// "gYearMonth", "org.apache.xmlbeans.XmlGYearMonth");
case SchemaType.BTC_G_YEAR:
return "java.util.Calendar";// "gYear", "org.apache.xmlbeans.XmlGYear");
case SchemaType.BTC_G_MONTH_DAY:
return "java.util.Calendar";// "gMonthDay", "org.apache.xmlbeans.XmlGMonthDay");
case SchemaType.BTC_G_DAY:
return "java.util.Calendar";// "gDay", "org.apache.xmlbeans.XmlGDay");
case SchemaType.BTC_G_MONTH:
return "java.util.Calendar";// "gMonth", "org.apache.xmlbeans.XmlGMonth");
// derived numerics
case SchemaType.BTC_INTEGER:
return "java.lang.Integer";// "integer", "org.apache.xmlbeans.XmlInteger");
case SchemaType.BTC_LONG:
return "long";// "long", "org.apache.xmlbeans.XmlLong");
case SchemaType.BTC_INT:
return "int";// "int", "org.apache.xmlbeans.XmlInt");
case SchemaType.BTC_SHORT:
return "short";// , "short", "org.apache.xmlbeans.XmlShort");
case SchemaType.BTC_BYTE:
return "byte";// , "byte", "org.apache.xmlbeans.XmlByte");
case SchemaType.BTC_NON_POSITIVE_INTEGER:
return "java.lang.Integer";// "nonPositiveInteger", "org.apache.xmlbeans.XmlNonPositiveInteger");
case SchemaType.BTC_NEGATIVE_INTEGER:
return "java.lang.Integer";// "negativeInteger", "org.apache.xmlbeans.XmlNegativeInteger");
case SchemaType.BTC_NON_NEGATIVE_INTEGER:
return "java.lang.Integer";// "nonNegativeInteger", "org.apache.xmlbeans.XmlNonNegativeInteger");
case SchemaType.BTC_POSITIVE_INTEGER:
return "java.lang.Integer";// "positiveInteger", "org.apache.xmlbeans.XmlPositiveInteger");
case SchemaType.BTC_UNSIGNED_LONG:
return "long";// ????? "unsignedLong", "org.apache.xmlbeans.XmlUnsignedLong");
case SchemaType.BTC_UNSIGNED_INT:
return "int";// , "unsignedInt", "org.apache.xmlbeans.XmlUnsignedInt");
case SchemaType.BTC_UNSIGNED_SHORT:
return "short";// "unsignedShort", "org.apache.xmlbeans.XmlUnsignedShort");
case SchemaType.BTC_UNSIGNED_BYTE:
return "byte";// "unsignedByte", "org.apache.xmlbeans.XmlUnsignedByte");
// derived strings
case SchemaType.BTC_NORMALIZED_STRING:
return "java.lang.String";// "normalizedString", "org.apache.xmlbeans.XmlNormalizedString");
case SchemaType.BTC_TOKEN:
return "java.lang.String";// , "token", "org.apache.xmlbeans.XmlToken");
case SchemaType.BTC_NAME:
return "java.lang.String";// , "Name", "org.apache.xmlbeans.XmlName");
case SchemaType.BTC_NCNAME:
return "java.lang.String";// , "NCName", "org.apache.xmlbeans.XmlNCName");
case SchemaType.BTC_LANGUAGE:
return "java.lang.String";// , "language", "org.apache.xmlbeans.XmlLanguage");
case SchemaType.BTC_ID:
return "java.lang.String";// , "ID", "org.apache.xmlbeans.XmlID");
case SchemaType.BTC_IDREF:
return "java.lang.String";// , "IDREF", "org.apache.xmlbeans.XmlIDREF");
case SchemaType.BTC_IDREFS:
return "java.lang.String";// , "IDREFS", "org.apache.xmlbeans.XmlIDREFS");
case SchemaType.BTC_ENTITY:
return "java.lang.String";// , "ENTITY", "org.apache.xmlbeans.XmlENTITY");
case SchemaType.BTC_ENTITIES:
return "java.lang.String";// , "ENTITIES", "org.apache.xmlbeans.XmlENTITIES");
case SchemaType.BTC_NMTOKEN:
return "java.lang.String";// , "NMTOKEN", "org.apache.xmlbeans.XmlNMTOKEN");
case SchemaType.BTC_NMTOKENS:
return "java.lang.String";// , "NMTOKENS", "org.apache.xmlbeans.XmlNMTOKENS");
// the no-type
case SchemaType.BTC_NOT_BUILTIN:
return null;// , null, null);
default:
return null;
}
}
/*
* Built-In Schema Type XMLBean Type Natural Java Type xs:anyType XmlObject org.apache.xmlbeans.XmlObject
* xs:anySimpleType XmlAnySimpleType String xs:anyURI XmlAnyURI String xs:base64Binary XmlBase64Binary byte[]
* xs:boolean XmlBoolean boolean xs:byte XmlByte byte xs:date XmlDate java.util.Calendar xs:dateTime XmlDateTime
* java.util.Calendar xs:decimal XmlDecimal java.math.BigDecimal xs:double XmlDouble double xs:duration XmlDuration
* org.apache.xmlbeans.GDuration xs:ENTITIES XmlENTITIES String xs:ENTITY XmlENTITY String xs:float XmlFloat float
* xs:gDay XmlGDay java.util.Calendar xs:gMonth XmlGMonth java.util.Calendar xs:gMonthDay XmlGMonthDay
* java.util.Calendar xs:gYear XmlGYear java.util.Calendar xs:gYearMonth XmlGYearMonth java.util.Calendar
* xs:hexBinary XmlHexBinary byte[] xs:ID XmlID String xs:IDREF XmlIDREF String xs:IDREFS XmlIDREFS String xs:int
* XmlInt int xs:integer XmlInteger java.math.BigInteger xs:language XmlLanguage String xs:long XmlLong long xs:Name
* XmlName String xs:NCName XmlNCNAME String xs:negativeInteger XmlNegativeInteger java.math.BigInteger xs:NMTOKEN
* XmlNMTOKEN String xs:NMTOKENS XmlNMTOKENS String xs:nonNegativeInteger XmlNonNegativeInteger java.math.BigInteger
* xs:nonPositiveInteger XmlNonPositiveInteger java.math.BigInteger xs:normalizedString XmlNormalizedString String
* xs:NOTATION XmlNOTATION Not supported xs:positiveInteger XmlPositiveInteger java.math.BigInteger xs:QName
* XmlQName javax.xml.namespace.QName xs:short XmlShort short xs:string XmlString String xs:time XmlTime
* java.util.Calendar xs:token XmlToken String xs:unsignedByte XmlUnsignedByte short xs:unsignedInt XmlUnsignedInt
* long xs:unsignedLong XmlUnsignedLong java.math.BigInteger xs:unsignedShort XmlUnsignedShort int
*/
}