Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jaxws/src/share/jaxws_classes/javax/xml/bind/JAXB.java
38890 views
1
/*
2
* Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package javax.xml.bind;
27
28
import javax.xml.bind.annotation.XmlRootElement;
29
import javax.xml.namespace.QName;
30
import javax.xml.transform.Result;
31
import javax.xml.transform.Source;
32
import javax.xml.transform.stream.StreamResult;
33
import javax.xml.transform.stream.StreamSource;
34
import java.beans.Introspector;
35
import java.io.File;
36
import java.io.IOException;
37
import java.io.InputStream;
38
import java.io.OutputStream;
39
import java.io.Reader;
40
import java.io.Writer;
41
import java.lang.ref.WeakReference;
42
import java.net.HttpURLConnection;
43
import java.net.URI;
44
import java.net.URISyntaxException;
45
import java.net.URL;
46
import java.net.URLConnection;
47
48
/**
49
* Class that defines convenience methods for common, simple use of JAXB.
50
*
51
* <p>
52
* Methods defined in this class are convenience methods that combine several basic operations
53
* in the {@link JAXBContext}, {@link Unmarshaller}, and {@link Marshaller}.
54
*
55
* They are designed
56
* to be the prefered methods for developers new to JAXB. They have
57
* the following characterstics:
58
*
59
* <ol>
60
* <li>Generally speaking, the performance is not necessarily optimal.
61
* It is expected that people who need to write performance
62
* critical code will use the rest of the JAXB API directly.
63
* <li>Errors that happen during the processing is wrapped into
64
* {@link DataBindingException} (which will have {@link JAXBException}
65
* as its {@link Throwable#getCause() cause}. It is expected that
66
* people who prefer the checked exception would use
67
* the rest of the JAXB API directly.
68
* </ol>
69
*
70
* <p>
71
* In addition, the <tt>unmarshal</tt> methods have the following characteristic:
72
*
73
* <ol>
74
* <li>Schema validation is not performed on the input XML.
75
* The processing will try to continue even if there
76
* are errors in the XML, as much as possible. Only as
77
* the last resort, this method fails with {@link DataBindingException}.
78
* </ol>
79
*
80
* <p>
81
* Similarly, the <tt>marshal</tt> methods have the following characteristic:
82
* <ol>
83
* <li>The processing will try to continue even if the Java object tree
84
* does not meet the validity requirement. Only as
85
* the last resort, this method fails with {@link DataBindingException}.
86
* </ol>
87
*
88
*
89
* <p>
90
* All the methods on this class require non-null arguments to all parameters.
91
* The <tt>unmarshal</tt> methods either fail with an exception or return
92
* a non-null value.
93
*
94
* @author Kohsuke Kawaguchi
95
* @since 2.1
96
*/
97
public final class JAXB {
98
/**
99
* No instanciation is allowed.
100
*/
101
private JAXB() {}
102
103
/**
104
* To improve the performance, we'll cache the last {@link JAXBContext} used.
105
*/
106
private static final class Cache {
107
final Class type;
108
final JAXBContext context;
109
110
public Cache(Class type) throws JAXBException {
111
this.type = type;
112
this.context = JAXBContext.newInstance(type);
113
}
114
}
115
116
/**
117
* Cache. We don't want to prevent the {@link Cache#type} from GC-ed,
118
* hence {@link WeakReference}.
119
*/
120
private static volatile WeakReference<Cache> cache;
121
122
/**
123
* Obtains the {@link JAXBContext} from the given type,
124
* by using the cache if possible.
125
*
126
* <p>
127
* We don't use locks to control access to {@link #cache}, but this code
128
* should be thread-safe thanks to the immutable {@link Cache} and {@code volatile}.
129
*/
130
private static <T> JAXBContext getContext(Class<T> type) throws JAXBException {
131
WeakReference<Cache> c = cache;
132
if(c!=null) {
133
Cache d = c.get();
134
if(d!=null && d.type==type)
135
return d.context;
136
}
137
138
// overwrite the cache
139
Cache d = new Cache(type);
140
cache = new WeakReference<Cache>(d);
141
142
return d.context;
143
}
144
145
/**
146
* Reads in a Java object tree from the given XML input.
147
*
148
* @param xml
149
* Reads the entire file as XML.
150
*/
151
public static <T> T unmarshal( File xml, Class<T> type ) {
152
try {
153
JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(new StreamSource(xml), type);
154
return item.getValue();
155
} catch (JAXBException e) {
156
throw new DataBindingException(e);
157
}
158
}
159
160
/**
161
* Reads in a Java object tree from the given XML input.
162
*
163
* @param xml
164
* The resource pointed by the URL is read in its entirety.
165
*/
166
public static <T> T unmarshal( URL xml, Class<T> type ) {
167
try {
168
JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(toSource(xml), type);
169
return item.getValue();
170
} catch (JAXBException e) {
171
throw new DataBindingException(e);
172
} catch (IOException e) {
173
throw new DataBindingException(e);
174
}
175
}
176
177
/**
178
* Reads in a Java object tree from the given XML input.
179
*
180
* @param xml
181
* The URI is {@link URI#toURL() turned into URL} and then
182
* follows the handling of <tt>URL</tt>.
183
*/
184
public static <T> T unmarshal( URI xml, Class<T> type ) {
185
try {
186
JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(toSource(xml), type);
187
return item.getValue();
188
} catch (JAXBException e) {
189
throw new DataBindingException(e);
190
} catch (IOException e) {
191
throw new DataBindingException(e);
192
}
193
}
194
195
/**
196
* Reads in a Java object tree from the given XML input.
197
*
198
* @param xml
199
* The string is first interpreted as an absolute <tt>URI</tt>.
200
* If it's not {@link URI#isAbsolute() a valid absolute URI},
201
* then it's interpreted as a <tt>File</tt>
202
*/
203
public static <T> T unmarshal( String xml, Class<T> type ) {
204
try {
205
JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(toSource(xml), type);
206
return item.getValue();
207
} catch (JAXBException e) {
208
throw new DataBindingException(e);
209
} catch (IOException e) {
210
throw new DataBindingException(e);
211
}
212
}
213
214
/**
215
* Reads in a Java object tree from the given XML input.
216
*
217
* @param xml
218
* The entire stream is read as an XML infoset.
219
* Upon a successful completion, the stream will be closed by this method.
220
*/
221
public static <T> T unmarshal( InputStream xml, Class<T> type ) {
222
try {
223
JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(toSource(xml), type);
224
return item.getValue();
225
} catch (JAXBException e) {
226
throw new DataBindingException(e);
227
} catch (IOException e) {
228
throw new DataBindingException(e);
229
}
230
}
231
232
/**
233
* Reads in a Java object tree from the given XML input.
234
*
235
* @param xml
236
* The character stream is read as an XML infoset.
237
* The encoding declaration in the XML will be ignored.
238
* Upon a successful completion, the stream will be closed by this method.
239
*/
240
public static <T> T unmarshal( Reader xml, Class<T> type ) {
241
try {
242
JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(toSource(xml), type);
243
return item.getValue();
244
} catch (JAXBException e) {
245
throw new DataBindingException(e);
246
} catch (IOException e) {
247
throw new DataBindingException(e);
248
}
249
}
250
251
/**
252
* Reads in a Java object tree from the given XML input.
253
*
254
* @param xml
255
* The XML infoset that the {@link Source} represents is read.
256
*/
257
public static <T> T unmarshal( Source xml, Class<T> type ) {
258
try {
259
JAXBElement<T> item = getContext(type).createUnmarshaller().unmarshal(toSource(xml), type);
260
return item.getValue();
261
} catch (JAXBException e) {
262
throw new DataBindingException(e);
263
} catch (IOException e) {
264
throw new DataBindingException(e);
265
}
266
}
267
268
269
270
/**
271
* Creates {@link Source} from various XML representation.
272
* See {@link #unmarshal} for the conversion rules.
273
*/
274
private static Source toSource(Object xml) throws IOException {
275
if(xml==null)
276
throw new IllegalArgumentException("no XML is given");
277
278
if (xml instanceof String) {
279
try {
280
xml=new URI((String)xml);
281
} catch (URISyntaxException e) {
282
xml=new File((String)xml);
283
}
284
}
285
if (xml instanceof File) {
286
File file = (File) xml;
287
return new StreamSource(file);
288
}
289
if (xml instanceof URI) {
290
URI uri = (URI) xml;
291
xml=uri.toURL();
292
}
293
if (xml instanceof URL) {
294
URL url = (URL) xml;
295
return new StreamSource(url.toExternalForm());
296
}
297
if (xml instanceof InputStream) {
298
InputStream in = (InputStream) xml;
299
return new StreamSource(in);
300
}
301
if (xml instanceof Reader) {
302
Reader r = (Reader) xml;
303
return new StreamSource(r);
304
}
305
if (xml instanceof Source) {
306
return (Source) xml;
307
}
308
throw new IllegalArgumentException("I don't understand how to handle "+xml.getClass());
309
}
310
311
/**
312
* Writes a Java object tree to XML and store it to the specified location.
313
*
314
* @param jaxbObject
315
* The Java object to be marshalled into XML. If this object is
316
* a {@link JAXBElement}, it will provide the root tag name and
317
* the body. If this object has {@link XmlRootElement}
318
* on its class definition, that will be used as the root tag name
319
* and the given object will provide the body. Otherwise,
320
* the root tag name is {@link Introspector#decapitalize(String) infered} from
321
* {@link Class#getSimpleName() the short class name}.
322
* This parameter must not be null.
323
*
324
* @param xml
325
* XML will be written to this file. If it already exists,
326
* it will be overwritten.
327
*
328
* @throws DataBindingException
329
* If the operation fails, such as due to I/O error, unbindable classes.
330
*/
331
public static void marshal( Object jaxbObject, File xml ) {
332
_marshal(jaxbObject,xml);
333
}
334
335
/**
336
* Writes a Java object tree to XML and store it to the specified location.
337
*
338
* @param jaxbObject
339
* The Java object to be marshalled into XML. If this object is
340
* a {@link JAXBElement}, it will provide the root tag name and
341
* the body. If this object has {@link XmlRootElement}
342
* on its class definition, that will be used as the root tag name
343
* and the given object will provide the body. Otherwise,
344
* the root tag name is {@link Introspector#decapitalize(String) infered} from
345
* {@link Class#getSimpleName() the short class name}.
346
* This parameter must not be null.
347
*
348
* @param xml
349
* The XML will be {@link URLConnection#getOutputStream() sent} to the
350
* resource pointed by this URL. Note that not all <tt>URL</tt>s support
351
* such operation, and exact semantics depends on the <tt>URL</tt>
352
* implementations. In case of {@link HttpURLConnection HTTP URLs},
353
* this will perform HTTP POST.
354
*
355
* @throws DataBindingException
356
* If the operation fails, such as due to I/O error, unbindable classes.
357
*/
358
public static void marshal( Object jaxbObject, URL xml ) {
359
_marshal(jaxbObject,xml);
360
}
361
362
/**
363
* Writes a Java object tree to XML and store it to the specified location.
364
*
365
* @param jaxbObject
366
* The Java object to be marshalled into XML. If this object is
367
* a {@link JAXBElement}, it will provide the root tag name and
368
* the body. If this object has {@link XmlRootElement}
369
* on its class definition, that will be used as the root tag name
370
* and the given object will provide the body. Otherwise,
371
* the root tag name is {@link Introspector#decapitalize(String) infered} from
372
* {@link Class#getSimpleName() the short class name}.
373
* This parameter must not be null.
374
*
375
* @param xml
376
* The URI is {@link URI#toURL() turned into URL} and then
377
* follows the handling of <tt>URL</tt>. See above.
378
*
379
* @throws DataBindingException
380
* If the operation fails, such as due to I/O error, unbindable classes.
381
*/
382
public static void marshal( Object jaxbObject, URI xml ) {
383
_marshal(jaxbObject,xml);
384
}
385
386
/**
387
* Writes a Java object tree to XML and store it to the specified location.
388
*
389
* @param jaxbObject
390
* The Java object to be marshalled into XML. If this object is
391
* a {@link JAXBElement}, it will provide the root tag name and
392
* the body. If this object has {@link XmlRootElement}
393
* on its class definition, that will be used as the root tag name
394
* and the given object will provide the body. Otherwise,
395
* the root tag name is {@link Introspector#decapitalize(String) infered} from
396
* {@link Class#getSimpleName() the short class name}.
397
* This parameter must not be null.
398
*
399
* @param xml
400
* The string is first interpreted as an absolute <tt>URI</tt>.
401
* If it's not {@link URI#isAbsolute() a valid absolute URI},
402
* then it's interpreted as a <tt>File</tt>
403
*
404
* @throws DataBindingException
405
* If the operation fails, such as due to I/O error, unbindable classes.
406
*/
407
public static void marshal( Object jaxbObject, String xml ) {
408
_marshal(jaxbObject,xml);
409
}
410
411
/**
412
* Writes a Java object tree to XML and store it to the specified location.
413
*
414
* @param jaxbObject
415
* The Java object to be marshalled into XML. If this object is
416
* a {@link JAXBElement}, it will provide the root tag name and
417
* the body. If this object has {@link XmlRootElement}
418
* on its class definition, that will be used as the root tag name
419
* and the given object will provide the body. Otherwise,
420
* the root tag name is {@link Introspector#decapitalize(String) infered} from
421
* {@link Class#getSimpleName() the short class name}.
422
* This parameter must not be null.
423
*
424
* @param xml
425
* The XML will be sent to the given {@link OutputStream}.
426
* Upon a successful completion, the stream will be closed by this method.
427
*
428
* @throws DataBindingException
429
* If the operation fails, such as due to I/O error, unbindable classes.
430
*/
431
public static void marshal( Object jaxbObject, OutputStream xml ) {
432
_marshal(jaxbObject,xml);
433
}
434
435
/**
436
* Writes a Java object tree to XML and store it to the specified location.
437
*
438
* @param jaxbObject
439
* The Java object to be marshalled into XML. If this object is
440
* a {@link JAXBElement}, it will provide the root tag name and
441
* the body. If this object has {@link XmlRootElement}
442
* on its class definition, that will be used as the root tag name
443
* and the given object will provide the body. Otherwise,
444
* the root tag name is {@link Introspector#decapitalize(String) infered} from
445
* {@link Class#getSimpleName() the short class name}.
446
* This parameter must not be null.
447
*
448
* @param xml
449
* The XML will be sent as a character stream to the given {@link Writer}.
450
* Upon a successful completion, the stream will be closed by this method.
451
*
452
* @throws DataBindingException
453
* If the operation fails, such as due to I/O error, unbindable classes.
454
*/
455
public static void marshal( Object jaxbObject, Writer xml ) {
456
_marshal(jaxbObject,xml);
457
}
458
459
/**
460
* Writes a Java object tree to XML and store it to the specified location.
461
*
462
* @param jaxbObject
463
* The Java object to be marshalled into XML. If this object is
464
* a {@link JAXBElement}, it will provide the root tag name and
465
* the body. If this object has {@link XmlRootElement}
466
* on its class definition, that will be used as the root tag name
467
* and the given object will provide the body. Otherwise,
468
* the root tag name is {@link Introspector#decapitalize(String) infered} from
469
* {@link Class#getSimpleName() the short class name}.
470
* This parameter must not be null.
471
*
472
* @param xml
473
* The XML will be sent to the {@link Result} object.
474
*
475
* @throws DataBindingException
476
* If the operation fails, such as due to I/O error, unbindable classes.
477
*/
478
public static void marshal( Object jaxbObject, Result xml ) {
479
_marshal(jaxbObject,xml);
480
}
481
482
/**
483
* Writes a Java object tree to XML and store it to the specified location.
484
*
485
* <p>
486
* This method is a convenience method that combines several basic operations
487
* in the {@link JAXBContext} and {@link Marshaller}. This method is designed
488
* to be the prefered method for developers new to JAXB. This method
489
* has the following characterstics:
490
*
491
* <ol>
492
* <li>Generally speaking, the performance is not necessarily optimal.
493
* It is expected that those people who need to write performance
494
* critical code will use the rest of the JAXB API directly.
495
* <li>Errors that happen during the processing is wrapped into
496
* {@link DataBindingException} (which will have {@link JAXBException}
497
* as its {@link Throwable#getCause() cause}. It is expected that
498
* those people who prefer the checked exception would use
499
* the rest of the JAXB API directly.
500
* </ol>
501
*
502
* @param jaxbObject
503
* The Java object to be marshalled into XML. If this object is
504
* a {@link JAXBElement}, it will provide the root tag name and
505
* the body. If this object has {@link XmlRootElement}
506
* on its class definition, that will be used as the root tag name
507
* and the given object will provide the body. Otherwise,
508
* the root tag name is {@link Introspector#decapitalize(String) infered} from
509
* {@link Class#getSimpleName() the short class name}.
510
* This parameter must not be null.
511
*
512
* @param xml
513
* Represents the receiver of XML. Objects of the following types are allowed.
514
*
515
* <table><tr>
516
* <th>Type</th>
517
* <th>Operation</th>
518
* </tr><tr>
519
* <td>{@link File}</td>
520
* <td>XML will be written to this file. If it already exists,
521
* it will be overwritten.</td>
522
* </tr><tr>
523
* <td>{@link URL}</td>
524
* <td>The XML will be {@link URLConnection#getOutputStream() sent} to the
525
* resource pointed by this URL. Note that not all <tt>URL</tt>s support
526
* such operation, and exact semantics depends on the <tt>URL</tt>
527
* implementations. In case of {@link HttpURLConnection HTTP URLs},
528
* this will perform HTTP POST.</td>
529
* </tr><tr>
530
* <td>{@link URI}</td>
531
* <td>The URI is {@link URI#toURL() turned into URL} and then
532
* follows the handling of <tt>URL</tt>. See above.</td>
533
* </tr><tr>
534
* <td>{@link String}</td>
535
* <td>The string is first interpreted as an absolute <tt>URI</tt>.
536
* If it's not {@link URI#isAbsolute() a valid absolute URI},
537
* then it's interpreted as a <tt>File</tt></td>
538
* </tr><tr>
539
* <td>{@link OutputStream}</td>
540
* <td>The XML will be sent to the given {@link OutputStream}.
541
* Upon a successful completion, the stream will be closed by this method.</td>
542
* </tr><tr>
543
* <td>{@link Writer}</td>
544
* <td>The XML will be sent as a character stream to the given {@link Writer}.
545
* Upon a successful completion, the stream will be closed by this method.</td>
546
* </tr><tr>
547
* <td>{@link Result}</td>
548
* <td>The XML will be sent to the {@link Result} object.</td>
549
* </tr></table>
550
*
551
* @throws DataBindingException
552
* If the operation fails, such as due to I/O error, unbindable classes.
553
*/
554
private static void _marshal( Object jaxbObject, Object xml ) {
555
try {
556
JAXBContext context;
557
558
if(jaxbObject instanceof JAXBElement) {
559
context = getContext(((JAXBElement<?>)jaxbObject).getDeclaredType());
560
} else {
561
Class<?> clazz = jaxbObject.getClass();
562
XmlRootElement r = clazz.getAnnotation(XmlRootElement.class);
563
context = getContext(clazz);
564
if(r==null) {
565
// we need to infer the name
566
jaxbObject = new JAXBElement(new QName(inferName(clazz)),clazz,jaxbObject);
567
}
568
}
569
570
Marshaller m = context.createMarshaller();
571
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);
572
m.marshal(jaxbObject, toResult(xml));
573
} catch (JAXBException e) {
574
throw new DataBindingException(e);
575
} catch (IOException e) {
576
throw new DataBindingException(e);
577
}
578
}
579
580
private static String inferName(Class clazz) {
581
return Introspector.decapitalize(clazz.getSimpleName());
582
}
583
584
/**
585
* Creates {@link Result} from various XML representation.
586
* See {@link #_marshal(Object,Object)} for the conversion rules.
587
*/
588
private static Result toResult(Object xml) throws IOException {
589
if(xml==null)
590
throw new IllegalArgumentException("no XML is given");
591
592
if (xml instanceof String) {
593
try {
594
xml=new URI((String)xml);
595
} catch (URISyntaxException e) {
596
xml=new File((String)xml);
597
}
598
}
599
if (xml instanceof File) {
600
File file = (File) xml;
601
return new StreamResult(file);
602
}
603
if (xml instanceof URI) {
604
URI uri = (URI) xml;
605
xml=uri.toURL();
606
}
607
if (xml instanceof URL) {
608
URL url = (URL) xml;
609
URLConnection con = url.openConnection();
610
con.setDoOutput(true);
611
con.setDoInput(false);
612
con.connect();
613
return new StreamResult(con.getOutputStream());
614
}
615
if (xml instanceof OutputStream) {
616
OutputStream os = (OutputStream) xml;
617
return new StreamResult(os);
618
}
619
if (xml instanceof Writer) {
620
Writer w = (Writer)xml;
621
return new StreamResult(w);
622
}
623
if (xml instanceof Result) {
624
return (Result) xml;
625
}
626
throw new IllegalArgumentException("I don't understand how to handle "+xml.getClass());
627
}
628
629
}
630
631