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

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 514
29a761eaff0d
parent 0
373ffda63c9a
child 760
e530533619ec
permissions
-rw-r--r--

merge

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

mercurial