summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/tags/2.0.1-RC1/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/impl/SimpleTypeMapperImpl.java
blob: 16eb4b42edb9dd488eb5344dd363986e0c424299 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
/*
 * 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;
    }

}