1
10
11 package com.sun.xml.bind.v2.model.impl;
12
13 import java.awt.Component;
14 import java.awt.Graphics;
15 import java.awt.Image;
16 import java.awt.MediaTracker;
17 import java.awt.image.BufferedImage;
18 import java.io.ByteArrayInputStream;
19 import java.io.File;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.OutputStreamWriter;
23 import java.io.UnsupportedEncodingException;
24 import java.lang.reflect.Type;
25 import java.math.BigDecimal;
26 import java.math.BigInteger;
27 import java.net.MalformedURLException;
28 import java.net.URI;
29 import java.net.URISyntaxException;
30 import java.net.URL;
31 import java.security.AccessController;
32 import java.security.PrivilegedAction;
33 import java.util.ArrayList;
34 import java.util.Calendar;
35 import java.util.Collections;
36 import java.util.Date;
37 import java.util.GregorianCalendar;
38 import java.util.HashMap;
39 import java.util.Iterator;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.UUID;
43
44 import javax.activation.DataHandler;
45 import javax.activation.DataSource;
46 import javax.activation.MimeType;
47 import javax.activation.MimeTypeParseException;
48 import javax.imageio.ImageIO;
49 import javax.imageio.ImageWriter;
50 import javax.imageio.stream.ImageOutputStream;
51 import javax.xml.bind.ValidationEvent;
52 import javax.xml.bind.helpers.ValidationEventImpl;
53 import javax.xml.datatype.DatatypeConstants;
54 import javax.xml.datatype.Duration;
55 import javax.xml.datatype.XMLGregorianCalendar;
56 import javax.xml.namespace.QName;
57 import javax.xml.stream.XMLStreamException;
58 import javax.xml.transform.OutputKeys;
59 import javax.xml.transform.Source;
60 import javax.xml.transform.Transformer;
61 import javax.xml.transform.TransformerException;
62 import javax.xml.transform.stream.StreamResult;
63
64 import com.sun.istack.ByteArrayDataSource;
65 import com.sun.xml.bind.DatatypeConverterImpl;
66 import com.sun.xml.bind.WhiteSpaceProcessor;
67 import com.sun.xml.bind.api.AccessorException;
68 import com.sun.xml.bind.v2.TODO;
69 import com.sun.xml.bind.v2.WellKnownNamespace;
70 import com.sun.xml.bind.v2.model.runtime.RuntimeBuiltinLeafInfo;
71 import com.sun.xml.bind.v2.runtime.Name;
72 import com.sun.xml.bind.v2.runtime.Transducer;
73 import com.sun.xml.bind.v2.runtime.XMLSerializer;
74 import com.sun.xml.bind.v2.runtime.output.Pcdata;
75 import com.sun.xml.bind.v2.runtime.unmarshaller.Base64Data;
76 import com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext;
77 import com.sun.xml.bind.v2.util.ByteArrayOutputStreamEx;
78 import com.sun.xml.bind.v2.util.DataSourceSource;
79 import java.util.logging.Logger;
80 import com.sun.xml.bind.Utils;
81 import java.util.logging.Level;
82
83 import org.xml.sax.SAXException;
84
85
93 public abstract class RuntimeBuiltinLeafInfoImpl<T> extends BuiltinLeafInfoImpl<Type,Class>
94 implements RuntimeBuiltinLeafInfo, Transducer<T> {
95
96 private static final Logger logger = Utils.getClassLogger();
97
98 private RuntimeBuiltinLeafInfoImpl(Class type, QName... typeNames) {
99 super(type, typeNames);
100 LEAVES.put(type,this);
101 }
102
103 public final Class getClazz() {
104 return (Class)getType();
105 }
106
107
108 public final Transducer getTransducer() {
109 return this;
110 }
111
112 public boolean useNamespace() {
113 return false;
114 }
115
116 public final boolean isDefault() {
117 return true;
118 }
119
120 public void declareNamespace(T o, XMLSerializer w) throws AccessorException {
121 }
122
123 public QName getTypeName(T instance) {
124 return null;
125 }
126
127
130 private static abstract class StringImpl<T> extends RuntimeBuiltinLeafInfoImpl<T> {
131 protected StringImpl(Class type, QName... typeNames) {
132 super(type,typeNames);
133 }
134
135 public abstract String print(T o) throws AccessorException;
136
137 public void writeText(XMLSerializer w, T o, String fieldName) throws IOException, SAXException, XMLStreamException, AccessorException {
138 w.text(print(o),fieldName);
139 }
140
141 public void writeLeafElement(XMLSerializer w, Name tagName, T o, String fieldName) throws IOException, SAXException, XMLStreamException, AccessorException {
142 w.leafElement(tagName,print(o),fieldName);
143 }
144 }
145
146
149 private static abstract class PcdataImpl<T> extends RuntimeBuiltinLeafInfoImpl<T> {
150 protected PcdataImpl(Class type, QName... typeNames) {
151 super(type,typeNames);
152 }
153
154 public abstract Pcdata print(T o) throws AccessorException;
155
156 public final void writeText(XMLSerializer w, T o, String fieldName) throws IOException, SAXException, XMLStreamException, AccessorException {
157 w.text(print(o),fieldName);
158 }
159
160 public final void writeLeafElement(XMLSerializer w, Name tagName, T o, String fieldName) throws IOException, SAXException, XMLStreamException, AccessorException {
161 w.leafElement(tagName,print(o),fieldName);
162 }
163
164 }
165
166
169 public static final Map<Type,RuntimeBuiltinLeafInfoImpl<?>> LEAVES = new HashMap<Type, RuntimeBuiltinLeafInfoImpl<?>>();
170
171 private static QName createXS(String typeName) {
172 return new QName(WellKnownNamespace.XML_SCHEMA,typeName);
173 }
174
175 public static final RuntimeBuiltinLeafInfoImpl<String> STRING;
176
177 private static final String DATE = "date";
178
179
186 public static final List<RuntimeBuiltinLeafInfoImpl<?>> builtinBeanInfos;
187
188 public static final String MAP_ANYURI_TO_URI = "mapAnyUriToUri";
189 public static final String USE_OLD_GMONTH_MAPPING = "jaxb.ri.useOldGmonthMapping";
190
191 static {
192
193 String MAP_ANYURI_TO_URI_VALUE = AccessController.doPrivileged(
194 new PrivilegedAction<String>() {
195 @Override
196 public String run() {
197 return System.getProperty(MAP_ANYURI_TO_URI);
198 }
199 }
200 );
201 QName[] qnames = (MAP_ANYURI_TO_URI_VALUE == null) ? new QName[] {
202 createXS("string"),
203 createXS("anySimpleType"),
204 createXS("normalizedString"),
205 createXS("anyURI"),
206 createXS("token"),
207 createXS("language"),
208 createXS("Name"),
209 createXS("NCName"),
210 createXS("NMTOKEN"),
211 createXS("ENTITY")}
212 :
213 new QName[] {
214 createXS("string"),
215 createXS("anySimpleType"),
216 createXS("normalizedString"),
217 createXS("token"),
218 createXS("language"),
219 createXS("Name"),
220 createXS("NCName"),
221 createXS("NMTOKEN"),
222 createXS("ENTITY")};
223
224 STRING = new StringImplImpl(String.class, qnames);
225
226 ArrayList<RuntimeBuiltinLeafInfoImpl<?>> secondaryList = new ArrayList<RuntimeBuiltinLeafInfoImpl<?>>();
227
240
241
244 secondaryList.add(
245 new StringImpl<Character>(Character.class, createXS("unsignedShort")) {
246 public Character parse(CharSequence text) {
247
248 return (char)DatatypeConverterImpl._parseInt(text);
249 }
250 public String print(Character v) {
251 return Integer.toString(v);
252 }
253 });
254 secondaryList.add(
255 new StringImpl<Calendar>(Calendar.class, DatatypeConstants.DATETIME) {
256 public Calendar parse(CharSequence text) {
257 return DatatypeConverterImpl._parseDateTime(text.toString());
258 }
259 public String print(Calendar v) {
260 return DatatypeConverterImpl._printDateTime(v);
261 }
262 });
263 secondaryList.add(
264 new StringImpl<GregorianCalendar>(GregorianCalendar.class, DatatypeConstants.DATETIME) {
265 public GregorianCalendar parse(CharSequence text) {
266 return DatatypeConverterImpl._parseDateTime(text.toString());
267 }
268 public String print(GregorianCalendar v) {
269 return DatatypeConverterImpl._printDateTime(v);
270 }
271 });
272 secondaryList.add(
273 new StringImpl<Date>(Date.class, DatatypeConstants.DATETIME) {
274 public Date parse(CharSequence text) {
275 return DatatypeConverterImpl._parseDateTime(text.toString()).getTime();
276 }
277 public String print(Date v) {
278 XMLSerializer xs = XMLSerializer.getInstance();
279 QName type = xs.getSchemaType();
280 GregorianCalendar cal = new GregorianCalendar(0,0,0);
281 cal.setTime(v);
282 if ((type != null) && (WellKnownNamespace.XML_SCHEMA.equals(type.getNamespaceURI())) &&
283 DATE.equals(type.getLocalPart())) {
284 return DatatypeConverterImpl._printDate(cal);
285 } else {
286 return DatatypeConverterImpl._printDateTime(cal);
287 }
288 }
289 });
290 secondaryList.add(
291 new StringImpl<File>(File.class, createXS("string")) {
292 public File parse(CharSequence text) {
293 return new File(WhiteSpaceProcessor.trim(text).toString());
294 }
295 public String print(File v) {
296 return v.getPath();
297 }
298 });
299 secondaryList.add(
300 new StringImpl<URL>(URL.class, createXS("anyURI")) {
301 public URL parse(CharSequence text) throws SAXException {
302 TODO.checkSpec("JSR222 Issue #42");
303 try {
304 return new URL(WhiteSpaceProcessor.trim(text).toString());
305 } catch (MalformedURLException e) {
306 UnmarshallingContext.getInstance().handleError(e);
307 return null;
308 }
309 }
310 public String print(URL v) {
311 return v.toExternalForm();
312 }
313 });
314 if (MAP_ANYURI_TO_URI_VALUE == null) {
315 secondaryList.add(
316 new StringImpl<URI>(URI.class, createXS("string")) {
317 public URI parse(CharSequence text) throws SAXException {
318 try {
319 return new URI(text.toString());
320 } catch (URISyntaxException e) {
321 UnmarshallingContext.getInstance().handleError(e);
322 return null;
323 }
324 }
325
326 public String print(URI v) {
327 return v.toString();
328 }
329 });
330 }
331 secondaryList.add(
332 new StringImpl<Class>(Class.class, createXS("string")) {
333 public Class parse(CharSequence text) throws SAXException {
334 TODO.checkSpec("JSR222 Issue #42");
335 try {
336 String name = WhiteSpaceProcessor.trim(text).toString();
337 ClassLoader cl = UnmarshallingContext.getInstance().classLoader;
338 if(cl==null)
339 cl = Thread.currentThread().getContextClassLoader();
340
341 if(cl!=null)
342 return cl.loadClass(name);
343 else
344 return Class.forName(name);
345 } catch (ClassNotFoundException e) {
346 UnmarshallingContext.getInstance().handleError(e);
347 return null;
348 }
349 }
350 public String print(Class v) {
351 return v.getName();
352 }
353 });
354
355
359 secondaryList.add(
360 new PcdataImpl<Image>(Image.class, createXS("base64Binary")) {
361 public Image parse(CharSequence text) throws SAXException {
362 try {
363 InputStream is;
364 if(text instanceof Base64Data)
365 is = ((Base64Data)text).getInputStream();
366 else
367 is = new ByteArrayInputStream(decodeBase64(text));
368
369
370
371
372
373 try {
374 return ImageIO.read(is);
375 } finally {
376 is.close();
377 }
378 } catch (IOException e) {
379 UnmarshallingContext.getInstance().handleError(e);
380 return null;
381 }
382 }
383
384 private BufferedImage convertToBufferedImage(Image image) throws IOException {
385 if (image instanceof BufferedImage) {
386 return (BufferedImage)image;
387
388 } else {
389 MediaTracker tracker = new MediaTracker(new Component(){});
390 tracker.addImage(image, 0);
391 try {
392 tracker.waitForAll();
393 } catch (InterruptedException e) {
394 throw new IOException(e.getMessage());
395 }
396 BufferedImage bufImage = new BufferedImage(
397 image.getWidth(null),
398 image.getHeight(null),
399 BufferedImage.TYPE_INT_ARGB);
400
401 Graphics g = bufImage.createGraphics();
402 g.drawImage(image, 0, 0, null);
403 return bufImage;
404 }
405 }
406
407 public Base64Data print(Image v) {
408 ByteArrayOutputStreamEx imageData = new ByteArrayOutputStreamEx();
409 XMLSerializer xs = XMLSerializer.getInstance();
410
411 String mimeType = xs.getXMIMEContentType();
412 if(mimeType==null || mimeType.startsWith("image))
413
414
415
416
417
418 mimeType = "image/png";
419
420 try {
421 Iterator<ImageWriter> itr = ImageIO.getImageWritersByMIMEType(mimeType);
422 if(itr.hasNext()) {
423 ImageWriter w = itr.next();
424 ImageOutputStream os = ImageIO.createImageOutputStream(imageData);
425 w.setOutput(os);
426 w.write(convertToBufferedImage(v));
427 os.close();
428 w.dispose();
429 } else {
430
431 xs.handleEvent(new ValidationEventImpl(
432 ValidationEvent.ERROR,
433 Messages.NO_IMAGE_WRITER.format(mimeType),
434 xs.getCurrentLocation(null) ));
435
436 throw new RuntimeException("no encoder for MIME type "+mimeType);
437 }
438 } catch (IOException e) {
439 xs.handleError(e);
440
441 throw new RuntimeException(e);
442 }
443 Base64Data bd = new Base64Data();
444 imageData.set(bd,mimeType);
445 return bd;
446 }
447 });
448 secondaryList.add(
449 new PcdataImpl<DataHandler>(DataHandler.class, createXS("base64Binary")) {
450 public DataHandler parse(CharSequence text) {
451 if(text instanceof Base64Data)
452 return ((Base64Data)text).getDataHandler();
453 else
454 return new DataHandler(new ByteArrayDataSource(decodeBase64(text),
455 UnmarshallingContext.getInstance().getXMIMEContentType()));
456 }
457
458 public Base64Data print(DataHandler v) {
459 Base64Data bd = new Base64Data();
460 bd.set(v);
461 return bd;
462 }
463 });
464 secondaryList.add(
465 new PcdataImpl<Source>(Source.class, createXS("base64Binary")) {
466 public Source parse(CharSequence text) throws SAXException {
467 try {
468 if(text instanceof Base64Data)
469 return new DataSourceSource( ((Base64Data)text).getDataHandler() );
470 else
471 return new DataSourceSource(new ByteArrayDataSource(decodeBase64(text),
472 UnmarshallingContext.getInstance().getXMIMEContentType()));
473 } catch (MimeTypeParseException e) {
474 UnmarshallingContext.getInstance().handleError(e);
475 return null;
476 }
477 }
478
479 public Base64Data print(Source v) {
480 XMLSerializer xs = XMLSerializer.getInstance();
481 Base64Data bd = new Base64Data();
482
483 String contentType = xs.getXMIMEContentType();
484 MimeType mt = null;
485 if(contentType!=null)
486 try {
487 mt = new MimeType(contentType);
488 } catch (MimeTypeParseException e) {
489 xs.handleError(e);
490
491 }
492
493 if( v instanceof DataSourceSource ) {
494
495
496 DataSource ds = ((DataSourceSource)v).getDataSource();
497
498 String dsct = ds.getContentType();
499 if(dsct!=null && (contentType==null || contentType.equals(dsct))) {
500 bd.set(new DataHandler(ds));
501 return bd;
502 }
503 }
504
505
506
507
508 String charset=null;
509 if(mt!=null)
510 charset = mt.getParameter("charset");
511 if(charset==null)
512 charset = "UTF-8";
513
514 try {
515 ByteArrayOutputStreamEx baos = new ByteArrayOutputStreamEx();
516 Transformer tr = xs.getIdentityTransformer();
517 String defaultEncoding = tr.getOutputProperty(OutputKeys.ENCODING);
518 tr.setOutputProperty(OutputKeys.ENCODING, charset);
519 tr.transform(v, new StreamResult(new OutputStreamWriter(baos,charset)));
520 tr.setOutputProperty(OutputKeys.ENCODING, defaultEncoding);
521 baos.set(bd,"application/xml; charset="+charset);
522 return bd;
523 } catch (TransformerException e) {
524
525 xs.handleError(e);
526 } catch (UnsupportedEncodingException e) {
527 xs.handleError(e);
528 }
529
530
531 bd.set(new byte[0],"application/xml");
532 return bd;
533 }
534 });
535 secondaryList.add(
536 new StringImpl<XMLGregorianCalendar>(XMLGregorianCalendar.class,
537 createXS("anySimpleType"),
538 DatatypeConstants.DATE,
539 DatatypeConstants.DATETIME,
540 DatatypeConstants.TIME,
541 DatatypeConstants.GMONTH,
542 DatatypeConstants.GDAY,
543 DatatypeConstants.GYEAR,
544 DatatypeConstants.GYEARMONTH,
545 DatatypeConstants.GMONTHDAY
546 ) {
547 public String print(XMLGregorianCalendar cal) {
548 XMLSerializer xs = XMLSerializer.getInstance();
549
550 QName type = xs.getSchemaType();
551 if (type != null) {
552 try {
553 checkXmlGregorianCalendarFieldRef(type, cal);
554 String format = xmlGregorianCalendarFormatString.get(type);
555 if (format != null) {
556 return format(format, cal);
557 }
558 } catch (javax.xml.bind.MarshalException e) {
559
560 xs.handleEvent(new ValidationEventImpl(ValidationEvent.WARNING, e.getMessage(),
561 xs.getCurrentLocation(null) ));
562 return "";
563 }
564 }
565 return cal.toXMLFormat();
566 }
567
568 public XMLGregorianCalendar parse(CharSequence lexical) throws SAXException {
569 try {
570 return DatatypeConverterImpl.getDatatypeFactory()
571 .newXMLGregorianCalendar(lexical.toString().trim());
572 } catch (Exception e) {
573 UnmarshallingContext.getInstance().handleError(e);
574 return null;
575 }
576 }
577
578
579 private String format( String format, XMLGregorianCalendar value ) {
580 StringBuilder buf = new StringBuilder();
581 int fidx=0,flen=format.length();
582
583 while(fidx<flen) {
584 char fch = format.charAt(fidx++);
585 if(fch!='%') {
586 buf.append(fch);
587 continue;
588 }
589
590 switch(format.charAt(fidx++)) {
591 case 'Y':
592 printNumber(buf,value.getEonAndYear(), 4);
593 break;
594 case 'M':
595 printNumber(buf,value.getMonth(),2);
596 break;
597 case 'D':
598 printNumber(buf,value.getDay(),2);
599 break;
600 case 'h':
601 printNumber(buf,value.getHour(),2);
602 break;
603 case 'm':
604 printNumber(buf,value.getMinute(),2);
605 break;
606 case 's':
607 printNumber(buf,value.getSecond(),2);
608 if (value.getFractionalSecond() != null) {
609 String frac = value.getFractionalSecond().toPlainString();
610
611 buf.append(frac.substring(1, frac.length()));
612 }
613 break;
614 case 'z':
615 int offset = value.getTimezone();
616 if(offset == 0) {
617 buf.append('Z');
618 } else if (offset != DatatypeConstants.FIELD_UNDEFINED) {
619 if(offset<0) {
620 buf.append('-');
621 offset *= -1;
622 } else {
623 buf.append('+');
624 }
625 printNumber(buf,offset/60,2);
626 buf.append(':');
627 printNumber(buf,offset%60,2);
628 }
629 break;
630 default:
631 throw new InternalError();
632 }
633 }
634
635 return buf.toString();
636 }
637 private void printNumber( StringBuilder out, BigInteger number, int nDigits) {
638 String s = number.toString();
639 for( int i=s.length(); i<nDigits; i++ )
640 out.append('0');
641 out.append(s);
642 }
643 private void printNumber( StringBuilder out, int number, int nDigits ) {
644 String s = String.valueOf(number);
645 for( int i=s.length(); i<nDigits; i++ )
646 out.append('0');
647 out.append(s);
648 }
649 @Override
650 public QName getTypeName(XMLGregorianCalendar cal) {
651 return cal.getXMLSchemaType();
652 }
653 });
654
655 ArrayList<RuntimeBuiltinLeafInfoImpl<?>> primaryList = new ArrayList<RuntimeBuiltinLeafInfoImpl<?>>();
656
657 /*
658 primary bindings
659 */
660 primaryList.add(STRING);
661 primaryList.add(new StringImpl<Boolean>(Boolean.class,
662 createXS("boolean")
663 ) {
664 public Boolean parse(CharSequence text) {
665 return DatatypeConverterImpl._parseBoolean(text);
666 }
667
668 public String print(Boolean v) {
669 return v.toString();
670 }
671 });
672 primaryList.add(new PcdataImpl<byte[]>(byte[].class,
673 createXS("base64Binary"),
674 createXS("hexBinary")
675 ) {
676 public byte[] parse(CharSequence text) {
677 return decodeBase64(text);
678 }
679
680 public Base64Data print(byte[] v) {
681 XMLSerializer w = XMLSerializer.getInstance();
682 Base64Data bd = new Base64Data();
683 String mimeType = w.getXMIMEContentType();
684 bd.set(v,mimeType);
685 return bd;
686 }
687 });
688 primaryList.add(new StringImpl<Byte>(Byte.class,
689 createXS("byte")
690 ) {
691 public Byte parse(CharSequence text) {
692 return DatatypeConverterImpl._parseByte(text);
693 }
694
695 public String print(Byte v) {
696 return DatatypeConverterImpl._printByte(v);
697 }
698 });
699 primaryList.add(new StringImpl<Short>(Short.class,
700 createXS("short"),
701 createXS("unsignedByte")
702 ) {
703 public Short parse(CharSequence text) {
704 return DatatypeConverterImpl._parseShort(text);
705 }
706
707 public String print(Short v) {
708 return DatatypeConverterImpl._printShort(v);
709 }
710 });
711 primaryList.add(new StringImpl<Integer>(Integer.class,
712 createXS("int"),
713 createXS("unsignedShort")
714 ) {
715 public Integer parse(CharSequence text) {
716 return DatatypeConverterImpl._parseInt(text);
717 }
718
719 public String print(Integer v) {
720 return DatatypeConverterImpl._printInt(v);
721 }
722 });
723 primaryList.add(
724 new StringImpl<Long>(Long.class,
725 createXS("long"),
726 createXS("unsignedInt")
727 ) {
728 public Long parse(CharSequence text) {
729 return DatatypeConverterImpl._parseLong(text);
730 }
731
732 public String print(Long v) {
733 return DatatypeConverterImpl._printLong(v);
734 }
735 });
736 primaryList.add(
737 new StringImpl<Float>(Float.class,
738 createXS("float")
739 ) {
740 public Float parse(CharSequence text) {
741 return DatatypeConverterImpl._parseFloat(text.toString());
742 }
743
744 public String print(Float v) {
745 return DatatypeConverterImpl._printFloat(v);
746 }
747 });
748 primaryList.add(
749 new StringImpl<Double>(Double.class,
750 createXS("double")
751 ) {
752 public Double parse(CharSequence text) {
753 return DatatypeConverterImpl._parseDouble(text);
754 }
755
756 public String print(Double v) {
757 return DatatypeConverterImpl._printDouble(v);
758 }
759 });
760 primaryList.add(
761 new StringImpl<BigInteger>(BigInteger.class,
762 createXS("integer"),
763 createXS("positiveInteger"),
764 createXS("negativeInteger"),
765 createXS("nonPositiveInteger"),
766 createXS("nonNegativeInteger"),
767 createXS("unsignedLong")
768 ) {
769 public BigInteger parse(CharSequence text) {
770 return DatatypeConverterImpl._parseInteger(text);
771 }
772
773 public String print(BigInteger v) {
774 return DatatypeConverterImpl._printInteger(v);
775 }
776 });
777 primaryList.add(
778 new StringImpl<BigDecimal>(BigDecimal.class,
779 createXS("decimal")
780 ) {
781 public BigDecimal parse(CharSequence text) {
782 return DatatypeConverterImpl._parseDecimal(text.toString());
783 }
784
785 public String print(BigDecimal v) {
786 return DatatypeConverterImpl._printDecimal(v);
787 }
788 }
789 );
790 primaryList.add(
791 new StringImpl<QName>(QName.class,
792 createXS("QName")
793 ) {
794 public QName parse(CharSequence text) throws SAXException {
795 try {
796 return DatatypeConverterImpl._parseQName(text.toString(),UnmarshallingContext.getInstance());
797 } catch (IllegalArgumentException e) {
798 UnmarshallingContext.getInstance().handleError(e);
799 return null;
800 }
801 }
802
803 public String print(QName v) {
804 return DatatypeConverterImpl._printQName(v,XMLSerializer.getInstance().getNamespaceContext());
805 }
806
807 @Override
808 public boolean useNamespace() {
809 return true;
810 }
811
812 @Override
813 public void declareNamespace(QName v, XMLSerializer w) {
814 w.getNamespaceContext().declareNamespace(v.getNamespaceURI(),v.getPrefix(),false);
815 }
816 });
817 if (MAP_ANYURI_TO_URI_VALUE != null) {
818 primaryList.add(
819 new StringImpl<URI>(URI.class, createXS("anyURI")) {
820 public URI parse(CharSequence text) throws SAXException {
821 try {
822 return new URI(text.toString());
823 } catch (URISyntaxException e) {
824 UnmarshallingContext.getInstance().handleError(e);
825 return null;
826 }
827 }
828
829 public String print(URI v) {
830 return v.toString();
831 }
832 });
833 }
834 primaryList.add(
835 new StringImpl<Duration>(Duration.class, createXS("duration")) {
836 public String print(Duration duration) {
837 return duration.toString();
838 }
839
840 public Duration parse(CharSequence lexical) {
841 TODO.checkSpec("JSR222 Issue #42");
842 return DatatypeConverterImpl.getDatatypeFactory().newDuration(lexical.toString());
843 }
844 }
845 );
846 primaryList.add(
847 new StringImpl<Void>(Void.class) {
848
849
850
851 public String print(Void value) {
852 return "";
853 }
854
855 public Void parse(CharSequence lexical) {
856 return null;
857 }
858 });
859
860 List<RuntimeBuiltinLeafInfoImpl<?>> l = new ArrayList<RuntimeBuiltinLeafInfoImpl<?>>(secondaryList.size()+primaryList.size()+1);
861 l.addAll(secondaryList);
862
863
864 try {
865 l.add(new UUIDImpl());
866 } catch (LinkageError e) {
867
868 }
869
870 l.addAll(primaryList);
871
872 builtinBeanInfos = Collections.unmodifiableList(l);
873 }
874
875 private static byte[] decodeBase64(CharSequence text) {
876 if (text instanceof Base64Data) {
877 Base64Data base64Data = (Base64Data) text;
878 return base64Data.getExact();
879 } else {
880 return DatatypeConverterImpl._parseBase64Binary(text.toString());
881 }
882 }
883
884 private static void checkXmlGregorianCalendarFieldRef(QName type,
885 XMLGregorianCalendar cal)throws javax.xml.bind.MarshalException{
886 StringBuilder buf = new StringBuilder();
887 int bitField = xmlGregorianCalendarFieldRef.get(type);
888 final int l = 0x1;
889 int pos = 0;
890 while (bitField != 0x0){
891 int bit = bitField & l;
892 bitField >>>= 4;
893 pos++;
894
895 if (bit == 1) {
896 switch(pos){
897 case 1:
898 if (cal.getSecond() == DatatypeConstants.FIELD_UNDEFINED){
899 buf.append(" ").append(Messages.XMLGREGORIANCALENDAR_SEC);
900 }
901 break;
902 case 2:
903 if (cal.getMinute() == DatatypeConstants.FIELD_UNDEFINED){
904 buf.append(" ").append(Messages.XMLGREGORIANCALENDAR_MIN);
905 }
906 break;
907 case 3:
908 if (cal.getHour() == DatatypeConstants.FIELD_UNDEFINED){
909 buf.append(" ").append(Messages.XMLGREGORIANCALENDAR_HR);
910 }
911 break;
912 case 4:
913 if (cal.getDay() == DatatypeConstants.FIELD_UNDEFINED){
914 buf.append(" ").append(Messages.XMLGREGORIANCALENDAR_DAY);
915 }
916 break;
917 case 5:
918 if (cal.getMonth() == DatatypeConstants.FIELD_UNDEFINED){
919 buf.append(" ").append(Messages.XMLGREGORIANCALENDAR_MONTH);
920 }
921 break;
922 case 6:
923 if (cal.getYear() == DatatypeConstants.FIELD_UNDEFINED){
924 buf.append(" ").append(Messages.XMLGREGORIANCALENDAR_YEAR);
925 }
926 break;
927 case 7:
928 break;
929 }
930 }
931 }
932 if (buf.length() > 0){
933 throw new javax.xml.bind.MarshalException(
934 Messages.XMLGREGORIANCALENDAR_INVALID.format(type.getLocalPart())
935 + buf.toString());
936 }
937 }
938
939
942 private static final Map<QName,String> xmlGregorianCalendarFormatString = new HashMap<QName, String>();
943
944 static {
945 Map<QName,String> m = xmlGregorianCalendarFormatString;
946
947 m.put(DatatypeConstants.DATETIME, "%Y-%M-%DT%h:%m:%s"+ "%z");
948 m.put(DatatypeConstants.DATE, "%Y-%M-%D" +"%z");
949 m.put(DatatypeConstants.TIME, "%h:%m:%s"+ "%z");
950 final String oldGmonthMappingProperty = AccessController.doPrivileged(new PrivilegedAction<String>() {
951 @Override
952 public String run() {
953 return System.getProperty(USE_OLD_GMONTH_MAPPING);
954 }
955 });
956 if (oldGmonthMappingProperty == null) {
957 m.put(DatatypeConstants.GMONTH, "--%M%z");
958 } else {
959 if (logger.isLoggable(Level.FINE)) {
960 logger.log(Level.FINE, "Old GMonth mapping used.");
961 }
962 m.put(DatatypeConstants.GMONTH, "--%M--%z");
963 }
964 m.put(DatatypeConstants.GDAY, "---%D" + "%z");
965 m.put(DatatypeConstants.GYEAR, "%Y" + "%z");
966 m.put(DatatypeConstants.GYEARMONTH, "%Y-%M" + "%z");
967 m.put(DatatypeConstants.GMONTHDAY, "--%M-%D" +"%z");
968 }
969
970
980 private static final Map<QName, Integer> xmlGregorianCalendarFieldRef =
981 new HashMap<QName, Integer>();
982 static {
983 Map<QName, Integer> f = xmlGregorianCalendarFieldRef;
984 f.put(DatatypeConstants.DATETIME, 0x1111111);
985 f.put(DatatypeConstants.DATE, 0x1111000);
986 f.put(DatatypeConstants.TIME, 0x1000111);
987 f.put(DatatypeConstants.GDAY, 0x1001000);
988 f.put(DatatypeConstants.GMONTH, 0x1010000);
989 f.put(DatatypeConstants.GYEAR, 0x1100000);
990 f.put(DatatypeConstants.GYEARMONTH, 0x1110000);
991 f.put(DatatypeConstants.GMONTHDAY, 0x1011000);
992 }
993
994
999 private static class UUIDImpl extends StringImpl<UUID> {
1000 public UUIDImpl() {
1001 super(UUID.class, RuntimeBuiltinLeafInfoImpl.createXS("string"));
1002 }
1003
1004 public UUID parse(CharSequence text) throws SAXException {
1005 TODO.checkSpec("JSR222 Issue #42");
1006 try {
1007 return UUID.fromString(WhiteSpaceProcessor.trim(text).toString());
1008 } catch (IllegalArgumentException e) {
1009 UnmarshallingContext.getInstance().handleError(e);
1010 return null;
1011 }
1012 }
1013
1014 public String print(UUID v) {
1015 return v.toString();
1016 }
1017 }
1018
1019 private static class StringImplImpl extends StringImpl<String> {
1020
1021 public StringImplImpl(Class type, QName[] typeNames) {
1022 super(type, typeNames);
1023 }
1024
1025 public String parse(CharSequence text) {
1026 return text.toString();
1027 }
1028
1029 public String print(String s) {
1030 return s;
1031 }
1032
1033 @Override
1034 public final void writeText(XMLSerializer w, String o, String fieldName) throws IOException, SAXException, XMLStreamException {
1035 w.text(o, fieldName);
1036 }
1037
1038 @Override
1039 public final void writeLeafElement(XMLSerializer w, Name tagName, String o, String fieldName) throws IOException, SAXException, XMLStreamException {
1040 w.leafElement(tagName, o, fieldName);
1041 }
1042 }
1043 }
1044