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

Fri, 24 Oct 2014 15:02:28 +0200

author
mkos
date
Fri, 24 Oct 2014 15:02:28 +0200
changeset 786
a14efa699f0f
parent 721
06807f9a6835
child 760
e530533619ec
permissions
-rw-r--r--

8054367: More references for endpoints
Summary: fix also reviewed by Iaroslav.Savytskyi@oracle.com, Alexander.Fomin@oracle.com
Reviewed-by: mullan, skoivu

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

mercurial