src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/impl/RuntimeBuiltinLeafInfoImpl.java

Fri, 23 Aug 2013 09:57:21 +0100

author
mkos
date
Fri, 23 Aug 2013 09:57:21 +0100
changeset 397
b99d7e355d4b
parent 368
0989ad8c0860
child 450
b0c2840e2513
permissions
-rw-r--r--

8022885: Update JAX-WS RI integration to 2.2.9-b14140
8013016: Rebase 8009009 against the latest jdk8/jaxws
Reviewed-by: alanb, chegar

ohair@286 1 /*
alanb@368 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
ohair@286 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ohair@286 4 *
ohair@286 5 * This code is free software; you can redistribute it and/or modify it
ohair@286 6 * under the terms of the GNU General Public License version 2 only, as
ohair@286 7 * published by the Free Software Foundation. Oracle designates this
ohair@286 8 * particular file as subject to the "Classpath" exception as provided
ohair@286 9 * by Oracle in the LICENSE file that accompanied this code.
ohair@286 10 *
ohair@286 11 * This code is distributed in the hope that it will be useful, but WITHOUT
ohair@286 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ohair@286 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ohair@286 14 * version 2 for more details (a copy is included in the LICENSE file that
ohair@286 15 * accompanied this code).
ohair@286 16 *
ohair@286 17 * You should have received a copy of the GNU General Public License version
ohair@286 18 * 2 along with this work; if not, write to the Free Software Foundation,
ohair@286 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ohair@286 20 *
ohair@286 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@286 22 * or visit www.oracle.com if you need additional information or have any
ohair@286 23 * questions.
ohair@286 24 */
ohair@286 25
ohair@286 26 package com.sun.xml.internal.bind.v2.model.impl;
ohair@286 27
alanb@368 28 import java.awt.Component;
alanb@368 29 import java.awt.Graphics;
alanb@368 30 import java.awt.Image;
alanb@368 31 import java.awt.MediaTracker;
ohair@286 32 import java.awt.image.BufferedImage;
ohair@286 33 import java.io.ByteArrayInputStream;
ohair@286 34 import java.io.File;
ohair@286 35 import java.io.IOException;
ohair@286 36 import java.io.InputStream;
ohair@286 37 import java.io.OutputStreamWriter;
ohair@286 38 import java.io.UnsupportedEncodingException;
ohair@286 39 import java.lang.reflect.Type;
ohair@286 40 import java.math.BigDecimal;
ohair@286 41 import java.math.BigInteger;
ohair@286 42 import java.net.MalformedURLException;
ohair@286 43 import java.net.URI;
ohair@286 44 import java.net.URISyntaxException;
ohair@286 45 import java.net.URL;
ohair@286 46 import java.util.ArrayList;
ohair@286 47 import java.util.Calendar;
ohair@286 48 import java.util.Collections;
ohair@286 49 import java.util.Date;
ohair@286 50 import java.util.GregorianCalendar;
ohair@286 51 import java.util.HashMap;
ohair@286 52 import java.util.Iterator;
ohair@286 53 import java.util.List;
ohair@286 54 import java.util.Map;
ohair@286 55 import java.util.UUID;
ohair@286 56
ohair@286 57 import javax.activation.DataHandler;
ohair@286 58 import javax.activation.DataSource;
ohair@286 59 import javax.activation.MimeType;
ohair@286 60 import javax.activation.MimeTypeParseException;
ohair@286 61 import javax.imageio.ImageIO;
ohair@286 62 import javax.imageio.ImageWriter;
ohair@286 63 import javax.imageio.stream.ImageOutputStream;
ohair@286 64 import javax.xml.bind.ValidationEvent;
ohair@286 65 import javax.xml.bind.helpers.ValidationEventImpl;
ohair@286 66 import javax.xml.datatype.DatatypeConfigurationException;
ohair@286 67 import javax.xml.datatype.DatatypeConstants;
ohair@286 68 import javax.xml.datatype.DatatypeFactory;
ohair@286 69 import javax.xml.datatype.Duration;
ohair@286 70 import javax.xml.datatype.XMLGregorianCalendar;
ohair@286 71 import javax.xml.namespace.QName;
ohair@286 72 import javax.xml.stream.XMLStreamException;
ohair@286 73 import javax.xml.transform.OutputKeys;
ohair@286 74 import javax.xml.transform.Source;
ohair@286 75 import javax.xml.transform.Transformer;
ohair@286 76 import javax.xml.transform.TransformerException;
ohair@286 77 import javax.xml.transform.stream.StreamResult;
ohair@286 78
ohair@286 79 import com.sun.istack.internal.ByteArrayDataSource;
ohair@286 80 import com.sun.xml.internal.bind.DatatypeConverterImpl;
ohair@286 81 import com.sun.xml.internal.bind.WhiteSpaceProcessor;
ohair@286 82 import com.sun.xml.internal.bind.api.AccessorException;
ohair@286 83 import com.sun.xml.internal.bind.v2.TODO;
ohair@286 84 import com.sun.xml.internal.bind.v2.WellKnownNamespace;
ohair@286 85 import com.sun.xml.internal.bind.v2.model.runtime.RuntimeBuiltinLeafInfo;
ohair@286 86 import com.sun.xml.internal.bind.v2.runtime.Name;
ohair@286 87 import com.sun.xml.internal.bind.v2.runtime.Transducer;
ohair@286 88 import com.sun.xml.internal.bind.v2.runtime.XMLSerializer;
ohair@286 89 import com.sun.xml.internal.bind.v2.runtime.output.Pcdata;
ohair@286 90 import com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data;
ohair@286 91 import com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext;
ohair@286 92 import com.sun.xml.internal.bind.v2.util.ByteArrayOutputStreamEx;
ohair@286 93 import com.sun.xml.internal.bind.v2.util.DataSourceSource;
mkos@397 94 import java.util.logging.Logger;
mkos@397 95 import com.sun.xml.internal.bind.Util;
mkos@397 96 import java.util.logging.Level;
ohair@286 97
ohair@286 98 import org.xml.sax.SAXException;
ohair@286 99
ohair@286 100 /**
ohair@286 101 * {@link BuiltinLeafInfoImpl} with a support for runtime.
ohair@286 102 *
ohair@286 103 * <p>
ohair@286 104 * In particular this class defines {@link Transducer}s for the built-in types.
ohair@286 105 *
ohair@286 106 * @author Kohsuke Kawaguchi
ohair@286 107 */
ohair@286 108 public abstract class RuntimeBuiltinLeafInfoImpl<T> extends BuiltinLeafInfoImpl<Type,Class>
ohair@286 109 implements RuntimeBuiltinLeafInfo, Transducer<T> {
ohair@286 110
mkos@397 111 private static final Logger logger = Util.getClassLogger();
mkos@397 112
ohair@286 113 private RuntimeBuiltinLeafInfoImpl(Class type, QName... typeNames) {
ohair@286 114 super(type, typeNames);
ohair@286 115 LEAVES.put(type,this);
ohair@286 116 }
ohair@286 117
ohair@286 118 public final Class getClazz() {
ohair@286 119 return (Class)getType();
ohair@286 120 }
ohair@286 121
ohair@286 122
ohair@286 123 public final Transducer getTransducer() {
ohair@286 124 return this;
ohair@286 125 }
ohair@286 126
ohair@286 127 public boolean useNamespace() {
ohair@286 128 return false;
ohair@286 129 }
ohair@286 130
ohair@286 131 public final boolean isDefault() {
ohair@286 132 return true;
ohair@286 133 }
ohair@286 134
ohair@286 135 public void declareNamespace(T o, XMLSerializer w) throws AccessorException {
ohair@286 136 }
ohair@286 137
ohair@286 138 public QName getTypeName(T instance) {
ohair@286 139 return null;
ohair@286 140 }
ohair@286 141
ohair@286 142 /**
ohair@286 143 * Those built-in types that print to {@link String}.
ohair@286 144 */
ohair@286 145 private static abstract class StringImpl<T> extends RuntimeBuiltinLeafInfoImpl<T> {
ohair@286 146 protected StringImpl(Class type, QName... typeNames) {
ohair@286 147 super(type,typeNames);
ohair@286 148 }
ohair@286 149
ohair@286 150 public abstract String print(T o) throws AccessorException;
ohair@286 151
ohair@286 152 public void writeText(XMLSerializer w, T o, String fieldName) throws IOException, SAXException, XMLStreamException, AccessorException {
ohair@286 153 w.text(print(o),fieldName);
ohair@286 154 }
ohair@286 155
ohair@286 156 public void writeLeafElement(XMLSerializer w, Name tagName, T o, String fieldName) throws IOException, SAXException, XMLStreamException, AccessorException {
ohair@286 157 w.leafElement(tagName,print(o),fieldName);
ohair@286 158 }
ohair@286 159 }
ohair@286 160
ohair@286 161 /**
ohair@286 162 * Those built-in types that print to {@link Pcdata}.
ohair@286 163 */
ohair@286 164 private static abstract class PcdataImpl<T> extends RuntimeBuiltinLeafInfoImpl<T> {
ohair@286 165 protected PcdataImpl(Class type, QName... typeNames) {
ohair@286 166 super(type,typeNames);
ohair@286 167 }
ohair@286 168
ohair@286 169 public abstract Pcdata print(T o) throws AccessorException;
ohair@286 170
ohair@286 171 public final void writeText(XMLSerializer w, T o, String fieldName) throws IOException, SAXException, XMLStreamException, AccessorException {
ohair@286 172 w.text(print(o),fieldName);
ohair@286 173 }
ohair@286 174
ohair@286 175 public final void writeLeafElement(XMLSerializer w, Name tagName, T o, String fieldName) throws IOException, SAXException, XMLStreamException, AccessorException {
ohair@286 176 w.leafElement(tagName,print(o),fieldName);
ohair@286 177 }
ohair@286 178
ohair@286 179 }
ohair@286 180
ohair@286 181 /**
ohair@286 182 * All instances of {@link RuntimeBuiltinLeafInfoImpl}s keyed by their type.
ohair@286 183 */
ohair@286 184 public static final Map<Type,RuntimeBuiltinLeafInfoImpl<?>> LEAVES = new HashMap<Type, RuntimeBuiltinLeafInfoImpl<?>>();
ohair@286 185
ohair@286 186 private static QName createXS(String typeName) {
ohair@286 187 return new QName(WellKnownNamespace.XML_SCHEMA,typeName);
ohair@286 188 }
ohair@286 189
ohair@286 190 public static final RuntimeBuiltinLeafInfoImpl<String> STRING;
ohair@286 191
ohair@286 192 private static final String DATE = "date";
ohair@286 193
ohair@286 194 /**
ohair@286 195 * List of all {@link RuntimeBuiltinLeafInfoImpl}s.
ohair@286 196 *
ohair@286 197 * <p>
ohair@286 198 * This corresponds to the built-in Java classes that are specified to be
ohair@286 199 * handled differently than ordinary classes. See table 8-2 "Mapping of Standard Java classes".
ohair@286 200 */
ohair@286 201 public static final List<RuntimeBuiltinLeafInfoImpl<?>> builtinBeanInfos;
ohair@286 202
ohair@286 203 public static final String MAP_ANYURI_TO_URI = "mapAnyUriToUri";
mkos@397 204 public static final String USE_OLD_GMONTH_MAPPING = "jaxb.ri.useOldGmonthMapping";
ohair@286 205
ohair@286 206 static {
ohair@286 207
ohair@286 208 QName[] qnames = (System.getProperty(MAP_ANYURI_TO_URI) == null) ? new QName[] {
ohair@286 209 createXS("string"),
ohair@286 210 createXS("anySimpleType"),
ohair@286 211 createXS("normalizedString"),
ohair@286 212 createXS("anyURI"),
ohair@286 213 createXS("token"),
ohair@286 214 createXS("language"),
ohair@286 215 createXS("Name"),
ohair@286 216 createXS("NCName"),
ohair@286 217 createXS("NMTOKEN"),
ohair@286 218 createXS("ENTITY")}
ohair@286 219 :
ohair@286 220 new QName[] {
ohair@286 221 createXS("string"),
ohair@286 222 createXS("anySimpleType"),
ohair@286 223 createXS("normalizedString"),
ohair@286 224 createXS("token"),
ohair@286 225 createXS("language"),
ohair@286 226 createXS("Name"),
ohair@286 227 createXS("NCName"),
ohair@286 228 createXS("NMTOKEN"),
ohair@286 229 createXS("ENTITY")};
ohair@286 230
ohair@286 231 STRING = new StringImplImpl(String.class, qnames);
ohair@286 232
ohair@286 233 ArrayList<RuntimeBuiltinLeafInfoImpl<?>> secondaryList = new ArrayList<RuntimeBuiltinLeafInfoImpl<?>>();
ohair@286 234 /*
ohair@286 235 There are cases where more than one Java classes map to the same XML type.
ohair@286 236 But when we see the same XML type in an incoming document, we only pick
ohair@286 237 one of those Java classes to unmarshal. This Java class is called 'primary'.
ohair@286 238 The rest are called 'secondary'.
ohair@286 239
ohair@286 240 Currently we lack the proper infrastructure to handle those nicely.
ohair@286 241 For now, we rely on a hack.
ohair@286 242
ohair@286 243 We define secondary mappings first, then primary ones later. GrammarInfo
ohair@286 244 builds a map from type name to BeanInfo. By defining primary ones later,
ohair@286 245 those primary bindings will overwrite the secondary ones.
ohair@286 246 */
ohair@286 247
ohair@286 248 /*
ohair@286 249 secondary bindings
ohair@286 250 */
ohair@286 251 secondaryList.add(
ohair@286 252 new StringImpl<Character>(Character.class, createXS("unsignedShort")) {
ohair@286 253 public Character parse(CharSequence text) {
ohair@286 254 // TODO.checkSpec("default mapping for char is not defined yet");
ohair@286 255 return (char)DatatypeConverterImpl._parseInt(text);
ohair@286 256 }
ohair@286 257 public String print(Character v) {
ohair@286 258 return Integer.toString(v);
ohair@286 259 }
ohair@286 260 });
ohair@286 261 secondaryList.add(
ohair@286 262 new StringImpl<Calendar>(Calendar.class, DatatypeConstants.DATETIME) {
ohair@286 263 public Calendar parse(CharSequence text) {
ohair@286 264 return DatatypeConverterImpl._parseDateTime(text.toString());
ohair@286 265 }
ohair@286 266 public String print(Calendar v) {
ohair@286 267 return DatatypeConverterImpl._printDateTime(v);
ohair@286 268 }
ohair@286 269 });
ohair@286 270 secondaryList.add(
ohair@286 271 new StringImpl<GregorianCalendar>(GregorianCalendar.class, DatatypeConstants.DATETIME) {
ohair@286 272 public GregorianCalendar parse(CharSequence text) {
ohair@286 273 return DatatypeConverterImpl._parseDateTime(text.toString());
ohair@286 274 }
ohair@286 275 public String print(GregorianCalendar v) {
ohair@286 276 return DatatypeConverterImpl._printDateTime(v);
ohair@286 277 }
ohair@286 278 });
ohair@286 279 secondaryList.add(
ohair@286 280 new StringImpl<Date>(Date.class, DatatypeConstants.DATETIME) {
ohair@286 281 public Date parse(CharSequence text) {
ohair@286 282 return DatatypeConverterImpl._parseDateTime(text.toString()).getTime();
ohair@286 283 }
ohair@286 284 public String print(Date v) {
ohair@286 285 XMLSerializer xs = XMLSerializer.getInstance();
ohair@286 286 QName type = xs.getSchemaType();
ohair@286 287 GregorianCalendar cal = new GregorianCalendar(0,0,0);
ohair@286 288 cal.setTime(v);
ohair@286 289 if ((type != null) && (WellKnownNamespace.XML_SCHEMA.equals(type.getNamespaceURI())) &&
ohair@286 290 DATE.equals(type.getLocalPart())) {
ohair@286 291 return DatatypeConverterImpl._printDate(cal);
ohair@286 292 } else {
ohair@286 293 return DatatypeConverterImpl._printDateTime(cal);
ohair@286 294 }
ohair@286 295 }
ohair@286 296 });
ohair@286 297 secondaryList.add(
ohair@286 298 new StringImpl<File>(File.class, createXS("string")) {
ohair@286 299 public File parse(CharSequence text) {
ohair@286 300 return new File(WhiteSpaceProcessor.trim(text).toString());
ohair@286 301 }
ohair@286 302 public String print(File v) {
ohair@286 303 return v.getPath();
ohair@286 304 }
ohair@286 305 });
ohair@286 306 secondaryList.add(
ohair@286 307 new StringImpl<URL>(URL.class, createXS("anyURI")) {
ohair@286 308 public URL parse(CharSequence text) throws SAXException {
ohair@286 309 TODO.checkSpec("JSR222 Issue #42");
ohair@286 310 try {
ohair@286 311 return new URL(WhiteSpaceProcessor.trim(text).toString());
ohair@286 312 } catch (MalformedURLException e) {
ohair@286 313 UnmarshallingContext.getInstance().handleError(e);
ohair@286 314 return null;
ohair@286 315 }
ohair@286 316 }
ohair@286 317 public String print(URL v) {
ohair@286 318 return v.toExternalForm();
ohair@286 319 }
ohair@286 320 });
ohair@286 321 if (System.getProperty(MAP_ANYURI_TO_URI) == null) {
ohair@286 322 secondaryList.add(
ohair@286 323 new StringImpl<URI>(URI.class, createXS("string")) {
ohair@286 324 public URI parse(CharSequence text) throws SAXException {
ohair@286 325 try {
ohair@286 326 return new URI(text.toString());
ohair@286 327 } catch (URISyntaxException e) {
ohair@286 328 UnmarshallingContext.getInstance().handleError(e);
ohair@286 329 return null;
ohair@286 330 }
ohair@286 331 }
ohair@286 332
ohair@286 333 public String print(URI v) {
ohair@286 334 return v.toString();
ohair@286 335 }
ohair@286 336 });
ohair@286 337 }
ohair@286 338 secondaryList.add(
ohair@286 339 new StringImpl<Class>(Class.class, createXS("string")) {
ohair@286 340 public Class parse(CharSequence text) throws SAXException {
ohair@286 341 TODO.checkSpec("JSR222 Issue #42");
ohair@286 342 try {
ohair@286 343 String name = WhiteSpaceProcessor.trim(text).toString();
ohair@286 344 ClassLoader cl = UnmarshallingContext.getInstance().classLoader;
ohair@286 345 if(cl==null)
ohair@286 346 cl = Thread.currentThread().getContextClassLoader();
ohair@286 347
ohair@286 348 if(cl!=null)
ohair@286 349 return cl.loadClass(name);
ohair@286 350 else
ohair@286 351 return Class.forName(name);
ohair@286 352 } catch (ClassNotFoundException e) {
ohair@286 353 UnmarshallingContext.getInstance().handleError(e);
ohair@286 354 return null;
ohair@286 355 }
ohair@286 356 }
ohair@286 357 public String print(Class v) {
ohair@286 358 return v.getName();
ohair@286 359 }
ohair@286 360 });
ohair@286 361
ohair@286 362 /*
ohair@286 363 classes that map to base64Binary / MTOM related classes.
ohair@286 364 a part of the secondary binding.
ohair@286 365 */
ohair@286 366 secondaryList.add(
ohair@286 367 new PcdataImpl<Image>(Image.class, createXS("base64Binary")) {
ohair@286 368 public Image parse(CharSequence text) throws SAXException {
ohair@286 369 try {
ohair@286 370 InputStream is;
ohair@286 371 if(text instanceof Base64Data)
ohair@286 372 is = ((Base64Data)text).getInputStream();
ohair@286 373 else
ohair@286 374 is = new ByteArrayInputStream(decodeBase64(text)); // TODO: buffering is inefficient
ohair@286 375
ohair@286 376 // technically we should check the MIME type here, but
ohair@286 377 // normally images can be content-sniffed.
ohair@286 378 // so the MIME type check will only make us slower and draconian, both of which
ohair@286 379 // JAXB 2.0 isn't interested.
ohair@286 380 try {
ohair@286 381 return ImageIO.read(is);
ohair@286 382 } finally {
ohair@286 383 is.close();
ohair@286 384 }
ohair@286 385 } catch (IOException e) {
ohair@286 386 UnmarshallingContext.getInstance().handleError(e);
ohair@286 387 return null;
ohair@286 388 }
ohair@286 389 }
ohair@286 390
ohair@286 391 private BufferedImage convertToBufferedImage(Image image) throws IOException {
ohair@286 392 if (image instanceof BufferedImage) {
ohair@286 393 return (BufferedImage)image;
ohair@286 394
ohair@286 395 } else {
ohair@286 396 MediaTracker tracker = new MediaTracker(new Component(){}); // not sure if this is the right thing to do.
ohair@286 397 tracker.addImage(image, 0);
ohair@286 398 try {
ohair@286 399 tracker.waitForAll();
ohair@286 400 } catch (InterruptedException e) {
ohair@286 401 throw new IOException(e.getMessage());
ohair@286 402 }
ohair@286 403 BufferedImage bufImage = new BufferedImage(
ohair@286 404 image.getWidth(null),
ohair@286 405 image.getHeight(null),
ohair@286 406 BufferedImage.TYPE_INT_ARGB);
ohair@286 407
ohair@286 408 Graphics g = bufImage.createGraphics();
ohair@286 409 g.drawImage(image, 0, 0, null);
ohair@286 410 return bufImage;
ohair@286 411 }
ohair@286 412 }
ohair@286 413
ohair@286 414 public Base64Data print(Image v) {
ohair@286 415 ByteArrayOutputStreamEx imageData = new ByteArrayOutputStreamEx();
ohair@286 416 XMLSerializer xs = XMLSerializer.getInstance();
ohair@286 417
ohair@286 418 String mimeType = xs.getXMIMEContentType();
ohair@286 419 if(mimeType==null || mimeType.startsWith("image/*"))
ohair@286 420 // because PNG is lossless, it's a good default
ohair@286 421 //
ohair@286 422 // mime type can be a range, in which case we can't just pass that
ohair@286 423 // to ImageIO.getImageWritersByMIMEType, so here I'm just assuming
ohair@286 424 // the default of PNG. Not sure if this is complete.
ohair@286 425 mimeType = "image/png";
ohair@286 426
ohair@286 427 try {
ohair@286 428 Iterator<ImageWriter> itr = ImageIO.getImageWritersByMIMEType(mimeType);
ohair@286 429 if(itr.hasNext()) {
ohair@286 430 ImageWriter w = itr.next();
ohair@286 431 ImageOutputStream os = ImageIO.createImageOutputStream(imageData);
ohair@286 432 w.setOutput(os);
ohair@286 433 w.write(convertToBufferedImage(v));
ohair@286 434 os.close();
ohair@286 435 w.dispose();
ohair@286 436 } else {
ohair@286 437 // no encoder
ohair@286 438 xs.handleEvent(new ValidationEventImpl(
ohair@286 439 ValidationEvent.ERROR,
ohair@286 440 Messages.NO_IMAGE_WRITER.format(mimeType),
ohair@286 441 xs.getCurrentLocation(null) ));
ohair@286 442 // TODO: proper error reporting
ohair@286 443 throw new RuntimeException("no encoder for MIME type "+mimeType);
ohair@286 444 }
ohair@286 445 } catch (IOException e) {
ohair@286 446 xs.handleError(e);
ohair@286 447 // TODO: proper error reporting
ohair@286 448 throw new RuntimeException(e);
ohair@286 449 }
ohair@286 450 Base64Data bd = new Base64Data();
ohair@286 451 imageData.set(bd,mimeType);
ohair@286 452 return bd;
ohair@286 453 }
ohair@286 454 });
ohair@286 455 secondaryList.add(
ohair@286 456 new PcdataImpl<DataHandler>(DataHandler.class, createXS("base64Binary")) {
ohair@286 457 public DataHandler parse(CharSequence text) {
ohair@286 458 if(text instanceof Base64Data)
ohair@286 459 return ((Base64Data)text).getDataHandler();
ohair@286 460 else
ohair@286 461 return new DataHandler(new ByteArrayDataSource(decodeBase64(text),
ohair@286 462 UnmarshallingContext.getInstance().getXMIMEContentType()));
ohair@286 463 }
ohair@286 464
ohair@286 465 public Base64Data print(DataHandler v) {
ohair@286 466 Base64Data bd = new Base64Data();
ohair@286 467 bd.set(v);
ohair@286 468 return bd;
ohair@286 469 }
ohair@286 470 });
ohair@286 471 secondaryList.add(
ohair@286 472 new PcdataImpl<Source>(Source.class, createXS("base64Binary")) {
ohair@286 473 public Source parse(CharSequence text) throws SAXException {
ohair@286 474 try {
ohair@286 475 if(text instanceof Base64Data)
ohair@286 476 return new DataSourceSource( ((Base64Data)text).getDataHandler() );
ohair@286 477 else
ohair@286 478 return new DataSourceSource(new ByteArrayDataSource(decodeBase64(text),
ohair@286 479 UnmarshallingContext.getInstance().getXMIMEContentType()));
ohair@286 480 } catch (MimeTypeParseException e) {
ohair@286 481 UnmarshallingContext.getInstance().handleError(e);
ohair@286 482 return null;
ohair@286 483 }
ohair@286 484 }
ohair@286 485
ohair@286 486 public Base64Data print(Source v) {
ohair@286 487 XMLSerializer xs = XMLSerializer.getInstance();
ohair@286 488 Base64Data bd = new Base64Data();
ohair@286 489
ohair@286 490 String contentType = xs.getXMIMEContentType();
ohair@286 491 MimeType mt = null;
ohair@286 492 if(contentType!=null)
ohair@286 493 try {
ohair@286 494 mt = new MimeType(contentType);
ohair@286 495 } catch (MimeTypeParseException e) {
ohair@286 496 xs.handleError(e);
ohair@286 497 // recover by ignoring the content type specification
ohair@286 498 }
ohair@286 499
ohair@286 500 if( v instanceof DataSourceSource ) {
ohair@286 501 // if so, we already have immutable DataSource so
ohair@286 502 // this can be done efficiently
ohair@286 503 DataSource ds = ((DataSourceSource)v).getDataSource();
ohair@286 504
ohair@286 505 String dsct = ds.getContentType();
ohair@286 506 if(dsct!=null && (contentType==null || contentType.equals(dsct))) {
ohair@286 507 bd.set(new DataHandler(ds));
ohair@286 508 return bd;
ohair@286 509 }
ohair@286 510 }
ohair@286 511
ohair@286 512 // general case. slower.
ohair@286 513
ohair@286 514 // find out the encoding
ohair@286 515 String charset=null;
ohair@286 516 if(mt!=null)
ohair@286 517 charset = mt.getParameter("charset");
ohair@286 518 if(charset==null)
ohair@286 519 charset = "UTF-8";
ohair@286 520
ohair@286 521 try {
ohair@286 522 ByteArrayOutputStreamEx baos = new ByteArrayOutputStreamEx();
ohair@286 523 Transformer tr = xs.getIdentityTransformer();
ohair@286 524 String defaultEncoding = tr.getOutputProperty(OutputKeys.ENCODING);
ohair@286 525 tr.setOutputProperty(OutputKeys.ENCODING, charset);
ohair@286 526 tr.transform(v, new StreamResult(new OutputStreamWriter(baos,charset)));
ohair@286 527 tr.setOutputProperty(OutputKeys.ENCODING, defaultEncoding);
ohair@286 528 baos.set(bd,"application/xml; charset="+charset);
ohair@286 529 return bd;
ohair@286 530 } catch (TransformerException e) {
ohair@286 531 // TODO: marshaller error handling
ohair@286 532 xs.handleError(e);
ohair@286 533 } catch (UnsupportedEncodingException e) {
ohair@286 534 xs.handleError(e);
ohair@286 535 }
ohair@286 536
ohair@286 537 // error recoverly
ohair@286 538 bd.set(new byte[0],"application/xml");
ohair@286 539 return bd;
ohair@286 540 }
ohair@286 541 });
ohair@286 542 secondaryList.add(
ohair@286 543 new StringImpl<XMLGregorianCalendar>(XMLGregorianCalendar.class,
ohair@286 544 createXS("anySimpleType"),
ohair@286 545 DatatypeConstants.DATE,
ohair@286 546 DatatypeConstants.DATETIME,
ohair@286 547 DatatypeConstants.TIME,
ohair@286 548 DatatypeConstants.GMONTH,
ohair@286 549 DatatypeConstants.GDAY,
ohair@286 550 DatatypeConstants.GYEAR,
ohair@286 551 DatatypeConstants.GYEARMONTH,
ohair@286 552 DatatypeConstants.GMONTHDAY
ohair@286 553 ) {
ohair@286 554 public String print(XMLGregorianCalendar cal) {
ohair@286 555 XMLSerializer xs = XMLSerializer.getInstance();
ohair@286 556
ohair@286 557 QName type = xs.getSchemaType();
ohair@286 558 if (type != null) {
ohair@286 559 try {
ohair@286 560 checkXmlGregorianCalendarFieldRef(type, cal);
ohair@286 561 String format = xmlGregorianCalendarFormatString.get(type);
ohair@286 562 if (format != null) {
ohair@286 563 return format(format, cal);
ohair@286 564 }
ohair@286 565 } catch (javax.xml.bind.MarshalException e) {
ohair@286 566 // see issue 649
ohair@286 567 xs.handleEvent(new ValidationEventImpl(ValidationEvent.WARNING, e.getMessage(),
ohair@286 568 xs.getCurrentLocation(null) ));
ohair@286 569 return "";
ohair@286 570 }
ohair@286 571 }
ohair@286 572 return cal.toXMLFormat();
ohair@286 573 }
ohair@286 574
ohair@286 575 public XMLGregorianCalendar parse(CharSequence lexical) throws SAXException {
ohair@286 576 try {
ohair@286 577 return datatypeFactory.newXMLGregorianCalendar(lexical.toString().trim()); // (.trim() - issue 396)
ohair@286 578 } catch (Exception e) {
ohair@286 579 UnmarshallingContext.getInstance().handleError(e);
ohair@286 580 return null;
ohair@286 581 }
ohair@286 582 }
ohair@286 583
ohair@286 584 // code duplicated from JAXP RI 1.3. See 6277586
ohair@286 585 private String format( String format, XMLGregorianCalendar value ) {
ohair@286 586 StringBuilder buf = new StringBuilder();
ohair@286 587 int fidx=0,flen=format.length();
ohair@286 588
ohair@286 589 while(fidx<flen) {
ohair@286 590 char fch = format.charAt(fidx++);
ohair@286 591 if(fch!='%') {// not a meta char
ohair@286 592 buf.append(fch);
ohair@286 593 continue;
ohair@286 594 }
ohair@286 595
ohair@286 596 switch(format.charAt(fidx++)) {
ohair@286 597 case 'Y':
ohair@286 598 printNumber(buf,value.getEonAndYear(), 4);
ohair@286 599 break;
ohair@286 600 case 'M':
ohair@286 601 printNumber(buf,value.getMonth(),2);
ohair@286 602 break;
ohair@286 603 case 'D':
ohair@286 604 printNumber(buf,value.getDay(),2);
ohair@286 605 break;
ohair@286 606 case 'h':
ohair@286 607 printNumber(buf,value.getHour(),2);
ohair@286 608 break;
ohair@286 609 case 'm':
ohair@286 610 printNumber(buf,value.getMinute(),2);
ohair@286 611 break;
ohair@286 612 case 's':
ohair@286 613 printNumber(buf,value.getSecond(),2);
ohair@286 614 if (value.getFractionalSecond() != null) {
ohair@286 615 String frac = value.getFractionalSecond().toPlainString();
ohair@286 616 //skip leading zero.
ohair@286 617 buf.append(frac.substring(1, frac.length()));
ohair@286 618 }
ohair@286 619 break;
ohair@286 620 case 'z':
ohair@286 621 int offset = value.getTimezone();
ohair@286 622 if(offset == 0) {
ohair@286 623 buf.append('Z');
ohair@286 624 } else if (offset != DatatypeConstants.FIELD_UNDEFINED) {
ohair@286 625 if(offset<0) {
ohair@286 626 buf.append('-');
ohair@286 627 offset *= -1;
ohair@286 628 } else {
ohair@286 629 buf.append('+');
ohair@286 630 }
ohair@286 631 printNumber(buf,offset/60,2);
ohair@286 632 buf.append(':');
ohair@286 633 printNumber(buf,offset%60,2);
ohair@286 634 }
ohair@286 635 break;
ohair@286 636 default:
ohair@286 637 throw new InternalError(); // impossible
ohair@286 638 }
ohair@286 639 }
ohair@286 640
ohair@286 641 return buf.toString();
ohair@286 642 }
ohair@286 643 private void printNumber( StringBuilder out, BigInteger number, int nDigits) {
ohair@286 644 String s = number.toString();
ohair@286 645 for( int i=s.length(); i<nDigits; i++ )
ohair@286 646 out.append('0');
ohair@286 647 out.append(s);
ohair@286 648 }
ohair@286 649 private void printNumber( StringBuilder out, int number, int nDigits ) {
ohair@286 650 String s = String.valueOf(number);
ohair@286 651 for( int i=s.length(); i<nDigits; i++ )
ohair@286 652 out.append('0');
ohair@286 653 out.append(s);
ohair@286 654 }
ohair@286 655 @Override
ohair@286 656 public QName getTypeName(XMLGregorianCalendar cal) {
ohair@286 657 return cal.getXMLSchemaType();
ohair@286 658 }
ohair@286 659 });
ohair@286 660
ohair@286 661 ArrayList<RuntimeBuiltinLeafInfoImpl<?>> primaryList = new ArrayList<RuntimeBuiltinLeafInfoImpl<?>>();
ohair@286 662
ohair@286 663 /*
ohair@286 664 primary bindings
ohair@286 665 */
ohair@286 666 primaryList.add(STRING);
ohair@286 667 primaryList.add(new StringImpl<Boolean>(Boolean.class,
ohair@286 668 createXS("boolean")
ohair@286 669 ) {
ohair@286 670 public Boolean parse(CharSequence text) {
ohair@286 671 return DatatypeConverterImpl._parseBoolean(text);
ohair@286 672 }
ohair@286 673
ohair@286 674 public String print(Boolean v) {
ohair@286 675 return v.toString();
ohair@286 676 }
ohair@286 677 });
ohair@286 678 primaryList.add(new PcdataImpl<byte[]>(byte[].class,
ohair@286 679 createXS("base64Binary"),
ohair@286 680 createXS("hexBinary")
ohair@286 681 ) {
ohair@286 682 public byte[] parse(CharSequence text) {
ohair@286 683 return decodeBase64(text);
ohair@286 684 }
ohair@286 685
ohair@286 686 public Base64Data print(byte[] v) {
ohair@286 687 XMLSerializer w = XMLSerializer.getInstance();
ohair@286 688 Base64Data bd = new Base64Data();
ohair@286 689 String mimeType = w.getXMIMEContentType();
ohair@286 690 bd.set(v,mimeType);
ohair@286 691 return bd;
ohair@286 692 }
ohair@286 693 });
ohair@286 694 primaryList.add(new StringImpl<Byte>(Byte.class,
ohair@286 695 createXS("byte")
ohair@286 696 ) {
ohair@286 697 public Byte parse(CharSequence text) {
ohair@286 698 return DatatypeConverterImpl._parseByte(text);
ohair@286 699 }
ohair@286 700
ohair@286 701 public String print(Byte v) {
ohair@286 702 return DatatypeConverterImpl._printByte(v);
ohair@286 703 }
ohair@286 704 });
ohair@286 705 primaryList.add(new StringImpl<Short>(Short.class,
ohair@286 706 createXS("short"),
ohair@286 707 createXS("unsignedByte")
ohair@286 708 ) {
ohair@286 709 public Short parse(CharSequence text) {
ohair@286 710 return DatatypeConverterImpl._parseShort(text);
ohair@286 711 }
ohair@286 712
ohair@286 713 public String print(Short v) {
ohair@286 714 return DatatypeConverterImpl._printShort(v);
ohair@286 715 }
ohair@286 716 });
ohair@286 717 primaryList.add(new StringImpl<Integer>(Integer.class,
ohair@286 718 createXS("int"),
ohair@286 719 createXS("unsignedShort")
ohair@286 720 ) {
ohair@286 721 public Integer parse(CharSequence text) {
ohair@286 722 return DatatypeConverterImpl._parseInt(text);
ohair@286 723 }
ohair@286 724
ohair@286 725 public String print(Integer v) {
ohair@286 726 return DatatypeConverterImpl._printInt(v);
ohair@286 727 }
ohair@286 728 });
ohair@286 729 primaryList.add(
ohair@286 730 new StringImpl<Long>(Long.class,
ohair@286 731 createXS("long"),
ohair@286 732 createXS("unsignedInt")
ohair@286 733 ) {
ohair@286 734 public Long parse(CharSequence text) {
ohair@286 735 return DatatypeConverterImpl._parseLong(text);
ohair@286 736 }
ohair@286 737
ohair@286 738 public String print(Long v) {
ohair@286 739 return DatatypeConverterImpl._printLong(v);
ohair@286 740 }
ohair@286 741 });
ohair@286 742 primaryList.add(
ohair@286 743 new StringImpl<Float>(Float.class,
ohair@286 744 createXS("float")
ohair@286 745 ) {
ohair@286 746 public Float parse(CharSequence text) {
ohair@286 747 return DatatypeConverterImpl._parseFloat(text.toString());
ohair@286 748 }
ohair@286 749
ohair@286 750 public String print(Float v) {
ohair@286 751 return DatatypeConverterImpl._printFloat(v);
ohair@286 752 }
ohair@286 753 });
ohair@286 754 primaryList.add(
ohair@286 755 new StringImpl<Double>(Double.class,
ohair@286 756 createXS("double")
ohair@286 757 ) {
ohair@286 758 public Double parse(CharSequence text) {
ohair@286 759 return DatatypeConverterImpl._parseDouble(text);
ohair@286 760 }
ohair@286 761
ohair@286 762 public String print(Double v) {
ohair@286 763 return DatatypeConverterImpl._printDouble(v);
ohair@286 764 }
ohair@286 765 });
ohair@286 766 primaryList.add(
ohair@286 767 new StringImpl<BigInteger>(BigInteger.class,
ohair@286 768 createXS("integer"),
ohair@286 769 createXS("positiveInteger"),
ohair@286 770 createXS("negativeInteger"),
ohair@286 771 createXS("nonPositiveInteger"),
ohair@286 772 createXS("nonNegativeInteger"),
ohair@286 773 createXS("unsignedLong")
ohair@286 774 ) {
ohair@286 775 public BigInteger parse(CharSequence text) {
ohair@286 776 return DatatypeConverterImpl._parseInteger(text);
ohair@286 777 }
ohair@286 778
ohair@286 779 public String print(BigInteger v) {
ohair@286 780 return DatatypeConverterImpl._printInteger(v);
ohair@286 781 }
ohair@286 782 });
ohair@286 783 primaryList.add(
ohair@286 784 new StringImpl<BigDecimal>(BigDecimal.class,
ohair@286 785 createXS("decimal")
ohair@286 786 ) {
ohair@286 787 public BigDecimal parse(CharSequence text) {
ohair@286 788 return DatatypeConverterImpl._parseDecimal(text.toString());
ohair@286 789 }
ohair@286 790
ohair@286 791 public String print(BigDecimal v) {
ohair@286 792 return DatatypeConverterImpl._printDecimal(v);
ohair@286 793 }
ohair@286 794 });
ohair@286 795 primaryList.add(
ohair@286 796 new StringImpl<QName>(QName.class,
ohair@286 797 createXS("QName")
ohair@286 798 ) {
ohair@286 799 public QName parse(CharSequence text) throws SAXException {
ohair@286 800 try {
ohair@286 801 return DatatypeConverterImpl._parseQName(text.toString(),UnmarshallingContext.getInstance());
ohair@286 802 } catch (IllegalArgumentException e) {
ohair@286 803 UnmarshallingContext.getInstance().handleError(e);
ohair@286 804 return null;
ohair@286 805 }
ohair@286 806 }
ohair@286 807
ohair@286 808 public String print(QName v) {
ohair@286 809 return DatatypeConverterImpl._printQName(v,XMLSerializer.getInstance().getNamespaceContext());
ohair@286 810 }
ohair@286 811
ohair@286 812 @Override
ohair@286 813 public boolean useNamespace() {
ohair@286 814 return true;
ohair@286 815 }
ohair@286 816
ohair@286 817 @Override
ohair@286 818 public void declareNamespace(QName v, XMLSerializer w) {
ohair@286 819 w.getNamespaceContext().declareNamespace(v.getNamespaceURI(),v.getPrefix(),false);
ohair@286 820 }
ohair@286 821 });
ohair@286 822 if (System.getProperty(MAP_ANYURI_TO_URI) != null) {
ohair@286 823 primaryList.add(
ohair@286 824 new StringImpl<URI>(URI.class, createXS("anyURI")) {
ohair@286 825 public URI parse(CharSequence text) throws SAXException {
ohair@286 826 try {
ohair@286 827 return new URI(text.toString());
ohair@286 828 } catch (URISyntaxException e) {
ohair@286 829 UnmarshallingContext.getInstance().handleError(e);
ohair@286 830 return null;
ohair@286 831 }
ohair@286 832 }
ohair@286 833
ohair@286 834 public String print(URI v) {
ohair@286 835 return v.toString();
ohair@286 836 }
ohair@286 837 });
ohair@286 838 }
ohair@286 839 primaryList.add(
ohair@286 840 new StringImpl<Duration>(Duration.class, createXS("duration")) {
ohair@286 841 public String print(Duration duration) {
ohair@286 842 return duration.toString();
ohair@286 843 }
ohair@286 844
ohair@286 845 public Duration parse(CharSequence lexical) {
ohair@286 846 TODO.checkSpec("JSR222 Issue #42");
ohair@286 847 return datatypeFactory.newDuration(lexical.toString());
ohair@286 848 }
ohair@286 849 });
ohair@286 850 primaryList.add(
ohair@286 851 new StringImpl<Void>(Void.class) {
ohair@286 852 // 'void' binding isn't defined by the spec, but when the JAX-RPC processes user-defined
ohair@286 853 // methods like "int actionFoo()", they need this pseudo-void property.
ohair@286 854
ohair@286 855 public String print(Void value) {
ohair@286 856 return "";
ohair@286 857 }
ohair@286 858
ohair@286 859 public Void parse(CharSequence lexical) {
ohair@286 860 return null;
ohair@286 861 }
ohair@286 862 });
ohair@286 863
ohair@286 864 List<RuntimeBuiltinLeafInfoImpl<?>> l = new ArrayList<RuntimeBuiltinLeafInfoImpl<?>>(secondaryList.size()+primaryList.size()+1);
ohair@286 865 l.addAll(secondaryList);
ohair@286 866
ohair@286 867 // UUID may fail to load if we are running on JDK 1.4. Handle gracefully
ohair@286 868 try {
ohair@286 869 l.add(new UUIDImpl());
ohair@286 870 } catch (LinkageError e) {
ohair@286 871 // ignore
ohair@286 872 }
ohair@286 873
ohair@286 874 l.addAll(primaryList);
ohair@286 875
ohair@286 876 builtinBeanInfos = Collections.unmodifiableList(l);
ohair@286 877 }
ohair@286 878
ohair@286 879 private static byte[] decodeBase64(CharSequence text) {
ohair@286 880 if (text instanceof Base64Data) {
ohair@286 881 Base64Data base64Data = (Base64Data) text;
ohair@286 882 return base64Data.getExact();
ohair@286 883 } else {
ohair@286 884 return DatatypeConverterImpl._parseBase64Binary(text.toString());
ohair@286 885 }
ohair@286 886 }
ohair@286 887
ohair@286 888
ohair@286 889 /**
ohair@286 890 * Cached instance of {@link DatatypeFactory} to create
ohair@286 891 * {@link XMLGregorianCalendar} and {@link Duration}.
ohair@286 892 */
ohair@286 893 private static final DatatypeFactory datatypeFactory = init();
ohair@286 894
ohair@286 895 private static DatatypeFactory init() {
ohair@286 896 try {
ohair@286 897 return DatatypeFactory.newInstance();
ohair@286 898 } catch (DatatypeConfigurationException e) {
ohair@286 899 throw new Error(Messages.FAILED_TO_INITIALE_DATATYPE_FACTORY.format(),e);
ohair@286 900 }
ohair@286 901 }
ohair@286 902
ohair@286 903 private static void checkXmlGregorianCalendarFieldRef(QName type,
ohair@286 904 XMLGregorianCalendar cal)throws javax.xml.bind.MarshalException{
ohair@286 905 StringBuilder buf = new StringBuilder();
ohair@286 906 int bitField = xmlGregorianCalendarFieldRef.get(type);
ohair@286 907 final int l = 0x1;
ohair@286 908 int pos = 0;
ohair@286 909 while (bitField != 0x0){
ohair@286 910 int bit = bitField & l;
ohair@286 911 bitField >>>= 4;
ohair@286 912 pos++;
ohair@286 913
ohair@286 914 if (bit == 1) {
ohair@286 915 switch(pos){
ohair@286 916 case 1:
ohair@286 917 if (cal.getSecond() == DatatypeConstants.FIELD_UNDEFINED){
ohair@286 918 buf.append(" ").append(Messages.XMLGREGORIANCALENDAR_SEC);
ohair@286 919 }
ohair@286 920 break;
ohair@286 921 case 2:
ohair@286 922 if (cal.getMinute() == DatatypeConstants.FIELD_UNDEFINED){
ohair@286 923 buf.append(" ").append(Messages.XMLGREGORIANCALENDAR_MIN);
ohair@286 924 }
ohair@286 925 break;
ohair@286 926 case 3:
ohair@286 927 if (cal.getHour() == DatatypeConstants.FIELD_UNDEFINED){
ohair@286 928 buf.append(" ").append(Messages.XMLGREGORIANCALENDAR_HR);
ohair@286 929 }
ohair@286 930 break;
ohair@286 931 case 4:
ohair@286 932 if (cal.getDay() == DatatypeConstants.FIELD_UNDEFINED){
ohair@286 933 buf.append(" ").append(Messages.XMLGREGORIANCALENDAR_DAY);
ohair@286 934 }
ohair@286 935 break;
ohair@286 936 case 5:
ohair@286 937 if (cal.getMonth() == DatatypeConstants.FIELD_UNDEFINED){
ohair@286 938 buf.append(" ").append(Messages.XMLGREGORIANCALENDAR_MONTH);
ohair@286 939 }
ohair@286 940 break;
ohair@286 941 case 6:
ohair@286 942 if (cal.getYear() == DatatypeConstants.FIELD_UNDEFINED){
ohair@286 943 buf.append(" ").append(Messages.XMLGREGORIANCALENDAR_YEAR);
ohair@286 944 }
ohair@286 945 break;
ohair@286 946 case 7: // ignore timezone setting
ohair@286 947 break;
ohair@286 948 }
ohair@286 949 }
ohair@286 950 }
ohair@286 951 if (buf.length() > 0){
ohair@286 952 throw new javax.xml.bind.MarshalException(
ohair@286 953 Messages.XMLGREGORIANCALENDAR_INVALID.format(type.getLocalPart())
ohair@286 954 + buf.toString());
ohair@286 955 }
ohair@286 956 }
ohair@286 957
ohair@286 958 /**
ohair@286 959 * Format string for the {@link XMLGregorianCalendar}.
ohair@286 960 */
ohair@286 961 private static final Map<QName,String> xmlGregorianCalendarFormatString = new HashMap<QName, String>();
ohair@286 962
ohair@286 963 static {
ohair@286 964 Map<QName,String> m = xmlGregorianCalendarFormatString;
ohair@286 965 // See 4971612: be careful for SCCS substitution
ohair@286 966 m.put(DatatypeConstants.DATETIME, "%Y-%M-%DT%h:%m:%s"+ "%z");
ohair@286 967 m.put(DatatypeConstants.DATE, "%Y-%M-%D" +"%z");
ohair@286 968 m.put(DatatypeConstants.TIME, "%h:%m:%s"+ "%z");
mkos@397 969 if (System.getProperty(USE_OLD_GMONTH_MAPPING) == null) {
mkos@397 970 m.put(DatatypeConstants.GMONTH, "--%M%z"); // E2-12 Error. http://www.w3.org/2001/05/xmlschema-errata#e2-12
mkos@397 971 } else { // backw. compatibility
mkos@397 972 if (logger.isLoggable(Level.FINE)) {
mkos@397 973 logger.log(Level.FINE, "Old GMonth mapping used.");
mkos@397 974 }
mkos@397 975 m.put(DatatypeConstants.GMONTH, "--%M--%z");
mkos@397 976 }
ohair@286 977 m.put(DatatypeConstants.GDAY, "---%D" + "%z");
ohair@286 978 m.put(DatatypeConstants.GYEAR, "%Y" + "%z");
ohair@286 979 m.put(DatatypeConstants.GYEARMONTH, "%Y-%M" + "%z");
ohair@286 980 m.put(DatatypeConstants.GMONTHDAY, "--%M-%D" +"%z");
ohair@286 981 }
ohair@286 982
ohair@286 983 /**
ohair@286 984 * Field designations for XMLGregorianCalendar format string.
ohair@286 985 * sec 0x0000001
ohair@286 986 * min 0x0000010
ohair@286 987 * hrs 0x0000100
ohair@286 988 * day 0x0001000
ohair@286 989 * month 0x0010000
ohair@286 990 * year 0x0100000
ohair@286 991 * timezone 0x1000000
ohair@286 992 */
ohair@286 993 private static final Map<QName, Integer> xmlGregorianCalendarFieldRef =
ohair@286 994 new HashMap<QName, Integer>();
ohair@286 995 static {
ohair@286 996 Map<QName, Integer> f = xmlGregorianCalendarFieldRef;
ohair@286 997 f.put(DatatypeConstants.DATETIME, 0x1111111);
ohair@286 998 f.put(DatatypeConstants.DATE, 0x1111000);
ohair@286 999 f.put(DatatypeConstants.TIME, 0x1000111);
ohair@286 1000 f.put(DatatypeConstants.GDAY, 0x1001000);
ohair@286 1001 f.put(DatatypeConstants.GMONTH, 0x1010000);
ohair@286 1002 f.put(DatatypeConstants.GYEAR, 0x1100000);
ohair@286 1003 f.put(DatatypeConstants.GYEARMONTH, 0x1110000);
ohair@286 1004 f.put(DatatypeConstants.GMONTHDAY, 0x1011000);
ohair@286 1005 }
ohair@286 1006
ohair@286 1007 /**
ohair@286 1008 * {@link RuntimeBuiltinLeafInfoImpl} for {@link UUID}.
ohair@286 1009 *
ohair@286 1010 * This class is given a name so that failing to load this class won't cause a fatal problem.
ohair@286 1011 */
ohair@286 1012 private static class UUIDImpl extends StringImpl<UUID> {
ohair@286 1013 public UUIDImpl() {
ohair@286 1014 super(UUID.class, RuntimeBuiltinLeafInfoImpl.createXS("string"));
ohair@286 1015 }
ohair@286 1016
ohair@286 1017 public UUID parse(CharSequence text) throws SAXException {
ohair@286 1018 TODO.checkSpec("JSR222 Issue #42");
ohair@286 1019 try {
ohair@286 1020 return UUID.fromString(WhiteSpaceProcessor.trim(text).toString());
ohair@286 1021 } catch (IllegalArgumentException e) {
ohair@286 1022 UnmarshallingContext.getInstance().handleError(e);
ohair@286 1023 return null;
ohair@286 1024 }
ohair@286 1025 }
ohair@286 1026
ohair@286 1027 public String print(UUID v) {
ohair@286 1028 return v.toString();
ohair@286 1029 }
ohair@286 1030 }
ohair@286 1031
ohair@286 1032 private static class StringImplImpl extends StringImpl<String> {
ohair@286 1033
ohair@286 1034 public StringImplImpl(Class type, QName[] typeNames) {
ohair@286 1035 super(type, typeNames);
ohair@286 1036 }
ohair@286 1037
ohair@286 1038 public String parse(CharSequence text) {
ohair@286 1039 return text.toString();
ohair@286 1040 }
ohair@286 1041
ohair@286 1042 public String print(String s) {
ohair@286 1043 return s;
ohair@286 1044 }
ohair@286 1045
ohair@286 1046 @Override
ohair@286 1047 public final void writeText(XMLSerializer w, String o, String fieldName) throws IOException, SAXException, XMLStreamException {
ohair@286 1048 w.text(o, fieldName);
ohair@286 1049 }
ohair@286 1050
ohair@286 1051 @Override
ohair@286 1052 public final void writeLeafElement(XMLSerializer w, Name tagName, String o, String fieldName) throws IOException, SAXException, XMLStreamException {
ohair@286 1053 w.leafElement(tagName, o, fieldName);
ohair@286 1054 }
ohair@286 1055 }
ohair@286 1056 }

mercurial