/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.tuscany.sca.databinding.impl; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Map; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.QName; import org.apache.tuscany.sca.databinding.SimpleTypeMapper; import org.apache.tuscany.sca.databinding.TransformationContext; import org.apache.tuscany.sca.interfacedef.util.TypeInfo; /** * Simple type mapper that maps from XSD types to Java Classes and Java Classes to XSD types. * * @version $Rev$ $Date$ * @tuscany.spi.extension.asclient */ public class SimpleTypeMapperImpl extends XSDDataTypeConverter implements SimpleTypeMapper { public static final Map<Class, String> JAVA2XML = new HashMap<Class, String>(); public static final String URI_2001_SCHEMA_XSD = "http://www.w3.org/2001/XMLSchema"; public static final Map<String, Class> XML2JAVA = new HashMap<String, Class>(); public static final QName XSD_ANY = new QName(URI_2001_SCHEMA_XSD, "any"); public static final QName XSD_ANYSIMPLETYPE = new QName(URI_2001_SCHEMA_XSD, "anySimpleType"); public static final QName XSD_ANYTYPE = new QName(URI_2001_SCHEMA_XSD, "anyType"); public static final QName XSD_ANYURI = new QName(URI_2001_SCHEMA_XSD, "anyURI"); public static final QName XSD_BASE64 = new QName(URI_2001_SCHEMA_XSD, "base64Binary"); public static final QName XSD_BOOLEAN = new QName(URI_2001_SCHEMA_XSD, "boolean"); public static final QName XSD_BYTE = new QName(URI_2001_SCHEMA_XSD, "byte"); public static final QName XSD_DATE = new QName(URI_2001_SCHEMA_XSD, "date"); public static final QName XSD_DATETIME = new QName(URI_2001_SCHEMA_XSD, "dateTime"); public static final QName XSD_DAY = new QName(URI_2001_SCHEMA_XSD, "gDay"); public static final QName XSD_DECIMAL = new QName(URI_2001_SCHEMA_XSD, "decimal"); public static final QName XSD_DOUBLE = new QName(URI_2001_SCHEMA_XSD, "double"); public static final QName XSD_DURATION = new QName(URI_2001_SCHEMA_XSD, "duration"); public static final QName XSD_ENTITIES = new QName(URI_2001_SCHEMA_XSD, "ENTITIES"); public static final QName XSD_ENTITY = new QName(URI_2001_SCHEMA_XSD, "ENTITY"); public static final QName XSD_FLOAT = new QName(URI_2001_SCHEMA_XSD, "float"); public static final QName XSD_HEXBIN = new QName(URI_2001_SCHEMA_XSD, "hexBinary"); public static final QName XSD_IDREF = new QName(URI_2001_SCHEMA_XSD, "IDREF"); public static final QName XSD_IDREFS = new QName(URI_2001_SCHEMA_XSD, "IDREFS"); public static final QName XSD_INT = new QName(URI_2001_SCHEMA_XSD, "int"); public static final QName XSD_INTEGER = new QName(URI_2001_SCHEMA_XSD, "integer"); public static final QName XSD_LONG = new QName(URI_2001_SCHEMA_XSD, "long"); public static final QName XSD_MONTH = new QName(URI_2001_SCHEMA_XSD, "gMonth"); public static final QName XSD_MONTHDAY = new QName(URI_2001_SCHEMA_XSD, "gMonthDay"); public static final QName XSD_NAME = new QName(URI_2001_SCHEMA_XSD, "Name"); public static final QName XSD_NCNAME = new QName(URI_2001_SCHEMA_XSD, "NCName"); public static final QName XSD_NEGATIVEINTEGER = new QName(URI_2001_SCHEMA_XSD, "negativeInteger"); public static final QName XSD_NMTOKEN = new QName(URI_2001_SCHEMA_XSD, "NMTOKEN"); public static final QName XSD_NMTOKENS = new QName(URI_2001_SCHEMA_XSD, "NMTOKENS"); public static final QName XSD_NONNEGATIVEINTEGER = new QName(URI_2001_SCHEMA_XSD, "nonNegativeInteger"); public static final QName XSD_NONPOSITIVEINTEGER = new QName(URI_2001_SCHEMA_XSD, "nonPositiveInteger"); public static final QName XSD_NORMALIZEDSTRING = new QName(URI_2001_SCHEMA_XSD, "normalizedString"); public static final QName XSD_NOTATION = new QName(URI_2001_SCHEMA_XSD, "NOTATION"); public static final QName XSD_POSITIVEINTEGER = new QName(URI_2001_SCHEMA_XSD, "positiveInteger"); public static final QName XSD_QNAME = new QName(URI_2001_SCHEMA_XSD, "QName"); public static final QName XSD_SHORT = new QName(URI_2001_SCHEMA_XSD, "short"); public static final Map<String, TypeInfo> XSD_SIMPLE_TYPES = new HashMap<String, TypeInfo>(); public static final QName XSD_STRING = new QName(URI_2001_SCHEMA_XSD, "string"); public static final QName XSD_TIME = new QName(URI_2001_SCHEMA_XSD, "time"); public static final QName XSD_TOKEN = new QName(URI_2001_SCHEMA_XSD, "token"); public static final QName XSD_UNSIGNEDBYTE = new QName(URI_2001_SCHEMA_XSD, "unsignedByte"); public static final QName XSD_UNSIGNEDINT = new QName(URI_2001_SCHEMA_XSD, "unsignedInt"); public static final QName XSD_UNSIGNEDLONG = new QName(URI_2001_SCHEMA_XSD, "unsignedLong"); public static final QName XSD_UNSIGNEDSHORT = new QName(URI_2001_SCHEMA_XSD, "unsignedShort"); public static final QName XSD_YEAR = new QName(URI_2001_SCHEMA_XSD, "gYear"); public static final QName XSD_YEARMONTH = new QName(URI_2001_SCHEMA_XSD, "gYearMonth"); private static final String[] XSD_TYPE_NAMES = {"string", "boolean", "double", "float", "int", "integer", "long", "short", "byte", "decimal", "base64Binary", "hexBinary", "anySimpleType", "anyType", "any", "QName", "dateTime", "date", "time", "normalizedString", "token", "unsignedLong", "unsignedInt", "unsignedShort", "unsignedByte", "positiveInteger", "negativeInteger", "nonNegativeInteger", "nonPositiveInteger", "gYearMonth", "gMonthDay", "gYear", "gMonth", "gDay", "duration", "Name", "NCName", "NMTOKEN", "NMTOKENS", "NOTATION", "ENTITY", "ENTITIES", "IDREF", "IDREFS", "anyURI", "language", "ID"}; static { for (String type : XSD_TYPE_NAMES) { TypeInfo simpleType = new TypeInfo(new QName(URI_2001_SCHEMA_XSD, type), true, null); XSD_SIMPLE_TYPES.put(type, simpleType); } } static { JAVA2XML.put(boolean.class, "boolean"); JAVA2XML.put(byte.class, "byte"); JAVA2XML.put(short.class, "short"); JAVA2XML.put(int.class, "int"); JAVA2XML.put(long.class, "long"); JAVA2XML.put(float.class, "float"); JAVA2XML.put(double.class, "double"); JAVA2XML.put(Boolean.class, "boolean"); JAVA2XML.put(Byte.class, "byte"); JAVA2XML.put(Short.class, "short"); JAVA2XML.put(Integer.class, "int"); JAVA2XML.put(Long.class, "long"); JAVA2XML.put(Float.class, "float"); JAVA2XML.put(Double.class, "double"); JAVA2XML.put(java.lang.String.class, "string"); JAVA2XML.put(java.math.BigInteger.class, "integer"); JAVA2XML.put(java.math.BigDecimal.class, "decimal"); JAVA2XML.put(java.util.Calendar.class, "dateTime"); JAVA2XML.put(java.util.Date.class, "dateTime"); JAVA2XML.put(javax.xml.namespace.QName.class, "QName"); JAVA2XML.put(java.net.URI.class, "string"); JAVA2XML.put(javax.xml.datatype.XMLGregorianCalendar.class, "anySimpleType"); JAVA2XML.put(javax.xml.datatype.Duration.class, "duration"); JAVA2XML.put(java.lang.Object.class, "anyType"); JAVA2XML.put(java.awt.Image.class, "base64Binary"); JAVA2XML.put(byte[].class, "base64Binary"); // java2XSD.put(javax.activation.DataHandler.class, "base64Binary"); JAVA2XML.put(javax.xml.transform.Source.class, "base64Binary"); JAVA2XML.put(java.util.UUID.class, "string"); } static { XML2JAVA.put("string", java.lang.String.class); XML2JAVA.put("integer", java.math.BigInteger.class); XML2JAVA.put("int", int.class); XML2JAVA.put("long", long.class); XML2JAVA.put("short", short.class); XML2JAVA.put("decimal", java.math.BigDecimal.class); XML2JAVA.put("float", float.class); XML2JAVA.put("double", double.class); XML2JAVA.put("boolean", boolean.class); XML2JAVA.put("byte", byte.class); XML2JAVA.put("QName", javax.xml.namespace.QName.class); XML2JAVA.put("dateTime", javax.xml.datatype.XMLGregorianCalendar.class); XML2JAVA.put("base64Binary", byte[].class); XML2JAVA.put("hexBinary", byte[].class); XML2JAVA.put("unsignedInt", long.class); XML2JAVA.put("unsignedShort", int.class); XML2JAVA.put("unsignedByte", short.class); XML2JAVA.put("time", javax.xml.datatype.XMLGregorianCalendar.class); XML2JAVA.put("date", javax.xml.datatype.XMLGregorianCalendar.class); XML2JAVA.put("gDay", javax.xml.datatype.XMLGregorianCalendar.class); XML2JAVA.put("gMonth", javax.xml.datatype.XMLGregorianCalendar.class); XML2JAVA.put("gYear", javax.xml.datatype.XMLGregorianCalendar.class); XML2JAVA.put("gYearMonth", javax.xml.datatype.XMLGregorianCalendar.class); XML2JAVA.put("gMonthDay", javax.xml.datatype.XMLGregorianCalendar.class); XML2JAVA.put("anySimpleType", java.lang.Object.class); // For elements // XML2JAVA.put("anySimpleType", java.lang.String.class); // For // attributes XML2JAVA.put("duration", javax.xml.datatype.Duration.class); XML2JAVA.put("NOTATION", javax.xml.namespace.QName.class); } private DatatypeFactory factory; public SimpleTypeMapperImpl() { super(); try { this.factory = DatatypeFactory.newInstance(); } catch (DatatypeConfigurationException e) { throw new IllegalArgumentException(e); } } public Class<?> getJavaType(QName xmlType) { if (xmlType != null && URI_2001_SCHEMA_XSD.equals(xmlType.getNamespaceURI())) { return XML2JAVA.get(xmlType.getLocalPart()); } else { return null; } } public TypeInfo getXMLType(Class javaType) { return XSD_SIMPLE_TYPES.get(JAVA2XML.get(javaType)); } public Object toJavaObject(QName simpleType, String literal, TransformationContext context) { /** * <ul> * <li>xsd:string --- java.lang.String * <li>xsd:integer --- java.math.BigInteger * <li>xsd:int --- int * <li>xsd:long --- long * <li>xsd:short --- short * <li>xsd:decimal --- java.math.BigDecimal * <li>xsd:float --- float * <li>xsd:double --- double * <li>xsd:boolean --- boolean * <li>xsd:byte --- byte * <li>xsd:QName --- javax.xml.namespace.QName * <li>xsd:dateTime --- javax.xml.datatype.XMLGregorianCalendar * <li>xsd:base64Binary --- byte[] * <li>xsd:hexBinary --- byte[] * <li>xsd:unsignedInt --- long * <li>xsd:unsignedShort --- int * <li>xsd:unsignedByte --- short * <li>xsd:time --- javax.xml.datatype.XMLGregorianCalendar * <li>xsd:date --- javax.xml.datatype.XMLGregorianCalendar * <li>xsd:g* --- javax.xml.datatype.XMLGregorianCalendar * <li>xsd:anySimpleType (for xsd:element of this type)a * java.lang.Object * <li>xsd:anySimpleType (for xsd:attribute of this type) * java.lang.String * <li>xsd:duration javax.xml.datatype.Duration * <li>xsd:NOTATION javax.xml.namespace.QName * </ul> */ if (literal == null) { return null; } String value = literal.trim(); QName type = simpleType; if (type.equals(XSD_STRING)) { return parseString(value); } else if (type.equals(XSD_INT)) { return parseInt(value); } else if (type.equals(XSD_INTEGER)) { return parseInteger(value); } else if (type.equals(XSD_INT)) { return parseInt(value); } else if (type.equals(XSD_FLOAT)) { return parseFloat(value); } else if (type.equals(XSD_DOUBLE)) { return parseDouble(value); } else if (type.equals(XSD_SHORT)) { return parseShort(value); } else if (type.equals(XSD_DECIMAL)) { return parseDecimal(value); } else if (type.equals(XSD_BOOLEAN)) { return parseBoolean(value); } else if (type.equals(XSD_BYTE)) { return parseByte(value); } else if (type.equals(XSD_LONG)) { return parseLong(value); } else if (type.equals(XSD_UNSIGNEDBYTE)) { return parseUnsignedShort(value); } else if (type.equals(XSD_UNSIGNEDSHORT)) { return parseUnsignedShort(value); } else if (type.equals(XSD_UNSIGNEDINT)) { return parseUnsignedInt(value); } else if (type.equals(XSD_UNSIGNEDLONG)) { return parseUnsignedInt(value); } else if (type.equals(XSD_DATETIME)) { return parseDateTime(value); } else if (type.equals(XSD_DATE)) { return parseDate(value); } else if (type.equals(XSD_TIME)) { return parseTime(value); } else if (type.equals(XSD_DURATION)) { return parseDuration(value); } else if (type.equals(XSD_HEXBIN)) { return parseHexBinary(value); } else if (type.equals(XSD_BASE64)) { return parseBase64Binary(value); } else if (type.equals(XSD_QNAME)) { NamespaceContext namespaceContext = (NamespaceContext)((context != null) ? context.getMetadata().get(NamespaceContext.class.getName()) : null); return parseQName(value, namespaceContext); } else if (type.equals(XSD_NOTATION)) { NamespaceContext namespaceContext = (NamespaceContext)((context != null) ? context.getMetadata().get(NamespaceContext.class.getName()) : null); return parseQName(value, namespaceContext); } else if (type.equals(XSD_YEAR)) { return factory.newXMLGregorianCalendar(value); } else if (type.equals(XSD_MONTH)) { return factory.newXMLGregorianCalendar(value); } else if (type.equals(XSD_DAY)) { return factory.newXMLGregorianCalendar(value); } else if (type.equals(XSD_YEARMONTH)) { return factory.newXMLGregorianCalendar(value); } else if (type.equals(XSD_MONTHDAY)) { return factory.newXMLGregorianCalendar(value); } else { return value; } } @SuppressWarnings("deprecation") private XMLGregorianCalendar toXMLGregorianCalendar(Date date) { GregorianCalendar c = new GregorianCalendar(date.getYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()); return factory.newXMLGregorianCalendar(c); } private XMLGregorianCalendar toXMLGregorianCalendar(GregorianCalendar calendar) { return factory.newXMLGregorianCalendar(calendar); } public String toXMLLiteral(QName simpleType, Object obj, TransformationContext context) { if(obj == null) { // It could be null if nilable=true return null; } if (obj instanceof Float || obj instanceof Double) { if (obj instanceof Float) { return printDouble(((Float)obj).floatValue()); } else { return printDouble(((Double)obj).doubleValue()); } } else if (obj instanceof GregorianCalendar) { GregorianCalendar calendar = (GregorianCalendar)obj; return toXMLGregorianCalendar(calendar).toXMLFormat(); } else if (obj instanceof Date) { return toXMLGregorianCalendar((Date)obj).toXMLFormat(); } else if (obj instanceof XMLGregorianCalendar) { return ((XMLGregorianCalendar)obj).toXMLFormat(); } else if (obj instanceof byte[]) { if (simpleType != null) { if (simpleType.equals(XSD_BASE64)) { return printBase64Binary((byte[])obj); } else if (simpleType.equals(XSD_HEXBIN)) { return printHexBinary((byte[])obj); } } } else if (obj instanceof QName) { NamespaceContext namespaceContext = (NamespaceContext)((context != null) ? context.getMetadata().get(NamespaceContext.class.getName()) : null); return printQName((QName)obj, namespaceContext); } return obj.toString(); } public boolean isSimpleXSDType(QName typeName) { if (typeName == null) { return false; } return typeName.getNamespaceURI().equals(URI_2001_SCHEMA_XSD) && XSD_SIMPLE_TYPES.get(typeName.getLocalPart()) != null; } }