Import Debian changes 1.4.11.1-1+deb9u1
libxstream-java (1.4.11.1-1+deb9u1) stretch-security; urgency=high
.
* Team upload.
* Fix CVE-2020-26258:
XStream is vulnerable to a Server-Side Forgery Request which can be
activated when unmarshalling. The vulnerability may allow a remote attacker
to request data from internal resources that are not publicly available
only by manipulating the processed input stream.
* Fix CVE-2020-26259:
Xstream is vulnerable to an Arbitrary File Deletion on the local host when
unmarshalling. The vulnerability may allow a remote attacker to delete
arbitrary known files on the host as long as the executing process has
sufficient rights only by manipulating the processed input stream.
.
libxstream-java (1.4.11.1-1+deb10u1) buster-security; urgency=high
.
* Team upload.
* Fix CVE-2020-26217:
It was found that XStream is vulnerable to Remote Code Execution. The
vulnerability may allow a remote attacker to run arbitrary shell commands
only by manipulating the processed input stream. Users who rely on
blocklists are affected (the default in Debian). We strongly recommend to
use the whitelist approach of XStream's Security Framework because there
are likely more class combinations the blacklist approach may not address.
.
libxstream-java (1.4.11.1-1) unstable; urgency=medium
.
* Team upload.
* New upstream version 1.4.11.1.
.
libxstream-java (1.4.11-1) unstable; urgency=medium
.
* Team upload.
* New upstream version 1.4.11.
* Switch to compat level 11.
* Declare compliance with Debian Policy 4.2.1.
* Build-depend on libjaxb-api-java to fix FTBFS with Java 11.
(Closes: #912377)
* Add a new maven rule for xpp3 to fix a FTBFS.
* Remove Damien Raude-Morvan from Uploaders. (Closes: #889445)
.
libxstream-java (1.4.10-1) unstable; urgency=medium
.
* New upstream release
- Removed CVE-2017-7957.patch (fixed upstream)
* Standards-Version updated to 3.9.8
* Switch to debhelper level 10
Markus Koschany
3 years ago
0 | <settings> | |
1 | <mirrors> | |
2 | <mirror> | |
3 | <id>central</id> | |
4 | <url>http://repo1.maven.org/maven2</url> | |
5 | <mirrorOf>*</mirrorOf> | |
6 | </mirror> | |
7 | </mirrors> | |
8 | </settings> |
0 | 0 | language: java |
1 | sudo: false | |
2 | addons: | |
3 | apt: | |
4 | packages: | |
5 | - openjdk-6-jdk | |
1 | 6 | jdk: |
7 | - openjdk11 | |
8 | - openjdk10 | |
9 | - oraclejdk9 | |
2 | 10 | - oraclejdk8 |
3 | - oraclejdk7 | |
11 | - openjdk7 | |
4 | 12 | - openjdk6 |
5 | 13 | install: true |
6 | script: "mvn -V -B -e clean package" | |
14 | script: | |
15 | if [ "$TRAVIS_JDK_VERSION" == "openjdk6" ]; then | |
16 | wget https://archive.apache.org/dist/maven/maven-3/3.2.5/binaries/apache-maven-3.2.5-bin.zip -P ./target; | |
17 | unzip -qq ./target/apache-maven-3.2.5-bin.zip -d ./target; | |
18 | export M2_HOME=$PWD/target/apache-maven-3.2.5; | |
19 | export PATH=$M2_HOME/bin:$JAVA_HOME/bin:$PATH; | |
20 | export SETTINGS="-s .travis.settings.xml"; | |
21 | fi; | |
22 | if [ "$TRAVIS_JDK_VERSION" == "oraclejdk8" ]; then | |
23 | mkdir -p xstream/profiles/coveralls; | |
24 | mkdir -p xstream-hibernate/profiles/coveralls; | |
25 | mvn -V -B -e clean package jacoco:report coveralls:report; | |
26 | else | |
27 | mvn -V -B -e clean package $SETTINGS; | |
28 | fi | |
7 | 29 | cache: |
8 | directories: | |
30 | directories: | |
9 | 31 | - $HOME/.m2 |
0 | For Java 6 or higher build with Maven 3.2.5 or higher | |
0 | For Java 7, 8, or 9 build with Maven 3.3.9 or higher | |
1 | For Java 6 or higher build with Maven 3.2.5 | |
1 | 2 | For Java 5 build with Maven 3.0.5 |
2 | 3 | For Java 1.4 build with Maven 2.0.11 |
3 | ||
4 | Before building: | |
5 | 4 | |
6 | 5 | To build: |
7 | 6 |
0 | [![Build Status](https://travis-ci.org/x-stream/xstream.svg?branch=v-1.4.x)](https://travis-ci.org/x-stream/xstream) | |
1 | ---- | |
0 | master: [![Build Status](https://travis-ci.org/x-stream/xstream.svg?branch=master)](https://travis-ci.org/x-stream/xstream) [![Coverage Status](https://coveralls.io/repos/github/x-stream/xstream/badge.svg?branch=master)](https://coveralls.io/github/x-stream/xstream?branch=master) | |
1 | v-1.4.x: [![Build Status](https://travis-ci.org/x-stream/xstream.svg?branch=v-1.4.x)](https://travis-ci.org/x-stream/xstream) [![Coverage Status](https://coveralls.io/repos/github/x-stream/xstream/badge.svg?branch=v-1.4.x)](https://coveralls.io/github/x-stream/xstream?branch=v-1.4.x) | |
2 | ||
3 | - - - - | |
2 | 4 | # XStream |
3 | 5 | _Java to XML Serialization, and back again_ |
4 | 6 | |
11 | 13 | ## Documentation |
12 | 14 | Documentation can be found at [GitHub](http://x-stream.github.io). This |
13 | 15 | includes: |
14 | * Introduction and tutorial | |
15 | * JavaDoc | |
16 | * Change log | |
17 | * Frequently asked questions | |
16 | * [Introduction](http://x-stream.github.io) and [Tutorials](http://x-stream.github.io/tutorial.html) | |
17 | * [JavaDoc](http://x-stream.github.io/javadoc/index.html) | |
18 | * [Change History](http://x-stream.github.io/changes.html) | |
19 | * [Frequently Asked Questions](http://x-stream.github.io/faq.html) | |
18 | 20 | |
19 | 21 | ## Source |
20 | 22 | The complete source for XStream is bundled in the -src archive. This includes: |
21 | 23 | * Main API [xstream/src/java] |
22 | * Unit tests [xstream/src/test] | |
23 | * Maven build files [pom.xml] | |
24 | * Hibernate module [xstream-hibernate] | |
25 | * Web site [xstream-distribution] | |
24 | * Unit Tests [xstream/src/test] | |
25 | * Maven Build Files [pom.xml] | |
26 | * Hibernate Module [xstream-hibernate] | |
27 | * Website [xstream-distribution] | |
26 | 28 |
16 | 16 | |
17 | 17 | Documentation can be found at http://x-stream.github.io. This |
18 | 18 | includes: |
19 | * Introduction and tutorial | |
19 | * Introduction and Tutorials | |
20 | 20 | * JavaDoc |
21 | * Change log | |
22 | * Frequently asked questions | |
21 | * Change History | |
22 | * Frequently Asked Questions | |
23 | 23 | |
24 | 24 | --[ Source ]------------------------------------------------- |
25 | 25 | |
26 | 26 | The complete source for XStream is bundled in the -src archive. |
27 | 27 | This includes: |
28 | 28 | * Main API [xstream/src/java] |
29 | * Unit tests [xstream/src/test] | |
30 | * Maven build files [pom.xml] | |
31 | * Hibernate module [xstream-hibernate] | |
32 | * Web site [xstream-distribution] | |
29 | * Unit Tests [xstream/src/test] | |
30 | * Maven Build Files [pom.xml] | |
31 | * Hibernate Module [xstream-hibernate] | |
32 | * Website [xstream-distribution] | |
33 | 33 | |
34 | 34 | ------------------------------------------------------------- |
35 | 35 |
0 | libxstream-java (1.4.9-2+deb9u1) stretch-security; urgency=high | |
1 | ||
2 | * Non-maintainer upload by the LTS team. | |
3 | * XStream is vulnerable to Remote Code Execution.The vulnerability may allow | |
4 | a remote attacker to run arbitrary shell commands only by manipulating the | |
5 | processed input stream. Only users who rely on blocklists are affected. | |
6 | Anyone using XStream's Security Framework allowlist is not affected. | |
7 | ||
8 | -- Markus Koschany <apo@debian.org> Mon, 30 Nov 2020 00:04:50 +0100 | |
0 | libxstream-java (1.4.11.1-1+deb9u1) stretch-security; urgency=high | |
1 | ||
2 | * Team upload. | |
3 | * Fix CVE-2020-26258: | |
4 | XStream is vulnerable to a Server-Side Forgery Request which can be | |
5 | activated when unmarshalling. The vulnerability may allow a remote attacker | |
6 | to request data from internal resources that are not publicly available | |
7 | only by manipulating the processed input stream. | |
8 | * Fix CVE-2020-26259: | |
9 | Xstream is vulnerable to an Arbitrary File Deletion on the local host when | |
10 | unmarshalling. The vulnerability may allow a remote attacker to delete | |
11 | arbitrary known files on the host as long as the executing process has | |
12 | sufficient rights only by manipulating the processed input stream. | |
13 | ||
14 | -- Markus Koschany <apo@debian.org> Thu, 31 Dec 2020 14:15:35 +0100 | |
15 | ||
16 | libxstream-java (1.4.11.1-1+deb10u1) buster-security; urgency=high | |
17 | ||
18 | * Team upload. | |
19 | * Fix CVE-2020-26217: | |
20 | It was found that XStream is vulnerable to Remote Code Execution. The | |
21 | vulnerability may allow a remote attacker to run arbitrary shell commands | |
22 | only by manipulating the processed input stream. Users who rely on | |
23 | blocklists are affected (the default in Debian). We strongly recommend to | |
24 | use the whitelist approach of XStream's Security Framework because there | |
25 | are likely more class combinations the blacklist approach may not address. | |
26 | ||
27 | -- Markus Koschany <apo@debian.org> Tue, 01 Dec 2020 23:35:51 +0100 | |
28 | ||
29 | libxstream-java (1.4.11.1-1) unstable; urgency=medium | |
30 | ||
31 | * Team upload. | |
32 | * New upstream version 1.4.11.1. | |
33 | ||
34 | -- Markus Koschany <apo@debian.org> Sun, 11 Nov 2018 00:04:59 +0100 | |
35 | ||
36 | libxstream-java (1.4.11-1) unstable; urgency=medium | |
37 | ||
38 | * Team upload. | |
39 | * New upstream version 1.4.11. | |
40 | * Switch to compat level 11. | |
41 | * Declare compliance with Debian Policy 4.2.1. | |
42 | * Build-depend on libjaxb-api-java to fix FTBFS with Java 11. | |
43 | (Closes: #912377) | |
44 | * Add a new maven rule for xpp3 to fix a FTBFS. | |
45 | * Remove Damien Raude-Morvan from Uploaders. (Closes: #889445) | |
46 | ||
47 | -- Markus Koschany <apo@debian.org> Sat, 10 Nov 2018 22:56:01 +0100 | |
48 | ||
49 | libxstream-java (1.4.10-1) unstable; urgency=medium | |
50 | ||
51 | * New upstream release | |
52 | - Removed CVE-2017-7957.patch (fixed upstream) | |
53 | * Standards-Version updated to 3.9.8 | |
54 | * Switch to debhelper level 10 | |
55 | ||
56 | -- Emmanuel Bourg <ebourg@apache.org> Tue, 20 Jun 2017 10:22:33 +0200 | |
9 | 57 | |
10 | 58 | libxstream-java (1.4.9-2) unstable; urgency=medium |
11 | 59 |
1 | 1 | Section: java |
2 | 2 | Priority: optional |
3 | 3 | Maintainer: Debian Java Maintainers <pkg-java-maintainers@lists.alioth.debian.org> |
4 | Uploaders: Torsten Werner <twerner@debian.org>, | |
5 | Varun Hiremath <varun@debian.org>, | |
6 | Damien Raude-Morvan <drazzib@debian.org>, | |
7 | Emmanuel Bourg <ebourg@apache.org> | |
8 | Build-Depends: maven-debian-helper, | |
9 | debhelper (>= 9), | |
10 | default-jdk, | |
11 | javahelper, | |
12 | libbuild-helper-maven-plugin-java, | |
13 | libcglib-nodep-java, | |
14 | libdom4j-java, | |
15 | libjdom1-java, | |
16 | libjdom2-java, | |
17 | libjettison-java, | |
18 | libjoda-time-java, | |
19 | libkxml2-java, | |
20 | libmaven-bundle-plugin-java, | |
21 | libstax-java, | |
22 | libstax2-api-java, | |
23 | libwoodstox-java, | |
24 | libxom-java, | |
25 | libxpp3-java | |
26 | Standards-Version: 3.9.7 | |
4 | Uploaders: | |
5 | Torsten Werner <twerner@debian.org>, | |
6 | Varun Hiremath <varun@debian.org>, | |
7 | Emmanuel Bourg <ebourg@apache.org> | |
8 | Build-Depends: | |
9 | debhelper (>= 9), | |
10 | default-jdk, | |
11 | javahelper, | |
12 | libbuild-helper-maven-plugin-java, | |
13 | libcglib-nodep-java, | |
14 | libdom4j-java, | |
15 | libjaxb-api-java, | |
16 | libjdom1-java, | |
17 | libjdom2-java, | |
18 | libjettison-java, | |
19 | libjoda-time-java, | |
20 | libkxml2-java, | |
21 | libmaven-bundle-plugin-java, | |
22 | libstax-java, | |
23 | libstax2-api-java, | |
24 | libwoodstox-java, | |
25 | libxom-java, | |
26 | libxpp3-java, | |
27 | maven-debian-helper | |
28 | Standards-Version: 4.2.1 | |
27 | 29 | Vcs-Git: https://anonscm.debian.org/git/pkg-java/libxstream-java.git |
28 | 30 | Vcs-Browser: https://anonscm.debian.org/cgit/pkg-java/libxstream-java.git |
29 | 31 | Homepage: http://x-stream.github.io |
30 | 32 | |
31 | 33 | Package: libxstream-java |
32 | 34 | Architecture: all |
33 | Depends: ${misc:Depends}, ${maven:Depends} | |
35 | Depends: ${maven:Depends}, ${misc:Depends} | |
34 | 36 | Suggests: ${maven:OptionalDepends} |
35 | 37 | Description: Java library to serialize objects to XML and back again |
36 | 38 | The features of the XStream library are: |
0 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ | |
0 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ | |
1 | 1 | Upstream-Name: XStream |
2 | 2 | Source: https://github.com/x-stream/xstream |
3 | 3 |
35 | 35 | org.json json * * * * |
36 | 36 | oro oro * * * * |
37 | 37 | xmlpull xmlpull * * * * |
38 | com.sun.xml.ws jaxws-rt * * * * |
21 | 21 | s/net.sf.kxml/kxml2/ kxml2 jar s/.*/debian/ * * |
22 | 22 | org.codehaus.jettison jettison s/bundle/jar/ s/.*/debian/ * * |
23 | 23 | org.codehaus.woodstox s/wstx-asl/woodstox-core-lgpl/ * s/.*/debian/ * * |
24 | xpp3 s/xpp3_min/xpp3/ * s/.*/debian/ * * |
0 | Description: Fixes CVE-2017-7957: When a certain denyTypes workaround is not | |
1 | used, XStream mishandles attempts to create an instance of the primitive type | |
2 | 'void' during unmarshalling, leading to a remote application crash, as | |
3 | demonstrated by an xstream.fromXML("<void/>") call. | |
4 | Origin: backport, https://github.com/x-stream/xstream/commit/b3570be | |
5 | Bug-Debian: https://bugs.debian.org/861521 | |
6 | --- a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProvider.java | |
7 | +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProvider.java | |
8 | @@ -78,14 +78,18 @@ | |
9 | throw ex; | |
10 | } | |
11 | ErrorWritingException ex = null; | |
12 | - try { | |
13 | - return unsafe.allocateInstance(type); | |
14 | - } catch (SecurityException e) { | |
15 | - ex = new ObjectAccessException("Cannot construct type", e); | |
16 | - } catch (InstantiationException e) { | |
17 | - ex = new ConversionException("Cannot construct type", e); | |
18 | - } catch (IllegalArgumentException e) { | |
19 | - ex = new ObjectAccessException("Cannot construct type", e); | |
20 | + if (type == void.class || type == Void.class) { | |
21 | + ex = new ConversionException("Type void cannot have an instance"); | |
22 | + } else { | |
23 | + try { | |
24 | + return unsafe.allocateInstance(type); | |
25 | + } catch (final SecurityException e) { | |
26 | + ex = new ObjectAccessException("Cannot construct type", e); | |
27 | + } catch (final InstantiationException e) { | |
28 | + ex = new ConversionException("Cannot construct type", e); | |
29 | + } catch (final IllegalArgumentException e) { | |
30 | + ex = new ObjectAccessException("Cannot construct type", e); | |
31 | + } | |
32 | } | |
33 | ex.add("construction-type", type.getName()); | |
34 | throw ex; | |
35 | --- a/xstream/src/java/com/thoughtworks/xstream/security/PrimitiveTypePermission.java | |
36 | +++ b/xstream/src/java/com/thoughtworks/xstream/security/PrimitiveTypePermission.java | |
37 | @@ -8,8 +8,9 @@ | |
38 | ||
39 | import com.thoughtworks.xstream.core.util.Primitives; | |
40 | ||
41 | + | |
42 | /** | |
43 | - * Permission for any primitive type and its boxed counterpart (incl. void). | |
44 | + * Permission for any primitive type and its boxed counterpart (excl. void). | |
45 | * | |
46 | * @author Jörg Schaible | |
47 | * @since 1.4.7 | |
48 | @@ -21,7 +22,8 @@ | |
49 | public static final TypePermission PRIMITIVES = new PrimitiveTypePermission(); | |
50 | ||
51 | public boolean allows(Class type) { | |
52 | - return type != null && type.isPrimitive() || Primitives.isBoxed(type); | |
53 | + return type != null && type != void.class && type != Void.class && type.isPrimitive() | |
54 | + || Primitives.isBoxed(type); | |
55 | } | |
56 | ||
57 | public int hashCode() { | |
58 | --- a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java | |
59 | +++ b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java | |
60 | @@ -13,9 +13,12 @@ | |
61 | import java.beans.EventHandler; | |
62 | ||
63 | import com.thoughtworks.xstream.XStreamException; | |
64 | +import com.thoughtworks.xstream.converters.ConversionException; | |
65 | import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; | |
66 | +import com.thoughtworks.xstream.security.ForbiddenClassException; | |
67 | import com.thoughtworks.xstream.security.ProxyTypePermission; | |
68 | ||
69 | + | |
70 | /** | |
71 | * @author Jörg Schaible | |
72 | */ | |
73 | @@ -80,4 +83,23 @@ | |
74 | BUFFER.append("Executed!"); | |
75 | } | |
76 | } | |
77 | + | |
78 | + public void testDeniedInstanceOfVoid() { | |
79 | + try { | |
80 | + xstream.fromXML("<void/>"); | |
81 | + fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); | |
82 | + } catch (final ForbiddenClassException e) { | |
83 | + // OK | |
84 | + } | |
85 | + } | |
86 | + | |
87 | + public void testAllowedInstanceOfVoid() { | |
88 | + xstream.allowTypes(void.class, Void.class); | |
89 | + try { | |
90 | + xstream.fromXML("<void/>"); | |
91 | + fail("Thrown " + ConversionException.class.getName() + " expected"); | |
92 | + } catch (final ConversionException e) { | |
93 | + assertEquals("void", e.get("construction-type")); | |
94 | + } | |
95 | + } | |
96 | } |
0 | 0 | From: Markus Koschany <apo@debian.org> |
1 | Date: Sun, 29 Nov 2020 17:04:10 +0100 | |
1 | Date: Tue, 1 Dec 2020 23:11:04 +0100 | |
2 | 2 | Subject: CVE-2020-26217 |
3 | 3 | |
4 | Origin: https://github.com/x-stream/xstream/commit/6ec68c4e4192faec64f350e9449f44bc120c813b | |
5 | Origin: https://github.com/x-stream/xstream/commit/51abe602e09016c8e43e91325a15226022f4da46 | |
4 | 6 | Origin: https://github.com/x-stream/xstream/commit/0fec095d534126931c99fd38e9c6d41f5c685c1a |
5 | 7 | --- |
6 | .../src/java/com/thoughtworks/xstream/XStream.java | 4 + | |
7 | .../acceptance/SecurityVulnerabilityTest.java | 86 +++++++++++++++++++--- | |
8 | 2 files changed, 80 insertions(+), 10 deletions(-) | |
8 | .../src/java/com/thoughtworks/xstream/XStream.java | 40 ++---- | |
9 | .../acceptance/SecurityVulnerabilityTest.java | 136 ++++++++++++++++----- | |
10 | 2 files changed, 121 insertions(+), 55 deletions(-) | |
9 | 11 | |
10 | 12 | diff --git a/xstream/src/java/com/thoughtworks/xstream/XStream.java b/xstream/src/java/com/thoughtworks/xstream/XStream.java |
11 | index a2b7feb..a1fd703 100644 | |
13 | index a088877..0ae38b6 100644 | |
12 | 14 | --- a/xstream/src/java/com/thoughtworks/xstream/XStream.java |
13 | 15 | +++ b/xstream/src/java/com/thoughtworks/xstream/XStream.java |
14 | @@ -676,6 +676,10 @@ public class XStream { | |
16 | @@ -1,6 +1,6 @@ | |
17 | /* | |
18 | * Copyright (C) 2003, 2004, 2005, 2006 Joe Walnes. | |
19 | - * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 XStream Committers. | |
20 | + * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2020 XStream Committers. | |
21 | * All rights reserved. | |
22 | * | |
23 | * The software in this package is published under the terms of the BSD | |
24 | @@ -36,6 +36,7 @@ import java.net.URL; | |
25 | import java.nio.charset.Charset; | |
26 | import java.text.DecimalFormatSymbols; | |
27 | import java.util.ArrayList; | |
28 | +import java.util.Arrays; | |
29 | import java.util.BitSet; | |
30 | import java.util.Calendar; | |
31 | import java.util.Collection; | |
32 | @@ -65,10 +66,8 @@ import com.thoughtworks.xstream.converters.Converter; | |
33 | import com.thoughtworks.xstream.converters.ConverterLookup; | |
34 | import com.thoughtworks.xstream.converters.ConverterRegistry; | |
35 | import com.thoughtworks.xstream.converters.DataHolder; | |
36 | -import com.thoughtworks.xstream.converters.MarshallingContext; | |
37 | import com.thoughtworks.xstream.converters.SingleValueConverter; | |
38 | import com.thoughtworks.xstream.converters.SingleValueConverterWrapper; | |
39 | -import com.thoughtworks.xstream.converters.UnmarshallingContext; | |
40 | import com.thoughtworks.xstream.converters.basic.BigDecimalConverter; | |
41 | import com.thoughtworks.xstream.converters.basic.BigIntegerConverter; | |
42 | import com.thoughtworks.xstream.converters.basic.BooleanConverter; | |
43 | @@ -355,6 +354,8 @@ public class XStream { | |
44 | ||
45 | private static final String ANNOTATION_MAPPER_TYPE = "com.thoughtworks.xstream.mapper.AnnotationMapper"; | |
46 | private static final Pattern IGNORE_ALL = Pattern.compile(".*"); | |
47 | + private static final Pattern LAZY_ITERATORS = Pattern.compile(".*\\$LazyIterator"); | |
48 | + private static final Pattern JAVAX_CRYPTO = Pattern.compile("javax\\.crypto\\..*"); | |
49 | ||
50 | /** | |
51 | * Constructs a default XStream. | |
52 | @@ -697,6 +698,12 @@ public class XStream { | |
15 | 53 | } |
16 | 54 | |
17 | 55 | addPermission(AnyTypePermission.ANY); |
19 | 57 | + denyTypes(new Class[]{ java.lang.ProcessBuilder.class, |
20 | 58 | + java.beans.EventHandler.class, java.lang.ProcessBuilder.class, |
21 | 59 | + java.lang.Void.class, void.class }); |
22 | } | |
23 | ||
24 | protected void setupAliases() { | |
60 | + denyTypesByRegExp(new Pattern[] {LAZY_ITERATORS, JAVAX_CRYPTO}); | |
61 | + allowTypeHierarchy(Exception.class); | |
62 | securityInitialized = false; | |
63 | } | |
64 | ||
65 | @@ -962,7 +969,6 @@ public class XStream { | |
66 | registerConverter( | |
67 | new SerializableConverter(mapper, reflectionProvider, classLoaderReference), PRIORITY_LOW); | |
68 | registerConverter(new ExternalizableConverter(mapper, classLoaderReference), PRIORITY_LOW); | |
69 | - registerConverter(new InternalBlackList(), PRIORITY_LOW); | |
70 | ||
71 | registerConverter(new NullConverter(), PRIORITY_VERY_HIGH); | |
72 | registerConverter(new IntConverter(), PRIORITY_NORMAL); | |
73 | @@ -1482,7 +1488,8 @@ public class XStream { | |
74 | try { | |
75 | if (!securityInitialized && !securityWarningGiven) { | |
76 | securityWarningGiven = true; | |
77 | - System.err.println("Security framework of XStream not initialized, XStream is probably vulnerable."); | |
78 | + System.err | |
79 | + .println("Security framework of XStream not explicitly initialized, using predefined black list on your own risk."); | |
80 | } | |
81 | return marshallingStrategy.unmarshal( | |
82 | root, reader, dataHolder, converterLookup, mapper); | |
83 | @@ -2360,7 +2367,7 @@ public class XStream { | |
84 | */ | |
85 | public void addPermission(TypePermission permission) { | |
86 | if (securityMapper != null) { | |
87 | - securityInitialized = true; | |
88 | + securityInitialized |= permission.equals(NoTypePermission.NONE) || permission.equals(AnyTypePermission.ANY); | |
89 | securityMapper.addPermission(permission); | |
90 | } | |
91 | } | |
92 | @@ -2539,25 +2546,4 @@ public class XStream { | |
93 | super(message); | |
94 | } | |
95 | } | |
96 | - | |
97 | - private class InternalBlackList implements Converter { | |
98 | - | |
99 | - public boolean canConvert(final Class type) { | |
100 | - return (type == void.class || type == Void.class) | |
101 | - || (!securityInitialized | |
102 | - && type != null | |
103 | - && (type.getName().equals("java.beans.EventHandler") | |
104 | - || type.getName().endsWith("$LazyIterator") | |
105 | - || type.getName().startsWith("javax.crypto."))); | |
106 | - } | |
107 | - | |
108 | - public void marshal(final Object source, final HierarchicalStreamWriter writer, | |
109 | - final MarshallingContext context) { | |
110 | - throw new ConversionException("Security alert. Marshalling rejected."); | |
111 | - } | |
112 | - | |
113 | - public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { | |
114 | - throw new ConversionException("Security alert. Unmarshalling rejected."); | |
115 | - } | |
116 | - } | |
117 | } | |
25 | 118 | diff --git a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java |
26 | index 9f1cef2..1ceb450 100644 | |
119 | index 85eaf1c..44b0015 100644 | |
27 | 120 | --- a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java |
28 | 121 | +++ b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java |
29 | @@ -11,10 +11,11 @@ | |
122 | @@ -11,13 +11,15 @@ | |
30 | 123 | package com.thoughtworks.acceptance; |
31 | 124 | |
32 | 125 | import java.beans.EventHandler; |
33 | 126 | +import java.util.Iterator; |
34 | 127 | |
128 | import com.thoughtworks.xstream.XStream; | |
35 | 129 | import com.thoughtworks.xstream.XStreamException; |
36 | 130 | import com.thoughtworks.xstream.converters.ConversionException; |
37 | 131 | -import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; |
38 | 132 | +import com.thoughtworks.xstream.core.JVM; |
133 | +import com.thoughtworks.xstream.security.AnyTypePermission; | |
39 | 134 | import com.thoughtworks.xstream.security.ForbiddenClassException; |
40 | import com.thoughtworks.xstream.security.ProxyTypePermission; | |
41 | ||
42 | @@ -37,15 +38,15 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest { | |
135 | -import com.thoughtworks.xstream.security.ProxyTypePermission; | |
136 | +import com.thoughtworks.xstream.security.NoTypePermission; | |
137 | ||
138 | ||
139 | /** | |
140 | @@ -31,21 +33,22 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest { | |
141 | super.setUp(); | |
142 | BUFFER.setLength(0); | |
143 | xstream.alias("runnable", Runnable.class); | |
144 | - xstream.allowTypeHierarchy(Runnable.class); | |
145 | - xstream.addPermission(ProxyTypePermission.PROXIES); | |
146 | + } | |
147 | + | |
148 | + protected void setupSecurity(XStream xstream) { | |
149 | } | |
43 | 150 | |
44 | 151 | public void testCannotInjectEventHandler() { |
45 | 152 | final String xml = "" |
64 | 171 | |
65 | 172 | try { |
66 | 173 | xstream.fromXML(xml); |
67 | @@ -77,6 +78,71 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest { | |
174 | @@ -57,7 +60,6 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest { | |
175 | } | |
176 | ||
177 | public void testCannotInjectEventHandlerWithUnconfiguredSecurityFramework() { | |
178 | - xstream = new XStream(createDriver()); | |
179 | xstream.alias("runnable", Runnable.class); | |
180 | final String xml = "" | |
181 | + "<string class='runnable-array'>\n" | |
182 | @@ -74,26 +76,24 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest { | |
183 | xstream.fromXML(xml); | |
184 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
185 | } catch (final XStreamException e) { | |
186 | - assertTrue(e.getMessage().indexOf(EventHandler.class.getName())>=0); | |
187 | + assertTrue(e.getMessage().indexOf(EventHandler.class.getName()) >= 0); | |
188 | } | |
189 | assertEquals(0, BUFFER.length()); | |
190 | } | |
191 | ||
192 | public void testExplicitlyConvertEventHandler() { | |
193 | final String xml = "" | |
194 | - + "<string class='runnable-array'>\n" | |
195 | - + " <dynamic-proxy>\n" | |
196 | - + " <interface>java.lang.Runnable</interface>\n" | |
197 | - + " <handler class='java.beans.EventHandler'>\n" | |
198 | - + " <target class='com.thoughtworks.acceptance.SecurityVulnerabilityTest$Exec'/>\n" | |
199 | - + " <action>exec</action>\n" | |
200 | - + " </handler>\n" | |
201 | - + " </dynamic-proxy>\n" | |
202 | - + "</string>"; | |
203 | + + "<string class='runnable-array'>\n" | |
204 | + + " <dynamic-proxy>\n" | |
205 | + + " <interface>java.lang.Runnable</interface>\n" | |
206 | + + " <handler class='java.beans.EventHandler'>\n" | |
207 | + + " <target class='com.thoughtworks.acceptance.SecurityVulnerabilityTest$Exec'/>\n" | |
208 | + + " <action>exec</action>\n" | |
209 | + + " </handler>\n" | |
210 | + + " </dynamic-proxy>\n" | |
211 | + + "</string>"; | |
212 | ||
213 | xstream.allowTypes(new Class[]{EventHandler.class}); | |
214 | - xstream.registerConverter(new ReflectionConverter(xstream.getMapper(), xstream | |
215 | - .getReflectionProvider(), EventHandler.class)); | |
216 | ||
217 | final Runnable[] array = (Runnable[])xstream.fromXML(xml); | |
218 | assertEquals(0, BUFFER.length()); | |
219 | @@ -101,6 +101,71 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest { | |
68 | 220 | assertEquals("Executed!", BUFFER.toString()); |
69 | 221 | } |
70 | 222 | |
136 | 288 | public static class Exec { |
137 | 289 | |
138 | 290 | public void exec() { |
291 | @@ -109,6 +174,8 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest { | |
292 | } | |
293 | ||
294 | public void testDeniedInstanceOfVoid() { | |
295 | + xstream.addPermission(AnyTypePermission.ANY); // clear out defaults | |
296 | + xstream.denyTypes(new Class[] { void.class, Void.class }); | |
297 | try { | |
298 | xstream.fromXML("<void/>"); | |
299 | fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); | |
300 | @@ -118,12 +185,25 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest { | |
301 | } | |
302 | ||
303 | public void testAllowedInstanceOfVoid() { | |
304 | - xstream.allowTypes(new Class[] { void.class, Void.class }); | |
305 | + xstream.allowTypes(new Class[]{void.class, Void.class}); | |
306 | try { | |
307 | xstream.fromXML("<void/>"); | |
308 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
309 | } catch (final ConversionException e) { | |
310 | - assertEquals("void", e.get("required-type")); | |
311 | + assertEquals("void", e.get("construction-type")); | |
312 | + } | |
313 | + } | |
314 | + | |
315 | + public static class LazyIterator { | |
316 | + } | |
317 | + | |
318 | + public void testInstanceOfLazyIterator() { | |
319 | + xstream.alias("lazy-iterator", LazyIterator.class); | |
320 | + try { | |
321 | + xstream.fromXML("<lazy-iterator/>"); | |
322 | + fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); | |
323 | + } catch (final ForbiddenClassException e) { | |
324 | + // OK | |
325 | } | |
326 | } | |
327 | } |
0 | From: Markus Koschany <apo@debian.org> | |
1 | Date: Sun, 27 Dec 2020 11:00:57 +0100 | |
2 | Subject: CVE-2020-26258 | |
3 | ||
4 | Origin: https://github.com/x-stream/xstream/commit/6740c04b217aef02d44fba26402b35e0f6f493ce | |
5 | --- | |
6 | xstream/src/java/com/thoughtworks/xstream/XStream.java | 6 +++++- | |
7 | 1 file changed, 5 insertions(+), 1 deletion(-) | |
8 | ||
9 | diff --git a/xstream/src/java/com/thoughtworks/xstream/XStream.java b/xstream/src/java/com/thoughtworks/xstream/XStream.java | |
10 | index 0ae38b6..65670f1 100644 | |
11 | --- a/xstream/src/java/com/thoughtworks/xstream/XStream.java | |
12 | +++ b/xstream/src/java/com/thoughtworks/xstream/XStream.java | |
13 | @@ -698,7 +698,11 @@ public class XStream { | |
14 | } | |
15 | ||
16 | addPermission(AnyTypePermission.ANY); | |
17 | - denyTypes(new String[]{"java.beans.EventHandler", "javax.imageio.ImageIO$ContainsFilter"}); | |
18 | + denyTypes(new String[]{ | |
19 | + "java.beans.EventHandler", | |
20 | + "java.lang.ProcessBuilder", | |
21 | + "javax.imageio.ImageIO$ContainsFilter", | |
22 | + "jdk.nashorn.internal.objects.NativeString"}); | |
23 | denyTypes(new Class[]{ java.lang.ProcessBuilder.class, | |
24 | java.beans.EventHandler.class, java.lang.ProcessBuilder.class, | |
25 | java.lang.Void.class, void.class }); |
0 | From: Markus Koschany <apo@debian.org> | |
1 | Date: Sun, 27 Dec 2020 11:05:05 +0100 | |
2 | Subject: CVE-2020-26259 | |
3 | ||
4 | Origin: https://github.com/x-stream/xstream/commit/0bcbf50126a62dfcd65f93a0da0c6d1ae92aa738 | |
5 | --- | |
6 | pom.xml | 6 ++ | |
7 | xstream/pom.xml | 48 ++++++++++++++++ | |
8 | .../src/java/com/thoughtworks/xstream/XStream.java | 10 +++- | |
9 | .../acceptance/SecurityVulnerabilityTest.java | 65 ++++++++++++++++++++++ | |
10 | 4 files changed, 126 insertions(+), 3 deletions(-) | |
11 | ||
12 | diff --git a/pom.xml b/pom.xml | |
13 | index 5d52a8f..3e47500 100644 | |
14 | --- a/pom.xml | |
15 | +++ b/pom.xml | |
16 | @@ -552,6 +552,11 @@ | |
17 | <artifactId>jaxb-api</artifactId> | |
18 | <version>${version.javax.xml.bind.api}</version> | |
19 | </dependency> | |
20 | + <dependency> | |
21 | + <groupId>com.sun.xml.ws</groupId> | |
22 | + <artifactId>jaxws-rt</artifactId> | |
23 | + <version>${version.javax.xml.ws.jaxws.rt}</version> | |
24 | + </dependency> | |
25 | ||
26 | <dependency> | |
27 | <groupId>org.hibernate</groupId> | |
28 | @@ -984,6 +989,7 @@ | |
29 | <version.javax.activation>1.1.1</version.javax.activation> | |
30 | <version.javax.annotation.api>1.3.2</version.javax.annotation.api> | |
31 | <version.javax.xml.bind.api>2.3.1</version.javax.xml.bind.api> | |
32 | + <version.javax.xml.ws.jaxws.rt>2.2</version.javax.xml.ws.jaxws.rt><!-- Java 5 --> | |
33 | <version.jmock>1.0.1</version.jmock> | |
34 | <version.joda-time>1.6</version.joda-time> | |
35 | <version.junit>3.8.1</version.junit> | |
36 | diff --git a/xstream/pom.xml b/xstream/pom.xml | |
37 | index 566b619..8b9dc22 100644 | |
38 | --- a/xstream/pom.xml | |
39 | +++ b/xstream/pom.xml | |
40 | @@ -149,6 +149,54 @@ | |
41 | <artifactId>commons-lang</artifactId> | |
42 | <scope>test</scope> | |
43 | </dependency> | |
44 | + | |
45 | + <dependency> | |
46 | + <groupId>com.sun.xml.ws</groupId> | |
47 | + <artifactId>jaxws-rt</artifactId> | |
48 | + <scope>test</scope> | |
49 | + <exclusions> | |
50 | + <exclusion> | |
51 | + <groupId>javax.xml.ws</groupId> | |
52 | + <artifactId>jaxws-api</artifactId> | |
53 | + </exclusion> | |
54 | + <exclusion> | |
55 | + <groupId>com.sun.istack</groupId> | |
56 | + <artifactId>istack-commons-runtime</artifactId> | |
57 | + </exclusion> | |
58 | + <exclusion> | |
59 | + <groupId>com.sun.xml.bind</groupId> | |
60 | + <artifactId>jaxb-impl</artifactId> | |
61 | + </exclusion> | |
62 | + <exclusion> | |
63 | + <groupId>com.sun.xml.messaging.saaj</groupId> | |
64 | + <artifactId>saaj-impl</artifactId> | |
65 | + </exclusion> | |
66 | + <exclusion> | |
67 | + <groupId>com.sun.xml.stream.buffer</groupId> | |
68 | + <artifactId>streambuffer</artifactId> | |
69 | + </exclusion> | |
70 | + <exclusion> | |
71 | + <groupId>com.sun.xml.ws</groupId> | |
72 | + <artifactId>policy</artifactId> | |
73 | + </exclusion> | |
74 | + <exclusion> | |
75 | + <groupId>com.sun.org.apache.xml.internal</groupId> | |
76 | + <artifactId>resolver</artifactId> | |
77 | + </exclusion> | |
78 | + <exclusion> | |
79 | + <groupId>org.glassfish.gmbal</groupId> | |
80 | + <artifactId>gmbal-api-only</artifactId> | |
81 | + </exclusion> | |
82 | + <exclusion> | |
83 | + <groupId>org.jvnet</groupId> | |
84 | + <artifactId>mimepull</artifactId> | |
85 | + </exclusion> | |
86 | + <exclusion> | |
87 | + <groupId>org.jvnet.staxex</groupId> | |
88 | + <artifactId>stax-ex</artifactId> | |
89 | + </exclusion> | |
90 | + </exclusions> | |
91 | + </dependency> | |
92 | </dependencies> | |
93 | ||
94 | <build> | |
95 | diff --git a/xstream/src/java/com/thoughtworks/xstream/XStream.java b/xstream/src/java/com/thoughtworks/xstream/XStream.java | |
96 | index 65670f1..1d28088 100644 | |
97 | --- a/xstream/src/java/com/thoughtworks/xstream/XStream.java | |
98 | +++ b/xstream/src/java/com/thoughtworks/xstream/XStream.java | |
99 | @@ -356,6 +356,7 @@ public class XStream { | |
100 | private static final Pattern IGNORE_ALL = Pattern.compile(".*"); | |
101 | private static final Pattern LAZY_ITERATORS = Pattern.compile(".*\\$LazyIterator"); | |
102 | private static final Pattern JAVAX_CRYPTO = Pattern.compile("javax\\.crypto\\..*"); | |
103 | + private static final Pattern JAXWS_FILE_STREAM = Pattern.compile(".*\\.ReadAllStream\\$FileStream"); | |
104 | ||
105 | /** | |
106 | * Constructs a default XStream. | |
107 | @@ -703,10 +704,13 @@ public class XStream { | |
108 | "java.lang.ProcessBuilder", | |
109 | "javax.imageio.ImageIO$ContainsFilter", | |
110 | "jdk.nashorn.internal.objects.NativeString"}); | |
111 | - denyTypes(new Class[]{ java.lang.ProcessBuilder.class, | |
112 | - java.beans.EventHandler.class, java.lang.ProcessBuilder.class, | |
113 | + denyTypes(new Class[]{ | |
114 | + java.lang.ProcessBuilder.class, | |
115 | + jdk.nashorn.internal.objects.NativeString.class, | |
116 | + java.beans.EventHandler.class, | |
117 | + java.lang.ProcessBuilder.class, | |
118 | java.lang.Void.class, void.class }); | |
119 | - denyTypesByRegExp(new Pattern[] {LAZY_ITERATORS, JAVAX_CRYPTO}); | |
120 | + denyTypesByRegExp(new Pattern[] {LAZY_ITERATORS, JAVAX_CRYPTO, JAXWS_FILE_STREAM}); | |
121 | allowTypeHierarchy(Exception.class); | |
122 | securityInitialized = false; | |
123 | } | |
124 | diff --git a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java | |
125 | index 44b0015..36b61a1 100644 | |
126 | --- a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java | |
127 | +++ b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java | |
128 | @@ -11,6 +11,11 @@ | |
129 | package com.thoughtworks.acceptance; | |
130 | ||
131 | import java.beans.EventHandler; | |
132 | +import java.io.File; | |
133 | +import java.io.FileOutputStream; | |
134 | +import java.io.IOException; | |
135 | +import java.io.InputStream; | |
136 | +import java.io.OutputStream; | |
137 | import java.util.Iterator; | |
138 | ||
139 | import com.thoughtworks.xstream.XStream; | |
140 | @@ -206,4 +211,64 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest { | |
141 | // OK | |
142 | } | |
143 | } | |
144 | + | |
145 | + public void testCannotUseJaxwsInputStreamToDeleteFile() { | |
146 | + final String xml = "" | |
147 | + + "<is class='com.sun.xml.ws.util.ReadAllStream$FileStream'>\n" | |
148 | + + " <tempFile>target/junit/test.txt</tempFile>\n" | |
149 | + + "</is>"; | |
150 | + | |
151 | + xstream.aliasType("is", InputStream.class); | |
152 | + try { | |
153 | + xstream.fromXML(xml); | |
154 | + fail("Thrown " + ConversionException.class.getName() + " expected"); | |
155 | + } catch (final ForbiddenClassException e) { | |
156 | + // OK | |
157 | + } | |
158 | + } | |
159 | + | |
160 | + public void testExplicitlyUseJaxwsInputStreamToDeleteFile() throws IOException { | |
161 | + final File testDir = new File("target/junit"); | |
162 | + final File testFile = new File(testDir, "test.txt"); | |
163 | + try { | |
164 | + testDir.mkdirs(); | |
165 | + | |
166 | + final OutputStream out = new FileOutputStream(testFile); | |
167 | + out.write("JUnit".getBytes()); | |
168 | + out.flush(); | |
169 | + out.close(); | |
170 | + | |
171 | + assertTrue("Test file " + testFile.getPath() + " does not exist.", testFile.exists()); | |
172 | + | |
173 | + final String xml = "" | |
174 | + + "<is class='com.sun.xml.ws.util.ReadAllStream$FileStream'>\n" | |
175 | + + " <tempFile>target/junit/test.txt</tempFile>\n" | |
176 | + + "</is>"; | |
177 | + | |
178 | + xstream.addPermission(AnyTypePermission.ANY); // clear out defaults | |
179 | + xstream.aliasType("is", InputStream.class); | |
180 | + | |
181 | + InputStream is = null; | |
182 | + try { | |
183 | + is = (InputStream)xstream.fromXML(xml); | |
184 | + } catch (final ForbiddenClassException e) { | |
185 | + // OK | |
186 | + } | |
187 | + | |
188 | + assertTrue("Test file " + testFile.getPath() + " no longer exists.", testFile.exists()); | |
189 | + | |
190 | + byte[] data = new byte[10]; | |
191 | + is.read(data); | |
192 | + is.close(); | |
193 | + | |
194 | + assertFalse("Test file " + testFile.getPath() + " still exists exist.", testFile.exists()); | |
195 | + } finally { | |
196 | + if (testFile.exists()) { | |
197 | + testFile.delete(); | |
198 | + } | |
199 | + if (testDir.exists()) { | |
200 | + testDir.delete(); | |
201 | + } | |
202 | + } | |
203 | + } | |
204 | } |
0 | 0 | 01-java7-compatibility.patch |
1 | CVE-2017-7957.patch | |
2 | 1 | CVE-2020-26217.patch |
2 | CVE-2020-26258.patch | |
3 | CVE-2020-26259.patch |
0 | 0 | #!/usr/bin/make -f |
1 | 1 | |
2 | 2 | %: |
3 | dh $@ --buildsystem=maven --with javahelper | |
3 | dh $@ --with javahelper | |
4 | 4 | |
5 | 5 | get-orig-source: |
6 | 6 | uscan --download-current-version --force-download --rename --repack --compression xz |
0 | 0 | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> |
1 | 1 | <!-- |
2 | 2 | Copyright (C) 2006 Joe Walnes. |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2015, 2016 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2015, 2016, 2017, 2018 XStream committers. | |
4 | 4 | All rights reserved. |
5 | 5 | |
6 | 6 | The software in this package is published under the terms of the BSD |
13 | 13 | <groupId>com.thoughtworks.xstream</groupId> |
14 | 14 | <artifactId>xstream-parent</artifactId> |
15 | 15 | <packaging>pom</packaging> |
16 | <version>1.4.9</version> | |
16 | <version>1.4.11.1</version> | |
17 | 17 | <name>XStream Parent</name> |
18 | 18 | <url>http://x-stream.github.io</url> |
19 | 19 | <description> |
36 | 36 | |
37 | 37 | <profiles> |
38 | 38 | <profile> |
39 | <id>jdk19</id> | |
39 | <id>jdk9-ge</id> | |
40 | 40 | <activation> |
41 | <jdk>1.9</jdk> | |
41 | <jdk>[9,</jdk> | |
42 | 42 | </activation> |
43 | 43 | <properties> |
44 | <version.java.5>1.6</version.java.5> | |
44 | 45 | <version.java.source>1.6</version.java.source> |
45 | 46 | <version.java.target>1.6</version.java.target> |
47 | <version.plugin.maven.enforcer>3.0.0-M1</version.plugin.maven.enforcer> | |
46 | 48 | </properties> |
47 | 49 | </profile> |
48 | 50 | <profile> |
49 | <id>jdk18ge</id> | |
51 | <id>jdk18-ge</id> | |
50 | 52 | <activation> |
51 | 53 | <jdk>[1.8,)</jdk> |
52 | 54 | </activation> |
53 | 55 | <properties> |
54 | 56 | <javadoc.xdoclint>-Xdoclint:-missing</javadoc.xdoclint> |
57 | <version.plugin.felix.bundle>2.5.4</version.plugin.felix.bundle> | |
58 | </properties> | |
59 | </profile> | |
60 | <profile> | |
61 | <id>jdk18</id> | |
62 | <activation> | |
63 | <jdk>1.8</jdk> | |
64 | </activation> | |
65 | <properties> | |
66 | <version.java.source>1.4</version.java.source> | |
67 | <version.java.target>1.4</version.java.target> | |
68 | </properties> | |
69 | </profile> | |
70 | <profile> | |
71 | <id>jdk16</id> | |
72 | <activation> | |
73 | <jdk>1.6</jdk> | |
74 | </activation> | |
75 | <properties> | |
76 | <version.org.openjdk.jmh>1.16</version.org.openjdk.jmh> | |
55 | 77 | </properties> |
56 | 78 | </profile> |
57 | 79 | <profile> |
155 | 177 | <configuration> |
156 | 178 | <instructions combine.children="append"> |
157 | 179 | <Export-Package>${bundle.export.package}</Export-Package> |
180 | <Import-Package>${bundle.import.package}</Import-Package> | |
158 | 181 | </instructions> |
159 | 182 | </configuration> |
160 | 183 | </plugin> |
179 | 202 | </build> |
180 | 203 | <properties> |
181 | 204 | <bundle.export.package>${project.groupId}.*;-noimport:=true</bundle.export.package> |
205 | <bundle.import.package>*</bundle.import.package> | |
182 | 206 | </properties> |
183 | 207 | </profile> |
184 | 208 | <profile> |
199 | 223 | <goal>sign</goal> |
200 | 224 | </goals> |
201 | 225 | </execution> |
226 | </executions> | |
227 | </plugin> | |
228 | </plugins> | |
229 | </build> | |
230 | </profile> | |
231 | <profile> | |
232 | <id>coveralls</id> | |
233 | <activation> | |
234 | <file> | |
235 | <exists>profiles/coveralls</exists> | |
236 | </file> | |
237 | </activation> | |
238 | <build> | |
239 | <plugins> | |
240 | <plugin> | |
241 | <groupId>org.eluder.coveralls</groupId> | |
242 | <artifactId>coveralls-maven-plugin</artifactId> | |
243 | </plugin> | |
244 | <plugin> | |
245 | <groupId>org.jacoco</groupId> | |
246 | <artifactId>jacoco-maven-plugin</artifactId> | |
247 | <executions> | |
248 | <execution> | |
249 | <id>prepare-agent</id> | |
250 | <goals> | |
251 | <goal>prepare-agent</goal> | |
252 | </goals> | |
253 | </execution> | |
202 | 254 | </executions> |
203 | 255 | </plugin> |
204 | 256 | </plugins> |
268 | 320 | <dependency> |
269 | 321 | <groupId>com.thoughtworks.xstream</groupId> |
270 | 322 | <artifactId>xstream</artifactId> |
271 | <version>1.4.9</version> | |
323 | <version>1.4.11.1</version> | |
272 | 324 | </dependency> |
273 | 325 | <dependency> |
274 | 326 | <groupId>com.thoughtworks.xstream</groupId> |
275 | 327 | <artifactId>xstream</artifactId> |
276 | <version>1.4.9</version> | |
328 | <version>1.4.11.1</version> | |
277 | 329 | <classifier>tests</classifier> |
278 | 330 | <type>test-jar</type> |
279 | 331 | <scope>test</scope> |
281 | 333 | <dependency> |
282 | 334 | <groupId>com.thoughtworks.xstream</groupId> |
283 | 335 | <artifactId>xstream</artifactId> |
284 | <version>1.4.9</version> | |
336 | <version>1.4.11.1</version> | |
285 | 337 | <classifier>javadoc</classifier> |
286 | 338 | <scope>provided</scope> |
287 | 339 | </dependency> |
288 | 340 | <dependency> |
289 | 341 | <groupId>com.thoughtworks.xstream</groupId> |
290 | 342 | <artifactId>xstream-hibernate</artifactId> |
291 | <version>1.4.9</version> | |
343 | <version>1.4.11.1</version> | |
292 | 344 | </dependency> |
293 | 345 | <dependency> |
294 | 346 | <groupId>com.thoughtworks.xstream</groupId> |
295 | 347 | <artifactId>xstream-hibernate</artifactId> |
296 | <version>1.4.9</version> | |
348 | <version>1.4.11.1</version> | |
297 | 349 | <classifier>javadoc</classifier> |
298 | 350 | <scope>provided</scope> |
299 | 351 | </dependency> |
300 | 352 | <dependency> |
301 | 353 | <groupId>com.thoughtworks.xstream</groupId> |
302 | 354 | <artifactId>xstream-jmh</artifactId> |
303 | <version>1.4.9</version> | |
355 | <version>1.4.11.1</version> | |
304 | 356 | </dependency> |
305 | 357 | <dependency> |
306 | 358 | <groupId>com.thoughtworks.xstream</groupId> |
307 | 359 | <artifactId>xstream-jmh</artifactId> |
308 | <version>1.4.9</version> | |
360 | <version>1.4.11.1</version> | |
309 | 361 | <classifier>javadoc</classifier> |
310 | 362 | <scope>provided</scope> |
311 | 363 | </dependency> |
312 | 364 | <dependency> |
313 | 365 | <groupId>com.thoughtworks.xstream</groupId> |
314 | 366 | <artifactId>xstream-benchmark</artifactId> |
315 | <version>1.4.9</version> | |
367 | <version>1.4.11.1</version> | |
316 | 368 | </dependency> |
317 | 369 | <dependency> |
318 | 370 | <groupId>com.thoughtworks.xstream</groupId> |
319 | 371 | <artifactId>xstream-benchmark</artifactId> |
320 | <version>1.4.9</version> | |
372 | <version>1.4.11.1</version> | |
321 | 373 | <classifier>javadoc</classifier> |
322 | 374 | <scope>provided</scope> |
323 | 375 | </dependency> |
488 | 540 | <groupId>javax.activation</groupId> |
489 | 541 | <artifactId>activation</artifactId> |
490 | 542 | <version>${version.javax.activation}</version> |
491 | <scope>provided</scope> | |
543 | </dependency> | |
544 | <dependency> | |
545 | <groupId>javax.annotation</groupId> | |
546 | <artifactId>javax.annotation-api</artifactId> | |
547 | <version>${version.javax.annotation.api}</version> | |
548 | </dependency> | |
549 | <dependency> | |
550 | <groupId>javax.xml.bind</groupId> | |
551 | <artifactId>jaxb-api</artifactId> | |
552 | <version>${version.javax.xml.bind.api}</version> | |
492 | 553 | </dependency> |
493 | 554 | |
494 | 555 | <dependency> |
535 | 596 | <artifactId>jmh-generator-annprocess</artifactId> |
536 | 597 | <version>${version.org.openjdk.jmh}</version> |
537 | 598 | <scope>provided</scope> |
599 | </dependency> | |
600 | <dependency> | |
601 | <groupId>commons-codec</groupId> | |
602 | <artifactId>commons-codec</artifactId> | |
603 | <version>${version.commons.codec}</version> | |
604 | </dependency> | |
605 | <dependency> | |
606 | <groupId>com.brsanthu</groupId> | |
607 | <artifactId>migbase64</artifactId> | |
608 | <version>${version.com.brsanthu.migbase64}</version> | |
538 | 609 | </dependency> |
539 | 610 | |
540 | 611 | <!-- always test-scoped --> |
673 | 744 | <additionalparam>${javadoc.xdoclint}</additionalparam> |
674 | 745 | <source>${version.java.source}</source> |
675 | 746 | <links> |
676 | <link>${link.javadoc.javase}</link> | |
747 | <link>${javadoc.link.javase}</link> | |
677 | 748 | </links> |
678 | 749 | <archive> |
679 | 750 | <manifest> |
685 | 756 | </manifestEntries> |
686 | 757 | </archive> |
687 | 758 | </configuration> |
759 | </plugin> | |
760 | <plugin> | |
761 | <groupId>org.apache.maven.plugins</groupId> | |
762 | <artifactId>maven-jxr-plugin</artifactId> | |
763 | <version>${version.plugin.maven.jxr}</version> | |
688 | 764 | </plugin> |
689 | 765 | <plugin> |
690 | 766 | <groupId>org.apache.maven.plugins</groupId> |
779 | 855 | <version>${version.plugin.mojo.build-helper}</version> |
780 | 856 | </plugin> |
781 | 857 | <plugin> |
782 | <groupId>org.codehaus.mojo</groupId> | |
783 | <artifactId>cobertura-maven-plugin</artifactId> | |
784 | <version>${version.plugin.mojo.cobertura}</version> | |
785 | <executions> | |
786 | <execution> | |
787 | <goals> | |
788 | <goal>clean</goal> | |
789 | </goals> | |
790 | </execution> | |
791 | </executions> | |
792 | </plugin> | |
793 | <plugin> | |
794 | <groupId>org.codehaus.mojo</groupId> | |
795 | <artifactId>jxr-maven-plugin</artifactId> | |
796 | <version>${version.plugin.mojo.jxr}</version> | |
797 | </plugin> | |
798 | <plugin> | |
799 | 858 | <groupId>org.codehaus.xsite</groupId> |
800 | 859 | <artifactId>xsite-maven-plugin</artifactId> |
801 | 860 | <version>${version.plugin.codehaus.xsite}</version> |
817 | 876 | </manifest> |
818 | 877 | </archive> |
819 | 878 | </configuration> |
879 | </plugin> | |
880 | <plugin> | |
881 | <groupId>org.eluder.coveralls</groupId> | |
882 | <artifactId>coveralls-maven-plugin</artifactId> | |
883 | <version>${version.plugin.eluder.coveralls}</version> | |
884 | </plugin> | |
885 | <plugin> | |
886 | <groupId>org.jacoco</groupId> | |
887 | <artifactId>jacoco-maven-plugin</artifactId> | |
888 | <version>${version.plugin.jacoco}</version> | |
820 | 889 | </plugin> |
821 | 890 | </plugins> |
822 | 891 | </pluginManagement> |
846 | 915 | </configuration> |
847 | 916 | </plugin> |
848 | 917 | </plugins> |
849 | <extensions> | |
850 | <extension> | |
851 | <groupId>org.apache.maven.wagon</groupId> | |
852 | <artifactId>wagon-webdav</artifactId> | |
853 | <version>${version.org.apache.maven.wagon.webdev}</version> | |
854 | </extension> | |
855 | </extensions> | |
856 | 918 | </build> |
857 | 919 | |
858 | 920 | <distributionManagement> |
859 | 921 | <repository> |
860 | 922 | <id>ossrh-staging</id> |
861 | <url>http://oss.sonatype.org/service/local/staging/deploy/maven2</url> | |
923 | <url>https://oss.sonatype.org/service/local/staging/deploy/maven2</url> | |
862 | 924 | </repository> |
863 | 925 | <snapshotRepository> |
864 | 926 | <id>ossrh-snapshots</id> |
865 | <url>http://oss.sonatype.org/content/repositories/snapshots</url> | |
927 | <url>https://oss.sonatype.org/content/repositories/snapshots</url> | |
866 | 928 | </snapshotRepository> |
867 | 929 | <!--site> |
868 | 930 | <id>github</id> |
880 | 942 | <properties> |
881 | 943 | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
882 | 944 | |
945 | <version.java.5>1.5</version.java.5> | |
883 | 946 | <version.java.source>1.5</version.java.source> |
884 | 947 | <version.java.target>1.5</version.java.target> |
885 | 948 | <version.java.enforced>[1.4,)</version.java.enforced> |
897 | 960 | <version.plugin.maven.install>2.2</version.plugin.maven.install> |
898 | 961 | <version.plugin.maven.jar>2.2</version.plugin.maven.jar> |
899 | 962 | <version.plugin.maven.javadoc>2.10</version.plugin.maven.javadoc> |
963 | <version.plugin.maven.jxr>2.5</version.plugin.maven.jxr> | |
900 | 964 | <version.plugin.maven.release>2.1</version.plugin.maven.release> |
901 | 965 | <version.plugin.maven.resources>2.2</version.plugin.maven.resources> |
902 | 966 | <version.plugin.maven.site>2.0-beta-6</version.plugin.maven.site> |
903 | 967 | <version.plugin.maven.source>2.1.2</version.plugin.maven.source> |
904 | 968 | <version.plugin.maven.surefire>2.4.3</version.plugin.maven.surefire> |
905 | 969 | <version.plugin.mojo.build-helper>1.5</version.plugin.mojo.build-helper> |
906 | <version.plugin.mojo.cobertura>2.0</version.plugin.mojo.cobertura> | |
907 | <version.plugin.mojo.jxr>2.0-beta-1</version.plugin.mojo.jxr> | |
908 | ||
909 | <version.org.apache.maven.wagon.webdev>1.0-beta-2</version.org.apache.maven.wagon.webdev> | |
970 | <version.plugin.eluder.coveralls>4.2.0</version.plugin.eluder.coveralls> | |
971 | <version.plugin.jacoco>0.8.1</version.plugin.jacoco> | |
910 | 972 | |
911 | 973 | <version.cglib.nodep>2.2</version.cglib.nodep> |
974 | <version.com.brsanthu.migbase64>2.2</version.com.brsanthu.migbase64> | |
912 | 975 | <version.com.megginson.sax.xml-writer>0.2</version.com.megginson.sax.xml-writer> |
913 | 976 | <version.commons.cli>1.1</version.commons.cli> |
977 | <version.commons.codec>1.10</version.commons.codec> | |
914 | 978 | <version.commons.io>1.4</version.commons.io> |
915 | 979 | <version.commons.lang>2.4</version.commons.lang> |
916 | 980 | <version.dom4j>1.6.1</version.dom4j> |
917 | 981 | <version.hsqldb>2.2.8</version.hsqldb> |
918 | 982 | <version.javaassist>3.12.1.GA</version.javaassist> |
919 | 983 | <version.javax.activation>1.1.1</version.javax.activation> |
984 | <version.javax.annotation.api>1.3.2</version.javax.annotation.api> | |
985 | <version.javax.xml.bind.api>2.3.1</version.javax.xml.bind.api> | |
920 | 986 | <version.jmock>1.0.1</version.jmock> |
921 | 987 | <version.joda-time>1.6</version.joda-time> |
922 | 988 | <version.junit>3.8.1</version.junit> |
928 | 994 | <version.org.jdom>1.1.3</version.org.jdom> |
929 | 995 | <version.org.jdom2>2.0.5</version.org.jdom2> |
930 | 996 | <version.org.json>20080701</version.org.json> |
931 | <version.org.openjdk.jmh>1.11.1</version.org.openjdk.jmh> | |
997 | <version.org.openjdk.jmh>1.21</version.org.openjdk.jmh> | |
932 | 998 | <version.org.slf4j>1.6.1</version.org.slf4j> |
933 | 999 | <version.oro>2.0.8</version.oro> |
934 | 1000 | <version.stax>1.2.0</version.stax> |
939 | 1005 | <version.xom>1.1</version.xom> |
940 | 1006 | <version.xpp3>1.1.4c</version.xpp3> |
941 | 1007 | |
942 | <link.javadoc.javase>http://docs.oracle.com/javase/8/docs/api/</link.javadoc.javase> | |
943 | ||
1008 | <javadoc.link.javase>http://docs.oracle.com/javase/8/docs/api/</javadoc.link.javase> | |
1009 | <surefire.illegal.access>permit</surefire.illegal.access> | |
1010 | ||
1011 | <argLine>${surefire.argline}</argLine> | |
944 | 1012 | <javadoc.xdoclint /> |
1013 | <surefire.argline /> | |
945 | 1014 | </properties> |
946 | 1015 | </project> |
0 | 0 | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> |
1 | 1 | <!-- |
2 | 2 | Copyright (C) 2006 Joe Walnes. |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 XStream committers. | |
4 | 4 | All rights reserved. |
5 | 5 | |
6 | 6 | The software in this package is published under the terms of the BSD |
13 | 13 | <parent> |
14 | 14 | <groupId>com.thoughtworks.xstream</groupId> |
15 | 15 | <artifactId>xstream-parent</artifactId> |
16 | <version>1.4.9</version> | |
16 | <version>1.4.11.1</version> | |
17 | 17 | </parent> |
18 | 18 | <artifactId>xstream</artifactId> |
19 | 19 | <packaging>jar</packaging> |
78 | 78 | <optional>true</optional> |
79 | 79 | </dependency> |
80 | 80 | |
81 | <!-- Registers itself as Service like Xpp3 | |
81 | 82 | <dependency> |
82 | 83 | <groupId>net.sf.kxml</groupId> |
83 | 84 | <artifactId>kxml2</artifactId> |
84 | 85 | <optional>true</optional> |
85 | 86 | </dependency> |
87 | --> | |
86 | 88 | |
87 | 89 | <dependency> |
88 | 90 | <groupId>xpp3</groupId> |
104 | 106 | <dependency> |
105 | 107 | <groupId>javax.activation</groupId> |
106 | 108 | <artifactId>activation</artifactId> |
109 | <optional>true</optional> | |
110 | </dependency> | |
111 | <dependency> | |
112 | <groupId>javax.xml.bind</groupId> | |
113 | <artifactId>jaxb-api</artifactId> | |
114 | <scope>provided</scope><!-- only required for compilation with Java 11 or higher, but only used by Java 7 or below --> | |
107 | 115 | </dependency> |
108 | 116 | |
109 | 117 | <!-- test-scoped --> |
205 | 213 | |
206 | 214 | <profiles> |
207 | 215 | <profile> |
208 | <id>jdk18ge</id> | |
216 | <id>jdk11-ge</id> | |
217 | <activation> | |
218 | <jdk>[11,)</jdk> | |
219 | </activation> | |
220 | <build> | |
221 | <plugins> | |
222 | <plugin> | |
223 | <groupId>org.apache.maven.plugins</groupId> | |
224 | <artifactId>maven-surefire-plugin</artifactId> | |
225 | <dependencies> | |
226 | <dependency> | |
227 | <groupId>javax.xml.bind</groupId> | |
228 | <artifactId>jaxb-api</artifactId> | |
229 | <version>${version.javax.xml.bind.api}</version> | |
230 | </dependency> | |
231 | </dependencies> | |
232 | </plugin> | |
233 | </plugins> | |
234 | </build> | |
235 | <properties> | |
236 | <surefire.argline>--illegal-access=${surefire.illegal.access}</surefire.argline> | |
237 | </properties> | |
238 | </profile> | |
239 | <profile> | |
240 | <id>jdk9-ge-jdk10</id> | |
241 | <activation> | |
242 | <jdk>[9,11)</jdk> | |
243 | </activation> | |
244 | <properties> | |
245 | <surefire.argline>--add-modules java.activation,java.xml.bind --illegal-access=${surefire.illegal.access}</surefire.argline> | |
246 | </properties> | |
247 | </profile> | |
248 | <profile> | |
249 | <id>jdk18-ge</id> | |
209 | 250 | <activation> |
210 | 251 | <jdk>[1.8,)</jdk> |
211 | 252 | </activation> |
220 | 261 | </compilerArgs> |
221 | 262 | <excludes> |
222 | 263 | <exclude>**/Lambda**</exclude> |
264 | <exclude>**/time/**</exclude> | |
265 | <exclude>**/ISO8601JavaTimeConverter.java</exclude> | |
266 | <exclude>**/annotations/*</exclude> | |
267 | <exclude>**/AnnotationMapper*</exclude> | |
268 | <exclude>**/enums/*</exclude> | |
269 | <exclude>**/EnumMapper*</exclude> | |
270 | <exclude>**/*15.java</exclude> | |
271 | <exclude>**/PathConverter.java</exclude> | |
272 | <exclude>**/Base64*Codec.java</exclude> | |
273 | <exclude>**/Types.java</exclude> | |
274 | <exclude>**/JDom2*.java</exclude> | |
223 | 275 | </excludes> |
224 | 276 | <testExcludes> |
225 | 277 | <exclude>**/Lambda**</exclude> |
278 | <exclude>**/*18TypesTest.java</exclude> | |
279 | <exclude>**/*17TypesTest.java</exclude> | |
280 | <exclude>**/*15TypesTest.java</exclude> | |
281 | <exclude>**/FieldDictionaryTest.java</exclude> | |
282 | <exclude>**/annotations/*</exclude> | |
283 | <exclude>**/enums/*</exclude> | |
226 | 284 | </testExcludes> |
227 | 285 | </configuration> |
228 | 286 | <executions> |
229 | 287 | <execution> |
230 | <id>compile-jdk18</id> | |
288 | <id>compile-jdk15</id> | |
231 | 289 | <configuration> |
232 | <source>1.8</source> | |
233 | <target>1.8</target> | |
234 | <excludes> | |
235 | <exclude>foo</exclude> | |
290 | <source>${version.java.5}</source> | |
291 | <target>${version.java.5}</target> | |
292 | <excludes combine.self="override"> | |
293 | <exclude>**/Lambda**</exclude> | |
294 | <exclude>**/time/**</exclude> | |
295 | <exclude>**/ISO8601JavaTimeConverter.java</exclude> | |
236 | 296 | </excludes> |
237 | <testExcludes> | |
238 | <exclude>foo</exclude> | |
297 | <testExcludes combine.self="override"> | |
298 | <exclude>**/Lambda**</exclude> | |
299 | <exclude>**/*18TypesTest.java</exclude> | |
239 | 300 | </testExcludes> |
240 | 301 | </configuration> |
241 | 302 | <goals> |
243 | 304 | <goal>testCompile</goal> |
244 | 305 | </goals> |
245 | 306 | </execution> |
307 | <execution> | |
308 | <id>compile-jdk18</id> | |
309 | <configuration> | |
310 | <source>1.8</source> | |
311 | <target>1.8</target> | |
312 | <excludes combine.self="override" /> | |
313 | <textExcludes combine.self="override" /> | |
314 | </configuration> | |
315 | <goals> | |
316 | <goal>compile</goal> | |
317 | <goal>testCompile</goal> | |
318 | </goals> | |
319 | </execution> | |
246 | 320 | </executions> |
247 | 321 | </plugin> |
322 | </plugins> | |
323 | </build> | |
324 | </profile> | |
325 | <profile> | |
326 | <id>jdk18</id> | |
327 | <activation> | |
328 | <jdk>1.8</jdk> | |
329 | </activation> | |
330 | <build> | |
331 | <plugins> | |
248 | 332 | <plugin> |
249 | 333 | <groupId>org.apache.maven.plugins</groupId> |
250 | 334 | <artifactId>maven-javadoc-plugin</artifactId> |
251 | 335 | <configuration> |
336 | <source>1.8</source> | |
252 | 337 | <excludePackageNames>com.thoughtworks.xstream.core.util</excludePackageNames> |
253 | 338 | </configuration> |
254 | 339 | </plugin> |
264 | 349 | <excludePackageNames>com.thoughtworks.xstream.core.util</excludePackageNames> |
265 | 350 | <additionalparam>${javadoc.xdoclint}</additionalparam> |
266 | 351 | <detectJavaApiLink>false</detectJavaApiLink> |
267 | <source>${version.java.source}</source> | |
352 | <source>1.8</source> | |
268 | 353 | <links> |
269 | <link>${link.javadoc.javase}</link> | |
354 | <link>${javadoc.link.javase}</link> | |
270 | 355 | </links> |
271 | 356 | </configuration> |
272 | 357 | </plugin> |
289 | 374 | </compilerArgs> |
290 | 375 | <excludes> |
291 | 376 | <exclude>**/Lambda**</exclude> |
377 | <exclude>**/time/**</exclude> | |
378 | <exclude>**/ISO8601JavaTimeConverter.java</exclude> | |
379 | <exclude>**/Base64JavaUtilCodec.java</exclude> | |
292 | 380 | </excludes> |
293 | 381 | <testExcludes> |
294 | 382 | <exclude>**/Lambda**</exclude> |
383 | <exclude>**/Base64JavaUtilCodecTest.java</exclude> | |
384 | <exclude>**/*18TypesTest.java</exclude> | |
295 | 385 | </testExcludes> |
296 | 386 | </configuration> |
297 | 387 | </plugin> |
298 | </plugins> | |
299 | </build> | |
300 | </profile> | |
301 | <profile> | |
302 | <id>jdk15-16</id> | |
303 | <activation> | |
304 | <jdk>[1.5,1.7)</jdk> | |
388 | <plugin><!-- required for Maven Central --> | |
389 | <groupId>org.apache.maven.plugins</groupId> | |
390 | <artifactId>maven-javadoc-plugin</artifactId> | |
391 | <configuration> | |
392 | <source>1.7</source> | |
393 | <excludePackageNames>com.thoughtworks.xstream.core.util</excludePackageNames> | |
394 | </configuration> | |
395 | </plugin> | |
396 | </plugins> | |
397 | </build> | |
398 | </profile> | |
399 | <profile> | |
400 | <id>jdk16</id> | |
401 | <activation> | |
402 | <jdk>1.6</jdk> | |
305 | 403 | </activation> |
306 | 404 | <build> |
307 | 405 | <plugins> |
315 | 413 | <excludes> |
316 | 414 | <exclude>**/Lambda**</exclude> |
317 | 415 | <exclude>**/extended/PathConverter*</exclude> |
416 | <exclude>**/time/**</exclude> | |
417 | <exclude>**/ISO8601JavaTimeConverter.java</exclude> | |
418 | <exclude>**/Base64JavaUtilCodec.java</exclude> | |
318 | 419 | </excludes> |
319 | 420 | <testExcludes> |
320 | 421 | <exclude>**/Lambda**</exclude> |
422 | <exclude>**/extended/*17Test*</exclude> | |
423 | <exclude>**/Base64JavaUtilCodecTest.java</exclude> | |
321 | 424 | <exclude>**/acceptance/Extended17TypesTest*</exclude> |
425 | <exclude>**/acceptance/*18TypesTest.java</exclude> | |
426 | </testExcludes> | |
427 | </configuration> | |
428 | </plugin> | |
429 | </plugins> | |
430 | </build> | |
431 | </profile> | |
432 | <profile> | |
433 | <id>jdk15</id> | |
434 | <activation> | |
435 | <jdk>1.5</jdk> | |
436 | </activation> | |
437 | <build> | |
438 | <plugins> | |
439 | <plugin> | |
440 | <groupId>org.apache.maven.plugins</groupId> | |
441 | <artifactId>maven-compiler-plugin</artifactId> | |
442 | <configuration> | |
443 | <compilerArgs> | |
444 | <arg>-XDignore.symbol.file</arg> | |
445 | </compilerArgs> | |
446 | <excludes> | |
447 | <exclude>**/Lambda**</exclude> | |
448 | <exclude>**/extended/PathConverter*</exclude> | |
449 | <exclude>**/time/**</exclude> | |
450 | <exclude>**/ISO8601JavaTimeConverter.java</exclude> | |
451 | <exclude>**/Base64JavaUtilCodec.java</exclude> | |
452 | <exclude>**/Base64JAXBCodec.java</exclude> | |
453 | </excludes> | |
454 | <testExcludes> | |
455 | <exclude>**/Lambda**</exclude> | |
322 | 456 | <exclude>**/extended/*17Test*</exclude> |
457 | <exclude>**/Base64JavaUtilCodecTest.java</exclude> | |
458 | <exclude>**/Base64JAXBCodecTest.java</exclude> | |
459 | <exclude>**/acceptance/Extended17TypesTest*</exclude> | |
460 | <exclude>**/acceptance/*18TypesTest.java</exclude> | |
323 | 461 | </testExcludes> |
324 | 462 | </configuration> |
325 | 463 | </plugin> |
327 | 465 | </build> |
328 | 466 | </profile> |
329 | 467 | <profile> |
330 | <id>jdk15-ge</id> | |
331 | <activation> | |
332 | <jdk>[1.5,)</jdk> | |
468 | <id>jdk16-ge</id> | |
469 | <activation> | |
470 | <jdk>[1.6,)</jdk> | |
333 | 471 | </activation> |
334 | 472 | <build> |
335 | 473 | <plugins> |
383 | 521 | <exclude>**/AnnotationMapper*</exclude> |
384 | 522 | <exclude>**/EnumMapper*</exclude> |
385 | 523 | <exclude>**/enums/*</exclude> |
524 | <exclude>**/time/**</exclude> | |
525 | <exclude>**/ISO8601JavaTimeConverter.java</exclude> | |
526 | <exclude>**/Base64JavaUtilCodec.java</exclude> | |
527 | <exclude>**/Base64JAXBCodec.java</exclude> | |
386 | 528 | <exclude>**/basic/StringBuilder*</exclude> |
387 | 529 | <exclude>**/basic/UUID*</exclude> |
388 | 530 | <exclude>**/core/util/Types*</exclude> |
531 | <exclude>**/reflection/*15*</exclude> | |
389 | 532 | <exclude>**/extended/*15*</exclude> |
390 | 533 | <exclude>**/extended/PathConverter*</exclude> |
391 | 534 | <exclude>**/io/xml/JDom2*</exclude> |
397 | 540 | <exclude>**/extended/*17Test*</exclude> |
398 | 541 | <exclude>**/reflection/SunLimitedUnsafeReflectionProviderTest*</exclude> |
399 | 542 | <exclude>**/reflection/PureJavaReflectionProvider15Test*</exclude> |
543 | <exclude>**/Base64JavaUtilCodecTest.java</exclude> | |
544 | <exclude>**/Base64JAXBCodecTest.java</exclude> | |
400 | 545 | <exclude>**/io/xml/JDom2*Test*</exclude> |
401 | 546 | <exclude>**/acceptance/Basic15TypesTest*</exclude> |
402 | 547 | <exclude>**/acceptance/Concurrent15TypesTest*</exclude> |
403 | 548 | <exclude>**/acceptance/Extended17TypesTest*</exclude> |
549 | <exclude>**/acceptance/*18TypesTest.java</exclude> | |
404 | 550 | </testExcludes> |
405 | 551 | </configuration> |
406 | 552 | </plugin> |
430 | 576 | <version>${version.plugin.maven.surefire}</version> |
431 | 577 | </plugin> |
432 | 578 | <plugin> |
433 | <groupId>org.codehaus.mojo</groupId> | |
434 | <artifactId>cobertura-maven-plugin</artifactId> | |
435 | <version>${version.plugin.mojo.cobertura}</version> | |
579 | <groupId>org.jacoco</groupId> | |
580 | <artifactId>jacoco-maven-plugin</artifactId> | |
581 | <version>${version.plugin.jacoco}</version> | |
582 | <reportSets> | |
583 | <reportSet> | |
584 | <reports> | |
585 | <report>report</report> | |
586 | </reports> | |
587 | </reportSet> | |
588 | </reportSets> | |
436 | 589 | </plugin> |
437 | 590 | </plugins> |
438 | 591 | </reporting> |
439 | 592 | |
440 | 593 | <properties> |
441 | 594 | <bundle.export.package>!com.thoughtworks.xstream.core.util,com.thoughtworks.xstream.*;-noimport:=true</bundle.export.package> |
595 | <bundle.import.package>org.xmlpull.mxp1;resolution:=optional,org.xmlpull.v1;resolution:=optional,*</bundle.import.package> | |
442 | 596 | </properties> |
443 | 597 | |
444 | 598 | </project> |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
25 | 25 | import java.io.Writer; |
26 | 26 | import java.lang.reflect.Constructor; |
27 | 27 | import java.lang.reflect.Field; |
28 | import java.lang.reflect.InvocationTargetException; | |
29 | import java.lang.reflect.Member; | |
28 | 30 | import java.lang.reflect.Method; |
29 | 31 | import java.math.BigDecimal; |
30 | 32 | import java.math.BigInteger; |
31 | 33 | import java.net.URI; |
32 | 34 | import java.net.URL; |
35 | import java.nio.charset.Charset; | |
36 | import java.text.DecimalFormatSymbols; | |
33 | 37 | import java.util.ArrayList; |
34 | 38 | import java.util.BitSet; |
35 | 39 | import java.util.Calendar; |
40 | import java.util.Collection; | |
36 | 41 | import java.util.Collections; |
42 | import java.util.Currency; | |
37 | 43 | import java.util.Date; |
38 | 44 | import java.util.GregorianCalendar; |
39 | 45 | import java.util.HashMap; |
40 | 46 | import java.util.HashSet; |
41 | 47 | import java.util.Hashtable; |
48 | import java.util.Iterator; | |
42 | 49 | import java.util.LinkedList; |
43 | 50 | import java.util.List; |
44 | 51 | import java.util.Locale; |
46 | 53 | import java.util.Properties; |
47 | 54 | import java.util.Set; |
48 | 55 | import java.util.SortedSet; |
56 | import java.util.TimeZone; | |
49 | 57 | import java.util.TreeMap; |
50 | 58 | import java.util.TreeSet; |
51 | 59 | import java.util.Vector; |
56 | 64 | import com.thoughtworks.xstream.converters.ConverterLookup; |
57 | 65 | import com.thoughtworks.xstream.converters.ConverterRegistry; |
58 | 66 | import com.thoughtworks.xstream.converters.DataHolder; |
67 | import com.thoughtworks.xstream.converters.MarshallingContext; | |
59 | 68 | import com.thoughtworks.xstream.converters.SingleValueConverter; |
60 | 69 | import com.thoughtworks.xstream.converters.SingleValueConverterWrapper; |
70 | import com.thoughtworks.xstream.converters.UnmarshallingContext; | |
61 | 71 | import com.thoughtworks.xstream.converters.basic.BigDecimalConverter; |
62 | 72 | import com.thoughtworks.xstream.converters.basic.BigIntegerConverter; |
63 | 73 | import com.thoughtworks.xstream.converters.basic.BooleanConverter; |
128 | 138 | import com.thoughtworks.xstream.mapper.DefaultImplementationsMapper; |
129 | 139 | import com.thoughtworks.xstream.mapper.DefaultMapper; |
130 | 140 | import com.thoughtworks.xstream.mapper.DynamicProxyMapper; |
141 | import com.thoughtworks.xstream.mapper.ElementIgnoringMapper; | |
131 | 142 | import com.thoughtworks.xstream.mapper.FieldAliasingMapper; |
132 | 143 | import com.thoughtworks.xstream.mapper.ImmutableTypesMapper; |
133 | 144 | import com.thoughtworks.xstream.mapper.ImplicitCollectionMapper; |
140 | 151 | import com.thoughtworks.xstream.mapper.SystemAttributeAliasingMapper; |
141 | 152 | import com.thoughtworks.xstream.mapper.XStream11XmlFriendlyMapper; |
142 | 153 | import com.thoughtworks.xstream.security.AnyTypePermission; |
154 | import com.thoughtworks.xstream.security.ArrayTypePermission; | |
143 | 155 | import com.thoughtworks.xstream.security.ExplicitTypePermission; |
156 | import com.thoughtworks.xstream.security.InterfaceTypePermission; | |
144 | 157 | import com.thoughtworks.xstream.security.NoPermission; |
145 | 158 | import com.thoughtworks.xstream.security.NoTypePermission; |
159 | import com.thoughtworks.xstream.security.NullPermission; | |
160 | import com.thoughtworks.xstream.security.PrimitiveTypePermission; | |
146 | 161 | import com.thoughtworks.xstream.security.RegExpTypePermission; |
147 | 162 | import com.thoughtworks.xstream.security.TypeHierarchyPermission; |
148 | 163 | import com.thoughtworks.xstream.security.TypePermission; |
311 | 326 | private PackageAliasingMapper packageAliasingMapper; |
312 | 327 | private ClassAliasingMapper classAliasingMapper; |
313 | 328 | private FieldAliasingMapper fieldAliasingMapper; |
329 | private ElementIgnoringMapper elementIgnoringMapper; | |
314 | 330 | private AttributeAliasingMapper attributeAliasingMapper; |
315 | 331 | private SystemAttributeAliasingMapper systemAttributeAliasingMapper; |
316 | 332 | private AttributeMapper attributeMapper; |
320 | 336 | private LocalConversionMapper localConversionMapper; |
321 | 337 | private SecurityMapper securityMapper; |
322 | 338 | private AnnotationConfiguration annotationConfiguration; |
339 | ||
340 | private transient boolean securityInitialized; | |
341 | private transient boolean securityWarningGiven; | |
323 | 342 | |
324 | 343 | public static final int NO_REFERENCES = 1001; |
325 | 344 | public static final int ID_REFERENCES = 1002; |
583 | 602 | mapper = new DynamicProxyMapper(mapper); |
584 | 603 | mapper = new PackageAliasingMapper(mapper); |
585 | 604 | mapper = new ClassAliasingMapper(mapper); |
605 | mapper = new ElementIgnoringMapper(mapper); | |
586 | 606 | mapper = new FieldAliasingMapper(mapper); |
587 | 607 | mapper = new AttributeAliasingMapper(mapper); |
588 | 608 | mapper = new SystemAttributeAliasingMapper(mapper); |
589 | mapper = new ImplicitCollectionMapper(mapper); | |
609 | mapper = new ImplicitCollectionMapper(mapper, reflectionProvider); | |
590 | 610 | mapper = new OuterClassMapper(mapper); |
591 | 611 | mapper = new ArrayMapper(mapper); |
592 | 612 | mapper = new DefaultImplementationsMapper(mapper); |
593 | 613 | mapper = new AttributeMapper(mapper, converterLookup, reflectionProvider); |
594 | if (JVM.is15()) { | |
614 | if (JVM.isVersion(5)) { | |
595 | 615 | mapper = buildMapperDynamically( |
596 | 616 | "com.thoughtworks.xstream.mapper.EnumMapper", new Class[]{Mapper.class}, |
597 | 617 | new Object[]{mapper}); |
598 | 618 | } |
599 | 619 | mapper = new LocalConversionMapper(mapper); |
600 | 620 | mapper = new ImmutableTypesMapper(mapper); |
601 | if (JVM.is18()) { | |
602 | mapper = | |
603 | buildMapperDynamically("com.thoughtworks.xstream.mapper.LambdaMapper", new Class[]{Mapper.class}, | |
604 | new Object[]{mapper}); | |
621 | if (JVM.isVersion(8)) { | |
622 | mapper = buildMapperDynamically("com.thoughtworks.xstream.mapper.LambdaMapper", new Class[]{Mapper.class}, | |
623 | new Object[]{mapper}); | |
605 | 624 | } |
606 | 625 | mapper = new SecurityMapper(mapper); |
607 | if (JVM.is15()) { | |
626 | if (JVM.isVersion(5)) { | |
608 | 627 | mapper = buildMapperDynamically(ANNOTATION_MAPPER_TYPE, new Class[]{ |
609 | 628 | Mapper.class, ConverterRegistry.class, ConverterLookup.class, |
610 | 629 | ClassLoaderReference.class, ReflectionProvider.class}, new Object[]{ |
647 | 666 | .lookupMapperOfType(PackageAliasingMapper.class); |
648 | 667 | classAliasingMapper = (ClassAliasingMapper)this.mapper |
649 | 668 | .lookupMapperOfType(ClassAliasingMapper.class); |
669 | elementIgnoringMapper = (ElementIgnoringMapper)this.mapper | |
670 | .lookupMapperOfType(ElementIgnoringMapper.class); | |
650 | 671 | fieldAliasingMapper = (FieldAliasingMapper)this.mapper |
651 | 672 | .lookupMapperOfType(FieldAliasingMapper.class); |
652 | 673 | attributeMapper = (AttributeMapper)this.mapper |
675 | 696 | } |
676 | 697 | |
677 | 698 | addPermission(AnyTypePermission.ANY); |
699 | securityInitialized = false; | |
700 | } | |
701 | ||
702 | /** | |
703 | * Setup the security framework of a XStream instance. | |
704 | * <p> | |
705 | * This method is a pure helper method for XStream 1.4.x. It initializes an XStream instance with a white list of | |
706 | * well-known and simply types of the Java runtime as it is done in XStream 1.5.x by default. This method will do | |
707 | * therefore nothing in XStream 1.5. | |
708 | * </p> | |
709 | * | |
710 | * @param xstream | |
711 | * @since 1.4.10 | |
712 | */ | |
713 | public static void setupDefaultSecurity(final XStream xstream) { | |
714 | if (!xstream.securityInitialized) { | |
715 | xstream.addPermission(NoTypePermission.NONE); | |
716 | xstream.addPermission(NullPermission.NULL); | |
717 | xstream.addPermission(PrimitiveTypePermission.PRIMITIVES); | |
718 | xstream.addPermission(ArrayTypePermission.ARRAYS); | |
719 | xstream.addPermission(InterfaceTypePermission.INTERFACES); | |
720 | xstream.allowTypeHierarchy(Calendar.class); | |
721 | xstream.allowTypeHierarchy(Collection.class); | |
722 | xstream.allowTypeHierarchy(Map.class); | |
723 | xstream.allowTypeHierarchy(Map.Entry.class); | |
724 | xstream.allowTypeHierarchy(Member.class); | |
725 | xstream.allowTypeHierarchy(Number.class); | |
726 | xstream.allowTypeHierarchy(Throwable.class); | |
727 | xstream.allowTypeHierarchy(TimeZone.class); | |
728 | ||
729 | Class type = JVM.loadClassForName("java.lang.Enum"); | |
730 | if (type != null) { | |
731 | xstream.allowTypeHierarchy(type); | |
732 | } | |
733 | type = JVM.loadClassForName("java.nio.file.Path"); | |
734 | if (type != null) { | |
735 | xstream.allowTypeHierarchy(type); | |
736 | } | |
737 | ||
738 | final Set types = new HashSet(); | |
739 | types.add(BitSet.class); | |
740 | types.add(Charset.class); | |
741 | types.add(Class.class); | |
742 | types.add(Currency.class); | |
743 | types.add(Date.class); | |
744 | types.add(DecimalFormatSymbols.class); | |
745 | types.add(File.class); | |
746 | types.add(Locale.class); | |
747 | types.add(Object.class); | |
748 | types.add(Pattern.class); | |
749 | types.add(StackTraceElement.class); | |
750 | types.add(String.class); | |
751 | types.add(StringBuffer.class); | |
752 | types.add(JVM.loadClassForName("java.lang.StringBuilder")); | |
753 | types.add(URL.class); | |
754 | types.add(URI.class); | |
755 | types.add(JVM.loadClassForName("java.util.UUID")); | |
756 | if (JVM.isSQLAvailable()) { | |
757 | types.add(JVM.loadClassForName("java.sql.Timestamp")); | |
758 | types.add(JVM.loadClassForName("java.sql.Time")); | |
759 | types.add(JVM.loadClassForName("java.sql.Date")); | |
760 | } | |
761 | if (JVM.isVersion(8)) { | |
762 | xstream.allowTypeHierarchy(JVM.loadClassForName("java.time.Clock")); | |
763 | types.add(JVM.loadClassForName("java.time.Duration")); | |
764 | types.add(JVM.loadClassForName("java.time.Instant")); | |
765 | types.add(JVM.loadClassForName("java.time.LocalDate")); | |
766 | types.add(JVM.loadClassForName("java.time.LocalDateTime")); | |
767 | types.add(JVM.loadClassForName("java.time.LocalTime")); | |
768 | types.add(JVM.loadClassForName("java.time.MonthDay")); | |
769 | types.add(JVM.loadClassForName("java.time.OffsetDateTime")); | |
770 | types.add(JVM.loadClassForName("java.time.OffsetTime")); | |
771 | types.add(JVM.loadClassForName("java.time.Period")); | |
772 | types.add(JVM.loadClassForName("java.time.Ser")); | |
773 | types.add(JVM.loadClassForName("java.time.Year")); | |
774 | types.add(JVM.loadClassForName("java.time.YearMonth")); | |
775 | types.add(JVM.loadClassForName("java.time.ZonedDateTime")); | |
776 | xstream.allowTypeHierarchy(JVM.loadClassForName("java.time.ZoneId")); | |
777 | types.add(JVM.loadClassForName("java.time.chrono.HijrahDate")); | |
778 | types.add(JVM.loadClassForName("java.time.chrono.JapaneseDate")); | |
779 | types.add(JVM.loadClassForName("java.time.chrono.JapaneseEra")); | |
780 | types.add(JVM.loadClassForName("java.time.chrono.MinguoDate")); | |
781 | types.add(JVM.loadClassForName("java.time.chrono.ThaiBuddhistDate")); | |
782 | types.add(JVM.loadClassForName("java.time.chrono.Ser")); | |
783 | xstream.allowTypeHierarchy(JVM.loadClassForName("java.time.chrono.Chronology")); | |
784 | types.add(JVM.loadClassForName("java.time.temporal.ValueRange")); | |
785 | types.add(JVM.loadClassForName("java.time.temporal.WeekFields")); | |
786 | } | |
787 | types.remove(null); | |
788 | ||
789 | final Iterator iter = types.iterator(); | |
790 | final Class[] classes = new Class[types.size()]; | |
791 | for (int i = 0; i < classes.length; ++i) { | |
792 | classes[i] = (Class)iter.next(); | |
793 | } | |
794 | xstream.allowTypes(classes); | |
795 | } else { | |
796 | throw new IllegalArgumentException("Security framework of XStream instance already initialized"); | |
797 | } | |
678 | 798 | } |
679 | 799 | |
680 | 800 | protected void setupAliases() { |
734 | 854 | alias("awt-color", JVM.loadClassForName("java.awt.Color", false)); |
735 | 855 | alias("awt-font", JVM.loadClassForName("java.awt.Font", false)); |
736 | 856 | alias("awt-text-attribute", JVM.loadClassForName("java.awt.font.TextAttribute")); |
737 | ||
738 | // only available in Java 5 when javax.activation:activation is available on CP | |
739 | Class type = JVM.loadClassForName("javax.activation.ActivationDataFlavor"); | |
740 | if (type != null) { | |
741 | alias("activation-data-flavor", type); | |
742 | } | |
857 | } | |
858 | ||
859 | Class type = JVM.loadClassForName("javax.activation.ActivationDataFlavor"); | |
860 | if (type != null) { | |
861 | alias("activation-data-flavor", type); | |
743 | 862 | } |
744 | 863 | |
745 | 864 | if (JVM.isSQLAvailable()) { |
752 | 871 | alias("locale", Locale.class); |
753 | 872 | alias("gregorian-calendar", Calendar.class); |
754 | 873 | |
755 | if (JVM.is14()) { | |
874 | if (JVM.isVersion(4)) { | |
756 | 875 | aliasDynamically("auth-subject", "javax.security.auth.Subject"); |
757 | 876 | alias("linked-hash-map", JVM.loadClassForName("java.util.LinkedHashMap")); |
758 | 877 | alias("linked-hash-set", JVM.loadClassForName("java.util.LinkedHashSet")); |
761 | 880 | aliasType("charset", JVM.loadClassForName("java.nio.charset.Charset")); |
762 | 881 | } |
763 | 882 | |
764 | if (JVM.is15()) { | |
765 | aliasDynamically("duration", "javax.xml.datatype.Duration"); | |
883 | if (JVM.isVersion(5)) { | |
884 | aliasDynamically("xml-duration", "javax.xml.datatype.Duration"); | |
766 | 885 | alias("concurrent-hash-map", JVM.loadClassForName("java.util.concurrent.ConcurrentHashMap")); |
767 | 886 | alias("enum-set", JVM.loadClassForName("java.util.EnumSet")); |
768 | 887 | alias("enum-map", JVM.loadClassForName("java.util.EnumMap")); |
770 | 889 | alias("uuid", JVM.loadClassForName("java.util.UUID")); |
771 | 890 | } |
772 | 891 | |
773 | if (JVM.is17()) { | |
892 | if (JVM.isVersion(7)) { | |
774 | 893 | aliasType("path", JVM.loadClassForName("java.nio.file.Path")); |
775 | 894 | } |
776 | ||
895 | ||
896 | if (JVM.isVersion(8)) { | |
897 | alias("fixed-clock", JVM.loadClassForName("java.time.Clock$FixedClock")); | |
898 | alias("offset-clock", JVM.loadClassForName("java.time.Clock$OffsetClock")); | |
899 | alias("system-clock", JVM.loadClassForName("java.time.Clock$SystemClock")); | |
900 | alias("tick-clock", JVM.loadClassForName("java.time.Clock$TickClock")); | |
901 | alias("day-of-week", JVM.loadClassForName("java.time.DayOfWeek")); | |
902 | alias("duration", JVM.loadClassForName("java.time.Duration")); | |
903 | alias("instant", JVM.loadClassForName("java.time.Instant")); | |
904 | alias("local-date", JVM.loadClassForName("java.time.LocalDate")); | |
905 | alias("local-date-time", JVM.loadClassForName("java.time.LocalDateTime")); | |
906 | alias("local-time", JVM.loadClassForName("java.time.LocalTime")); | |
907 | alias("month", JVM.loadClassForName("java.time.Month")); | |
908 | alias("month-day", JVM.loadClassForName("java.time.MonthDay")); | |
909 | alias("offset-date-time", JVM.loadClassForName("java.time.OffsetDateTime")); | |
910 | alias("offset-time", JVM.loadClassForName("java.time.OffsetTime")); | |
911 | alias("period", JVM.loadClassForName("java.time.Period")); | |
912 | alias("year", JVM.loadClassForName("java.time.Year")); | |
913 | alias("year-month", JVM.loadClassForName("java.time.YearMonth")); | |
914 | alias("zoned-date-time", JVM.loadClassForName("java.time.ZonedDateTime")); | |
915 | aliasType("zone-id", JVM.loadClassForName("java.time.ZoneId")); | |
916 | aliasType("chronology", JVM.loadClassForName("java.time.chrono.Chronology")); | |
917 | alias("hijrah-date", JVM.loadClassForName("java.time.chrono.HijrahDate")); | |
918 | alias("hijrah-era", JVM.loadClassForName("java.time.chrono.HijrahEra")); | |
919 | alias("japanese-date", JVM.loadClassForName("java.time.chrono.JapaneseDate")); | |
920 | alias("japanese-era", JVM.loadClassForName("java.time.chrono.JapaneseEra")); | |
921 | alias("minguo-date", JVM.loadClassForName("java.time.chrono.MinguoDate")); | |
922 | alias("minguo-era", JVM.loadClassForName("java.time.chrono.MinguoEra")); | |
923 | alias("thai-buddhist-date", JVM.loadClassForName("java.time.chrono.ThaiBuddhistDate")); | |
924 | alias("thai-buddhist-era", JVM.loadClassForName("java.time.chrono.ThaiBuddhistEra")); | |
925 | alias("chrono-field", JVM.loadClassForName("java.time.temporal.ChronoField")); | |
926 | alias("chrono-unit", JVM.loadClassForName("java.time.temporal.ChronoUnit")); | |
927 | alias("iso-field", JVM.loadClassForName("java.time.temporal.IsoFields$Field")); | |
928 | alias("iso-unit", JVM.loadClassForName("java.time.temporal.IsoFields$Unit")); | |
929 | alias("julian-field", JVM.loadClassForName("java.time.temporal.JulianFields$Field")); | |
930 | alias("temporal-value-range", JVM.loadClassForName("java.time.temporal.ValueRange")); | |
931 | alias("week-fields", JVM.loadClassForName("java.time.temporal.WeekFields")); | |
932 | } | |
933 | ||
777 | 934 | if (JVM.loadClassForName("java.lang.invoke.SerializedLambda") != null) { |
778 | 935 | aliasDynamically("serialized-lambda", "java.lang.invoke.SerializedLambda"); |
779 | 936 | } |
804 | 961 | registerConverter( |
805 | 962 | new SerializableConverter(mapper, reflectionProvider, classLoaderReference), PRIORITY_LOW); |
806 | 963 | registerConverter(new ExternalizableConverter(mapper, classLoaderReference), PRIORITY_LOW); |
964 | registerConverter(new InternalBlackList(), PRIORITY_LOW); | |
807 | 965 | |
808 | 966 | registerConverter(new NullConverter(), PRIORITY_VERY_HIGH); |
809 | 967 | registerConverter(new IntConverter(), PRIORITY_NORMAL); |
841 | 999 | registerConverter(new SqlTimeConverter(), PRIORITY_NORMAL); |
842 | 1000 | registerConverter(new SqlDateConverter(), PRIORITY_NORMAL); |
843 | 1001 | } |
844 | registerConverter( | |
845 | new DynamicProxyConverter(mapper, classLoaderReference), PRIORITY_NORMAL); | |
1002 | registerConverter(new DynamicProxyConverter(mapper, classLoaderReference), PRIORITY_NORMAL); | |
846 | 1003 | registerConverter(new JavaClassConverter(classLoaderReference), PRIORITY_NORMAL); |
847 | 1004 | registerConverter(new JavaMethodConverter(classLoaderReference), PRIORITY_NORMAL); |
848 | 1005 | registerConverter(new JavaFieldConverter(classLoaderReference), PRIORITY_NORMAL); |
1006 | ||
849 | 1007 | if (JVM.isAWTAvailable()) { |
850 | 1008 | registerConverter(new FontConverter(mapper), PRIORITY_NORMAL); |
851 | 1009 | registerConverter(new ColorConverter(), PRIORITY_NORMAL); |
858 | 1016 | registerConverter(new LocaleConverter(), PRIORITY_NORMAL); |
859 | 1017 | registerConverter(new GregorianCalendarConverter(), PRIORITY_NORMAL); |
860 | 1018 | |
861 | if (JVM.is14()) { | |
1019 | if (JVM.isVersion(4)) { | |
862 | 1020 | // late bound converters - allows XStream to be compiled on earlier JDKs |
863 | 1021 | registerConverterDynamically( |
864 | 1022 | "com.thoughtworks.xstream.converters.extended.SubjectConverter", |
881 | 1039 | PRIORITY_NORMAL, null, null); |
882 | 1040 | } |
883 | 1041 | |
884 | if (JVM.is15()) { | |
1042 | if (JVM.isVersion(5)) { | |
885 | 1043 | // late bound converters - allows XStream to be compiled on earlier JDKs |
886 | 1044 | if (JVM.loadClassForName("javax.xml.datatype.Duration") != null) { |
887 | 1045 | registerConverterDynamically( |
908 | 1066 | registerConverterDynamically("com.thoughtworks.xstream.converters.extended.ActivationDataFlavorConverter", |
909 | 1067 | PRIORITY_NORMAL, null, null); |
910 | 1068 | } |
911 | if (JVM.is17()) { | |
1069 | if (JVM.isVersion(7)) { | |
912 | 1070 | registerConverterDynamically("com.thoughtworks.xstream.converters.extended.PathConverter", |
913 | 1071 | PRIORITY_NORMAL, null, null); |
914 | 1072 | } |
915 | if (JVM.is18()) { | |
1073 | if (JVM.isVersion(8)) { | |
1074 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.ChronologyConverter", | |
1075 | PRIORITY_NORMAL, null, null); | |
1076 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.DurationConverter", PRIORITY_NORMAL, | |
1077 | null, null); | |
1078 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.HijrahDateConverter", | |
1079 | PRIORITY_NORMAL, null, null); | |
1080 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.JapaneseDateConverter", | |
1081 | PRIORITY_NORMAL, null, null); | |
1082 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.JapaneseEraConverter", | |
1083 | PRIORITY_NORMAL, null, null); | |
1084 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.InstantConverter", PRIORITY_NORMAL, | |
1085 | null, null); | |
1086 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.LocalDateConverter", PRIORITY_NORMAL, | |
1087 | null, null); | |
1088 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.LocalDateTimeConverter", | |
1089 | PRIORITY_NORMAL, null, null); | |
1090 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.LocalTimeConverter", PRIORITY_NORMAL, | |
1091 | null, null); | |
1092 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.MinguoDateConverter", | |
1093 | PRIORITY_NORMAL, null, null); | |
1094 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.MonthDayConverter", PRIORITY_NORMAL, | |
1095 | null, null); | |
1096 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.OffsetDateTimeConverter", | |
1097 | PRIORITY_NORMAL, null, null); | |
1098 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.OffsetTimeConverter", | |
1099 | PRIORITY_NORMAL, null, null); | |
1100 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.PeriodConverter", PRIORITY_NORMAL, | |
1101 | null, null); | |
1102 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.SystemClockConverter", | |
1103 | PRIORITY_NORMAL, new Class[]{Mapper.class}, new Object[]{mapper}); | |
1104 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.ThaiBuddhistDateConverter", | |
1105 | PRIORITY_NORMAL, null, null); | |
1106 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.ValueRangeConverter", | |
1107 | PRIORITY_NORMAL, new Class[]{Mapper.class}, new Object[]{mapper}); | |
1108 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.WeekFieldsConverter", | |
1109 | PRIORITY_NORMAL, new Class[]{Mapper.class}, new Object[]{mapper}); | |
1110 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.YearConverter", PRIORITY_NORMAL, | |
1111 | null, null); | |
1112 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.YearMonthConverter", PRIORITY_NORMAL, | |
1113 | null, null); | |
1114 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.ZonedDateTimeConverter", | |
1115 | PRIORITY_NORMAL, null, null); | |
1116 | registerConverterDynamically("com.thoughtworks.xstream.converters.time.ZoneIdConverter", PRIORITY_NORMAL, | |
1117 | null, null); | |
916 | 1118 | registerConverterDynamically("com.thoughtworks.xstream.converters.reflection.LambdaConverter", |
917 | 1119 | PRIORITY_NORMAL, new Class[]{Mapper.class, ReflectionProvider.class, ClassLoaderReference.class}, |
918 | 1120 | new Object[]{mapper, reflectionProvider, classLoaderReference}); |
974 | 1176 | addImmutableType(File.class, false); |
975 | 1177 | addImmutableType(Class.class, false); |
976 | 1178 | |
1179 | if (JVM.isVersion(7)) { | |
1180 | Class type = JVM.loadClassForName("java.nio.file.Paths"); | |
1181 | if (type != null) { | |
1182 | Method methodGet; | |
1183 | try { | |
1184 | methodGet = type.getDeclaredMethod("get", new Class[] {String.class, String[].class}); | |
1185 | if (methodGet != null) { | |
1186 | Object path = methodGet.invoke(null, new Object[]{".", new String[0]}); | |
1187 | if (path != null) { | |
1188 | addImmutableType(path.getClass(), false); | |
1189 | } | |
1190 | } | |
1191 | } catch (NoSuchMethodException e) { | |
1192 | } catch (SecurityException e) { | |
1193 | } catch (IllegalAccessException e) { | |
1194 | } catch (InvocationTargetException e) { | |
1195 | } | |
1196 | } | |
1197 | } | |
1198 | ||
977 | 1199 | if (JVM.isAWTAvailable()) { |
978 | 1200 | addImmutableTypeDynamically("java.awt.font.TextAttribute", false); |
979 | 1201 | } |
980 | 1202 | |
981 | if (JVM.is14()) { | |
1203 | if (JVM.isVersion(4)) { | |
982 | 1204 | // late bound types - allows XStream to be compiled on earlier JDKs |
983 | 1205 | addImmutableTypeDynamically("java.nio.charset.Charset", true); |
984 | 1206 | addImmutableTypeDynamically("java.util.Currency", true); |
985 | 1207 | } |
986 | 1208 | |
987 | if (JVM.is15()) { | |
1209 | if (JVM.isVersion(5)) { | |
988 | 1210 | addImmutableTypeDynamically("java.util.UUID", true); |
989 | 1211 | } |
990 | 1212 | |
992 | 1214 | addImmutableType(Collections.EMPTY_LIST.getClass(), true); |
993 | 1215 | addImmutableType(Collections.EMPTY_SET.getClass(), true); |
994 | 1216 | addImmutableType(Collections.EMPTY_MAP.getClass(), true); |
1217 | ||
1218 | if (JVM.isVersion(8)) { | |
1219 | addImmutableTypeDynamically("java.time.Duration", false); | |
1220 | addImmutableTypeDynamically("java.time.Instant", false); | |
1221 | addImmutableTypeDynamically("java.time.LocalDate", false); | |
1222 | addImmutableTypeDynamically("java.time.LocalDateTime", false); | |
1223 | addImmutableTypeDynamically("java.time.LocalTime", false); | |
1224 | addImmutableTypeDynamically("java.time.MonthDay", false); | |
1225 | addImmutableTypeDynamically("java.time.OffsetDateTime", false); | |
1226 | addImmutableTypeDynamically("java.time.OffsetTime", false); | |
1227 | addImmutableTypeDynamically("java.time.Period", false); | |
1228 | addImmutableTypeDynamically("java.time.Year", false); | |
1229 | addImmutableTypeDynamically("java.time.YearMonth", false); | |
1230 | addImmutableTypeDynamically("java.time.ZonedDateTime", false); | |
1231 | addImmutableTypeDynamically("java.time.ZoneId", false); | |
1232 | addImmutableTypeDynamically("java.time.ZoneOffset", false); | |
1233 | addImmutableTypeDynamically("java.time.ZoneRegion", false); | |
1234 | addImmutableTypeDynamically("java.time.chrono.HijrahChronology", false); | |
1235 | addImmutableTypeDynamically("java.time.chrono.HijrahDate", false); | |
1236 | addImmutableTypeDynamically("java.time.chrono.IsoChronology", false); | |
1237 | addImmutableTypeDynamically("java.time.chrono.JapaneseChronology", false); | |
1238 | addImmutableTypeDynamically("java.time.chrono.JapaneseDate", false); | |
1239 | addImmutableTypeDynamically("java.time.chrono.JapaneseEra", false); | |
1240 | addImmutableTypeDynamically("java.time.chrono.MinguoChronology", false); | |
1241 | addImmutableTypeDynamically("java.time.chrono.MinguoDate", false); | |
1242 | addImmutableTypeDynamically("java.time.chrono.ThaiBuddhistChronology", false); | |
1243 | addImmutableTypeDynamically("java.time.chrono.ThaiBuddhistDate", false); | |
1244 | addImmutableTypeDynamically("java.time.temporal.IsoFields$Field", false); | |
1245 | addImmutableTypeDynamically("java.time.temporal.IsoFields$Unit", false); | |
1246 | addImmutableTypeDynamically("java.time.temporal.JulianFields$Field", false); | |
1247 | } | |
995 | 1248 | } |
996 | 1249 | |
997 | 1250 | private void addImmutableTypeDynamically(String className, boolean isReferenceable) { |
1226 | 1479 | */ |
1227 | 1480 | public Object unmarshal(HierarchicalStreamReader reader, Object root, DataHolder dataHolder) { |
1228 | 1481 | try { |
1482 | if (!securityInitialized && !securityWarningGiven) { | |
1483 | securityWarningGiven = true; | |
1484 | System.err.println("Security framework of XStream not initialized, XStream is probably vulnerable."); | |
1485 | } | |
1229 | 1486 | return marshallingStrategy.unmarshal( |
1230 | 1487 | root, reader, dataHolder, converterLookup, mapper); |
1231 | 1488 | |
1713 | 1970 | } |
1714 | 1971 | |
1715 | 1972 | /** |
1716 | * Create a DataHolder that can be used to pass data to the converters. The DataHolder is | |
1717 | * provided with a call to {@link #marshal(Object, HierarchicalStreamWriter, DataHolder)} or | |
1718 | * {@link #unmarshal(HierarchicalStreamReader, Object, DataHolder)}. | |
1973 | * Create a DataHolder that can be used to pass data to the converters. The DataHolder is provided with a call to | |
1974 | * {@link #marshal(Object, HierarchicalStreamWriter, DataHolder)}, | |
1975 | * {@link #unmarshal(HierarchicalStreamReader, Object, DataHolder)}, | |
1976 | * {@link #createObjectInputStream(HierarchicalStreamReader, DataHolder)} or | |
1977 | * {@link #createObjectOutputStream(HierarchicalStreamWriter, String, DataHolder)}. | |
1719 | 1978 | * |
1720 | 1979 | * @return a new {@link DataHolder} |
1721 | 1980 | */ |
1833 | 2092 | * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader) |
1834 | 2093 | * @since 1.0.3 |
1835 | 2094 | */ |
1836 | public ObjectOutputStream createObjectOutputStream(final HierarchicalStreamWriter writer, | |
1837 | String rootNodeName) throws IOException { | |
2095 | public ObjectOutputStream createObjectOutputStream(final HierarchicalStreamWriter writer, final String rootNodeName) | |
2096 | throws IOException { | |
2097 | return createObjectOutputStream(writer, rootNodeName, null); | |
2098 | } | |
2099 | ||
2100 | /** | |
2101 | * Creates an ObjectOutputStream that serializes a stream of objects to the writer using XStream. | |
2102 | * | |
2103 | * @see #createObjectOutputStream(com.thoughtworks.xstream.io.HierarchicalStreamWriter, String) | |
2104 | * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader) | |
2105 | * @since 1.4.10 | |
2106 | */ | |
2107 | public ObjectOutputStream createObjectOutputStream(final HierarchicalStreamWriter writer, final String rootNodeName, | |
2108 | final DataHolder dataHolder) throws IOException { | |
1838 | 2109 | final StatefulWriter statefulWriter = new StatefulWriter(writer); |
1839 | 2110 | statefulWriter.startNode(rootNodeName, null); |
1840 | 2111 | return new CustomObjectOutputStream(new CustomObjectOutputStream.StreamCallback() { |
1841 | public void writeToStream(Object object) { | |
1842 | marshal(object, statefulWriter); | |
2112 | public void writeToStream(final Object object) { | |
2113 | marshal(object, statefulWriter, dataHolder); | |
1843 | 2114 | } |
1844 | 2115 | |
1845 | 2116 | public void writeFieldsToStream(Map fields) throws NotActiveException { |
1890 | 2161 | } |
1891 | 2162 | |
1892 | 2163 | /** |
1893 | * Creates an ObjectInputStream that deserializes a stream of objects from a reader using | |
1894 | * XStream. <h3>Example</h3> | |
1895 | * | |
2164 | * Creates an ObjectInputStream that deserializes a stream of objects from a reader using XStream. | |
2165 | * <p> | |
2166 | * It is necessary to call ObjectInputStream.close() when done, otherwise the stream might keep system resources. | |
2167 | * </p> | |
2168 | * <h3>Example</h3> | |
2169 | * | |
1896 | 2170 | * <pre> |
1897 | 2171 | * ObjectInputStream in = xstream.createObjectOutputStream(aReader); |
1898 | 2172 | * int a = out.readInt(); |
1904 | 2178 | * String) |
1905 | 2179 | * @since 1.0.3 |
1906 | 2180 | */ |
1907 | public ObjectInputStream createObjectInputStream(final HierarchicalStreamReader reader) | |
1908 | throws IOException { | |
2181 | public ObjectInputStream createObjectInputStream(final HierarchicalStreamReader reader) throws IOException { | |
2182 | return createObjectInputStream(reader, null); | |
2183 | } | |
2184 | ||
2185 | /** | |
2186 | * Creates an ObjectInputStream that deserializes a stream of objects from a reader using XStream. | |
2187 | * | |
2188 | * @see #createObjectOutputStream(com.thoughtworks.xstream.io.HierarchicalStreamWriter, String) | |
2189 | * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader) | |
2190 | * @since 1.4.10 | |
2191 | */ | |
2192 | public ObjectInputStream createObjectInputStream(final HierarchicalStreamReader reader, final DataHolder dataHolder) | |
2193 | throws IOException { | |
1909 | 2194 | return new CustomObjectInputStream(new CustomObjectInputStream.StreamCallback() { |
1910 | 2195 | public Object readFromStream() throws EOFException { |
1911 | 2196 | if (!reader.hasMoreChildren()) { |
1912 | 2197 | throw new EOFException(); |
1913 | 2198 | } |
1914 | 2199 | reader.moveDown(); |
1915 | Object result = unmarshal(reader); | |
2200 | final Object result = unmarshal(reader, dataHolder); | |
1916 | 2201 | reader.moveUp(); |
1917 | 2202 | return result; |
1918 | 2203 | } |
1975 | 2260 | * declaring type and not necessarily the type that is converted. |
1976 | 2261 | * |
1977 | 2262 | * @since 1.1.3 |
1978 | * @throws InitializationException if no {@link FieldAliasingMapper} is available | |
2263 | * @throws InitializationException if no {@link ElementIgnoringMapper} is available | |
1979 | 2264 | */ |
1980 | 2265 | public void omitField(Class definedIn, String fieldName) { |
1981 | if (fieldAliasingMapper == null) { | |
2266 | if (elementIgnoringMapper == null) { | |
1982 | 2267 | throw new com.thoughtworks.xstream.InitializationException("No " |
1983 | + FieldAliasingMapper.class.getName() | |
2268 | + ElementIgnoringMapper.class.getName() | |
1984 | 2269 | + " available"); |
1985 | 2270 | } |
1986 | fieldAliasingMapper.omitField(definedIn, fieldName); | |
2271 | elementIgnoringMapper.omitField(definedIn, fieldName); | |
1987 | 2272 | } |
1988 | 2273 | |
1989 | 2274 | /** |
2012 | 2297 | * @since 1.4.5 |
2013 | 2298 | */ |
2014 | 2299 | public void ignoreUnknownElements(final Pattern pattern) { |
2015 | if (fieldAliasingMapper == null) { | |
2300 | if (elementIgnoringMapper == null) { | |
2016 | 2301 | throw new com.thoughtworks.xstream.InitializationException("No " |
2017 | + FieldAliasingMapper.class.getName() | |
2302 | + ElementIgnoringMapper.class.getName() | |
2018 | 2303 | + " available"); |
2019 | 2304 | } |
2020 | fieldAliasingMapper.addFieldsToIgnore(pattern); | |
2305 | elementIgnoringMapper.addElementsToIgnore(pattern); | |
2021 | 2306 | } |
2022 | 2307 | |
2023 | 2308 | /** |
2074 | 2359 | */ |
2075 | 2360 | public void addPermission(TypePermission permission) { |
2076 | 2361 | if (securityMapper != null) { |
2362 | securityInitialized = true; | |
2077 | 2363 | securityMapper.addPermission(permission); |
2078 | 2364 | } |
2079 | 2365 | } |
2224 | 2510 | denyPermission(new WildcardTypePermission(patterns)); |
2225 | 2511 | } |
2226 | 2512 | |
2513 | private Object readResolve() { | |
2514 | securityWarningGiven = true; | |
2515 | return this; | |
2516 | } | |
2517 | ||
2227 | 2518 | /** |
2228 | 2519 | * @deprecated As of 1.3, use {@link com.thoughtworks.xstream.InitializationException} |
2229 | 2520 | * instead |
2247 | 2538 | super(message); |
2248 | 2539 | } |
2249 | 2540 | } |
2541 | ||
2542 | private class InternalBlackList implements Converter { | |
2543 | ||
2544 | public boolean canConvert(final Class type) { | |
2545 | return (type == void.class || type == Void.class) | |
2546 | || (!securityInitialized | |
2547 | && type != null | |
2548 | && (type.getName().equals("java.beans.EventHandler") | |
2549 | || type.getName().endsWith("$LazyIterator") | |
2550 | || type.getName().startsWith("javax.crypto."))); | |
2551 | } | |
2552 | ||
2553 | public void marshal(final Object source, final HierarchicalStreamWriter writer, | |
2554 | final MarshallingContext context) { | |
2555 | throw new ConversionException("Security alert. Marshalling rejected."); | |
2556 | } | |
2557 | ||
2558 | public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { | |
2559 | throw new ConversionException("Security alert. Unmarshalling rejected."); | |
2560 | } | |
2561 | } | |
2250 | 2562 | } |
0 | 0 | /* |
1 | * Copyright (C) 2006, 2007, 2014, 2016 XStream Committers. | |
1 | * Copyright (C) 2006, 2007, 2014, 2016, 2017, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
35 | 35 | import com.thoughtworks.xstream.io.naming.NameCoder; |
36 | 36 | import com.thoughtworks.xstream.io.xml.XppDriver; |
37 | 37 | import com.thoughtworks.xstream.mapper.Mapper; |
38 | import com.thoughtworks.xstream.security.AnyTypePermission; | |
39 | 38 | import com.thoughtworks.xstream.security.TypeHierarchyPermission; |
40 | 39 | import com.thoughtworks.xstream.security.TypePermission; |
41 | 40 | import com.thoughtworks.xstream.security.WildcardTypePermission; |
107 | 106 | public void toXML(final XStream xstream, final Object obj, final Writer out) |
108 | 107 | throws IOException { |
109 | 108 | final XStream outer = new XStream(); |
109 | XStream.setupDefaultSecurity(outer); | |
110 | 110 | final ObjectOutputStream oos = outer.createObjectOutputStream(out); |
111 | 111 | try { |
112 | 112 | oos.writeObject(xstream); |
250 | 250 | */ |
251 | 251 | public Object fromXML(final HierarchicalStreamDriver driver, final Reader xml) |
252 | 252 | throws IOException, ClassNotFoundException { |
253 | return fromXML(driver, xml, new TypePermission[]{AnyTypePermission.ANY}); | |
253 | return fromXML(driver, xml, PERMISSIONS); | |
254 | 254 | } |
255 | 255 | |
256 | 256 | /** |
267 | 267 | public Object fromXML(final HierarchicalStreamDriver driver, final Reader xml, final TypePermission[] permissions) |
268 | 268 | throws IOException, ClassNotFoundException { |
269 | 269 | final XStream outer = new XStream(driver); |
270 | XStream.setupDefaultSecurity(outer); | |
270 | 271 | for(int i = 0; i < permissions.length; ++i) { |
271 | 272 | outer.addPermission(permissions[i]); |
272 | 273 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
21 | 21 | public class BigDecimalConverter extends AbstractSingleValueConverter { |
22 | 22 | |
23 | 23 | public boolean canConvert(Class type) { |
24 | return type.equals(BigDecimal.class); | |
24 | return type == BigDecimal.class; | |
25 | 25 | } |
26 | 26 | |
27 | 27 | public Object fromString(String str) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
20 | 20 | public class BigIntegerConverter extends AbstractSingleValueConverter { |
21 | 21 | |
22 | 22 | public boolean canConvert(Class type) { |
23 | return type.equals(BigInteger.class); | |
23 | return type == BigInteger.class; | |
24 | 24 | } |
25 | 25 | |
26 | 26 | public Object fromString(String str) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2014 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2014, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
21 | 21 | public class BooleanConverter extends AbstractSingleValueConverter { |
22 | 22 | |
23 | 23 | public static final BooleanConverter TRUE_FALSE = new BooleanConverter("true", "false", false); |
24 | ||
25 | 24 | public static final BooleanConverter YES_NO = new BooleanConverter("yes", "no", false); |
26 | ||
27 | 25 | public static final BooleanConverter BINARY = new BooleanConverter("1", "0", true); |
28 | 26 | |
29 | 27 | private final String positive; |
48 | 46 | } |
49 | 47 | |
50 | 48 | public boolean canConvert(final Class type) { |
51 | return type.equals(boolean.class) || type.equals(Boolean.class); | |
49 | return type == boolean.class || type == Boolean.class; | |
52 | 50 | } |
53 | 51 | |
54 | 52 | public Object fromString(final String str) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
19 | 19 | public class ByteConverter extends AbstractSingleValueConverter { |
20 | 20 | |
21 | 21 | public boolean canConvert(Class type) { |
22 | return type.equals(byte.class) || type.equals(Byte.class); | |
22 | return type == byte.class || type == Byte.class; | |
23 | 23 | } |
24 | 24 | |
25 | 25 | public Object fromString(String str) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
27 | 27 | public class CharConverter implements Converter, SingleValueConverter { |
28 | 28 | |
29 | 29 | public boolean canConvert(Class type) { |
30 | return type.equals(char.class) || type.equals(Character.class); | |
30 | return type == char.class || type == Character.class; | |
31 | 31 | } |
32 | 32 | |
33 | 33 | public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 2013, 2014, 2015, 2016 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 2013, 2014, 2015, 2016, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
200 | 200 | } |
201 | 201 | |
202 | 202 | public boolean canConvert(Class type) { |
203 | return type.equals(Date.class); | |
203 | return type == Date.class; | |
204 | 204 | } |
205 | 205 | |
206 | 206 | public Object fromString(String str) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
19 | 19 | public class DoubleConverter extends AbstractSingleValueConverter { |
20 | 20 | |
21 | 21 | public boolean canConvert(Class type) { |
22 | return type.equals(double.class) || type.equals(Double.class); | |
22 | return type == double.class || type == Double.class; | |
23 | 23 | } |
24 | 24 | |
25 | 25 | public Object fromString(String str) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
19 | 19 | public class FloatConverter extends AbstractSingleValueConverter { |
20 | 20 | |
21 | 21 | public boolean canConvert(Class type) { |
22 | return type.equals(float.class) || type.equals(Float.class); | |
22 | return type == float.class || type == Float.class; | |
23 | 23 | } |
24 | 24 | |
25 | 25 | public Object fromString(String str) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2014, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
19 | 19 | public class IntConverter extends AbstractSingleValueConverter { |
20 | 20 | |
21 | 21 | public boolean canConvert(Class type) { |
22 | return type.equals(int.class) || type.equals(Integer.class); | |
22 | return type == int.class || type == Integer.class; | |
23 | 23 | } |
24 | 24 | |
25 | 25 | public Object fromString(String str) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2013, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
18 | 18 | public class LongConverter extends AbstractSingleValueConverter { |
19 | 19 | |
20 | 20 | public boolean canConvert(Class type) { |
21 | return type.equals(long.class) || type.equals(Long.class); | |
21 | return type == long.class || type == Long.class; | |
22 | 22 | } |
23 | 23 | |
24 | 24 | public Object fromString(String str) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
19 | 19 | public class ShortConverter extends AbstractSingleValueConverter { |
20 | 20 | |
21 | 21 | public boolean canConvert(Class type) { |
22 | return type.equals(short.class) || type.equals(Short.class); | |
22 | return type == short.class || type == Short.class; | |
23 | 23 | } |
24 | 24 | |
25 | 25 | public Object fromString(String str) { |
+2
-2
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
22 | 22 | } |
23 | 23 | |
24 | 24 | public boolean canConvert(Class type) { |
25 | return type.equals(StringBuffer.class); | |
25 | return type == StringBuffer.class; | |
26 | 26 | } |
27 | 27 | } |
+2
-2
0 | 0 | /* |
1 | * Copyright (C) 2008 XStream Committers. | |
1 | * Copyright (C) 2008, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
21 | 21 | } |
22 | 22 | |
23 | 23 | public boolean canConvert(Class type) { |
24 | return type.equals(StringBuilder.class); | |
24 | return type == StringBuilder.class; | |
25 | 25 | } |
26 | 26 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2011 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2011, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
80 | 80 | } |
81 | 81 | |
82 | 82 | public boolean canConvert(final Class type) { |
83 | return type.equals(String.class); | |
83 | return type == String.class; | |
84 | 84 | } |
85 | 85 | |
86 | 86 | public Object fromString(final String str) { |
0 | 0 | /* |
1 | * Copyright (C) 2010 XStream Committers. | |
1 | * Copyright (C) 2010, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
23 | 23 | public class URIConverter extends AbstractSingleValueConverter { |
24 | 24 | |
25 | 25 | public boolean canConvert(Class type) { |
26 | return type.equals(URI.class); | |
26 | return type == URI.class; | |
27 | 27 | } |
28 | 28 | |
29 | 29 | public Object fromString(String str) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
23 | 23 | public class URLConverter extends AbstractSingleValueConverter { |
24 | 24 | |
25 | 25 | public boolean canConvert(Class type) { |
26 | return type.equals(URL.class); | |
26 | return type == URL.class; | |
27 | 27 | } |
28 | 28 | |
29 | 29 | public Object fromString(String str) { |
0 | 0 | /* |
1 | * Copyright (C) 2008 XStream Committers. | |
1 | * Copyright (C) 2008, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
22 | 22 | public class UUIDConverter extends AbstractSingleValueConverter { |
23 | 23 | |
24 | 24 | public boolean canConvert(Class type) { |
25 | return type.equals(UUID.class); | |
25 | return type == UUID.class; | |
26 | 26 | } |
27 | 27 | |
28 | 28 | public Object fromString(String str) { |
+84
-8
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2013, 2016 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2013, 2016, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
50 | 50 | |
51 | 51 | public abstract Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context); |
52 | 52 | |
53 | ||
54 | ||
53 | /** | |
54 | * @deprecated As of 1.4.11 use {@link #writeCompleteItem(Object, MarshallingContext, HierarchicalStreamWriter)} | |
55 | * instead. | |
56 | */ | |
55 | 57 | protected void writeItem(Object item, MarshallingContext context, HierarchicalStreamWriter writer) { |
56 | 58 | // PUBLISHED API METHOD! If changing signature, ensure backwards compatibility. |
57 | 59 | if (item == null) { |
58 | 60 | // todo: this is duplicated in TreeMarshaller.start() |
59 | String name = mapper().serializedClass(null); | |
60 | ExtendedHierarchicalStreamWriterHelper.startNode(writer, name, Mapper.Null.class); | |
61 | writer.endNode(); | |
61 | writeNullItem(context, writer); | |
62 | 62 | } else { |
63 | 63 | String name = mapper().serializedClass(item.getClass()); |
64 | 64 | ExtendedHierarchicalStreamWriterHelper.startNode(writer, name, item.getClass()); |
65 | context.convertAnother(item); | |
65 | writeBareItem(item, context, writer); | |
66 | 66 | writer.endNode(); |
67 | 67 | } |
68 | 68 | } |
69 | 69 | |
70 | protected Object readItem(HierarchicalStreamReader reader, UnmarshallingContext context, Object current) { | |
70 | /** | |
71 | * Write an item of the collection into the writer including surrounding tags. | |
72 | * | |
73 | * @param item the item to write | |
74 | * @param context the current marshalling context | |
75 | * @param writer the target writer | |
76 | * @since 1.4.11 | |
77 | */ | |
78 | protected void writeCompleteItem(final Object item, final MarshallingContext context, | |
79 | final HierarchicalStreamWriter writer) { | |
80 | writeItem(item, context, writer); | |
81 | } | |
82 | ||
83 | /** | |
84 | * Write the bare item of the collection into the writer. | |
85 | * | |
86 | * @param item the item to write | |
87 | * @param context the current marshalling context | |
88 | * @param writer the target writer | |
89 | * @since 1.4.11 | |
90 | */ | |
91 | protected void writeBareItem(final Object item, final MarshallingContext context, | |
92 | final HierarchicalStreamWriter writer) { | |
93 | context.convertAnother(item); | |
94 | } | |
95 | ||
96 | /** | |
97 | * Write a null item of the collection into the writer. The method readItem should be able to process the written | |
98 | * data i.e. it has to write the tags or may not write anything at all. | |
99 | * | |
100 | * @param context the current marshalling context | |
101 | * @param writer the target writer | |
102 | * @since 1.4.11 | |
103 | */ | |
104 | protected void writeNullItem(final MarshallingContext context, final HierarchicalStreamWriter writer) { | |
105 | final String name = mapper().serializedClass(null); | |
106 | ExtendedHierarchicalStreamWriterHelper.startNode(writer, name, Mapper.Null.class); | |
107 | writer.endNode(); | |
108 | } | |
109 | ||
110 | /** | |
111 | * @deprecated As of 1.4.11 use {@link #readBareItem(HierarchicalStreamReader, UnmarshallingContext, Object)} or | |
112 | * {@link #readCompleteItem(HierarchicalStreamReader, UnmarshallingContext, Object)} instead. | |
113 | */ | |
114 | protected Object readItem(final HierarchicalStreamReader reader, final UnmarshallingContext context, | |
115 | final Object current) { | |
116 | return readBareItem(reader, context, current); | |
117 | } | |
118 | ||
119 | /** | |
120 | * Read a bare item of the collection from the reader. | |
121 | * | |
122 | * @param reader the source reader | |
123 | * @param context the unmarshalling context | |
124 | * @param current the target collection (if already available) | |
125 | * @return the read item | |
126 | * @since 1.4.11 | |
127 | */ | |
128 | protected Object readBareItem(final HierarchicalStreamReader reader, final UnmarshallingContext context, | |
129 | final Object current) { | |
71 | 130 | Class type = HierarchicalStreams.readClassType(reader, mapper()); |
72 | 131 | return context.convertAnother(current, type); |
132 | } | |
133 | ||
134 | /** | |
135 | * Read an item of the collection including the tags from the reader. | |
136 | * | |
137 | * @param reader the source reader | |
138 | * @param context the unmarshalling context | |
139 | * @param current the target collection (if already available) | |
140 | * @return the read item | |
141 | * @since 1.4.11 | |
142 | */ | |
143 | protected Object readCompleteItem(final HierarchicalStreamReader reader, final UnmarshallingContext context, | |
144 | final Object current) { | |
145 | reader.moveDown(); | |
146 | final Object result = readItem(reader, context, current); | |
147 | reader.moveUp(); | |
148 | return result; | |
73 | 149 | } |
74 | 150 | |
75 | 151 | protected Object createCollection(Class type) { |
+5
-7
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
34 | 34 | } |
35 | 35 | |
36 | 36 | public boolean canConvert(Class type) { |
37 | return type.isArray(); | |
37 | return type != null && type.isArray(); | |
38 | 38 | } |
39 | 39 | |
40 | 40 | public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { |
41 | 41 | int length = Array.getLength(source); |
42 | 42 | for (int i = 0; i < length; i++) { |
43 | Object item = Array.get(source, i); | |
44 | writeItem(item, context, writer); | |
43 | final Object item = Array.get(source, i); | |
44 | writeCompleteItem(item, context, writer); | |
45 | 45 | } |
46 | 46 | |
47 | 47 | } |
50 | 50 | // read the items from xml into a list |
51 | 51 | List items = new ArrayList(); |
52 | 52 | while (reader.hasMoreChildren()) { |
53 | reader.moveDown(); | |
54 | Object item = readItem(reader, context, null); // TODO: arg, what should replace null? | |
53 | final Object item = readCompleteItem(reader, context, null); // TODO: arg, what should replace null? | |
55 | 54 | items.add(item); |
56 | reader.moveUp(); | |
57 | 55 | } |
58 | 56 | // now convertAnother the list into an array |
59 | 57 | // (this has to be done as a separate list as the array size is not |
+2
-2
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
28 | 28 | public class BitSetConverter implements Converter { |
29 | 29 | |
30 | 30 | public boolean canConvert(Class type) { |
31 | return type.equals(BitSet.class); | |
31 | return type == BitSet.class; | |
32 | 32 | } |
33 | 33 | |
34 | 34 | public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { |
+2
-2
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
25 | 25 | public class CharArrayConverter implements Converter { |
26 | 26 | |
27 | 27 | public boolean canConvert(Class type) { |
28 | return type.isArray() && type.getComponentType().equals(char.class); | |
28 | return type != null && type.isArray() && type.getComponentType().equals(char.class); | |
29 | 29 | } |
30 | 30 | |
31 | 31 | public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { |
+5
-5
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2010, 2011, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2010, 2011, 2013, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
12 | 12 | |
13 | 13 | import com.thoughtworks.xstream.converters.MarshallingContext; |
14 | 14 | import com.thoughtworks.xstream.converters.UnmarshallingContext; |
15 | import com.thoughtworks.xstream.core.JVM; | |
16 | 15 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
17 | 16 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; |
18 | 17 | import com.thoughtworks.xstream.mapper.Mapper; |
21 | 20 | import java.util.Collection; |
22 | 21 | import java.util.HashSet; |
23 | 22 | import java.util.Iterator; |
23 | import java.util.LinkedHashSet; | |
24 | 24 | import java.util.LinkedList; |
25 | 25 | import java.util.Vector; |
26 | 26 | |
63 | 63 | || type.equals(HashSet.class) |
64 | 64 | || type.equals(LinkedList.class) |
65 | 65 | || type.equals(Vector.class) |
66 | || (JVM.is14() && type.getName().equals("java.util.LinkedHashSet")); | |
66 | || type.equals(LinkedHashSet.class); | |
67 | 67 | } |
68 | 68 | |
69 | 69 | public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { |
70 | 70 | Collection collection = (Collection) source; |
71 | 71 | for (Iterator iterator = collection.iterator(); iterator.hasNext();) { |
72 | 72 | Object item = iterator.next(); |
73 | writeItem(item, context, writer); | |
73 | writeCompleteItem(item, context, writer); | |
74 | 74 | } |
75 | 75 | } |
76 | 76 | |
94 | 94 | |
95 | 95 | protected void addCurrentElementToCollection(HierarchicalStreamReader reader, UnmarshallingContext context, |
96 | 96 | Collection collection, Collection target) { |
97 | Object item = readItem(reader, context, collection); | |
97 | final Object item = readItem(reader, context, collection); // call readBareItem when deprecated method is removed | |
98 | 98 | target.add(item); |
99 | 99 | } |
100 | 100 |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2012, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2012, 2013, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
74 | 74 | Map.Entry entry = (Map.Entry) iterator.next(); |
75 | 75 | ExtendedHierarchicalStreamWriterHelper.startNode(writer, entryName, entry.getClass()); |
76 | 76 | |
77 | writeItem(entry.getKey(), context, writer); | |
78 | writeItem(entry.getValue(), context, writer); | |
77 | writeCompleteItem(entry.getKey(), context, writer); | |
78 | writeCompleteItem(entry.getValue(), context, writer); | |
79 | 79 | |
80 | 80 | writer.endNode(); |
81 | 81 | } |
101 | 101 | |
102 | 102 | protected void putCurrentEntryIntoMap(HierarchicalStreamReader reader, UnmarshallingContext context, |
103 | 103 | Map map, Map target) { |
104 | reader.moveDown(); | |
105 | Object key = readItem(reader, context, map); | |
106 | reader.moveUp(); | |
107 | ||
108 | reader.moveDown(); | |
109 | Object value = readItem(reader, context, map); | |
110 | reader.moveUp(); | |
111 | ||
104 | final Object key = readCompleteItem(reader, context, map); | |
105 | final Object value = readCompleteItem(reader, context, map); | |
112 | 106 | target.put(key, value); |
113 | 107 | } |
114 | 108 |
+2
-4
0 | 0 | /* |
1 | * Copyright (C) 2011 XStream Committers. | |
1 | * Copyright (C) 2011, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
46 | 46 | } |
47 | 47 | |
48 | 48 | public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { |
49 | reader.moveDown(); | |
50 | Object item = readItem(reader, context, null); | |
51 | reader.moveUp(); | |
49 | final Object item = readCompleteItem(reader, context, null); | |
52 | 50 | return context.getRequiredType() == LIST |
53 | 51 | ? (Object)Collections.singletonList(item) |
54 | 52 | : (Object)Collections.singleton(item); |
+3
-8
0 | 0 | /* |
1 | * Copyright (C) 2011 XStream Committers. | |
1 | * Copyright (C) 2011, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
45 | 45 | |
46 | 46 | public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { |
47 | 47 | reader.moveDown(); |
48 | reader.moveDown(); | |
49 | Object key = readItem(reader, context, null); | |
50 | reader.moveUp(); | |
51 | ||
52 | reader.moveDown(); | |
53 | Object value = readItem(reader, context, null); | |
54 | reader.moveUp(); | |
48 | final Object key = readCompleteItem(reader, context, null); | |
49 | final Object value = readCompleteItem(reader, context, null); | |
55 | 50 | reader.moveUp(); |
56 | 51 | |
57 | 52 | return Collections.singletonMap(key, value); |
+2
-2
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2010, 2011, 2013, 2016 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2010, 2011, 2013, 2016, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
73 | 73 | TreeMap result = comparatorField != null ? new TreeMap() : null; |
74 | 74 | final Comparator comparator = unmarshalComparator(reader, context, result); |
75 | 75 | if (result == null) { |
76 | result = comparator == null ? new TreeMap() : new TreeMap(comparator); | |
76 | result = comparator == null || comparator == NULL_MARKER ? new TreeMap() : new TreeMap(comparator); | |
77 | 77 | } |
78 | 78 | populateTreeMap(reader, context, result, comparator); |
79 | 79 | return result; |
+2
-2
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2010, 2011, 2013, 2014, 2016 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2010, 2011, 2013, 2014, 2016, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
149 | 149 | |
150 | 150 | protected void putCurrentEntryIntoMap(HierarchicalStreamReader reader, UnmarshallingContext context, |
151 | 151 | Map map, Map target) { |
152 | Object key = readItem(reader, context, map); | |
152 | final Object key = readItem(reader, context, map); // call readBareItem when deprecated method is removed | |
153 | 153 | target.put(key, key); |
154 | 154 | } |
155 | 155 | }; |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2009, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2009, 2013, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
30 | 30 | public class EnumConverter implements Converter { |
31 | 31 | |
32 | 32 | public boolean canConvert(Class type) { |
33 | return type.isEnum() || Enum.class.isAssignableFrom(type); | |
33 | return type != null && type.isEnum() || Enum.class.isAssignableFrom(type); | |
34 | 34 | } |
35 | 35 | |
36 | 36 | public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
46 | 46 | } |
47 | 47 | |
48 | 48 | public boolean canConvert(Class type) { |
49 | return typeField != null && EnumSet.class.isAssignableFrom(type); | |
49 | return typeField != null && type != null && EnumSet.class.isAssignableFrom(type); | |
50 | 50 | } |
51 | 51 | |
52 | 52 | public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { |
+2
-2
0 | 0 | /* |
1 | * Copyright (C) 2008, 2009, 2010, 2013 XStream Committers. | |
1 | * Copyright (C) 2008, 2009, 2010, 2013, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
32 | 32 | |
33 | 33 | @Override |
34 | 34 | public boolean canConvert(Class type) { |
35 | return enumType.isAssignableFrom(type); | |
35 | return type != null && enumType.isAssignableFrom(type); | |
36 | 36 | } |
37 | 37 | |
38 | 38 | @Override |
+2
-2
0 | 0 | /* |
1 | * Copyright (C) 2013, 2016 XStream Committers. | |
1 | * Copyright (C) 2013, 2016, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
77 | 77 | |
78 | 78 | @Override |
79 | 79 | public boolean canConvert(Class type) { |
80 | return enumType.isAssignableFrom(type); | |
80 | return type != null && enumType.isAssignableFrom(type); | |
81 | 81 | } |
82 | 82 | |
83 | 83 | @Override |
0 | 0 | /* |
1 | * Copyright (C) 2006, 2007 XStream Committers. | |
1 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
22 | 22 | public class CharsetConverter extends AbstractSingleValueConverter { |
23 | 23 | |
24 | 24 | public boolean canConvert(Class type) { |
25 | return Charset.class.isAssignableFrom(type); | |
25 | return type != null && Charset.class.isAssignableFrom(type); | |
26 | 26 | } |
27 | 27 | |
28 | 28 | public String toString(Object obj) { |
32 | 32 | public boolean canConvert(Class type) { |
33 | 33 | // String comparison is used here because Color.class loads the class which in turns instantiates AWT, |
34 | 34 | // which is nasty if you don't want it. |
35 | return type.getName().equals("java.awt.Color"); | |
35 | return type != null && type.getName().equals("java.awt.Color"); | |
36 | 36 | } |
37 | 37 | |
38 | 38 | public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { |
+2
-2
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
24 | 24 | public class CurrencyConverter extends AbstractSingleValueConverter { |
25 | 25 | |
26 | 26 | public boolean canConvert(Class type) { |
27 | return type.equals(Currency.class); | |
27 | return type == Currency.class; | |
28 | 28 | } |
29 | 29 | |
30 | 30 | public Object fromString(String str) { |
+3
-3
0 | 0 | /* |
1 | * Copyright (C) 2007, 2008, 2011 XStream Committers. | |
1 | * Copyright (C) 2007, 2008, 2011, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
47 | 47 | this.factory = factory; |
48 | 48 | } |
49 | 49 | |
50 | public boolean canConvert(Class c) { | |
51 | return factory != null && Duration.class.isAssignableFrom(c); | |
50 | public boolean canConvert(Class type) { | |
51 | return factory != null && type != null && Duration.class.isAssignableFrom(type); | |
52 | 52 | } |
53 | 53 | |
54 | 54 | public Object fromString(String s) { |
+2
-2
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2010, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2010, 2013, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
71 | 71 | } |
72 | 72 | |
73 | 73 | public boolean canConvert(Class type) { |
74 | return type.equals(DynamicProxyMapper.DynamicProxy.class) || Proxy.isProxyClass(type); | |
74 | return type != null && (type.equals(DynamicProxyMapper.DynamicProxy.class) || Proxy.isProxyClass(type)); | |
75 | 75 | } |
76 | 76 | |
77 | 77 | public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { |
+28
-10
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2010 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2010, 2017, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
6 | 6 | * style license a copy of which has been included with this distribution in |
7 | 7 | * the LICENSE.txt file. |
8 | * | |
8 | * | |
9 | 9 | * Created on 03. March 2004 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.converters.extended; |
15 | 15 | import com.thoughtworks.xstream.converters.SingleValueConverter; |
16 | 16 | import com.thoughtworks.xstream.converters.UnmarshallingContext; |
17 | 17 | import com.thoughtworks.xstream.converters.basic.ByteConverter; |
18 | import com.thoughtworks.xstream.core.util.Base64Encoder; | |
18 | import com.thoughtworks.xstream.core.JVM; | |
19 | import com.thoughtworks.xstream.core.StringCodec; | |
19 | 20 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
20 | 21 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; |
21 | 22 | |
24 | 25 | import java.util.List; |
25 | 26 | |
26 | 27 | /** |
27 | * Converts a byte array to a single Base64 encoding string. | |
28 | * Converts a byte array by default to a single Base64 encoding string. | |
28 | 29 | * |
29 | 30 | * @author Joe Walnes |
30 | 31 | * @author Jörg Schaible |
31 | 32 | */ |
32 | 33 | public class EncodedByteArrayConverter implements Converter, SingleValueConverter { |
33 | 34 | |
34 | private static final Base64Encoder base64 = new Base64Encoder(); | |
35 | 35 | private static final ByteConverter byteConverter = new ByteConverter(); |
36 | private final StringCodec codec; | |
37 | ||
38 | /** | |
39 | * Constructs an EncodedByteArrayConverter. Initializes the converter with a Base64 codec. | |
40 | */ | |
41 | public EncodedByteArrayConverter() { | |
42 | this(JVM.getBase64Codec()); | |
43 | } | |
44 | ||
45 | /** | |
46 | * Constructs an EncodedByteArrayConverter with a provided string codec. | |
47 | * | |
48 | * @param stringCodec the codec to encode and decode the data as string | |
49 | * @since 1.4.11 | |
50 | */ | |
51 | public EncodedByteArrayConverter(final StringCodec stringCodec) { | |
52 | codec = stringCodec; | |
53 | } | |
36 | 54 | |
37 | 55 | public boolean canConvert(Class type) { |
38 | return type.isArray() && type.getComponentType().equals(byte.class); | |
56 | return type != null && type.isArray() && type.getComponentType().equals(byte.class); | |
39 | 57 | } |
40 | 58 | |
41 | 59 | public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { |
72 | 90 | return result; |
73 | 91 | } |
74 | 92 | |
75 | public String toString(Object obj) { | |
76 | return base64.encode((byte[]) obj); | |
93 | public String toString(final Object obj) { | |
94 | return codec.encode((byte[])obj); | |
77 | 95 | } |
78 | 96 | |
79 | public Object fromString(String str) { | |
80 | return base64.decode(str); | |
97 | public Object fromString(final String str) { | |
98 | return codec.decode(str); | |
81 | 99 | } |
82 | 100 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
23 | 23 | public class FileConverter extends AbstractSingleValueConverter { |
24 | 24 | |
25 | 25 | public boolean canConvert(Class type) { |
26 | return type.equals(File.class); | |
26 | return type == File.class; | |
27 | 27 | } |
28 | 28 | |
29 | 29 | public Object fromString(String str) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2013, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
59 | 59 | public boolean canConvert(Class type) { |
60 | 60 | // String comparison is used here because Font.class loads the class which in turns instantiates AWT, |
61 | 61 | // which is nasty if you don't want it. |
62 | return type.getName().equals("java.awt.Font") || type.getName().equals("javax.swing.plaf.FontUIResource"); | |
62 | return type != null | |
63 | && (type.getName().equals("java.awt.Font") || type.getName().equals("javax.swing.plaf.FontUIResource")); | |
63 | 64 | } |
64 | 65 | |
65 | 66 | public void marshal(Object source, HierarchicalStreamWriter writer, |
112 | 113 | } else { |
113 | 114 | attributes = Collections.EMPTY_MAP; |
114 | 115 | } |
115 | if (!JVM.is16()) { | |
116 | if (!JVM.isVersion(6)) { | |
116 | 117 | for (Iterator iter = attributes.values().iterator(); iter.hasNext(); ) { |
117 | 118 | if (iter.next() == null) { |
118 | 119 | iter.remove(); |
+1
-1
31 | 31 | public class GregorianCalendarConverter implements Converter { |
32 | 32 | |
33 | 33 | public boolean canConvert(Class type) { |
34 | return type.equals(GregorianCalendar.class); | |
34 | return type == GregorianCalendar.class; | |
35 | 35 | } |
36 | 36 | |
37 | 37 | public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { |
+10
-6
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2017, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
12 | 12 | |
13 | 13 | import java.util.Calendar; |
14 | 14 | import java.util.Date; |
15 | import java.util.GregorianCalendar; | |
16 | ||
17 | import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; | |
15 | 18 | |
16 | 19 | |
17 | 20 | /** |
21 | 24 | * @author Mauro Talevi |
22 | 25 | * @author Jörg Schaible |
23 | 26 | */ |
24 | public class ISO8601DateConverter extends ISO8601GregorianCalendarConverter { | |
27 | public class ISO8601DateConverter extends AbstractSingleValueConverter { | |
28 | private final ISO8601GregorianCalendarConverter converter = new ISO8601GregorianCalendarConverter(); | |
25 | 29 | |
26 | 30 | public boolean canConvert(Class type) { |
27 | return type.equals(Date.class); | |
31 | return type == Date.class && converter.canConvert(GregorianCalendar.class); | |
28 | 32 | } |
29 | 33 | |
30 | 34 | public Object fromString(String str) { |
31 | return ((Calendar)super.fromString(str)).getTime(); | |
35 | return ((Calendar)converter.fromString(str)).getTime(); | |
32 | 36 | } |
33 | 37 | |
34 | 38 | public String toString(Object obj) { |
35 | Calendar calendar = Calendar.getInstance(); | |
39 | final Calendar calendar = Calendar.getInstance(); | |
36 | 40 | calendar.setTime((Date)obj); |
37 | return super.toString(calendar); | |
41 | return converter.toString(calendar); | |
38 | 42 | } |
39 | 43 | } |
+38
-92
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2011, 2013, 2014, 2015, 2016 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2011, 2013, 2014, 2015, 2016, 2017, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.converters.extended; |
12 | 12 | |
13 | import com.thoughtworks.xstream.converters.ConversionException; | |
13 | import java.lang.reflect.InvocationTargetException; | |
14 | import java.util.GregorianCalendar; | |
15 | ||
16 | import com.thoughtworks.xstream.converters.SingleValueConverter; | |
14 | 17 | import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; |
15 | ||
16 | import org.joda.time.DateTime; | |
17 | import org.joda.time.DateTimeZone; | |
18 | import org.joda.time.format.DateTimeFormatter; | |
19 | import org.joda.time.format.ISODateTimeFormat; | |
20 | ||
21 | import java.util.Calendar; | |
22 | import java.util.GregorianCalendar; | |
23 | import java.util.TimeZone; | |
18 | import com.thoughtworks.xstream.core.JVM; | |
24 | 19 | |
25 | 20 | |
26 | 21 | /** |
27 | * A GregorianCalendarConverter conforming to the ISO8601 standard. The converter will always | |
28 | * serialize the calendar value in UTC and deserialize it to a value in the current default time | |
29 | * zone. | |
22 | * A GregorianCalendarConverter conforming to the ISO8601 standard. The converter will always serialize the calendar | |
23 | * value in UTC and deserialize it to a value in the current default time zone. | |
30 | 24 | * |
31 | 25 | * @author Mauro Talevi |
32 | 26 | * @author Jörg Schaible |
34 | 28 | * @since 1.1.3 |
35 | 29 | */ |
36 | 30 | public class ISO8601GregorianCalendarConverter extends AbstractSingleValueConverter { |
37 | private static final DateTimeFormatter[] formattersUTC = new DateTimeFormatter[]{ | |
38 | ISODateTimeFormat.dateTime(), | |
39 | ISODateTimeFormat.dateTimeNoMillis(), | |
40 | ISODateTimeFormat.basicDateTime(), | |
41 | ISODateTimeFormat.basicOrdinalDateTime(), | |
42 | ISODateTimeFormat.basicOrdinalDateTimeNoMillis(), | |
43 | ISODateTimeFormat.basicTime(), | |
44 | ISODateTimeFormat.basicTimeNoMillis(), | |
45 | ISODateTimeFormat.basicTTime(), | |
46 | ISODateTimeFormat.basicTTimeNoMillis(), | |
47 | ISODateTimeFormat.basicWeekDateTime(), | |
48 | ISODateTimeFormat.basicWeekDateTimeNoMillis(), | |
49 | ISODateTimeFormat.ordinalDateTime(), | |
50 | ISODateTimeFormat.ordinalDateTimeNoMillis(), | |
51 | ISODateTimeFormat.time(), | |
52 | ISODateTimeFormat.timeNoMillis(), | |
53 | ISODateTimeFormat.tTime(), | |
54 | ISODateTimeFormat.tTimeNoMillis(), | |
55 | ISODateTimeFormat.weekDateTime(), | |
56 | ISODateTimeFormat.weekDateTimeNoMillis() | |
57 | }; | |
58 | private static final DateTimeFormatter[] formattersNoUTC = new DateTimeFormatter[]{ | |
59 | ISODateTimeFormat.basicDate(), | |
60 | ISODateTimeFormat.basicOrdinalDate(), | |
61 | ISODateTimeFormat.basicWeekDate(), | |
62 | ISODateTimeFormat.date(), | |
63 | ISODateTimeFormat.dateHour(), | |
64 | ISODateTimeFormat.dateHourMinute(), | |
65 | ISODateTimeFormat.dateHourMinuteSecond(), | |
66 | ISODateTimeFormat.dateHourMinuteSecondFraction(), | |
67 | ISODateTimeFormat.dateHourMinuteSecondMillis(), | |
68 | ISODateTimeFormat.hour(), | |
69 | ISODateTimeFormat.hourMinute(), | |
70 | ISODateTimeFormat.hourMinuteSecond(), | |
71 | ISODateTimeFormat.hourMinuteSecondFraction(), | |
72 | ISODateTimeFormat.hourMinuteSecondMillis(), | |
73 | ISODateTimeFormat.ordinalDate(), | |
74 | ISODateTimeFormat.weekDate(), | |
75 | ISODateTimeFormat.year(), | |
76 | ISODateTimeFormat.yearMonth(), | |
77 | ISODateTimeFormat.yearMonthDay(), | |
78 | ISODateTimeFormat.weekyear(), | |
79 | ISODateTimeFormat.weekyearWeek(), | |
80 | ISODateTimeFormat.weekyearWeekDay() | |
81 | }; | |
82 | ||
83 | public boolean canConvert(Class type) { | |
84 | return type.equals(GregorianCalendar.class); | |
31 | private final static Class[] EMPTY_CLASS_ARRAY = new Class[0]; | |
32 | private final static Object[] EMPTY_OBJECT_ARRAY = new Object[0]; | |
33 | private final SingleValueConverter converter; | |
34 | ||
35 | public ISO8601GregorianCalendarConverter() { | |
36 | SingleValueConverter svConverter = null; | |
37 | final Class type = JVM.loadClassForName(JVM.isVersion(8) | |
38 | ? "com.thoughtworks.xstream.core.util.ISO8601JavaTimeConverter" | |
39 | : "com.thoughtworks.xstream.core.util.ISO8601JodaTimeConverter"); | |
40 | try { | |
41 | svConverter = (SingleValueConverter)type.getDeclaredConstructor(EMPTY_CLASS_ARRAY).newInstance( | |
42 | EMPTY_OBJECT_ARRAY); | |
43 | } catch (final InstantiationException e) { | |
44 | // ignore | |
45 | } catch (final IllegalAccessException e) { | |
46 | // ignore | |
47 | } catch (final InvocationTargetException e) { | |
48 | // ignore | |
49 | } catch (final NoSuchMethodException e) { | |
50 | // ignore | |
51 | } | |
52 | converter = svConverter; | |
85 | 53 | } |
86 | 54 | |
87 | public Object fromString(String str) { | |
88 | for (int i = 0; i < formattersUTC.length; i++ ) { | |
89 | DateTimeFormatter formatter = formattersUTC[i]; | |
90 | try { | |
91 | DateTime dt = formatter.parseDateTime(str); | |
92 | Calendar calendar = dt.toGregorianCalendar(); | |
93 | calendar.setTimeZone(TimeZone.getDefault()); | |
94 | return calendar; | |
95 | } catch (IllegalArgumentException e) { | |
96 | // try with next formatter | |
97 | } | |
98 | } | |
99 | final DateTimeZone dateTimeZone = DateTimeZone.forTimeZone(TimeZone.getDefault()); | |
100 | for (int i = 0; i < formattersNoUTC.length; i++ ) { | |
101 | try { | |
102 | final DateTimeFormatter formatter = formattersNoUTC[i].withZone(dateTimeZone); | |
103 | final DateTime dt = formatter.parseDateTime(str); | |
104 | final Calendar calendar = dt.toGregorianCalendar(); | |
105 | calendar.setTimeZone(TimeZone.getDefault()); | |
106 | return calendar; | |
107 | } catch (IllegalArgumentException e) { | |
108 | // try with next formatter | |
109 | } | |
110 | } | |
111 | ConversionException exception = new ConversionException("Cannot parse date"); | |
112 | exception.add("date", str); | |
113 | throw exception; | |
55 | public boolean canConvert(final Class type) { | |
56 | return converter != null && type == GregorianCalendar.class; | |
114 | 57 | } |
115 | 58 | |
116 | public String toString(Object obj) { | |
117 | DateTime dt = new DateTime(obj); | |
118 | return dt.toString(formattersUTC[0]); | |
59 | public Object fromString(final String str) { | |
60 | return converter.fromString(str); | |
61 | } | |
62 | ||
63 | public String toString(final Object obj) { | |
64 | return converter.toString(obj); | |
119 | 65 | } |
120 | 66 | } |
+2
-2
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2017, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
26 | 26 | private final static String PADDING = "000000000"; |
27 | 27 | |
28 | 28 | public boolean canConvert(Class type) { |
29 | return type.equals(Timestamp.class); | |
29 | return type == Timestamp.class && super.canConvert(Date.class); | |
30 | 30 | } |
31 | 31 | |
32 | 32 | public Object fromString(String str) { |
+2
-2
0 | 0 | /* |
1 | * Copyright (C) 2009, 2013 XStream Committers. | |
1 | * Copyright (C) 2009, 2013, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
60 | 60 | } |
61 | 61 | |
62 | 62 | public boolean canConvert(Class type) { |
63 | return type.equals(Field.class); | |
63 | return type == Field.class; | |
64 | 64 | } |
65 | 65 | |
66 | 66 | public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { |
+2
-2
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2009, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2009, 2013, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
60 | 60 | } |
61 | 61 | |
62 | 62 | public boolean canConvert(Class type) { |
63 | return type.equals(Method.class) || type.equals(Constructor.class); | |
63 | return type == Method.class || type == Constructor.class; | |
64 | 64 | } |
65 | 65 | |
66 | 66 | public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
23 | 23 | public class LocaleConverter extends AbstractSingleValueConverter { |
24 | 24 | |
25 | 25 | public boolean canConvert(Class type) { |
26 | return type.equals(Locale.class); | |
26 | return type == Locale.class; | |
27 | 27 | } |
28 | 28 | |
29 | 29 | public Object fromString(String str) { |
+2
-2
0 | 0 | /* |
1 | * Copyright (C) 2007, 2008, 2013 XStream Committers. | |
1 | * Copyright (C) 2007, 2008, 2013, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
40 | 40 | } |
41 | 41 | |
42 | 42 | public boolean canConvert(Class type) { |
43 | return LookAndFeel.class.isAssignableFrom(type) && canAccess(type); | |
43 | return type != null && LookAndFeel.class.isAssignableFrom(type) && canAccess(type); | |
44 | 44 | } |
45 | 45 | } |
+15
-5
0 | 0 | /* |
1 | * Copyright (C) 2013 XStream Committers. | |
1 | * Copyright (C) 2013, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
61 | 61 | this.type = itemType; |
62 | 62 | } |
63 | 63 | |
64 | protected void writeCompleteItem(final Object item, final MarshallingContext context, | |
65 | final HierarchicalStreamWriter writer) { | |
66 | writeItem(item, context, writer); | |
67 | } | |
68 | ||
69 | /** | |
70 | * @deprecated As of 1.4.11 use {@link #writeCompleteItem(Object, MarshallingContext, HierarchicalStreamWriter)} | |
71 | * instead. | |
72 | */ | |
64 | 73 | protected void writeItem(Object item, MarshallingContext context, HierarchicalStreamWriter writer) { |
65 | Class itemType = item == null ? Mapper.Null.class : item.getClass(); | |
74 | final Class itemType = item == null ? Mapper.Null.class : item.getClass(); | |
66 | 75 | ExtendedHierarchicalStreamWriterHelper.startNode(writer, name, itemType); |
67 | 76 | if (!itemType.equals(type)) { |
68 | 77 | String attributeName = mapper().aliasForSystemAttribute("class"); |
76 | 85 | writer.endNode(); |
77 | 86 | } |
78 | 87 | |
79 | protected Object readItem(HierarchicalStreamReader reader, UnmarshallingContext context, Object current) { | |
80 | String className = HierarchicalStreams.readClassAttribute(reader, mapper()); | |
81 | Class itemType = className == null ? type : mapper().realClass(className); | |
88 | protected Object readBareItem(final HierarchicalStreamReader reader, final UnmarshallingContext context, | |
89 | final Object current) { | |
90 | final String className = HierarchicalStreams.readClassAttribute(reader, mapper()); | |
91 | final Class itemType = className == null ? type : mapper().realClass(className); | |
82 | 92 | if (Mapper.Null.class.equals(itemType)) { |
83 | 93 | return null; |
84 | 94 | } else { |
+2
-2
0 | 0 | /* |
1 | * Copyright (C) 2013, 2016 XStream Committers. | |
1 | * Copyright (C) 2013, 2016, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
207 | 207 | this.keyAsAttribute = keyAsAttribute; |
208 | 208 | this.valueAsAttribute = valueAsAttribute; |
209 | 209 | this.lookup = lookup; |
210 | enumMapper = JVM.is15() ? UseAttributeForEnumMapper.createEnumMapper(mapper) : null; | |
210 | enumMapper = JVM.isVersion(5) ? UseAttributeForEnumMapper.createEnumMapper(mapper) : null; | |
211 | 211 | |
212 | 212 | if (keyType == null || valueType == null) { |
213 | 213 | throw new IllegalArgumentException("Class types of key and value are mandatory"); |
0 | 0 | /* |
1 | * Copyright (C) 2016 XStream Committers. | |
1 | * Copyright (C) 2016, 2017, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
9 | 9 | */ |
10 | 10 | package com.thoughtworks.xstream.converters.extended; |
11 | 11 | |
12 | import java.io.File; | |
12 | 13 | import java.net.URI; |
13 | 14 | import java.net.URISyntaxException; |
14 | 15 | import java.nio.file.FileSystems; |
16 | import java.nio.file.InvalidPathException; | |
15 | 17 | import java.nio.file.Path; |
16 | 18 | import java.nio.file.Paths; |
17 | 19 | |
28 | 30 | public class PathConverter extends AbstractSingleValueConverter { |
29 | 31 | |
30 | 32 | @Override |
31 | public boolean canConvert(final Class type) { | |
32 | return Path.class.isAssignableFrom(type); | |
33 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
34 | return type != null && Path.class.isAssignableFrom(type); | |
33 | 35 | } |
34 | 36 | |
35 | 37 | @Override |
36 | public Object fromString(final String str) { | |
38 | public Path fromString(final String str) { | |
37 | 39 | try { |
38 | final URI uri = new URI(str); | |
39 | if (uri.getScheme() == null) { | |
40 | try { | |
41 | final URI uri = new URI(str); | |
42 | if (uri.getScheme() == null || uri.getScheme().length() == 1) { | |
43 | return Paths.get(File.separatorChar != '/' ? str.replace('/', File.separatorChar) : str); | |
44 | } else { | |
45 | return Paths.get(uri); | |
46 | } | |
47 | } catch (final URISyntaxException e) { | |
40 | 48 | return Paths.get(str); |
41 | } else { | |
42 | return Paths.get(uri); | |
43 | 49 | } |
44 | } catch (final URISyntaxException e) { | |
50 | } catch (final InvalidPathException e) { | |
45 | 51 | throw new ConversionException(e); |
46 | 52 | } |
47 | 53 | } |
50 | 56 | public String toString(final Object obj) { |
51 | 57 | final Path path = (Path)obj; |
52 | 58 | if (path.getFileSystem() == FileSystems.getDefault()) { |
53 | return path.toString(); | |
59 | final String localPath = path.toString(); | |
60 | if (File.separatorChar != '/') { | |
61 | return localPath.replace(File.separatorChar, '/'); | |
62 | } else { | |
63 | return localPath; | |
64 | } | |
54 | 65 | } else { |
55 | 66 | return path.toUri().toString(); |
56 | 67 | } |
+2
-2
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2013, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
39 | 39 | } |
40 | 40 | |
41 | 41 | public boolean canConvert(final Class type) { |
42 | return type.equals(Pattern.class); | |
42 | return type == Pattern.class; | |
43 | 43 | } |
44 | 44 | |
45 | 45 | public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
22 | 22 | public class SqlDateConverter extends AbstractSingleValueConverter { |
23 | 23 | |
24 | 24 | public boolean canConvert(Class type) { |
25 | return type.equals(Date.class); | |
25 | return type == Date.class; | |
26 | 26 | } |
27 | 27 | |
28 | 28 | public Object fromString(String str) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
22 | 22 | public class SqlTimeConverter extends AbstractSingleValueConverter { |
23 | 23 | |
24 | 24 | public boolean canConvert(Class type) { |
25 | return type.equals(Time.class); | |
25 | return type == Time.class; | |
26 | 26 | } |
27 | 27 | |
28 | 28 | public Object fromString(String str) { |
+45
-24
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2012, 2014 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2012, 2014, 2016, 2017, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
6 | 6 | * style license a copy of which has been included with this distribution in |
7 | 7 | * the LICENSE.txt file. |
8 | * | |
8 | * | |
9 | 9 | * Created on 01. October 2004 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.converters.extended; |
20 | 20 | |
21 | 21 | |
22 | 22 | /** |
23 | * Converts a java.sql.Timestamp to text. | |
24 | * | |
23 | * Converts a {@link Timestamp} to a string. | |
24 | * | |
25 | 25 | * @author Joe Walnes |
26 | 26 | * @author Jörg Schaible |
27 | 27 | */ |
28 | 28 | public class SqlTimestampConverter extends AbstractSingleValueConverter { |
29 | 29 | |
30 | private final ThreadSafeSimpleDateFormat format = new ThreadSafeSimpleDateFormat( | |
31 | "yyyy-MM-dd HH:mm:ss", TimeZone.getTimeZone("UTC"), 0, 5, false); | |
30 | private final ThreadSafeSimpleDateFormat format; | |
31 | ||
32 | /** | |
33 | * Constructs a SqlTimestampConverter using UTC format. | |
34 | */ | |
35 | public SqlTimestampConverter() { | |
36 | this(TimeZone.getTimeZone("UTC")); | |
37 | } | |
38 | ||
39 | /** | |
40 | * Constructs a SqlTimestampConverter. | |
41 | * <p> | |
42 | * XStream uses by default UTC as time zone. However, if the resulting XML is used as feed for a data base (like MS | |
43 | * SQL) the server might expect the timestamp to be in local time and does the conversion to UTC on its own. In such | |
44 | * a case you can register an own instance of the SqlTimestamp converter using e.g. {@link TimeZone#getDefault()}. | |
45 | * </p> | |
46 | * | |
47 | * @param timeZone the time zone used for the format | |
48 | * @since 1.4.10 | |
49 | */ | |
50 | public SqlTimestampConverter(final TimeZone timeZone) { | |
51 | format = new ThreadSafeSimpleDateFormat("yyyy-MM-dd HH:mm:ss", timeZone, 0, 5, false); | |
52 | } | |
32 | 53 | |
33 | 54 | public boolean canConvert(Class type) { |
34 | return type.equals(Timestamp.class); | |
55 | return type == Timestamp.class; | |
35 | 56 | } |
36 | 57 | |
37 | public String toString(Object obj) { | |
38 | Timestamp timestamp = (Timestamp)obj; | |
39 | StringBuffer buffer = new StringBuffer(format.format(timestamp)).append('.'); | |
40 | if (timestamp.getNanos() == 0) { | |
41 | buffer.append('0'); | |
42 | } else { | |
43 | String nanos = String.valueOf(timestamp.getNanos() + 1000000000); | |
58 | public String toString(final Object obj) { | |
59 | final Timestamp timestamp = (Timestamp)obj; | |
60 | final StringBuffer buffer = new StringBuffer(format.format(timestamp)); | |
61 | if (timestamp.getNanos() != 0) { | |
62 | buffer.append('.'); | |
63 | final String nanos = String.valueOf(timestamp.getNanos() + 1000000000); | |
44 | 64 | int last = 10; |
45 | 65 | while (last > 2 && nanos.charAt(last-1) == '0') |
46 | 66 | --last; |
49 | 69 | return buffer.toString(); |
50 | 70 | } |
51 | 71 | |
52 | public Object fromString(String str) { | |
53 | int idx = str.lastIndexOf('.'); | |
54 | if (idx < 0 || str.length() - idx < 2 || str.length() - idx > 10) { | |
55 | throw new ConversionException( | |
56 | "Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]"); | |
72 | public Object fromString(final String str) { | |
73 | final int idx = str.lastIndexOf('.'); | |
74 | if (idx > 0 && (str.length() - idx < 2 || str.length() - idx > 10)) { | |
75 | throw new ConversionException("Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]"); | |
57 | 76 | } |
58 | 77 | try { |
59 | Timestamp timestamp = new Timestamp(format.parse(str.substring(0, idx)).getTime()); | |
60 | StringBuffer buffer = new StringBuffer(str.substring(idx + 1)); | |
61 | while(buffer.length() != 9) { | |
62 | buffer.append('0'); | |
78 | final Timestamp timestamp = new Timestamp(format.parse(idx < 0 ? str : str.substring(0, idx)).getTime()); | |
79 | if (idx > 0) { | |
80 | final StringBuffer buffer = new StringBuffer(str.substring(idx + 1)); | |
81 | while (buffer.length() != 9) { | |
82 | buffer.append('0'); | |
83 | } | |
84 | timestamp.setNanos(Integer.parseInt(buffer.toString())); | |
63 | 85 | } |
64 | timestamp.setNanos(Integer.parseInt(buffer.toString())); | |
65 | 86 | return timestamp; |
66 | 87 | } catch (NumberFormatException e) { |
67 | 88 | throw new ConversionException( |
+2
-2
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
35 | 35 | private static final StackTraceElementFactory FACTORY; |
36 | 36 | static { |
37 | 37 | StackTraceElementFactory factory = null; |
38 | if (JVM.is15()) { | |
38 | if (JVM.isVersion(5)) { | |
39 | 39 | Class factoryType = JVM.loadClassForName( |
40 | 40 | "com.thoughtworks.xstream.converters.extended.StackTraceElementFactory15", |
41 | 41 | false); |
0 | 0 | /* |
1 | * Copyright (C) 2006, 2007 XStream Committers. | |
1 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
38 | 38 | } |
39 | 39 | |
40 | 40 | public boolean canConvert(Class type) { |
41 | return type.equals(Subject.class); | |
41 | return type == Subject.class; | |
42 | 42 | } |
43 | 43 | |
44 | 44 | public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { |
53 | 53 | writer.startNode("principals"); |
54 | 54 | for (final Iterator iter = principals.iterator(); iter.hasNext();) { |
55 | 55 | final Object principal = iter.next(); // pre jdk 1.4 a Principal was also in javax.security |
56 | writeItem(principal, context, writer); | |
56 | writeCompleteItem(principal, context, writer); | |
57 | 57 | } |
58 | 58 | writer.endNode(); |
59 | 59 | }; |
101 | 101 | Set set = new HashSet(); |
102 | 102 | reader.moveDown(); |
103 | 103 | while (reader.hasMoreChildren()) { |
104 | reader.moveDown(); | |
105 | Object elementl = readItem(reader, context, set); | |
106 | reader.moveUp(); | |
107 | set.add(elementl); | |
104 | final Object principal = readCompleteItem(reader, context, set); | |
105 | set.add(principal); | |
108 | 106 | } |
109 | 107 | reader.moveUp(); |
110 | 108 | return set; |
+2
-2
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2013, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
45 | 45 | } |
46 | 46 | |
47 | 47 | public boolean canConvert(final Class type) { |
48 | return Throwable.class.isAssignableFrom(type); | |
48 | return type != null && Throwable.class.isAssignableFrom(type); | |
49 | 49 | } |
50 | 50 | |
51 | 51 | public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { |
+2
-2
0 | 0 | /* |
1 | * Copyright (C) 2011, 2013, 2016 XStream Committers. | |
1 | * Copyright (C) 2011, 2013, 2016, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
121 | 121 | } |
122 | 122 | this.valueField = field; |
123 | 123 | } |
124 | enumMapper = JVM.is15() ? UseAttributeForEnumMapper.createEnumMapper(mapper) : null; | |
124 | enumMapper = JVM.isVersion(5) ? UseAttributeForEnumMapper.createEnumMapper(mapper) : null; | |
125 | 125 | } |
126 | 126 | |
127 | 127 | public boolean canConvert(final Class type) { |
+2
-2
0 | 0 | /* |
1 | * Copyright (C) 2006, 2007, 2016 XStream Committers. | |
1 | * Copyright (C) 2006, 2007, 2016, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
35 | 35 | ctor = clazz.getConstructor(STRING_PARAMETER); |
36 | 36 | } |
37 | 37 | public boolean canConvert(Class type) { |
38 | return type.equals(clazz); | |
38 | return type == clazz; | |
39 | 39 | } |
40 | 40 | public String toString(Object obj) { |
41 | 41 | return obj == null ? null : obj.toString(); |
127 | 127 | } |
128 | 128 | |
129 | 129 | public boolean propertyDefinedInClass(String name, Class type) { |
130 | return getProperty(name, type) != null; | |
130 | return propertyDictionary.propertyDescriptorOrNull(type, name) != null; | |
131 | 131 | } |
132 | 132 | |
133 | 133 | /** |
135 | 135 | */ |
136 | 136 | public boolean canInstantiate(Class type) { |
137 | 137 | try { |
138 | return newInstance(type) != null; | |
139 | } catch (ObjectAccessException e) { | |
138 | return type != null && newInstance(type) != null; | |
139 | } catch (final ErrorWritingException e) { | |
140 | 140 | return false; |
141 | 141 | } |
142 | 142 | } |
+2
-2
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
143 | 143 | Object value = context.convertAnother(result, type); |
144 | 144 | beanProvider.writeProperty(result, propertyName, value); |
145 | 145 | seenProperties.add(new FastField(resultType, propertyName)); |
146 | } else { | |
146 | } else if (!mapper.isIgnoredElement(propertyName)) { | |
147 | 147 | throw new MissingFieldException(resultType.getName(), propertyName); |
148 | 148 | } |
149 | 149 | } |
+16
-3
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2016 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2016, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
70 | 70 | */ |
71 | 71 | public BeanProperty property(Class cls, String name) { |
72 | 72 | BeanProperty beanProperty = null; |
73 | PropertyDescriptor descriptor = (PropertyDescriptor)buildMap(cls).get(name); | |
73 | PropertyDescriptor descriptor = propertyDescriptorOrNull(cls, name); | |
74 | 74 | if (descriptor == null) { |
75 | 75 | throw new MissingFieldException(cls.getName(), name); |
76 | 76 | } |
90 | 90 | * |
91 | 91 | * @param type |
92 | 92 | * @param name |
93 | * @throws MissingFieldException if property does not exist | |
93 | 94 | */ |
94 | 95 | public PropertyDescriptor propertyDescriptor(Class type, String name) { |
95 | PropertyDescriptor descriptor = (PropertyDescriptor)buildMap(type).get(name); | |
96 | PropertyDescriptor descriptor = propertyDescriptorOrNull(type, name); | |
96 | 97 | if (descriptor == null) { |
97 | 98 | throw new MissingFieldException(type.getName(), name); |
98 | 99 | } |
99 | 100 | return descriptor; |
101 | } | |
102 | ||
103 | /** | |
104 | * Locates a property descriptor. | |
105 | * | |
106 | * @param type | |
107 | * @param name | |
108 | * @return {@code null} if property does not exist | |
109 | * @since 1.4.10 | |
110 | */ | |
111 | public PropertyDescriptor propertyDescriptorOrNull(Class type, String name) { | |
112 | return (PropertyDescriptor)buildMap(type).get(name); | |
100 | 113 | } |
101 | 114 | |
102 | 115 | private Map buildMap(Class type) { |
+83
-81
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
140 | 140 | } |
141 | 141 | }); |
142 | 142 | |
143 | new Object() { | |
144 | { | |
145 | final Map hiddenMappers = new HashMap(); | |
146 | for (Iterator fieldIter = fields.iterator(); fieldIter.hasNext();) { | |
147 | FieldInfo info = (FieldInfo)fieldIter.next(); | |
148 | if (info.value != null) { | |
149 | final Field defaultField = (Field)defaultFieldDefinition.get(info.fieldName); | |
150 | Mapper.ImplicitCollectionMapping mapping = mapper | |
151 | .getImplicitCollectionDefForFieldName( | |
152 | defaultField.getDeclaringClass() == info.definedIn ? sourceType : info.definedIn, | |
153 | info.fieldName); | |
154 | if (mapping != null) { | |
155 | Set mappings = (Set)hiddenMappers.get(info.fieldName); | |
156 | if (mappings == null) { | |
157 | mappings = new HashSet(); | |
158 | mappings.add(mapping); | |
159 | hiddenMappers.put(info.fieldName, mappings); | |
160 | } else { | |
161 | if (!mappings.add(mapping)) { | |
162 | mapping = null; | |
163 | } | |
164 | } | |
165 | } | |
166 | if (mapping != null) { | |
167 | if (context instanceof ReferencingMarshallingContext) { | |
168 | if (info.value != Collections.EMPTY_LIST | |
169 | && info.value != Collections.EMPTY_SET | |
170 | && info.value != Collections.EMPTY_MAP) { | |
171 | ReferencingMarshallingContext refContext = (ReferencingMarshallingContext)context; | |
172 | refContext.registerImplicit(info.value); | |
173 | } | |
174 | } | |
175 | final boolean isCollection = info.value instanceof Collection; | |
176 | final boolean isMap = info.value instanceof Map; | |
177 | final boolean isEntry = isMap && mapping.getKeyFieldName() == null; | |
178 | final boolean isArray = info.value.getClass().isArray(); | |
179 | for (Iterator iter = isArray | |
180 | ? new ArrayIterator(info.value) | |
181 | : isCollection ? ((Collection)info.value).iterator() : isEntry | |
182 | ? ((Map)info.value).entrySet().iterator() | |
183 | : ((Map)info.value).values().iterator(); iter.hasNext();) { | |
184 | Object obj = iter.next(); | |
185 | final String itemName; | |
186 | final Class itemType; | |
187 | if (obj == null) { | |
188 | itemType = Object.class; | |
189 | itemName = mapper.serializedClass(null); | |
190 | } else if (isEntry) { | |
191 | final String entryName = mapping.getItemFieldName() != null | |
192 | ? mapping.getItemFieldName() | |
193 | : mapper.serializedClass(Map.Entry.class); | |
194 | Map.Entry entry = (Map.Entry)obj; | |
195 | ExtendedHierarchicalStreamWriterHelper.startNode( | |
196 | writer, entryName, entry.getClass()); | |
197 | writeItem(entry.getKey(), context, writer); | |
198 | writeItem(entry.getValue(), context, writer); | |
199 | writer.endNode(); | |
200 | continue; | |
201 | } else if (mapping.getItemFieldName() != null) { | |
202 | itemType = mapping.getItemType(); | |
203 | itemName = mapping.getItemFieldName(); | |
204 | } else { | |
205 | itemType = obj.getClass(); | |
206 | itemName = mapper.serializedClass(itemType); | |
207 | } | |
208 | writeField( | |
209 | info.fieldName, itemName, itemType, info.definedIn, obj); | |
210 | } | |
211 | } else { | |
212 | writeField( | |
213 | info.fieldName, null, info.type, info.definedIn, info.value); | |
214 | } | |
215 | } | |
216 | } | |
217 | ||
218 | } | |
219 | ||
220 | void writeField(String fieldName, String aliasName, Class fieldType, | |
143 | final FieldMarshaller fieldMarshaller = new FieldMarshaller() { | |
144 | public void writeField(String fieldName, String aliasName, Class fieldType, | |
221 | 145 | Class definedIn, Object newObj) { |
222 | 146 | Class actualType = newObj != null ? newObj.getClass() : fieldType; |
223 | 147 | ExtendedHierarchicalStreamWriterHelper.startNode(writer, aliasName != null |
251 | 175 | writer.endNode(); |
252 | 176 | } |
253 | 177 | |
254 | void writeItem(Object item, MarshallingContext context, | |
255 | HierarchicalStreamWriter writer) { | |
178 | public void writeItem(Object item) { | |
256 | 179 | if (item == null) { |
257 | 180 | String name = mapper.serializedClass(null); |
258 | 181 | ExtendedHierarchicalStreamWriterHelper.startNode( |
267 | 190 | } |
268 | 191 | } |
269 | 192 | }; |
193 | ||
194 | final Map hiddenMappers = new HashMap(); | |
195 | for (Iterator fieldIter = fields.iterator(); fieldIter.hasNext();) { | |
196 | FieldInfo info = (FieldInfo)fieldIter.next(); | |
197 | if (info.value != null) { | |
198 | final Field defaultField = (Field)defaultFieldDefinition.get(info.fieldName); | |
199 | Mapper.ImplicitCollectionMapping mapping = mapper | |
200 | .getImplicitCollectionDefForFieldName( | |
201 | defaultField.getDeclaringClass() == info.definedIn ? sourceType : info.definedIn, | |
202 | info.fieldName); | |
203 | if (mapping != null) { | |
204 | Set mappings = (Set)hiddenMappers.get(info.fieldName); | |
205 | if (mappings == null) { | |
206 | mappings = new HashSet(); | |
207 | mappings.add(mapping); | |
208 | hiddenMappers.put(info.fieldName, mappings); | |
209 | } else { | |
210 | if (!mappings.add(mapping)) { | |
211 | mapping = null; | |
212 | } | |
213 | } | |
214 | } | |
215 | if (mapping != null) { | |
216 | if (context instanceof ReferencingMarshallingContext) { | |
217 | if (info.value != Collections.EMPTY_LIST | |
218 | && info.value != Collections.EMPTY_SET | |
219 | && info.value != Collections.EMPTY_MAP) { | |
220 | ReferencingMarshallingContext refContext = (ReferencingMarshallingContext)context; | |
221 | refContext.registerImplicit(info.value); | |
222 | } | |
223 | } | |
224 | final boolean isCollection = info.value instanceof Collection; | |
225 | final boolean isMap = info.value instanceof Map; | |
226 | final boolean isEntry = isMap && mapping.getKeyFieldName() == null; | |
227 | final boolean isArray = info.value.getClass().isArray(); | |
228 | for (Iterator iter = isArray | |
229 | ? new ArrayIterator(info.value) | |
230 | : isCollection ? ((Collection)info.value).iterator() : isEntry | |
231 | ? ((Map)info.value).entrySet().iterator() | |
232 | : ((Map)info.value).values().iterator(); iter.hasNext();) { | |
233 | Object obj = iter.next(); | |
234 | final String itemName; | |
235 | final Class itemType; | |
236 | if (obj == null) { | |
237 | itemType = Object.class; | |
238 | itemName = mapper.serializedClass(null); | |
239 | } else if (isEntry) { | |
240 | final String entryName = mapping.getItemFieldName() != null | |
241 | ? mapping.getItemFieldName() | |
242 | : mapper.serializedClass(Map.Entry.class); | |
243 | Map.Entry entry = (Map.Entry)obj; | |
244 | ExtendedHierarchicalStreamWriterHelper.startNode( | |
245 | writer, entryName, entry.getClass()); | |
246 | fieldMarshaller.writeItem(entry.getKey()); | |
247 | fieldMarshaller.writeItem(entry.getValue()); | |
248 | writer.endNode(); | |
249 | continue; | |
250 | } else if (mapping.getItemFieldName() != null) { | |
251 | itemType = mapping.getItemType(); | |
252 | itemName = mapping.getItemFieldName(); | |
253 | } else { | |
254 | itemType = obj.getClass(); | |
255 | itemName = mapper.serializedClass(itemType); | |
256 | } | |
257 | fieldMarshaller.writeField( | |
258 | info.fieldName, itemName, itemType, info.definedIn, obj); | |
259 | } | |
260 | } else { | |
261 | fieldMarshaller.writeField( | |
262 | info.fieldName, null, info.type, info.definedIn, info.value); | |
263 | } | |
264 | } | |
265 | } | |
270 | 266 | } |
271 | 267 | |
272 | 268 | protected void marshallField(final MarshallingContext context, Object newObj, Field field) { |
661 | 657 | } |
662 | 658 | } |
663 | 659 | |
660 | private interface FieldMarshaller { | |
661 | void writeItem(final Object item); | |
662 | void writeField(final String fieldName, final String aliasName, final Class fieldType, | |
663 | final Class definedIn, final Object newObj); | |
664 | } | |
665 | ||
664 | 666 | private static class ArraysList extends ArrayList { |
665 | 667 | final Class physicalFieldType; |
666 | 668 |
+2
-2
0 | 0 | /* |
1 | * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2013, 2014, 2015, 2016 XStream Committers. | |
1 | * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2013, 2014, 2015, 2016, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
88 | 88 | } |
89 | 89 | |
90 | 90 | public boolean canConvert(Class type) { |
91 | return (Enhancer.isEnhanced(type) && type.getName().indexOf(DEFAULT_NAMING_MARKER) > 0) | |
91 | return type != null && Enhancer.isEnhanced(type) && type.getName().indexOf(DEFAULT_NAMING_MARKER) > 0 | |
92 | 92 | || type == CGLIBMapper.Marker.class; |
93 | 93 | } |
94 | 94 |
+1
-1
75 | 75 | } |
76 | 76 | |
77 | 77 | public boolean canConvert(Class type) { |
78 | return JVM.canCreateDerivedObjectOutputStream() && Externalizable.class.isAssignableFrom(type); | |
78 | return type != null && JVM.canCreateDerivedObjectOutputStream() && Externalizable.class.isAssignableFrom(type); | |
79 | 79 | } |
80 | 80 | |
81 | 81 | public void marshal(final Object original, final HierarchicalStreamWriter writer, final MarshallingContext context) { |
+17
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * The software in this package is published under the terms of the BSD |
5 | 5 | * style license a copy of which has been included with this distribution in |
34 | 34 | Collections.EMPTY_MAP); |
35 | 35 | |
36 | 36 | private transient Map dictionaryEntries; |
37 | private transient FieldUtil fieldUtil; | |
37 | 38 | private final FieldKeySorter sorter; |
38 | 39 | |
39 | 40 | public FieldDictionary() { |
47 | 48 | |
48 | 49 | private void init() { |
49 | 50 | dictionaryEntries = new HashMap(); |
51 | if (JVM.is15()) | |
52 | try { | |
53 | fieldUtil = (FieldUtil)JVM.loadClassForName("com.thoughtworks.xstream.converters.reflection.FieldUtil15", true).newInstance(); | |
54 | } catch (Exception e) { | |
55 | ; | |
56 | } | |
57 | if (fieldUtil == null) | |
58 | fieldUtil = new FieldUtil14(); | |
50 | 59 | } |
51 | 60 | |
52 | 61 | /** |
159 | 168 | } |
160 | 169 | for (int i = 0; i < fields.length; i++) { |
161 | 170 | final Field field = fields[i]; |
171 | if (fieldUtil.isSynthetic(field) && field.getName().startsWith("$jacoco")) { | |
172 | continue; | |
173 | } | |
162 | 174 | if (!field.isAccessible()) { |
163 | 175 | field.setAccessible(true); |
164 | 176 | } |
193 | 205 | return this; |
194 | 206 | } |
195 | 207 | |
208 | interface FieldUtil { | |
209 | boolean isSynthetic(Field field); | |
210 | } | |
211 | ||
196 | 212 | private static final class DictionaryEntry { |
197 | 213 | |
198 | 214 | private final Map keyedByFieldName; |
0 | /* | |
1 | * Copyright (C) 2018 XStream Committers. | |
2 | * All rights reserved. | |
3 | * The software in this package is published under the terms of the BSD | |
4 | * style license a copy of which has been included with this distribution in | |
5 | * the LICENSE.txt file. | |
6 | * Created on 10. October 2018 by Joerg Schaible. | |
7 | */ | |
8 | package com.thoughtworks.xstream.converters.reflection; | |
9 | ||
10 | import java.lang.reflect.Field; | |
11 | ||
12 | /** | |
13 | * @author Jörg Schaible | |
14 | */ | |
15 | class FieldUtil14 implements FieldDictionary.FieldUtil { | |
16 | ||
17 | public boolean isSynthetic(final Field field) { | |
18 | return false; | |
19 | } | |
20 | } |
0 | /* | |
1 | * Copyright (C) 2018 XStream Committers. | |
2 | * All rights reserved. | |
3 | * The software in this package is published under the terms of the BSD | |
4 | * style license a copy of which has been included with this distribution in | |
5 | * the LICENSE.txt file. | |
6 | * Created on 10. October 2018 by Joerg Schaible. | |
7 | */ | |
8 | package com.thoughtworks.xstream.converters.reflection; | |
9 | ||
10 | import java.lang.reflect.Field; | |
11 | ||
12 | /** | |
13 | * @author Jörg Schaible | |
14 | */ | |
15 | class FieldUtil15 implements FieldDictionary.FieldUtil { | |
16 | ||
17 | public boolean isSynthetic(final Field field) { | |
18 | return field.isSynthetic(); | |
19 | } | |
20 | } |
+2
-2
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2009, 2011, 2013, 2016 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2009, 2011, 2013, 2016, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
167 | 167 | |
168 | 168 | protected void validateFieldAccess(Field field) { |
169 | 169 | if (Modifier.isFinal(field.getModifiers())) { |
170 | if (JVM.is15()) { | |
170 | if (JVM.isVersion(5)) { | |
171 | 171 | if (!field.isAccessible()) { |
172 | 172 | field.setAccessible(true); |
173 | 173 | } |
+2
-6
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2013, 2014 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2013, 2014, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.converters.reflection; |
12 | 12 | |
13 | import com.thoughtworks.xstream.core.JVM; | |
14 | 13 | import com.thoughtworks.xstream.mapper.Mapper; |
15 | 14 | |
16 | 15 | public class ReflectionConverter extends AbstractReflectionConverter { |
17 | 16 | |
18 | // Might be missing in Android | |
19 | private final static Class eventHandlerType = JVM.loadClassForName("java.beans.EventHandler"); | |
20 | 17 | private Class type; |
21 | 18 | |
22 | 19 | public ReflectionConverter(Mapper mapper, ReflectionProvider reflectionProvider) { |
37 | 34 | } |
38 | 35 | |
39 | 36 | public boolean canConvert(Class type) { |
40 | return ((this.type != null && this.type == type) || (this.type == null && type != null && type != eventHandlerType)) | |
41 | && canAccess(type); | |
37 | return (this.type != null && this.type == type || this.type == null && type != null) && canAccess(type); | |
42 | 38 | } |
43 | 39 | } |
+13
-9
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2011, 2013, 2014, 2016 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2011, 2013, 2014, 2016, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * Created on 08. January 2014 by Joerg Schaible, factored out from SunUnsafeReflectionProvider |
77 | 77 | throw ex; |
78 | 78 | } |
79 | 79 | ErrorWritingException ex = null; |
80 | try { | |
81 | return unsafe.allocateInstance(type); | |
82 | } catch (SecurityException e) { | |
83 | ex = new ObjectAccessException("Cannot construct type", e); | |
84 | } catch (InstantiationException e) { | |
85 | ex = new ConversionException("Cannot construct type", e); | |
86 | } catch (IllegalArgumentException e) { | |
87 | ex = new ObjectAccessException("Cannot construct type", e); | |
80 | if (type == void.class || type == Void.class) { | |
81 | ex = new ConversionException("Type void cannot have an instance"); | |
82 | } else { | |
83 | try { | |
84 | return unsafe.allocateInstance(type); | |
85 | } catch (final SecurityException e) { | |
86 | ex = new ObjectAccessException("Cannot construct type", e); | |
87 | } catch (final InstantiationException e) { | |
88 | ex = new ConversionException("Cannot construct type", e); | |
89 | } catch (final IllegalArgumentException e) { | |
90 | ex = new ObjectAccessException("Cannot construct type", e); | |
91 | } | |
88 | 92 | } |
89 | 93 | ex.add("construction-type", type.getName()); |
90 | 94 | throw ex; |
+77
-0
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 22. February 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.DateTimeException; | |
13 | import java.time.chrono.ChronoLocalDate; | |
14 | import java.time.chrono.Chronology; | |
15 | import java.time.chrono.Era; | |
16 | import java.util.Set; | |
17 | import java.util.regex.Matcher; | |
18 | import java.util.regex.Pattern; | |
19 | ||
20 | import com.thoughtworks.xstream.converters.ConversionException; | |
21 | import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; | |
22 | ||
23 | ||
24 | /** | |
25 | * Abstract base class for converters handling derived classes of {@link java.time.chrono.ChronoLocalDate} instances. | |
26 | * | |
27 | * @author Jörg Schaible | |
28 | * @since 1.4.10 | |
29 | */ | |
30 | abstract class AbstractChronoLocalDateConverter<E extends Era> extends AbstractSingleValueConverter { | |
31 | protected abstract ChronoLocalDate chronoLocalDateOf(final E era, final int prolepticYear, final int month, | |
32 | final int dayOfMonth); | |
33 | ||
34 | protected abstract E eraOf(final String id); | |
35 | ||
36 | private final static Pattern CHRONO_DATE_PATTERN = Pattern.compile("^ (\\w+) (\\d+)-(\\d+)-(\\d+)$"); | |
37 | ||
38 | protected ChronoLocalDate parseChronoLocalDate(final String str, final String dateTypeName, | |
39 | final Set<Chronology> chronologies) { | |
40 | if (str == null) { | |
41 | return null; | |
42 | } | |
43 | ||
44 | ConversionException exception = null; | |
45 | for (final Chronology chronology : chronologies) { | |
46 | final String id = chronology.getId(); | |
47 | if (str.startsWith(id + ' ')) { | |
48 | final Matcher matcher = CHRONO_DATE_PATTERN.matcher(str.subSequence(id.length(), str.length())); | |
49 | if (matcher.matches()) { | |
50 | E era = null; | |
51 | try { | |
52 | era = eraOf(matcher.group(1)); | |
53 | } catch (final IllegalArgumentException e) { | |
54 | exception = new ConversionException("Cannot parse value as " + dateTypeName + " date", e); | |
55 | break; | |
56 | } | |
57 | if (era != null) { | |
58 | try { | |
59 | return chronoLocalDateOf(era, Integer.parseInt(matcher.group(2)), Integer.parseInt(matcher | |
60 | .group(3)), Integer.parseInt(matcher.group(4))); | |
61 | } catch (final DateTimeException e) { | |
62 | exception = new ConversionException("Cannot parse value as " + dateTypeName + " date", e); | |
63 | break; | |
64 | } | |
65 | } | |
66 | } | |
67 | } | |
68 | } | |
69 | if (exception == null) { | |
70 | exception = new ConversionException("Cannot parse value as " + dateTypeName + " date"); | |
71 | } | |
72 | exception.add("value", str); | |
73 | throw exception; | |
74 | } | |
75 | ||
76 | } |
0 | /* | |
1 | * Copyright (C) 2017, 2018 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 19. February 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.DateTimeException; | |
13 | import java.time.chrono.Chronology; | |
14 | ||
15 | import com.thoughtworks.xstream.converters.ConversionException; | |
16 | import com.thoughtworks.xstream.converters.SingleValueConverter; | |
17 | ||
18 | ||
19 | /** | |
20 | * Converts a {@link Chronology} instance to a string using its id. | |
21 | * | |
22 | * @author Jörg Schaible | |
23 | * @since 1.4.10 | |
24 | */ | |
25 | public class ChronologyConverter implements SingleValueConverter { | |
26 | ||
27 | @Override | |
28 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
29 | return type != null && Chronology.class.isAssignableFrom(type); | |
30 | } | |
31 | ||
32 | @Override | |
33 | public Chronology fromString(final String str) { | |
34 | if (str == null) { | |
35 | return null; | |
36 | } | |
37 | try { | |
38 | return Chronology.of(str); | |
39 | } catch (final DateTimeException e) { | |
40 | final ConversionException exception = new ConversionException("Cannot parse value as chronology", e); | |
41 | exception.add("value", str); | |
42 | throw exception; | |
43 | } | |
44 | } | |
45 | ||
46 | @Override | |
47 | public String toString(final Object obj) { | |
48 | return obj == null ? null : ((Chronology)obj).getId(); | |
49 | } | |
50 | } |
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 13. February 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.Duration; | |
13 | import java.time.format.DateTimeParseException; | |
14 | ||
15 | import com.thoughtworks.xstream.converters.ConversionException; | |
16 | import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; | |
17 | ||
18 | ||
19 | /** | |
20 | * Converts a {@link Duration} instance to string. | |
21 | * | |
22 | * @author Jörg Schaible | |
23 | * @since 1.4.10 | |
24 | */ | |
25 | public class DurationConverter extends AbstractSingleValueConverter { | |
26 | ||
27 | @Override | |
28 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
29 | return Duration.class == type; | |
30 | } | |
31 | ||
32 | @Override | |
33 | public Duration fromString(final String str) { | |
34 | try { | |
35 | return Duration.parse(str); | |
36 | } catch (final DateTimeParseException ex) { | |
37 | final ConversionException exception = new ConversionException("Cannot parse value as duration", ex); | |
38 | exception.add("value", str); | |
39 | throw exception; | |
40 | } | |
41 | } | |
42 | } |
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 21. February 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.chrono.ChronoLocalDate; | |
13 | import java.time.chrono.Chronology; | |
14 | import java.time.chrono.HijrahChronology; | |
15 | import java.time.chrono.HijrahDate; | |
16 | import java.time.chrono.HijrahEra; | |
17 | import java.util.HashSet; | |
18 | import java.util.Set; | |
19 | ||
20 | ||
21 | /** | |
22 | * Converts a {@link java.time.chrono.HijrahDate} to a string. | |
23 | * | |
24 | * @author Jörg Schaible | |
25 | * @since 1.4.10 | |
26 | */ | |
27 | public class HijrahDateConverter extends AbstractChronoLocalDateConverter<HijrahEra> { | |
28 | ||
29 | private final Set<Chronology> hijrahChronologies; | |
30 | ||
31 | /** | |
32 | * Constructs a HijrahDateConverter instance. | |
33 | */ | |
34 | public HijrahDateConverter() { | |
35 | hijrahChronologies = new HashSet<>(); | |
36 | final Set<Chronology> chronologies = Chronology.getAvailableChronologies(); | |
37 | for (final Chronology chronology : chronologies) { | |
38 | if (chronology instanceof HijrahChronology) { | |
39 | hijrahChronologies.add(chronology); | |
40 | } | |
41 | } | |
42 | } | |
43 | ||
44 | @Override | |
45 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
46 | return HijrahDate.class == type; | |
47 | } | |
48 | ||
49 | @Override | |
50 | public Object fromString(final String str) { | |
51 | return parseChronoLocalDate(str, "Hijrah", hijrahChronologies); | |
52 | } | |
53 | ||
54 | @Override | |
55 | protected ChronoLocalDate chronoLocalDateOf(final HijrahEra era, final int prolepticYear, final int month, | |
56 | final int dayOfMonth) { | |
57 | return era != null ? HijrahDate.of(prolepticYear, month, dayOfMonth) : null; | |
58 | } | |
59 | ||
60 | @Override | |
61 | protected HijrahEra eraOf(final String id) { | |
62 | return HijrahEra.valueOf(id); | |
63 | } | |
64 | ||
65 | } |
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 15. February 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.Instant; | |
13 | import java.time.format.DateTimeParseException; | |
14 | ||
15 | import com.thoughtworks.xstream.converters.ConversionException; | |
16 | import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; | |
17 | ||
18 | ||
19 | /** | |
20 | * Converts a {@link Instant} instance to string. | |
21 | * | |
22 | * @author Jörg Schaible | |
23 | * @since 1.4.10 | |
24 | */ | |
25 | public class InstantConverter extends AbstractSingleValueConverter { | |
26 | ||
27 | @Override | |
28 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
29 | return Instant.class == type; | |
30 | } | |
31 | ||
32 | @Override | |
33 | public Instant fromString(final String str) { | |
34 | try { | |
35 | return Instant.parse(str); | |
36 | } catch (final DateTimeParseException ex) { | |
37 | final ConversionException exception = new ConversionException("Cannot parse value as instant", ex); | |
38 | exception.add("value", str); | |
39 | throw exception; | |
40 | } | |
41 | } | |
42 | } |
+49
-0
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 22. February 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.chrono.ChronoLocalDate; | |
13 | import java.time.chrono.JapaneseChronology; | |
14 | import java.time.chrono.JapaneseDate; | |
15 | import java.time.chrono.JapaneseEra; | |
16 | import java.util.Collections; | |
17 | ||
18 | ||
19 | /** | |
20 | * Converts a {@link java.time.chrono.JapaneseDate} to a string. | |
21 | * | |
22 | * @author Jörg Schaible | |
23 | * @since 1.4.10 | |
24 | */ | |
25 | public class JapaneseDateConverter extends AbstractChronoLocalDateConverter<JapaneseEra> { | |
26 | ||
27 | @Override | |
28 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
29 | return JapaneseDate.class == type; | |
30 | } | |
31 | ||
32 | @Override | |
33 | public Object fromString(final String str) { | |
34 | return parseChronoLocalDate(str, "Japanese", Collections.singleton(JapaneseChronology.INSTANCE)); | |
35 | } | |
36 | ||
37 | @Override | |
38 | protected ChronoLocalDate chronoLocalDateOf(final JapaneseEra era, final int prolepticYear, final int month, | |
39 | final int dayOfMonth) { | |
40 | return JapaneseDate.of(era, prolepticYear, month, dayOfMonth); | |
41 | } | |
42 | ||
43 | @Override | |
44 | protected JapaneseEra eraOf(final String id) { | |
45 | return JapaneseEra.valueOf(id); | |
46 | } | |
47 | ||
48 | } |
+45
-0
0 | /* | |
1 | * Copyright (C) 2017, 2018 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 22. February 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.chrono.JapaneseEra; | |
13 | ||
14 | import com.thoughtworks.xstream.converters.ConversionException; | |
15 | import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; | |
16 | ||
17 | ||
18 | /** | |
19 | * Converts a {@link JapaneseEra} instance to a string using its id. | |
20 | * | |
21 | * @author Jörg Schaible | |
22 | * @since 1.4.10 | |
23 | */ | |
24 | public class JapaneseEraConverter extends AbstractSingleValueConverter { | |
25 | ||
26 | @Override | |
27 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
28 | return type != null && JapaneseEra.class.isAssignableFrom(type); | |
29 | } | |
30 | ||
31 | @Override | |
32 | public JapaneseEra fromString(final String str) { | |
33 | if (str == null) { | |
34 | return null; | |
35 | } | |
36 | try { | |
37 | return JapaneseEra.valueOf(str); | |
38 | } catch (final IllegalArgumentException e) { | |
39 | final ConversionException exception = new ConversionException("Cannot parse value as Japanese era", e); | |
40 | exception.add("value", str); | |
41 | throw exception; | |
42 | } | |
43 | } | |
44 | } |
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 13. January 2017 by Matej Cimbora | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.LocalDate; | |
13 | import java.time.format.DateTimeParseException; | |
14 | ||
15 | import com.thoughtworks.xstream.converters.ConversionException; | |
16 | import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; | |
17 | ||
18 | ||
19 | /** | |
20 | * Converts a {@link java.time.LocalDate} to a string. | |
21 | * | |
22 | * @author Matej Cimbora | |
23 | * @since 1.4.10 | |
24 | */ | |
25 | public class LocalDateConverter extends AbstractSingleValueConverter { | |
26 | ||
27 | @Override | |
28 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
29 | return LocalDate.class == type; | |
30 | } | |
31 | ||
32 | @Override | |
33 | public Object fromString(final String str) { | |
34 | try { | |
35 | return LocalDate.parse(str); | |
36 | } catch (final DateTimeParseException e) { | |
37 | final ConversionException exception = new ConversionException("Cannot parse value as local date", e); | |
38 | exception.add("value", str); | |
39 | throw exception; | |
40 | } | |
41 | } | |
42 | ||
43 | } |
+65
-0
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 13. January 2017 by Matej Cimbora | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.LocalDateTime; | |
13 | import java.time.format.DateTimeFormatter; | |
14 | import java.time.format.DateTimeFormatterBuilder; | |
15 | import java.time.format.DateTimeParseException; | |
16 | import java.time.temporal.ChronoField; | |
17 | ||
18 | import com.thoughtworks.xstream.converters.ConversionException; | |
19 | import com.thoughtworks.xstream.converters.SingleValueConverter; | |
20 | ||
21 | ||
22 | /** | |
23 | * Converts a {@link LocalDateTime} to a string. | |
24 | * | |
25 | * @author Matej Cimbora | |
26 | * @since 1.4.10 | |
27 | */ | |
28 | public class LocalDateTimeConverter implements SingleValueConverter { | |
29 | ||
30 | private static final DateTimeFormatter FORMATTER; | |
31 | ||
32 | static { | |
33 | FORMATTER = new DateTimeFormatterBuilder() | |
34 | .appendPattern("uuuu-MM-dd'T'HH:mm:ss") | |
35 | .appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true) | |
36 | .toFormatter(); | |
37 | } | |
38 | ||
39 | @Override | |
40 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
41 | return LocalDateTime.class == type; | |
42 | } | |
43 | ||
44 | @Override | |
45 | public Object fromString(final String str) { | |
46 | try { | |
47 | return LocalDateTime.parse(str); | |
48 | } catch (final DateTimeParseException e) { | |
49 | final ConversionException exception = new ConversionException("Cannot parse value as local date time", e); | |
50 | exception.add("value", str); | |
51 | throw exception; | |
52 | } | |
53 | } | |
54 | ||
55 | @Override | |
56 | public String toString(final Object obj) { | |
57 | if (obj == null) { | |
58 | return null; | |
59 | } | |
60 | ||
61 | final LocalDateTime localDateTime = (LocalDateTime)obj; | |
62 | return FORMATTER.format(localDateTime); | |
63 | } | |
64 | } |
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 13. January 2017 by Matej Cimbora | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.LocalTime; | |
13 | import java.time.format.DateTimeFormatter; | |
14 | import java.time.format.DateTimeFormatterBuilder; | |
15 | import java.time.format.DateTimeParseException; | |
16 | import java.time.temporal.ChronoField; | |
17 | ||
18 | import com.thoughtworks.xstream.converters.ConversionException; | |
19 | import com.thoughtworks.xstream.converters.SingleValueConverter; | |
20 | ||
21 | ||
22 | /** | |
23 | * Converts a {@link LocalTime} to a string. | |
24 | * | |
25 | * @author Matej Cimbora | |
26 | * @since 1.4.10 | |
27 | */ | |
28 | public class LocalTimeConverter implements SingleValueConverter { | |
29 | ||
30 | private static final DateTimeFormatter FORMATTER; | |
31 | ||
32 | static { | |
33 | FORMATTER = new DateTimeFormatterBuilder() | |
34 | .appendPattern("HH:mm:ss") | |
35 | .appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true) | |
36 | .toFormatter(); | |
37 | } | |
38 | ||
39 | @Override | |
40 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
41 | return LocalTime.class == type; | |
42 | } | |
43 | ||
44 | @Override | |
45 | public Object fromString(final String str) { | |
46 | try { | |
47 | return LocalTime.parse(str); | |
48 | } catch (final DateTimeParseException e) { | |
49 | final ConversionException exception = new ConversionException("Cannot parse value as local time", e); | |
50 | exception.add("value", str); | |
51 | throw exception; | |
52 | } | |
53 | } | |
54 | ||
55 | @Override | |
56 | public String toString(final Object obj) { | |
57 | if (obj == null) { | |
58 | return null; | |
59 | } | |
60 | ||
61 | final LocalTime localTime = (LocalTime)obj; | |
62 | return FORMATTER.format(localTime); | |
63 | } | |
64 | } |
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 22. February 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.chrono.ChronoLocalDate; | |
13 | import java.time.chrono.MinguoChronology; | |
14 | import java.time.chrono.MinguoDate; | |
15 | import java.time.chrono.MinguoEra; | |
16 | import java.util.Collections; | |
17 | ||
18 | ||
19 | /** | |
20 | * Converts a {@link java.time.chrono.MinguoDate} to a string. | |
21 | * | |
22 | * @author Jörg Schaible | |
23 | * @since 1.4.10 | |
24 | */ | |
25 | public class MinguoDateConverter extends AbstractChronoLocalDateConverter<MinguoEra> { | |
26 | ||
27 | @Override | |
28 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
29 | return MinguoDate.class == type; | |
30 | } | |
31 | ||
32 | @Override | |
33 | public Object fromString(final String str) { | |
34 | return parseChronoLocalDate(str, "Minguo", Collections.singleton(MinguoChronology.INSTANCE)); | |
35 | } | |
36 | ||
37 | @Override | |
38 | protected ChronoLocalDate chronoLocalDateOf(final MinguoEra era, final int prolepticYear, final int month, | |
39 | final int dayOfMonth) { | |
40 | return MinguoDate.of(prolepticYear, month, dayOfMonth); | |
41 | } | |
42 | ||
43 | @Override | |
44 | protected MinguoEra eraOf(final String id) { | |
45 | return MinguoEra.valueOf(id); | |
46 | } | |
47 | ||
48 | } |
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 13. February 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.MonthDay; | |
13 | import java.time.format.DateTimeParseException; | |
14 | ||
15 | import com.thoughtworks.xstream.converters.ConversionException; | |
16 | import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; | |
17 | ||
18 | ||
19 | /** | |
20 | * Converts a {@link MonthDay} instance to string. | |
21 | * | |
22 | * @author Jörg Schaible | |
23 | * @since 1.4.10 | |
24 | */ | |
25 | public class MonthDayConverter extends AbstractSingleValueConverter { | |
26 | ||
27 | @Override | |
28 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
29 | return MonthDay.class == type; | |
30 | } | |
31 | ||
32 | @Override | |
33 | public MonthDay fromString(final String str) { | |
34 | try { | |
35 | return MonthDay.parse(str); | |
36 | } catch (final DateTimeParseException ex) { | |
37 | final ConversionException exception = new ConversionException("Cannot parse value as month day", ex); | |
38 | exception.add("value", str); | |
39 | throw exception; | |
40 | } | |
41 | } | |
42 | } |
+66
-0
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 13. January 2017 by Matej Cimbora | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.OffsetDateTime; | |
13 | import java.time.format.DateTimeFormatter; | |
14 | import java.time.format.DateTimeFormatterBuilder; | |
15 | import java.time.format.DateTimeParseException; | |
16 | import java.time.temporal.ChronoField; | |
17 | ||
18 | import com.thoughtworks.xstream.converters.ConversionException; | |
19 | import com.thoughtworks.xstream.converters.SingleValueConverter; | |
20 | ||
21 | ||
22 | /** | |
23 | * Converts a {@link OffsetDateTime} to a string. | |
24 | * | |
25 | * @author Matej Cimbora | |
26 | * @since 1.4.10 | |
27 | */ | |
28 | public class OffsetDateTimeConverter implements SingleValueConverter { | |
29 | ||
30 | private static final DateTimeFormatter FORMATTER; | |
31 | ||
32 | static { | |
33 | FORMATTER = new DateTimeFormatterBuilder() | |
34 | .appendPattern("uuuu-MM-dd'T'HH:mm:ss") | |
35 | .appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true) | |
36 | .appendOffsetId() | |
37 | .toFormatter(); | |
38 | } | |
39 | ||
40 | @Override | |
41 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
42 | return OffsetDateTime.class == type; | |
43 | } | |
44 | ||
45 | @Override | |
46 | public Object fromString(final String str) { | |
47 | try { | |
48 | return OffsetDateTime.parse(str); | |
49 | } catch (final DateTimeParseException e) { | |
50 | final ConversionException exception = new ConversionException("Cannot parse value as offset date time", e); | |
51 | exception.add("value", str); | |
52 | throw exception; | |
53 | } | |
54 | } | |
55 | ||
56 | @Override | |
57 | public String toString(final Object obj) { | |
58 | if (obj == null) { | |
59 | return null; | |
60 | } | |
61 | ||
62 | final OffsetDateTime offsetDateTime = (OffsetDateTime)obj; | |
63 | return FORMATTER.format(offsetDateTime); | |
64 | } | |
65 | } |
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 11. February 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.OffsetTime; | |
13 | import java.time.format.DateTimeFormatter; | |
14 | import java.time.format.DateTimeFormatterBuilder; | |
15 | import java.time.format.DateTimeParseException; | |
16 | import java.time.temporal.ChronoField; | |
17 | ||
18 | import com.thoughtworks.xstream.converters.ConversionException; | |
19 | import com.thoughtworks.xstream.converters.SingleValueConverter; | |
20 | ||
21 | ||
22 | /** | |
23 | * Converts a {@link OffsetTime} to a string. | |
24 | * | |
25 | * @author Matej Cimbora | |
26 | * @author Jörg Schaible | |
27 | * @since 1.4.10 | |
28 | */ | |
29 | public class OffsetTimeConverter implements SingleValueConverter { | |
30 | ||
31 | private static final DateTimeFormatter FORMATTER; | |
32 | ||
33 | static { | |
34 | FORMATTER = new DateTimeFormatterBuilder() | |
35 | .appendPattern("HH:mm:ss") | |
36 | .appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true) | |
37 | .appendOffsetId() | |
38 | .toFormatter(); | |
39 | } | |
40 | ||
41 | @Override | |
42 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
43 | return OffsetTime.class == type; | |
44 | } | |
45 | ||
46 | @Override | |
47 | public Object fromString(final String str) { | |
48 | try { | |
49 | return OffsetTime.parse(str); | |
50 | } catch (final DateTimeParseException e) { | |
51 | final ConversionException exception = new ConversionException("Cannot parse value as offset time", e); | |
52 | exception.add("value", str); | |
53 | throw exception; | |
54 | } | |
55 | } | |
56 | ||
57 | @Override | |
58 | public String toString(final Object obj) { | |
59 | if (obj == null) { | |
60 | return null; | |
61 | } | |
62 | ||
63 | final OffsetTime offsetTime = (OffsetTime)obj; | |
64 | return FORMATTER.format(offsetTime); | |
65 | } | |
66 | } |
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 13. February 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.Period; | |
13 | import java.time.format.DateTimeParseException; | |
14 | ||
15 | import com.thoughtworks.xstream.converters.ConversionException; | |
16 | import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; | |
17 | ||
18 | ||
19 | /** | |
20 | * Converts a {@link Period} instance to string. | |
21 | * | |
22 | * @author Jörg Schaible | |
23 | * @since 1.4.10 | |
24 | */ | |
25 | public class PeriodConverter extends AbstractSingleValueConverter { | |
26 | ||
27 | @Override | |
28 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
29 | return Period.class == type; | |
30 | } | |
31 | ||
32 | @Override | |
33 | public Period fromString(final String str) { | |
34 | try { | |
35 | return Period.parse(str); | |
36 | } catch (final DateTimeParseException ex) { | |
37 | final ConversionException exception = new ConversionException("Cannot parse period value", ex); | |
38 | exception.add("period", str); | |
39 | throw exception; | |
40 | } | |
41 | } | |
42 | } |
+66
-0
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 06. March 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.Clock; | |
13 | import java.time.ZoneId; | |
14 | ||
15 | import com.thoughtworks.xstream.converters.Converter; | |
16 | import com.thoughtworks.xstream.converters.MarshallingContext; | |
17 | import com.thoughtworks.xstream.converters.UnmarshallingContext; | |
18 | import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; | |
19 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; | |
20 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; | |
21 | import com.thoughtworks.xstream.mapper.Mapper; | |
22 | ||
23 | ||
24 | /** | |
25 | * Converts a system {@link Clock}, using zone as nested element. | |
26 | * | |
27 | * @author Jörg Schaible | |
28 | * @since 1.4.10 | |
29 | */ | |
30 | public class SystemClockConverter implements Converter { | |
31 | ||
32 | private final Mapper mapper; | |
33 | private final Class<?> type; | |
34 | ||
35 | /** | |
36 | * Constructs a SystemClockConverter instance. | |
37 | * | |
38 | * @param mapper the Mapper instance | |
39 | */ | |
40 | public SystemClockConverter(final Mapper mapper) { | |
41 | this.mapper = mapper; | |
42 | type = Clock.systemUTC().getClass(); | |
43 | } | |
44 | ||
45 | @Override | |
46 | public boolean canConvert(final Class type) { | |
47 | return type == this.type; | |
48 | } | |
49 | ||
50 | @Override | |
51 | public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { | |
52 | final Clock clock = (Clock)source; | |
53 | ExtendedHierarchicalStreamWriterHelper.startNode(writer, mapper.serializedMember(Clock.class, "zone"), null); | |
54 | context.convertAnother(clock.getZone()); | |
55 | writer.endNode(); | |
56 | } | |
57 | ||
58 | @Override | |
59 | public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { | |
60 | reader.moveDown(); | |
61 | final ZoneId zone = (ZoneId)context.convertAnother(null, ZoneId.class); | |
62 | reader.moveUp(); | |
63 | return Clock.system(zone); | |
64 | } | |
65 | } |
+49
-0
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 22. February 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.chrono.ChronoLocalDate; | |
13 | import java.time.chrono.ThaiBuddhistChronology; | |
14 | import java.time.chrono.ThaiBuddhistDate; | |
15 | import java.time.chrono.ThaiBuddhistEra; | |
16 | import java.util.Collections; | |
17 | ||
18 | ||
19 | /** | |
20 | * Converts a {@link java.time.chrono.ThaiBuddhistDate} to a string. | |
21 | * | |
22 | * @author Jörg Schaible | |
23 | * @since 1.4.10 | |
24 | */ | |
25 | public class ThaiBuddhistDateConverter extends AbstractChronoLocalDateConverter<ThaiBuddhistEra> { | |
26 | ||
27 | @Override | |
28 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
29 | return ThaiBuddhistDate.class == type; | |
30 | } | |
31 | ||
32 | @Override | |
33 | public Object fromString(final String str) { | |
34 | return parseChronoLocalDate(str, "Thai Buddhist", Collections.singleton(ThaiBuddhistChronology.INSTANCE)); | |
35 | } | |
36 | ||
37 | @Override | |
38 | protected ChronoLocalDate chronoLocalDateOf(final ThaiBuddhistEra era, final int prolepticYear, final int month, | |
39 | final int dayOfMonth) { | |
40 | return ThaiBuddhistDate.of(prolepticYear, month, dayOfMonth); | |
41 | } | |
42 | ||
43 | @Override | |
44 | protected ThaiBuddhistEra eraOf(final String id) { | |
45 | return ThaiBuddhistEra.valueOf(id); | |
46 | } | |
47 | ||
48 | } |
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 22. February 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.temporal.ValueRange; | |
13 | import java.util.HashMap; | |
14 | import java.util.Map; | |
15 | ||
16 | import com.thoughtworks.xstream.converters.Converter; | |
17 | import com.thoughtworks.xstream.converters.MarshallingContext; | |
18 | import com.thoughtworks.xstream.converters.UnmarshallingContext; | |
19 | import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; | |
20 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; | |
21 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; | |
22 | import com.thoughtworks.xstream.mapper.Mapper; | |
23 | ||
24 | ||
25 | /** | |
26 | * Converts a temporal {@link ValueRange}, using four nested elements: maxLargest, maxSmallest, minLargest, and | |
27 | * minSmallest. | |
28 | * | |
29 | * @author Jörg Schaible | |
30 | * @since 1.4.10 | |
31 | */ | |
32 | public class ValueRangeConverter implements Converter { | |
33 | ||
34 | private final Mapper mapper; | |
35 | ||
36 | /** | |
37 | * Constructs a ValueRangeConverter instance. | |
38 | * | |
39 | * @param mapper the Mapper instance | |
40 | */ | |
41 | public ValueRangeConverter(final Mapper mapper) { | |
42 | this.mapper = mapper; | |
43 | ||
44 | } | |
45 | ||
46 | @Override | |
47 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
48 | return type == ValueRange.class; | |
49 | } | |
50 | ||
51 | @Override | |
52 | public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { | |
53 | final ValueRange valueRange = (ValueRange)source; | |
54 | write("maxLargest", valueRange.getMaximum(), writer); | |
55 | write("maxSmallest", valueRange.getSmallestMaximum(), writer); | |
56 | write("minLargest", valueRange.getLargestMinimum(), writer); | |
57 | write("minSmallest", valueRange.getMinimum(), writer); | |
58 | } | |
59 | ||
60 | @Override | |
61 | public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { | |
62 | final boolean oldFormat = "custom".equals(reader.getAttribute(mapper.aliasForSystemAttribute("serialization"))); | |
63 | if (oldFormat) { | |
64 | reader.moveDown(); | |
65 | reader.moveDown(); | |
66 | } | |
67 | final Map<String, Long> elements = new HashMap<>(); | |
68 | while (reader.hasMoreChildren()) { | |
69 | reader.moveDown(); | |
70 | ||
71 | final String name = reader.getNodeName(); | |
72 | elements.put(oldFormat ? name : mapper.realMember(ValueRange.class, name), Long.valueOf(reader.getValue())); | |
73 | reader.moveUp(); | |
74 | } | |
75 | if (oldFormat) { | |
76 | reader.moveUp(); | |
77 | reader.moveUp(); | |
78 | } | |
79 | return ValueRange.of(elements.get("minSmallest").longValue(), elements.get("minLargest").longValue(), elements | |
80 | .get("maxSmallest") | |
81 | .longValue(), elements.get("maxLargest").longValue()); | |
82 | } | |
83 | ||
84 | private void write(final String fieldName, final long value, final HierarchicalStreamWriter writer) { | |
85 | ExtendedHierarchicalStreamWriterHelper.startNode(writer, mapper.serializedMember(ValueRange.class, fieldName), | |
86 | long.class); | |
87 | writer.setValue(String.valueOf(value)); | |
88 | writer.endNode(); | |
89 | } | |
90 | } |
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 22. February 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.DayOfWeek; | |
13 | import java.time.temporal.WeekFields; | |
14 | ||
15 | import com.thoughtworks.xstream.converters.Converter; | |
16 | import com.thoughtworks.xstream.converters.MarshallingContext; | |
17 | import com.thoughtworks.xstream.converters.UnmarshallingContext; | |
18 | import com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.UnknownFieldException; | |
19 | import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; | |
20 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; | |
21 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; | |
22 | import com.thoughtworks.xstream.mapper.Mapper; | |
23 | ||
24 | ||
25 | /** | |
26 | * Converts a {@link WeekFields} instance, using two nested elements: minimalDays and minSmallest. | |
27 | * | |
28 | * @author Jörg Schaible | |
29 | * @since 1.4.10 | |
30 | */ | |
31 | public class WeekFieldsConverter implements Converter { | |
32 | ||
33 | private final Mapper mapper; | |
34 | ||
35 | /** | |
36 | * Constructs a WeekFieldsConverter instance. | |
37 | * | |
38 | * @param mapper the Mapper instance | |
39 | */ | |
40 | public WeekFieldsConverter(final Mapper mapper) { | |
41 | this.mapper = mapper; | |
42 | ||
43 | } | |
44 | ||
45 | @Override | |
46 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
47 | return type == WeekFields.class; | |
48 | } | |
49 | ||
50 | @Override | |
51 | public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { | |
52 | final WeekFields weekFields = (WeekFields)source; | |
53 | ExtendedHierarchicalStreamWriterHelper.startNode(writer, mapper.serializedMember(WeekFields.class, | |
54 | "minimalDays"), int.class); | |
55 | writer.setValue(String.valueOf(weekFields.getMinimalDaysInFirstWeek())); | |
56 | writer.endNode(); | |
57 | ExtendedHierarchicalStreamWriterHelper.startNode(writer, mapper.serializedMember(WeekFields.class, | |
58 | "firstDayOfWeek"), DayOfWeek.class); | |
59 | context.convertAnother(weekFields.getFirstDayOfWeek()); | |
60 | writer.endNode(); | |
61 | } | |
62 | ||
63 | @Override | |
64 | public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { | |
65 | final boolean oldFormat = "custom".equals(reader.getAttribute(mapper.aliasForSystemAttribute("serialization"))); | |
66 | if (oldFormat) { | |
67 | reader.moveDown(); | |
68 | reader.moveDown(); | |
69 | } | |
70 | ||
71 | int minimalDays = 0; | |
72 | DayOfWeek firstDayOfWeek = null; | |
73 | while (reader.hasMoreChildren()) { | |
74 | reader.moveDown(); | |
75 | final String name = oldFormat | |
76 | ? reader.getNodeName() | |
77 | : mapper.realMember(WeekFields.class, reader.getNodeName()); | |
78 | if ("minimalDays".equals(name)) { | |
79 | minimalDays = Integer.parseInt(reader.getValue()); | |
80 | } else if ("firstDayOfWeek".equals(name)) { | |
81 | firstDayOfWeek = (DayOfWeek)context.convertAnother(null, DayOfWeek.class); | |
82 | } else { | |
83 | throw new UnknownFieldException(WeekFields.class.getName(), name); | |
84 | } | |
85 | reader.moveUp(); | |
86 | } | |
87 | if (oldFormat) { | |
88 | reader.moveUp(); | |
89 | reader.moveUp(); | |
90 | } | |
91 | return WeekFields.of(firstDayOfWeek, minimalDays); | |
92 | } | |
93 | } |
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 11. February 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.Year; | |
13 | ||
14 | import com.thoughtworks.xstream.converters.ConversionException; | |
15 | import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; | |
16 | ||
17 | ||
18 | /** | |
19 | * Converts a {@link Year} instance to string. | |
20 | * | |
21 | * @author Jörg Schaible | |
22 | * @since 1.4.10 | |
23 | */ | |
24 | public class YearConverter extends AbstractSingleValueConverter { | |
25 | ||
26 | @Override | |
27 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
28 | return Year.class == type; | |
29 | } | |
30 | ||
31 | @Override | |
32 | public Year fromString(final String str) { | |
33 | try { | |
34 | return Year.of(Integer.parseInt(str)); | |
35 | } catch (final NumberFormatException ex) { | |
36 | final ConversionException exception = new ConversionException("Cannot parse value as year", ex); | |
37 | exception.add("value", str); | |
38 | throw exception; | |
39 | } | |
40 | } | |
41 | } |
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 11. February 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.YearMonth; | |
13 | import java.time.format.DateTimeParseException; | |
14 | ||
15 | import com.thoughtworks.xstream.converters.ConversionException; | |
16 | import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; | |
17 | ||
18 | ||
19 | /** | |
20 | * Converts a {@link YearMonth} instance to string. | |
21 | * | |
22 | * @author Jörg Schaible | |
23 | * @since 1.4.10 | |
24 | */ | |
25 | public class YearMonthConverter extends AbstractSingleValueConverter { | |
26 | ||
27 | @Override | |
28 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
29 | return YearMonth.class == type; | |
30 | } | |
31 | ||
32 | @Override | |
33 | public YearMonth fromString(final String str) { | |
34 | try { | |
35 | return YearMonth.parse(str); | |
36 | } catch (final DateTimeParseException ex) { | |
37 | final ConversionException exception = new ConversionException("Cannot parse value as year month", ex); | |
38 | exception.add("value", str); | |
39 | throw exception; | |
40 | } | |
41 | } | |
42 | } |
0 | /* | |
1 | * Copyright (C) 2017, 2018 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 8. February 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.DateTimeException; | |
13 | import java.time.ZoneId; | |
14 | import java.time.zone.ZoneRulesException; | |
15 | ||
16 | import com.thoughtworks.xstream.converters.ConversionException; | |
17 | import com.thoughtworks.xstream.converters.SingleValueConverter; | |
18 | ||
19 | ||
20 | /** | |
21 | * Converts a {@link ZoneId} instance to string. | |
22 | * | |
23 | * @author Jörg Schaible | |
24 | * @since 1.4.10 | |
25 | */ | |
26 | public class ZoneIdConverter implements SingleValueConverter { | |
27 | ||
28 | @Override | |
29 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
30 | return type != null && ZoneId.class.isAssignableFrom(type); | |
31 | } | |
32 | ||
33 | @Override | |
34 | public ZoneId fromString(final String str) { | |
35 | ConversionException exception; | |
36 | try { | |
37 | return ZoneId.of(str); | |
38 | } catch (final ZoneRulesException e) { | |
39 | exception = new ConversionException("Not a valid zone id", e); | |
40 | } catch (final DateTimeException e) { | |
41 | exception = new ConversionException("Cannot parse value as zone id", e); | |
42 | } | |
43 | exception.add("value", str); | |
44 | throw exception; | |
45 | } | |
46 | ||
47 | @Override | |
48 | public String toString(final Object obj) { | |
49 | if (obj == null) { | |
50 | return null; | |
51 | } | |
52 | final ZoneId zoneId = (ZoneId)obj; | |
53 | return zoneId.getId(); | |
54 | } | |
55 | } |
+70
-0
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 13. January 2017 by Matej Cimbora | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.time; | |
11 | ||
12 | import java.time.ZonedDateTime; | |
13 | import java.time.format.DateTimeFormatter; | |
14 | import java.time.format.DateTimeFormatterBuilder; | |
15 | import java.time.format.DateTimeParseException; | |
16 | import java.time.temporal.ChronoField; | |
17 | ||
18 | import com.thoughtworks.xstream.converters.ConversionException; | |
19 | import com.thoughtworks.xstream.converters.SingleValueConverter; | |
20 | ||
21 | ||
22 | /** | |
23 | * Converts a {@link ZonedDateTime} to a string. | |
24 | * | |
25 | * @author Matej Cimbora | |
26 | * @since 1.4.10 | |
27 | */ | |
28 | public class ZonedDateTimeConverter implements SingleValueConverter { | |
29 | ||
30 | private static final DateTimeFormatter FORMATTER; | |
31 | ||
32 | static { | |
33 | FORMATTER = new DateTimeFormatterBuilder() | |
34 | .appendPattern("uuuu-MM-dd'T'HH:mm:ss") | |
35 | .appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true) | |
36 | .appendOffsetId() | |
37 | .appendLiteral("[") | |
38 | .appendZoneId() | |
39 | .appendLiteral("]") | |
40 | .toFormatter(); | |
41 | } | |
42 | ||
43 | @Override | |
44 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
45 | return ZonedDateTime.class == type; | |
46 | } | |
47 | ||
48 | @Override | |
49 | public String toString(final Object obj) { | |
50 | if (obj == null) { | |
51 | return null; | |
52 | } | |
53 | ||
54 | final ZonedDateTime zonedDateTime = (ZonedDateTime)obj; | |
55 | return FORMATTER.format(zonedDateTime); | |
56 | } | |
57 | ||
58 | @Override | |
59 | public Object fromString(final String str) { | |
60 | try { | |
61 | return ZonedDateTime.parse(str); | |
62 | } catch (final DateTimeParseException e) { | |
63 | final ConversionException exception = new ConversionException("Cannot parse value as zoned date time", e); | |
64 | exception.add("value", str); | |
65 | throw exception; | |
66 | } | |
67 | } | |
68 | ||
69 | } |
0 | <!-- | |
1 | * Copyright (C) 2017 XStream committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 12. February 2017 by Joerg Schaible | |
9 | --> | |
10 | <body> | |
11 | <p>Extra converters for the java.time package.</p> | |
12 | </body> |
0 | 0 | /* |
1 | * Copyright (C) 2006, 2007, 2008, 2011, 2015 XStream Committers. | |
1 | * Copyright (C) 2006, 2007, 2008, 2011, 2015, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
66 | 66 | } else { |
67 | 67 | Object currentReferenceKey = getCurrentReferenceKey(); |
68 | 68 | parentStack.push(currentReferenceKey); |
69 | result = super.convert(parent, type, converter); | |
70 | if (currentReferenceKey != null) { | |
71 | values.put(currentReferenceKey, result == null ? NULL : result); | |
69 | Object localResult = null; | |
70 | try { | |
71 | localResult = super.convert(parent, type, converter); | |
72 | } finally { | |
73 | result = localResult; | |
74 | if (currentReferenceKey != null) { | |
75 | values.put(currentReferenceKey, result == null ? NULL : result); | |
76 | } | |
77 | parentStack.popSilently(); | |
72 | 78 | } |
73 | parentStack.popSilently(); | |
74 | 79 | } |
75 | 80 | return result; |
76 | 81 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013, 2016 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013, 2016, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
14 | 14 | import com.thoughtworks.xstream.converters.Converter; |
15 | 15 | import com.thoughtworks.xstream.converters.ConverterLookup; |
16 | 16 | import com.thoughtworks.xstream.converters.ConverterRegistry; |
17 | import com.thoughtworks.xstream.core.util.Cloneables; | |
17 | 18 | import com.thoughtworks.xstream.core.util.PrioritizedList; |
18 | 19 | import com.thoughtworks.xstream.mapper.Mapper; |
19 | 20 | |
20 | import java.util.Collections; | |
21 | import java.util.HashMap; | |
21 | 22 | import java.util.Iterator; |
23 | import java.util.LinkedHashMap; | |
22 | 24 | import java.util.Map; |
23 | import java.util.WeakHashMap; | |
25 | ||
24 | 26 | |
25 | 27 | /** |
26 | 28 | * The default implementation of converters lookup. |
33 | 35 | |
34 | 36 | private final PrioritizedList converters = new PrioritizedList(); |
35 | 37 | private transient Map typeToConverterMap; |
38 | private Map serializationMap = null; | |
36 | 39 | |
37 | 40 | public DefaultConverterLookup() { |
38 | readResolve(); | |
41 | this(new HashMap()); | |
42 | } | |
43 | ||
44 | /** | |
45 | * Constructs a DefaultConverterLookup with a provided map. | |
46 | * | |
47 | * @param map the map to use | |
48 | * @throws NullPointerException if map is null | |
49 | * @since 1.4.11 | |
50 | */ | |
51 | public DefaultConverterLookup(Map map) { | |
52 | typeToConverterMap = map; | |
53 | typeToConverterMap.clear(); | |
39 | 54 | } |
40 | 55 | |
41 | 56 | /** |
42 | 57 | * @deprecated As of 1.3, use {@link #DefaultConverterLookup()} |
43 | 58 | */ |
44 | 59 | public DefaultConverterLookup(Mapper mapper) { |
60 | this(); | |
45 | 61 | } |
46 | 62 | |
47 | 63 | public Converter lookupConverterForType(Class type) { |
48 | Converter cachedConverter = (Converter) typeToConverterMap.get(type); | |
64 | Converter cachedConverter = type != null ? (Converter)typeToConverterMap.get(type.getName()) : null; | |
49 | 65 | if (cachedConverter != null) { |
50 | 66 | return cachedConverter; |
51 | 67 | } |
68 | ||
69 | final Map errors = new LinkedHashMap(); | |
52 | 70 | Iterator iterator = converters.iterator(); |
53 | 71 | while (iterator.hasNext()) { |
54 | Converter converter = (Converter) iterator.next(); | |
55 | if (converter.canConvert(type)) { | |
56 | typeToConverterMap.put(type, converter); | |
57 | return converter; | |
72 | Converter converter = (Converter)iterator.next(); | |
73 | try { | |
74 | if (converter.canConvert(type)) { | |
75 | if (type != null) { | |
76 | typeToConverterMap.put(type.getName(), converter); | |
77 | } | |
78 | return converter; | |
79 | } | |
80 | } catch (final RuntimeException e) { | |
81 | errors.put(converter.getClass().getName(), e.getMessage()); | |
82 | } catch (final LinkageError e) { | |
83 | errors.put(converter.getClass().getName(), e.getMessage()); | |
58 | 84 | } |
59 | 85 | } |
60 | ConversionException exception = new ConversionException("No converter specified"); | |
86 | ||
87 | final ConversionException exception = new ConversionException(errors.isEmpty() | |
88 | ? "No converter specified" | |
89 | : "No converter available"); | |
61 | 90 | exception.add("type", type.getName()); |
91 | iterator = errors.entrySet().iterator(); | |
92 | while (iterator.hasNext()) { | |
93 | final Map.Entry entry = (Map.Entry)iterator.next(); | |
94 | exception.add("converter", entry.getKey().toString()); | |
95 | exception.add("message", entry.getValue().toString()); | |
96 | } | |
62 | 97 | throw exception; |
63 | 98 | } |
64 | ||
99 | ||
65 | 100 | public void registerConverter(Converter converter, int priority) { |
101 | typeToConverterMap.clear(); | |
66 | 102 | converters.add(converter, priority); |
67 | for (Iterator iter = typeToConverterMap.keySet().iterator(); iter.hasNext();) { | |
68 | Class type = (Class) iter.next(); | |
69 | if (converter.canConvert(type)) { | |
70 | iter.remove(); | |
71 | } | |
72 | } | |
73 | 103 | } |
74 | ||
104 | ||
75 | 105 | public void flushCache() { |
76 | 106 | typeToConverterMap.clear(); |
77 | 107 | Iterator iterator = converters.iterator(); |
78 | 108 | while (iterator.hasNext()) { |
79 | Converter converter = (Converter) iterator.next(); | |
109 | Converter converter = (Converter)iterator.next(); | |
80 | 110 | if (converter instanceof Caching) { |
81 | 111 | ((Caching)converter).flushCache(); |
82 | 112 | } |
83 | 113 | } |
84 | 114 | } |
85 | 115 | |
116 | private Object writeReplace() { | |
117 | serializationMap = (Map)Cloneables.cloneIfPossible(typeToConverterMap); | |
118 | serializationMap.clear(); | |
119 | return this; | |
120 | } | |
121 | ||
86 | 122 | private Object readResolve() { |
87 | typeToConverterMap = Collections.synchronizedMap(new WeakHashMap()); | |
123 | typeToConverterMap = serializationMap == null ? new HashMap() : serializationMap; | |
124 | serializationMap = null; | |
88 | 125 | return this; |
89 | 126 | } |
90 | 127 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2012, 2013, 2014, 2015 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
6 | 6 | * style license a copy of which has been included with this distribution in |
7 | 7 | * the LICENSE.txt file. |
8 | * | |
8 | * | |
9 | 9 | * Created on 09. May 2004 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.core; |
12 | ||
13 | import com.thoughtworks.xstream.converters.reflection.FieldDictionary; | |
14 | import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; | |
15 | import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; | |
16 | import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; | |
17 | import com.thoughtworks.xstream.core.util.CustomObjectOutputStream; | |
18 | import com.thoughtworks.xstream.core.util.DependencyInjectionFactory; | |
19 | import com.thoughtworks.xstream.core.util.PresortedMap; | |
20 | import com.thoughtworks.xstream.core.util.PresortedSet; | |
21 | 12 | |
22 | 13 | import java.io.IOException; |
23 | 14 | import java.lang.reflect.Field; |
31 | 22 | import java.util.TreeMap; |
32 | 23 | import java.util.TreeSet; |
33 | 24 | |
25 | import com.thoughtworks.xstream.converters.reflection.FieldDictionary; | |
26 | import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; | |
27 | import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; | |
28 | import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; | |
29 | import com.thoughtworks.xstream.core.util.Base64Encoder; | |
30 | import com.thoughtworks.xstream.core.util.CustomObjectOutputStream; | |
31 | import com.thoughtworks.xstream.core.util.DependencyInjectionFactory; | |
32 | import com.thoughtworks.xstream.core.util.PresortedMap; | |
33 | import com.thoughtworks.xstream.core.util.PresortedSet; | |
34 | ||
35 | ||
34 | 36 | public class JVM implements Caching { |
35 | 37 | |
36 | 38 | private ReflectionProvider reflectionProvider; |
51 | 53 | private static final float DEFAULT_JAVA_VERSION = 1.4f; |
52 | 54 | private static final boolean reverseFieldOrder = false; |
53 | 55 | private static final Class reflectionProviderType; |
56 | private static final StringCodec base64Codec; | |
54 | 57 | |
55 | 58 | static class Test { |
56 | 59 | private Object o; |
109 | 112 | cls = null; |
110 | 113 | } |
111 | 114 | if (cls == null) { |
112 | cls = loadClassForName("com.thoughtworks.xstream.converters.reflection.SunLimitedUnsafeReflectionProvider"); | |
115 | cls = loadClassForName( | |
116 | "com.thoughtworks.xstream.converters.reflection.SunLimitedUnsafeReflectionProvider"); | |
113 | 117 | } |
114 | 118 | type = cls; |
115 | 119 | } catch (ObjectAccessException e) { |
170 | 174 | isAWTAvailable = loadClassForName("java.awt.Color", false) != null; |
171 | 175 | isSwingAvailable = loadClassForName("javax.swing.LookAndFeel", false) != null; |
172 | 176 | isSQLAvailable = loadClassForName("java.sql.Date") != null; |
177 | ||
178 | StringCodec base64 = null; | |
179 | Class base64Class = loadClassForName( | |
180 | "com.thoughtworks.xstream.core.util.Base64JavaUtilCodec"); | |
181 | if (base64Class == null) { | |
182 | base64Class = loadClassForName("com.thoughtworks.xstream.core.util.Base64JAXBCodec"); | |
183 | } | |
184 | if (base64Class != null) { | |
185 | try { | |
186 | base64 = (StringCodec)base64Class.newInstance(); | |
187 | } catch (final Exception e) { | |
188 | } catch (final Error e) { | |
189 | } | |
190 | } | |
191 | if (base64 == null) { | |
192 | base64 = new Base64Encoder(); | |
193 | } | |
194 | base64Codec = base64; | |
173 | 195 | } |
174 | 196 | |
175 | 197 | /** |
179 | 201 | } |
180 | 202 | |
181 | 203 | /** |
182 | * Parses the java version system property to determine the major java version, | |
183 | * i.e. 1.x | |
204 | * Parses the java version system property to determine the major java version, i.e. 1.x | |
184 | 205 | * |
185 | 206 | * @return A float of the form 1.x |
186 | 207 | */ |
197 | 218 | * @deprecated As of 1.4.4, minimal JDK version is 1.4 already |
198 | 219 | */ |
199 | 220 | public static boolean is14() { |
200 | return majorJavaVersion >= 1.4f; | |
201 | } | |
202 | ||
203 | /** | |
204 | * @deprecated As of 1.4.4, minimal JDK version will be 1.6 for next major release | |
221 | return isVersion(4); | |
222 | } | |
223 | ||
224 | /** | |
225 | * @deprecated As of 1.4.4, minimal JDK version will be 1.7 for next major release | |
205 | 226 | */ |
206 | 227 | public static boolean is15() { |
207 | return majorJavaVersion >= 1.5f; | |
208 | } | |
209 | ||
210 | /** | |
211 | * @deprecated As of 1.4.4, minimal JDK version will be 1.6 for next major release | |
228 | return isVersion(5); | |
229 | } | |
230 | ||
231 | /** | |
232 | * @deprecated As of 1.4.4, minimal JDK version will be 1.7 for next major release | |
212 | 233 | */ |
213 | 234 | public static boolean is16() { |
214 | return majorJavaVersion >= 1.6f; | |
235 | return isVersion(6); | |
215 | 236 | } |
216 | 237 | |
217 | 238 | /** |
218 | 239 | * @since 1.4 |
240 | * @deprecated As of 1.4.10, minimal JDK version will be 1.7 for next major release | |
219 | 241 | */ |
220 | 242 | public static boolean is17() { |
221 | return majorJavaVersion >= 1.7f; | |
243 | return isVersion(7); | |
222 | 244 | } |
223 | 245 | |
224 | 246 | /** |
225 | 247 | * @since 1.4 |
248 | * @deprecated As of 1.4.11 use {@link #isVersion(int)}. | |
226 | 249 | */ |
227 | 250 | public static boolean is18() { |
228 | return majorJavaVersion >= 1.8f; | |
251 | return isVersion(8); | |
229 | 252 | } |
230 | 253 | |
231 | 254 | /** |
232 | 255 | * @since 1.4.8 |
256 | * @deprecated As of 1.4.10 use {@link #isVersion(int)}. | |
233 | 257 | */ |
234 | 258 | public static boolean is19() { |
235 | 259 | return majorJavaVersion >= 1.9f; |
236 | 260 | } |
237 | 261 | |
262 | /** | |
263 | * @since 1.4.10 | |
264 | * @deprecated As of 1.4.11 use {@link #isVersion(int)} | |
265 | */ | |
266 | public static boolean is9() { | |
267 | return isVersion(9); | |
268 | } | |
269 | ||
270 | /** | |
271 | * Checks current runtime against provided major Java version. | |
272 | * | |
273 | * @param version the requested major Java version | |
274 | * @return true if current runtime is at least the provided major version | |
275 | * @since 1.4.11 | |
276 | */ | |
277 | public static boolean isVersion(final int version) { | |
278 | if (version < 1) { | |
279 | throw new IllegalArgumentException("Java version range starts with at least 1."); | |
280 | } | |
281 | final float v = majorJavaVersion < 9 ? 1f + version * 0.1f : version; | |
282 | return majorJavaVersion >= v; | |
283 | } | |
284 | ||
238 | 285 | private static boolean isIBM() { |
239 | 286 | return vendor.indexOf("IBM") != -1; |
240 | 287 | } |
248 | 295 | |
249 | 296 | /** |
250 | 297 | * Load a XStream class for the given name. |
251 | * | |
252 | * <p>This method is not meant to use loading arbitrary classes. It is used by XStream bootstrap | |
253 | * until it is able to use the user provided or the default {@link ClassLoader}.</p> | |
254 | * | |
298 | * <p> | |
299 | * This method is not meant to use loading arbitrary classes. It is used by XStream bootstrap until it is able to | |
300 | * use the user provided or the default {@link ClassLoader}. | |
301 | * </p> | |
302 | * | |
255 | 303 | * @since 1.4.5 |
256 | 304 | */ |
257 | 305 | public static Class loadClassForName(String name) { |
267 | 315 | |
268 | 316 | /** |
269 | 317 | * Load a XStream class for the given name. |
270 | * | |
271 | * <p>This method is not meant to use loading arbitrary classes. It is used by XStream bootstrap | |
272 | * until it is able to use the user provided or the default {@link ClassLoader}.</p> | |
273 | * | |
318 | * <p> | |
319 | * This method is not meant to use loading arbitrary classes. It is used by XStream bootstrap until it is able to | |
320 | * use the user provided or the default {@link ClassLoader}. | |
321 | * </p> | |
322 | * | |
274 | 323 | * @since 1.4.5 |
275 | 324 | */ |
276 | 325 | public static Class loadClassForName(String name, boolean initialize) { |
294 | 343 | |
295 | 344 | /** |
296 | 345 | * Create the best matching ReflectionProvider. |
297 | * | |
346 | * | |
298 | 347 | * @return a new instance |
299 | 348 | * @since 1.4.5 |
300 | 349 | */ |
322 | 371 | * implementations configured in <em>lib/stax.properties</em> or registered with the Service |
323 | 372 | * API. |
324 | 373 | * </p> |
325 | * | |
374 | * | |
326 | 375 | * @return the XMLInputFactory implementation or null |
327 | 376 | * @throws ClassNotFoundException if the standard class cannot be found |
328 | 377 | * @since 1.4.5 |
329 | 378 | */ |
330 | 379 | public static Class getStaxInputFactory() throws ClassNotFoundException { |
331 | if (is16()) { | |
380 | if (isVersion(6)) { | |
332 | 381 | if (isIBM()) { |
333 | 382 | return Class.forName("com.ibm.xml.xlxp.api.stax.XMLInputFactoryImpl"); |
334 | 383 | } else { |
347 | 396 | * implementations configured in <em>lib/stax.properties</em> or registered with the Service |
348 | 397 | * API. |
349 | 398 | * </p> |
350 | * | |
399 | * | |
351 | 400 | * @return the XMLOutputFactory implementation or null |
352 | 401 | * @throws ClassNotFoundException if the standard class cannot be found |
353 | 402 | * @since 1.4.5 |
354 | 403 | */ |
355 | 404 | public static Class getStaxOutputFactory() throws ClassNotFoundException { |
356 | if (is16()) { | |
405 | if (isVersion(6)) { | |
357 | 406 | if (isIBM()) { |
358 | 407 | return Class.forName("com.ibm.xml.xlxp.api.stax.XMLOutputFactoryImpl"); |
359 | 408 | } else { |
364 | 413 | } |
365 | 414 | |
366 | 415 | /** |
416 | * Get an available Base64 implementation. Prefers java.util.Base64 over DataTypeConverter from JAXB over XStream's | |
417 | * own implementation. | |
418 | * | |
419 | * @return a Base64 codec implementation | |
420 | * @since 1.4.11 | |
421 | */ | |
422 | public static StringCodec getBase64Codec() { | |
423 | return base64Codec; | |
424 | } | |
425 | ||
426 | /** | |
367 | 427 | * @deprecated As of 1.4.5 use {@link #newReflectionProvider()} |
368 | 428 | */ |
369 | 429 | public synchronized ReflectionProvider bestReflectionProvider() { |
374 | 434 | } |
375 | 435 | |
376 | 436 | private static boolean canUseSunUnsafeReflectionProvider() { |
377 | return canAllocateWithUnsafe && is14(); | |
437 | return canAllocateWithUnsafe; | |
378 | 438 | } |
379 | 439 | |
380 | 440 | private static boolean canUseSunLimitedUnsafeReflectionProvider() { |
390 | 450 | |
391 | 451 | /** |
392 | 452 | * Checks if AWT is available. |
453 | * | |
393 | 454 | * @since 1.4.5 |
394 | 455 | */ |
395 | 456 | public static boolean isAWTAvailable() { |
397 | 458 | } |
398 | 459 | |
399 | 460 | /** |
400 | * Checks if the jvm supports awt. | |
461 | * Checks if the JVM supports AWT. | |
462 | * | |
401 | 463 | * @deprecated As of 1.4.5 use {@link #isAWTAvailable()} |
402 | 464 | */ |
403 | 465 | public boolean supportsAWT() { |
406 | 468 | |
407 | 469 | /** |
408 | 470 | * Checks if Swing is available. |
471 | * | |
409 | 472 | * @since 1.4.5 |
410 | 473 | */ |
411 | 474 | public static boolean isSwingAvailable() { |
413 | 476 | } |
414 | 477 | |
415 | 478 | /** |
416 | * Checks if the jvm supports swing. | |
479 | * Checks if the JVM supports Swing. | |
480 | * | |
417 | 481 | * @deprecated As of 1.4.5 use {@link #isSwingAvailable()} |
418 | 482 | */ |
419 | 483 | public boolean supportsSwing() { |
422 | 486 | |
423 | 487 | /** |
424 | 488 | * Checks if SQL is available. |
489 | * | |
425 | 490 | * @since 1.4.5 |
426 | 491 | */ |
427 | 492 | public static boolean isSQLAvailable() { |
429 | 494 | } |
430 | 495 | |
431 | 496 | /** |
432 | * Checks if the jvm supports sql. | |
497 | * Checks if the JVM supports SQL. | |
498 | * | |
433 | 499 | * @deprecated As of 1.4.5 use {@link #isSQLAvailable()} |
434 | 500 | */ |
435 | 501 | public boolean supportsSQL() { |
438 | 504 | |
439 | 505 | /** |
440 | 506 | * Checks if TreeSet.addAll is optimized for SortedSet argument. |
441 | * | |
507 | * | |
442 | 508 | * @since 1.4 |
443 | 509 | */ |
444 | 510 | public static boolean hasOptimizedTreeSetAddAll() { |
447 | 513 | |
448 | 514 | /** |
449 | 515 | * Checks if TreeMap.putAll is optimized for SortedMap argument. |
450 | * | |
516 | * | |
451 | 517 | * @since 1.4 |
452 | 518 | */ |
453 | 519 | public static boolean hasOptimizedTreeMapPutAll() { |
529 | 595 | System.out.println("Java Beans EventHandler present: " + (loadClassForName("java.beans.EventHandler") != null)); |
530 | 596 | System.out.println("Standard StAX XMLInputFactory: " + staxInputFactory); |
531 | 597 | System.out.println("Standard StAX XMLOutputFactory: " + staxOutputFactory); |
598 | System.out.println("Standard Base64 Codec: " + getBase64Codec().getClass().toString()); | |
532 | 599 | System.out.println("Optimized TreeSet.addAll: " + hasOptimizedTreeSetAddAll()); |
533 | 600 | System.out.println("Optimized TreeMap.putAll: " + hasOptimizedTreeMapPutAll()); |
534 | 601 | System.out.println("Can parse UTC date format: " + canParseUTCDateFormat()); |
535 | 602 | System.out.println("Can create derive ObjectOutputStream: " + canCreateDerivedObjectOutputStream()); |
536 | 603 | System.out.println("Reverse field order detected for JDK: " + reverseJDK); |
537 | System.out.println("Reverse field order detected (only if JVM class itself has been compiled): " + reverseLocal); | |
604 | System.out.println("Reverse field order detected (only if JVM class itself has been compiled): " | |
605 | + reverseLocal); | |
538 | 606 | } |
539 | 607 | } |
0 | /* | |
1 | * Copyright (C) 2017, 2018 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 12. August 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.core; | |
11 | ||
12 | /** | |
13 | * Interface for an encoder and decoder of data to string values and back. | |
14 | * | |
15 | * @author Jörg Schaible | |
16 | * @since 1.4.11 | |
17 | */ | |
18 | public interface StringCodec { | |
19 | ||
20 | /** | |
21 | * Decode the provided encoded string. | |
22 | * | |
23 | * @param encoded the encoded string | |
24 | * @return the decoded data | |
25 | * @since 1.4.11 | |
26 | */ | |
27 | byte[] decode(String encoded); | |
28 | ||
29 | /** | |
30 | * Encode the provided data. | |
31 | * | |
32 | * @param data the data to encode | |
33 | * @return the data encoded as string | |
34 | * @since 1.4.11 | |
35 | */ | |
36 | String encode(byte[] data); | |
37 | }⏎ |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
66 | 66 | } |
67 | 67 | |
68 | 68 | protected Object convert(Object parent, Class type, Converter converter) { |
69 | types.push(type); | |
69 | 70 | try { |
70 | types.push(type); | |
71 | Object result = converter.unmarshal(reader, this); | |
72 | types.popSilently(); | |
73 | return result; | |
74 | } catch (ConversionException conversionException) { | |
71 | return converter.unmarshal(reader, this); | |
72 | } catch (final ConversionException conversionException) { | |
75 | 73 | addInformationTo(conversionException, type, converter, parent); |
76 | 74 | throw conversionException; |
77 | 75 | } catch (RuntimeException e) { |
78 | 76 | ConversionException conversionException = new ConversionException(e); |
79 | 77 | addInformationTo(conversionException, type, converter, parent); |
80 | 78 | throw conversionException; |
79 | } finally { | |
80 | types.popSilently(); | |
81 | 81 | } |
82 | 82 | } |
83 | 83 |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2017, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
6 | 6 | * style license a copy of which has been included with this distribution in |
7 | 7 | * the LICENSE.txt file. |
8 | * | |
8 | * | |
9 | 9 | * Created on 06. August 2004 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.core.util; |
15 | 15 | import java.io.Reader; |
16 | 16 | import java.io.StringReader; |
17 | 17 | |
18 | import com.thoughtworks.xstream.core.StringCodec; | |
19 | ||
20 | ||
18 | 21 | /** |
19 | 22 | * Encodes binary data to plain text as Base64. |
20 | * | |
21 | * <p>Despite there being a gazillion other Base64 implementations out there, this has been written as part of XStream as | |
22 | * it forms a core part but is too trivial to warrant an extra dependency.</p> | |
23 | * | |
24 | * <p>This meets the standard as described in RFC 1521, section 5.2 <http://www.freesoft.org/CIE/RFC/1521/7.htm>, allowing | |
25 | * other Base64 tools to manipulate the data.</p> | |
23 | * <p> | |
24 | * Despite there being a gazillion other Base64 implementations out there, this has been written as part of XStream as | |
25 | * it forms a core part but is too trivial to warrant an extra dependency. Recent Java Runtimes (since Java 6) provide | |
26 | * an own Base64 codec though. | |
27 | * </p> | |
28 | * <p> | |
29 | * By default it will not insert line breaks to support Base64 values also as attribute values. However, the standard as | |
30 | * described in <a href="http://www.freesoft.org/CIE/RFC/1521/7.htm">RFC 1521, section 5.2</a> requires line breaks, | |
31 | * allowing other Base64 tools to manipulate the data. You can configure the Base64Encoder to be RFC compliant. | |
32 | * </p> | |
26 | 33 | * |
27 | 34 | * @author Joe Walnes |
28 | 35 | */ |
29 | public class Base64Encoder { | |
36 | public class Base64Encoder implements StringCodec { | |
30 | 37 | |
31 | 38 | // Here's how encoding works: |
32 | 39 | // |
34 | 41 | // |
35 | 42 | // 2) The combined 24 bits (3 * 8) are split into 4 groups of 6 bits. |
36 | 43 | // |
37 | // input |------||------||------| (3 values each with 8 bits) | |
38 | // 101010101010101010101010 | |
39 | // output |----||----||----||----| (4 values each with 6 bits) | |
44 | // Input: | |
45 | // |------||------||------| (3 values each with 8 bits) | |
46 | // 101010101010101010101010 | |
47 | // Output: | |
48 | // |----||----||----||----| (4 values each with 6 bits) | |
40 | 49 | // |
41 | 50 | // 3) Each of these 4 groups of 6 bits are converted back to a number, which will fall in the range of 0 - 63. |
42 | 51 | // |
43 | 52 | // 4) Each of these 4 numbers are converted to an alphanumeric char in a specified mapping table, to create |
44 | // a 4 character string. | |
53 | // a 4 character string. | |
45 | 54 | // |
46 | 55 | // 5) This is repeated for all groups of three bytes. |
47 | 56 | // |
48 | 57 | // 6) Special padding is done at the end of the stream using the '=' char. |
49 | 58 | |
50 | private static final char[] SIXTY_FOUR_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); | |
59 | private static final char[] SIXTY_FOUR_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" | |
60 | .toCharArray(); | |
51 | 61 | private static final int[] REVERSE_MAPPING = new int[123]; |
62 | private final boolean lineBreaks; | |
52 | 63 | |
53 | 64 | static { |
54 | for (int i = 0; i < SIXTY_FOUR_CHARS.length; i++) REVERSE_MAPPING[SIXTY_FOUR_CHARS[i]] = i + 1; | |
65 | for (int i = 0; i < SIXTY_FOUR_CHARS.length; i++) { | |
66 | REVERSE_MAPPING[SIXTY_FOUR_CHARS[i]] = i + 1; | |
67 | } | |
55 | 68 | } |
56 | 69 | |
57 | public String encode(byte[] input) { | |
58 | StringBuffer result = new StringBuffer(); | |
70 | /** | |
71 | * Constructs a Base64Encoder. | |
72 | * <p> | |
73 | * The encoder will not insert any line breaks. | |
74 | * </p> | |
75 | * | |
76 | * @since 1.4.11 | |
77 | */ | |
78 | public Base64Encoder() { | |
79 | this(false); | |
80 | } | |
81 | ||
82 | /** | |
83 | * Constructs a Base64Encoder. | |
84 | * | |
85 | * @param lineBreaks flag to insert line breaks | |
86 | * @since 1.4.11 | |
87 | */ | |
88 | public Base64Encoder(final boolean lineBreaks) { | |
89 | this.lineBreaks = lineBreaks; | |
90 | } | |
91 | ||
92 | public String encode(final byte[] input) { | |
93 | final int stringSize = computeResultingStringSize(input); | |
94 | final StringBuffer result = new StringBuffer(stringSize); | |
59 | 95 | int outputCharCount = 0; |
60 | 96 | for (int i = 0; i < input.length; i += 3) { |
61 | int remaining = Math.min(3, input.length - i); | |
62 | int oneBigNumber = (input[i] & 0xff) << 16 | (remaining <= 1 ? 0 : input[i + 1] & 0xff) << 8 | (remaining <= 2 ? 0 : input[i + 2] & 0xff); | |
63 | for (int j = 0; j < 4; j++) result.append(remaining + 1 > j ? SIXTY_FOUR_CHARS[0x3f & oneBigNumber >> 6 * (3 - j)] : '='); | |
64 | if ((outputCharCount += 4) % 76 == 0) result.append('\n'); | |
97 | final int remaining = Math.min(3, input.length - i); | |
98 | final int oneBigNumber = (input[i] & 0xff) << 16 | |
99 | | (remaining <= 1 ? 0 : input[i + 1] & 0xff) << 8 | |
100 | | (remaining <= 2 ? 0 : input[i + 2] & 0xff); | |
101 | for (int j = 0; j < 4; j++) { | |
102 | result.append(remaining + 1 > j ? SIXTY_FOUR_CHARS[0x3f & oneBigNumber >> 6 * (3 - j)] : '='); | |
103 | } | |
104 | if (lineBreaks && (outputCharCount += 4) % 76 == 0 && i + 3 < input.length) { | |
105 | result.append('\n'); | |
106 | } | |
65 | 107 | } |
66 | return result.toString(); | |
108 | final String s = result.toString(); | |
109 | return s; | |
67 | 110 | } |
68 | 111 | |
69 | public byte[] decode(String input) { | |
112 | // package private for testing purpose | |
113 | int computeResultingStringSize(final byte[] input) { | |
114 | int stringSize = input.length / 3 + (input.length % 3 == 0 ? 0 : 1); | |
115 | stringSize *= 4; | |
116 | if (lineBreaks) { | |
117 | stringSize += stringSize / 76; | |
118 | } | |
119 | return stringSize; | |
120 | } | |
121 | ||
122 | public byte[] decode(final String input) { | |
70 | 123 | try { |
71 | ByteArrayOutputStream out = new ByteArrayOutputStream(); | |
72 | StringReader in = new StringReader(input); | |
124 | final ByteArrayOutputStream out = new ByteArrayOutputStream(); | |
125 | final StringReader in = new StringReader(input); | |
73 | 126 | for (int i = 0; i < input.length(); i += 4) { |
74 | int a[] = {mapCharToInt(in), mapCharToInt(in), mapCharToInt(in), mapCharToInt(in)}; | |
75 | int oneBigNumber = (a[0] & 0x3f) << 18 | (a[1] & 0x3f) << 12 | (a[2] & 0x3f) << 6 | (a[3] & 0x3f); | |
76 | for (int j = 0; j < 3; j++) if (a[j + 1] >= 0) out.write(0xff & oneBigNumber >> 8 * (2 - j)); | |
127 | final int a[] = {mapCharToInt(in), mapCharToInt(in), mapCharToInt(in), mapCharToInt(in)}; | |
128 | final int oneBigNumber = (a[0] & 0x3f) << 18 | (a[1] & 0x3f) << 12 | (a[2] & 0x3f) << 6 | a[3] & 0x3f; | |
129 | for (int j = 0; j < 3; j++) { | |
130 | if (a[j + 1] >= 0) { | |
131 | out.write(0xff & oneBigNumber >> 8 * (2 - j)); | |
132 | } | |
133 | } | |
77 | 134 | } |
78 | 135 | return out.toByteArray(); |
79 | } catch (IOException e) { | |
136 | } catch (final IOException e) { | |
80 | 137 | throw new Error(e + ": " + e.getMessage()); |
81 | 138 | } |
82 | 139 | } |
83 | 140 | |
84 | private int mapCharToInt(Reader input) throws IOException { | |
141 | private int mapCharToInt(final Reader input) throws IOException { | |
85 | 142 | int c; |
86 | 143 | while ((c = input.read()) != -1) { |
87 | int result = REVERSE_MAPPING[c]; | |
88 | if (result != 0) return result -1; | |
89 | if (c == '=') return -1; | |
144 | final int result = REVERSE_MAPPING[c]; | |
145 | if (result != 0) { | |
146 | return result - 1; | |
147 | } | |
148 | if (c == '=') { | |
149 | return -1; | |
150 | } | |
90 | 151 | } |
91 | 152 | return -1; |
92 | 153 | } |
0 | /* | |
1 | * Copyright (C) 2017, 2018 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 12. August 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.core.util; | |
11 | ||
12 | import javax.xml.bind.DatatypeConverter; | |
13 | ||
14 | import com.thoughtworks.xstream.core.StringCodec; | |
15 | ||
16 | ||
17 | /** | |
18 | * Base64 codec implementation based on JAXB. | |
19 | * | |
20 | * @author Jörg Schaible | |
21 | * @since 1.4.11 | |
22 | */ | |
23 | public class Base64JAXBCodec implements StringCodec { | |
24 | ||
25 | @Override | |
26 | public byte[] decode(final String base64) { | |
27 | return DatatypeConverter.parseBase64Binary(base64); | |
28 | } | |
29 | ||
30 | @Override | |
31 | public String encode(final byte[] data) { | |
32 | return DatatypeConverter.printBase64Binary(data); | |
33 | } | |
34 | } |
0 | /* | |
1 | * Copyright (C) 2017, 2018 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 12. August 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.core.util; | |
11 | ||
12 | import java.util.Base64; | |
13 | ||
14 | import com.thoughtworks.xstream.core.StringCodec; | |
15 | ||
16 | ||
17 | /** | |
18 | * Base64 codec implementation based on java.util.Base64. | |
19 | * | |
20 | * @author Jörg Schaible | |
21 | * @since 1.4.11 | |
22 | */ | |
23 | public class Base64JavaUtilCodec implements StringCodec { | |
24 | final private Base64.Decoder decoder; | |
25 | final private Base64.Encoder encoder; | |
26 | ||
27 | /** | |
28 | * Constructs a Base64JavaUtilCodec. | |
29 | * <p> | |
30 | * The implementation will use a basic encoder and a MIME decoder by default. | |
31 | * </p> | |
32 | * | |
33 | * @since 1.4.11 | |
34 | */ | |
35 | public Base64JavaUtilCodec() { | |
36 | this(Base64.getEncoder(), Base64.getMimeDecoder()); | |
37 | } | |
38 | ||
39 | /** | |
40 | * Constructs a Base64JavaUtilCodec with provided encoder and decoder. | |
41 | * | |
42 | * @param encoder the encoder instance | |
43 | * @param decoder the decoder instance | |
44 | * @since 1.4.11 | |
45 | */ | |
46 | public Base64JavaUtilCodec(final Base64.Encoder encoder, final Base64.Decoder decoder) { | |
47 | this.encoder = encoder; | |
48 | this.decoder = decoder; | |
49 | } | |
50 | ||
51 | @Override | |
52 | public byte[] decode(final String base64) { | |
53 | return decoder.decode(base64); | |
54 | } | |
55 | ||
56 | @Override | |
57 | public String encode(final byte[] data) { | |
58 | return encoder.encodeToString(data); | |
59 | } | |
60 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2011, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2011, 2013, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
52 | 52 | */ |
53 | 53 | public class CompositeClassLoader extends ClassLoader { |
54 | 54 | static { |
55 | if (JVM.is17()) { | |
55 | if (JVM.isVersion(7)) { | |
56 | 56 | // see http://www.cs.duke.edu/csed/java/jdk1.7/technotes/guides/lang/cl-mt.html |
57 | 57 | try { |
58 | 58 | Method m = ClassLoader.class.getDeclaredMethod("registerAsParallelCapable", (Class[])null); |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2010, 2011, 2013, 2016 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2010, 2011, 2013, 2016, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
135 | 135 | } |
136 | 136 | |
137 | 137 | public int readUnsignedByte() throws IOException { |
138 | int b = ((Byte)peekCallback().readFromStream()).byteValue(); | |
139 | if (b < 0) { | |
140 | b += Byte.MAX_VALUE; | |
141 | } | |
142 | return b; | |
138 | return ((Byte)peekCallback().readFromStream()).intValue() & 0xff; | |
143 | 139 | } |
144 | 140 | |
145 | 141 | public int readInt() throws IOException { |
167 | 163 | } |
168 | 164 | |
169 | 165 | public int readUnsignedShort() throws IOException { |
170 | int b = ((Short)peekCallback().readFromStream()).shortValue(); | |
171 | if (b < 0) { | |
172 | b += Short.MAX_VALUE; | |
173 | } | |
174 | return b; | |
166 | return ((Short)peekCallback().readFromStream()).intValue() & 0xffff; | |
175 | 167 | } |
176 | 168 | |
177 | 169 | public String readUTF() throws IOException { |
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 05. May 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.core.util; | |
11 | ||
12 | import java.time.Instant; | |
13 | import java.time.LocalDate; | |
14 | import java.time.LocalDateTime; | |
15 | import java.time.LocalTime; | |
16 | import java.time.MonthDay; | |
17 | import java.time.OffsetDateTime; | |
18 | import java.time.OffsetTime; | |
19 | import java.time.Year; | |
20 | import java.time.YearMonth; | |
21 | import java.time.ZoneId; | |
22 | import java.time.ZoneOffset; | |
23 | import java.time.format.DateTimeFormatter; | |
24 | import java.time.format.DateTimeFormatterBuilder; | |
25 | import java.time.format.DateTimeParseException; | |
26 | import java.time.temporal.ChronoField; | |
27 | import java.time.temporal.IsoFields; | |
28 | import java.time.temporal.TemporalAccessor; | |
29 | import java.time.temporal.WeekFields; | |
30 | import java.util.Calendar; | |
31 | import java.util.GregorianCalendar; | |
32 | import java.util.Locale; | |
33 | ||
34 | import com.thoughtworks.xstream.converters.ConversionException; | |
35 | import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; | |
36 | ||
37 | ||
38 | /** | |
39 | * A converter for {@link GregorianCalendar} conforming to the ISO8601 standard based on java.time. | |
40 | * <p> | |
41 | * The converter will always serialize the calendar value in UTC and deserialize it to a value in the current default | |
42 | * time zone. | |
43 | * </p> | |
44 | * | |
45 | * @author Jörg Schaible | |
46 | * @see <a href="http://www.iso.org/iso/home/store/catalogue_ics/catalogue_detail_ics.htm?csnumber=40874">ISO 8601</a> | |
47 | * @since 1.4.10 | |
48 | */ | |
49 | public class ISO8601JavaTimeConverter extends AbstractSingleValueConverter { | |
50 | private static final DateTimeFormatter STD_DATE_TIME = new DateTimeFormatterBuilder() | |
51 | .appendPattern("yyyy-MM-dd'T'HH:mm:ss") | |
52 | .appendFraction(ChronoField.NANO_OF_SECOND, 3, 9, true) | |
53 | .appendOffsetId() | |
54 | .toFormatter(); | |
55 | private static final DateTimeFormatter STD_ORDINAL_DATE_TIME = new DateTimeFormatterBuilder() | |
56 | .appendPattern("yyyy-DDD'T'HH:mm:ss") | |
57 | .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 3, true) | |
58 | .appendOffsetId() | |
59 | .toFormatter(); | |
60 | private static final DateTimeFormatter BASIC_DATE_TIME = new DateTimeFormatterBuilder() | |
61 | .appendPattern("yyyyMMdd'T'HHmmss") | |
62 | .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 3, true) | |
63 | .appendOffsetId() | |
64 | .toFormatter(); | |
65 | private static final DateTimeFormatter BASIC_ORDINAL_DATE_TIME = new DateTimeFormatterBuilder() | |
66 | .appendPattern("yyyyDDD'T'HHmmss") | |
67 | .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 3, true) | |
68 | .appendOffsetId() | |
69 | .toFormatter(); | |
70 | private static final DateTimeFormatter BASIC_TIME = new DateTimeFormatterBuilder() | |
71 | .appendPattern("HHmmss") | |
72 | .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 3, true) | |
73 | .appendOffsetId() | |
74 | .toFormatter(); | |
75 | private static final DateTimeFormatter ISO_TTIME = new DateTimeFormatterBuilder() | |
76 | .appendPattern("'T'HH:mm:ss") | |
77 | .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 3, true) | |
78 | .appendOffsetId() | |
79 | .toFormatter(); | |
80 | private static final DateTimeFormatter BASIC_TTIME = new DateTimeFormatterBuilder() | |
81 | .appendPattern("'T'HHmmss") | |
82 | .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 3, true) | |
83 | .appendOffsetId() | |
84 | .toFormatter(); | |
85 | private static final DateTimeFormatter ISO_WEEK_DATE_TIME = new DateTimeFormatterBuilder() | |
86 | .appendPattern("YYYY-'W'ww-e'T'HH:mm:ss") | |
87 | .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 3, true) | |
88 | .appendOffsetId() | |
89 | .toFormatter(); | |
90 | private static final DateTimeFormatter BASIC_WEEK_DATE_TIME = new DateTimeFormatterBuilder() | |
91 | .appendPattern("YYYY'W'wwe'T'HHmmss") | |
92 | .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 3, true) | |
93 | .appendOffsetId() | |
94 | .toFormatter(); | |
95 | private static final DateTimeFormatter BASIC_ORDINAL_DATE = new DateTimeFormatterBuilder() | |
96 | .appendPattern("yyyyDDD") | |
97 | .toFormatter(); | |
98 | private static final DateTimeFormatter BASIC_WEEK_DATE = new DateTimeFormatterBuilder() | |
99 | .appendPattern("YYYY'W'wwe") | |
100 | .toFormatter(); | |
101 | private static final DateTimeFormatter STD_DATE_HOUR = new DateTimeFormatterBuilder() | |
102 | .appendPattern("yyyy-MM-dd'T'HH") | |
103 | .toFormatter(); | |
104 | private static final DateTimeFormatter STD_HOUR = new DateTimeFormatterBuilder().appendPattern("HH").toFormatter(); | |
105 | private static final DateTimeFormatter STD_YEAR_WEEK = new DateTimeFormatterBuilder() | |
106 | .appendPattern("YYYY-'W'ww") | |
107 | .parseDefaulting(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR, 1) | |
108 | .toFormatter(); | |
109 | ||
110 | @Override | |
111 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
112 | return false; | |
113 | } | |
114 | ||
115 | @Override | |
116 | public Object fromString(final String str) { | |
117 | try { | |
118 | final OffsetDateTime odt = OffsetDateTime.parse(str); | |
119 | return GregorianCalendar.from(odt.atZoneSameInstant(ZoneId.systemDefault())); | |
120 | } catch (final DateTimeParseException e) { | |
121 | // try with next formatter | |
122 | } | |
123 | try { | |
124 | final LocalDateTime ldt = LocalDateTime.parse(str); | |
125 | return GregorianCalendar.from(ldt.atZone(ZoneId.systemDefault())); | |
126 | } catch (final DateTimeParseException e) { | |
127 | // try with next formatter | |
128 | } | |
129 | try { | |
130 | final Instant instant = Instant.parse(str); | |
131 | return GregorianCalendar.from(instant.atZone(ZoneId.systemDefault())); | |
132 | } catch (final DateTimeParseException e) { | |
133 | // try with next formatter | |
134 | } | |
135 | try { | |
136 | final OffsetDateTime odt = BASIC_DATE_TIME.parse(str, OffsetDateTime::from); | |
137 | return GregorianCalendar.from(odt.atZoneSameInstant(ZoneId.systemDefault())); | |
138 | } catch (final DateTimeParseException e) { | |
139 | // try with next formatter | |
140 | } | |
141 | try { | |
142 | final OffsetDateTime odt = STD_ORDINAL_DATE_TIME.parse(str, OffsetDateTime::from); | |
143 | return GregorianCalendar.from(odt.atZoneSameInstant(ZoneId.systemDefault())); | |
144 | } catch (final DateTimeParseException e) { | |
145 | // try with next formatter | |
146 | } | |
147 | try { | |
148 | final OffsetDateTime odt = BASIC_ORDINAL_DATE_TIME.parse(str, OffsetDateTime::from); | |
149 | return GregorianCalendar.from(odt.atZoneSameInstant(ZoneId.systemDefault())); | |
150 | } catch (final DateTimeParseException e) { | |
151 | // try with next formatter | |
152 | } | |
153 | try { | |
154 | final OffsetTime ot = OffsetTime.parse(str); | |
155 | return GregorianCalendar.from(ot.atDate(LocalDate.ofEpochDay(0)).atZoneSameInstant(ZoneId.systemDefault())); | |
156 | } catch (final DateTimeParseException e) { | |
157 | // try with next formatter | |
158 | } | |
159 | try { | |
160 | final OffsetTime ot = BASIC_TIME.parse(str, OffsetTime::from); | |
161 | return GregorianCalendar.from(ot.atDate(LocalDate.ofEpochDay(0)).atZoneSameInstant(ZoneId.systemDefault())); | |
162 | } catch (final DateTimeParseException e) { | |
163 | // try with next formatter | |
164 | } | |
165 | try { | |
166 | final OffsetTime ot = ISO_TTIME.parse(str, OffsetTime::from); | |
167 | return GregorianCalendar.from(ot.atDate(LocalDate.ofEpochDay(0)).atZoneSameInstant(ZoneId.systemDefault())); | |
168 | } catch (final DateTimeParseException e) { | |
169 | // try with next formatter | |
170 | } | |
171 | try { | |
172 | final OffsetTime ot = BASIC_TTIME.parse(str, OffsetTime::from); | |
173 | return GregorianCalendar.from(ot.atDate(LocalDate.ofEpochDay(0)).atZoneSameInstant(ZoneId.systemDefault())); | |
174 | } catch (final DateTimeParseException e) { | |
175 | // try with next formatter | |
176 | } | |
177 | try { | |
178 | final TemporalAccessor ta = ISO_WEEK_DATE_TIME.withLocale(Locale.getDefault()).parse(str); | |
179 | final Year y = Year.from(ta); | |
180 | final MonthDay md = MonthDay.from(ta); | |
181 | final OffsetTime ot = OffsetTime.from(ta); | |
182 | return GregorianCalendar.from(ot.atDate(y.atMonthDay(md)).atZoneSameInstant(ZoneId.systemDefault())); | |
183 | } catch (final DateTimeParseException e) { | |
184 | // try with next formatter | |
185 | } | |
186 | try { | |
187 | final TemporalAccessor ta = BASIC_WEEK_DATE_TIME.withLocale(Locale.getDefault()).parse(str); | |
188 | final Year y = Year.from(ta); | |
189 | final MonthDay md = MonthDay.from(ta); | |
190 | final OffsetTime ot = OffsetTime.from(ta); | |
191 | return GregorianCalendar.from(ot.atDate(y.atMonthDay(md)).atZoneSameInstant(ZoneId.systemDefault())); | |
192 | } catch (final DateTimeParseException e) { | |
193 | // try with next formatter | |
194 | } | |
195 | try { | |
196 | final LocalDate ld = LocalDate.parse(str); | |
197 | return GregorianCalendar.from(ld.atStartOfDay(ZoneId.systemDefault())); | |
198 | } catch (final DateTimeParseException e) { | |
199 | // try with next formatter | |
200 | } | |
201 | try { | |
202 | final LocalDate ld = LocalDate.parse(str, DateTimeFormatter.BASIC_ISO_DATE); | |
203 | return GregorianCalendar.from(ld.atStartOfDay(ZoneId.systemDefault())); | |
204 | } catch (final DateTimeParseException e) { | |
205 | // try with next formatter | |
206 | } | |
207 | try { | |
208 | final LocalDate ld = LocalDate.parse(str, DateTimeFormatter.ISO_ORDINAL_DATE); | |
209 | return GregorianCalendar.from(ld.atStartOfDay(ZoneId.systemDefault())); | |
210 | } catch (final DateTimeParseException e) { | |
211 | // try with next formatter | |
212 | } | |
213 | try { | |
214 | final LocalDate ld = BASIC_ORDINAL_DATE.parse(str, LocalDate::from); | |
215 | return GregorianCalendar.from(ld.atStartOfDay(ZoneId.systemDefault())); | |
216 | } catch (final DateTimeParseException e) { | |
217 | // try with next formatter | |
218 | } | |
219 | try { | |
220 | final LocalDate ld = LocalDate.parse(str, DateTimeFormatter.ISO_WEEK_DATE.withLocale(Locale.getDefault())); | |
221 | return GregorianCalendar.from(ld.atStartOfDay(ZoneId.systemDefault())); | |
222 | } catch (final DateTimeParseException e) { | |
223 | // try with next formatter | |
224 | } | |
225 | try { | |
226 | final TemporalAccessor ta = BASIC_WEEK_DATE.withLocale(Locale.getDefault()).parse(str); | |
227 | final Year y = Year.from(ta); | |
228 | final MonthDay md = MonthDay.from(ta); | |
229 | return GregorianCalendar.from(y.atMonthDay(md).atStartOfDay(ZoneId.systemDefault())); | |
230 | } catch (final DateTimeParseException e) { | |
231 | // try with next formatter | |
232 | } | |
233 | try { | |
234 | final LocalDateTime ldt = STD_DATE_HOUR.parse(str, LocalDateTime::from); | |
235 | return GregorianCalendar.from(ldt.atZone(ZoneId.systemDefault())); | |
236 | } catch (final DateTimeParseException e) { | |
237 | // try with next formatter | |
238 | } | |
239 | try { | |
240 | final LocalTime lt = STD_HOUR.parse(str, LocalTime::from); | |
241 | return GregorianCalendar.from(lt.atDate(LocalDate.ofEpochDay(0)).atZone(ZoneId.systemDefault())); | |
242 | } catch (final DateTimeParseException e) { | |
243 | // try with next formatter | |
244 | } | |
245 | try { | |
246 | final LocalTime lt = LocalTime.parse(str); | |
247 | return GregorianCalendar.from(lt.atDate(LocalDate.ofEpochDay(0)).atZone(ZoneId.systemDefault())); | |
248 | } catch (final DateTimeParseException e) { | |
249 | // try with next formatter | |
250 | } | |
251 | try { | |
252 | final YearMonth ym = YearMonth.parse(str); | |
253 | return GregorianCalendar.from(ym.atDay(1).atStartOfDay(ZoneId.systemDefault())); | |
254 | } catch (final DateTimeParseException e) { | |
255 | // try with next formatter | |
256 | } | |
257 | try { | |
258 | final Year y = Year.parse(str); | |
259 | return GregorianCalendar.from(y.atDay(1).atStartOfDay(ZoneId.systemDefault())); | |
260 | } catch (final DateTimeParseException e) { | |
261 | // try with next formatter | |
262 | } | |
263 | try { | |
264 | final TemporalAccessor ta = STD_YEAR_WEEK.withLocale(Locale.getDefault()).parse(str); | |
265 | final int y = ta.get(WeekFields.ISO.weekBasedYear()); | |
266 | final int w = ta.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR); | |
267 | return GregorianCalendar.from(LocalDateTime | |
268 | .from(ta) | |
269 | .with(WeekFields.ISO.weekOfYear(), y) | |
270 | .with(WeekFields.ISO.weekOfWeekBasedYear(), w) | |
271 | .atZone(ZoneId.systemDefault())); | |
272 | // } catch (final IllegalArgumentException e) { // TODO: DateTimeParseException | |
273 | } catch (final DateTimeParseException e) { | |
274 | // try with next formatter | |
275 | } | |
276 | final ConversionException exception = new ConversionException("Cannot parse date"); | |
277 | exception.add("date", str); | |
278 | throw exception; | |
279 | } | |
280 | ||
281 | @Override | |
282 | public String toString(final Object obj) { | |
283 | final Calendar calendar = (Calendar)obj; | |
284 | final Instant instant = Instant.ofEpochMilli(calendar.getTimeInMillis()); | |
285 | final int offsetInMillis = calendar.getTimeZone().getOffset(calendar.getTimeInMillis()); | |
286 | final OffsetDateTime offsetDateTime = OffsetDateTime.ofInstant(instant, ZoneOffset.ofTotalSeconds(offsetInMillis | |
287 | / 1000)); | |
288 | return STD_DATE_TIME.format(offsetDateTime); | |
289 | } | |
290 | } |
0 | /* | |
1 | * Copyright (C) 2005 Joe Walnes. | |
2 | * Copyright (C) 2006, 2007, 2011, 2013, 2014, 2015, 2016, 2017 XStream Committers. | |
3 | * All rights reserved. | |
4 | * | |
5 | * The software in this package is published under the terms of the BSD | |
6 | * style license a copy of which has been included with this distribution in | |
7 | * the LICENSE.txt file. | |
8 | * | |
9 | * Created on 05. May 2017 by Joerg Schaible, copied from ISO8601GregorianCalendarConverter | |
10 | */ | |
11 | package com.thoughtworks.xstream.core.util; | |
12 | ||
13 | import java.util.Calendar; | |
14 | import java.util.GregorianCalendar; | |
15 | import java.util.TimeZone; | |
16 | ||
17 | import org.joda.time.DateTime; | |
18 | import org.joda.time.DateTimeZone; | |
19 | import org.joda.time.format.DateTimeFormatter; | |
20 | import org.joda.time.format.ISODateTimeFormat; | |
21 | ||
22 | import com.thoughtworks.xstream.converters.ConversionException; | |
23 | import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; | |
24 | ||
25 | ||
26 | /** | |
27 | * A converter for {@link GregorianCalendar} conforming to the ISO8601 standard based on Joda-Time. | |
28 | * <p> | |
29 | * The converter will always serialize the calendar value in UTC and deserialize it to a value in the current default | |
30 | * time zone. | |
31 | * </p> | |
32 | * | |
33 | * @author Mauro Talevi | |
34 | * @author Jörg Schaible | |
35 | * @see <a href="http://www.iso.org/iso/home/store/catalogue_ics/catalogue_detail_ics.htm?csnumber=40874">ISO 8601</a> | |
36 | * @since 1.4.10 | |
37 | */ | |
38 | public class ISO8601JodaTimeConverter extends AbstractSingleValueConverter { | |
39 | private static final DateTimeFormatter[] formattersUTC = { // | |
40 | ISODateTimeFormat.dateTime(), // | |
41 | ISODateTimeFormat.dateTimeNoMillis(), // | |
42 | ISODateTimeFormat.basicDateTime(), // | |
43 | ISODateTimeFormat.basicDateTimeNoMillis(), // | |
44 | ISODateTimeFormat.basicOrdinalDateTime(), // | |
45 | ISODateTimeFormat.basicOrdinalDateTimeNoMillis(), // | |
46 | ISODateTimeFormat.basicTime(), // | |
47 | ISODateTimeFormat.basicTimeNoMillis(), // | |
48 | ISODateTimeFormat.basicTTime(), // | |
49 | ISODateTimeFormat.basicTTimeNoMillis(), // | |
50 | ISODateTimeFormat.basicWeekDateTime(), // | |
51 | ISODateTimeFormat.basicWeekDateTimeNoMillis(), // | |
52 | ISODateTimeFormat.ordinalDateTime(), // | |
53 | ISODateTimeFormat.ordinalDateTimeNoMillis(), // | |
54 | ISODateTimeFormat.time(), // | |
55 | ISODateTimeFormat.timeNoMillis(), // | |
56 | ISODateTimeFormat.tTime(), // | |
57 | ISODateTimeFormat.tTimeNoMillis(), // | |
58 | ISODateTimeFormat.weekDateTime(), // | |
59 | ISODateTimeFormat.weekDateTimeNoMillis() // | |
60 | }; | |
61 | private static final DateTimeFormatter[] formattersNoUTC = { // | |
62 | ISODateTimeFormat.basicDate(), // | |
63 | ISODateTimeFormat.basicOrdinalDate(), // | |
64 | ISODateTimeFormat.basicWeekDate(), // | |
65 | ISODateTimeFormat.date(), // | |
66 | ISODateTimeFormat.dateHour(), // | |
67 | ISODateTimeFormat.dateHourMinute(), // | |
68 | ISODateTimeFormat.dateHourMinuteSecond(), // | |
69 | ISODateTimeFormat.dateHourMinuteSecondFraction(), // | |
70 | ISODateTimeFormat.dateHourMinuteSecondMillis(), // | |
71 | ISODateTimeFormat.hour(), // | |
72 | ISODateTimeFormat.hourMinute(), // | |
73 | ISODateTimeFormat.hourMinuteSecond(), // | |
74 | ISODateTimeFormat.hourMinuteSecondFraction(), // | |
75 | ISODateTimeFormat.hourMinuteSecondMillis(), // | |
76 | ISODateTimeFormat.ordinalDate(), // | |
77 | ISODateTimeFormat.weekDate(), // | |
78 | ISODateTimeFormat.year(), // | |
79 | ISODateTimeFormat.yearMonth(), // | |
80 | ISODateTimeFormat.yearMonthDay(), // | |
81 | ISODateTimeFormat.weekyear(), // | |
82 | ISODateTimeFormat.weekyearWeek(), // | |
83 | ISODateTimeFormat.weekyearWeekDay() // | |
84 | }; | |
85 | ||
86 | public boolean canConvert(final Class type) { | |
87 | return false; | |
88 | } | |
89 | ||
90 | public Object fromString(final String str) { | |
91 | for (int i = 0; i < formattersUTC.length ; ++i) { | |
92 | final DateTimeFormatter formatter = formattersUTC[i]; | |
93 | try { | |
94 | final DateTime dt = formatter.parseDateTime(str); | |
95 | final Calendar calendar = dt.toGregorianCalendar(); | |
96 | calendar.setTimeZone(TimeZone.getDefault()); | |
97 | return calendar; | |
98 | } catch (final IllegalArgumentException e) { | |
99 | // try with next formatter | |
100 | } | |
101 | } | |
102 | final DateTimeZone dateTimeZone = DateTimeZone.forTimeZone(TimeZone.getDefault()); | |
103 | for (int i = 0; i < formattersNoUTC.length ; ++i) { | |
104 | final DateTimeFormatter element = formattersNoUTC[i]; | |
105 | try { | |
106 | final DateTimeFormatter formatter = element.withZone(dateTimeZone); | |
107 | final DateTime dt = formatter.parseDateTime(str); | |
108 | final Calendar calendar = dt.toGregorianCalendar(); | |
109 | calendar.setTimeZone(TimeZone.getDefault()); | |
110 | return calendar; | |
111 | } catch (final IllegalArgumentException e) { | |
112 | // try with next formatter | |
113 | } | |
114 | } | |
115 | final ConversionException exception = new ConversionException("Cannot parse date"); | |
116 | exception.add("date", str); | |
117 | throw exception; | |
118 | } | |
119 | ||
120 | public String toString(final Object obj) { | |
121 | final DateTime dt = new DateTime(obj); | |
122 | return dt.toString(formattersUTC[0]); | |
123 | } | |
124 | } |
97 | 97 | if (writeReplaceMethod != null) { |
98 | 98 | ErrorWritingException ex = null; |
99 | 99 | try { |
100 | return writeReplaceMethod.invoke(object, EMPTY_ARGS); | |
101 | } catch (IllegalAccessException e) { | |
100 | Object replaced = writeReplaceMethod.invoke(object, EMPTY_ARGS); | |
101 | if (replaced != null && !object.getClass().equals(replaced.getClass())) { | |
102 | // call further writeReplace methods on replaced | |
103 | replaced = callWriteReplace(replaced); | |
104 | } | |
105 | return replaced; | |
106 | } catch (final IllegalAccessException e) { | |
102 | 107 | ex = new ObjectAccessException("Cannot access method", e); |
103 | 108 | } catch (InvocationTargetException e) { |
104 | 109 | ex = new ConversionException("Failed calling method", e.getTargetException()); |
110 | } catch (final ErrorWritingException e) { | |
111 | ex = e; | |
105 | 112 | } |
106 | 113 | ex.add("method", objectType.getName() + ".writeReplace()"); |
107 | 114 | throw ex; |
0 | 0 | /* |
1 | * Copyright (C) 2011 XStream Committers. | |
1 | * Copyright (C) 2011, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
12 | 12 | /** |
13 | 13 | * @author Jörg Schaible |
14 | 14 | * @since 1.4.2 |
15 | * @deprecated As of 1.4.11, this interface will be merged into parent with version 1.5.0. | |
15 | 16 | */ |
16 | 17 | public interface ExtendedHierarchicalStreamReader extends HierarchicalStreamReader { |
17 | 18 |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
12 | 12 | |
13 | 13 | /** |
14 | 14 | * @author Paul Hammant |
15 | * @deprecated As of 1.4.11, this interface will be merged into parent with version 1.5.0. | |
15 | 16 | */ |
16 | 17 | public interface ExtendedHierarchicalStreamWriter extends HierarchicalStreamWriter { |
17 | 18 |
+9
-2
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.io; |
12 | 12 | |
13 | /** | |
14 | * @deprecated As of 1.4.11, this helper is no longer required since version 1.5.0. | |
15 | */ | |
13 | 16 | public class ExtendedHierarchicalStreamWriterHelper { |
17 | /** | |
18 | * @deprecated As of 1.4.11, with version 1.5.0 use {@link HierarchicalStreamWriter#startNode(String, Class)} | |
19 | * directly. This helper will be no longer required. | |
20 | */ | |
14 | 21 | public static void startNode(HierarchicalStreamWriter writer, String name, Class clazz) { |
15 | 22 | if (writer instanceof ExtendedHierarchicalStreamWriter) { |
16 | ((ExtendedHierarchicalStreamWriter) writer).startNode(name, clazz); | |
23 | ((ExtendedHierarchicalStreamWriter)writer).startNode(name, clazz); | |
17 | 24 | } else { |
18 | 25 | writer.startNode(name); |
19 | 26 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2011 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2011, 2016 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
48 | 48 | |
49 | 49 | /** |
50 | 50 | * Get the value of an attribute of the current node. |
51 | * <p> | |
52 | * If no such attribute exists, the method returns null. | |
53 | * </p> | |
51 | 54 | */ |
52 | 55 | String getAttribute(String name); |
53 | 56 | |
54 | 57 | /** |
55 | 58 | * Get the value of an attribute of the current node, by index. |
59 | * <p> | |
60 | * Note, the behavior of this method is dependent on the underlying parser when calling it with a non-existing | |
61 | * index. Typically some kind of RuntimeException is thrown. | |
62 | * </p> | |
56 | 63 | */ |
57 | 64 | String getAttribute(int index); |
58 | 65 | |
63 | 70 | |
64 | 71 | /** |
65 | 72 | * Name of attribute in current node. |
73 | * <p> | |
74 | * Note, the behavior of this method is dependent on the underlying parser when calling it with a non-existing | |
75 | * index. Typically some kind of RuntimeException is thrown. | |
76 | * </p> | |
66 | 77 | */ |
67 | 78 | String getAttributeName(int index); |
68 | 79 | |
69 | 80 | /** |
70 | * Names of attributes (as Strings). | |
81 | * Iterator with the names of the attributes. | |
82 | * <p> | |
83 | * Note, the iterator is only valid as long as the internal state of the underlying parser is still at the start of | |
84 | * the current element. The behavior is undefined if the parser moved on. | |
85 | * </p> | |
71 | 86 | */ |
72 | 87 | Iterator getAttributeNames(); |
73 | 88 |
0 | 0 | /* |
1 | * Copyright (C) 2009, 2011, 2014, 2015 XStream Committers. | |
1 | * Copyright (C) 2009, 2011, 2014, 2015, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
21 | 21 | * |
22 | 22 | * @author Jörg Schaible |
23 | 23 | * @since 1.4 |
24 | * @deprecated As of 1.4.11 use {@link StandardStaxDriver} or {@link WstxDriver} instead. BEA StAX implementation is | |
25 | * outdated, unmaintained and has security issues. | |
24 | 26 | */ |
25 | 27 | public class BEAStaxDriver extends StaxDriver { |
26 | 28 | |
29 | /** | |
30 | * @deprecated As of 1.4.11 use {@link StandardStaxDriver} or {@link WstxDriver} instead. | |
31 | */ | |
27 | 32 | public BEAStaxDriver() { |
28 | 33 | super(); |
29 | 34 | } |
37 | 42 | |
38 | 43 | /** |
39 | 44 | * @since 1.4.6 |
45 | * @deprecated As of 1.4.11 use {@link StandardStaxDriver} or {@link WstxDriver} instead. | |
40 | 46 | */ |
41 | 47 | public BEAStaxDriver(QNameMap qnameMap, NameCoder nameCoder) { |
42 | 48 | super(qnameMap, nameCoder); |
43 | 49 | } |
44 | 50 | |
45 | public BEAStaxDriver(QNameMap qnameMap) { | |
51 | /** | |
52 | * @deprecated As of 1.4.11 use {@link StandardStaxDriver} or {@link WstxDriver} instead. | |
53 | */ | |
54 | public BEAStaxDriver(final QNameMap qnameMap) { | |
46 | 55 | super(qnameMap); |
47 | 56 | } |
48 | 57 | |
55 | 64 | |
56 | 65 | /** |
57 | 66 | * @since 1.4.6 |
67 | * @deprecated As of 1.4.11 use {@link StandardStaxDriver} or {@link WstxDriver} instead. | |
58 | 68 | */ |
59 | 69 | public BEAStaxDriver(NameCoder nameCoder) { |
60 | 70 | super(nameCoder); |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2009, 2011, 2014, 2015 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2009, 2011, 2014, 2015, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
18 | 18 | import java.io.Reader; |
19 | 19 | import java.io.Writer; |
20 | 20 | import java.net.URL; |
21 | import java.nio.charset.Charset; | |
21 | 22 | |
22 | 23 | import org.dom4j.Document; |
23 | 24 | import org.dom4j.DocumentException; |
141 | 142 | } |
142 | 143 | |
143 | 144 | public HierarchicalStreamWriter createWriter(final OutputStream out) { |
144 | final Writer writer = new OutputStreamWriter(out); | |
145 | final String encoding = getOutputFormat() != null ? getOutputFormat().getEncoding() : null; | |
146 | final Charset charset = encoding != null && Charset.isSupported(encoding) ? Charset.forName(encoding) : null; | |
147 | final Writer writer = charset != null ? new OutputStreamWriter(out, charset) : new OutputStreamWriter(out); | |
145 | 148 | return createWriter(writer); |
146 | 149 | } |
147 | 150 |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2009, 2011, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
13 | 13 | import com.thoughtworks.xstream.converters.ErrorWriter; |
14 | 14 | import com.thoughtworks.xstream.io.naming.NameCoder; |
15 | 15 | import java.util.List; |
16 | ||
17 | import org.dom4j.Branch; | |
16 | 18 | import org.dom4j.Document; |
17 | 19 | import org.dom4j.Element; |
18 | 20 | |
20 | 22 | |
21 | 23 | private Element currentElement; |
22 | 24 | |
23 | public Dom4JReader(Element rootElement) { | |
25 | /** | |
26 | * @since 1.4.11 | |
27 | */ | |
28 | public Dom4JReader(final Branch branch) { | |
29 | this(branch instanceof Element ? (Element)branch : ((Document)branch).getRootElement()); | |
30 | } | |
31 | ||
32 | public Dom4JReader(final Element rootElement) { | |
24 | 33 | this(rootElement, new XmlFriendlyNameCoder()); |
25 | 34 | } |
26 | 35 |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2009, 2011, 2016 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
6 | 6 | * style license a copy of which has been included with this distribution in |
7 | 7 | * the LICENSE.txt file. |
8 | * | |
8 | * | |
9 | 9 | * Created on 07. March 2004 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.io.xml; |
121 | 121 | public void close() { |
122 | 122 | try { |
123 | 123 | writer.endDocument(); |
124 | writer.flush(); | |
124 | 125 | } catch (SAXException e) { |
126 | throw new StreamException(e); | |
127 | } catch (IOException e) { | |
125 | 128 | throw new StreamException(e); |
126 | 129 | } |
127 | 130 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2014, 2015 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2014, 2015, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
139 | 139 | */ |
140 | 140 | protected DocumentBuilderFactory createDocumentBuilderFactory() { |
141 | 141 | final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
142 | if (JVM.is15()) { | |
142 | if (JVM.isVersion(5)) { | |
143 | 143 | try { |
144 | 144 | Method method = DocumentBuilderFactory.class.getMethod("setFeature", |
145 | 145 | new Class[]{ String.class, boolean.class }); |
150 | 150 | throw new ObjectAccessException("Cannot set feature of DocumentBuilderFactory.", e); |
151 | 151 | } catch (InvocationTargetException e) { |
152 | 152 | Throwable cause = e.getCause(); |
153 | if (JVM.is16() | |
153 | if (JVM.isVersion(6) | |
154 | 154 | || (cause instanceof ParserConfigurationException |
155 | 155 | && cause.getMessage().indexOf("disallow-doctype-decl") < 0)) { |
156 | 156 | throw new StreamException(cause); |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.io.xml; |
12 | 12 | |
13 | import org.xmlpull.v1.XmlPullParser; | |
14 | import org.xmlpull.v1.XmlPullParserException; | |
15 | ||
13 | 16 | import com.thoughtworks.xstream.io.HierarchicalStreamDriver; |
14 | 17 | import com.thoughtworks.xstream.io.naming.NameCoder; |
15 | ||
16 | import org.xmlpull.v1.XmlPullParser; | |
17 | import org.xmlpull.v1.XmlPullParserException; | |
18 | import org.xmlpull.v1.XmlPullParserFactory; | |
19 | 18 | |
20 | 19 | /** |
21 | 20 | * A {@link HierarchicalStreamDriver} for XPP DOM using the XmlPullParserFactory to locate an parser. |
25 | 24 | */ |
26 | 25 | public class XppDomDriver extends AbstractXppDomDriver { |
27 | 26 | |
28 | private static XmlPullParserFactory factory; | |
29 | ||
30 | 27 | public XppDomDriver() { |
31 | 28 | super(new XmlFriendlyNameCoder()); |
32 | 29 | } |
46 | 43 | super(replacer); |
47 | 44 | } |
48 | 45 | |
49 | /** | |
50 | * {@inheritDoc} | |
51 | */ | |
52 | 46 | protected synchronized XmlPullParser createParser() throws XmlPullParserException { |
53 | if (factory == null) { | |
54 | factory = XmlPullParserFactory.newInstance(null, XppDomDriver.class); | |
55 | } | |
56 | return factory.newPullParser(); | |
47 | return XppDriver.createDefaultParser(); | |
57 | 48 | } |
58 | 49 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
6 | 6 | * style license a copy of which has been included with this distribution in |
7 | 7 | * the LICENSE.txt file. |
8 | * | |
8 | * | |
9 | 9 | * Created on 08. March 2004 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.io.xml; |
49 | 49 | } |
50 | 50 | |
51 | 51 | /** |
52 | * {@inheritDoc} | |
52 | * Create a default XML Pull Parser. The method uses the Java Service API to get the registered | |
53 | * {@link XmlPullParserFactory} and let it create a new parser. | |
54 | * | |
55 | * @return a new instance of an XML Pull Parser | |
56 | * @throws XmlPullParserException if the creation of a new parser fails. | |
57 | * @since 1.4.11 | |
53 | 58 | */ |
54 | protected synchronized XmlPullParser createParser() throws XmlPullParserException { | |
59 | public static synchronized XmlPullParser createDefaultParser() throws XmlPullParserException { | |
55 | 60 | if (factory == null) { |
56 | 61 | factory = XmlPullParserFactory.newInstance(); |
57 | 62 | } |
58 | 63 | return factory.newPullParser(); |
59 | 64 | } |
65 | ||
66 | protected XmlPullParser createParser() throws XmlPullParserException { | |
67 | return createDefaultParser(); | |
68 | } | |
60 | 69 | } |
0 | 0 | /* |
1 | * Copyright (C) 2007, 2008, 2013 XStream Committers. | |
1 | * Copyright (C) 2007, 2008, 2013, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
14 | 14 | * |
15 | 15 | * @author Jörg Schaible |
16 | 16 | * @since 1.3 |
17 | * @deprecated As of 1.4.5, minimal JDK version will be 1.6 for next major release | |
17 | * @deprecated As of 1.4.5, minimal JDK version will be 1.7 for next major release | |
18 | 18 | */ |
19 | 19 | public interface AnnotationConfiguration { |
20 | 20 |
68 | 68 | private transient DefaultImplementationsMapper defaultImplementationsMapper; |
69 | 69 | private transient ImplicitCollectionMapper implicitCollectionMapper; |
70 | 70 | private transient FieldAliasingMapper fieldAliasingMapper; |
71 | private transient ElementIgnoringMapper elementIgnoringMapper; | |
71 | 72 | private transient AttributeMapper attributeMapper; |
72 | 73 | private transient LocalConversionMapper localConversionMapper; |
73 | 74 | private final Map<Class<?>, Map<List<Object>, Converter>> converterCache = |
456 | 457 | final XStreamOmitField omitFieldAnnotation = field |
457 | 458 | .getAnnotation(XStreamOmitField.class); |
458 | 459 | if (omitFieldAnnotation != null) { |
459 | if (fieldAliasingMapper == null) { | |
460 | if (elementIgnoringMapper == null) { | |
460 | 461 | throw new InitializationException("No " |
461 | + FieldAliasingMapper.class.getName() | |
462 | + ElementIgnoringMapper.class.getName() | |
462 | 463 | + " available"); |
463 | 464 | } |
464 | fieldAliasingMapper.omitField(field.getDeclaringClass(), field.getName()); | |
465 | elementIgnoringMapper.omitField(field.getDeclaringClass(), field.getName()); | |
465 | 466 | } |
466 | 467 | } |
467 | 468 | |
568 | 569 | defaultImplementationsMapper = (DefaultImplementationsMapper)lookupMapperOfType(DefaultImplementationsMapper.class); |
569 | 570 | implicitCollectionMapper = (ImplicitCollectionMapper)lookupMapperOfType(ImplicitCollectionMapper.class); |
570 | 571 | fieldAliasingMapper = (FieldAliasingMapper)lookupMapperOfType(FieldAliasingMapper.class); |
572 | elementIgnoringMapper = (ElementIgnoringMapper)lookupMapperOfType(ElementIgnoringMapper.class); | |
571 | 573 | attributeMapper = (AttributeMapper)lookupMapperOfType(AttributeMapper.class); |
572 | 574 | localConversionMapper = (LocalConversionMapper)lookupMapperOfType(LocalConversionMapper.class); |
573 | 575 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2013, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
106 | 106 | } else if (fieldNameToTypeMap.get(fieldName) == type) { |
107 | 107 | return true; |
108 | 108 | } else if (fieldName != null && definedIn != null) { |
109 | Field field = reflectionProvider.getField(definedIn, fieldName); | |
110 | return fieldToUseAsAttribute.contains(field); | |
109 | final Field field = reflectionProvider.getFieldOrNull(definedIn, fieldName); | |
110 | return field != null && fieldToUseAsAttribute.contains(field); | |
111 | 111 | } |
112 | 112 | return false; |
113 | 113 | } |
139 | 139 | * @deprecated As of 1.3.1, use {@link #getConverterFromAttribute(Class, String, Class)} |
140 | 140 | */ |
141 | 141 | public SingleValueConverter getConverterFromAttribute(Class definedIn, String attribute) { |
142 | Field field = reflectionProvider.getField(definedIn, attribute); | |
143 | return getConverterFromAttribute(definedIn, attribute, field.getType()); | |
142 | final Field field = reflectionProvider.getFieldOrNull(definedIn, attribute); | |
143 | return field != null ? getConverterFromAttribute(definedIn, attribute, field.getType()) : null; | |
144 | 144 | } |
145 | 145 | |
146 | 146 | public SingleValueConverter getConverterFromAttribute(Class definedIn, String attribute, Class type) { |
159 | 159 | * @param field the field itself |
160 | 160 | * @since 1.2.2 |
161 | 161 | */ |
162 | public void addAttributeFor(Field field) { | |
163 | fieldToUseAsAttribute.add(field); | |
162 | public void addAttributeFor(final Field field) { | |
163 | if (field != null) { | |
164 | fieldToUseAsAttribute.add(field); | |
165 | } | |
164 | 166 | } |
165 | 167 | |
166 | 168 | /** |
168 | 170 | * |
169 | 171 | * @param definedIn the declaring class of the field |
170 | 172 | * @param fieldName the name of the field |
171 | * @throws IllegalArgumentException if the field does not exist | |
172 | 173 | * @since 1.3 |
173 | 174 | */ |
174 | 175 | public void addAttributeFor(Class definedIn, String fieldName) { |
175 | fieldToUseAsAttribute.add(reflectionProvider.getField(definedIn, fieldName)); | |
176 | addAttributeFor(reflectionProvider.getField(definedIn, fieldName)); | |
176 | 177 | } |
177 | 178 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013, 2015 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013, 2015, 2016 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
120 | 120 | public boolean shouldSerializeMember(Class definedIn, String fieldName) { |
121 | 121 | return true; |
122 | 122 | } |
123 | ||
124 | public boolean isIgnoredElement(String name) { | |
125 | return false; | |
126 | } | |
123 | 127 | |
124 | 128 | public String lookupName(Class type) { |
125 | 129 | return serializedClass(type); |
0 | /* | |
1 | * Copyright (C) 2013, 2016 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 08. January 2016 by Joerg Schaible, factored out from FieldAliasingMapper. | |
9 | */ | |
10 | package com.thoughtworks.xstream.mapper; | |
11 | ||
12 | import java.util.HashSet; | |
13 | import java.util.Iterator; | |
14 | import java.util.LinkedHashSet; | |
15 | import java.util.Set; | |
16 | import java.util.regex.Pattern; | |
17 | ||
18 | import com.thoughtworks.xstream.core.util.FastField; | |
19 | ||
20 | /** | |
21 | * Mapper that allows an field of a specific class to be omitted entirely. | |
22 | * | |
23 | * @author Joerg Schaible | |
24 | */ | |
25 | public class ElementIgnoringMapper extends MapperWrapper { | |
26 | ||
27 | protected final Set fieldsToOmit = new HashSet(); | |
28 | protected final Set unknownElementsToIgnore = new LinkedHashSet(); | |
29 | ||
30 | public ElementIgnoringMapper(Mapper wrapped) { | |
31 | super(wrapped); | |
32 | } | |
33 | ||
34 | public void addElementsToIgnore(final Pattern pattern) { | |
35 | unknownElementsToIgnore.add(pattern); | |
36 | } | |
37 | ||
38 | public void omitField(Class definedIn, String fieldName) { | |
39 | fieldsToOmit.add(key(definedIn, fieldName)); | |
40 | } | |
41 | ||
42 | public boolean shouldSerializeMember(Class definedIn, String fieldName) { | |
43 | if (fieldsToOmit.contains(key(definedIn, fieldName))) { | |
44 | return false; | |
45 | } else if (definedIn == Object.class && isIgnoredElement(fieldName)) { | |
46 | return false; | |
47 | } | |
48 | return super.shouldSerializeMember(definedIn, fieldName); | |
49 | } | |
50 | ||
51 | public boolean isIgnoredElement(String name) { | |
52 | if (!unknownElementsToIgnore.isEmpty()) { | |
53 | for(Iterator iter = unknownElementsToIgnore.iterator(); iter.hasNext();) { | |
54 | Pattern pattern = (Pattern)iter.next(); | |
55 | if (pattern.matcher(name).matches()) { | |
56 | return true; | |
57 | } | |
58 | } | |
59 | } | |
60 | return super.isIgnoredElement(name); | |
61 | } | |
62 | ||
63 | private Object key(Class type, String name) { | |
64 | return new FastField(type, name); | |
65 | } | |
66 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2013, 2014 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2013, 2014, 2016 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
13 | 13 | import com.thoughtworks.xstream.core.util.FastField; |
14 | 14 | |
15 | 15 | import java.util.HashMap; |
16 | import java.util.HashSet; | |
17 | import java.util.Iterator; | |
18 | import java.util.LinkedHashSet; | |
19 | 16 | import java.util.Map; |
20 | import java.util.Set; | |
21 | 17 | import java.util.regex.Pattern; |
22 | 18 | |
23 | 19 | /** |
24 | * Mapper that allows a field of a specific class to be replaced with a shorter alias, or omitted | |
25 | * entirely. | |
20 | * Mapper that allows a field of a specific class to be replaced with a shorter alias. | |
26 | 21 | * |
27 | 22 | * @author Joe Walnes |
28 | 23 | */ |
30 | 25 | |
31 | 26 | protected final Map fieldToAliasMap = new HashMap(); |
32 | 27 | protected final Map aliasToFieldMap = new HashMap(); |
33 | protected final Set fieldsToOmit = new HashSet(); | |
34 | protected final Set unknownFieldsToIgnore = new LinkedHashSet(); | |
28 | private final ElementIgnoringMapper elementIgnoringMapper; | |
35 | 29 | |
36 | 30 | public FieldAliasingMapper(Mapper wrapped) { |
37 | 31 | super(wrapped); |
32 | elementIgnoringMapper = | |
33 | (ElementIgnoringMapper)lookupMapperOfType(ElementIgnoringMapper.class); | |
38 | 34 | } |
39 | 35 | |
40 | 36 | public void addFieldAlias(String alias, Class type, String fieldName) { |
42 | 38 | aliasToFieldMap.put(key(type, alias), fieldName); |
43 | 39 | } |
44 | 40 | |
41 | /** | |
42 | * @deprecated As of 1.4.9 use {@link ElementIgnoringMapper#addElementsToIgnore(Pattern)}. | |
43 | */ | |
45 | 44 | public void addFieldsToIgnore(final Pattern pattern) { |
46 | unknownFieldsToIgnore.add(pattern); | |
45 | if (elementIgnoringMapper != null) { | |
46 | elementIgnoringMapper.addElementsToIgnore(pattern); | |
47 | } | |
48 | } | |
49 | ||
50 | /** | |
51 | * @deprecated As of 1.4.9 use {@link ElementIgnoringMapper#omitField(Class, String)}. | |
52 | */ | |
53 | public void omitField(Class definedIn, String fieldName) { | |
54 | if (elementIgnoringMapper != null) { | |
55 | elementIgnoringMapper.omitField(definedIn, fieldName); | |
56 | } | |
47 | 57 | } |
48 | 58 | |
49 | 59 | private Object key(Class type, String name) { |
77 | 87 | } |
78 | 88 | return member; |
79 | 89 | } |
80 | ||
81 | public boolean shouldSerializeMember(Class definedIn, String fieldName) { | |
82 | if (fieldsToOmit.contains(key(definedIn, fieldName))) { | |
83 | return false; | |
84 | } else if (definedIn == Object.class && !unknownFieldsToIgnore.isEmpty()) { | |
85 | for(Iterator iter = unknownFieldsToIgnore.iterator(); iter.hasNext();) { | |
86 | Pattern pattern = (Pattern)iter.next(); | |
87 | if (pattern.matcher(fieldName).matches()) { | |
88 | return false; | |
89 | } | |
90 | } | |
91 | } | |
92 | return true; | |
93 | } | |
94 | ||
95 | public void omitField(Class definedIn, String fieldName) { | |
96 | fieldsToOmit.add(key(definedIn, fieldName)); | |
97 | } | |
98 | 90 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2009, 2011, 2012, 2013, 2014, 2015 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2009, 2011, 2012, 2013, 2014, 2015, 2016 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
11 | 11 | package com.thoughtworks.xstream.mapper; |
12 | 12 | |
13 | 13 | import com.thoughtworks.xstream.InitializationException; |
14 | import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; | |
14 | 15 | import com.thoughtworks.xstream.core.util.Primitives; |
15 | 16 | |
16 | 17 | import java.lang.reflect.Field; |
23 | 24 | |
24 | 25 | public class ImplicitCollectionMapper extends MapperWrapper { |
25 | 26 | |
26 | public ImplicitCollectionMapper(Mapper wrapped) { | |
27 | private ReflectionProvider reflectionProvider; | |
28 | ||
29 | public ImplicitCollectionMapper(Mapper wrapped, ReflectionProvider reflectionProvider) { | |
27 | 30 | super(wrapped); |
31 | this.reflectionProvider = reflectionProvider; | |
28 | 32 | } |
29 | 33 | |
30 | 34 | // { definedIn (Class) -> (ImplicitCollectionMapperForClass) } |
32 | 36 | |
33 | 37 | private ImplicitCollectionMapperForClass getMapper(final Class declaredFor, final String fieldName) { |
34 | 38 | Class definedIn = declaredFor; |
39 | Field field = fieldName != null ? reflectionProvider.getFieldOrNull(definedIn, fieldName) : null; | |
40 | Class inheritanceStop = field != null ? field.getDeclaringClass() : null; | |
35 | 41 | while (definedIn != null) { |
36 | 42 | ImplicitCollectionMapperForClass mapper = (ImplicitCollectionMapperForClass)classNameToMapper |
37 | 43 | .get(definedIn); |
38 | 44 | if (mapper != null) { |
39 | 45 | return mapper; |
40 | } else { | |
41 | if (fieldName != null) { | |
42 | try { | |
43 | // do not continue search for a hidden field | |
44 | final Field field = definedIn.getDeclaredField(fieldName); | |
45 | if (field != null && !Modifier.isStatic(field.getModifiers())) { | |
46 | return null; | |
47 | } | |
48 | } catch (final SecurityException e) { | |
49 | throw new InitializationException("Access denied for field with implicit collection", e); | |
50 | } catch (final NoSuchFieldException e) { | |
51 | // OK, we can continue the search in the class hierarchy | |
52 | } | |
53 | } | |
46 | } | |
47 | if (definedIn == inheritanceStop) { | |
48 | break; | |
54 | 49 | } |
55 | 50 | definedIn = definedIn.getSuperclass(); |
56 | 51 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2015 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2015, 2016 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
101 | 101 | */ |
102 | 102 | boolean shouldSerializeMember(Class definedIn, String fieldName); |
103 | 103 | |
104 | /** | |
105 | * Whether this name can be ignored. | |
106 | * | |
107 | * @since 1.4.9 | |
108 | */ | |
109 | boolean isIgnoredElement(String name); | |
110 | ||
104 | 111 | interface ImplicitCollectionMapping { |
105 | 112 | String getFieldName(); |
106 | 113 | String getItemFieldName(); |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2015 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2015, 2016 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.mapper; |
12 | 12 | |
13 | import java.lang.reflect.Method; | |
14 | import java.util.HashMap; | |
15 | import java.util.Map; | |
16 | ||
13 | 17 | import com.thoughtworks.xstream.converters.Converter; |
14 | 18 | import com.thoughtworks.xstream.converters.SingleValueConverter; |
15 | 19 | |
20 | ||
16 | 21 | public abstract class MapperWrapper implements Mapper { |
17 | ||
18 | 22 | private final Mapper wrapped; |
23 | private final Mapper aliasForAttributeMapper; | |
24 | private final Mapper aliasForSystemAttributeMapper; | |
25 | private final Mapper attributeForAliasMapper; | |
26 | private final Mapper defaultImplementationOfMapper; | |
27 | private final Mapper getConverterFromAttributeMapper; | |
28 | private final Mapper getConverterFromItemTypeMapper; | |
29 | private final Mapper getFieldNameForItemTypeAndNameMapper; | |
30 | private final Mapper getImplicitCollectionDefForFieldNameMapper; | |
31 | private final Mapper getItemTypeForItemFieldNameMapper; | |
32 | private final Mapper getLocalConverterMapper; | |
33 | private final Mapper isIgnoredElementMapper; | |
34 | private final Mapper isImmutableValueTypeMapper; | |
35 | private final Mapper isReferenceableMapper; | |
36 | private final Mapper realClassMapper; | |
37 | private final Mapper realMemberMapper; | |
38 | private final Mapper serializedClassMapper; | |
39 | private final Mapper serializedMemberMapper; | |
40 | private final Mapper shouldSerializeMemberMapper; | |
19 | 41 | |
20 | 42 | public MapperWrapper(Mapper wrapped) { |
21 | 43 | this.wrapped = wrapped; |
44 | ||
45 | if (wrapped instanceof MapperWrapper) { | |
46 | final MapperWrapper wrapper = (MapperWrapper)wrapped; | |
47 | final Map wrapperMap = new HashMap(); | |
48 | wrapperMap.put("aliasForAttribute", wrapper.aliasForAttributeMapper); | |
49 | wrapperMap.put("aliasForSystemAttribute", wrapper.aliasForSystemAttributeMapper); | |
50 | wrapperMap.put("attributeForAlias", wrapper.attributeForAliasMapper); | |
51 | wrapperMap.put("defaultImplementationOf", wrapper.defaultImplementationOfMapper); | |
52 | wrapperMap.put("getConverterFromAttribute", wrapper.getConverterFromAttributeMapper); | |
53 | wrapperMap.put("getConverterFromItemType", wrapper.getConverterFromItemTypeMapper); | |
54 | wrapperMap.put("getFieldNameForItemTypeAndName", wrapper.getFieldNameForItemTypeAndNameMapper); | |
55 | wrapperMap.put("getImplicitCollectionDefForFieldName", wrapper.getImplicitCollectionDefForFieldNameMapper); | |
56 | wrapperMap.put("getItemTypeForItemFieldName", wrapper.getItemTypeForItemFieldNameMapper); | |
57 | wrapperMap.put("getLocalConverter", wrapper.getLocalConverterMapper); | |
58 | wrapperMap.put("isIgnoredElement", wrapper.isIgnoredElementMapper); | |
59 | wrapperMap.put("isImmutableValueType", wrapper.isImmutableValueTypeMapper); | |
60 | wrapperMap.put("isReferenceable", wrapper.isReferenceableMapper); | |
61 | wrapperMap.put("realClass", wrapper.realClassMapper); | |
62 | wrapperMap.put("realMember", wrapper.realMemberMapper); | |
63 | wrapperMap.put("serializedClass", wrapper.serializedClassMapper); | |
64 | wrapperMap.put("serializedMember", wrapper.serializedMemberMapper); | |
65 | wrapperMap.put("shouldSerializeMember", wrapper.shouldSerializeMemberMapper); | |
66 | ||
67 | final Method[] methods = wrapped.getClass().getMethods(); | |
68 | for (int i = 0; i < methods.length; ++i) { | |
69 | final Method method = methods[i]; | |
70 | if (method.getDeclaringClass() != MapperWrapper.class) { | |
71 | final String name = method.getName(); | |
72 | if (wrapperMap.containsKey(name)) { | |
73 | wrapperMap.put(name, wrapped); | |
74 | } | |
75 | } | |
76 | } | |
77 | ||
78 | aliasForAttributeMapper = (Mapper)wrapperMap.get("aliasForAttribute"); | |
79 | aliasForSystemAttributeMapper = (Mapper)wrapperMap.get("aliasForSystemAttribute"); | |
80 | attributeForAliasMapper = (Mapper)wrapperMap.get("attributeForAlias"); | |
81 | defaultImplementationOfMapper = (Mapper)wrapperMap.get("defaultImplementationOf"); | |
82 | getConverterFromAttributeMapper = (Mapper)wrapperMap.get("getConverterFromAttribute"); | |
83 | getConverterFromItemTypeMapper = (Mapper)wrapperMap.get("getConverterFromItemType"); | |
84 | getFieldNameForItemTypeAndNameMapper = (Mapper)wrapperMap.get("getFieldNameForItemTypeAndName"); | |
85 | getImplicitCollectionDefForFieldNameMapper = (Mapper)wrapperMap.get("getImplicitCollectionDefForFieldName"); | |
86 | getItemTypeForItemFieldNameMapper = (Mapper)wrapperMap.get("getItemTypeForItemFieldName"); | |
87 | getLocalConverterMapper = (Mapper)wrapperMap.get("getLocalConverter"); | |
88 | isIgnoredElementMapper = (Mapper)wrapperMap.get("isIgnoredElement"); | |
89 | isImmutableValueTypeMapper = (Mapper)wrapperMap.get("isImmutableValueType"); | |
90 | isReferenceableMapper = (Mapper)wrapperMap.get("isReferenceable"); | |
91 | realClassMapper = (Mapper)wrapperMap.get("realClass"); | |
92 | realMemberMapper = (Mapper)wrapperMap.get("realMember"); | |
93 | serializedClassMapper = (Mapper)wrapperMap.get("serializedClass"); | |
94 | serializedMemberMapper = (Mapper)wrapperMap.get("serializedMember"); | |
95 | shouldSerializeMemberMapper = (Mapper)wrapperMap.get("shouldSerializeMember"); | |
96 | } else { | |
97 | aliasForAttributeMapper = wrapped; | |
98 | aliasForSystemAttributeMapper = wrapped; | |
99 | attributeForAliasMapper = wrapped; | |
100 | defaultImplementationOfMapper = wrapped; | |
101 | getConverterFromAttributeMapper = wrapped; | |
102 | getConverterFromItemTypeMapper = wrapped; | |
103 | getFieldNameForItemTypeAndNameMapper = wrapped; | |
104 | getImplicitCollectionDefForFieldNameMapper = wrapped; | |
105 | getItemTypeForItemFieldNameMapper = wrapped; | |
106 | getLocalConverterMapper = wrapped; | |
107 | isIgnoredElementMapper = wrapped; | |
108 | isImmutableValueTypeMapper = wrapped; | |
109 | isReferenceableMapper = wrapped; | |
110 | realClassMapper = wrapped; | |
111 | realMemberMapper = wrapped; | |
112 | serializedClassMapper = wrapped; | |
113 | serializedMemberMapper = wrapped; | |
114 | shouldSerializeMemberMapper = wrapped; | |
115 | } | |
116 | ||
22 | 117 | } |
23 | 118 | |
24 | 119 | public String serializedClass(Class type) { |
25 | return wrapped.serializedClass(type); | |
120 | return serializedClassMapper.serializedClass(type); | |
26 | 121 | } |
27 | 122 | |
28 | 123 | public Class realClass(String elementName) { |
29 | return wrapped.realClass(elementName); | |
124 | return realClassMapper.realClass(elementName); | |
30 | 125 | } |
31 | 126 | |
32 | 127 | public String serializedMember(Class type, String memberName) { |
33 | return wrapped.serializedMember(type, memberName); | |
128 | return serializedMemberMapper.serializedMember(type, memberName); | |
34 | 129 | } |
35 | 130 | |
36 | 131 | public String realMember(Class type, String serialized) { |
37 | return wrapped.realMember(type, serialized); | |
132 | return realMemberMapper.realMember(type, serialized); | |
38 | 133 | } |
39 | 134 | |
40 | 135 | public boolean isImmutableValueType(Class type) { |
41 | return wrapped.isImmutableValueType(type); | |
136 | return isImmutableValueTypeMapper.isImmutableValueType(type); | |
42 | 137 | } |
43 | 138 | |
44 | 139 | public boolean isReferenceable(Class type) { |
45 | return wrapped.isReferenceable(type); | |
140 | return isReferenceableMapper.isReferenceable(type); | |
46 | 141 | } |
47 | 142 | |
48 | 143 | public Class defaultImplementationOf(Class type) { |
49 | return wrapped.defaultImplementationOf(type); | |
144 | return defaultImplementationOfMapper.defaultImplementationOf(type); | |
50 | 145 | } |
51 | 146 | |
52 | 147 | public String aliasForAttribute(String attribute) { |
53 | return wrapped.aliasForAttribute(attribute); | |
148 | return aliasForAttributeMapper.aliasForAttribute(attribute); | |
54 | 149 | } |
55 | 150 | |
56 | 151 | public String attributeForAlias(String alias) { |
57 | return wrapped.attributeForAlias(alias); | |
152 | return attributeForAliasMapper.attributeForAlias(alias); | |
58 | 153 | } |
59 | 154 | |
60 | 155 | public String aliasForSystemAttribute(String attribute) { |
61 | return wrapped.aliasForSystemAttribute(attribute); | |
156 | return aliasForSystemAttributeMapper.aliasForSystemAttribute(attribute); | |
62 | 157 | } |
63 | 158 | |
64 | 159 | public String getFieldNameForItemTypeAndName(Class definedIn, Class itemType, String itemFieldName) { |
65 | return wrapped.getFieldNameForItemTypeAndName(definedIn, itemType, itemFieldName); | |
160 | return getFieldNameForItemTypeAndNameMapper.getFieldNameForItemTypeAndName(definedIn, itemType, itemFieldName); | |
66 | 161 | } |
67 | 162 | |
68 | 163 | public Class getItemTypeForItemFieldName(Class definedIn, String itemFieldName) { |
69 | return wrapped.getItemTypeForItemFieldName(definedIn, itemFieldName); | |
164 | return getItemTypeForItemFieldNameMapper.getItemTypeForItemFieldName(definedIn, itemFieldName); | |
70 | 165 | } |
71 | 166 | |
72 | 167 | public ImplicitCollectionMapping getImplicitCollectionDefForFieldName(Class itemType, String fieldName) { |
73 | return wrapped.getImplicitCollectionDefForFieldName(itemType, fieldName); | |
168 | return getImplicitCollectionDefForFieldNameMapper.getImplicitCollectionDefForFieldName(itemType, fieldName); | |
74 | 169 | } |
75 | 170 | |
76 | 171 | public boolean shouldSerializeMember(Class definedIn, String fieldName) { |
77 | return wrapped.shouldSerializeMember(definedIn, fieldName); | |
172 | return shouldSerializeMemberMapper.shouldSerializeMember(definedIn, fieldName); | |
173 | } | |
174 | ||
175 | public boolean isIgnoredElement(String name) { | |
176 | return isIgnoredElementMapper.isIgnoredElement(name); | |
78 | 177 | } |
79 | 178 | |
80 | 179 | /** |
81 | 180 | * @deprecated As of 1.3, use {@link #getConverterFromItemType(String, Class, Class)} |
82 | 181 | */ |
83 | 182 | public SingleValueConverter getConverterFromItemType(String fieldName, Class type) { |
84 | return wrapped.getConverterFromItemType(fieldName, type); | |
183 | return getConverterFromItemTypeMapper.getConverterFromItemType(fieldName, type); | |
85 | 184 | } |
86 | 185 | |
87 | 186 | /** |
88 | 187 | * @deprecated As of 1.3, use {@link #getConverterFromItemType(String, Class, Class)} |
89 | 188 | */ |
90 | 189 | public SingleValueConverter getConverterFromItemType(Class type) { |
91 | return wrapped.getConverterFromItemType(type); | |
190 | return getConverterFromItemTypeMapper.getConverterFromItemType(type); | |
92 | 191 | } |
93 | 192 | |
94 | 193 | /** |
95 | 194 | * @deprecated As of 1.3, use {@link #getConverterFromAttribute(Class, String, Class)} |
96 | 195 | */ |
97 | 196 | public SingleValueConverter getConverterFromAttribute(String name) { |
98 | return wrapped.getConverterFromAttribute(name); | |
197 | return getConverterFromAttributeMapper.getConverterFromAttribute(name); | |
99 | 198 | } |
100 | 199 | |
101 | 200 | public Converter getLocalConverter(Class definedIn, String fieldName) { |
102 | return wrapped.getLocalConverter(definedIn, fieldName); | |
201 | return getLocalConverterMapper.getLocalConverter(definedIn, fieldName); | |
103 | 202 | } |
104 | 203 | |
105 | 204 | public Mapper lookupMapperOfType(Class type) { |
106 | 205 | return type.isAssignableFrom(getClass()) ? this : wrapped.lookupMapperOfType(type); |
107 | 206 | } |
108 | ||
207 | ||
109 | 208 | public SingleValueConverter getConverterFromItemType(String fieldName, Class type, Class definedIn) { |
110 | return wrapped.getConverterFromItemType(fieldName, type, definedIn); | |
111 | } | |
112 | ||
113 | /** | |
114 | * @deprecated As of 1.3, use combination of {@link #serializedMember(Class, String)} and {@link #getConverterFromItemType(String, Class, Class)} | |
209 | return getConverterFromItemTypeMapper.getConverterFromItemType(fieldName, type, definedIn); | |
210 | } | |
211 | ||
212 | /** | |
213 | * @deprecated As of 1.3, use combination of {@link #serializedMember(Class, String)} and | |
214 | * {@link #getConverterFromItemType(String, Class, Class)} | |
115 | 215 | */ |
116 | 216 | public String aliasForAttribute(Class definedIn, String fieldName) { |
117 | return wrapped.aliasForAttribute(definedIn, fieldName); | |
118 | } | |
119 | ||
120 | /** | |
121 | * @deprecated As of 1.3, use combination of {@link #realMember(Class, String)} and {@link #getConverterFromItemType(String, Class, Class)} | |
217 | return aliasForAttributeMapper.aliasForAttribute(definedIn, fieldName); | |
218 | } | |
219 | ||
220 | /** | |
221 | * @deprecated As of 1.3, use combination of {@link #realMember(Class, String)} and | |
222 | * {@link #getConverterFromItemType(String, Class, Class)} | |
122 | 223 | */ |
123 | 224 | public String attributeForAlias(Class definedIn, String alias) { |
124 | return wrapped.attributeForAlias(definedIn, alias); | |
125 | } | |
126 | ||
127 | /** | |
128 | * @deprecated As of 1.3.1, use {@link #getConverterFromAttribute(Class, String, Class)} | |
225 | return attributeForAliasMapper.attributeForAlias(definedIn, alias); | |
226 | } | |
227 | ||
228 | /** | |
229 | * @deprecated As of 1.3.1, use {@link #getConverterFromAttribute(Class, String, Class)} | |
129 | 230 | */ |
130 | 231 | public SingleValueConverter getConverterFromAttribute(Class type, String attribute) { |
131 | return wrapped.getConverterFromAttribute(type, attribute); | |
132 | } | |
133 | ||
232 | return getConverterFromAttributeMapper.getConverterFromAttribute(type, attribute); | |
233 | } | |
234 | ||
134 | 235 | public SingleValueConverter getConverterFromAttribute(Class definedIn, String attribute, Class type) { |
135 | return wrapped.getConverterFromAttribute(definedIn, attribute, type); | |
236 | return getConverterFromAttributeMapper.getConverterFromAttribute(definedIn, attribute, type); | |
136 | 237 | } |
137 | 238 | |
138 | 239 | } |
0 | 0 | /* |
1 | * Copyright (C) 2014 XStream Committers. | |
1 | * Copyright (C) 2014, 2017 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * Created on 09. January 2014 by Joerg Schaible |
7 | 7 | |
8 | 8 | import com.thoughtworks.xstream.core.util.Primitives; |
9 | 9 | |
10 | ||
10 | 11 | /** |
11 | * Permission for any primitive type and its boxed counterpart (incl. void). | |
12 | * Permission for any primitive type and its boxed counterpart (excl. void). | |
12 | 13 | * |
13 | 14 | * @author Jörg Schaible |
14 | 15 | * @since 1.4.7 |
20 | 21 | public static final TypePermission PRIMITIVES = new PrimitiveTypePermission(); |
21 | 22 | |
22 | 23 | public boolean allows(Class type) { |
23 | return type != null && type.isPrimitive() || Primitives.isBoxed(type); | |
24 | return type != null && type != void.class && type != Void.class && type.isPrimitive() | |
25 | || Primitives.isBoxed(type); | |
24 | 26 | } |
25 | 27 | |
26 | 28 | public int hashCode() { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
269 | 269 | properties.setProperty("1", "I"); |
270 | 270 | properties.setProperty("3", "III"); |
271 | 271 | |
272 | assertBothWays(properties, | |
272 | assertBothWaysNormalized(properties, | |
273 | 273 | "<properties>\n" + |
274 | 274 | " <property name=\"3\" value=\"III\"/>\n" + |
275 | 275 | " <property name=\"1\" value=\"I\"/>\n" + |
277 | 277 | " <property name=\"2\" value=\"two\"/>\n" + |
278 | 278 | " <property name=\"1\" value=\"one\"/>\n" + |
279 | 279 | " </defaults>\n" + |
280 | "</properties>"); | |
280 | "</properties>", "properties", "property", "@name"); | |
281 | 281 | } |
282 | 282 | |
283 | 283 | public void testUnmodifiableList() { |
0 | 0 | /* |
1 | * Copyright (C) 2006, 2007 XStream Committers. | |
1 | * Copyright (C) 2006, 2007, 2017 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
9 | 9 | */ |
10 | 10 | package com.thoughtworks.acceptance; |
11 | 11 | |
12 | import java.util.ArrayList; | |
12 | 13 | import java.util.Arrays; |
13 | 14 | import java.util.HashMap; |
14 | 15 | import java.util.List; |
27 | 28 | xstream.alias("thing", WithNamedList.class); |
28 | 29 | xstream.addImplicitCollection(WithNamedList.class, "things"); |
29 | 30 | |
30 | final List reference = Arrays.asList(new String[]{"A", "B", "C", "D"}); | |
31 | final List reference = new ArrayList(Arrays.asList(new String[]{"A", "B", "C", "D"})); | |
31 | 32 | final WithNamedList[] namedLists = new WithNamedList[5]; |
32 | 33 | for (int i = 0; i < namedLists.length; ++i) { |
33 | 34 | namedLists[i] = new WithNamedList("Name " + (i + 1)); |
44 | 45 | } |
45 | 46 | }; |
46 | 47 | |
47 | final Object object = Arrays.asList(namedLists); | |
48 | final Object object = new ArrayList(Arrays.asList(namedLists)); | |
48 | 49 | final String xml = xstream.toXML(object); |
49 | 50 | final int[] counter = new int[1]; |
50 | 51 | counter[0] = 0; |
0 | 0 | /* |
1 | * Copyright (C) 2012, 2015 XStream Committers. | |
1 | * Copyright (C) 2012, 2015, 2017, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
12 | 12 | import java.util.Map; |
13 | 13 | import java.util.concurrent.ConcurrentHashMap; |
14 | 14 | |
15 | import com.thoughtworks.xstream.converters.collections.MapConverter; | |
15 | 16 | import com.thoughtworks.xstream.core.JVM; |
16 | 17 | |
17 | 18 | |
39 | 40 | } |
40 | 41 | |
41 | 42 | public void testDerivedConcurrentHashMap() { |
42 | if (JVM.is18()) { | |
43 | if (JVM.isVersion(8)) { | |
43 | 44 | xstream.alias("derived-map", DerivedConcurrentHashMap.class); |
45 | xstream.registerConverter(new MapConverter(xstream.getMapper(), DerivedConcurrentHashMap.class)); | |
44 | 46 | |
45 | 47 | Map<Object, Object> map = new DerivedConcurrentHashMap(); |
46 | 48 | map.put("test", "JUnit"); |
47 | 49 | |
48 | 50 | String xml = "" |
49 | + "<derived-map serialization=\"custom\">\n" | |
50 | + " <unserializable-parents/>\n" | |
51 | + " <concurrent-hash-map>\n" | |
52 | + " <default>\n" | |
53 | + " <segmentMask>15</segmentMask>\n" | |
54 | + " </default>\n" | |
51 | + "<derived-map>\n" | |
52 | + " <entry>\n" | |
55 | 53 | + " <string>test</string>\n" |
56 | 54 | + " <string>JUnit</string>\n" |
57 | + " <null/>\n" | |
58 | + " <null/>\n" | |
59 | + " </concurrent-hash-map>\n" | |
55 | + " </entry>\n" | |
60 | 56 | + "</derived-map>"; |
61 | 57 | |
62 | 58 | assertBothWays(map, xml); |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2016, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
6 | 6 | * style license a copy of which has been included with this distribution in |
7 | 7 | * the LICENSE.txt file. |
8 | * | |
8 | * | |
9 | 9 | * Created on 25. June 2006 by Guilherme Silveira |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.acceptance; |
12 | 12 | |
13 | 13 | import java.io.ByteArrayInputStream; |
14 | 14 | import java.io.ByteArrayOutputStream; |
15 | import java.io.File; | |
15 | 16 | import java.io.IOException; |
16 | 17 | import java.io.OutputStreamWriter; |
17 | 18 | import java.util.Properties; |
18 | 19 | |
19 | 20 | import javax.xml.stream.XMLInputFactory; |
20 | 21 | |
22 | import com.bea.xml.stream.MXParserFactory; | |
23 | import com.thoughtworks.acceptance.objects.StandardObject; | |
24 | import com.thoughtworks.xstream.XStream; | |
25 | import com.thoughtworks.xstream.core.JVM; | |
26 | import com.thoughtworks.xstream.io.HierarchicalStreamDriver; | |
27 | import com.thoughtworks.xstream.io.xml.BEAStaxDriver; | |
28 | import com.thoughtworks.xstream.io.xml.Dom4JDriver; | |
29 | import com.thoughtworks.xstream.io.xml.DomDriver; | |
30 | import com.thoughtworks.xstream.io.xml.JDomDriver; | |
31 | import com.thoughtworks.xstream.io.xml.KXml2DomDriver; | |
32 | import com.thoughtworks.xstream.io.xml.KXml2Driver; | |
33 | import com.thoughtworks.xstream.io.xml.StaxDriver; | |
34 | import com.thoughtworks.xstream.io.xml.WstxDriver; | |
35 | import com.thoughtworks.xstream.io.xml.XomDriver; | |
36 | import com.thoughtworks.xstream.io.xml.XppDomDriver; | |
37 | import com.thoughtworks.xstream.io.xml.XppDriver; | |
38 | ||
21 | 39 | import junit.framework.Assert; |
40 | import junit.framework.AssertionFailedError; | |
22 | 41 | import junit.framework.Test; |
23 | 42 | import junit.framework.TestCase; |
24 | 43 | import junit.framework.TestSuite; |
25 | ||
26 | import com.bea.xml.stream.MXParserFactory; | |
27 | import com.thoughtworks.acceptance.objects.StandardObject; | |
28 | import com.thoughtworks.xstream.XStream; | |
29 | import com.thoughtworks.xstream.io.HierarchicalStreamDriver; | |
30 | import com.thoughtworks.xstream.io.xml.Dom4JDriver; | |
31 | import com.thoughtworks.xstream.io.xml.DomDriver; | |
32 | import com.thoughtworks.xstream.io.xml.JDomDriver; | |
33 | import com.thoughtworks.xstream.io.xml.StaxDriver; | |
34 | import com.thoughtworks.xstream.io.xml.XomDriver; | |
35 | import com.thoughtworks.xstream.io.xml.XppDomDriver; | |
36 | import com.thoughtworks.xstream.io.xml.XppDriver; | |
37 | 44 | |
38 | 45 | |
39 | 46 | /** |
52 | 59 | addDriverTest(new Dom4JDriver()); |
53 | 60 | addDriverTest(new DomDriver()); |
54 | 61 | addDriverTest(new JDomDriver()); |
62 | if (JVM.is15()) { | |
63 | final Class driverType = JVM.loadClassForName("com.thoughtworks.xstream.io.xml.JDom2Driver"); | |
64 | try { | |
65 | addDriverTest((HierarchicalStreamDriver)driverType.newInstance()); | |
66 | } catch (final InstantiationException e) { | |
67 | throw new AssertionFailedError("Cannot instantiate " + driverType.getName()); | |
68 | } catch (final IllegalAccessException e) { | |
69 | throw new AssertionFailedError("Cannot access default constructor of " + driverType.getName()); | |
70 | } | |
71 | } | |
55 | 72 | addDriverTest(new StaxDriver()); |
73 | if (File.separatorChar == '\\') { // see comment below for Windows | |
74 | if (JVM.is16()) { | |
75 | final Class driverType = JVM.loadClassForName("com.thoughtworks.xstream.io.xml.StandardStaxDriver"); | |
76 | try { | |
77 | addDriverTest((HierarchicalStreamDriver)driverType.newInstance()); | |
78 | } catch (final InstantiationException e) { | |
79 | throw new AssertionFailedError("Cannot instantiate " + driverType.getName()); | |
80 | } catch (final IllegalAccessException e) { | |
81 | throw new AssertionFailedError("Cannot access default constructor of " + driverType.getName()); | |
82 | } | |
83 | } | |
84 | addDriverTest(new BEAStaxDriver()); | |
85 | addDriverTest(new WstxDriver()); | |
86 | } | |
87 | addDriverTest(new KXml2DomDriver()); | |
88 | addDriverTest(new KXml2Driver()); | |
56 | 89 | addDriverTest(new XppDomDriver()); |
57 | 90 | addDriverTest(new XppDriver()); |
58 | 91 | addDriverTest(new XomDriver()); |
59 | 92 | } |
60 | 93 | |
61 | private void test(HierarchicalStreamDriver driver, String encoding) throws IOException { | |
62 | String headerLine = encoding != null | |
63 | ? ("<?xml version=\"1.0\" encoding=\"" + encoding + "\"?>\n") | |
64 | : ""; | |
65 | String xmlData = headerLine // force code format | |
94 | private void test(final HierarchicalStreamDriver driver, final String encoding) throws IOException { | |
95 | final String headerLine = encoding != null ? "<?xml version=\"1.0\" encoding=\"" + encoding + "\"?>\n" : ""; | |
96 | final String xmlData = headerLine // force code format | |
66 | 97 | + "<test>\n" |
67 | 98 | + " <data>J\u00f6rg</data>\n" |
68 | 99 | + "</test>"; |
69 | 100 | |
70 | XStream xstream = new XStream(driver); | |
101 | final XStream xstream = new XStream(driver); | |
102 | XStream.setupDefaultSecurity(xstream); | |
103 | xstream.allowTypesByWildcard(new String[] {getClass().getName()+"$*"}); | |
71 | 104 | xstream.alias("test", TestObject.class); |
72 | TestObject obj = new TestObject(); | |
105 | final TestObject obj = new TestObject(); | |
73 | 106 | obj.data = "J\u00f6rg"; |
74 | 107 | |
75 | ByteArrayOutputStream bos = new ByteArrayOutputStream(); | |
76 | OutputStreamWriter writer = encoding != null | |
108 | final ByteArrayOutputStream bos = new ByteArrayOutputStream(); | |
109 | final OutputStreamWriter writer = encoding != null | |
77 | 110 | ? new OutputStreamWriter(bos, encoding) |
78 | 111 | : new OutputStreamWriter(bos); |
79 | 112 | xstream.toXML(obj, writer); |
80 | 113 | writer.close(); |
81 | 114 | |
82 | String generated = encoding != null ? bos.toString(encoding) : bos.toString(); | |
115 | final String generated = encoding != null ? bos.toString(encoding) : bos.toString(); | |
83 | 116 | Assert.assertTrue("'" + obj.data + "' was not found", generated.indexOf(obj.data) > 0); |
84 | 117 | |
85 | Object restored = xstream.fromXML(new ByteArrayInputStream(encoding != null ? xmlData | |
86 | .getBytes(encoding) : xmlData.getBytes())); | |
118 | final Object restored = xstream.fromXML(new ByteArrayInputStream(encoding != null | |
119 | ? xmlData.getBytes(encoding) | |
120 | : xmlData.getBytes())); | |
87 | 121 | Assert.assertEquals(obj, restored); |
88 | 122 | } |
89 | 123 | |
90 | 124 | private void addDriverTest(final HierarchicalStreamDriver driver) { |
91 | String testName = getShortName(driver); | |
125 | final String testName = getShortName(driver); | |
92 | 126 | final String allEncodingTests = System.getProperty("xstream.test.encoding.all"); |
93 | 127 | if ("true".equals(allEncodingTests)) { |
94 | 128 | // Native encoding normally fails on most systems!! |
106 | 140 | try { |
107 | 141 | // Use BEA reference implementation for StAX |
108 | 142 | // (Woodstox will fail on Windows because of unknown system encoding) |
109 | System.setProperty( | |
110 | XMLInputFactory.class.getName(), MXParserFactory.class.getName()); | |
143 | System.setProperty(XMLInputFactory.class.getName(), MXParserFactory.class.getName()); | |
111 | 144 | test(driver, systemEncoding); |
112 | 145 | } finally { |
113 | 146 | System.setProperties(systemProperties); |
127 | 160 | }); |
128 | 161 | } |
129 | 162 | |
130 | private String getShortName(HierarchicalStreamDriver driver) { | |
163 | private String getShortName(final HierarchicalStreamDriver driver) { | |
131 | 164 | String result = driver.getClass().getName(); |
132 | 165 | result = result.substring(result.lastIndexOf('.') + 1); |
133 | 166 | return result; |
108 | 108 | " <principals>\n" + |
109 | 109 | " <javax.security.auth.x500.X500Principal serialization=\"custom\">\n" + |
110 | 110 | " <javax.security.auth.x500.X500Principal>\n" + |
111 | " <byte-array>MDYxEDAOBgNVBAsTB1hTdHJlYW0xFTATBgNVBAoTDFRob3VnaHR3b3JrczELMAkGA1UEBhMCdWs=\n</byte-array>\n" + | |
111 | " <byte-array>MDYxEDAOBgNVBAsTB1hTdHJlYW0xFTATBgNVBAoTDFRob3VnaHR3b3JrczELMAkGA1UEBhMCdWs=</byte-array>\n" + | |
112 | 112 | " </javax.security.auth.x500.X500Principal>\n" + |
113 | 113 | " </javax.security.auth.x500.X500Principal>\n" + |
114 | 114 | " </principals>\n" + |
9 | 9 | */ |
10 | 10 | package com.thoughtworks.acceptance; |
11 | 11 | |
12 | import java.io.File; | |
12 | 13 | import java.io.IOException; |
13 | 14 | import java.net.URI; |
14 | 15 | import java.nio.file.FileSystem; |
37 | 38 | assertBothWays(Paths.get("../a/relative/path"), "<path>../a/relative/path</path>"); |
38 | 39 | assertBothWays(Paths.get("/an/absolute/path"), "<path>/an/absolute/path</path>"); |
39 | 40 | |
40 | final String absolutePathName = Paths.get("target").toAbsolutePath().toString(); | |
41 | final URI uri = URI.create("file://" + absolutePathName); | |
42 | assertBothWays(Paths.get(uri), "<path>" + absolutePathName + "</path>"); | |
41 | final Path absolutePath = Paths.get("target").toAbsolutePath(); | |
42 | String absolutePathName = absolutePath.toString(); | |
43 | if (File.separatorChar != '/') { | |
44 | absolutePathName = absolutePathName.replace(File.separatorChar, '/'); | |
45 | } | |
46 | final Path path = Paths.get(absolutePath.toUri()); | |
47 | assertBothWays(path, "<path>" + absolutePathName + "</path>"); | |
48 | } | |
49 | ||
50 | public void testPathWithSpecialCharacters() { | |
51 | assertBothWays(Paths.get("with space"), "<path>with space</path>"); | |
52 | assertBothWays(Paths.get("with+plus"), "<path>with+plus</path>"); | |
53 | assertBothWays(Paths.get("with&ersand"), "<path>with&ampersand</path>"); | |
54 | assertBothWays(Paths.get("with%20encoding"), "<path>with%20encoding</path>"); | |
43 | 55 | } |
44 | 56 | |
45 | 57 | public void testPathOfNonDefaultFileSystem() throws IOException { |
46 | 58 | final Map<String, String> env = new HashMap<String, String>(); |
47 | 59 | env.put("create", "true"); |
48 | final URI uri = URI.create("jar:file://" | |
49 | + Paths.get("target/lib/proxytoys-0.2.1.jar").toAbsolutePath().toString()); | |
60 | final URI uri = URI.create("jar:" | |
61 | + Paths.get("target/lib/proxytoys-0.2.1.jar").toAbsolutePath().toUri().toString()); | |
50 | 62 | |
51 | 63 | FileSystem zipfs = null; |
52 | 64 | try { |
60 | 72 | } |
61 | 73 | } |
62 | 74 | } |
75 | ||
76 | public void testPathIsImmutable() { | |
77 | Path[] array = new Path[2]; | |
78 | array[0] = array[1] = Paths.get("same"); | |
79 | assertBothWays(array, "" // | |
80 | + "<path-array>\n" // | |
81 | + " <path>same</path>\n" // | |
82 | + " <path>same</path>\n" // | |
83 | + "</path-array>"); | |
84 | } | |
63 | 85 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2012, 2014 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2012, 2014, 2016 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.acceptance; |
12 | 12 | |
13 | import com.thoughtworks.xstream.converters.extended.SqlTimestampConverter; | |
13 | 14 | import com.thoughtworks.xstream.core.JVM; |
14 | 15 | import com.thoughtworks.xstream.testutil.TimeZoneChanger; |
15 | 16 | |
22 | 23 | import java.sql.Time; |
23 | 24 | import java.sql.Timestamp; |
24 | 25 | import java.util.Locale; |
26 | import java.util.TimeZone; | |
25 | 27 | |
26 | 28 | public class ExtendedTypesTest extends AbstractAcceptanceTest { |
27 | 29 | |
59 | 61 | } |
60 | 62 | |
61 | 63 | public void testSqlTimestamp() { |
64 | assertBothWays(new Timestamp(1000), | |
65 | "<sql-timestamp>1970-01-01 00:00:01</sql-timestamp>"); | |
66 | } | |
67 | ||
68 | public void testSqlTimestampWithFraction() { | |
62 | 69 | Timestamp timestamp = new Timestamp(1234); |
63 | 70 | timestamp.setNanos(78900); |
64 | 71 | assertBothWays(timestamp, |
65 | 72 | "<sql-timestamp>1970-01-01 00:00:01.0000789</sql-timestamp>"); |
73 | } | |
74 | ||
75 | public void testSqlTimestampWithLocalTimeZone() { | |
76 | xstream.registerConverter(new SqlTimestampConverter(TimeZone.getDefault())); | |
77 | Timestamp timestamp = new Timestamp(1234); | |
78 | timestamp.setNanos(78900); | |
79 | assertBothWays(timestamp, | |
80 | "<sql-timestamp>"+timestamp.toString()+"</sql-timestamp>"); | |
66 | 81 | } |
67 | 82 | |
68 | 83 | public void testSqlTime() { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
13 | 13 | import com.thoughtworks.acceptance.objects.Software; |
14 | 14 | import com.thoughtworks.acceptance.objects.StandardObject; |
15 | 15 | import com.thoughtworks.xstream.MarshallingStrategy; |
16 | import com.thoughtworks.xstream.converters.ConversionException; | |
16 | 17 | import com.thoughtworks.xstream.converters.ConverterLookup; |
17 | 18 | import com.thoughtworks.xstream.converters.DataHolder; |
18 | 19 | import com.thoughtworks.xstream.core.ReferenceByIdMarshaller; |
19 | 20 | import com.thoughtworks.xstream.core.ReferenceByIdUnmarshaller; |
20 | 21 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
21 | 22 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; |
23 | import com.thoughtworks.xstream.io.ReaderWrapper; | |
22 | 24 | import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; |
25 | import com.thoughtworks.xstream.io.xml.Xpp3Driver; | |
23 | 26 | import com.thoughtworks.xstream.io.xml.XppReader; |
24 | 27 | import com.thoughtworks.xstream.mapper.Mapper; |
25 | 28 | import com.thoughtworks.xstream.testutil.CallLog; |
175 | 178 | } |
176 | 179 | } |
177 | 180 | |
181 | private static class LevelTrackingReader extends ReaderWrapper { | |
182 | private int level; | |
183 | protected LevelTrackingReader(HierarchicalStreamReader reader) { | |
184 | super(reader); | |
185 | } | |
186 | ||
187 | public void moveDown() { | |
188 | ++level; | |
189 | super.moveDown(); | |
190 | } | |
191 | ||
192 | public void moveUp() { | |
193 | super.moveUp(); | |
194 | --level; | |
195 | } | |
196 | ||
197 | public int getLevel() { | |
198 | return level; | |
199 | } | |
200 | } | |
201 | ||
202 | public void testFailSafeDeserialization() throws IOException, ClassNotFoundException { | |
203 | final String xml = "" | |
204 | + "<object-stream>\n" | |
205 | + " <string>top</string>\n" | |
206 | + " <list>\n" | |
207 | + " <string>first</string>\n" | |
208 | + " <int-array>\n" | |
209 | + " <int>1</int>\n" | |
210 | + " <int>invalid</int>\n" // deserialization will fail here | |
211 | + " <int>3</int>\n" | |
212 | + " </int-array>\n" | |
213 | + " <string>last</string>\n" | |
214 | + " </list>\n" | |
215 | + " <string>bottom</string>\n" | |
216 | + "</object-stream>"; | |
217 | ||
218 | final LevelTrackingReader reader = new LevelTrackingReader(new Xpp3Driver().createReader(new StringReader(xml))); | |
219 | final ObjectInputStream ois = xstream.createObjectInputStream(reader); | |
220 | final int level = reader.getLevel(); | |
221 | assertEquals("top", ois.readObject()); | |
222 | try { | |
223 | ois.readObject(); | |
224 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
225 | } catch (final ConversionException e) { | |
226 | assertEquals(3, reader.getLevel() - level); | |
227 | do { | |
228 | reader.moveUp(); | |
229 | } while (level != reader.getLevel()); | |
230 | } | |
231 | assertEquals("bottom", ois.readObject()); | |
232 | ois.close(); | |
233 | } | |
234 | ||
178 | 235 | public void testObjectOutputStreamPropagatesCloseAndFlushEvents() throws IOException { |
179 | 236 | // setup |
180 | 237 | final CallLog log = new CallLog(); |
302 | 359 | |
303 | 360 | assertSame(alice, jane.secretary); |
304 | 361 | } |
362 | ||
363 | public void testReadUnsignedValuesFromInputStream() throws IOException { | |
364 | final Writer writer = new StringWriter(); | |
365 | final ObjectOutputStream oos = xstream.createObjectOutputStream(writer); | |
366 | oos.writeByte(1); | |
367 | oos.writeByte(-1); | |
368 | oos.writeByte(Byte.MIN_VALUE); | |
369 | oos.writeShort(1); | |
370 | oos.writeShort(-1); | |
371 | oos.writeShort(Short.MIN_VALUE); | |
372 | oos.close(); | |
373 | ||
374 | final String expectedXml = "" | |
375 | + "<object-stream>\n" | |
376 | + " <byte>1</byte>\n" | |
377 | + " <byte>-1</byte>\n" | |
378 | + " <byte>-128</byte>\n" | |
379 | + " <short>1</short>\n" | |
380 | + " <short>-1</short>\n" | |
381 | + " <short>-32768</short>\n" | |
382 | + "</object-stream>"; | |
383 | ||
384 | assertEquals(expectedXml, writer.toString()); | |
385 | ||
386 | final ObjectInputStream ois = xstream.createObjectInputStream(new StringReader(writer.toString())); | |
387 | assertEquals(1, ois.readUnsignedByte()); | |
388 | assertEquals(255, ois.readUnsignedByte()); | |
389 | assertEquals(128, ois.readUnsignedByte()); | |
390 | assertEquals(1, ois.readUnsignedShort()); | |
391 | assertEquals(65535, ois.readUnsignedShort()); | |
392 | assertEquals(32768, ois.readUnsignedShort()); | |
393 | ||
394 | ois.close(); | |
395 | } | |
305 | 396 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2010, 2012, 2013, 2014 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2010, 2012, 2013, 2014, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
15 | 15 | import com.thoughtworks.xstream.converters.ConversionException; |
16 | 16 | import com.thoughtworks.xstream.mapper.Mapper; |
17 | 17 | import com.thoughtworks.xstream.mapper.MapperWrapper; |
18 | import com.thoughtworks.xstream.security.NoTypePermission; | |
18 | 19 | |
19 | 20 | |
20 | 21 | public class OmitFieldsTest extends AbstractAcceptanceTest { |
162 | 163 | return new OmitFieldsWithMyPrefixMapper(next); |
163 | 164 | } |
164 | 165 | }; |
166 | xstream.addPermission(NoTypePermission.NONE); // clear out defaults | |
165 | 167 | |
166 | 168 | xstream.allowTypes(new Class[]{AnotherThing.class}); |
167 | 169 | xstream.alias("thing", AnotherThing.class); |
0 | 0 | /* |
1 | * Copyright (C) 2006, 2007, 2009, 2010, 2013, 2015 XStream Committers. | |
1 | * Copyright (C) 2006, 2007, 2009, 2010, 2013, 2015, 2016, 2017 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
179 | 179 | sm.addPermission(source, new PropertyPermission("jdk.util.TimeZone.allowSetDefault", "read")); |
180 | 180 | sm.addPermission(source, new PropertyPermission("jdk.xml.elementAttributeLimit", "read")); |
181 | 181 | sm.addPermission(source, new PropertyPermission("jdk.xml.entityExpansionLimit", "read")); |
182 | sm.addPermission(source, new PropertyPermission("jdk.xml.entityReplacementLimit", "read")); | |
182 | 183 | sm.addPermission(source, new PropertyPermission("jdk.xml.maxElementDepth", "read")); |
183 | 184 | sm.addPermission(source, new PropertyPermission("jdk.xml.maxGeneralEntitySizeLimit", "read")); |
184 | 185 | sm.addPermission(source, new PropertyPermission("jdk.xml.maxParameterEntitySizeLimit", "read")); |
203 | 204 | } |
204 | 205 | |
205 | 206 | private void assertBothWays() { |
206 | ||
207 | XStream.setupDefaultSecurity(xstream); | |
208 | xstream.allowTypesByWildcard(new String[] {"com.thoughtworks.acceptance.objects.*"}); | |
207 | 209 | xstream.alias("software", Software.class); |
208 | 210 | |
209 | 211 | final Software sw = new Software("jw", "xstr"); |
0 | 0 | /* |
1 | * Copyright (C) 2013, 2014 XStream Committers. | |
1 | * Copyright (C) 2013, 2014, 2017, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
11 | 11 | |
12 | 12 | import java.beans.EventHandler; |
13 | 13 | |
14 | import com.thoughtworks.xstream.XStream; | |
14 | 15 | import com.thoughtworks.xstream.XStreamException; |
16 | import com.thoughtworks.xstream.converters.ConversionException; | |
15 | 17 | import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; |
18 | import com.thoughtworks.xstream.security.ForbiddenClassException; | |
16 | 19 | import com.thoughtworks.xstream.security.ProxyTypePermission; |
20 | ||
17 | 21 | |
18 | 22 | /** |
19 | 23 | * @author Jörg Schaible |
26 | 30 | super.setUp(); |
27 | 31 | BUFFER.setLength(0); |
28 | 32 | xstream.alias("runnable", Runnable.class); |
29 | xstream.allowTypes(new Class[]{EventHandler.class}); | |
30 | 33 | xstream.allowTypeHierarchy(Runnable.class); |
31 | 34 | xstream.addPermission(ProxyTypePermission.PROXIES); |
32 | 35 | } |
52 | 55 | assertEquals(0, BUFFER.length()); |
53 | 56 | } |
54 | 57 | |
58 | public void testCannotInjectEventHandlerWithUnconfiguredSecurityFramework() { | |
59 | xstream = new XStream(createDriver()); | |
60 | xstream.alias("runnable", Runnable.class); | |
61 | final String xml = "" | |
62 | + "<string class='runnable-array'>\n" | |
63 | + " <dynamic-proxy>\n" | |
64 | + " <interface>java.lang.Runnable</interface>\n" | |
65 | + " <handler class='java.beans.EventHandler'>\n" | |
66 | + " <target class='com.thoughtworks.acceptance.SecurityVulnerabilityTest$Exec'/>\n" | |
67 | + " <action>exec</action>\n" | |
68 | + " </handler>\n" | |
69 | + " </dynamic-proxy>\n" | |
70 | + "</string>"; | |
71 | ||
72 | try { | |
73 | xstream.fromXML(xml); | |
74 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
75 | } catch (final XStreamException e) { | |
76 | assertTrue(e.getMessage().indexOf(EventHandler.class.getName())>=0); | |
77 | } | |
78 | assertEquals(0, BUFFER.length()); | |
79 | } | |
80 | ||
55 | 81 | public void testExplicitlyConvertEventHandler() { |
56 | 82 | final String xml = "" |
57 | 83 | + "<string class='runnable-array'>\n" |
64 | 90 | + " </dynamic-proxy>\n" |
65 | 91 | + "</string>"; |
66 | 92 | |
93 | xstream.allowTypes(new Class[]{EventHandler.class}); | |
67 | 94 | xstream.registerConverter(new ReflectionConverter(xstream.getMapper(), xstream |
68 | 95 | .getReflectionProvider(), EventHandler.class)); |
69 | 96 | |
79 | 106 | BUFFER.append("Executed!"); |
80 | 107 | } |
81 | 108 | } |
109 | ||
110 | public void testDeniedInstanceOfVoid() { | |
111 | try { | |
112 | xstream.fromXML("<void/>"); | |
113 | fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); | |
114 | } catch (final ForbiddenClassException e) { | |
115 | // OK | |
116 | } | |
117 | } | |
118 | ||
119 | public void testAllowedInstanceOfVoid() { | |
120 | xstream.allowTypes(new Class[] { void.class, Void.class }); | |
121 | try { | |
122 | xstream.fromXML("<void/>"); | |
123 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
124 | } catch (final ConversionException e) { | |
125 | assertEquals("void", e.get("required-type")); | |
126 | } | |
127 | } | |
82 | 128 | } |
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 13. January 2017 by Matej Cimbora | |
9 | */ | |
10 | package com.thoughtworks.acceptance; | |
11 | ||
12 | import java.time.Clock; | |
13 | import java.time.DayOfWeek; | |
14 | import java.time.Duration; | |
15 | import java.time.Instant; | |
16 | import java.time.LocalDate; | |
17 | import java.time.LocalDateTime; | |
18 | import java.time.LocalTime; | |
19 | import java.time.Month; | |
20 | import java.time.MonthDay; | |
21 | import java.time.OffsetDateTime; | |
22 | import java.time.OffsetTime; | |
23 | import java.time.Period; | |
24 | import java.time.Year; | |
25 | import java.time.YearMonth; | |
26 | import java.time.ZoneId; | |
27 | import java.time.ZoneOffset; | |
28 | import java.time.ZonedDateTime; | |
29 | import java.time.chrono.Chronology; | |
30 | import java.time.chrono.HijrahChronology; | |
31 | import java.time.chrono.HijrahDate; | |
32 | import java.time.chrono.HijrahEra; | |
33 | import java.time.chrono.IsoChronology; | |
34 | import java.time.chrono.JapaneseChronology; | |
35 | import java.time.chrono.JapaneseDate; | |
36 | import java.time.chrono.JapaneseEra; | |
37 | import java.time.chrono.MinguoChronology; | |
38 | import java.time.chrono.MinguoDate; | |
39 | import java.time.chrono.MinguoEra; | |
40 | import java.time.chrono.ThaiBuddhistChronology; | |
41 | import java.time.chrono.ThaiBuddhistDate; | |
42 | import java.time.chrono.ThaiBuddhistEra; | |
43 | import java.time.temporal.ChronoField; | |
44 | import java.time.temporal.ChronoUnit; | |
45 | import java.time.temporal.IsoFields; | |
46 | import java.time.temporal.JulianFields; | |
47 | import java.time.temporal.TemporalField; | |
48 | import java.time.temporal.ValueRange; | |
49 | import java.time.temporal.WeekFields; | |
50 | ||
51 | import com.thoughtworks.xstream.XStream; | |
52 | import com.thoughtworks.xstream.converters.ConversionException; | |
53 | ||
54 | ||
55 | /** | |
56 | * Test types of java.time.* package. | |
57 | * | |
58 | * @author Matej Cimbora | |
59 | * @author Jörg Schaible | |
60 | */ | |
61 | public class Time18TypesTest extends AbstractAcceptanceTest { | |
62 | ||
63 | @Override | |
64 | protected void setupSecurity(XStream xstream) { | |
65 | super.setupSecurity(xstream); | |
66 | xstream.allowTypesByWildcard(new String[]{ "java.time.**" }); | |
67 | } | |
68 | ||
69 | public void testFixedClock() { | |
70 | assertBothWays(Clock.fixed(Instant.parse("2017-02-15T18:49:25Z"), ZoneOffset.of("Z")), "" // | |
71 | + "<fixed-clock>\n" // | |
72 | + " <instant>2017-02-15T18:49:25Z</instant>\n" // | |
73 | + " <zone>Z</zone>\n" // | |
74 | + "</fixed-clock>"); | |
75 | } | |
76 | ||
77 | public void testOffsetClock() { | |
78 | assertBothWays(Clock.offset(Clock.systemUTC(), Duration.ofHours(1)), "" // | |
79 | + "<offset-clock>\n" // | |
80 | + " <baseClock class=\"system-clock\">\n" // | |
81 | + " <zone>Z</zone>\n" // | |
82 | + " </baseClock>\n" // | |
83 | + " <offset>PT1H</offset>\n" // | |
84 | + "</offset-clock>"); | |
85 | } | |
86 | ||
87 | public void testSystemClock() { | |
88 | assertBothWays(Clock.systemUTC(), "" // | |
89 | + "<system-clock>\n" // | |
90 | + " <zone>Z</zone>\n" // | |
91 | + "</system-clock>"); | |
92 | assertBothWays(Clock.system(ZoneId.of("Europe/Berlin")), "" // | |
93 | + "<system-clock>\n" // | |
94 | + " <zone>Europe/Berlin</zone>\n" // | |
95 | + "</system-clock>"); | |
96 | } | |
97 | ||
98 | public void testTickClock() { | |
99 | assertBothWays(Clock.tick(Clock.systemUTC(), Duration.ofMillis(42)), "" // | |
100 | + "<tick-clock>\n" // | |
101 | + " <baseClock class=\"system-clock\">\n" // | |
102 | + " <zone>Z</zone>\n" // | |
103 | + " </baseClock>\n" // | |
104 | + " <tickNanos>42000000</tickNanos>\n" // | |
105 | + "</tick-clock>"); | |
106 | } | |
107 | ||
108 | public void testDuration() { | |
109 | assertBothWays(Duration.ofDays(1000), "<duration>PT24000H</duration>"); | |
110 | assertBothWays(Duration.ofHours(50), "<duration>PT50H</duration>"); | |
111 | assertBothWays(Duration.ofMinutes(77), "<duration>PT1H17M</duration>"); | |
112 | assertBothWays(Duration.ofSeconds(55), "<duration>PT55S</duration>"); | |
113 | assertBothWays(Duration.ofMillis(4444), "<duration>PT4.444S</duration>"); | |
114 | assertBothWays(Duration.ofNanos(123456789), "<duration>PT0.123456789S</duration>"); | |
115 | assertBothWays(Duration.ofNanos(100000000), "<duration>PT0.1S</duration>"); | |
116 | assertBothWays(Duration.ofNanos(9), "<duration>PT0.000000009S</duration>"); | |
117 | assertBothWays(Duration.ofNanos(6333123456789L), "<duration>PT1H45M33.123456789S</duration>"); | |
118 | assertBothWays(Duration.ofSeconds(-3), "<duration>PT-3S</duration>"); | |
119 | assertBothWays(Duration.ofSeconds(-30001), "<duration>PT-8H-20M-1S</duration>"); | |
120 | } | |
121 | ||
122 | public void testDurationConversionExceptionContainsInvalidValue() { | |
123 | try { | |
124 | xstream.fromXML("<duration>PT77XS</duration>"); | |
125 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
126 | } catch (final ConversionException e) { | |
127 | assertEquals(Duration.class.getName(), e.get("class")); | |
128 | assertEquals("PT77XS", e.get("value")); | |
129 | } | |
130 | } | |
131 | ||
132 | public void testDurationWithOldFormat() { | |
133 | assertEquals(Duration.ofSeconds(7777), xstream.fromXML("" // | |
134 | + "<java.time.Duration resolves-to=\"java.time.Ser\">\n" // | |
135 | + " <byte>1</byte>\n" // | |
136 | + " <long>7777</long>\n" // | |
137 | + " <int>0</int>\n" // | |
138 | + "</java.time.Duration>")); | |
139 | } | |
140 | ||
141 | public void testDurationIsImmutable() { | |
142 | final Duration[] array = new Duration[2]; | |
143 | array[0] = array[1] = Duration.ofHours(50); | |
144 | assertBothWays(array, "" // | |
145 | + "<duration-array>\n" // | |
146 | + " <duration>PT50H</duration>\n" // | |
147 | + " <duration>PT50H</duration>\n" // | |
148 | + "</duration-array>"); | |
149 | } | |
150 | ||
151 | public void testInstant() { | |
152 | assertBothWays(Instant.from(ZonedDateTime.of(2017, 7, 30, 20, 40, 0, 0, ZoneOffset.of("Z"))), | |
153 | "<instant>2017-07-30T20:40:00Z</instant>"); | |
154 | assertBothWays(Instant.from(ZonedDateTime.of(2017, 7, 30, 20, 40, 0, 0, ZoneId.of("Europe/London"))), | |
155 | "<instant>2017-07-30T19:40:00Z</instant>"); | |
156 | assertBothWays(Instant.from(ZonedDateTime.of(2017, 7, 30, 20, 40, 0, 0, ZoneId.of("Europe/Paris"))), | |
157 | "<instant>2017-07-30T18:40:00Z</instant>"); | |
158 | assertBothWays(Instant.from(ZonedDateTime.of(2017, 7, 30, 20, 40, 0, 123456789, ZoneOffset.of("Z"))), | |
159 | "<instant>2017-07-30T20:40:00.123456789Z</instant>"); | |
160 | assertBothWays(Instant.from(ZonedDateTime.of(2017, 7, 30, 20, 40, 0, 100000000, ZoneOffset.of("Z"))), | |
161 | "<instant>2017-07-30T20:40:00.100Z</instant>"); | |
162 | assertBothWays(Instant.from(ZonedDateTime.of(2017, 7, 30, 20, 40, 0, 100000, ZoneOffset.of("Z"))), | |
163 | "<instant>2017-07-30T20:40:00.000100Z</instant>"); | |
164 | assertBothWays(Instant.from(ZonedDateTime.of(2017, 7, 30, 20, 40, 0, 1000, ZoneOffset.of("Z"))), | |
165 | "<instant>2017-07-30T20:40:00.000001Z</instant>"); | |
166 | assertBothWays(Instant.from(ZonedDateTime.of(2017, 7, 30, 20, 40, 0, 100, ZoneOffset.of("Z"))), | |
167 | "<instant>2017-07-30T20:40:00.000000100Z</instant>"); | |
168 | } | |
169 | ||
170 | public void testInstantConversionExceptionContainsInvalidValue() { | |
171 | try { | |
172 | xstream.fromXML("<instant>2017-07-30X20:40:00Z</instant>"); | |
173 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
174 | } catch (final ConversionException e) { | |
175 | assertEquals(Instant.class.getName(), e.get("class")); | |
176 | assertEquals("2017-07-30X20:40:00Z", e.get("value")); | |
177 | } | |
178 | } | |
179 | ||
180 | public void testInstantWithOldFormat() { | |
181 | assertEquals(Instant.parse("2017-02-15T18:49:25Z"), xstream.fromXML("" // | |
182 | + "<java.time.Instant resolves-to=\"java.time.Ser\">\n" // | |
183 | + " <byte>2</byte>\n" // | |
184 | + " <long>1487184565</long>\n" // | |
185 | + " <int>0</int>\n" // | |
186 | + "</java.time.Instant>")); | |
187 | } | |
188 | ||
189 | public void testInstantIsImmutable() { | |
190 | final Instant[] array = new Instant[2]; | |
191 | array[0] = array[1] = Instant.from(ZonedDateTime.of(2017, 7, 30, 20, 40, 0, 0, ZoneOffset.of("Z"))); | |
192 | assertBothWays(array, "" // | |
193 | + "<instant-array>\n" // | |
194 | + " <instant>2017-07-30T20:40:00Z</instant>\n" // | |
195 | + " <instant>2017-07-30T20:40:00Z</instant>\n" // | |
196 | + "</instant-array>"); | |
197 | } | |
198 | ||
199 | public void testPeriod() { | |
200 | assertBothWays(Period.ofDays(1000), "<period>P1000D</period>"); | |
201 | assertBothWays(Period.ofWeeks(70), "<period>P490D</period>"); | |
202 | assertBothWays(Period.ofMonths(70), "<period>P70M</period>"); | |
203 | assertBothWays(Period.ofYears(2017), "<period>P2017Y</period>"); | |
204 | assertBothWays(Period.of(-5, 70, -45), "<period>P-5Y70M-45D</period>"); | |
205 | assertBothWays(Period.ofYears(0), "<period>P0D</period>"); | |
206 | assertBothWays(Period.of(1, 0, 2), "<period>P1Y2D</period>"); | |
207 | assertEquals(Period.ofDays(21), xstream.fromXML("<period>P3W</period>")); | |
208 | } | |
209 | ||
210 | public void testPeriodConversionExceptionContainsInvalidValue() { | |
211 | try { | |
212 | xstream.fromXML("<period>P1YXD</period>"); | |
213 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
214 | } catch (final ConversionException e) { | |
215 | assertEquals(Period.class.getName(), e.get("class")); | |
216 | assertEquals("P1YXD", e.get("period")); | |
217 | } | |
218 | } | |
219 | ||
220 | public void testPeriodWithOldFormat() { | |
221 | assertEquals(Period.ofDays(7777), xstream.fromXML("" // | |
222 | + "<java.time.Period resolves-to=\"java.time.Ser\">\n" // | |
223 | + " <byte>14</byte>\n" // | |
224 | + " <int>0</int>\n" // | |
225 | + " <int>0</int>\n" // | |
226 | + " <int>7777</int>\n" // | |
227 | + "</java.time.Period>")); | |
228 | } | |
229 | ||
230 | public void testPeriodIsImmutable() { | |
231 | final Period[] array = new Period[2]; | |
232 | array[0] = array[1] = Period.ofDays(1); | |
233 | assertBothWays(array, "" // | |
234 | + "<period-array>\n" // | |
235 | + " <period>P1D</period>\n" // | |
236 | + " <period>P1D</period>\n" // | |
237 | + "</period-array>"); | |
238 | } | |
239 | ||
240 | public void testLocalDate() { | |
241 | assertBothWays(LocalDate.of(2017, 10, 30), "<local-date>2017-10-30</local-date>"); | |
242 | } | |
243 | ||
244 | public void testLocalDateConversionExceptionContainsInvalidValue() { | |
245 | try { | |
246 | xstream.fromXML("<local-date>2017-13-30</local-date>"); | |
247 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
248 | } catch (final ConversionException e) { | |
249 | assertEquals(LocalDate.class.getName(), e.get("class")); | |
250 | assertEquals("2017-13-30", e.get("value")); | |
251 | } | |
252 | } | |
253 | ||
254 | public void testLocalDateWithOldFormat() { | |
255 | assertEquals(LocalDate.of(2017, 10, 30), xstream.fromXML("" // | |
256 | + "<java.time.LocalDate resolves-to=\"java.time.Ser\">\n" // | |
257 | + " <byte>3</byte>\n" // | |
258 | + " <int>2017</int>\n" // | |
259 | + " <byte>10</byte>\n" // | |
260 | + " <byte>30</byte>\n" // | |
261 | + "</java.time.LocalDate>")); | |
262 | } | |
263 | ||
264 | public void testLocalDateIsImmutable() { | |
265 | final LocalDate[] array = new LocalDate[2]; | |
266 | array[0] = array[1] = LocalDate.of(2017, 10, 30); | |
267 | assertBothWays(array, "" // | |
268 | + "<local-date-array>\n" // | |
269 | + " <local-date>2017-10-30</local-date>\n" // | |
270 | + " <local-date>2017-10-30</local-date>\n" // | |
271 | + "</local-date-array>"); | |
272 | } | |
273 | ||
274 | public void testLocalDateTime() { | |
275 | assertBothWays(LocalDateTime.of(2017, 7, 30, 20, 40), "<local-date-time>2017-07-30T20:40:00</local-date-time>"); | |
276 | assertBothWays(LocalDateTime.of(2017, 10, 30, 20, 40, 15), | |
277 | "<local-date-time>2017-10-30T20:40:15</local-date-time>"); | |
278 | assertBothWays(LocalDateTime.of(2017, 10, 30, 20, 40, 15, 123456789), | |
279 | "<local-date-time>2017-10-30T20:40:15.123456789</local-date-time>"); | |
280 | assertBothWays(LocalDateTime.of(2017, 10, 30, 20, 40, 15, 9), | |
281 | "<local-date-time>2017-10-30T20:40:15.000000009</local-date-time>"); | |
282 | assertEquals(LocalDateTime.of(2017, 7, 30, 20, 40), xstream.fromXML( | |
283 | "<local-date-time>2017-07-30T20:40</local-date-time>")); | |
284 | } | |
285 | ||
286 | public void testLocalDateTimeConversionExceptionContainsInvalidValue() { | |
287 | try { | |
288 | xstream.fromXML("<local-date-time>2017-13-30T20:40:00</local-date-time>"); | |
289 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
290 | } catch (final ConversionException e) { | |
291 | assertEquals(LocalDateTime.class.getName(), e.get("class")); | |
292 | assertEquals("2017-13-30T20:40:00", e.get("value")); | |
293 | } | |
294 | } | |
295 | ||
296 | public void testLocalDateTimeWithOldFormat() { | |
297 | assertEquals(LocalDateTime.of(2017, 7, 30, 20, 40), xstream.fromXML("" // | |
298 | + "<java.time.LocalDateTime resolves-to=\"java.time.Ser\">\n" // | |
299 | + " <byte>5</byte>\n" // | |
300 | + " <int>2017</int>\n" // | |
301 | + " <byte>7</byte>\n" // | |
302 | + " <byte>30</byte>\n" // | |
303 | + " <byte>20</byte>\n" // | |
304 | + " <byte>-41</byte>\n" // | |
305 | + "</java.time.LocalDateTime>")); | |
306 | } | |
307 | ||
308 | public void testLocalDateTimeIsImmutable() { | |
309 | final LocalDateTime[] array = new LocalDateTime[2]; | |
310 | array[0] = array[1] = LocalDateTime.of(2017, 7, 30, 20, 40); | |
311 | assertBothWays(array, "" // | |
312 | + "<local-date-time-array>\n" // | |
313 | + " <local-date-time>2017-07-30T20:40:00</local-date-time>\n" // | |
314 | + " <local-date-time>2017-07-30T20:40:00</local-date-time>\n" // | |
315 | + "</local-date-time-array>"); | |
316 | } | |
317 | ||
318 | public void testLocalTime() { | |
319 | assertBothWays(LocalTime.of(10, 30), "<local-time>10:30:00</local-time>"); | |
320 | assertBothWays(LocalTime.of(10, 30, 20), "<local-time>10:30:20</local-time>"); | |
321 | assertBothWays(LocalTime.of(10, 30, 20, 123456789), "<local-time>10:30:20.123456789</local-time>"); | |
322 | assertBothWays(LocalTime.of(10, 30, 20, 9), "<local-time>10:30:20.000000009</local-time>"); | |
323 | assertBothWays(LocalTime.of(10, 30, 20, 1000000), "<local-time>10:30:20.001</local-time>"); | |
324 | assertBothWays(LocalTime.of(10, 30, 20, 100000000), "<local-time>10:30:20.1</local-time>"); | |
325 | assertEquals(LocalTime.of(10, 30), xstream.fromXML("<local-time>10:30</local-time>")); | |
326 | } | |
327 | ||
328 | public void testLocalTimeConversionExceptionContainsInvalidValue() { | |
329 | try { | |
330 | xstream.fromXML("<local-time>10:30:77</local-time>"); | |
331 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
332 | } catch (final ConversionException e) { | |
333 | assertEquals(LocalTime.class.getName(), e.get("class")); | |
334 | assertEquals("10:30:77", e.get("value")); | |
335 | } | |
336 | } | |
337 | ||
338 | public void testLocalTimeWithOldFormat() { | |
339 | assertEquals(LocalTime.of(10, 30), xstream.fromXML("" // | |
340 | + "<java.time.LocalTime resolves-to=\"java.time.Ser\">\n" // | |
341 | + " <byte>4</byte>\n" // | |
342 | + " <byte>10</byte>\n" // | |
343 | + " <byte>-31</byte>\n" // | |
344 | + "</java.time.LocalTime>")); | |
345 | } | |
346 | ||
347 | public void testLocalTimeIsImmutable() { | |
348 | final LocalTime array[] = new LocalTime[2]; | |
349 | array[0] = array[1] = LocalTime.of(10, 30); | |
350 | assertBothWays(array, "" // | |
351 | + "<local-time-array>\n" | |
352 | + " <local-time>10:30:00</local-time>\n" // | |
353 | + " <local-time>10:30:00</local-time>\n" // | |
354 | + "</local-time-array>"); | |
355 | } | |
356 | ||
357 | public void testDayOfWeek() { | |
358 | assertBothWays(DayOfWeek.MONDAY, "<day-of-week>MONDAY</day-of-week>"); | |
359 | } | |
360 | ||
361 | public void testMonth() { | |
362 | assertBothWays(Month.FEBRUARY, "<month>FEBRUARY</month>"); | |
363 | } | |
364 | ||
365 | public void testMonthDay() { | |
366 | assertBothWays(MonthDay.of(1, 13), "<month-day>--01-13</month-day>"); | |
367 | assertBothWays(MonthDay.of(2, 29), "<month-day>--02-29</month-day>"); | |
368 | } | |
369 | ||
370 | public void testMonthDayConversionExceptionContainsInvalidValue() { | |
371 | try { | |
372 | xstream.fromXML("<month-day>--00-13</month-day>"); | |
373 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
374 | } catch (final ConversionException e) { | |
375 | assertEquals(MonthDay.class.getName(), e.get("class")); | |
376 | assertEquals("--00-13", e.get("value")); | |
377 | } | |
378 | } | |
379 | ||
380 | public void testMonthDayWithOldFormat() { | |
381 | assertEquals(MonthDay.of(Month.JANUARY, 13), xstream.fromXML("" // | |
382 | + "<java.time.MonthDay resolves-to=\"java.time.Ser\">\n" // | |
383 | + " <byte>13</byte>\n" // | |
384 | + " <byte>1</byte>\n" // | |
385 | + " <byte>13</byte>\n" // | |
386 | + "</java.time.MonthDay>")); | |
387 | } | |
388 | ||
389 | public void testMonthDayIsImmutable() { | |
390 | final MonthDay array[] = new MonthDay[2]; | |
391 | array[0] = array[1] = MonthDay.of(Month.APRIL, 10); | |
392 | assertBothWays(array, "" // | |
393 | + "<month-day-array>\n" | |
394 | + " <month-day>--04-10</month-day>\n" // | |
395 | + " <month-day>--04-10</month-day>\n" // | |
396 | + "</month-day-array>"); | |
397 | } | |
398 | ||
399 | public void testOffsetDateTime() { | |
400 | assertBothWays(OffsetDateTime.of(2017, 7, 30, 20, 40, 0, 0, ZoneOffset.ofHours(0)), | |
401 | "<offset-date-time>2017-07-30T20:40:00Z</offset-date-time>"); | |
402 | assertBothWays(OffsetDateTime.of(2017, 7, 30, 20, 40, 15, 0, ZoneOffset.ofHours(0)), | |
403 | "<offset-date-time>2017-07-30T20:40:15Z</offset-date-time>"); | |
404 | assertBothWays(OffsetDateTime.of(2017, 7, 30, 20, 40, 15, 0, ZoneOffset.ofHours(1)), | |
405 | "<offset-date-time>2017-07-30T20:40:15+01:00</offset-date-time>"); | |
406 | assertBothWays(OffsetDateTime.of(2017, 10, 30, 20, 40, 15, 123456789, ZoneOffset.ofHours(1)), | |
407 | "<offset-date-time>2017-10-30T20:40:15.123456789+01:00</offset-date-time>"); | |
408 | assertBothWays(OffsetDateTime.of(2017, 10, 30, 20, 40, 15, 9, ZoneOffset.ofHours(1)), | |
409 | "<offset-date-time>2017-10-30T20:40:15.000000009+01:00</offset-date-time>"); | |
410 | assertBothWays(OffsetDateTime.of(2017, 10, 30, 20, 40, 15, 1000000, ZoneOffset.ofHours(1)), | |
411 | "<offset-date-time>2017-10-30T20:40:15.001+01:00</offset-date-time>"); | |
412 | assertBothWays(OffsetDateTime.of(2017, 10, 30, 20, 40, 15, 100000000, ZoneOffset.ofHours(1)), | |
413 | "<offset-date-time>2017-10-30T20:40:15.1+01:00</offset-date-time>"); | |
414 | assertBothWays(OffsetDateTime.of(2017, 10, 30, 20, 40, 15, 123456789, ZoneOffset.ofHoursMinutesSeconds(1, 30, | |
415 | 15)), "<offset-date-time>2017-10-30T20:40:15.123456789+01:30:15</offset-date-time>"); | |
416 | assertEquals(OffsetDateTime.of(2017, 7, 30, 20, 40, 0, 0, ZoneOffset.ofHours(0)), xstream.fromXML( | |
417 | "<offset-date-time>2017-07-30T20:40Z</offset-date-time>")); | |
418 | assertEquals(OffsetDateTime.of(2017, 10, 30, 20, 40, 15, 100000000, ZoneOffset.ofHours(1)), xstream.fromXML( | |
419 | "<offset-date-time>2017-10-30T20:40:15.100+01:00</offset-date-time>")); | |
420 | } | |
421 | ||
422 | public void testOffsetDateTimeConversionExceptionContainsInvalidValue() { | |
423 | try { | |
424 | xstream.fromXML("<offset-date-time>2017-07-30T27:40:00Z</offset-date-time>"); | |
425 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
426 | } catch (final ConversionException e) { | |
427 | assertEquals(OffsetDateTime.class.getName(), e.get("class")); | |
428 | assertEquals("2017-07-30T27:40:00Z", e.get("value")); | |
429 | } | |
430 | } | |
431 | ||
432 | public void testOffsetDateTimeWithOldFormat() { | |
433 | assertEquals(OffsetDateTime.of(2017, 7, 30, 20, 40, 0, 0, ZoneOffset.ofHours(0)), xstream.fromXML("" // | |
434 | + "<java.time.OffsetDateTime resolves-to=\"java.time.Ser\">\n" // | |
435 | + " <byte>10</byte>\n" // | |
436 | + " <int>2017</int>\n" // | |
437 | + " <byte>7</byte>\n" // | |
438 | + " <byte>30</byte>\n" // | |
439 | + " <byte>20</byte>\n" // | |
440 | + " <byte>-41</byte>\n" // | |
441 | + " <byte>0</byte>\n" // | |
442 | + "</java.time.OffsetDateTime>")); | |
443 | } | |
444 | ||
445 | public void testOffsetDateTimeIsImmutable() { | |
446 | final OffsetDateTime array[] = new OffsetDateTime[2]; | |
447 | array[0] = array[1] = OffsetDateTime.of(2017, 7, 30, 20, 40, 15, 0, ZoneOffset.ofHours(1)); | |
448 | assertBothWays(array, "" // | |
449 | + "<offset-date-time-array>\n" | |
450 | + " <offset-date-time>2017-07-30T20:40:15+01:00</offset-date-time>\n" // | |
451 | + " <offset-date-time>2017-07-30T20:40:15+01:00</offset-date-time>\n" // | |
452 | + "</offset-date-time-array>"); | |
453 | } | |
454 | ||
455 | public void testOffsetTime() { | |
456 | assertBothWays(OffsetTime.of(20, 40, 0, 0, ZoneOffset.ofHours(0)), "<offset-time>20:40:00Z</offset-time>"); | |
457 | assertBothWays(OffsetTime.of(20, 40, 15, 0, ZoneOffset.ofHours(0)), "<offset-time>20:40:15Z</offset-time>"); | |
458 | assertBothWays(OffsetTime.of(20, 40, 15, 0, ZoneOffset.ofHours(1)), | |
459 | "<offset-time>20:40:15+01:00</offset-time>"); | |
460 | assertBothWays(OffsetTime.of(20, 40, 15, 123456789, ZoneOffset.ofHours(1)), | |
461 | "<offset-time>20:40:15.123456789+01:00</offset-time>"); | |
462 | assertBothWays(OffsetTime.of(20, 40, 15, 9, ZoneOffset.ofHours(1)), | |
463 | "<offset-time>20:40:15.000000009+01:00</offset-time>"); | |
464 | assertBothWays(OffsetTime.of(20, 40, 15, 1000000, ZoneOffset.ofHours(1)), | |
465 | "<offset-time>20:40:15.001+01:00</offset-time>"); | |
466 | assertBothWays(OffsetTime.of(20, 40, 15, 100000000, ZoneOffset.ofHours(1)), | |
467 | "<offset-time>20:40:15.1+01:00</offset-time>"); | |
468 | assertBothWays(OffsetTime.of(20, 40, 15, 123456789, ZoneOffset.ofHoursMinutesSeconds(1, 30, 15)), | |
469 | "<offset-time>20:40:15.123456789+01:30:15</offset-time>"); | |
470 | assertEquals(OffsetTime.of(20, 40, 0, 0, ZoneOffset.ofHours(0)), xstream.fromXML( | |
471 | "<offset-time>20:40Z</offset-time>")); | |
472 | assertEquals(OffsetTime.of(20, 40, 15, 100000000, ZoneOffset.ofHours(1)), xstream.fromXML( | |
473 | "<offset-time>20:40:15.100+01:00</offset-time>")); | |
474 | } | |
475 | ||
476 | public void testOffsetTimeConversionExceptionContainsInvalidValue() { | |
477 | try { | |
478 | xstream.fromXML("<offset-time>20:77:00Z</offset-time>"); | |
479 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
480 | } catch (final ConversionException e) { | |
481 | assertEquals(OffsetTime.class.getName(), e.get("class")); | |
482 | assertEquals("20:77:00Z", e.get("value")); | |
483 | } | |
484 | } | |
485 | ||
486 | public void testOffsetTimeWithOldFormat() { | |
487 | assertEquals(OffsetTime.of(20, 40, 0, 0, ZoneOffset.ofHours(0)), xstream.fromXML("" // | |
488 | + "<java.time.OffsetTime resolves-to=\"java.time.Ser\">\n" // | |
489 | + " <byte>9</byte>\n" // | |
490 | + " <byte>20</byte>\n" // | |
491 | + " <byte>-41</byte>\n" // | |
492 | + " <byte>0</byte>\n" // | |
493 | + "</java.time.OffsetTime>")); | |
494 | } | |
495 | ||
496 | public void testOffsetTimeIsImmutable() { | |
497 | final OffsetTime array[] = new OffsetTime[2]; | |
498 | array[0] = array[1] = OffsetTime.of(20, 40, 15, 0, ZoneOffset.ofHours(1)); | |
499 | assertBothWays(array, "" // | |
500 | + "<offset-time-array>\n" | |
501 | + " <offset-time>20:40:15+01:00</offset-time>\n" // | |
502 | + " <offset-time>20:40:15+01:00</offset-time>\n" // | |
503 | + "</offset-time-array>"); | |
504 | } | |
505 | ||
506 | public void testYear() { | |
507 | assertBothWays(Year.of(2017), "<year>2017</year>"); | |
508 | assertBothWays(Year.of(0), "<year>0</year>"); | |
509 | assertBothWays(Year.of(-1), "<year>-1</year>"); | |
510 | } | |
511 | ||
512 | public void testYearConversionExceptionContainsInvalidValue() { | |
513 | try { | |
514 | xstream.fromXML("<year>Z</year>"); | |
515 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
516 | } catch (final ConversionException e) { | |
517 | assertEquals(Year.class.getName(), e.get("class")); | |
518 | assertEquals("Z", e.get("value")); | |
519 | } | |
520 | } | |
521 | ||
522 | public void testYearWithOldFormat() { | |
523 | assertEquals(Year.of(2017), xstream.fromXML("" // | |
524 | + "<java.time.Year resolves-to=\"java.time.Ser\">\n" // | |
525 | + " <byte>11</byte>\n" // | |
526 | + " <int>2017</int>\n" // | |
527 | + "</java.time.Year>")); | |
528 | } | |
529 | ||
530 | public void testYearIsImmutable() { | |
531 | final Year array[] = new Year[2]; | |
532 | array[0] = array[1] = Year.of(2017); | |
533 | assertBothWays(array, "" // | |
534 | + "<year-array>\n" | |
535 | + " <year>2017</year>\n" // | |
536 | + " <year>2017</year>\n" // | |
537 | + "</year-array>"); | |
538 | } | |
539 | ||
540 | public void testYearMonth() { | |
541 | assertBothWays(YearMonth.of(2017, 2), "<year-month>2017-02</year-month>"); | |
542 | assertBothWays(YearMonth.of(0, 2), "<year-month>0000-02</year-month>"); | |
543 | assertBothWays(YearMonth.of(-1, 2), "<year-month>-0001-02</year-month>"); | |
544 | } | |
545 | ||
546 | public void testYearMonthConversionExceptionContainsInvalidValue() { | |
547 | try { | |
548 | xstream.fromXML("<year-month>Z-02</year-month>"); | |
549 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
550 | } catch (final ConversionException e) { | |
551 | assertEquals(YearMonth.class.getName(), e.get("class")); | |
552 | assertEquals("Z-02", e.get("value")); | |
553 | } | |
554 | } | |
555 | ||
556 | public void testYearMonthWithOldFormat() { | |
557 | assertEquals(YearMonth.of(2017, 2), xstream.fromXML("" // | |
558 | + "<java.time.YearMonth resolves-to=\"java.time.Ser\">\n" // | |
559 | + " <byte>12</byte>\n" // | |
560 | + " <int>2017</int>\n" // | |
561 | + " <byte>2</byte>\n" // | |
562 | + "</java.time.YearMonth>")); | |
563 | } | |
564 | ||
565 | public void testYearMonthIsImmutable() { | |
566 | final YearMonth array[] = new YearMonth[2]; | |
567 | array[0] = array[1] = YearMonth.of(2017, 2); | |
568 | assertBothWays(array, "" // | |
569 | + "<year-month-array>\n" | |
570 | + " <year-month>2017-02</year-month>\n" // | |
571 | + " <year-month>2017-02</year-month>\n" // | |
572 | + "</year-month-array>"); | |
573 | } | |
574 | ||
575 | public void testZonedDateTime() { | |
576 | assertBothWays(ZonedDateTime.of(2017, 10, 30, 20, 40, 0, 0, ZoneId.of("Europe/London")), | |
577 | "<zoned-date-time>2017-10-30T20:40:00Z[Europe/London]</zoned-date-time>"); | |
578 | assertBothWays(ZonedDateTime.of(2017, 10, 30, 20, 40, 15, 0, ZoneId.of("Europe/London")), | |
579 | "<zoned-date-time>2017-10-30T20:40:15Z[Europe/London]</zoned-date-time>"); | |
580 | assertBothWays(ZonedDateTime.of(2017, 10, 30, 20, 40, 15, 0, ZoneId.of("Europe/Paris")), | |
581 | "<zoned-date-time>2017-10-30T20:40:15+01:00[Europe/Paris]</zoned-date-time>"); | |
582 | assertBothWays(ZonedDateTime.of(2017, 10, 30, 20, 40, 15, 123456789, ZoneId.of("Europe/Paris")), | |
583 | "<zoned-date-time>2017-10-30T20:40:15.123456789+01:00[Europe/Paris]</zoned-date-time>"); | |
584 | assertBothWays(ZonedDateTime.of(2017, 10, 30, 20, 40, 15, 9, ZoneId.of("Europe/Paris")), | |
585 | "<zoned-date-time>2017-10-30T20:40:15.000000009+01:00[Europe/Paris]</zoned-date-time>"); | |
586 | assertBothWays(ZonedDateTime.of(2017, 10, 30, 20, 40, 15, 1000000, ZoneId.of("Europe/Paris")), | |
587 | "<zoned-date-time>2017-10-30T20:40:15.001+01:00[Europe/Paris]</zoned-date-time>"); | |
588 | assertBothWays(ZonedDateTime.of(2017, 10, 30, 20, 40, 15, 100000000, ZoneId.of("Europe/Paris")), | |
589 | "<zoned-date-time>2017-10-30T20:40:15.1+01:00[Europe/Paris]</zoned-date-time>"); | |
590 | assertEquals(ZonedDateTime.of(2017, 10, 30, 20, 40, 0, 0, ZoneId.of("Europe/London")), xstream.fromXML( | |
591 | "<zoned-date-time>2017-10-30T20:40Z[Europe/London]</zoned-date-time>")); | |
592 | assertEquals(ZonedDateTime.of(2017, 10, 30, 20, 40, 15, 100000000, ZoneId.of("Europe/Paris")), xstream.fromXML( | |
593 | "<zoned-date-time>2017-10-30T20:40:15.100+01:00[Europe/Paris]</zoned-date-time>")); | |
594 | } | |
595 | ||
596 | public void testZonedDateTimeConversionExceptionContainsInvalidValue() { | |
597 | try { | |
598 | xstream.fromXML("<zoned-date-time>2017-10-30T20:40:00Z[Europe/Bonn]</zoned-date-time>"); | |
599 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
600 | } catch (final ConversionException e) { | |
601 | assertEquals(ZonedDateTime.class.getName(), e.get("class")); | |
602 | assertEquals("2017-10-30T20:40:00Z[Europe/Bonn]", e.get("value")); | |
603 | } | |
604 | } | |
605 | ||
606 | public void testZonedDateTimeWithOldFormat() { | |
607 | assertEquals(ZonedDateTime.of(2017, 10, 30, 20, 40, 0, 0, ZoneId.of("Europe/London")), xstream.fromXML("" // | |
608 | + "<java.time.ZonedDateTime resolves-to=\"java.time.Ser\">\n" // | |
609 | + " <byte>6</byte>\n" // | |
610 | + " <int>2017</int>\n" // | |
611 | + " <byte>10</byte>\n" // | |
612 | + " <byte>30</byte>\n" // | |
613 | + " <byte>20</byte>\n" // | |
614 | + " <byte>-41</byte>\n" // | |
615 | + " <byte>0</byte>\n" // | |
616 | + " <byte>7</byte>\n" // | |
617 | + " <string>Europe/London</string>\n" // | |
618 | + "</java.time.ZonedDateTime>")); | |
619 | } | |
620 | ||
621 | public void testZonedDateTimeIsImmutable() { | |
622 | final ZonedDateTime array[] = new ZonedDateTime[2]; | |
623 | array[0] = array[1] = ZonedDateTime.of(2017, 10, 30, 20, 40, 15, 0, ZoneId.of("Europe/Paris")); | |
624 | assertBothWays(array, "" | |
625 | + "<zoned-date-time-array>\n" | |
626 | + " <zoned-date-time>2017-10-30T20:40:15+01:00[Europe/Paris]</zoned-date-time>\n" | |
627 | + " <zoned-date-time>2017-10-30T20:40:15+01:00[Europe/Paris]</zoned-date-time>\n" | |
628 | + "</zoned-date-time-array>"); | |
629 | } | |
630 | ||
631 | public void testZoneOffest() { | |
632 | assertBothWays(ZoneOffset.of("Z"), "<zone-id>Z</zone-id>"); | |
633 | assertBothWays(ZoneOffset.ofTotalSeconds(7777), "<zone-id>+02:09:37</zone-id>"); | |
634 | assertBothWays(ZoneId.ofOffset("GMT", ZoneOffset.ofTotalSeconds(7777)), "<zone-id>GMT+02:09:37</zone-id>"); | |
635 | assertBothWays(ZoneId.of("ECT", ZoneId.SHORT_IDS), "<zone-id>Europe/Paris</zone-id>"); | |
636 | assertBothWays(ZoneId.of("CET"), "<zone-id>CET</zone-id>"); | |
637 | } | |
638 | ||
639 | public void testZoneIdConversionExceptionContainsInvalidValue() { | |
640 | try { | |
641 | xstream.fromXML("<zone-id>X</zone-id>"); | |
642 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
643 | } catch (final ConversionException e) { | |
644 | assertEquals(ZoneId.class.getName(), e.get("class")); | |
645 | assertEquals("X", e.get("value")); | |
646 | } | |
647 | try { | |
648 | xstream.fromXML("<zone-id>Europe/X</zone-id>"); | |
649 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
650 | } catch (final ConversionException e) { | |
651 | assertEquals(ZoneId.class.getName(), e.get("class")); | |
652 | assertEquals("Europe/X", e.get("value")); | |
653 | } | |
654 | } | |
655 | ||
656 | public void testZoneOffestWithOldFormat() { | |
657 | assertEquals(ZoneOffset.ofTotalSeconds(7777), xstream.fromXML("" // | |
658 | + "<java.time.ZoneOffset resolves-to=\"java.time.Ser\">\n" // | |
659 | + " <byte>8</byte>\n" // | |
660 | + " <byte>127</byte>\n" // | |
661 | + " <int>7777</int>\n" // | |
662 | + "</java.time.ZoneOffset>")); | |
663 | } | |
664 | ||
665 | public void testZoneOffestIsImmutable() { | |
666 | final ZoneOffset[] array = new ZoneOffset[2]; | |
667 | array[0] = array[1] = ZoneOffset.of("Z"); | |
668 | assertBothWays(array, "" // | |
669 | + "<zone-id-array>\n" // | |
670 | + " <zone-id>Z</zone-id>\n" // | |
671 | + " <zone-id>Z</zone-id>\n" // | |
672 | + "</zone-id-array>"); | |
673 | } | |
674 | ||
675 | public void testZoneRegion() { | |
676 | assertBothWays(ZoneId.of("America/Caracas"), "<zone-id>America/Caracas</zone-id>"); | |
677 | assertBothWays(ZoneId.of("Europe/Berlin"), "<zone-id>Europe/Berlin</zone-id>"); | |
678 | } | |
679 | ||
680 | public void testZoneRegionWithOldFormat() { | |
681 | assertEquals(ZoneId.of("America/Caracas"), xstream.fromXML("" // | |
682 | + "<java.time.ZoneRegion resolves-to=\"java.time.Ser\">\n" // | |
683 | + " <byte>7</byte>\n" // | |
684 | + " <string>America/Caracas</string>\n" // | |
685 | + "</java.time.ZoneRegion>")); | |
686 | } | |
687 | ||
688 | public void testZoneRegionIsImmutable() { | |
689 | final ZoneId[] array = new ZoneId[2]; | |
690 | array[0] = array[1] = ZoneId.of("Europe/Rome"); | |
691 | assertBothWays(array, "" // | |
692 | + "<zone-id-array>\n" // | |
693 | + " <zone-id>Europe/Rome</zone-id>\n" // | |
694 | + " <zone-id>Europe/Rome</zone-id>\n" // | |
695 | + "</zone-id-array>"); | |
696 | } | |
697 | ||
698 | public void testChronology() { | |
699 | assertBothWays(IsoChronology.INSTANCE, "<chronology>ISO</chronology>"); | |
700 | assertBothWays(JapaneseChronology.INSTANCE, "<chronology>Japanese</chronology>"); | |
701 | } | |
702 | ||
703 | public void testChronologyConversionExceptionContainsInvalidValue() { | |
704 | try { | |
705 | xstream.fromXML("<chronology>Z</chronology>"); | |
706 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
707 | } catch (final ConversionException e) { | |
708 | assertEquals(Chronology.class.getName(), e.get("class")); | |
709 | assertEquals("Z", e.get("value")); | |
710 | } | |
711 | } | |
712 | ||
713 | public void testChronologyWithOldFormat() { | |
714 | assertSame(IsoChronology.INSTANCE, xstream.fromXML("" // | |
715 | + "<java.time.chrono.IsoChronology resolves-to=\"java.time.chrono.Ser\">\n" // | |
716 | + " <byte>1</byte>\n" // | |
717 | + " <string>ISO</string>\n" // | |
718 | + "</java.time.chrono.IsoChronology>")); | |
719 | } | |
720 | ||
721 | public void testChronologyIsImmutable() { | |
722 | final Chronology[] array = new Chronology[2]; | |
723 | array[0] = array[1] = IsoChronology.INSTANCE; | |
724 | assertBothWays(array, "" // | |
725 | + "<chronology-array>\n" // | |
726 | + " <chronology>ISO</chronology>\n" // | |
727 | + " <chronology>ISO</chronology>\n" // | |
728 | + "</chronology-array>"); | |
729 | } | |
730 | ||
731 | public void testHijrahDate() { | |
732 | assertBothWays(HijrahChronology.INSTANCE.date(LocalDate.of(2017, 7, 30)), | |
733 | "<hijrah-date>Hijrah-umalqura AH 1438-11-07</hijrah-date>"); | |
734 | } | |
735 | ||
736 | public void testHijrahDateWithOldFormat() { | |
737 | assertEquals(HijrahChronology.INSTANCE.date(LocalDate.of(2017, 7, 30)), xstream.fromXML("" // | |
738 | + "<java.time.chrono.HijrahDate resolves-to=\"java.time.chrono.Ser\">\n" // | |
739 | + " <byte>6</byte>\n" // | |
740 | + " <java.time.chrono.HijrahChronology resolves-to=\"java.time.chrono.Ser\">\n" // | |
741 | + " <byte>1</byte>\n" // | |
742 | + " <string>Hijrah-umalqura</string>\n" // | |
743 | + " </java.time.chrono.HijrahChronology>\n" // | |
744 | + " <int>1438</int>\n" // | |
745 | + " <byte>11</byte>\n" // | |
746 | + " <byte>7</byte>\n" // | |
747 | + "</java.time.chrono.HijrahDate>")); | |
748 | } | |
749 | ||
750 | public void testHijrahDateConversionExceptionContainsInvalidValue() { | |
751 | try { | |
752 | xstream.fromXML("<hijrah-date>Hijrah-X AH 1438-11-07</hijrah-date>"); | |
753 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
754 | } catch (final ConversionException e) { | |
755 | assertEquals(HijrahDate.class.getName(), e.get("class")); | |
756 | assertEquals("Hijrah-X AH 1438-11-07", e.get("value")); | |
757 | } | |
758 | try { | |
759 | xstream.fromXML("<hijrah-date>Hijrah-umalqura X 1438-11-07</hijrah-date>"); | |
760 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
761 | } catch (final ConversionException e) { | |
762 | assertEquals(HijrahDate.class.getName(), e.get("class")); | |
763 | assertEquals("Hijrah-umalqura X 1438-11-07", e.get("value")); | |
764 | } | |
765 | try { | |
766 | xstream.fromXML("<hijrah-date>Hijrah-umalqura AH 1438-42-07</hijrah-date>"); | |
767 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
768 | } catch (final ConversionException e) { | |
769 | assertEquals(HijrahDate.class.getName(), e.get("class")); | |
770 | assertEquals("Hijrah-umalqura AH 1438-42-07", e.get("value")); | |
771 | } | |
772 | } | |
773 | ||
774 | public void testHijrahDateIsImmutable() { | |
775 | final HijrahDate[] array = new HijrahDate[2]; | |
776 | array[0] = array[1] = HijrahChronology.INSTANCE.date(LocalDate.of(2017, 7, 30)); | |
777 | assertBothWays(array, "" // | |
778 | + "<hijrah-date-array>\n" // | |
779 | + " <hijrah-date>Hijrah-umalqura AH 1438-11-07</hijrah-date>\n" // | |
780 | + " <hijrah-date>Hijrah-umalqura AH 1438-11-07</hijrah-date>\n" // | |
781 | + "</hijrah-date-array>"); | |
782 | } | |
783 | ||
784 | public void testHijrahEra() { | |
785 | assertBothWays(HijrahEra.AH, "<hijrah-era>AH</hijrah-era>"); | |
786 | } | |
787 | ||
788 | public void testJapaneseDate() { | |
789 | assertBothWays(JapaneseChronology.INSTANCE.date(LocalDate.of(2017, 7, 30)), | |
790 | "<japanese-date>Japanese Heisei 29-07-30</japanese-date>"); | |
791 | } | |
792 | ||
793 | public void testJapaneseDateWithOldFormat() { | |
794 | assertEquals(JapaneseChronology.INSTANCE.date(LocalDate.of(2017, 7, 30)), xstream.fromXML("" // | |
795 | + "<java.time.chrono.JapaneseDate resolves-to=\"java.time.chrono.Ser\">\n" // | |
796 | + " <byte>4</byte>\n" // | |
797 | + " <int>2017</int>\n" // | |
798 | + " <byte>7</byte>\n" // | |
799 | + " <byte>30</byte>\n" // | |
800 | + "</java.time.chrono.JapaneseDate>")); | |
801 | } | |
802 | ||
803 | public void testJapaneseDateConversionExceptionContainsInvalidValue() { | |
804 | try { | |
805 | xstream.fromXML("<japanese-date>Chinese Heisei 29-07-30</japanese-date>"); | |
806 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
807 | } catch (final ConversionException e) { | |
808 | assertEquals(JapaneseDate.class.getName(), e.get("class")); | |
809 | assertEquals("Chinese Heisei 29-07-30", e.get("value")); | |
810 | } | |
811 | try { | |
812 | xstream.fromXML("<japanese-date>Japanese Mitsubishi 29-07-30</japanese-date>"); | |
813 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
814 | } catch (final ConversionException e) { | |
815 | assertEquals(JapaneseDate.class.getName(), e.get("class")); | |
816 | assertEquals("Japanese Mitsubishi 29-07-30", e.get("value")); | |
817 | } | |
818 | try { | |
819 | xstream.fromXML("<japanese-date>Japanese Heisei 29-13-30</japanese-date>"); | |
820 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
821 | } catch (final ConversionException e) { | |
822 | assertEquals(JapaneseDate.class.getName(), e.get("class")); | |
823 | assertEquals("Japanese Heisei 29-13-30", e.get("value")); | |
824 | } | |
825 | } | |
826 | ||
827 | public void testJapaneseDateIsImmutable() { | |
828 | final JapaneseDate[] array = new JapaneseDate[2]; | |
829 | array[0] = array[1] = JapaneseChronology.INSTANCE.date(LocalDate.of(2017, 7, 30)); | |
830 | assertBothWays(array, "" // | |
831 | + "<japanese-date-array>\n" // | |
832 | + " <japanese-date>Japanese Heisei 29-07-30</japanese-date>\n" // | |
833 | + " <japanese-date>Japanese Heisei 29-07-30</japanese-date>\n" // | |
834 | + "</japanese-date-array>"); | |
835 | } | |
836 | ||
837 | public void testJapaneseEra() { | |
838 | assertBothWays(JapaneseEra.TAISHO, "<japanese-era>Taisho</japanese-era>"); | |
839 | } | |
840 | ||
841 | public void testJapaneseEraWithOldFormat() { | |
842 | assertEquals(JapaneseEra.TAISHO, xstream.fromXML("" // | |
843 | + "<java.time.chrono.JapaneseEra resolves-to=\"java.time.chrono.Ser\">\n" // | |
844 | + " <byte>5</byte>\n" // | |
845 | + " <byte>0</byte>\n" // | |
846 | + "</java.time.chrono.JapaneseEra>")); | |
847 | } | |
848 | ||
849 | public void testJapaneseEraConversionExceptionContainsInvalidValue() { | |
850 | try { | |
851 | xstream.fromXML("<japanese-era>NEMO</japanese-era>"); | |
852 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
853 | } catch (final ConversionException e) { | |
854 | assertEquals(JapaneseEra.class.getName(), e.get("class")); | |
855 | assertEquals("NEMO", e.get("value")); | |
856 | } | |
857 | } | |
858 | ||
859 | public void testJapaneseEraIsImmutable() { | |
860 | final JapaneseEra[] array = new JapaneseEra[2]; | |
861 | array[0] = array[1] = JapaneseEra.SHOWA; | |
862 | assertBothWays(array, "" // | |
863 | + "<japanese-era-array>\n" // | |
864 | + " <japanese-era>Showa</japanese-era>\n" // | |
865 | + " <japanese-era>Showa</japanese-era>\n" // | |
866 | + "</japanese-era-array>"); | |
867 | } | |
868 | ||
869 | public void testMinguoDate() { | |
870 | assertBothWays(MinguoChronology.INSTANCE.date(LocalDate.of(2017, 7, 30)), | |
871 | "<minguo-date>Minguo ROC 106-07-30</minguo-date>"); | |
872 | } | |
873 | ||
874 | public void testMinguoDateWithOldFormat() { | |
875 | assertEquals(MinguoChronology.INSTANCE.date(LocalDate.of(2017, 7, 30)), xstream.fromXML("" // | |
876 | + "<java.time.chrono.MinguoDate resolves-to=\"java.time.chrono.Ser\">\n" // | |
877 | + " <byte>7</byte>\n" // | |
878 | + " <int>106</int>\n" // | |
879 | + " <byte>7</byte>\n" // | |
880 | + " <byte>30</byte>\n" // | |
881 | + "</java.time.chrono.MinguoDate>")); | |
882 | } | |
883 | ||
884 | public void testMinguoDateConversionExceptionContainsInvalidValue() { | |
885 | try { | |
886 | xstream.fromXML("<minguo-date>Chinese ROC 106-07-30</minguo-date>"); | |
887 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
888 | } catch (final ConversionException e) { | |
889 | assertEquals(MinguoDate.class.getName(), e.get("class")); | |
890 | assertEquals("Chinese ROC 106-07-30", e.get("value")); | |
891 | } | |
892 | try { | |
893 | xstream.fromXML("<minguo-date>Minguo X 106-07-30</minguo-date>"); | |
894 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
895 | } catch (final ConversionException e) { | |
896 | assertEquals(MinguoDate.class.getName(), e.get("class")); | |
897 | assertEquals("Minguo X 106-07-30", e.get("value")); | |
898 | } | |
899 | try { | |
900 | xstream.fromXML("<minguo-date>Minguo ROC 106-13-30</minguo-date>"); | |
901 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
902 | } catch (final ConversionException e) { | |
903 | assertEquals(MinguoDate.class.getName(), e.get("class")); | |
904 | assertEquals("Minguo ROC 106-13-30", e.get("value")); | |
905 | } | |
906 | } | |
907 | ||
908 | public void testMinguoDateIsImmutable() { | |
909 | final MinguoDate[] array = new MinguoDate[2]; | |
910 | array[0] = array[1] = MinguoChronology.INSTANCE.date(LocalDate.of(2017, 7, 30)); | |
911 | assertBothWays(array, "" // | |
912 | + "<minguo-date-array>\n" // | |
913 | + " <minguo-date>Minguo ROC 106-07-30</minguo-date>\n" // | |
914 | + " <minguo-date>Minguo ROC 106-07-30</minguo-date>\n" // | |
915 | + "</minguo-date-array>"); | |
916 | } | |
917 | ||
918 | public void testMinguoEra() { | |
919 | assertBothWays(MinguoEra.ROC, "<minguo-era>ROC</minguo-era>"); | |
920 | } | |
921 | ||
922 | public void testThaiBuddhistDate() { | |
923 | assertBothWays(ThaiBuddhistChronology.INSTANCE.date(LocalDate.of(2017, 7, 30)), | |
924 | "<thai-buddhist-date>ThaiBuddhist BE 2560-07-30</thai-buddhist-date>"); | |
925 | } | |
926 | ||
927 | public void testThaiBuddhistDateWithOldFormat() { | |
928 | assertEquals(ThaiBuddhistChronology.INSTANCE.date(LocalDate.of(2017, 7, 30)), xstream.fromXML("" // | |
929 | + "<java.time.chrono.ThaiBuddhistDate resolves-to=\"java.time.chrono.Ser\">\n" // | |
930 | + " <byte>8</byte>\n" // | |
931 | + " <int>2560</int>\n" // | |
932 | + " <byte>7</byte>\n" // | |
933 | + " <byte>30</byte>\n" // | |
934 | + "</java.time.chrono.ThaiBuddhistDate>")); | |
935 | } | |
936 | ||
937 | public void testThaiBuddhistDateConversionExceptionContainsInvalidValue() { | |
938 | try { | |
939 | xstream.fromXML("<thai-buddhist-date>Chinese BE 2560-07-30</thai-buddhist-date>"); | |
940 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
941 | } catch (final ConversionException e) { | |
942 | assertEquals(ThaiBuddhistDate.class.getName(), e.get("class")); | |
943 | assertEquals("Chinese BE 2560-07-30", e.get("value")); | |
944 | } | |
945 | try { | |
946 | xstream.fromXML("<thai-buddhist-date>ThaiBuddhist X 2560-07-30</thai-buddhist-date>"); | |
947 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
948 | } catch (final ConversionException e) { | |
949 | assertEquals(ThaiBuddhistDate.class.getName(), e.get("class")); | |
950 | assertEquals("ThaiBuddhist X 2560-07-30", e.get("value")); | |
951 | } | |
952 | try { | |
953 | xstream.fromXML("<thai-buddhist-date>ThaiBuddhist BE 2560-13-30</thai-buddhist-date>"); | |
954 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
955 | } catch (final ConversionException e) { | |
956 | assertEquals(ThaiBuddhistDate.class.getName(), e.get("class")); | |
957 | assertEquals("ThaiBuddhist BE 2560-13-30", e.get("value")); | |
958 | } | |
959 | } | |
960 | ||
961 | public void testThaiBuddhistDateIsImmutable() { | |
962 | final ThaiBuddhistDate[] array = new ThaiBuddhistDate[2]; | |
963 | array[0] = array[1] = ThaiBuddhistChronology.INSTANCE.date(LocalDate.of(2017, 7, 30)); | |
964 | assertBothWays(array, "" // | |
965 | + "<thai-buddhist-date-array>\n" // | |
966 | + " <thai-buddhist-date>ThaiBuddhist BE 2560-07-30</thai-buddhist-date>\n" // | |
967 | + " <thai-buddhist-date>ThaiBuddhist BE 2560-07-30</thai-buddhist-date>\n" // | |
968 | + "</thai-buddhist-date-array>"); | |
969 | } | |
970 | ||
971 | public void testThaiBuddhistEra() { | |
972 | assertBothWays(ThaiBuddhistEra.BE, "<thai-buddhist-era>BE</thai-buddhist-era>"); | |
973 | } | |
974 | ||
975 | public void testChronoField() { | |
976 | assertBothWays(ChronoField.ERA, "<chrono-field>ERA</chrono-field>"); | |
977 | } | |
978 | ||
979 | public void testChronoUnit() { | |
980 | assertBothWays(ChronoUnit.DECADES, "<chrono-unit>DECADES</chrono-unit>"); | |
981 | } | |
982 | ||
983 | public void testIsoFields() { | |
984 | assertBothWays(IsoFields.DAY_OF_QUARTER, "<iso-field>DAY_OF_QUARTER</iso-field>"); | |
985 | assertBothWays(IsoFields.QUARTER_OF_YEAR, "<iso-field>QUARTER_OF_YEAR</iso-field>"); | |
986 | assertBothWays(IsoFields.QUARTER_YEARS, "<iso-unit>QUARTER_YEARS</iso-unit>"); | |
987 | assertBothWays(IsoFields.WEEK_BASED_YEAR, "<iso-field>WEEK_BASED_YEAR</iso-field>"); | |
988 | assertBothWays(IsoFields.WEEK_BASED_YEARS, "<iso-unit>WEEK_BASED_YEARS</iso-unit>"); | |
989 | assertBothWays(IsoFields.WEEK_OF_WEEK_BASED_YEAR, "<iso-field>WEEK_OF_WEEK_BASED_YEAR</iso-field>"); | |
990 | } | |
991 | ||
992 | public void testIsoFieldsAreImmutable() { | |
993 | final Object[] array = new Object[4]; | |
994 | array[0] = array[1] = IsoFields.DAY_OF_QUARTER; | |
995 | array[2] = array[3] = IsoFields.QUARTER_YEARS; | |
996 | assertBothWays(array, "" // | |
997 | + "<object-array>\n" // | |
998 | + " <iso-field>DAY_OF_QUARTER</iso-field>\n" // | |
999 | + " <iso-field>DAY_OF_QUARTER</iso-field>\n" // | |
1000 | + " <iso-unit>QUARTER_YEARS</iso-unit>\n" // | |
1001 | + " <iso-unit>QUARTER_YEARS</iso-unit>\n" // | |
1002 | + "</object-array>"); | |
1003 | } | |
1004 | ||
1005 | public void testJulianFields() { | |
1006 | assertBothWays(JulianFields.JULIAN_DAY, "<julian-field>JULIAN_DAY</julian-field>"); | |
1007 | assertBothWays(JulianFields.MODIFIED_JULIAN_DAY, "<julian-field>MODIFIED_JULIAN_DAY</julian-field>"); | |
1008 | assertBothWays(JulianFields.RATA_DIE, "<julian-field>RATA_DIE</julian-field>"); | |
1009 | } | |
1010 | ||
1011 | public void testJulianFieldsAreImmutable() { | |
1012 | final TemporalField[] array = new TemporalField[2]; | |
1013 | array[0] = array[1] = JulianFields.JULIAN_DAY; | |
1014 | assertBothWays(array, "" // | |
1015 | + "<java.time.temporal.TemporalField-array>\n" // | |
1016 | + " <julian-field>JULIAN_DAY</julian-field>\n" // | |
1017 | + " <julian-field>JULIAN_DAY</julian-field>\n" // | |
1018 | + "</java.time.temporal.TemporalField-array>"); | |
1019 | } | |
1020 | ||
1021 | public void testValueRange() { | |
1022 | assertBothWays(ValueRange.of(0, 1, 30, 45), "" // | |
1023 | + "<temporal-value-range>\n" // | |
1024 | + " <maxLargest>45</maxLargest>\n" // | |
1025 | + " <maxSmallest>30</maxSmallest>\n" // | |
1026 | + " <minLargest>1</minLargest>\n" // | |
1027 | + " <minSmallest>0</minSmallest>\n" // | |
1028 | + "</temporal-value-range>"); | |
1029 | } | |
1030 | ||
1031 | public void testValueRangeWithAlias() { | |
1032 | xstream.aliasField("max", ValueRange.class, "maxLargest"); | |
1033 | xstream.aliasField("max-s", ValueRange.class, "maxSmallest"); | |
1034 | xstream.aliasField("min-l", ValueRange.class, "minLargest"); | |
1035 | xstream.aliasField("min", ValueRange.class, "minSmallest"); | |
1036 | assertBothWays(ValueRange.of(0, 1, 30, 45), "" // | |
1037 | + "<temporal-value-range>\n" // | |
1038 | + " <max>45</max>\n" // | |
1039 | + " <max-s>30</max-s>\n" // | |
1040 | + " <min-l>1</min-l>\n" // | |
1041 | + " <min>0</min>\n" // | |
1042 | + "</temporal-value-range>"); | |
1043 | } | |
1044 | ||
1045 | public void testValueRangeWithOldFormat() { | |
1046 | assertEquals(ValueRange.of(0, 1, 30, 45), xstream.fromXML("" // | |
1047 | + "<java.time.temporal.ValueRange serialization=\"custom\">\n" // | |
1048 | + " <java.time.temporal.ValueRange>\n" // | |
1049 | + " <default>\n" // | |
1050 | + " <maxLargest>45</maxLargest>\n" // | |
1051 | + " <maxSmallest>30</maxSmallest>\n" // | |
1052 | + " <minLargest>1</minLargest>\n" // | |
1053 | + " <minSmallest>0</minSmallest>\n" // | |
1054 | + " </default>\n" // | |
1055 | + " </java.time.temporal.ValueRange>\n" // | |
1056 | + "</java.time.temporal.ValueRange>")); | |
1057 | } | |
1058 | ||
1059 | public void testWeekFields() { | |
1060 | assertBothWays(WeekFields.of(DayOfWeek.TUESDAY, 2), "" // | |
1061 | + "<week-fields>\n" // | |
1062 | + " <minimalDays>2</minimalDays>\n" // | |
1063 | + " <firstDayOfWeek>TUESDAY</firstDayOfWeek>\n" // | |
1064 | + "</week-fields>"); | |
1065 | assertBothWays(WeekFields.ISO, "" // | |
1066 | + "<week-fields>\n" // | |
1067 | + " <minimalDays>4</minimalDays>\n" // | |
1068 | + " <firstDayOfWeek>MONDAY</firstDayOfWeek>\n" // | |
1069 | + "</week-fields>"); | |
1070 | } | |
1071 | ||
1072 | public void testWeekFieldsWithFieldAlias() { | |
1073 | xstream.aliasField("days", WeekFields.class, "minimalDays"); | |
1074 | xstream.aliasField("week-day", WeekFields.class, "firstDayOfWeek"); | |
1075 | assertBothWays(WeekFields.of(DayOfWeek.TUESDAY, 2), "" // | |
1076 | + "<week-fields>\n" // | |
1077 | + " <days>2</days>\n" // | |
1078 | + " <week-day>TUESDAY</week-day>\n" // | |
1079 | + "</week-fields>"); | |
1080 | } | |
1081 | ||
1082 | public void testWeekFieldsWithOldFormat() { | |
1083 | assertEquals(WeekFields.of(DayOfWeek.TUESDAY, 2), xstream.fromXML("" // | |
1084 | + "<java.time.temporal.WeekFields serialization=\"custom\">\n" // | |
1085 | + " <java.time.temporal.WeekFields>\n" // | |
1086 | + " <default>\n" // | |
1087 | + " <minimalDays>2</minimalDays>\n" // | |
1088 | + " <firstDayOfWeek>TUESDAY</firstDayOfWeek>\n" // | |
1089 | + " </default>\n" // | |
1090 | + " </java.time.temporal.WeekFields>\n" // | |
1091 | + "</java.time.temporal.WeekFields>")); | |
1092 | } | |
1093 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2014, 2015 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2014, 2015, 2016 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
6 | 6 | * style license a copy of which has been included with this distribution in |
7 | 7 | * the LICENSE.txt file. |
8 | * | |
8 | * | |
9 | 9 | * Created on 24. August 2004 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.acceptance; |
12 | ||
13 | import com.thoughtworks.acceptance.objects.Original; | |
14 | import com.thoughtworks.acceptance.objects.Replaced; | |
15 | import com.thoughtworks.acceptance.objects.StandardObject; | |
16 | 12 | |
17 | 13 | import java.io.ByteArrayInputStream; |
18 | 14 | import java.io.ByteArrayOutputStream; |
28 | 24 | |
29 | 25 | import org.apache.commons.lang.StringUtils; |
30 | 26 | |
27 | import com.thoughtworks.acceptance.objects.Original; | |
28 | import com.thoughtworks.acceptance.objects.Replaced; | |
29 | import com.thoughtworks.acceptance.objects.StandardObject; | |
30 | ||
31 | ||
31 | 32 | public class WriteReplaceTest extends AbstractAcceptanceTest { |
32 | 33 | |
33 | 34 | public static class Thing extends StandardObject implements Serializable { |
38 | 39 | public Thing() { |
39 | 40 | } |
40 | 41 | |
41 | public Thing(int a, int b) { | |
42 | public Thing(final int a, final int b) { | |
42 | 43 | this.a = a; |
43 | 44 | this.b = b; |
44 | 45 | } |
54 | 55 | } |
55 | 56 | |
56 | 57 | public void testReplacesAndResolves() throws IOException, ClassNotFoundException { |
57 | Thing thing = new Thing(3, 6); | |
58 | final Thing thing = new Thing(3, 6); | |
58 | 59 | |
59 | 60 | // ensure that Java serialization does not cause endless loop for a Thing |
60 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |
61 | ObjectOutputStream oos = new ObjectOutputStream(baos); | |
61 | final ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |
62 | final ObjectOutputStream oos = new ObjectOutputStream(baos); | |
62 | 63 | oos.writeObject(thing); |
63 | 64 | oos.close(); |
64 | ||
65 | ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); | |
66 | ObjectInputStream ios = new ObjectInputStream(bais); | |
65 | ||
66 | final ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); | |
67 | final ObjectInputStream ios = new ObjectInputStream(bais); | |
67 | 68 | assertEquals(thing, ios.readObject()); |
68 | 69 | ios.close(); |
69 | ||
70 | ||
70 | 71 | // ensure that XStream does not cause endless loop for a Thing |
71 | 72 | xstream.alias("thing", Thing.class); |
72 | 73 | |
73 | String expectedXml = "" | |
74 | + "<thing>\n" | |
75 | + " <a>3000</a>\n" | |
76 | + " <b>6000</b>\n" | |
77 | + "</thing>"; | |
74 | final String expectedXml = "" + "<thing>\n" + " <a>3000</a>\n" + " <b>6000</b>\n" + "</thing>"; | |
78 | 75 | |
79 | 76 | assertBothWays(thing, expectedXml); |
80 | 77 | } |
83 | 80 | xstream.alias("original-class", Original.class); |
84 | 81 | xstream.alias("replaced-class", Replaced.class); |
85 | 82 | |
86 | Original in = new Original("hello world"); | |
87 | ||
88 | String expectedXml = "" | |
89 | + "<original-class resolves-to=\"replaced-class\">\n" | |
90 | + " <replacedValue>HELLO WORLD</replacedValue>\n" | |
91 | + "</original-class>"; | |
83 | final Original in = new Original("hello world"); | |
84 | ||
85 | final String expectedXml = "" | |
86 | + "<original-class resolves-to=\"replaced-class\">\n" | |
87 | + " <replacedValue>HELLO WORLD</replacedValue>\n" | |
88 | + "</original-class>"; | |
92 | 89 | |
93 | 90 | assertBothWays(in, expectedXml); |
94 | 91 | } |
97 | 94 | xstream.alias("original-class", Original.class); |
98 | 95 | xstream.alias("replaced-class", Replaced.class); |
99 | 96 | |
100 | List in = new ArrayList(); | |
97 | final List in = new ArrayList(); | |
101 | 98 | in.add(new Original("hello world")); |
102 | 99 | |
103 | String expectedXml = "" | |
104 | + "<list>\n" | |
105 | + " <original-class resolves-to=\"replaced-class\">\n" | |
106 | + " <replacedValue>HELLO WORLD</replacedValue>\n" | |
107 | + " </original-class>\n" | |
108 | + "</list>"; | |
100 | final String expectedXml = "" | |
101 | + "<list>\n" | |
102 | + " <original-class resolves-to=\"replaced-class\">\n" | |
103 | + " <replacedValue>HELLO WORLD</replacedValue>\n" | |
104 | + " </original-class>\n" | |
105 | + "</list>"; | |
109 | 106 | |
110 | 107 | assertBothWays(in, expectedXml); |
111 | 108 | } |
113 | 110 | public static class Container extends StandardObject { |
114 | 111 | Original original; |
115 | 112 | } |
116 | ||
113 | ||
117 | 114 | public void testAllowsDifferentTypeToBeSubstitutedAsMember() { |
118 | 115 | xstream.alias("container", Container.class); |
119 | 116 | xstream.alias("original-class", Original.class); |
120 | 117 | xstream.alias("replaced-class", Replaced.class); |
121 | 118 | |
122 | Container in = new Container(); | |
119 | final Container in = new Container(); | |
123 | 120 | in.original = new Original("hello world"); |
124 | 121 | |
125 | String expectedXml = "" | |
126 | + "<container>\n" | |
127 | + " <original resolves-to=\"replaced-class\">\n" | |
128 | + " <replacedValue>HELLO WORLD</replacedValue>\n" | |
129 | + " </original>\n" | |
130 | + "</container>"; | |
122 | final String expectedXml = "" | |
123 | + "<container>\n" | |
124 | + " <original resolves-to=\"replaced-class\">\n" | |
125 | + " <replacedValue>HELLO WORLD</replacedValue>\n" | |
126 | + " </original>\n" | |
127 | + "</container>"; | |
131 | 128 | |
132 | 129 | assertBothWays(in, expectedXml); |
133 | 130 | } |
134 | 131 | |
135 | 132 | public static class ExternalizableContainer extends StandardObject implements Externalizable { |
136 | 133 | Original original; |
137 | ||
138 | public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { | |
134 | ||
135 | public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { | |
139 | 136 | original = (Original)in.readObject(); |
140 | 137 | } |
141 | 138 | |
142 | public void writeExternal(ObjectOutput out) throws IOException { | |
139 | public void writeExternal(final ObjectOutput out) throws IOException { | |
143 | 140 | out.writeObject(original); |
144 | 141 | } |
145 | 142 | } |
146 | ||
143 | ||
147 | 144 | public void testAllowsDifferentTypeToBeSubstitutedInExternalizable() { |
148 | 145 | xstream.alias("container", ExternalizableContainer.class); |
149 | 146 | xstream.alias("original-class", Original.class); |
150 | 147 | xstream.alias("replaced-class", Replaced.class); |
151 | 148 | |
152 | ExternalizableContainer in = new ExternalizableContainer(); | |
149 | final ExternalizableContainer in = new ExternalizableContainer(); | |
153 | 150 | in.original = new Original("hello world"); |
154 | 151 | |
155 | String expectedXml = "" | |
156 | + "<container>\n" | |
157 | + " <original-class resolves-to=\"replaced-class\">\n" | |
158 | + " <replacedValue>HELLO WORLD</replacedValue>\n" | |
159 | + " </original-class>\n" | |
160 | + "</container>"; | |
152 | final String expectedXml = "" | |
153 | + "<container>\n" | |
154 | + " <original-class resolves-to=\"replaced-class\">\n" | |
155 | + " <replacedValue>HELLO WORLD</replacedValue>\n" | |
156 | + " </original-class>\n" | |
157 | + "</container>"; | |
161 | 158 | |
162 | 159 | assertBothWays(in, expectedXml); |
163 | 160 | } |
166 | 163 | xstream.alias("original-class", Original.class); |
167 | 164 | xstream.alias("replaced-class", Replaced.class); |
168 | 165 | |
169 | Original in = new Original("hello world"); | |
170 | ||
171 | String xml = "" | |
172 | + "<original-class resolves-to=\"replaced-class\" class=\"not.Existing\">\n" | |
173 | + " <replacedValue>HELLO WORLD</replacedValue>\n" | |
174 | + "</original-class>"; | |
166 | final Original in = new Original("hello world"); | |
167 | ||
168 | final String xml = "" | |
169 | + "<original-class resolves-to=\"replaced-class\" class=\"not.Existing\">\n" | |
170 | + " <replacedValue>HELLO WORLD</replacedValue>\n" | |
171 | + "</original-class>"; | |
175 | 172 | |
176 | 173 | assertEquals(in, xstream.fromXML(xml)); |
177 | 174 | } |
180 | 177 | xstream.alias("original-class", Original.class); |
181 | 178 | xstream.alias("replaced-class", Replaced.class); |
182 | 179 | |
183 | List in = new ArrayList(); | |
180 | final List in = new ArrayList(); | |
184 | 181 | in.add(new Original("hello world")); |
185 | 182 | |
186 | String xml = "" | |
187 | + "<list>\n" | |
188 | + " <original-class resolves-to=\"replaced-class\" class=\"not.Existing\">\n" | |
189 | + " <replacedValue>HELLO WORLD</replacedValue>\n" | |
190 | + " </original-class>\n" | |
191 | + "</list>"; | |
183 | final String xml = "" | |
184 | + "<list>\n" | |
185 | + " <original-class resolves-to=\"replaced-class\" class=\"not.Existing\">\n" | |
186 | + " <replacedValue>HELLO WORLD</replacedValue>\n" | |
187 | + " </original-class>\n" | |
188 | + "</list>"; | |
192 | 189 | |
193 | 190 | assertEquals(in, xstream.fromXML(xml)); |
194 | 191 | } |
198 | 195 | xstream.alias("original-class", Original.class); |
199 | 196 | xstream.alias("replaced-class", Replaced.class); |
200 | 197 | |
201 | Container in = new Container(); | |
198 | final Container in = new Container(); | |
202 | 199 | in.original = new Original("hello world"); |
203 | 200 | |
204 | String xml = "" | |
205 | + "<container>\n" | |
206 | + " <original resolves-to=\"replaced-class\" class=\"not.Existing\">\n" | |
207 | + " <replacedValue>HELLO WORLD</replacedValue>\n" | |
208 | + " </original>\n" | |
209 | + "</container>"; | |
201 | final String xml = "" | |
202 | + "<container>\n" | |
203 | + " <original resolves-to=\"replaced-class\" class=\"not.Existing\">\n" | |
204 | + " <replacedValue>HELLO WORLD</replacedValue>\n" | |
205 | + " </original>\n" | |
206 | + "</container>"; | |
210 | 207 | |
211 | 208 | assertEquals(in, xstream.fromXML(xml)); |
212 | 209 | } |
213 | ||
210 | ||
214 | 211 | public void testAllowsDifferentTypeToBeSubstitutedWithNonExistingClassInExternalizable() { |
215 | 212 | xstream.alias("container", ExternalizableContainer.class); |
216 | 213 | xstream.alias("original-class", Original.class); |
217 | 214 | xstream.alias("replaced-class", Replaced.class); |
218 | 215 | |
219 | ExternalizableContainer in = new ExternalizableContainer(); | |
216 | final ExternalizableContainer in = new ExternalizableContainer(); | |
220 | 217 | in.original = new Original("hello world"); |
221 | 218 | |
222 | String xml = "" | |
223 | + "<container>\n" | |
224 | + " <original-class resolves-to=\"replaced-class\" class=\"not.Existing\">\n" | |
225 | + " <replacedValue>HELLO WORLD</replacedValue>\n" | |
226 | + " </original-class>\n" | |
227 | + "</container>"; | |
219 | final String xml = "" | |
220 | + "<container>\n" | |
221 | + " <original-class resolves-to=\"replaced-class\" class=\"not.Existing\">\n" | |
222 | + " <replacedValue>HELLO WORLD</replacedValue>\n" | |
223 | + " </original-class>\n" | |
224 | + "</container>"; | |
228 | 225 | |
229 | 226 | assertEquals(in, xstream.fromXML(xml)); |
230 | 227 | } |
235 | 232 | public OriginalSerializable() { |
236 | 233 | } |
237 | 234 | |
238 | public OriginalSerializable(String originalValue) { | |
235 | public OriginalSerializable(final String originalValue) { | |
239 | 236 | this.originalValue = originalValue; |
240 | 237 | } |
241 | 238 | |
243 | 240 | return new ReplacedSerializable(originalValue.toUpperCase()); |
244 | 241 | } |
245 | 242 | |
246 | private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { | |
243 | private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { | |
247 | 244 | in.defaultReadObject(); |
248 | 245 | } |
249 | 246 | } |
254 | 251 | public ReplacedSerializable() { |
255 | 252 | } |
256 | 253 | |
257 | public ReplacedSerializable(String replacedValue) { | |
254 | public ReplacedSerializable(final String replacedValue) { | |
258 | 255 | this.replacedValue = replacedValue; |
259 | 256 | } |
260 | 257 | |
262 | 259 | return new OriginalSerializable(replacedValue.toLowerCase()); |
263 | 260 | } |
264 | 261 | |
265 | private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { | |
262 | private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { | |
266 | 263 | in.defaultReadObject(); |
267 | 264 | } |
268 | 265 | } |
271 | 268 | xstream.alias("original-serializable-class", OriginalSerializable.class); |
272 | 269 | xstream.alias("replaced-serializable-class", ReplacedSerializable.class); |
273 | 270 | |
274 | OriginalSerializable in = new OriginalSerializable("hello world"); | |
275 | ||
276 | String expectedXml = "" | |
277 | + "<original-serializable-class resolves-to=\"replaced-serializable-class\" serialization=\"custom\">\n" | |
278 | + " <replaced-serializable-class>\n" | |
279 | + " <default>\n" | |
280 | + " <replacedValue>HELLO WORLD</replacedValue>\n" | |
281 | + " </default>\n" | |
282 | + " </replaced-serializable-class>\n" | |
283 | + "</original-serializable-class>"; | |
271 | final OriginalSerializable in = new OriginalSerializable("hello world"); | |
272 | ||
273 | final String expectedXml = "" | |
274 | + "<original-serializable-class resolves-to=\"replaced-serializable-class\" serialization=\"custom\">\n" | |
275 | + " <replaced-serializable-class>\n" | |
276 | + " <default>\n" | |
277 | + " <replacedValue>HELLO WORLD</replacedValue>\n" | |
278 | + " </default>\n" | |
279 | + " </replaced-serializable-class>\n" | |
280 | + "</original-serializable-class>"; | |
284 | 281 | |
285 | 282 | assertBothWays(in, expectedXml); |
286 | 283 | } |
291 | 288 | public OriginalExternalizable() { |
292 | 289 | } |
293 | 290 | |
294 | public OriginalExternalizable(String originalValue) { | |
291 | public OriginalExternalizable(final String originalValue) { | |
295 | 292 | this.originalValue = originalValue; |
296 | 293 | } |
297 | 294 | |
299 | 296 | return new ReplacedExternalizable(originalValue.toUpperCase()); |
300 | 297 | } |
301 | 298 | |
302 | public void writeExternal(ObjectOutput out) throws IOException { | |
299 | public void writeExternal(final ObjectOutput out) throws IOException { | |
303 | 300 | out.writeObject(originalValue); |
304 | 301 | } |
305 | 302 | |
306 | public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { | |
303 | public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { | |
307 | 304 | originalValue = (String)in.readObject(); |
308 | 305 | } |
309 | 306 | } |
314 | 311 | public ReplacedExternalizable() { |
315 | 312 | } |
316 | 313 | |
317 | public ReplacedExternalizable(String replacedValue) { | |
314 | public ReplacedExternalizable(final String replacedValue) { | |
318 | 315 | this.replacedValue = replacedValue; |
319 | 316 | } |
320 | 317 | |
322 | 319 | return new OriginalExternalizable(replacedValue.toLowerCase()); |
323 | 320 | } |
324 | 321 | |
325 | public void writeExternal(ObjectOutput out) throws IOException { | |
322 | public void writeExternal(final ObjectOutput out) throws IOException { | |
326 | 323 | out.writeObject(StringUtils.reverse(replacedValue)); |
327 | 324 | } |
328 | 325 | |
329 | public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { | |
326 | public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { | |
330 | 327 | replacedValue = StringUtils.reverse((String)in.readObject()); |
331 | 328 | } |
332 | 329 | } |
335 | 332 | xstream.alias("original-externalizable-class", OriginalExternalizable.class); |
336 | 333 | xstream.alias("replaced-externalizable-class", ReplacedExternalizable.class); |
337 | 334 | |
338 | OriginalExternalizable in = new OriginalExternalizable("hello world"); | |
339 | ||
340 | String expectedXml = "" | |
341 | + "<original-externalizable-class resolves-to=\"replaced-externalizable-class\">\n" | |
342 | + " <string>DLROW OLLEH</string>\n" | |
343 | + "</original-externalizable-class>"; | |
335 | final OriginalExternalizable in = new OriginalExternalizable("hello world"); | |
336 | ||
337 | final String expectedXml = "" | |
338 | + "<original-externalizable-class resolves-to=\"replaced-externalizable-class\">\n" | |
339 | + " <string>DLROW OLLEH</string>\n" | |
340 | + "</original-externalizable-class>"; | |
341 | ||
342 | assertBothWays(in, expectedXml); | |
343 | } | |
344 | ||
345 | public static class OriginalThing extends StandardObject { | |
346 | private final String value; | |
347 | ||
348 | public OriginalThing() { | |
349 | this(""); | |
350 | } | |
351 | ||
352 | public OriginalThing(final String value) { | |
353 | this.value = value; | |
354 | } | |
355 | ||
356 | private Object writeReplace() { | |
357 | return new IntermediateThing(value); | |
358 | } | |
359 | } | |
360 | ||
361 | public static class IntermediateThing { | |
362 | private final String value; | |
363 | ||
364 | public IntermediateThing(final String value) { | |
365 | this.value = value; | |
366 | } | |
367 | ||
368 | private Object writeReplace() { | |
369 | return new ReplacedThing(value); | |
370 | } | |
371 | } | |
372 | ||
373 | public static class ReplacedThing { | |
374 | private final String value; | |
375 | ||
376 | public ReplacedThing(final String value) { | |
377 | this.value = value; | |
378 | } | |
379 | ||
380 | private Object readResolve() { | |
381 | return new OriginalThing(value); | |
382 | } | |
383 | } | |
384 | ||
385 | public void testCascadedWriteReplace() { | |
386 | xstream.alias("original-thing", OriginalThing.class); | |
387 | xstream.alias("intermediate-thing", IntermediateThing.class); | |
388 | xstream.alias("replaced-thing", ReplacedThing.class); | |
389 | ||
390 | final OriginalThing in = new OriginalThing("hello world"); | |
391 | ||
392 | final String expectedXml = "" | |
393 | + "<original-thing resolves-to=\"replaced-thing\">\n" | |
394 | + " <value>hello world</value>\n" | |
395 | + "</original-thing>"; | |
344 | 396 | |
345 | 397 | assertBothWays(in, expectedXml); |
346 | 398 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2014 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2014, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
81 | 81 | public void testCanSerializeSelfContained() throws ClassNotFoundException, ObjectStreamException { |
82 | 82 | final OpenSourceSoftware oos = new OpenSourceSoftware("Walnes", "XStream", "BSD"); |
83 | 83 | xstream.alias("software", OpenSourceSoftware.class); |
84 | final TypePermission[] permissions = XStreamer.getDefaultPermissions(); | |
85 | for(int i = 0; i < permissions.length; ++i) | |
86 | xstream.addPermission(permissions[i]); | |
84 | 87 | String xml = new XStreamer().toXML(xstream, oos); |
85 | assertEquals(oos, new XStreamer().fromXML(xml)); | |
88 | assertEquals(oos, new XStreamer().fromXML(xml, XStreamer.getDefaultPermissions())); | |
86 | 89 | } |
87 | 90 | |
88 | 91 | private String normalizedXStreamXML(String xml) throws TransformerException { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2011 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2011, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
203 | 203 | + " <percent>%</percent>\n" |
204 | 204 | + " <serialVersionOnStream>1</serialVersionOnStream>\n" |
205 | 205 | + " <zeroDigit>0</zeroDigit>\n" |
206 | + " <NaN>\ufffd</NaN>\n" | |
206 | + " <NaN>NaN</NaN>\n" | |
207 | 207 | + " <currencySymbol>DM</currencySymbol>\n" |
208 | 208 | + " <infinity>\u221e</infinity>\n" |
209 | 209 | + " <intlCurrencySymbol>DEM</intlCurrencySymbol>\n" |
225 | 225 | + " <percent>%</percent>\n" |
226 | 226 | + " <serialVersionOnStream>2</serialVersionOnStream>\n" |
227 | 227 | + " <zeroDigit>0</zeroDigit>\n" |
228 | + " <NaN>\ufffd</NaN>\n" | |
228 | + " <NaN>NaN</NaN>\n" | |
229 | 229 | + " <currencySymbol>\u20ac</currencySymbol>\n" |
230 | 230 | + " <infinity>\u221e</infinity>\n" |
231 | 231 | + " <intlCurrencySymbol>EUR</intlCurrencySymbol>\n" |
248 | 248 | + " <percent>%</percent>\n" |
249 | 249 | + " <serialVersionOnStream>3</serialVersionOnStream>\n" |
250 | 250 | + " <zeroDigit>0</zeroDigit>\n" |
251 | + " <NaN>\ufffd</NaN>\n" | |
251 | + " <NaN>NaN</NaN>\n" | |
252 | 252 | + " <currencySymbol>\u20ac</currencySymbol>\n" |
253 | 253 | + " <exponentialSeparator>E</exponentialSeparator>\n" |
254 | 254 | + " <infinity>\u221e</infinity>\n" |
259 | 259 | + "</java.text.DecimalFormatSymbols>"; |
260 | 260 | } |
261 | 261 | final DecimalFormatSymbols format = new DecimalFormatSymbols(Locale.GERMANY); |
262 | format.setNaN("NaN"); | |
263 | assertEquals("EUR", format.getInternationalCurrencySymbol()); | |
262 | 264 | assertBothWays(format, xml); |
263 | 265 | } |
264 | 266 |
+6
-4
0 | 0 | /* |
1 | * Copyright (C) 2007 XStream Committers. | |
1 | * Copyright (C) 2007, 2017 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
26 | 26 | protected void setUp() throws Exception { |
27 | 27 | super.setUp(); |
28 | 28 | xstream = new XStream(); |
29 | xstream.registerConverter( | |
30 | new AnnotationReflectionConverter(xstream.getMapper(), xstream | |
31 | .getReflectionProvider(), new AnnotationProvider()), XStream.PRIORITY_VERY_LOW); | |
29 | XStream.setupDefaultSecurity(xstream); | |
30 | xstream.allowTypes(new Class[]{ | |
31 | FieldConverterTest.TaskWithAnnotations.class, ImplicitCollectionTest.ImplicitRootOne.class}); | |
32 | xstream.registerConverter(new AnnotationReflectionConverter(xstream.getMapper(), xstream | |
33 | .getReflectionProvider(), new AnnotationProvider()), XStream.PRIORITY_VERY_LOW); | |
32 | 34 | xstream.alias("annotatedTask", FieldConverterTest.TaskWithAnnotations.class); |
33 | 35 | } |
34 | 36 |
+12
-32
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.converters.collections; |
12 | 12 | |
13 | import com.thoughtworks.xstream.XStream; | |
14 | ||
15 | import junit.framework.TestCase; | |
13 | import com.thoughtworks.acceptance.AbstractAcceptanceTest; | |
16 | 14 | |
17 | 15 | import java.util.Properties; |
18 | 16 | |
19 | public class PropertiesConverterTest extends TestCase { | |
17 | public class PropertiesConverterTest extends AbstractAcceptanceTest { | |
20 | 18 | |
21 | 19 | public void testConvertsPropertiesObjectToShortKeyValueElements() { |
22 | Properties in = new Properties(); | |
23 | in.setProperty("hello", "world"); | |
24 | in.setProperty("foo", "cheese"); | |
20 | Properties properties = new Properties(); | |
21 | properties.setProperty("hello", "world"); | |
22 | properties.setProperty("foo", "cheese"); | |
25 | 23 | |
26 | String expectedXML = "" + | |
24 | String expected = "" + | |
27 | 25 | "<properties>\n" + |
28 | 26 | " <property name=\"hello\" value=\"world\"/>\n" + |
29 | 27 | " <property name=\"foo\" value=\"cheese\"/>\n" + |
30 | 28 | "</properties>"; |
31 | XStream xstream = new XStream(); | |
32 | String actualXML = xstream.toXML(in); | |
33 | assertEquals(expectedXML, actualXML); | |
34 | ||
35 | Properties expectedOut = new Properties(); | |
36 | expectedOut.setProperty("hello", "world"); | |
37 | expectedOut.setProperty("foo", "cheese"); | |
38 | Properties actualOut = (Properties) xstream.fromXML(actualXML); | |
39 | assertEquals(in, actualOut); | |
40 | assertEquals(in.toString(), actualOut.toString()); | |
41 | ||
29 | assertBothWaysNormalized(properties, expected, "properties", "property", "@name"); | |
42 | 30 | } |
43 | 31 | |
44 | 32 | public void testIncludesDefaultProperties() { |
53 | 41 | assertEquals("Unexpected overriden property", "999", override.getProperty("port")); |
54 | 42 | assertEquals("Unexpected default property", "localhost", override.getProperty("host")); |
55 | 43 | |
56 | String expectedXML = "" + | |
44 | String expected = "" + | |
57 | 45 | "<properties>\n" + |
58 | 46 | " <property name=\"port\" value=\"999\"/>\n" + |
59 | 47 | " <defaults>\n" + |
62 | 50 | " </defaults>\n" + |
63 | 51 | "</properties>"; |
64 | 52 | |
65 | XStream xstream = new XStream(); | |
66 | String actualXML = xstream.toXML(override); | |
67 | assertEquals(expectedXML, actualXML); | |
68 | ||
69 | Properties out = (Properties) xstream.fromXML(actualXML); | |
53 | Properties out = (Properties) assertBothWays(override, expected); | |
70 | 54 | assertEquals("Unexpected overriden property", "999", out.getProperty("port")); |
71 | 55 | assertEquals("Unexpected default property", "localhost", out.getProperty("host")); |
72 | 56 | assertEquals(override, out); |
81 | 65 | override.setProperty("port", "999"); |
82 | 66 | override.setProperty("domain", "codehaus.org"); |
83 | 67 | |
84 | String expectedXML = "" + | |
68 | String expected = "" + | |
85 | 69 | "<properties>\n" + |
86 | 70 | " <property name=\"domain\" value=\"codehaus.org\"/>\n" + |
87 | 71 | " <property name=\"port\" value=\"999\"/>\n" + |
91 | 75 | " </defaults>\n" + |
92 | 76 | "</properties>"; |
93 | 77 | |
94 | XStream xstream = new XStream(); | |
95 | 78 | xstream.registerConverter(new PropertiesConverter(true)); |
96 | String actualXML = xstream.toXML(override); | |
97 | assertEquals(expectedXML, actualXML); | |
98 | ||
99 | Properties out = (Properties) xstream.fromXML(actualXML); | |
79 | Properties out = (Properties) assertBothWays(override, expected); | |
100 | 80 | assertEquals("Unexpected overriden property", "999", out.getProperty("port")); |
101 | 81 | assertEquals("Unexpected default property", "localhost", out.getProperty("host")); |
102 | 82 | assertEquals(override, out); |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
11 | 11 | package com.thoughtworks.xstream.converters.enums; |
12 | 12 | |
13 | 13 | import com.thoughtworks.xstream.XStream; |
14 | ||
14 | 15 | import junit.framework.TestCase; |
15 | 16 | |
16 | 17 | // ***** READ THIS ***** |
28 | 29 | protected void setUp() throws Exception { |
29 | 30 | super.setUp(); |
30 | 31 | xstream = new XStream(); |
32 | XStream.setupDefaultSecurity(xstream); | |
31 | 33 | xstream.alias("simple", SimpleEnum.class); |
32 | 34 | xstream.alias("polymorphic", PolymorphicEnum.class); |
33 | 35 | } |
+3
-1
0 | 0 | /* |
1 | * Copyright (C) 2008 XStream Committers. | |
1 | * Copyright (C) 2008, 2017 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
29 | 29 | protected void setUp() throws Exception { |
30 | 30 | super.setUp(); |
31 | 31 | xstream = new XStream(); |
32 | XStream.setupDefaultSecurity(xstream); | |
33 | xstream.allowTypes(new Class[] {TypeWithEnums.class}); | |
32 | 34 | xstream.alias("simple", SimpleEnum.class); |
33 | 35 | xstream.alias("polymorphic", PolymorphicEnum.class); |
34 | 36 | } |
+2
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
23 | 23 | protected void setUp() throws Exception { |
24 | 24 | super.setUp(); |
25 | 25 | xstream = new XStream(); |
26 | XStream.setupDefaultSecurity(xstream); | |
26 | 27 | } |
27 | 28 | |
28 | 29 | public void testIncludesEnumTypeInSerializedForm() { |
0 | 0 | /* |
1 | * Copyright (C) 2008 XStream Committers. | |
1 | * Copyright (C) 2008, 2017 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
33 | 33 | protected void setUp() throws Exception { |
34 | 34 | super.setUp(); |
35 | 35 | xstream = new XStream(); |
36 | XStream.setupDefaultSecurity(xstream); | |
37 | xstream.allowTypesByWildcard(new String[] {getClass().getName()+"$*"}); | |
36 | 38 | xstream.alias("simple", SimpleEnum.class); |
37 | 39 | xstream.alias("polymorphic", PolymorphicEnum.class); |
38 | 40 | } |
+3
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2013, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
11 | 11 | package com.thoughtworks.xstream.converters.enums; |
12 | 12 | |
13 | 13 | import com.thoughtworks.xstream.XStream; |
14 | ||
14 | 15 | import junit.framework.TestCase; |
15 | 16 | |
16 | 17 | import java.util.EnumSet; |
22 | 23 | protected void setUp() throws Exception { |
23 | 24 | super.setUp(); |
24 | 25 | xstream = new XStream(); |
26 | XStream.setupDefaultSecurity(xstream); | |
25 | 27 | } |
26 | 28 | |
27 | 29 | public void testPutsEnumsInCompactCommaSeparatedString() { |
+3
-1
0 | 0 | /* |
1 | * Copyright (C) 2013 XStream Committers. | |
1 | * Copyright (C) 2013, 2017 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
13 | 13 | import java.util.Map; |
14 | 14 | |
15 | 15 | import com.thoughtworks.xstream.XStream; |
16 | ||
16 | 17 | import junit.framework.TestCase; |
17 | 18 | |
18 | 19 | |
30 | 31 | protected void setUp() throws Exception { |
31 | 32 | super.setUp(); |
32 | 33 | xstream = new XStream(); |
34 | XStream.setupDefaultSecurity(xstream); | |
33 | 35 | xstream.alias("simple", SimpleEnum.class); |
34 | 36 | xstream.alias("big", BigEnum.class); |
35 | 37 | xstream.alias("polymorphic", PolymorphicEnum.class); |
+5
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2013, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
21 | 21 | import java.awt.Font; |
22 | 22 | import java.awt.Toolkit; |
23 | 23 | import java.awt.font.TextAttribute; |
24 | import java.awt.font.TransformAttribute; | |
25 | import java.awt.geom.AffineTransform; | |
24 | 26 | import java.util.Map; |
25 | 27 | |
26 | 28 | public class FontConverterTest extends TestCase { |
41 | 43 | super.setUp(); |
42 | 44 | // fonts should be serializable also with pure Java |
43 | 45 | xstream = new XStream(new PureJavaReflectionProvider()); |
46 | XStream.setupDefaultSecurity(xstream); | |
47 | xstream.allowTypes(new Class[] {Font.class, TextAttribute.class, TransformAttribute.class, AffineTransform.class}); | |
44 | 48 | in = new Font("Arial", Font.BOLD, 20); |
45 | 49 | } |
46 | 50 |
+2
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
25 | 25 | public void testCalendar() { |
26 | 26 | final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); |
27 | 27 | final XStream xstream = new XStream(); |
28 | XStream.setupDefaultSecurity(xstream); | |
28 | 29 | final String xml = xstream.toXML(cal); |
29 | 30 | final Calendar serialized = (Calendar)xstream.fromXML(xml); |
30 | 31 | assertEquals(cal, serialized); |
+2
-2
0 | 0 | /* |
1 | * 2013 XStream Committers. | |
1 | * 2013, 2017 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
45 | 45 | |
46 | 46 | String converterXML = converter.toString(in); |
47 | 47 | Calendar out = (Calendar) converter.fromString(converterXML); |
48 | assertEquals(in, out); | |
48 | assertEquals(in.getTime(), out.getTime()); | |
49 | 49 | } finally { |
50 | 50 | Locale.setDefault(defaultLocale); |
51 | 51 | Locale.setDefault(defaultLocaleForFormat); |
+268
-38
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2011 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2011, 2017, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
6 | 6 | * style license a copy of which has been included with this distribution in |
7 | 7 | * the LICENSE.txt file. |
8 | * | |
8 | * | |
9 | 9 | * Created on 03. October 2005 by Joerg Schaible |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.converters.extended; |
12 | ||
13 | import com.thoughtworks.xstream.converters.ConversionException; | |
14 | import com.thoughtworks.xstream.testutil.TimeZoneChanger; | |
15 | ||
16 | import junit.framework.TestCase; | |
17 | ||
18 | import org.joda.time.DateTime; | |
19 | 12 | |
20 | 13 | import java.util.ArrayList; |
21 | 14 | import java.util.Calendar; |
22 | 15 | import java.util.Collections; |
23 | 16 | import java.util.List; |
17 | import java.util.Locale; | |
24 | 18 | import java.util.TimeZone; |
25 | 19 | |
20 | import org.joda.time.DateTime; | |
21 | ||
22 | import com.thoughtworks.xstream.converters.ConversionException; | |
23 | import com.thoughtworks.xstream.core.JVM; | |
24 | import com.thoughtworks.xstream.testutil.TimeZoneChanger; | |
25 | ||
26 | import junit.framework.TestCase; | |
27 | ||
28 | ||
26 | 29 | public class ISO8601GregorianCalendarConverterTest extends TestCase { |
27 | 30 | |
31 | private Locale locale; | |
28 | 32 | private ISO8601GregorianCalendarConverter converter; |
29 | 33 | |
30 | 34 | protected void setUp() throws Exception { |
31 | 35 | super.setUp(); |
32 | 36 | converter = new ISO8601GregorianCalendarConverter(); |
33 | ||
37 | locale = Locale.getDefault(); | |
38 | Locale.setDefault(Locale.GERMANY); | |
39 | ||
34 | 40 | // Ensure that this test always run as if it were in the timezone of Panama. |
35 | 41 | // This prevents failures when running the tests in different zones. |
36 | 42 | // Note: 'America/Panama' has no relevance - it was just a randomly chosen zone. |
39 | 45 | |
40 | 46 | protected void tearDown() throws Exception { |
41 | 47 | TimeZoneChanger.reset(); |
48 | Locale.setDefault(locale); | |
42 | 49 | super.tearDown(); |
43 | 50 | } |
44 | 51 | |
45 | 52 | public void testRetainsDetailDownToMillisecondLevel() { |
46 | 53 | // setup |
47 | Calendar in = Calendar.getInstance(); | |
54 | final Calendar in = Calendar.getInstance(); | |
48 | 55 | |
49 | 56 | // execute |
50 | String text = converter.toString(in); | |
51 | Calendar out = (Calendar) converter.fromString(text); | |
57 | final String text = converter.toString(in); | |
58 | final Calendar out = (Calendar)converter.fromString(text); | |
52 | 59 | |
53 | 60 | // verify |
54 | assertEquals(in, out); | |
55 | } | |
56 | ||
61 | assertEquals(in.getTime(), out.getTime()); | |
62 | } | |
63 | ||
57 | 64 | public void testSavedTimeIsInUTC() { |
58 | Calendar in = Calendar.getInstance(); | |
65 | final Calendar in = Calendar.getInstance(); | |
59 | 66 | final String iso8601; |
60 | 67 | iso8601 = new DateTime(in).toString(); |
61 | String converterXML = converter.toString(in); | |
68 | final String converterXML = converter.toString(in); | |
62 | 69 | assertEquals(iso8601, converterXML); |
63 | ||
64 | Calendar out = (Calendar) converter.fromString(converterXML); | |
65 | assertEquals(in, out); | |
66 | } | |
67 | ||
70 | ||
71 | final Calendar out = (Calendar)converter.fromString(converterXML); | |
72 | assertEquals(in.getTime(), out.getTime()); | |
73 | } | |
74 | ||
68 | 75 | public void testCanLoadTimeInDifferentTimeZone() { |
69 | Calendar in = Calendar.getInstance(); | |
70 | String converterXML = converter.toString(in); | |
76 | final Calendar in = Calendar.getInstance(); | |
77 | final String converterXML = converter.toString(in); | |
71 | 78 | |
72 | 79 | TimeZone.setDefault(TimeZone.getTimeZone("Europe/Moscow")); |
73 | Calendar timeInMoscow = Calendar.getInstance(); | |
80 | final Calendar timeInMoscow = Calendar.getInstance(); | |
74 | 81 | timeInMoscow.setTime(in.getTime()); |
75 | Calendar out = (Calendar) converter.fromString(converterXML); | |
76 | assertEquals(timeInMoscow, out); | |
77 | } | |
78 | ||
82 | final Calendar out = (Calendar)converter.fromString(converterXML); | |
83 | assertEquals(timeInMoscow.getTime(), out.getTime()); | |
84 | } | |
85 | ||
86 | public void testParsesBasicDateTime() { | |
87 | final Calendar expected = Calendar.getInstance(); | |
88 | expected.clear(); | |
89 | expected.set(2017, 4, 7, 19, 11, 22); | |
90 | Calendar out = (Calendar)converter.fromString("20170508T001122Z"); | |
91 | assertEquals(expected.getTime(), out.getTime()); | |
92 | expected.set(Calendar.MILLISECOND, 300); | |
93 | out = (Calendar)converter.fromString("20170508T001122.300Z"); | |
94 | assertEquals(expected.getTime(), out.getTime()); | |
95 | expected.set(2017, 3, 20, 19, 11, 22); | |
96 | } | |
97 | ||
98 | public void testParsesBasicOrdinalDateTime() { | |
99 | final Calendar expected = Calendar.getInstance(); | |
100 | expected.clear(); | |
101 | expected.set(2017, 3, 20, 19, 11, 22); | |
102 | Calendar out = (Calendar)converter.fromString("2017111T001122Z"); | |
103 | assertEquals(expected.getTime(), out.getTime()); | |
104 | expected.set(Calendar.MILLISECOND, 300); | |
105 | out = (Calendar)converter.fromString("2017111T001122.300Z"); | |
106 | assertEquals(expected.getTime(), out.getTime()); | |
107 | expected.set(1970, 0, 1, 13, 11, 22); | |
108 | } | |
109 | ||
110 | public void testParsesBasicTime() { | |
111 | final Calendar expected = Calendar.getInstance(); | |
112 | expected.clear(); | |
113 | expected.set(1970, 0, 1, 13, 11, 22); | |
114 | Calendar out = (Calendar)converter.fromString("181122Z"); | |
115 | assertEquals(expected.getTime(), out.getTime()); | |
116 | expected.set(Calendar.MILLISECOND, 300); | |
117 | out = (Calendar)converter.fromString("181122.300Z"); | |
118 | assertEquals(expected.getTime(), out.getTime()); | |
119 | } | |
120 | ||
121 | public void testParsesBasicTTime() { | |
122 | final Calendar expected = Calendar.getInstance(); | |
123 | expected.clear(); | |
124 | expected.set(1970, 0, 1, 13, 11, 22); | |
125 | Calendar out = (Calendar)converter.fromString("T181122Z"); | |
126 | assertEquals(expected.getTime(), out.getTime()); | |
127 | expected.set(Calendar.MILLISECOND, 300); | |
128 | out = (Calendar)converter.fromString("T181122.300Z"); | |
129 | assertEquals(expected.getTime(), out.getTime()); | |
130 | } | |
131 | ||
132 | public void testParsesBasicWeekDateTime() { | |
133 | final Calendar expected = Calendar.getInstance(); | |
134 | expected.clear(); | |
135 | expected.set(2017, 4, 8, 13, 11, 22); | |
136 | Calendar out = (Calendar)converter.fromString("2017W191T181122Z"); | |
137 | assertEquals(expected.getTime(), out.getTime()); | |
138 | expected.set(Calendar.MILLISECOND, 300); | |
139 | out = (Calendar)converter.fromString("2017W191T181122.300Z"); | |
140 | assertEquals(expected.getTime(), out.getTime()); | |
141 | } | |
142 | ||
143 | public void testParsesBasicDate() { | |
144 | final Calendar expected = Calendar.getInstance(); | |
145 | expected.clear(); | |
146 | expected.set(2017, 3, 21); | |
147 | final Calendar out = (Calendar)converter.fromString("20170421"); | |
148 | assertEquals(expected.getTime(), out.getTime()); | |
149 | } | |
150 | ||
151 | public void testParsesBasicOrdinalDate() { | |
152 | final Calendar expected = Calendar.getInstance(); | |
153 | expected.clear(); | |
154 | expected.set(2017, 3, 21); | |
155 | final Calendar out = (Calendar)converter.fromString("2017111"); | |
156 | assertEquals(expected.getTime(), out.getTime()); | |
157 | } | |
158 | ||
159 | public void testParsesBasicWeekDate() { | |
160 | final Calendar expected = Calendar.getInstance(); | |
161 | expected.clear(); | |
162 | expected.set(2017, 3, 21); | |
163 | final Calendar out = (Calendar)converter.fromString("2017W165"); | |
164 | assertEquals(expected.getTime(), out.getTime()); | |
165 | } | |
166 | ||
167 | public void testParsesStandardDateTime() { | |
168 | final Calendar expected = Calendar.getInstance(); | |
169 | expected.clear(); | |
170 | expected.set(2017, 4, 7, 19, 11, 22); | |
171 | Calendar out = (Calendar)converter.fromString("2017-05-08T00:11:22Z"); | |
172 | assertEquals(expected.getTime(), out.getTime()); | |
173 | expected.set(Calendar.MILLISECOND, 300); | |
174 | out = (Calendar)converter.fromString("2017-05-08T00:11:22.300Z"); | |
175 | assertEquals(expected.getTime(), out.getTime()); | |
176 | } | |
177 | ||
178 | public void testParsesStandardOrdinalDateTime() { | |
179 | final Calendar expected = Calendar.getInstance(); | |
180 | expected.clear(); | |
181 | expected.set(2017, 3, 20, 19, 11, 22); | |
182 | Calendar out = (Calendar)converter.fromString("2017-111T00:11:22Z"); | |
183 | assertEquals(expected.getTime(), out.getTime()); | |
184 | expected.set(Calendar.MILLISECOND, 300); | |
185 | out = (Calendar)converter.fromString("2017-111T00:11:22.300Z"); | |
186 | assertEquals(expected.getTime(), out.getTime()); | |
187 | } | |
188 | ||
189 | public void testParsesStandardTime() { | |
190 | final Calendar expected = Calendar.getInstance(); | |
191 | expected.clear(); | |
192 | expected.set(1970, 0, 1, 13, 11, 22); | |
193 | Calendar out = (Calendar)converter.fromString("18:11:22Z"); | |
194 | assertEquals(expected.getTime(), out.getTime()); | |
195 | expected.set(Calendar.MILLISECOND, 300); | |
196 | out = (Calendar)converter.fromString("18:11:22.300Z"); | |
197 | assertEquals(expected.getTime(), out.getTime()); | |
198 | } | |
199 | ||
200 | public void testParsesStandardTTime() { | |
201 | final Calendar expected = Calendar.getInstance(); | |
202 | expected.clear(); | |
203 | expected.set(1970, 0, 1, 13, 11, 22); | |
204 | Calendar out = (Calendar)converter.fromString("T18:11:22Z"); | |
205 | assertEquals(expected.getTime(), out.getTime()); | |
206 | expected.set(Calendar.MILLISECOND, 300); | |
207 | out = (Calendar)converter.fromString("T18:11:22.300Z"); | |
208 | assertEquals(expected.getTime(), out.getTime()); | |
209 | } | |
210 | ||
211 | public void testParsesStandardWeekDateTime() { | |
212 | final Calendar expected = Calendar.getInstance(); | |
213 | expected.clear(); | |
214 | expected.set(2017, 4, 8, 13, 11, 22); | |
215 | Calendar out = (Calendar)converter.fromString("2017-W19-1T18:11:22Z"); | |
216 | assertEquals(expected.getTime(), out.getTime()); | |
217 | expected.set(Calendar.MILLISECOND, 300); | |
218 | out = (Calendar)converter.fromString("2017-W19-1T18:11:22.300Z"); | |
219 | assertEquals(expected.getTime(), out.getTime()); | |
220 | } | |
221 | ||
222 | public void testParsesStandardDate() { | |
223 | final Calendar expected = Calendar.getInstance(); | |
224 | expected.clear(); | |
225 | expected.set(2017, 3, 21); | |
226 | final Calendar out = (Calendar)converter.fromString("2017-04-21"); | |
227 | assertEquals(expected.getTime(), out.getTime()); | |
228 | } | |
229 | ||
230 | public void testParsesStandardOrdinalDate() { | |
231 | final Calendar expected = Calendar.getInstance(); | |
232 | expected.clear(); | |
233 | expected.set(2017, 3, 21); | |
234 | final Calendar out = (Calendar)converter.fromString("2017-111"); | |
235 | assertEquals(expected.getTime(), out.getTime()); | |
236 | } | |
237 | ||
238 | public void testParsesStandardWeekDate() { | |
239 | final Calendar expected = Calendar.getInstance(); | |
240 | expected.clear(); | |
241 | expected.set(2017, 3, 21); | |
242 | final Calendar out = (Calendar)converter.fromString("2017-W16-5"); | |
243 | assertEquals(expected.getTime(), out.getTime()); | |
244 | ||
245 | } | |
246 | ||
247 | public void testParsesStandardDateTimeFragment() { | |
248 | final Calendar expected = Calendar.getInstance(); | |
249 | expected.clear(); | |
250 | expected.set(2017, 3, 21); | |
251 | expected.set(Calendar.HOUR, 11); | |
252 | Calendar out = (Calendar)converter.fromString("2017-04-21T11"); | |
253 | assertEquals(expected.getTime(), out.getTime()); | |
254 | expected.set(Calendar.MINUTE, 22); | |
255 | out = (Calendar)converter.fromString("2017-04-21T11:22"); | |
256 | assertEquals(expected.getTime(), out.getTime()); | |
257 | expected.set(Calendar.SECOND, 33); | |
258 | out = (Calendar)converter.fromString("2017-04-21T11:22:33"); | |
259 | assertEquals(expected.getTime(), out.getTime()); | |
260 | expected.set(Calendar.MILLISECOND, 44); | |
261 | out = (Calendar)converter.fromString("2017-04-21T11:22:33.044"); | |
262 | assertEquals(expected.getTime(), out.getTime()); | |
263 | out = (Calendar)converter.fromString("2017-04-21T11:22:33.044777888"); | |
264 | assertEquals(expected.getTime(), out.getTime()); | |
265 | } | |
266 | ||
267 | public void testParsesStandardTimeFragment() { | |
268 | final Calendar expected = Calendar.getInstance(); | |
269 | expected.clear(); | |
270 | expected.set(Calendar.HOUR, 11); | |
271 | Calendar out = (Calendar)converter.fromString("11"); | |
272 | assertEquals(expected.getTime(), out.getTime()); | |
273 | expected.set(Calendar.MINUTE, 22); | |
274 | out = (Calendar)converter.fromString("11:22"); | |
275 | assertEquals(expected.getTime(), out.getTime()); | |
276 | expected.set(Calendar.SECOND, 33); | |
277 | out = (Calendar)converter.fromString("11:22:33"); | |
278 | assertEquals(expected.getTime(), out.getTime()); | |
279 | expected.set(Calendar.MILLISECOND, 44); | |
280 | out = (Calendar)converter.fromString("11:22:33.044"); | |
281 | assertEquals(expected.getTime(), out.getTime()); | |
282 | out = (Calendar)converter.fromString("11:22:33.044777888"); | |
283 | assertEquals(expected.getTime(), out.getTime()); | |
284 | } | |
285 | ||
286 | public void testParsesStandardDateFragment() { | |
287 | final Calendar expected = Calendar.getInstance(); | |
288 | expected.clear(); | |
289 | expected.set(Calendar.YEAR, 2017); | |
290 | Calendar out = (Calendar)converter.fromString("2017"); | |
291 | assertEquals(expected.getTime(), out.getTime()); | |
292 | if (JVM.isVersion(8)) { // Java 8 passes, Joda-Time fails | |
293 | expected.set(Calendar.MONTH, 3); | |
294 | out = (Calendar)converter.fromString("2017-04"); | |
295 | assertEquals(expected.getTime(), out.getTime()); | |
296 | } | |
297 | } | |
298 | ||
299 | public void testParsesStandardWeekDateFragment() { | |
300 | final Calendar expected = Calendar.getInstance(); | |
301 | expected.clear(); | |
302 | if (!JVM.isVersion(8)) { // TODO: Java 8 fails here, Joda-Time passes | |
303 | expected.set(2017, 3, 17); | |
304 | final Calendar out = (Calendar)converter.fromString("2017-W16"); | |
305 | assertEquals(expected.getTime(), out.getTime()); | |
306 | } | |
307 | } | |
308 | ||
79 | 309 | public void testCalendarWithExplicitTimeZone() { |
80 | Calendar timeInMoscow = Calendar.getInstance(); | |
310 | final Calendar timeInMoscow = Calendar.getInstance(); | |
81 | 311 | timeInMoscow.set(2010, 6, 3, 10, 20, 36); |
82 | 312 | timeInMoscow.setTimeZone(TimeZone.getTimeZone("Europe/Moscow")); |
83 | ||
84 | String converterXML = converter.toString(timeInMoscow); | |
85 | Calendar out = (Calendar) converter.fromString(converterXML); | |
313 | ||
314 | final String converterXML = converter.toString(timeInMoscow); | |
315 | final Calendar out = (Calendar)converter.fromString(converterXML); | |
86 | 316 | assertEquals(timeInMoscow.getTimeInMillis(), out.getTimeInMillis()); |
87 | ||
317 | ||
88 | 318 | out.setTimeZone(TimeZone.getTimeZone("Europe/Moscow")); |
89 | assertEquals(timeInMoscow, out); | |
319 | assertEquals(timeInMoscow.getTime(), out.getTime()); | |
90 | 320 | } |
91 | 321 | |
92 | 322 | public void testIsThreadSafe() throws InterruptedException { |
97 | 327 | final int numberOfThreads = 20; |
98 | 328 | |
99 | 329 | // spawn some concurrent threads, that hammer the converter |
100 | Runnable runnable = new Runnable() { | |
330 | final Runnable runnable = new Runnable() { | |
101 | 331 | public void run() { |
102 | 332 | for (int i = 0; i < numberOfCallsPerThread; i++) { |
103 | 333 | try { |
104 | 334 | converter.fromString("1993-02-14T13:10:30"); |
105 | 335 | results.add("PASS"); |
106 | } catch (ConversionException e) { | |
336 | } catch (final ConversionException e) { | |
107 | 337 | results.add("FAIL"); |
108 | 338 | } finally { |
109 | 339 | synchronized (monitor) { |
+10
-4
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
40 | 40 | super.tearDown(); |
41 | 41 | } |
42 | 42 | |
43 | private XStream createXStream() { | |
44 | XStream xs = new XStream(); | |
45 | XStream.setupDefaultSecurity(xs); | |
46 | return xs; | |
47 | } | |
48 | ||
43 | 49 | public void testISO8601SqlTimestamp() { |
44 | XStream xs = new XStream(); | |
50 | XStream xs = createXStream(); | |
45 | 51 | xs.registerConverter(converter); |
46 | 52 | |
47 | 53 | long currentTime = System.currentTimeMillis(); |
58 | 64 | } |
59 | 65 | |
60 | 66 | public void testISO8601SqlTimestampWith1Milli() { |
61 | XStream xs = new XStream(); | |
67 | XStream xs = createXStream(); | |
62 | 68 | xs.registerConverter(converter); |
63 | 69 | |
64 | 70 | long currentTime = (System.currentTimeMillis() / 1000 * 1000) + 1; |
75 | 81 | } |
76 | 82 | |
77 | 83 | public void testISO8601SqlTimestampWithNanos() { |
78 | XStream xs = new XStream(); | |
84 | XStream xs = createXStream(); | |
79 | 85 | xs.registerConverter(converter); |
80 | 86 | |
81 | 87 | Timestamp ts1 = new Timestamp(System.currentTimeMillis()); |
+44
-12
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2013, 2014, 2015 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2013, 2014, 2015, 2016, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
17 | 17 | import com.thoughtworks.acceptance.objects.StandardObject; |
18 | 18 | import com.thoughtworks.xstream.XStream; |
19 | 19 | |
20 | ||
21 | 20 | public class JavaBeanConverterTest extends TestCase { |
21 | ||
22 | private XStream createXStream() { | |
23 | XStream xstream = new XStream(); | |
24 | XStream.setupDefaultSecurity(xstream); | |
25 | xstream.allowTypesByWildcard(new String[] {getClass().getName()+"$*"}); | |
26 | return xstream; | |
27 | } | |
22 | 28 | |
23 | 29 | // Different JDK versions deliver properties in different order - so sort them! |
24 | 30 | static class StringComparator implements Comparator { |
171 | 177 | public void testSerializesAllPrimitiveFieldsInACustomObject() { |
172 | 178 | World world = new World(); |
173 | 179 | |
174 | XStream xstream = new XStream(); | |
180 | XStream xstream = createXStream(); | |
175 | 181 | xstream.registerConverter(new JavaBeanConverter(xstream.getMapper(), new BeanProvider( |
176 | 182 | new StringComparator())), XStream.PRIORITY_LOW); |
177 | 183 | xstream.alias("world", World.class); |
204 | 210 | World world = new World(); |
205 | 211 | world.setAString(null); |
206 | 212 | |
207 | XStream xstream = new XStream(); | |
213 | XStream xstream = createXStream(); | |
208 | 214 | xstream.registerConverter(new JavaBeanConverter(xstream.getMapper(), new BeanProvider( |
209 | 215 | new StringComparator())), XStream.PRIORITY_LOW); |
210 | 216 | xstream.alias("world", World.class); |
285 | 291 | + " <trans>transient</trans>\n" |
286 | 292 | + "</types>"; |
287 | 293 | |
288 | XStream xstream = new XStream(); | |
294 | XStream xstream = createXStream(); | |
289 | 295 | xstream.registerConverter(new JavaBeanConverter(xstream.getMapper(), new BeanProvider( |
290 | 296 | new StringComparator())), -20); |
291 | 297 | xstream.alias("types", TypesOfFields.class); |
320 | 326 | + " </member>\n" |
321 | 327 | + "</bean>"; |
322 | 328 | |
323 | XStream xstream = new XStream(); | |
329 | XStream xstream = createXStream(); | |
324 | 330 | xstream.registerConverter(new JavaBeanConverter(xstream.getMapper()), XStream.PRIORITY_LOW); |
325 | 331 | xstream.alias("bean", SimpleBean.class); |
326 | 332 | |
332 | 338 | TypesOfFields fields = new TypesOfFields(); |
333 | 339 | String expected = "<types/>"; |
334 | 340 | |
335 | XStream xstream = new XStream(); | |
341 | XStream xstream = createXStream(); | |
336 | 342 | xstream.registerConverter(new JavaBeanConverter(xstream.getMapper()), XStream.PRIORITY_LOW); |
337 | 343 | xstream.alias("types", TypesOfFields.class); |
338 | 344 | xstream.omitField(TypesOfFields.class, "trans"); |
351 | 357 | + " <foo>bar</foo>\n" |
352 | 358 | + "</types>"; |
353 | 359 | |
354 | XStream xstream = new XStream(); | |
360 | XStream xstream = createXStream(); | |
355 | 361 | xstream.registerConverter(new JavaBeanConverter(xstream.getMapper()), XStream.PRIORITY_LOW); |
356 | 362 | xstream.alias("types", TypesOfFields.class); |
357 | 363 | xstream.omitField(TypesOfFields.class, "foo"); |
360 | 366 | TypesOfFields unmarshalledFields = (TypesOfFields)xstream.fromXML(xml); |
361 | 367 | assertEquals(fields, unmarshalledFields); |
362 | 368 | } |
369 | ||
370 | public void testIgnoresUnknownFieldsMatchingPattern() { | |
371 | TypesOfFields fields = new TypesOfFields(); | |
372 | fields.setNormal("foo"); | |
373 | String xml = "" | |
374 | + "<types>\n" | |
375 | + " <normal>foo</normal>\n" | |
376 | + " <foo>bar</foo>\n" | |
377 | + "</types>"; | |
378 | ||
379 | XStream xstream = createXStream(); | |
380 | xstream.registerConverter(new JavaBeanConverter(xstream.getMapper()), XStream.PRIORITY_LOW); | |
381 | xstream.alias("types", TypesOfFields.class); | |
382 | xstream.ignoreUnknownElements("fo.*"); | |
383 | ||
384 | TypesOfFields unmarshalledFields = (TypesOfFields)xstream.fromXML(xml); | |
385 | assertEquals(fields, unmarshalledFields); | |
386 | } | |
363 | 387 | |
364 | 388 | public static class UnsafeBean { |
365 | 389 | public String getUnsafe() { |
374 | 398 | UnsafeBean bean = new UnsafeBean(); |
375 | 399 | String expected = "<unsafeBean/>"; |
376 | 400 | |
377 | XStream xstream = new XStream(); | |
401 | XStream xstream = createXStream(); | |
378 | 402 | xstream.registerConverter(new JavaBeanConverter(xstream.getMapper()), XStream.PRIORITY_LOW); |
379 | 403 | xstream.alias("unsafeBean", UnsafeBean.class); |
380 | 404 | xstream.omitField(UnsafeBean.class, "unsafe"); |
427 | 451 | } |
428 | 452 | |
429 | 453 | public void testDoesNotSerializeOmittedInheritedFields() { |
430 | XStream xstream = new XStream(); | |
454 | XStream xstream = createXStream(); | |
431 | 455 | xstream.registerConverter( |
432 | 456 | new JavaBeanConverter(xstream.getMapper()), XStream.PRIORITY_LOW); |
433 | 457 | xstream.omitField(Person.class, "lastName"); |
443 | 467 | } |
444 | 468 | |
445 | 469 | public void testUseAliasInheritedFields() { |
446 | XStream xstream = new XStream(); | |
470 | XStream xstream = createXStream(); | |
447 | 471 | xstream.registerConverter( |
448 | 472 | new JavaBeanConverter(xstream.getMapper(), new BeanProvider( |
449 | 473 | new StringComparator())), XStream.PRIORITY_LOW); |
462 | 486 | } |
463 | 487 | |
464 | 488 | public void testFailsFastIfPropertyIsDefinedTwice() { |
465 | XStream xstream = new XStream(); | |
489 | XStream xstream = createXStream(); | |
466 | 490 | xstream.registerConverter( |
467 | 491 | new JavaBeanConverter(xstream.getMapper()), XStream.PRIORITY_LOW); |
468 | 492 | String input = "" |
481 | 505 | assertEquals("normal", expected.get("property")); |
482 | 506 | } |
483 | 507 | } |
508 | ||
509 | public void testCanConvertDoesNotThrowException() { | |
510 | JavaBeanConverter converter = new JavaBeanConverter(null); | |
511 | assertTrue(converter.canConvert(SimpleBean.class)); | |
512 | assertFalse(converter.canConvert(null)); | |
513 | assertFalse(converter.canConvert(long.class)); | |
514 | assertFalse(converter.canConvert(Object[].class)); | |
515 | } | |
484 | 516 | } |
+5
-2
0 | 0 | /* |
1 | * Copyright (C) 2007 XStream Committers. | |
1 | * Copyright (C) 2007, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
52 | 52 | while (!cls.equals(Object.class)) { |
53 | 53 | Field[] fields = cls.getDeclaredFields(); |
54 | 54 | for (int i = 0; i < fields.length; i++) { |
55 | Field field = fields[i]; | |
55 | final Field field = fields[i]; | |
56 | if (field.getName().startsWith("$jacoco")) { | |
57 | continue; | |
58 | } | |
56 | 59 | map.put(new FieldKey(field.getName(), cls, i), field); |
57 | 60 | } |
58 | 61 | cls = cls.getSuperclass(); |
+12
-5
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2010, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2010, 2013, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
45 | 45 | public void testSerializesAllPrimitiveFieldsInACustomObject() { |
46 | 46 | World world = new World(); |
47 | 47 | |
48 | XStream xstream = new XStream(new XppDriver()); | |
48 | XStream xstream = createXStream(); | |
49 | 49 | xstream.alias("world", World.class); |
50 | 50 | |
51 | 51 | String expected = |
70 | 70 | assertEquals(expected, xstream.toXML(world)); |
71 | 71 | } |
72 | 72 | |
73 | private XStream createXStream() { | |
74 | XStream xstream = new XStream(new XppDriver()); | |
75 | XStream.setupDefaultSecurity(xstream); | |
76 | return xstream; | |
77 | } | |
78 | ||
73 | 79 | public static class TypesOfFields extends StandardObject { |
74 | 80 | String normal = "normal"; |
75 | 81 | transient String trans = "transient"; |
83 | 89 | " <normal>normal</normal>\n" + |
84 | 90 | "</types>"; |
85 | 91 | |
86 | XStream xstream = new XStream(new XppDriver()); | |
92 | XStream xstream = createXStream(); | |
87 | 93 | xstream.alias("types", TypesOfFields.class); |
88 | 94 | |
89 | 95 | String xml = xstream.toXML(fields); |
92 | 98 | } |
93 | 99 | |
94 | 100 | public void testCanBeOverloadedToDeserializeTransientFields() { |
95 | XStream xstream = new XStream(new XppDriver()); | |
101 | XStream xstream = createXStream(); | |
102 | xstream.allowTypesByWildcard(new String[] {getClass().getName()+"$*"}); | |
96 | 103 | xstream.alias("types", TypesOfFields.class); |
97 | 104 | xstream.registerConverter(new ReflectionConverter(xstream.getMapper(), xstream |
98 | 105 | .getReflectionProvider()) { |
117 | 124 | } |
118 | 125 | |
119 | 126 | public void testCustomConverterCanBeInstantiatedAndRegisteredWithDesiredPriority() { |
120 | XStream xstream = new XStream(new XppDriver()); | |
127 | XStream xstream = createXStream(); | |
121 | 128 | // using default mapper instead of XStream#buildMapper() |
122 | 129 | Mapper mapper = new DefaultMapper(new ClassLoaderReference(new CompositeClassLoader())); |
123 | 130 | // AttributeMapper required by ReflectionConverter |
+17
-10
0 | 0 | /* |
1 | * Copyright (C) 2007, 2014 XStream Committers. | |
1 | * Copyright (C) 2007, 2014, 2017 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
26 | 26 | */ |
27 | 27 | public class SerializableConverterTest extends TestCase { |
28 | 28 | |
29 | private XStream createXStream() { | |
30 | XStream xstream = new XStream(); | |
31 | XStream.setupDefaultSecurity(xstream); | |
32 | xstream.allowTypesByWildcard(new String[] {getClass().getName()+"$*"}); | |
33 | return xstream; | |
34 | } | |
35 | ||
29 | 36 | static class SimpleType extends StandardObject { |
30 | 37 | private String one; |
31 | 38 | private String two; |
57 | 64 | } |
58 | 65 | |
59 | 66 | public void testCanOmitFieldAtSerialization() { |
60 | XStream xstream = new XStream(); | |
67 | XStream xstream = createXStream(); | |
61 | 68 | xstream.alias("simple", SimpleType.class); |
62 | 69 | xstream.omitField(SimpleType.class, "two"); |
63 | 70 | |
79 | 86 | } |
80 | 87 | |
81 | 88 | public void testCanOmitFieldAtDeserialization() { |
82 | XStream xstream = new XStream(); | |
89 | XStream xstream = createXStream(); | |
83 | 90 | xstream.alias("simple", SimpleType.class); |
84 | 91 | xstream.omitField(SimpleType.class, "two"); |
85 | 92 | xstream.omitField(SimpleType.class, "x"); |
123 | 130 | } |
124 | 131 | |
125 | 132 | public void testCanOmitInheritedFieldAtSerialization() { |
126 | XStream xstream = new XStream(); | |
133 | XStream xstream = createXStream(); | |
127 | 134 | xstream.alias("extended", ExtendedType.class); |
128 | 135 | xstream.alias("simple", SimpleType.class); |
129 | 136 | xstream.omitField(SimpleType.class, "two"); |
152 | 159 | } |
153 | 160 | |
154 | 161 | public void testCanOmitInheritedFieldAtDeserialization() { |
155 | XStream xstream = new XStream(); | |
162 | XStream xstream = createXStream(); | |
156 | 163 | xstream.alias("extended", ExtendedType.class); |
157 | 164 | xstream.alias("simple", SimpleType.class); |
158 | 165 | xstream.omitField(SimpleType.class, "two"); |
224 | 231 | } |
225 | 232 | |
226 | 233 | public void testCanOmitNamedFieldAtSerialization() { |
227 | XStream xstream = new XStream(); | |
234 | XStream xstream = createXStream(); | |
228 | 235 | xstream.alias("simple", SimpleNamedFieldsType.class); |
229 | 236 | xstream.omitField(SimpleNamedFieldsType.class, "s2"); |
230 | 237 | |
246 | 253 | } |
247 | 254 | |
248 | 255 | public void testCanOmitNamedFieldAtDeserialization() { |
249 | XStream xstream = new XStream(); | |
256 | XStream xstream = createXStream(); | |
250 | 257 | xstream.alias("simple", SimpleNamedFieldsType.class); |
251 | 258 | xstream.omitField(SimpleNamedFieldsType.class, "s2"); |
252 | 259 | xstream.omitField(SimpleNamedFieldsType.class, "x"); |
270 | 277 | } |
271 | 278 | |
272 | 279 | public void testCanAliasField() { |
273 | XStream xstream = new XStream(); | |
280 | XStream xstream = createXStream(); | |
274 | 281 | xstream.alias("simple", SimpleType.class); |
275 | 282 | xstream.aliasField("s2", SimpleType.class, "two"); |
276 | 283 | |
295 | 302 | } |
296 | 303 | |
297 | 304 | public void testCanAliasNamedField() { |
298 | XStream xstream = new XStream(); | |
305 | XStream xstream = createXStream(); | |
299 | 306 | xstream.alias("simple", SimpleNamedFieldsType.class); |
300 | 307 | xstream.aliasField("two", SimpleNamedFieldsType.class, "s2"); |
301 | 308 | |
324 | 331 | } |
325 | 332 | |
326 | 333 | public void testCanHandleFieldsDeclaredWithSerializableInterface() { |
327 | XStream xstream = new XStream(); | |
334 | XStream xstream = createXStream(); | |
328 | 335 | xstream.alias("sertype", SerializableType.class); |
329 | 336 | xstream.useAttributeFor(SerializableType.class, "serializable"); |
330 | 337 |
+5
-2
0 | 0 | /* |
1 | * Copyright (C) 2007, 2016 XStream Committers. | |
1 | * Copyright (C) 2007, 2016, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
72 | 72 | while (!cls.equals(Object.class)) { |
73 | 73 | Field[] fields = cls.getDeclaredFields(); |
74 | 74 | for (int i = 0; i < fields.length; i++) { |
75 | Field field = fields[i]; | |
75 | final Field field = fields[i]; | |
76 | if (field.getName().startsWith("$jacoco")) { | |
77 | continue; | |
78 | } | |
76 | 79 | map.put(new FieldKey(field.getName(), cls, i), field); |
77 | 80 | } |
78 | 81 | cls = cls.getSuperclass(); |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
6 | 6 | * style license a copy of which has been included with this distribution in |
7 | 7 | * the LICENSE.txt file. |
8 | * | |
8 | * | |
9 | 9 | * Created on 06. August 2004 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.core.util; |
12 | 12 | |
13 | 13 | import com.thoughtworks.acceptance.AbstractAcceptanceTest; |
14 | 14 | |
15 | ||
15 | 16 | public class Base64EncoderTest extends AbstractAcceptanceTest { |
16 | 17 | |
17 | private Base64Encoder encoder = new Base64Encoder(); | |
18 | private Base64Encoder encoder = new Base64Encoder(true); | |
18 | 19 | |
19 | 20 | public void testEncodesEntireByteArrayAsString() { |
20 | byte input[] = "hello world".getBytes(); | |
21 | String expected = "aGVsbG8gd29ybGQ="; | |
21 | final byte input[] = "hello world".getBytes(); | |
22 | final String expected = "aGVsbG8gd29ybGQ="; | |
22 | 23 | assertEquals(expected, encoder.encode(input)); |
23 | 24 | assertByteArrayEquals(input, encoder.decode(expected)); |
24 | 25 | } |
25 | 26 | |
26 | 27 | public void testWrapsLinesAt76Chars() { |
27 | byte input[] = ("hello world. hello world. hello world. hello world. hello world. hello world. hello world. " | |
28 | + "hello world. hello world. hello world. hello world. hello world. hello world. hello world. ").getBytes(); | |
29 | String expected = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv\n" | |
30 | + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3Js\n" | |
31 | + "ZC4gaGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhl\n" | |
32 | + "bGxvIHdvcmxkLiA="; | |
28 | final byte input[] = | |
29 | ("hello world. hello world. hello world. hello world. hello world. hello world. hello world. " | |
30 | + "hello world. hello world. hello world. hello world. hello world. hello world. hello world. ") | |
31 | .getBytes(); | |
32 | final String expected = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv\n" | |
33 | + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3Js\n" | |
34 | + "ZC4gaGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhl\n" | |
35 | + "bGxvIHdvcmxkLiA="; | |
33 | 36 | assertEquals(expected, encoder.encode(input)); |
34 | 37 | assertByteArrayEquals(input, encoder.decode(expected)); |
35 | 38 | } |
36 | 39 | |
40 | public void testExactly76Chars() { | |
41 | final byte input[] = "hello world. hello world. hello world. hello world. hello".getBytes(); | |
42 | final String expected = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv"; | |
43 | assertEquals(expected, encoder.encode(input)); | |
44 | assertByteArrayEquals(input, encoder.decode(expected)); | |
45 | } | |
46 | ||
47 | public void testModeWithoutLineWraps() { | |
48 | final byte input[] = | |
49 | "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " | |
50 | .getBytes(); | |
51 | final String expected = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv" | |
52 | + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; | |
53 | encoder = new Base64Encoder(false); | |
54 | assertEquals(expected, encoder.encode(input)); | |
55 | assertByteArrayEquals(input, encoder.decode(expected)); | |
56 | } | |
57 | ||
58 | public void testDecodesLinesWithLF() { | |
59 | final byte data[] = | |
60 | "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " | |
61 | .getBytes(); | |
62 | final String input = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv\n" | |
63 | + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; | |
64 | encoder = new Base64Encoder(false); | |
65 | assertByteArrayEquals(data, encoder.decode(input)); | |
66 | } | |
67 | ||
68 | public void testDecodesLinesWithCRLF() { | |
69 | final byte data[] = | |
70 | "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " | |
71 | .getBytes(); | |
72 | final String input = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv\r\n" | |
73 | + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; | |
74 | encoder = new Base64Encoder(false); | |
75 | assertByteArrayEquals(data, encoder.decode(input)); | |
76 | } | |
77 | ||
78 | public void testDecodesUnwrappedLines() { | |
79 | final byte data[] = | |
80 | "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " | |
81 | .getBytes(); | |
82 | final String input = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv" | |
83 | + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; | |
84 | encoder = new Base64Encoder(false); | |
85 | assertByteArrayEquals(data, encoder.decode(input)); | |
86 | } | |
87 | ||
88 | public void testDecodesShortLines() { | |
89 | final byte data[] = "hello world".getBytes(); | |
90 | final String input = "aGVs\nbG8g\nd29y\nbGQ="; | |
91 | assertByteArrayEquals(data, encoder.decode(input)); | |
92 | } | |
93 | ||
37 | 94 | public void testPadsSingleMissingByteWhenNotMultipleOfThree() { |
38 | byte input[] = { 1, 2, 3, 4, 5 }; | |
39 | String expected = "AQIDBAU="; | |
95 | final byte input[] = {1, 2, 3, 4, 5}; | |
96 | final String expected = "AQIDBAU="; | |
40 | 97 | assertEquals(expected, encoder.encode(input)); |
41 | 98 | assertByteArrayEquals(input, encoder.decode(expected)); |
42 | 99 | } |
43 | 100 | |
44 | 101 | public void testPadsDoubleMissingByteWhenNotMultipleOfThree() { |
45 | byte input[] = { 1, 2, 3, 4 }; | |
46 | String expected = "AQIDBA=="; | |
102 | final byte input[] = {1, 2, 3, 4}; | |
103 | final String expected = "AQIDBA=="; | |
47 | 104 | assertEquals(expected, encoder.encode(input)); |
48 | 105 | assertByteArrayEquals(input, encoder.decode(expected)); |
49 | 106 | } |
50 | 107 | |
51 | 108 | public void testDoesNotPadWhenMultipleOfThree() { |
52 | byte input[] = { 1, 2, 3, 4, 5, 6 }; | |
53 | String expected = "AQIDBAUG"; | |
109 | final byte input[] = {1, 2, 3, 4, 5, 6}; | |
110 | final String expected = "AQIDBAUG"; | |
54 | 111 | assertEquals(expected, encoder.encode(input)); |
55 | 112 | assertByteArrayEquals(input, encoder.decode(expected)); |
56 | 113 | } |
57 | 114 | |
58 | 115 | public void testHandlesAllPositiveBytes() { |
59 | byte input[] = new byte[127]; | |
60 | for (int i = 0; i < 126; i++) input[i] = (byte) (i + 1); | |
61 | String expected = "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5\n" | |
62 | + "Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFy\n" | |
63 | + "c3R1dnd4eXp7fH1+AA=="; | |
116 | final byte input[] = new byte[127]; | |
117 | for (int i = 0; i < 126; i++) { | |
118 | input[i] = (byte)(i + 1); | |
119 | } | |
120 | final String expected = "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5\n" | |
121 | + "Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFy\n" | |
122 | + "c3R1dnd4eXp7fH1+AA=="; | |
64 | 123 | assertEquals(expected, encoder.encode(input)); |
65 | 124 | assertByteArrayEquals(input, encoder.decode(expected)); |
66 | 125 | } |
67 | 126 | |
68 | 127 | public void testHandlesAllNegativeBytes() { |
69 | byte input[] = new byte[128]; | |
70 | for (int i = 0; i < 127; i++) input[i] = (byte) (-1 - i); | |
71 | String expected = "//79/Pv6+fj39vX08/Lx8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjH\n" | |
72 | + "xsXEw8LBwL++vby7urm4t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI+O\n" | |
73 | + "jYyLiomIh4aFhIOCgQA="; | |
128 | final byte input[] = new byte[128]; | |
129 | for (int i = 0; i < 127; i++) { | |
130 | input[i] = (byte)(-1 - i); | |
131 | } | |
132 | final String expected = "//79/Pv6+fj39vX08/Lx8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjH\n" | |
133 | + "xsXEw8LBwL++vby7urm4t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI+O\n" | |
134 | + "jYyLiomIh4aFhIOCgQA="; | |
74 | 135 | assertEquals(expected, encoder.encode(input)); |
75 | 136 | assertByteArrayEquals(input, encoder.decode(expected)); |
76 | 137 | } |
77 | 138 | |
78 | 139 | public void testHandlesZeroByte() { |
79 | byte input[] = { 0, 0, 0, 0 }; | |
80 | String expected = "AAAAAA=="; | |
140 | final byte input[] = {0, 0, 0, 0}; | |
141 | final String expected = "AAAAAA=="; | |
81 | 142 | assertEquals(expected, encoder.encode(input)); |
82 | 143 | assertByteArrayEquals(input, encoder.decode(expected)); |
83 | 144 | } |
84 | 145 | |
85 | 146 | public void testProducesEmptyStringWhenNoBytesGiven() { |
86 | byte input[] = new byte[0]; | |
87 | String expected = ""; | |
147 | final byte input[] = new byte[0]; | |
148 | final String expected = ""; | |
88 | 149 | assertEquals(expected, encoder.encode(input)); |
89 | 150 | assertByteArrayEquals(input, encoder.decode(expected)); |
90 | 151 | } |
91 | 152 | |
153 | public void testInitializeStringBufferWithExpectedSizeUsing6BytesInput() throws Exception { | |
154 | final byte input[] = {1, 2, 3, 4, 5, 6}; | |
155 | assertEquals(encoder.encode(input).length(), encoder.computeResultingStringSize(input)); | |
156 | } | |
157 | ||
158 | public void testInitializeStringBufferWithExpectedSizeUsing1BytesInput() throws Exception { | |
159 | final byte input[] = {1}; | |
160 | assertEquals(encoder.encode(input).length(), encoder.computeResultingStringSize(input)); | |
161 | } | |
162 | ||
163 | public void testInitializeStringBufferWithExpectedSizeUsing4BytesInput() throws Exception { | |
164 | final byte input[] = {1, 2, 3, 4}; | |
165 | assertEquals(encoder.encode(input).length(), encoder.computeResultingStringSize(input)); | |
166 | } | |
167 | ||
168 | public void testInitializeStringBufferWithExpectedSizeUsing140BytesInput() throws Exception { | |
169 | final byte input[] = new byte[140]; | |
170 | for (int i = 0; i < 139; i++) { | |
171 | input[i] = (byte)(i + 1); | |
172 | } | |
173 | assertEquals(encoder.encode(input).length(), encoder.computeResultingStringSize(input)); | |
174 | } | |
175 | ||
92 | 176 | } |
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 13. August 2017 Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.core.util; | |
11 | ||
12 | import com.thoughtworks.acceptance.AbstractAcceptanceTest; | |
13 | import com.thoughtworks.xstream.core.StringCodec; | |
14 | ||
15 | ||
16 | public class Base64JAXBCodecTest extends AbstractAcceptanceTest { | |
17 | ||
18 | private StringCodec encoder = new Base64JAXBCodec(); | |
19 | ||
20 | public void testEncodesEntireByteArrayAsString() { | |
21 | final byte input[] = "hello world".getBytes(); | |
22 | final String expected = "aGVsbG8gd29ybGQ="; | |
23 | assertEquals(expected, encoder.encode(input)); | |
24 | assertByteArrayEquals(input, encoder.decode(expected)); | |
25 | } | |
26 | ||
27 | public void testModeWithoutLineWraps() { | |
28 | final byte input[] = | |
29 | "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " | |
30 | .getBytes(); | |
31 | final String expected = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv" | |
32 | + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; | |
33 | assertEquals(expected, encoder.encode(input)); | |
34 | assertByteArrayEquals(input, encoder.decode(expected)); | |
35 | } | |
36 | ||
37 | public void testDecodesLinesWithLF() { | |
38 | final byte data[] = | |
39 | "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " | |
40 | .getBytes(); | |
41 | final String input = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv\n" | |
42 | + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; | |
43 | assertByteArrayEquals(data, encoder.decode(input)); | |
44 | } | |
45 | ||
46 | public void testDecodesLinesWithCRLF() { | |
47 | final byte data[] = | |
48 | "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " | |
49 | .getBytes(); | |
50 | final String input = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv\r\n" | |
51 | + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; | |
52 | assertByteArrayEquals(data, encoder.decode(input)); | |
53 | } | |
54 | ||
55 | public void testDecodesShortLines() { | |
56 | final byte data[] = "hello world".getBytes(); | |
57 | final String input = "aGVs\nbG8g\nd29y\nbGQ="; | |
58 | assertByteArrayEquals(data, encoder.decode(input)); | |
59 | } | |
60 | ||
61 | public void testPadsSingleMissingByteWhenNotMultipleOfThree() { | |
62 | final byte input[] = {1, 2, 3, 4, 5}; | |
63 | final String expected = "AQIDBAU="; | |
64 | assertEquals(expected, encoder.encode(input)); | |
65 | assertByteArrayEquals(input, encoder.decode(expected)); | |
66 | } | |
67 | ||
68 | public void testPadsDoubleMissingByteWhenNotMultipleOfThree() { | |
69 | final byte input[] = {1, 2, 3, 4}; | |
70 | final String expected = "AQIDBA=="; | |
71 | assertEquals(expected, encoder.encode(input)); | |
72 | assertByteArrayEquals(input, encoder.decode(expected)); | |
73 | } | |
74 | ||
75 | public void testDoesNotPadWhenMultipleOfThree() { | |
76 | final byte input[] = {1, 2, 3, 4, 5, 6}; | |
77 | final String expected = "AQIDBAUG"; | |
78 | assertEquals(expected, encoder.encode(input)); | |
79 | assertByteArrayEquals(input, encoder.decode(expected)); | |
80 | } | |
81 | ||
82 | public void testHandlesAllPositiveBytes() { | |
83 | final byte input[] = new byte[127]; | |
84 | for (int i = 0; i < 126; i++) { | |
85 | input[i] = (byte)(i + 1); | |
86 | } | |
87 | final String expected = "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5" | |
88 | + "Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFy" | |
89 | + "c3R1dnd4eXp7fH1+AA=="; | |
90 | assertEquals(expected, encoder.encode(input)); | |
91 | assertByteArrayEquals(input, encoder.decode(expected)); | |
92 | } | |
93 | ||
94 | public void testHandlesAllNegativeBytes() { | |
95 | final byte input[] = new byte[128]; | |
96 | for (int i = 0; i < 127; i++) { | |
97 | input[i] = (byte)(-1 - i); | |
98 | } | |
99 | final String expected = "//79/Pv6+fj39vX08/Lx8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjH" | |
100 | + "xsXEw8LBwL++vby7urm4t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI+O" | |
101 | + "jYyLiomIh4aFhIOCgQA="; | |
102 | assertEquals(expected, encoder.encode(input)); | |
103 | assertByteArrayEquals(input, encoder.decode(expected)); | |
104 | } | |
105 | ||
106 | public void testHandlesZeroByte() { | |
107 | final byte input[] = {0, 0, 0, 0}; | |
108 | final String expected = "AAAAAA=="; | |
109 | assertEquals(expected, encoder.encode(input)); | |
110 | assertByteArrayEquals(input, encoder.decode(expected)); | |
111 | } | |
112 | ||
113 | public void testProducesEmptyStringWhenNoBytesGiven() { | |
114 | final byte input[] = new byte[0]; | |
115 | final String expected = ""; | |
116 | assertEquals(expected, encoder.encode(input)); | |
117 | assertByteArrayEquals(input, encoder.decode(expected)); | |
118 | } | |
119 | } |
0 | /* | |
1 | * Copyright (C) 2017 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 13. August 2017 Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.core.util; | |
11 | ||
12 | import com.thoughtworks.acceptance.AbstractAcceptanceTest; | |
13 | import com.thoughtworks.xstream.core.StringCodec; | |
14 | ||
15 | ||
16 | public class Base64JavaUtilCodecTest extends AbstractAcceptanceTest { | |
17 | ||
18 | private StringCodec encoder = new Base64JavaUtilCodec(); | |
19 | ||
20 | public void testEncodesEntireByteArrayAsString() { | |
21 | final byte input[] = "hello world".getBytes(); | |
22 | final String expected = "aGVsbG8gd29ybGQ="; | |
23 | assertEquals(expected, encoder.encode(input)); | |
24 | assertByteArrayEquals(input, encoder.decode(expected)); | |
25 | } | |
26 | ||
27 | public void testModeWithoutLineWraps() { | |
28 | final byte input[] = | |
29 | "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " | |
30 | .getBytes(); | |
31 | final String expected = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv" | |
32 | + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; | |
33 | assertEquals(expected, encoder.encode(input)); | |
34 | assertByteArrayEquals(input, encoder.decode(expected)); | |
35 | } | |
36 | ||
37 | public void testDecodesLinesWithLF() { | |
38 | final byte data[] = | |
39 | "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " | |
40 | .getBytes(); | |
41 | final String input = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv\n" | |
42 | + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; | |
43 | assertByteArrayEquals(data, encoder.decode(input)); | |
44 | } | |
45 | ||
46 | public void testDecodesLinesWithCRLF() { | |
47 | final byte data[] = | |
48 | "hello world. hello world. hello world. hello world. hello world. hello world. hello world. " | |
49 | .getBytes(); | |
50 | final String input = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv\r\n" | |
51 | + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIA=="; | |
52 | assertByteArrayEquals(data, encoder.decode(input)); | |
53 | } | |
54 | ||
55 | public void testDecodesShortLines() { | |
56 | final byte data[] = "hello world".getBytes(); | |
57 | final String input = "aGVs\nbG8g\nd29y\nbGQ="; | |
58 | assertByteArrayEquals(data, encoder.decode(input)); | |
59 | } | |
60 | ||
61 | public void testPadsSingleMissingByteWhenNotMultipleOfThree() { | |
62 | final byte input[] = {1, 2, 3, 4, 5}; | |
63 | final String expected = "AQIDBAU="; | |
64 | assertEquals(expected, encoder.encode(input)); | |
65 | assertByteArrayEquals(input, encoder.decode(expected)); | |
66 | } | |
67 | ||
68 | public void testPadsDoubleMissingByteWhenNotMultipleOfThree() { | |
69 | final byte input[] = {1, 2, 3, 4}; | |
70 | final String expected = "AQIDBA=="; | |
71 | assertEquals(expected, encoder.encode(input)); | |
72 | assertByteArrayEquals(input, encoder.decode(expected)); | |
73 | } | |
74 | ||
75 | public void testDoesNotPadWhenMultipleOfThree() { | |
76 | final byte input[] = {1, 2, 3, 4, 5, 6}; | |
77 | final String expected = "AQIDBAUG"; | |
78 | assertEquals(expected, encoder.encode(input)); | |
79 | assertByteArrayEquals(input, encoder.decode(expected)); | |
80 | } | |
81 | ||
82 | public void testHandlesAllPositiveBytes() { | |
83 | final byte input[] = new byte[127]; | |
84 | for (int i = 0; i < 126; i++) { | |
85 | input[i] = (byte)(i + 1); | |
86 | } | |
87 | final String expected = "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5" | |
88 | + "Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFy" | |
89 | + "c3R1dnd4eXp7fH1+AA=="; | |
90 | assertEquals(expected, encoder.encode(input)); | |
91 | assertByteArrayEquals(input, encoder.decode(expected)); | |
92 | } | |
93 | ||
94 | public void testHandlesAllNegativeBytes() { | |
95 | final byte input[] = new byte[128]; | |
96 | for (int i = 0; i < 127; i++) { | |
97 | input[i] = (byte)(-1 - i); | |
98 | } | |
99 | final String expected = "//79/Pv6+fj39vX08/Lx8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjH" | |
100 | + "xsXEw8LBwL++vby7urm4t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI+O" | |
101 | + "jYyLiomIh4aFhIOCgQA="; | |
102 | assertEquals(expected, encoder.encode(input)); | |
103 | assertByteArrayEquals(input, encoder.decode(expected)); | |
104 | } | |
105 | ||
106 | public void testHandlesZeroByte() { | |
107 | final byte input[] = {0, 0, 0, 0}; | |
108 | final String expected = "AAAAAA=="; | |
109 | assertEquals(expected, encoder.encode(input)); | |
110 | assertByteArrayEquals(input, encoder.decode(expected)); | |
111 | } | |
112 | ||
113 | public void testProducesEmptyStringWhenNoBytesGiven() { | |
114 | final byte input[] = new byte[0]; | |
115 | final String expected = ""; | |
116 | assertEquals(expected, encoder.encode(input)); | |
117 | assertByteArrayEquals(input, encoder.decode(expected)); | |
118 | } | |
119 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2011, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2011, 2013, 2016, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
6 | 6 | * style license a copy of which has been included with this distribution in |
7 | 7 | * the LICENSE.txt file. |
8 | * | |
8 | * | |
9 | 9 | * Created on 30. April 2005 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.io; |
40 | 40 | import junit.framework.TestCase; |
41 | 41 | import junit.framework.TestSuite; |
42 | 42 | |
43 | ||
43 | 44 | public class DriverEndToEndTestSuite extends TestSuite { |
44 | 45 | |
45 | 46 | public static Test suite() { |
54 | 55 | addDriverTest(new DomDriver()); |
55 | 56 | addDriverTest(new JDomDriver()); |
56 | 57 | if (JVM.is15()) { |
57 | Class driverType = JVM.loadClassForName("com.thoughtworks.xstream.io.xml.JDom2Driver"); | |
58 | final Class driverType = JVM.loadClassForName("com.thoughtworks.xstream.io.xml.JDom2Driver"); | |
58 | 59 | try { |
59 | 60 | addDriverTest((HierarchicalStreamDriver)driverType.newInstance()); |
60 | } catch (InstantiationException e) { | |
61 | } catch (final InstantiationException e) { | |
61 | 62 | throw new AssertionFailedError("Cannot instantiate " + driverType.getName()); |
62 | } catch (IllegalAccessException e) { | |
63 | } catch (final IllegalAccessException e) { | |
63 | 64 | throw new AssertionFailedError("Cannot access default constructor of " + driverType.getName()); |
64 | 65 | } |
65 | 66 | } |
67 | 68 | addDriverTest(new KXml2Driver()); |
68 | 69 | addDriverTest(new StaxDriver()); |
69 | 70 | if (JVM.is16()) { |
70 | Class driverType = JVM.loadClassForName("com.thoughtworks.xstream.io.xml.StandardStaxDriver"); | |
71 | final Class driverType = JVM.loadClassForName("com.thoughtworks.xstream.io.xml.StandardStaxDriver"); | |
71 | 72 | try { |
72 | 73 | addDriverTest((HierarchicalStreamDriver)driverType.newInstance()); |
73 | } catch (InstantiationException e) { | |
74 | } catch (final InstantiationException e) { | |
74 | 75 | throw new AssertionFailedError("Cannot instantiate " + driverType.getName()); |
75 | } catch (IllegalAccessException e) { | |
76 | } catch (final IllegalAccessException e) { | |
76 | 77 | throw new AssertionFailedError("Cannot access default constructor of " + driverType.getName()); |
77 | 78 | } |
78 | 79 | } |
83 | 84 | addDriverTest(new XppDomDriver()); |
84 | 85 | addDriverTest(new XppDriver()); |
85 | 86 | if (JVM.is14()) { |
86 | Class driverType = JVM.loadClassForName("com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver"); | |
87 | final Class driverType = JVM.loadClassForName("com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver"); | |
87 | 88 | try { |
88 | 89 | addDriverTest((HierarchicalStreamDriver)driverType.newInstance()); |
89 | } catch (InstantiationException e) { | |
90 | } catch (final InstantiationException e) { | |
90 | 91 | throw new AssertionFailedError("Cannot instantiate " + driverType.getName()); |
91 | } catch (IllegalAccessException e) { | |
92 | } catch (final IllegalAccessException e) { | |
92 | 93 | throw new AssertionFailedError("Cannot access default constructor of " + driverType.getName()); |
93 | 94 | } |
94 | 95 | } |
95 | 96 | } |
96 | 97 | |
97 | private void test(HierarchicalStreamDriver driver) { | |
98 | XStream xstream = new XStream(driver); | |
98 | private void testObject(final HierarchicalStreamDriver driver) { | |
99 | final XStream xstream = new XStream(driver); | |
100 | xstream.setupDefaultSecurity(xstream); | |
101 | xstream.allowTypes(new Class[] { SampleLists.class }); | |
99 | 102 | xstream.registerConverter(new CollectionConverter(xstream.getMapper()) { |
100 | 103 | |
101 | public Object unmarshal(HierarchicalStreamReader reader, | |
102 | UnmarshallingContext context) { | |
103 | ExtendedHierarchicalStreamReader exReader = (ExtendedHierarchicalStreamReader)reader; | |
104 | public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { | |
105 | final ExtendedHierarchicalStreamReader exReader = (ExtendedHierarchicalStreamReader)reader; | |
104 | 106 | if (exReader.peekNextChild() == null) { |
105 | 107 | return new ArrayList(); |
106 | 108 | } |
107 | 109 | return super.unmarshal(reader, context); |
108 | 110 | } |
109 | ||
111 | ||
110 | 112 | }); |
111 | 113 | |
112 | SampleLists in = new SampleLists(); | |
114 | final SampleLists in = new SampleLists(); | |
113 | 115 | in.good.add("one"); |
114 | 116 | in.good.add("two"); |
115 | 117 | in.good.add("three"); |
116 | 118 | in.bad.add(Boolean.TRUE); |
117 | 119 | in.bad.add(Boolean.FALSE); |
118 | ByteArrayOutputStream buffer = new ByteArrayOutputStream(); | |
120 | final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); | |
119 | 121 | xstream.toXML(in, buffer); |
120 | Object out = xstream.fromXML(new ByteArrayInputStream(buffer.toByteArray())); | |
122 | final Object out = xstream.fromXML(new ByteArrayInputStream(buffer.toByteArray())); | |
121 | 123 | |
122 | 124 | Assert.assertEquals(in, out); |
123 | 125 | } |
124 | 126 | |
127 | private void testStream(final HierarchicalStreamDriver driver) { | |
128 | final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); | |
129 | final HierarchicalStreamWriter writer = driver.createWriter(buffer); | |
130 | writer.startNode("root"); | |
131 | writer.startNode("child1"); | |
132 | writer.startNode("baby"); | |
133 | writer.endNode(); | |
134 | writer.endNode(); | |
135 | writer.startNode("child2"); | |
136 | writer.addAttribute("A", "a"); | |
137 | writer.setValue("v"); | |
138 | writer.endNode(); | |
139 | writer.endNode(); | |
140 | writer.close(); | |
141 | ||
142 | final HierarchicalStreamReader reader = driver.createReader(new ByteArrayInputStream(buffer.toByteArray())); | |
143 | Assert.assertEquals("root", reader.getNodeName()); | |
144 | Assert.assertTrue(reader.hasMoreChildren()); | |
145 | reader.moveDown(); | |
146 | Assert.assertEquals("child1", reader.getNodeName()); | |
147 | Assert.assertEquals(0, reader.getAttributeCount()); | |
148 | Assert.assertNull(reader.getAttribute("foo")); | |
149 | Assert.assertTrue(reader.hasMoreChildren()); | |
150 | reader.moveUp(); | |
151 | Assert.assertTrue(reader.hasMoreChildren()); | |
152 | reader.moveDown(); | |
153 | Assert.assertEquals("child2", reader.getNodeName()); | |
154 | Assert.assertEquals(1, reader.getAttributeCount()); | |
155 | Assert.assertEquals("a", reader.getAttribute("A")); | |
156 | Assert.assertNull(reader.getAttribute("foo")); | |
157 | //Assert.assertNull(reader.getAttribute(1)); | |
158 | Assert.assertFalse(reader.hasMoreChildren()); | |
159 | reader.moveUp(); | |
160 | Assert.assertFalse(reader.hasMoreChildren()); | |
161 | reader.close(); | |
162 | } | |
163 | ||
125 | 164 | private void addDriverTest(final HierarchicalStreamDriver driver) { |
126 | String testName = getShortName(driver); | |
127 | addTest(new TestCase(testName) { | |
165 | final String testName = getShortName(driver); | |
166 | addTest(new TestCase(testName + "_Object") { | |
128 | 167 | protected void runTest() throws Throwable { |
129 | test(driver); | |
168 | testObject(driver); | |
169 | } | |
170 | }); | |
171 | addTest(new TestCase(testName + "_Stream") { | |
172 | protected void runTest() throws Throwable { | |
173 | testStream(driver); | |
130 | 174 | } |
131 | 175 | }); |
132 | 176 | } |
133 | 177 | |
134 | private String getShortName(HierarchicalStreamDriver driver) { | |
178 | private String getShortName(final HierarchicalStreamDriver driver) { | |
135 | 179 | String result = driver.getClass().getName(); |
136 | 180 | result = result.substring(result.lastIndexOf('.') + 1); |
137 | 181 | return result; |
138 | 182 | } |
139 | ||
140 | 183 | } |
0 | 0 | /* |
1 | * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2013 XStream Committers. | |
1 | * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2013, 2016, 2017 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
57 | 57 | super.setUp(); |
58 | 58 | TimeZoneChanger.change("UTC"); |
59 | 59 | xstream = new XStream(new JettisonMappedXmlDriver()); |
60 | XStream.setupDefaultSecurity(xstream); | |
61 | xstream.allowTypesByWildcard(new String[]{ | |
62 | getClass().getName() + "$*", "com.thoughtworks.acceptance.objects.*"}); | |
60 | 63 | xstream.alias("category", Category.class); |
61 | 64 | xstream.alias("product", Product.class); |
62 | 65 | } |
90 | 93 | Configuration config = new Configuration(); |
91 | 94 | setTypeConverter.invoke(config, new Object[]{typeConverter}); |
92 | 95 | xstream = new XStream(new JettisonMappedXmlDriver(config)); |
96 | XStream.setupDefaultSecurity(xstream); | |
97 | xstream.allowTypesByWildcard(new String[]{"com.thoughtworks.acceptance.objects.*"}); | |
93 | 98 | xstream.alias("product", Product.class); |
94 | 99 | Product product = new Product("Banana", "123", 23.00); |
95 | 100 | String result = xstream.toXML(product); |
236 | 241 | xstream.alias("topic", Topic.class); |
237 | 242 | String json = xstream.toXML(topic1); |
238 | 243 | assertEquals( |
239 | "{'topic':{'id':4711,'description':'JSON','createdOn':{'@class':'sql-timestamp','$':'1970-01-01 00:00:01.0'}}}" | |
244 | "{'topic':{'id':4711,'description':'JSON','createdOn':{'@class':'sql-timestamp','$':'1970-01-01 00:00:01'}}}" | |
240 | 245 | .replace('\'', '"'), json); |
241 | 246 | Topic topic2 = (Topic)xstream.fromXML(json); |
242 | 247 | assertEquals(json, xstream.toXML(topic2)); |
0 | 0 | /* |
1 | * Copyright (C) 2013 XStream Committers. | |
1 | * Copyright (C) 2013, 2017 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
30 | 30 | protected void setUp() throws Exception { |
31 | 31 | super.setUp(); |
32 | 32 | xstream = new XStream(); |
33 | XStream.setupDefaultSecurity(xstream); | |
34 | xstream.allowTypesByWildcard(new String[] {"com.thoughtworks.acceptance.someobjects.*"}); | |
33 | 35 | xstream.alias("x", X.class); |
34 | 36 | } |
35 | 37 |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
31 | 31 | protected void setUp() throws Exception { |
32 | 32 | super.setUp(); |
33 | 33 | xstream = new XStream(); |
34 | XStream.setupDefaultSecurity(xstream); | |
35 | xstream.allowTypesByWildcard(new String[] {"com.thoughtworks.acceptance.someobjects.*"}); | |
34 | 36 | xstream.alias("x", X.class); |
35 | 37 | } |
36 | 38 |
0 | 0 | /* |
1 | * Copyright (C) 2006, 2007 XStream Committers. | |
1 | * Copyright (C) 2006, 2007, 2017 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
50 | 50 | System.setProperty(XMLOutputFactory.class.getName(), XMLOutputFactoryBase.class.getName()); |
51 | 51 | final MyStaxDriver driver = new MyStaxDriver(); |
52 | 52 | xstream = new XStream(driver); |
53 | XStream.setupDefaultSecurity(xstream); | |
53 | 54 | assertBothWays("Hi", "<?xml version='1.0' encoding='utf-8'?><string>Hi</string>"); |
54 | 55 | assertTrue(driver.createStaxReaderCalled); |
55 | 56 | assertTrue(driver.createStaxWriterCalled); |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2015, 2016 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2015, 2016, 2018 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
17 | 17 | |
18 | 18 | public class XppReaderTest extends AbstractXMLReaderTest { |
19 | 19 | protected HierarchicalStreamReader createReader(String xml) throws Exception { |
20 | return new XppReader(new StringReader(xml)); | |
20 | return new XppReader(new StringReader(xml), XppDriver.createDefaultParser()); | |
21 | 21 | } |
22 | 22 | |
23 | 23 | public void testIsXXEVulnerableWithExternalGeneralEntity() throws Exception { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2011, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2011, 2013, 2016 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
19 | 19 | import com.thoughtworks.acceptance.objects.SampleMaps; |
20 | 20 | import com.thoughtworks.acceptance.objects.Software; |
21 | 21 | import com.thoughtworks.xstream.core.ClassLoaderReference; |
22 | import com.thoughtworks.xstream.core.JVM; | |
22 | 23 | |
23 | 24 | import junit.framework.TestCase; |
24 | 25 | |
25 | 26 | public class ImplicitCollectionMapperTest extends TestCase { |
26 | 27 | |
27 | 28 | private ImplicitCollectionMapper implicitCollections = new ImplicitCollectionMapper( |
28 | new DefaultMapper(new ClassLoaderReference(null))); | |
29 | new DefaultMapper(new ClassLoaderReference(null)), JVM.newReflectionProvider()); | |
29 | 30 | |
30 | 31 | public void testAllowsFieldsToBeMarkedAsImplicitCollectionsToBeAdded() { |
31 | 32 | implicitCollections.add(SampleLists.class, "good", null); |
+40
-31
0 | 0 | /* |
1 | * Copyright (C) 2008, 2009 XStream Committers. | |
1 | * Copyright (C) 2008, 2009, 2017 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
15 | 15 | import java.util.HashMap; |
16 | 16 | import java.util.Iterator; |
17 | 17 | import java.util.Map; |
18 | ||
19 | import com.thoughtworks.xstream.XStream; | |
20 | import com.thoughtworks.xstream.io.xml.DomDriver; | |
18 | 21 | |
19 | 22 | import junit.framework.TestCase; |
20 | 23 | |
55 | 58 | dir.delete(); |
56 | 59 | } |
57 | 60 | |
61 | private XStream createXStream() { | |
62 | XStream xstream = new XStream(new DomDriver()); | |
63 | XStream.setupDefaultSecurity(xstream); | |
64 | return xstream; | |
65 | } | |
66 | ||
58 | 67 | public void testConcatenatesXmlExtensionWhileGettingAFilename() { |
59 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
68 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
60 | 69 | assertEquals("string@guilherme.xml", strategy.getName("guilherme")); |
61 | 70 | } |
62 | 71 | |
63 | 72 | public void testConcatenatesXmlExtensionWhileExtractingAKey() { |
64 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
73 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
65 | 74 | assertEquals("guilherme", strategy.extractKey("string@guilherme.xml")); |
66 | 75 | } |
67 | 76 | |
68 | 77 | public void testEscapesNonAcceptableCharacterWhileExtractingAKey() { |
69 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
78 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
70 | 79 | assertEquals("../guilherme", strategy.extractKey("string@..%2Fguilherme.xml")); |
71 | 80 | } |
72 | 81 | |
73 | 82 | public void testEscapesNonAcceptableCharacterWhileGettingAFilename() { |
74 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
83 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
75 | 84 | assertEquals("string@..%2Fguilherme.xml", strategy.getName("../guilherme")); |
76 | 85 | } |
77 | 86 | |
78 | 87 | public void testEscapesUTF8NonAcceptableCharacterWhileGettingAFilename() { |
79 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
88 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
80 | 89 | assertEquals("string@\u5377guilherme.xml", strategy.getName("\u5377guilherme")); |
81 | 90 | } |
82 | 91 | |
83 | 92 | public void testEscapesUTF8NonAcceptableCharacterWhileExtractingAKey() { |
84 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
93 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
85 | 94 | assertEquals("\u5377guilherme", strategy.extractKey("string@\u5377guilherme.xml")); |
86 | 95 | } |
87 | 96 | |
88 | 97 | public void testEscapesPercentageWhileGettingAFilename() { |
89 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
98 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
90 | 99 | assertEquals("string@%25guilherme.xml", strategy.getName("%guilherme")); |
91 | 100 | } |
92 | 101 | |
93 | 102 | public void testEscapesPercentageWhileExtractingAKey() { |
94 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
103 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
95 | 104 | assertEquals("%guilherme", strategy.extractKey("string@%25guilherme.xml")); |
96 | 105 | } |
97 | 106 | |
98 | 107 | public void testEscapesNullKeyWhileGettingAFileName() { |
99 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
108 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
100 | 109 | assertEquals("null@null.xml", strategy.getName(null)); |
101 | 110 | } |
102 | 111 | |
103 | 112 | public void testRestoresTypeOfKey() throws MalformedURLException { |
104 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
113 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
105 | 114 | assertEquals(new URL("http://xstream.codehaus.org"), strategy |
106 | 115 | .extractKey("url@http%3A%2F%2Fxstream.codehaus.org.xml")); |
107 | 116 | } |
108 | 117 | |
109 | 118 | public void testEscapesNullKeyWhileExtractingKey() { |
110 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
119 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
111 | 120 | assertNull(strategy.extractKey("null@null.xml")); |
112 | 121 | } |
113 | 122 | |
114 | 123 | public void testWritesASingleFile() { |
115 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
124 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
116 | 125 | strategy.put("guilherme", "aCuteString"); |
117 | 126 | File file = new File(baseDir, "string@guilherme.xml"); |
118 | 127 | assertTrue(file.isFile()); |
119 | 128 | } |
120 | 129 | |
121 | 130 | public void testWritesTwoFiles() { |
122 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
131 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
123 | 132 | strategy.put("guilherme", "aCuteString"); |
124 | 133 | strategy.put("silveira", "anotherCuteString"); |
125 | 134 | assertTrue(new File(baseDir, "string@guilherme.xml").isFile()); |
127 | 136 | } |
128 | 137 | |
129 | 138 | public void testRemovesAWrittenFile() { |
130 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
139 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
131 | 140 | strategy.put("guilherme", "aCuteString"); |
132 | 141 | assertTrue(new File(baseDir, "string@guilherme.xml").isFile()); |
133 | 142 | String aCuteString = (String)strategy.remove("guilherme"); |
136 | 145 | } |
137 | 146 | |
138 | 147 | public void testRemovesAnInvalidFile() { |
139 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
148 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
140 | 149 | String aCuteString = (String)strategy.remove("guilherme"); |
141 | 150 | assertNull(aCuteString); |
142 | 151 | } |
143 | 152 | |
144 | 153 | public void testHasZeroLength() { |
145 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
154 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
146 | 155 | assertEquals(0, strategy.size()); |
147 | 156 | } |
148 | 157 | |
149 | 158 | public void testHasOneItem() { |
150 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
159 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
151 | 160 | strategy.put("guilherme", "aCuteString"); |
152 | 161 | assertEquals(1, strategy.size()); |
153 | 162 | } |
154 | 163 | |
155 | 164 | public void testHasTwoItems() { |
156 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
165 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
157 | 166 | strategy.put("guilherme", "aCuteString"); |
158 | 167 | strategy.put("silveira", "anotherCuteString"); |
159 | 168 | assertEquals(2, strategy.size()); |
160 | 169 | } |
161 | 170 | |
162 | 171 | public void testIsNotEmpty() { |
163 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
172 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
164 | 173 | strategy.put("guilherme", "aCuteString"); |
165 | 174 | assertEquals("Map should not be empty", 1, strategy.size()); |
166 | 175 | } |
167 | 176 | |
168 | 177 | public void testDoesNotContainKey() { |
169 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
178 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
170 | 179 | assertFalse(strategy.containsKey("guilherme")); |
171 | 180 | } |
172 | 181 | |
173 | 182 | public void testContainsKey() { |
174 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
183 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
175 | 184 | strategy.put("guilherme", "aCuteString"); |
176 | 185 | assertTrue(strategy.containsKey("guilherme")); |
177 | 186 | } |
178 | 187 | |
179 | 188 | public void testGetsAFile() { |
180 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
189 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
181 | 190 | strategy.put("guilherme", "aCuteString"); |
182 | 191 | assertTrue(new File(baseDir, "string@guilherme.xml").isFile()); |
183 | 192 | String aCuteString = (String)strategy.get("guilherme"); |
185 | 194 | } |
186 | 195 | |
187 | 196 | public void testGetsAnInvalidFile() { |
188 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
197 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
189 | 198 | String aCuteString = (String)strategy.get("guilherme"); |
190 | 199 | assertNull(aCuteString); |
191 | 200 | } |
192 | 201 | |
193 | 202 | public void testRewritesASingleFile() { |
194 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
203 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
195 | 204 | strategy.put("guilherme", "aCuteString"); |
196 | 205 | File file = new File(baseDir, "string@guilherme.xml"); |
197 | 206 | assertTrue(file.isFile()); |
200 | 209 | } |
201 | 210 | |
202 | 211 | public void testIsEmpty() { |
203 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
212 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
204 | 213 | assertEquals("Map should be empty", 0, strategy.size()); |
205 | 214 | } |
206 | 215 | |
208 | 217 | Map original = new HashMap(); |
209 | 218 | original.put("guilherme", "aCuteString"); |
210 | 219 | original.put("silveira", "anotherCuteString"); |
211 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
220 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
212 | 221 | strategy.put("guilherme", "aCuteString"); |
213 | 222 | strategy.put("silveira", "anotherCuteString"); |
214 | 223 | for (Iterator iter = original.keySet().iterator(); iter.hasNext();) { |
217 | 226 | } |
218 | 227 | |
219 | 228 | public void testIteratesOverEntryAndChecksItsKeyWithAnotherInstance() { |
220 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
229 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
221 | 230 | strategy.put("guilherme", "aCuteString"); |
222 | 231 | strategy.put("silveira", "anotherCuteString"); |
223 | 232 | FilePersistenceStrategy built = new FilePersistenceStrategy(baseDir); |
228 | 237 | } |
229 | 238 | |
230 | 239 | public void testRemovesAnItemThroughIteration() { |
231 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
240 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
232 | 241 | strategy.put("guilherme", "aCuteString"); |
233 | 242 | strategy.put("silveira", "anotherCuteString"); |
234 | 243 | for (Iterator iter = strategy.iterator(); iter.hasNext();) { |
241 | 250 | } |
242 | 251 | |
243 | 252 | public void testRewritesAFile() { |
244 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
253 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
245 | 254 | strategy.put("guilherme", "aCuteString"); |
246 | 255 | strategy.put("guilherme", "anotherCuteString"); |
247 | 256 | assertEquals("anotherCuteString", strategy.get("guilherme")); |
248 | 257 | } |
249 | 258 | |
250 | 259 | public void testPutReturnsTheOldValueWhenRewritingAFile() { |
251 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); | |
260 | FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir, createXStream()); | |
252 | 261 | strategy.put("guilherme", "aCuteString"); |
253 | 262 | assertEquals("aCuteString", strategy.put("guilherme", "anotherCuteString")); |
254 | 263 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2007, 2008, 2009 XStream Committers. | |
2 | * Copyright (C) 2007, 2008, 2009, 2017 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
14 | 14 | import java.util.HashMap; |
15 | 15 | import java.util.Iterator; |
16 | 16 | import java.util.Map; |
17 | ||
18 | import com.thoughtworks.xstream.XStream; | |
19 | import com.thoughtworks.xstream.io.xml.DomDriver; | |
17 | 20 | |
18 | 21 | import junit.framework.TestCase; |
19 | 22 | |
53 | 56 | dir.delete(); |
54 | 57 | } |
55 | 58 | |
59 | private XStream createXStream() { | |
60 | XStream xstream = new XStream(new DomDriver()); | |
61 | XStream.setupDefaultSecurity(xstream); | |
62 | return xstream; | |
63 | } | |
64 | ||
56 | 65 | public void testConcatenatesXmlExtensionWhileGettingAFilename() { |
57 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
66 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
58 | 67 | assertEquals("guilherme.xml", strategy.getName("guilherme")); |
59 | 68 | } |
60 | 69 | |
61 | 70 | public void testConcatenatesXmlExtensionWhileExtractingAKey() { |
62 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
71 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
63 | 72 | assertEquals("guilherme", strategy.extractKey("guilherme.xml")); |
64 | 73 | } |
65 | 74 | |
66 | 75 | public void testEscapesNonAcceptableCharacterWhileExtractingAKey() { |
67 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
76 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
68 | 77 | assertEquals("../guilherme", strategy.extractKey("_2e__2e__2f_guilherme.xml")); |
69 | 78 | } |
70 | 79 | |
71 | 80 | public void testEscapesNonAcceptableCharacterWhileGettingAFilename() { |
72 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
81 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
73 | 82 | assertEquals("_2e__2e__2f_guilherme.xml", strategy.getName("../guilherme")); |
74 | 83 | } |
75 | 84 | |
76 | 85 | public void testEscapesUTF8NonAcceptableCharacterWhileGettingAFilename() { |
77 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
86 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
78 | 87 | assertEquals("_5377_guilherme.xml", strategy.getName("\u5377guilherme")); |
79 | 88 | } |
80 | 89 | |
81 | 90 | public void testEscapesUTF8NonAcceptableCharacterWhileExtractingAKey() { |
82 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
91 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
83 | 92 | assertEquals("\u5377guilherme", strategy.extractKey("_5377_guilherme.xml")); |
84 | 93 | } |
85 | 94 | |
86 | 95 | public void testEscapesUnderlineWhileGettingAFilename() { |
87 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
96 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
88 | 97 | assertEquals("__guilherme.xml", strategy.getName("_guilherme")); |
89 | 98 | } |
90 | 99 | |
91 | 100 | public void testEscapesUnderlineWhileExtractingAKey() { |
92 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
101 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
93 | 102 | assertEquals("_guilherme", strategy.extractKey("__guilherme.xml")); |
94 | 103 | } |
95 | 104 | |
96 | 105 | public void testEscapesNullKeyWhileGettingAFileName() { |
97 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
106 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
98 | 107 | assertEquals("_0_.xml", strategy.getName(null)); |
99 | 108 | } |
100 | 109 | |
101 | 110 | public void testEscapesNullKeyWhileExtractingKey() { |
102 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
111 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
103 | 112 | assertNull(strategy.extractKey("_0_.xml")); |
104 | 113 | } |
105 | 114 | |
106 | 115 | public void testWritesASingleFile() { |
107 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
116 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
108 | 117 | strategy.put("guilherme", "aCuteString"); |
109 | 118 | File file = new File(baseDir, "guilherme.xml"); |
110 | 119 | assertTrue(file.exists()); |
111 | 120 | } |
112 | 121 | |
113 | 122 | public void testWritesTwoFiles() { |
114 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
123 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
115 | 124 | strategy.put("guilherme", "aCuteString"); |
116 | 125 | strategy.put("silveira", "anotherCuteString"); |
117 | 126 | assertTrue(new File(baseDir, "guilherme.xml").exists()); |
119 | 128 | } |
120 | 129 | |
121 | 130 | public void testRemovesAWrittenFile() { |
122 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
131 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
123 | 132 | strategy.put("guilherme", "aCuteString"); |
124 | 133 | assertTrue(new File(baseDir, "guilherme.xml").exists()); |
125 | 134 | String aCuteString = (String)strategy.remove("guilherme"); |
128 | 137 | } |
129 | 138 | |
130 | 139 | public void testRemovesAnInvalidFile() { |
131 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
140 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
132 | 141 | String aCuteString = (String)strategy.remove("guilherme"); |
133 | 142 | assertNull(aCuteString); |
134 | 143 | } |
135 | 144 | |
136 | 145 | public void testHasZeroLength() { |
137 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
146 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
138 | 147 | assertEquals(0, strategy.size()); |
139 | 148 | } |
140 | 149 | |
141 | 150 | public void testHasOneItem() { |
142 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
151 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
143 | 152 | strategy.put("guilherme", "aCuteString"); |
144 | 153 | assertEquals(1, strategy.size()); |
145 | 154 | } |
146 | 155 | |
147 | 156 | public void testHasTwoItems() { |
148 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
157 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
149 | 158 | strategy.put("guilherme", "aCuteString"); |
150 | 159 | strategy.put("silveira", "anotherCuteString"); |
151 | 160 | assertEquals(2, strategy.size()); |
152 | 161 | } |
153 | 162 | |
154 | 163 | public void testIsNotEmpty() { |
155 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
164 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
156 | 165 | strategy.put("guilherme", "aCuteString"); |
157 | 166 | assertEquals("Map should not be empty", 1, strategy.size()); |
158 | 167 | } |
159 | 168 | |
160 | 169 | public void testDoesNotContainKey() { |
161 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
170 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
162 | 171 | assertFalse(strategy.containsKey("guilherme")); |
163 | 172 | } |
164 | 173 | |
165 | 174 | public void testContainsKey() { |
166 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
175 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
167 | 176 | strategy.put("guilherme", "aCuteString"); |
168 | 177 | assertTrue(strategy.containsKey("guilherme")); |
169 | 178 | } |
170 | 179 | |
171 | 180 | public void testGetsAFile() { |
172 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
181 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
173 | 182 | strategy.put("guilherme", "aCuteString"); |
174 | 183 | assertTrue(new File(baseDir, "guilherme.xml").exists()); |
175 | 184 | String aCuteString = (String)strategy.get("guilherme"); |
177 | 186 | } |
178 | 187 | |
179 | 188 | public void testGetsAnInvalidFile() { |
180 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
189 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
181 | 190 | String aCuteString = (String)strategy.get("guilherme"); |
182 | 191 | assertNull(aCuteString); |
183 | 192 | } |
184 | 193 | |
185 | 194 | public void testRewritesASingleFile() { |
186 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
195 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
187 | 196 | strategy.put("guilherme", "aCuteString"); |
188 | 197 | File file = new File(baseDir, "guilherme.xml"); |
189 | 198 | assertTrue(file.exists()); |
192 | 201 | } |
193 | 202 | |
194 | 203 | public void testIsEmpty() { |
195 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
204 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
196 | 205 | assertEquals("Map should be empty", 0, strategy.size()); |
197 | 206 | } |
198 | 207 | |
200 | 209 | Map original = new HashMap(); |
201 | 210 | original.put("guilherme", "aCuteString"); |
202 | 211 | original.put("silveira", "anotherCuteString"); |
203 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
212 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
204 | 213 | strategy.put("guilherme", "aCuteString"); |
205 | 214 | strategy.put("silveira", "anotherCuteString"); |
206 | 215 | for (Iterator iter = original.keySet().iterator(); iter.hasNext();) { |
210 | 219 | |
211 | 220 | // actually an acceptance test? |
212 | 221 | public void testIteratesOverEntryAndChecksItsKeyWithAnotherInstance() { |
213 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
222 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
214 | 223 | strategy.put("guilherme", "aCuteString"); |
215 | 224 | strategy.put("silveira", "anotherCuteString"); |
216 | 225 | FileStreamStrategy built = new FileStreamStrategy(baseDir); |
221 | 230 | } |
222 | 231 | |
223 | 232 | public void testRemovesAnItemThroughIteration() { |
224 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
233 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
225 | 234 | strategy.put("guilherme", "aCuteString"); |
226 | 235 | strategy.put("silveira", "anotherCuteString"); |
227 | 236 | for (Iterator iter = strategy.iterator(); iter.hasNext();) { |
234 | 243 | } |
235 | 244 | |
236 | 245 | public void testRewritesAFile() { |
237 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
246 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
238 | 247 | strategy.put("guilherme", "aCuteString"); |
239 | 248 | strategy.put("guilherme", "anotherCuteString"); |
240 | 249 | assertEquals("anotherCuteString", strategy.get("guilherme")); |
241 | 250 | } |
242 | 251 | |
243 | 252 | public void testPutReturnsTheOldValueWhenRewritingAFile() { |
244 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir); | |
253 | FileStreamStrategy strategy = new FileStreamStrategy(baseDir, createXStream()); | |
245 | 254 | strategy.put("guilherme", "aCuteString"); |
246 | 255 | assertEquals("aCuteString", strategy.put("guilherme", "anotherCuteString")); |
247 | 256 | } |
248 | ||
249 | 257 | } |
0 | 0 | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> |
1 | 1 | <!-- |
2 | 2 | Copyright (C) 2006 Joe Walnes. |
3 | Copyright (C) 2006, 2007, 2009, 2011, 2012, 2013 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2009, 2011, 2012, 2013, 2017 XStream committers. | |
4 | 4 | All rights reserved. |
5 | 5 | |
6 | 6 | The software in this package is published under the terms of the BSD |
13 | 13 | <parent> |
14 | 14 | <groupId>com.thoughtworks.xstream</groupId> |
15 | 15 | <artifactId>xstream-parent</artifactId> |
16 | <version>1.4.9</version> | |
16 | <version>1.4.11.1</version> | |
17 | 17 | </parent> |
18 | 18 | <artifactId>xstream-benchmark</artifactId> |
19 | 19 | <packaging>jar</packaging> |
22 | 22 | |
23 | 23 | <profiles> |
24 | 24 | <profile> |
25 | <id>jdk18-ge</id> | |
25 | <id>jdk18</id> | |
26 | 26 | <activation> |
27 | <jdk>[1.8,)</jdk> | |
27 | <jdk>1.8</jdk> | |
28 | 28 | </activation> |
29 | 29 | <build> |
30 | 30 | <plugins> |
49 | 49 | <detectJavaApiLink>false</detectJavaApiLink> |
50 | 50 | <source>${version.java.source}</source> |
51 | 51 | <links> |
52 | <link>${link.javadoc.javase}</link> | |
52 | <link>${javadoc.link.javase}</link> | |
53 | 53 | </links> |
54 | 54 | </configuration> |
55 | 55 | </plugin> |
57 | 57 | </reporting> |
58 | 58 | </profile> |
59 | 59 | <profile> |
60 | <id>jdk15-ge</id> | |
60 | <id>jdk16-ge</id> | |
61 | 61 | <activation> |
62 | <jdk>[1.5,)</jdk> | |
62 | <jdk>[1.6,)</jdk> | |
63 | 63 | </activation> |
64 | 64 | <build> |
65 | 65 | <plugins> |
13 | 13 | <parent> |
14 | 14 | <groupId>com.thoughtworks.xstream</groupId> |
15 | 15 | <artifactId>xstream-parent</artifactId> |
16 | <version>1.4.9</version> | |
16 | <version>1.4.11.1</version> | |
17 | 17 | </parent> |
18 | 18 | <artifactId>xstream-distribution</artifactId> |
19 | 19 | <packaging>pom</packaging> |
47 | 47 | |
48 | 48 | <profiles> |
49 | 49 | <profile> |
50 | <id>jdk18-ge</id> | |
50 | <id>jdk18</id> | |
51 | 51 | <activation> |
52 | <jdk>[1.8,)</jdk> | |
52 | <jdk>1.8</jdk> | |
53 | 53 | </activation> |
54 | 54 | <build> |
55 | 55 | <plugins> |
0 | <html> | |
1 | <!-- | |
2 | Copyright (C) 2017, 2018 XStream committers. | |
3 | All rights reserved. | |
4 | ||
5 | The software in this package is published under the terms of the BSD | |
6 | style license a copy of which has been included with this distribution in | |
7 | the LICENSE.txt file. | |
8 | ||
9 | Created on 25. April 2017 by Joerg Schaible | |
10 | --> | |
11 | <head> | |
12 | <title>CVE-2013-7285</title> | |
13 | </head> | |
14 | <body> | |
15 | ||
16 | <h2 id="vulnerability">Vulnerability</h2> | |
17 | ||
18 | <p>CVE-2013-7285: XStream can be used for Remote Code Execution.</p> | |
19 | ||
20 | <h2 id="affected_versions">Affected Versions</h2> | |
21 | ||
22 | <p>All versions until and including version 1.4.6 are affected, but a <a href="#workaround">workaround</a> exist.</p> | |
23 | ||
24 | <p>Version 1.4.10 is affected if the security framework has not been initialized.</p> | |
25 | ||
26 | <h2 id="description">Description</h2> | |
27 | ||
28 | <p>The processed stream at unmarshalling time contains type information to recreate the formerly written objects. | |
29 | XStream creates therefore new instances based on these type information. An attacker can manipulate the processed | |
30 | input stream and replace or inject objects, that can execute arbitrary shell commands.</p> | |
31 | ||
32 | <h2 id="reproduction">Steps to Reproduce</h2> | |
33 | ||
34 | <p>Create a simple interface e.g. named <em>Contact</em> and an implementation class. Use XStream to marshal such | |
35 | an object to XML. Replace the XML with following snippet and unmarshal it again with XStream:</p> | |
36 | <div class="Source XML"><pre><contact> | |
37 | <dynamic-proxy> | |
38 | <interface>org.company.model.Contact</interface> | |
39 | <handler class='java.beans.EventHandler'> | |
40 | <target class='java.lang.ProcessBuilder'> | |
41 | <command> | |
42 | <string>calc.exe</string> | |
43 | </command> | |
44 | </target> | |
45 | <action>start</action> | |
46 | <handler> | |
47 | </dynamic-proxy> | |
48 | </contact> | |
49 | </pre></div> | |
50 | <div class="Source Java"><pre>XStream xstream = new XStream(); | |
51 | Contact contact = (Contact)xstream.fromXML(xml); | |
52 | </pre></div> | |
53 | ||
54 | <p>Then as soon as the code calls any method on the Contact instance, the payload gets executed, e.g. | |
55 | contact.getFirstName().</p> | |
56 | ||
57 | <p>Note, this example uses XML, but the attack can be performed for any supported format. e.g. JSON.</p> | |
58 | ||
59 | <h2 id="impact">Impact</h2> | |
60 | ||
61 | <p>The vulnerability may allow a remote attacker to run arbitrary shell commands only by manipulating the processed | |
62 | input stream.</p> | |
63 | ||
64 | <h2 id="workaround">Workaround</h2> | |
65 | <p>Users can register an own converter for dynamic proxies, the <em>java.beans.EventHandler</em> type or for the | |
66 | <em>java.lang.ProcessBuilder</em> type, that also protects against an attack for this special case:</p> | |
67 | <div class="Source Java"><pre>xstream.registerConverter(new Converter() { | |
68 | public boolean canConvert(Class type) { | |
69 | return type != null && (type == java.beans.EventHandler || type == java.lang.ProcessBuilder || Proxy.isProxy(type)); | |
70 | } | |
71 | ||
72 | public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { | |
73 | throw new ConversionException("Unsupported type due to security reasons."); | |
74 | } | |
75 | ||
76 | public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { | |
77 | throw new ConversionException("Unsupported type due to security reasons."); | |
78 | } | |
79 | }, XStream.PRIORITY_LOW); | |
80 | </pre></div> | |
81 | ||
82 | <h2 id="credits">Credits</h2> | |
83 | ||
84 | <p>The vulnerability was discovered and reported by Pierre Francis Ernst of IBM Canada.</p> | |
85 | ||
86 | </body> | |
87 | </html>⏎ |
0 | <html> | |
1 | <!-- | |
2 | Copyright (C) 2017, 2018 XStream committers. | |
3 | All rights reserved. | |
4 | ||
5 | The software in this package is published under the terms of the BSD | |
6 | style license a copy of which has been included with this distribution in | |
7 | the LICENSE.txt file. | |
8 | ||
9 | Created on 3. May 2017 by Joerg Schaible | |
10 | --> | |
11 | <head> | |
12 | <title>CVE-2016-3674</title> | |
13 | </head> | |
14 | <body> | |
15 | ||
16 | <h2 id="vulnerability">Vulnerability</h2> | |
17 | ||
18 | <p>CVE-2016-3674: XML External Entity (XXE) Vulnerability in XStream.</p> | |
19 | ||
20 | <h2 id="affected_versions">Affected Versions</h2> | |
21 | ||
22 | <p>XStream is not vulnerable, if the default XML Pull Parser is used (Xpp3 or kXML2), since these parser types do | |
23 | not process XML entities at all.</p> | |
24 | ||
25 | <p>All versions until and including version 1.4.8 are affected, if they use explicitly one of the following parsers:</p> | |
26 | <ul> | |
27 | <li>DOM4J</li> | |
28 | <li>DOM</li> | |
29 | <li>JDOM</li> | |
30 | <li>JDOM2</li> | |
31 | <li>StAX implementation</li> | |
32 | <li>XOM</li> | |
33 | </ul> | |
34 | ||
35 | <p>XStream's HierarchicalStreamDriver implementations will now explicitly turn off the processing of external | |
36 | entities, but the setting is not respected by all parser implementations. XStream stays therefore vulnerable in | |
37 | future, if one of the following parser implementations is explicitly used:</p> | |
38 | <ul> | |
39 | <li>DOM implementation from Java 5 runtime and below</li> | |
40 | <li>StAX implementation from Java 6 runtime and below</li> | |
41 | <li>StAX implementation from BEA (old reference implementation)</li> | |
42 | <li>XOM</li> | |
43 | </ul> | |
44 | ||
45 | <p>See <a href="faq.html#Security_XXEVulnerability">FAQ</a> for a matrix explaining some parser behavior.</p> | |
46 | ||
47 | <h2 id="description">Description</h2> | |
48 | ||
49 | <p>XStream supports a lot of different XML parsers. Some of those can also process external entities which was | |
50 | enabled by default. An attacker could therefore provide manipulated XML as input to access data on the file | |
51 | system, see <a href="https://www.owasp.org/index.php/XML_External_Entity_%28XXE%29_Processing">XXE Vulnerability</a>.</p> | |
52 | ||
53 | <h2 id="reproduction">Steps to Reproduce</h2> | |
54 | ||
55 | <p>An attacker might use external general or parameter entities:</p> | |
56 | <div class="Source XML"><pre><?xml version="1.0"> | |
57 | <!DOCTYPE root [ | |
58 | <!ELEMENT string (#PCDATA)> | |
59 | <!ENTITY content SYSTEM "file:/etc/passwd"> | |
60 | ]><string>&content;</string> | |
61 | </pre></div> | |
62 | <div class="Source XML"><pre><?xml version="1.0"> | |
63 | <!DOCTYPE root [ | |
64 | <!ELEMENT string (#PCDATA)> | |
65 | <!ENTITY content SYSTEM "file:/etc/passwd"> | |
66 | %content; | |
67 | ]><string>test</string> | |
68 | </pre></div> | |
69 | <p>Use one of the XML documents above, initialize XStream with a vulnerable parser and unmarshal the XML:</p> | |
70 | <div class="Source Java"><pre>XStream xstream = new XStream(); | |
71 | String s = (String)xstream.fromXML(xml); | |
72 | </pre></div> | |
73 | ||
74 | <h2 id="impact">Impact</h2> | |
75 | ||
76 | <p>The vulnerability may allow a remote attacker to retrieve the content of arbitrary files with known locations in | |
77 | a local file system if the Java process has read access.</p> | |
78 | ||
79 | <h2 id="workarounds">Workaround</h2> | |
80 | ||
81 | <p>Use one of the XML Pull Parser implementations.</p> | |
82 | ||
83 | <h2 id="credits">Credits</h2> | |
84 | ||
85 | <p>The vulnerability was discovered and reported by Alexander Klink.</p> | |
86 | ||
87 | </body> | |
88 | </html>⏎ |
0 | <html> | |
1 | <!-- | |
2 | Copyright (C) 2017 XStream committers. | |
3 | All rights reserved. | |
4 | ||
5 | The software in this package is published under the terms of the BSD | |
6 | style license a copy of which has been included with this distribution in | |
7 | the LICENSE.txt file. | |
8 | ||
9 | Created on 25. April 2017 by Joerg Schaible | |
10 | --> | |
11 | <head> | |
12 | <title>CVE-2017-7957</title> | |
13 | </head> | |
14 | <body> | |
15 | ||
16 | <h2 id="vulnerability">Vulnerability</h2> | |
17 | ||
18 | <p>CVE-2017-7957: XStream can cause a Denial of Service when unmarshalling void.</p> | |
19 | ||
20 | <h2 id="affected_versions">Affected Versions</h2> | |
21 | ||
22 | <p>All versions until and including version 1.4.9 are affected, but <a href="#workarounds">workarounds</a> exist.</p> | |
23 | ||
24 | <h2 id="description">Description</h2> | |
25 | ||
26 | <p>The processed stream at unmarshalling time contains type information to recreate the formerly written objects. | |
27 | XStream creates therefore new instances based on these type information. The crash occurs if this information | |
28 | advises XStream to create an instance of the primitive type <em>void</em>. This situation can only happen if an | |
29 | attacker was able to manipulate the incoming data, since such an instance does not exist and cannot be marshalled | |
30 | therefore in first place.</p> | |
31 | ||
32 | <h2 id="reproduction">Steps to Reproduce</h2> | |
33 | ||
34 | <p>The simplest way to demonstrate the problem is with this snippet:</p> | |
35 | <div class="Source Java"><pre>XStream xstream = new XStream(); | |
36 | xstream.fromXML("<void/>"); | |
37 | </pre></div> | |
38 | ||
39 | <p>If XStream is configured to read JSON, the equivalent line is:</p> | |
40 | <div class="Source Java"><pre>xstream.fromXML("{'void':null}"); | |
41 | </pre></div> | |
42 | ||
43 | <p>However, the problematic type information can be injected at any position in | |
44 | the provided stream, in XML just by adding a class attribute:</p> | |
45 | <div class="Source Java"><pre>xstream.fromXML("<string class='void'>Hello, world!</string>"); | |
46 | </pre></div> | |
47 | ||
48 | <h2 id="impact">Impact</h2> | |
49 | ||
50 | <p>The vulnerability may allow a remote attacker to cause a crash on the target system resulting in a denial of | |
51 | service only by manipulating the processed input stream.</p> | |
52 | ||
53 | <h2 id="workarounds">Workarounds</h2> | |
54 | <p>XStream contains since version 1.4.7 a <a href="security.html">security framework</a> to prevent an attack | |
55 | described in CVE-2013-7285. This framework can also be used to suppress the current vulnerability by setting:</p> | |
56 | <div class="Source Java"><pre>xstream.denyTypes(new Class[]{ void.class, Void.class }); | |
57 | </pre></div> | |
58 | ||
59 | <p>Users of older XStream releases can register an own converter for the <em>void</em> type, that also protects | |
60 | against this attack:</p> | |
61 | <div class="Source Java"><pre>xstream.registerConverter(new Converter() { | |
62 | public boolean canConvert(Class type) { | |
63 | return Void.class == type || void.class == type; | |
64 | } | |
65 | ||
66 | public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { | |
67 | throw new ConversionException("Type void cannot have an instance"); | |
68 | } | |
69 | ||
70 | public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { | |
71 | throw new ConversionException("Type void cannot have an instance"); | |
72 | } | |
73 | }, XStream.PRIORITY_VERY_HIGH); | |
74 | </pre></div> | |
75 | ||
76 | <h2 id="credits">Credits</h2> | |
77 | ||
78 | <p>The vulnerability was discovered and reported by Huijun Chen and Xiaolong Zhu of Huawei Technologies Co., Ltd.</p> | |
79 | ||
80 | </body> | |
81 | </html> |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | 2 | Copyright (C) 2006 Joe Walnes. |
3 | Copyright (C) 2006, 2007, 2011 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2011, 2017 XStream committers. | |
4 | 4 | All rights reserved. |
5 | 5 | |
6 | 6 | The software in this package is published under the terms of the BSD |
37 | 37 | public class Tutorial { |
38 | 38 | |
39 | 39 | public static void main(String[] args) { |
40 | XStream stream = new XStream(); | |
40 | XStream xstream = new XStream(); | |
41 | 41 | RendezvousMessage msg = new RendezvousMessage(15); |
42 | System.out.println(stream.toXML(msg)); | |
42 | System.out.println(xstream.toXML(msg)); | |
43 | 43 | } |
44 | 44 | |
45 | 45 | } |
73 | 73 | this type:</p> |
74 | 74 | <div class="Source Java"><pre> |
75 | 75 | public static void main(String[] args) { |
76 | XStream stream = new XStream(); | |
76 | XStream xstream = new XStream(); | |
77 | 77 | xstream.processAnnotations(RendezvousMessage.class); |
78 | 78 | RendezvousMessage msg = new RendezvousMessage(15); |
79 | System.out.println(stream.toXML(msg)); | |
79 | System.out.println(xstream.toXML(msg)); | |
80 | 80 | } |
81 | 81 | </pre></div> |
82 | 82 | <p>Note that we have called the processAnnotations method of XStream. This method registers all aliases annotations in |
112 | 112 | </pre></div> |
113 | 113 | <div class="Source Java"><pre> |
114 | 114 | public static void main(String[] args) { |
115 | XStream stream = new XStream(); | |
115 | XStream xstream = new XStream(); | |
116 | 116 | xstream.processAnnotations(RendezvousMessage.class); |
117 | 117 | RendezvousMessage msg = new RendezvousMessage(15, "firstPart","secondPart"); |
118 | System.out.println(stream.toXML(msg)); | |
118 | System.out.println(xstream.toXML(msg)); | |
119 | 119 | } |
120 | 120 | </pre></div> |
121 | 121 | <p>The resulting XML shows the collection name before its elements:</p> |
481 | 481 | public class Tutorial { |
482 | 482 | |
483 | 483 | public static void main(String[] args) { |
484 | XStream stream = new XStream(); | |
484 | XStream xstream = new XStream(); | |
485 | 485 | xstream.autodetectAnnotations(true); |
486 | 486 | RendezvousMessage msg = new RendezvousMessage(15); |
487 | System.out.println(stream.toXML(msg)); | |
487 | System.out.println(xstream.toXML(msg)); | |
488 | 488 | } |
489 | 489 | |
490 | 490 | } |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | Copyright (C) 2015, 2016 XStream committers. | |
2 | Copyright (C) 2015, 2016, 2017, 2018 XStream committers. | |
3 | 3 | All rights reserved. |
4 | 4 | |
5 | 5 | The software in this package is published under the terms of the BSD |
32 | 32 | |
33 | 33 | <p>All benchmark values below measure the average throughput in nanosecond per operation. JMH provides additional |
34 | 34 | measurement options, see online help. The maximum deviation for each benchmark is recorded in the reference files |
35 | of the distributed ZIP file. The benchmark is executed on Linux 4.1.12 Gentoo 64-bit system with an Intel Core i7 | |
35 | of the distributed ZIP file. The benchmark is executed on Linux 4.14.65 Gentoo 64-bit system with an Intel Core i7 | |
36 | 36 | CPU 920 of 2.67 GHz. Note again, that these values are no replacement for real profiler results and they may |
37 | vary from run to run (see reference files) due to this machine's background processes on a single CPU. However, it | |
38 | can give you some idea of what you can expect using different parser technologies.</p> | |
37 | vary from run to run (see reference files) due to this machine's background processes. However, it can give you some | |
38 | idea of what you can expect using different parser technologies.</p> | |
39 | 39 | |
40 | 40 | <h2 id="parser">Parser Benchmark</h2> |
41 | 41 | |
50 | 50 | <th>Nested</th> |
51 | 51 | </tr> |
52 | 52 | <tr> |
53 | <th>W3C DOM (Oracle JDK 1.8.0_66)</th> | |
54 | <td>10037380.795</td> | |
55 | <td>54234293.351</td> | |
56 | <td>1917332.056</td> | |
53 | <th>W3C DOM (Oracle JDK 1.8.0_181)</th> | |
54 | <td>9710278.896</td> | |
55 | <td>53954694.751</td> | |
56 | <td>5148010.389</td> | |
57 | 57 | </tr> |
58 | 58 | <tr> |
59 | 59 | <th>JDOM (1.1.3)</th> |
60 | <td>6368317.636</td> | |
61 | <td>7910979.223</td> | |
62 | <td>3862796.027</td> | |
60 | <td>6387821.035</td> | |
61 | <td>6898339.792</td> | |
62 | <td>14111857.552</td> | |
63 | 63 | </tr> |
64 | 64 | <tr> |
65 | 65 | <th>JDOM 2 (2.0.5)</th> |
66 | <td>5767640.105</td> | |
67 | <td>10570210.653</td> | |
68 | <td>2980906.727</td> | |
66 | <td>5921949.583</td> | |
67 | <td>8723291.385</td> | |
68 | <td>10579620.188</td> | |
69 | 69 | </tr> |
70 | 70 | <tr> |
71 | 71 | <th>DOM4J (1.6.1)</th> |
72 | <td>7816280.084</td> | |
73 | <td>92998322.952</td> | |
74 | <td>2108075.646</td> | |
72 | <td>7452345.867</td> | |
73 | <td>93099746.029</td> | |
74 | <td>5533035.930</td> | |
75 | 75 | </tr> |
76 | 76 | <tr> |
77 | 77 | <th>XOM (1.1)</th> |
78 | <td>7950778.533</td> | |
79 | <td>38704485.310</td> | |
80 | <td>2471019.743</td> | |
78 | <td>8204769.944</td> | |
79 | <td>42486494.920</td> | |
80 | <td>8086714.065</td> | |
81 | 81 | </tr> |
82 | 82 | <tr> |
83 | 83 | <th>StAX (BEA 1.2.0)</th> |
84 | <td>3108517.699</td> | |
85 | <td>1310406.961</td> | |
86 | <td>669111.164</td> | |
84 | <td>2879876.995</td> | |
85 | <td>666062.149</td> | |
86 | <td>572549.126</td> | |
87 | 87 | </tr> |
88 | 88 | <tr> |
89 | 89 | <th>StAX (Woodstox 3.2.7)</th> |
90 | <td>1884858.525</td> | |
91 | <td>1240767.393</td> | |
92 | <td>650470.623</td> | |
93 | </tr> | |
94 | <tr> | |
95 | <th>StAX (Oracle JDK 1.8.0_66)</th> | |
96 | <td>7366387.272</td> | |
97 | <td>1334398.501</td> | |
98 | <td>688229.709</td> | |
90 | <td>1845769.311</td> | |
91 | <td>632147.776</td> | |
92 | <td>604788.852</td> | |
93 | </tr> | |
94 | <tr> | |
95 | <th>StAX (Oracle JDK 1.8.0_131)</th> | |
96 | <td>7444273.102</td> | |
97 | <td>706572.092</td> | |
98 | <td>617636.917</td> | |
99 | 99 | </tr> |
100 | 100 | <tr> |
101 | 101 | <th>XPP (Xpp3 min 1.1.4c)</th> |
102 | <td>2109341.076</td> | |
103 | <td>1309607.210</td> | |
104 | <td>3301732.767</td> | |
102 | <td>2155470.575</td> | |
103 | <td>661082.180</td> | |
104 | <td>12444913.194</td> | |
105 | 105 | </tr> |
106 | 106 | <tr> |
107 | 107 | <th>XPP (kXML2 min 2.3.0)</th> |
108 | <td>3391204.266</td> | |
109 | <td>1514514.680</td> | |
110 | <td>8105934.241</td> | |
111 | </tr> | |
112 | <tr> | |
113 | <th>Binary (XStream 1.4.9)</th> | |
114 | <td>1144243.750</td> | |
115 | <td>1062031.901</td> | |
116 | <td>496839.565</td> | |
108 | <td>3663477.841</td> | |
109 | <td>854613.418</td> | |
110 | <td>34372562.351</td> | |
111 | </tr> | |
112 | <tr> | |
113 | <th>Binary (XStream 1.4.10)</th> | |
114 | <td>1129812.942</td> | |
115 | <td>383203.739</td> | |
116 | <td>260233.635</td> | |
117 | 117 | </tr> |
118 | 118 | <tr> |
119 | 119 | <th>Jettison (1.2)</th> |
120 | <td>3002547.220</td> | |
121 | <td>1159238.555</td> | |
122 | <td>682182.733</td> | |
120 | <td>3016232.225</td> | |
121 | <td>555908.503</td> | |
122 | <td>619961.028</td> | |
123 | 123 | </tr> |
124 | 124 | </table> |
125 | 125 | |
129 | 129 | <dt>Array</dt> |
130 | 130 | <dd>A single element with 1.000 child elements.</dd> |
131 | 131 | <dt>Nested</dt> |
132 | <dd>Nested elements in 500 levels.</dd> | |
132 | <dd>Nested elements in 1000 levels (since version 1.4.10).</dd> | |
133 | 133 | </dl> |
134 | 134 | |
135 | 135 | <h2 id="converterType">Converter Type Benchmark</h2> |
145 | 145 | </tr> |
146 | 146 | <tr> |
147 | 147 | <th>Custom</th> |
148 | <td>11276718.384</td> | |
148 | <td>9176744.283</td> | |
149 | 149 | </tr> |
150 | 150 | <tr> |
151 | 151 | <th>Java Bean</th> |
152 | <td>28878706.293</td> | |
152 | <td>18353984.976</td> | |
153 | 153 | </tr> |
154 | 154 | <tr> |
155 | 155 | <th>Reflection</th> |
156 | <td>40085786.696</td> | |
156 | <td>23371721.858</td> | |
157 | 157 | </tr> |
158 | 158 | </table> |
159 | 159 | |
179 | 179 | </tr> |
180 | 180 | <tr> |
181 | 181 | <th>No Cache</th> |
182 | <td>19626160.696</td> | |
182 | <td>9422597.717</td> | |
183 | 183 | </tr> |
184 | 184 | <tr> |
185 | 185 | <th>Intern</th> |
186 | <td>23060982.052</td> | |
186 | <td>12576002.757</td> | |
187 | 187 | </tr> |
188 | 188 | <tr> |
189 | 189 | <th>ConcurrentMap (length limit)</th> |
190 | <td>21796001.29</td> | |
190 | <td>10411028.373</td> | |
191 | 191 | </tr> |
192 | 192 | <tr> |
193 | 193 | <th>ConcurrentMap (unlimited)</th> |
194 | <td>21378299.003</td> | |
194 | <td>10666492.267</td> | |
195 | 195 | </tr> |
196 | 196 | <tr> |
197 | 197 | <th>Sync'd WeakCache (length limit)</th> |
198 | <td>21838410.801</td> | |
198 | <td>10948390.386</td> | |
199 | 199 | </tr> |
200 | 200 | <tr> |
201 | 201 | <th>Sync'd WeakCache (unlimited)</th> |
202 | <td>22011251.691</td> | |
202 | <td>11917404.787</td> | |
203 | 203 | </tr> |
204 | 204 | </table> |
205 | 205 | |
240 | 240 | </tr> |
241 | 241 | <tr> |
242 | 242 | <th>No Coding</th> |
243 | <td>7299475.975</td> | |
243 | <td>4190972.243</td> | |
244 | 244 | </tr> |
245 | 245 | <tr> |
246 | 246 | <th>Dollar Coding</th> |
247 | <td>7767196.902</td> | |
247 | <td>4621025.135</td> | |
248 | 248 | </tr> |
249 | 249 | <tr> |
250 | 250 | <th>Escaped Underscore Coding</th> |
251 | <td>9894393.289</td> | |
251 | <td>5896886.514</td> | |
252 | 252 | </tr> |
253 | 253 | <tr> |
254 | 254 | <th>Cached Escaped Underscore Coding</th> |
255 | <td>7867671.962</td> | |
255 | <td>4350643.046</td> | |
256 | 256 | </tr> |
257 | 257 | <tr> |
258 | 258 | <th>Xml Friendly Coding</th> |
259 | <td>8635501.208</td> | |
259 | <td>4938586.549</td> | |
260 | 260 | </tr> |
261 | 261 | </table> |
262 | 262 |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | 2 | Copyright (C) 2005, 2006 Joe Walnes. |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 XStream committers. | |
4 | 4 | All rights reserved. |
5 | 5 | |
6 | 6 | The software in this package is published under the terms of the BSD |
9 | 9 | |
10 | 10 | Created on 29. January 2005 by Joe Walnes |
11 | 11 | --> |
12 | <head> | |
13 | <title>Change History</title> | |
14 | </head> | |
15 | <body> | |
16 | ||
17 | <p>Changes are split into three categories:</p> | |
18 | ||
19 | <ul> | |
20 | <li><b>Major changes</b>: The major new features that all users should know about.</li> | |
21 | <li><b>Minor changes</b>: Any smaller changes, including bugfixes.</li> | |
22 | <li><b>API changes</b>: Any changes to the API that could impact existing users.</li> | |
23 | </ul> | |
24 | ||
25 | <p>Full details can be found in GitHub's | |
26 | <a href="https://github.com/x-stream/xstream/issues?q=is%3Aissue+is%3Aclosed">Issues</a>, filter for the | |
27 | appropriate milestone. | |
12 | <head> | |
13 | <title>Change History</title> | |
14 | </head> | |
15 | <body> | |
16 | ||
17 | <p>Changes are split into three categories:</p> | |
18 | ||
19 | <ul> | |
20 | <li><b>Major changes</b>: The major new features that all users should know about.</li> | |
21 | <li><b>Minor changes</b>: Any smaller changes, including bugfixes.</li> | |
22 | <li><b>API changes</b>: Any changes to the API that could impact existing users.</li> | |
23 | </ul> | |
24 | ||
25 | <p> | |
26 | Full details can be found in GitHub's <a href="https://github.com/x-stream/xstream/issues?q=is%3Aissue+is%3Aclosed">Issues</a>, | |
27 | filter for the appropriate milestone. | |
28 | 28 | </p> |
29 | ||
29 | ||
30 | 30 | <!-- |
31 | <h1 id="upcoming-1.4.x">Upcoming 1.4.x maintenance release</h1> | |
32 | ||
33 | <p>Not yet released.</p> | |
31 | <h1 id="upcoming-1.4.x">Upcoming 1.4.x maintenance release</h1> | |
32 | ||
33 | <p>Not yet released.</p> | |
34 | 34 | --> |
35 | ||
36 | <h1 id="1.4.9">1.4.9</h1> | |
37 | ||
38 | <p>Released March 15, 2016.</p> | |
39 | ||
40 | <h2>Major changes</h2> | |
41 | ||
42 | <ul> | |
43 | <li>GHI:#25: Fix <a href="https://www.owasp.org/index.php/XML_External_Entity_%28XXE%29_Processing">XXE | |
44 | vulnerability</a>: Fixed affected drivers were Dom4JDriver, DomDriver, JDomDriver, JDom2Driver, SjsxpDriver, | |
45 | StandardStaxDriver and WstxDriver. Still vulnerable are BEAStaxDriver and XomDriver. Processing of (external) | |
46 | entities has been disabled. See <a href="faq.html#Security_XXEVulnerability">FAQ</a> for more information.</li> | |
47 | <li>Benchmark module has been deprecated in favor of <a href="http://openjdk.java.net/projects/code-tools/jmh/"> | |
48 | JMH (Java Microbenchmarking Harness)</a>.</li> | |
49 | <li>GHI:#33 and GHPR:#38: Add converter for java.nio.file.Path (by Aaron Jonson).</li> | |
50 | </ul> | |
51 | ||
52 | <h2>Minor changes</h2> | |
53 | ||
54 | <ul> | |
55 | <li>GHI:#35: AnnotationMapper dropped silently constructor arguments for converters if they were equal.</li> | |
56 | <li>Fix: Possible concurrency problem with XomDriver.</li> | |
57 | <li>JIRA:XSTR-773, GHPR:#3: Minimize memory footprint by not keeping internal references to instances of | |
58 | immutable types.</li> | |
59 | <li>Drop automatic reference support at deserialization time for immutable types before version 1.4 (primitive | |
60 | types and their boxed counterpart, java.lang.Class, java.lang.String, java.math.BigDecimal, | |
61 | java.math.BigInteger, java.io.File, java.net.URL, and java.awt.font.TextAttribute).</li> | |
62 | <li>Fix: Implicit collection declaration is erroneously inherited or propagated to hidden field of same name.</li> | |
63 | <li>XStreamConverter annotation supports null values as arguments for converter instantiation.</li> | |
64 | <li>GHI:#5: Support null values for JavaBean properties.</li> | |
65 | <li>GHI:#36: Fix NamedMapConverter, does not use SingleValueConverter of value if value is text of entry element.</li> | |
66 | <li>GHI:#13: Own converter for javax.activation.ActivationDataFlavor, because ExternalizableConverter cannot handle | |
67 | a type that violates the Java specification.</li> | |
68 | <li>GHPR:#18: Minimize synchronized block in FieldDictionary.</li> | |
69 | <li>JIRA:XSTR-769: Synthetic fields with references to outer class use compiler dependent names.</li> | |
70 | <li>JIRA:XSTR-771: UUID is an immutable type by default.</li> | |
71 | <li>GHPR:#23: Constructor of AbstractXppDriver swallows causing exception.</li> | |
72 | <li>GHI:#28: Fix functionality of ClassAliaslingMapper.itemTypeAsAttributes(Class).</li> | |
73 | <li>GHI:#37: Historical Java 1.3 support suppresses causing exception of a thrown InvocationTargetException.</li> | |
74 | <li>GHI:#41: Cannot instantiate ToAttributedValueConverter with null value for valueFieldName using | |
75 | XStreamConverter annotation.</li> | |
76 | <li>Fix example code in description of security framework.</li> | |
77 | <li>Clean-up usage of exceptions.</li> | |
78 | </ul> | |
79 | ||
80 | <h2>API changes</h2> | |
81 | ||
82 | <ul> | |
83 | <li>Added c.t.x.XStream.addImmutableType(Class, boolean) and deprecated c.t.x.XStream.addImmutableType(Class).</li> | |
84 | <li>Added c.t.x.mapper.Mapper.isReferenceable(Class).</li> | |
85 | <li>Added c.t.x.mapper.ImmutableTypesMapper.addImmutableType(Class, boolean) and deprecated | |
86 | c.t.x.mapper.ImmutableTypesMapper.addImmutableType(Class).</li> | |
87 | <li>Added c.t.x.io.xml.Dom4JDriver.createReader().</li> | |
88 | <li>Added c.t.x.io.xml.DomDriver.createDocumentBuilderFactory().</li> | |
89 | <li>Added c.t.x.io.xml.JDomDriver.createBuilder().</li> | |
90 | <li>Added c.t.x.io.xml.JDom2Driver.createBuilder().</li> | |
91 | <li>Added c.t.x.io.xml.XomDriver.createBuilder().</li> | |
92 | <li>Added constructor c.t.x.converter.extended.ToAttributedValueConverter.ToAttributedValueConverter(Class, | |
93 | Mapper, ReflectionProvider, ConverterLookup).</li> | |
94 | <li>Added abstract c.t.x.converter.ErrorWritingException as common base for c.t.x.converter.ConversionException | |
95 | and c.t.x.converter.reflection.ObjectAccessException.</li> | |
96 | <li>Deprecated c.t.x.io.xml.XomDriver(Builder), c.t.x.io.xml.XomDriver(Builder, NameCoder) and c.t.x.io.xml.XomDriver.getBuilder().</li> | |
97 | <li>Deprecated c.t.x.mapper.ClassAliaslingMapper.itemTypeAsAttributes(Class) and | |
98 | c.t.x.mapper.ClassAliaslingMapper.aliasIsAttribute(String). Methods never called, left-over from old refactoring.</li> | |
99 | </ul> | |
100 | ||
101 | <h1 id="1.4.8">1.4.8</h1> | |
102 | ||
103 | <p>Released February 18, 2015.</p> | |
104 | ||
105 | <h2>Major changes</h2> | |
106 | ||
107 | <ul> | |
108 | <li>Support for serializable lambda expressions and handling of non-serializable ones.</li> | |
109 | </ul> | |
110 | ||
111 | <h2>Minor changes</h2> | |
112 | ||
113 | <ul> | |
114 | <li>Detect Java 9 runtime.</li> | |
115 | <li>JIRA:XSTR-767: Deserialization of referenced lambda expressions fail.</li> | |
116 | <li>JIRA:XSTR-762: Private method readResolve() called on base classes.</li> | |
117 | <li>JIRA:XSTR-761: Support ignored serialPersistentField at deserialization time.</li> | |
118 | <li>JIRA:XSTR-755: ExternalizableConverter does not respect writeReplace and readResolve.</li> | |
119 | <li>JIRA:XSTR-757: Deserialized TreeSet does not honor remove(Object) return value contract.</li> | |
120 | <li>JIRA:XSTR-759: Support deserialization of <a href="http://www.w3.org/TR/NOTE-datetime">W3C datetime format</a> | |
121 | in DateConverter with Java 7 runtime.</li> | |
122 | <li>Fix: DateConverter ignores provided locale.</li> | |
123 | <li>JIRA:XSTR-768: ISO8601GregorianCalendarConverter may set invalid time zone for Joda-Time.</li> | |
124 | <li>Fix: WeakCache.entrySet().iterator().next.setValue(value) returns the reference instead of the old value.</li> | |
125 | <li>Fix: SqlTimestampConverter throws IllegalArgumentException instead of ConversionException on fromString().</li> | |
126 | <li>Fix: CGLIBEnhancedConverter does not initialize transient members of parent after deserialization.</li> | |
127 | <li>JIRA:XSTR-763: Set scope of org.json:json to test instead declaring the dependency as optional.</li> | |
128 | </ul> | |
129 | ||
130 | <h2>API changes</h2> | |
131 | ||
132 | <ul> | |
133 | <li>Added c.t.x.util.JVM.is19().</li> | |
134 | <li>Added c.t.x.converter.reflection.LambdaConverter and c.t.x.mapper.LambdaMapper.</li> | |
135 | <li>Declare c.t.x.XStream.ignoreUnknownElements(Pattern) as public.</li> | |
136 | <li>c.t.x.converters.reflection.AbstractReflectionConverter.readResolve() is protected now.</li> | |
137 | <li>c.t.x.mapper.AbstractAttributeAliasingMapper.readResolve() is protected now.</li> | |
138 | <li>Deprecated c.t.x.converters.extended.StackTraceElementFactory, it is an internal helper class.</li> | |
139 | <li>Deprecated c.t.x.converters.reflection.SerializationMethodInvoker, it is an internal helper class.</li> | |
140 | <li>Deprecated c.t.x.io.AttributeNameIterator, it is an internal helper class.</li> | |
141 | <li>Deprecated c.t.x.XStream.useXStream11XmlFriendlyMapper(), corresponding | |
142 | c.t.x.mapper.XStream11XmlFriendlyMapper has been deprecated long ago.</li> | |
143 | <li>Deprecated c.t.x.converter.basic.BooleanConverter.shouldConvert(Class,Object), undetected remainder of | |
144 | ancient XStream version.</li> | |
145 | </ul> | |
146 | ||
147 | <h1 id="1.4.7">1.4.7</h1> | |
148 | ||
149 | <p>Released February 8, 2014.</p> | |
150 | ||
151 | <p class="highlight">This maintenance release addresses mainly the security vulnerability CVE-2013-7285, an | |
152 | arbitrary execution of commands when unmarshalling.</p> | |
153 | ||
154 | <h2>Major changes</h2> | |
155 | ||
156 | <ul> | |
157 | <li>Add <a href="security.html#framework">security framework</a> to limit handled types while unmarshalling.</li> | |
158 | <li>java.bean.EventHandler no longer handled automatically because of severe security vulnerability.</li> | |
159 | <li>JIRA:XSTR-751: New SunLimitedUnsafeReflectionProvider that uses undocumented features only to allocate new | |
160 | instances as required on Dalvik.</li> | |
161 | <li>Fix instantiation of AnnotationMapper that requires ConverterLookup and ConverterRegistry to be the same | |
162 | instance.</li> | |
163 | </ul> | |
164 | ||
165 | <h2>Minor changes</h2> | |
166 | ||
167 | <ul> | |
168 | <li>XSTR-749: NPE if ReflectionConverter.canConvert(type) is called with null as argument.</li> | |
169 | <li>XSTR-753: NPE if SerializationConverter.canConvert(type) is called with an interface type as argument that | |
170 | extends Serializable.</li> | |
171 | <li>Add constructor to ReflectionConverter taking an additional type to create an instance that is | |
172 | dedicated to a specific type only.</li> | |
173 | <li>The ConverterLookup used by default cannot be casted to a ConverterRegistry anymore.</li> | |
174 | </ul> | |
175 | ||
176 | <h2>API changes</h2> | |
177 | ||
178 | <ul> | |
179 | <li>Added package c.t.x.security with interface TypePermission, all its implementations and | |
180 | ForbiddenClassException.</li> | |
181 | <li>Added c.t.x.mapper.SecurityMapper handling the new type permissions.</li> | |
182 | <li>Added methods addPermission, denyPermission, allowTypesXXX and denyTypesXXX to c.t.x.XStream to setup | |
183 | security at unmarshalling time.</li> | |
184 | <li>Added c.t.x.converters.reflection.SunLimitedUnsafeReflectionProvider.</li> | |
185 | <li>Deprecated c.t.x.converters.reflection.Sun14ReflectionProvider in favor of new | |
186 | c.t.x.converters.reflection.SunUnsafeReflectionProvider.</li> | |
187 | <li>Added c.t.x.converters.reflection.ReflectionConverter(Mapper,ReflectionProvider,Class).</li> | |
188 | </ul> | |
189 | ||
190 | <h1 id="1.4.6">1.4.6</h1> | |
191 | ||
192 | <p>Released December 12, 2013.</p> | |
193 | ||
194 | <h2>Major changes</h2> | |
195 | ||
196 | <ul> | |
197 | <li>JIRA:XSTR-566 and JIRA:XSTR-200: Better compatibility with GAE and environments with active SecurityManager (i.e. in an | |
198 | Applet). XStream converters try now to ensure already in the canConvert methods that they can handle the requested type in | |
199 | practice and not only theoretically. Additionally the implementations even better take care, that the initialization of a | |
200 | converter will not break the setup of XStream itself. Following modifications have been done for these topics: | |
201 | <ul> | |
202 | <li>ReflectionConverter, SerializationConverter and LookAndFieldConverter will check if they can access the fields by | |
203 | reflection for a requested type.</li> | |
204 | <li>SerializationConverter and ExternalizableConverter will check if they can create an instance of a derived | |
205 | OutputObjectStream first.</li> | |
206 | <li>BeanProvider does no longer use reflection to locate default constructor.</li> | |
207 | <li>AbstractAttributedCharacterIteratorAttributeConverter (and therefore TextAttributeConverter) will check first if it | |
208 | can access the possible constants of the type by reflection.</li> | |
209 | <li>NoClassDefFoundError raised in GAE accessing the fields of restricted types by reflection will be handled.</li> | |
210 | <li>StackTraceElementConverter uses constructor for StackTraceElement instances in Java 5 and GEA.</li> | |
211 | </ul> | |
212 | </li> | |
213 | <li>JIRA:XSTR-739 and JIRA:XSTR-746: OrderRetainingMap fails if HashMap.putAll(Map) of Java Runtime is not | |
214 | implemented calling put for every element within the map.</li> | |
215 | <li>New NamedArrayConverter to define names of inner elements.</li> | |
216 | </ul> | |
217 | ||
218 | <h2>Minor changes</h2> | |
219 | ||
220 | <ul> | |
221 | <li>JIRA:XSTR-747: All constructors of StaxDriver derived classes take erroneously a XmlFriendlyNameCoder | |
222 | instead of a plain NameCoder.</li> | |
223 | </ul> | |
224 | ||
225 | <h2>API changes</h2> | |
226 | ||
227 | <ul> | |
228 | <li>Added c.t.x.converters.extended.NamedArrayConverter for free element names in arrays.</li> | |
229 | <li>Added constructors to c.t.x.io.xml.StandardStaxDriver taking NameCoder instead of XmlFriendlyNameCoder.</li> | |
230 | <li>Deprecated constructors of c.t.x.io.xml.StandardStaxDriver taking a XmlFriendlyNameCoder.</li> | |
231 | <li>Added constructors to c.t.x.io.xml.BEAStaxDriver taking NameCoder instead of XmlFriendlyNameCoder.</li> | |
232 | <li>Deprecated constructors of c.t.x.io.xml.BEAStaxDriver taking a XmlFriendlyNameCoder.</li> | |
233 | <li>Added constructors to c.t.x.io.xml.WstxDriver taking NameCoder instead of XmlFriendlyNameCoder.</li> | |
234 | <li>Deprecated constructors of c.t.x.io.xml.WstxDriver taking a XmlFriendlyNameCoder.</li> | |
235 | <li>Added method canAccess to c.t.x.converter.reflection.AbstractReflectionConverter.</li> | |
236 | <li>Added static method canCreateDerivedObjectOutputStream to c.t.x.core.JVM.</li> | |
237 | <li>Deprecated unused member c.t.x.converter.javabean.BeanProvider.NO_PARAMS.</li> | |
238 | <li>Deprecated unused method c.t.x.converter.javabean.BeanProvider.getDefaultConstrutor(Class).</li> | |
239 | </ul> | |
240 | ||
241 | ||
242 | <h1 id="1.4.5">1.4.5</h1> | |
243 | ||
244 | <p>Released September 18, 2013.</p> | |
245 | ||
246 | <h2>Major changes</h2> | |
247 | ||
248 | <ul> | |
249 | <li>JIRA:XSTR-732: Use a referencing implementation for the ClassLoader to support environments where no new | |
250 | ClassLoader can be instantiated due to security restrictions.</li> | |
251 | <li>JIRA:XSTR-691: Allow unknown XML elements to be ignored using new method XStream.ignoreUnknownElements.</li> | |
252 | <li>JIRA:XSTR-728: XStream creates invalid JSON with JsonHierarchicalStreamDriver for custom converters since | |
253 | XStream 1.4.</li> | |
254 | <li>JIRA:XSTR-300: New EnumToStringConverter to support custom string representations of Enum values.</li> | |
255 | <li>JIRA:XSTR-292 and JIRA:XSTR-405: New NamedMapConverter and NamedCollectionConverter to define names of | |
256 | inner elements.</li> | |
257 | <li>JIRA:XSTR-726: New annotation XStreamAliasType to support declarative definition of XStream.aliasType().</li> | |
258 | <li>JIRA:XSTR-735: Support for JDOM2 with JDom2Driver, JDom2Reader and JDom2Writer.</li> | |
259 | <li>Optimized XML structure for java.awt.Font.</li> | |
260 | <li>Fix: ToAttributedValueConverter silently appends fields without attribute support to the value producing mixed-mode XML.</li> | |
261 | <li>JIRA:XSTR-566 and JIRA:XSTR-249: Better compatibility with Google AppEngine and J2ME, setup no longer fails for unavailable converters.</li> | |
262 | </ul> | |
263 | ||
264 | <h2>Minor changes</h2> | |
265 | ||
266 | <ul> | |
267 | <li>Fix missing manifest information.</li> | |
268 | <li>JIRA:XSTR-729: Add OSGi information to manifests.</li> | |
269 | <li>JIRA:XSTR-723: XStream will now detect a working enhanced mode dynamically instead using lists of known | |
270 | vendors. This allows enhanced support for JamVM if it is bundled with OpenJDK. It will currently fail on a | |
271 | runtime based on GNU Classpath (at least up to version 0.98).</li> | |
272 | <li>JIRA:XSTR-541: JavaScript compatibility problem with 64-bit integers in JSON.</li> | |
273 | <li>JIRA:XSTR-719: Support replacement of default converter in any case.</li> | |
274 | <li>JIRA:XSTR-725: processAnnotation performance improvement in concurrent situation.</li> | |
275 | <li>JIRA:XSTR-721: EnumConverter is more lenient while parsing constants.</li> | |
276 | <li>New constructors for CollectionConverter and MapConverter to allow registration for an individual type.</li> | |
277 | <li>JIRA:XSTR-724: Cache class name lookup failures.</li> | |
278 | <li>Current IBM JDK for Java 1.4.2 no longer has a reverse field ordering.</li> | |
279 | <li>LongConverter supports now positive hex and octal numbers over Long.MAX_VALUE within 64 bit.</li> | |
280 | <li>Fix: Sun14RefectionProvider ignores a provided FieldDictionary.</li> | |
281 | <li>JIRA:XSTR-457: Do not write 'defined-in' attribute if not needed.</li> | |
282 | <li>JettisonMappedXmlDriver provides better support to overwrite its create methods.</li> | |
283 | <li>JIRA:XSTR-685: StAX based drivers (StaxDriver and JettisonMappedXmlDriver) are not closing internal input | |
284 | stream reading from file or URL.</li> | |
285 | <li>JIRA:XSTR-736: XStream.unmarshal may throw NPE if version info of manifest is missing.</li> | |
286 | <li>JIRA:XSTR-733: Implicit elements that match multiple defined implicit collections will be assigned to the | |
287 | map with the nearest matching element type.</li> | |
288 | <li>JIRA:XSTR-740: ISO8601GregorianCalendarConverter creates Calendar instance with wrong Locale in Java 7 if | |
289 | the Locale for the LocaleCategory.FORMAT is different to the global default Locale.</li> | |
290 | <li>JIRA:XSTR-578: Implement support for aliasing in JavaClasConverter, JavaFieldConverter and | |
291 | JavaMethodConverter. While it is not possible to enable this in general, new constructors have been added to | |
292 | these converters and an example in the acceptance tests (AliasTest).</li> | |
293 | <li>JIRA:XSTR-742: Register CompositeClassLoader in Java 7 as parallel capable.</li> | |
294 | <li>JIRA:XSTR-743: Support proxy collections of Hibernate Envers.</li> | |
295 | <li>Fix NPE in AttributeMapper.shouldLookForSingleValueConverter if parameters fieldName and definedIn are null.</li> | |
296 | <li>Implicit type argument can be omitted when registering converters with @XStreamConverter annotation.</li> | |
297 | </ul> | |
298 | ||
299 | <h2>API changes</h2> | |
300 | ||
301 | <ul> | |
302 | <li>Added c.t.x.converters.extended.NamedCollectionConverter for free element names in collections.</li> | |
303 | <li>Added c.t.x.converters.extended.NamedMapConverter for free element names in maps.</li> | |
304 | <li>Added c.t.x.io.xml.StandardStaxDriver to use the StAX implementation delivered with the Java 6 runtime.</li> | |
305 | <li>Deprecated c.t.x.io.xml.SjsxpStaxDriver to select the internal StAX implementation of Oracle.</li> | |
306 | <li>Added static methods getStaxInputFactory and getStaxOutputFactory to c.t.x.core.JVM as returning the | |
307 | implementations of javax.xml.stream.XMLInputFactory (resp. javax.xml.stream.XMLOutputFactory) delivered with | |
308 | the Java Runtime since Java 6.</li> | |
309 | <li>Added c.t.x.core.ClassLoaderReference.</li> | |
310 | <li>Added constructors taking an additional Class argument for c.t.x.converters.collections.CollectionConverter | |
311 | and c.t.x.converters.collections.MapConverter.</li> | |
312 | <li>Added constructors taking a ClassLoaderReference instead of a ClassLoader and deprecated the ones taking the ClassLoader: | |
313 | <ul> | |
314 | <li>c.t.x.XStream</li> | |
315 | <li>c.t.x.converters.extended.DynamicProxyConverter</li> | |
316 | <li>c.t.x.converters.extended.JavaClassConverter</li> | |
317 | <li>c.t.x.converters.extended.JavaFieldConverter</li> | |
318 | <li>c.t.x.converters.extended.JavaMethodConverter</li> | |
319 | <li>c.t.x.converters.reflection.CGLIBEnhancedConverter</li> | |
320 | <li>c.t.x.converters.reflection.ExternalizableConverter</li> | |
321 | <li>c.t.x.converters.reflection.SerializableConverter</li> | |
322 | <li>c.t.x.mapper.AnnotationMapper</li> | |
323 | <li>c.t.x.mapper.DefaultMapper</li> | |
324 | </ul> | |
325 | </li> | |
326 | <li>Added static methods newReflectionProvider, isAWTAvailable, isSQLAvailable and isSwingAvailable to | |
327 | c.t.x.core.JVM as replacement for the deprecated non-static methods.</li> | |
328 | <li>Deprecated c.t.x.core.JVM() and all non-static methods.</li> | |
329 | <li>Added method useImplicitType to c.t.x.annotations.XStreamConverter.</li> | |
330 | <li>JIRA:XSTR-722: Added | |
331 | c.t.x.converters.reflection.ReflectionProvider.getFieldOrNull(Class, String).</li> | |
332 | <li>Deprecated | |
333 | c.t.x.converters.reflection.ReflectionProvider.fieldDefinedInClass(Class, String) in | |
334 | favor of new c.t.x.converters.reflection.ReflectionProvider.getFieldOrNull(Class, | |
335 | String).</li> | |
336 | <li>Deprecated constructor c.t.x.converters.extended.RegexPatternConverter(Converter) | |
337 | in favor of c.t.x.converters.extended.RegexPatternConverter().</li> | |
338 | <li>Deprecated default constructor of c.t.x.converters.extended.FontConverter in favor of | |
339 | c.t.x.converters.extended.FontConverter(Mapper).</li> | |
340 | <li>Deprecated constructor c.t.x.converters.extended.ThrowableConverter(Converter) | |
341 | in favor of c.t.x.converters.extended.ThrowableConverter(ConverterLookup).</li> | |
342 | <li>Deprecated class c.t.x.converters.reflection.SelfStreamingInstanceChecker and moved | |
343 | original implementation into c.t.x.core.util, since it is internal.</li> | |
344 | <li>Deprecated interface c.t.x.mapper.AnnotationConfiguration.</li> | |
345 | </ul> | |
346 | ||
347 | <h1 id="1.4.4">1.4.4</h1> | |
348 | ||
349 | <p>Released January 19, 2013.</p> | |
350 | ||
351 | <h2>Minor changes</h2> | |
352 | ||
353 | <ul> | |
354 | <li>JIRA:XSTR-709: Locks up on Mac with Apple JVM due to unwanted initialization of AWT.</li> | |
355 | <li>JIRA:XSTR-711: DateConverter cannot handle dates in different era.</li> | |
356 | <li>JIRA:XSTR-741: ToAttributedValueConverter fails to write enums as attributes.</li> | |
357 | <li>JIRA:XSTR-712: HibernateMapper throws NPE if a collection contains null.</li> | |
358 | <li>DateConverter supports now localized formats.</li> | |
359 | <li>JIRA:XSTR-710: JsonWriter does not write BigInteger and BigDecimal as number values.</li> | |
360 | <li>JIRA:XSTR-708: SqlTimestampConverter does not ignore timezone.</li> | |
361 | <li>JIRA:XSTR-707: Creation of XmllPullParser with the XmlPullParserFactory may fail in OSGi environment.</li> | |
362 | <li>JIRA:XSTR-705: Unnecessary synchronization accessing the field cache decreases performance.</li> | |
363 | <li>JIRA:XSTR-714: Fields not found when XStream12FieldKeySorter used.</li> | |
364 | </ul> | |
365 | ||
366 | <h2>API changes</h2> | |
367 | ||
368 | <ul> | |
369 | <li>Deprecated method c.t.x.core.util.JVM.is14(), c.t.x.core.util.JVM.is15() and c.t.x.core.util.JVM.is16().</li> | |
370 | </ul> | |
371 | ||
372 | <h1 id="1.4.3">1.4.3</h1> | |
373 | ||
374 | <p>Released July 17, 2012.</p> | |
375 | ||
376 | <h2>Major changes</h2> | |
377 | ||
378 | <ul> | |
379 | <li>Support java.util.concurrent.ConcurrentHashMap with the MapConverter. This will also avoid a bug in JRockit | |
380 | JDK reported in JIRA:XSTR-608.</li> | |
381 | <li>JIRA:XSTR-699: Support for Hibernate 4 with XStream's Hibernate module as default for Java 6 or higher.</li> | |
382 | </ul> | |
383 | ||
384 | <h2>Minor changes</h2> | |
385 | ||
386 | <ul> | |
387 | <li>JVM.loadClass will now also initialize the loaded class and ignore any occurring LinkageError.</li> | |
388 | <li>JIRA:XSTR-596: SubjectConverter will be no longer registered if initialization of javax.security.auth.Subject fails.</li> | |
389 | <li>JIRA:XSTR-683: Inheritance of implicit collections, arrays or maps is dependent on declaration sequence.</li> | |
390 | <li>Inherited implicit collections, arrays or maps can be overwritten with own definition in subtype.</li> | |
391 | <li>JIRA:XSTR-688: Cannot omit XML elements from derived fields.</li> | |
392 | <li>JIRA:XSTR-696: Ill-formed JSON generated, because JSON writer is fed with type of declaring field instead of | |
393 | the real object's type.</li> | |
394 | <li>JIRA:XSTR-685: Deserialization from file or URL keeps stream open.</li> | |
395 | <li>JIRA:XSTR-684: XML 1.0 character validation fails for characters from 0x10 to 0x1f.</li> | |
396 | <li>JavaBeanConverter supports now instantiation for a specific type and can therefore be used in | |
397 | @XStreamConverter annotation.</li> | |
398 | <li>SerializableConverter is broken if the serialized type is the default implementation.</li> | |
399 | <li>Method marshalUnserializableParent of SerializableConverter is protected now to skip the default mechanism | |
400 | in a derived converter that uses the default constructor to create the original type (as an alternative for | |
401 | JIRA:XSTR-695).</li> | |
402 | <li>FieldDictionary may call sort of FieldKeySorter implementation with wrong type as key.</li> | |
403 | <li>Sometimes DependencyInjectionFactory tries to instantiate objects with mismatching constructor arguments.</li> | |
404 | <li>HSQLDB has to be a test dependency only for XStream's Hibernate module.</li> | |
405 | </ul> | |
406 | ||
407 | <h1 id="1.4.2">1.4.2</h1> | |
408 | ||
409 | <p>Released November 3, 2011.</p> | |
410 | ||
411 | <h2>Major changes</h2> | |
412 | ||
413 | <ul> | |
414 | <li>XStream libraries can be used now directly in Android, therefore support of Java 1.4.2 has been stopped with the delivery. | |
415 | Anyone who needs a version for Java 1.4.2 can build it easily from source, this build is still supported and part of CI.</li> | |
416 | <li>JIRA:XSTR-675: New extended HierarchicalStreamReader interface with peekNextChild method. All XStream | |
417 | readers implement the new interface (by Nikita Levyankov).</li> | |
418 | <li>JIRA:XSTR-673: Collections.EMPTY_LIST, Collections.EMPTY_SET and Collections.EMPTY_MAP supported with own | |
419 | alias and defined as immutable.</li> | |
420 | <li>JIRA:XSTR-631: Collections.singletonList(), Collections.singletonSet() and Collections.singletonMap() | |
421 | supported with own alias and own converters.</li> | |
422 | <li>JIRA:XSTR-406 + JIRA:XSTR-663: Support additional parameters for XStreamConverter annotation (e.g. to declare a | |
423 | ToAttributedValueConverter).</li> | |
424 | </ul> | |
425 | ||
426 | <h2>Minor changes</h2> | |
427 | ||
428 | <ul> | |
429 | <li>WstxDriver did not trigger Woodstox, but BEA StAX implementation.</li> | |
430 | <li>JIRA:XSTR-260: PrettyPrintWriter does not handle tab and new line characters in attributes.</li> | |
431 | <li>JIRA:XSTR-667: Cannot serialize empty list with JsonHierarchicalStreamDriver.</li> | |
432 | <li>JIRA:XSTR-661: TreeMarshaller.CircularReference is not a ConversionException.</li> | |
433 | <li>JIRA:XSTR-562: StAX: Namespace attribute is not written in non-repairing mode for second sibling.</li> | |
434 | <li>JIRA:XSTR-664: ClassCastException in HibernatePersistentSortedSetConverter and | |
435 | HibernatePersistentSortedMapConverter.</li> | |
436 | <li>JIRA:XSTR-674: Recreate binary compatibility with 1.3.x series for method | |
437 | CustomObjectInputStream.getInstance(...).</li> | |
438 | <li>JIRA:XSTR-671: CannotResolveClassException should accept cause.</li> | |
439 | <li>JIRA:XSTR-672: Collections.EMPTY_LIST, Collections.EMPTY_SET and Collections.EMPTY_MAP used for in implicit | |
440 | collection should not throw ReferencedImplicitElementException.</li> | |
441 | <li>JIRA:XSTR-676: Introduce MissingFieldException thrown at deserialization time indicating a missing field or | |
442 | property (by Nikita Levyankov).</li> | |
443 | <li>Add length limit for cached strings in StringConverter, 38 characters by default.</li> | |
444 | <li>The JsonHierarchicalStreamDriver and the JsonWriter did not support the inherited NameCoder instance.</li> | |
445 | <li>Add BinaryStreamDriver.</li> | |
446 | <li>NPE in XppDomComparator.</li> | |
447 | <li>Dom4JXmlWriter fails to flush the underlying writer.</li> | |
448 | <li>Known control characters are not encoded with JsonWriter as proposed at json.org.</li> | |
449 | <li>Detect duplicate property processing in JavaBeanConverter and throw DuplicatePropertyException instead of | |
450 | clobbering silently.</li> | |
451 | <li>Allow access to Mapper and JavaBeanProvider in derived instances of JavaBeanConverter.</li> | |
452 | <li>DependencyInjectionFactory failed to create instance when a matching constructor was found, but a default | |
453 | constructor was also present.</li> | |
454 | </ul> | |
455 | ||
456 | <h2>API changes</h2> | |
457 | ||
458 | <ul> | |
459 | <li>Added interface c.t.x.io.ExtendedHierarchicalStreamReader extending c.t.x.io.HierarchicalStreamReader. All | |
460 | implementations of c.t.x.io.HierarchicalStreamReader will implement also the extended interface.</li> | |
461 | <li>Added c.t.x.converters.reflection.MissingFieldException derived from | |
462 | c.t.x.converters.reflection.ObjectAccessException and used instead when the unmarshalling process should write | |
463 | a field or property that is missing and does not exist.</li> | |
464 | <li>Added methods c.t.x.io.path.PathTracker.peekElement(), c.t.x.io.path.PathTracker.peekElement(int), and | |
465 | c.t.x.io.path.PathTracker.depth().</li> | |
466 | <li>Deprecated method c.t.x.core.ReferencingMarshallingContext.currentPath(). Wrong approach.</li> | |
467 | </ul> | |
468 | ||
469 | <h1 id="1.4.1">1.4.1</h1> | |
470 | ||
471 | <p>Released August 11, 2011.</p> | |
472 | ||
473 | <h2>Major changes</h2> | |
474 | ||
475 | <ul> | |
476 | <li>JIRA:XSTR-659: Use again Xpp3 as default parser, now with additional XmlPullParser API as regular | |
477 | dependency for the XPP factory. Only standard kXML2 package contains the XPP factory, but not the minimal kXML2 | |
478 | version.</li> | |
479 | </ul> | |
480 | ||
481 | <h2>Minor changes</h2> | |
482 | ||
483 | <ul> | |
484 | <li>Add utility class c.t.x.io.xml.xppdom.XppFactory and a path tracking comparator for XppDom.</li> | |
485 | </ul> | |
486 | ||
487 | <h1 id="1.4">1.4</h1> | |
488 | ||
489 | <p>Released August 6, 2011.</p> | |
490 | ||
491 | <h2>Major changes</h2> | |
492 | ||
493 | <ul> | |
494 | <li>Java 7 is detected and supported.</li> | |
495 | <li>JIRA:XSTR-542: The XppDriver uses now the official XmlPullParser API to locate an available parser using | |
496 | the XmlPullParserFactory. This allows the usage of XPP technology with XStream in Android.</li> | |
497 | <li>Additional explicit XPP drivers for the Xpp3 and kXML2 implementations.</li> | |
498 | <li>Additional explicit XPP DOM drivers for the Xpp3 and kXML2 implementations.</li> | |
499 | <li>kXML2 is now the preferred parser implementation, Xpp3 is optional.</li> | |
500 | <li>Additional explicit StAX drivers for Woodstox, BEA StAX and SJSXP of the JDK 6 implementations.</li> | |
501 | <li>JDK 1.3 is no longer officially supported.</li> | |
502 | <li>JIRA:XSTR-377+JIRA:XSTR-226: New artifact xstream-hibernate with converters and mapper to process Hibernate | |
503 | object graphs (by Costin Leau, Konstantin Pribluda and in special Jaime Metcher).</li> | |
504 | <li>New NameCoder interface and implementations to support a generic name translation between names from the | |
505 | object graph and a target format. The new XmlFriendlyNameCoder replaces the XmlFriendlyReplacer used for XML | |
506 | only.</li> | |
507 | <li>JIRA:XSTR-553: Support annotations in Android.</li> | |
508 | <li>JIRA:XSTR-556: DateConverter uses format with 3-letter time zones that are ambiguous. Therefore it will now | |
509 | always use UTC to write dates. Unmarshalled dates are not affected as long as they contain a time zone.</li> | |
510 | <li>The type java.lang.reflect.Field is now handled by an own converter, that can still read the old format.</li> | |
511 | <li>JIRA:XSTR-490: Provide path in Converter for contexts that track the path.</li> | |
512 | <li>JIRA:XSTR-592+JIRA:XSTR-579: OmitField respected at deserialization time even for existing fields.</li> | |
513 | <li>JIRA:XSTR-593: Direct support for java.net.URI instances (by Carlos Roman).</li> | |
514 | <li>JIRA:XSTR-615+JIRA:XSTR-580: Dynamic proxies cannot be referenced recursively.</li> | |
515 | <li>JIRA:XSTR-547: Wrong class loader used for Serializable types deserialized with an ObjectInputStream.</li> | |
516 | <li>JIRA:XSTR-341: Support of implicit arrays.</li> | |
517 | <li>JIRA:XSTR-306+JIRA:XSTR-406: Support of implicit maps.</li> | |
518 | <li>JIRA:XSTR-344: New ToAttributedValueConverter to allow conversion of an element with string body and | |
519 | attributes.</li> | |
520 | <li>JIRA:XSTR-573: SortedSet added with TreeSet as the default implementation.</li> | |
521 | <li>JIRA:XSTR-576: TreeMap and TreeSet no longer add an element without comparator (by Jason Greanya), | |
522 | solves also invalid format with JSON for such objects (JIRA:XSTR-640).</li> | |
523 | </ul> | |
524 | ||
525 | <h2>Minor changes</h2> | |
526 | ||
527 | <ul> | |
528 | <li>JIRA:XSTR-612: Improve extensibility of c.t.x.javabean.* package by reintroducing a PropertyDictionary with | |
529 | the additional interface PropertySorter.</li> | |
530 | <li>JIRA:XSTR-591: EnumSingleValueConverter did use toString() instead of name() to create the String | |
531 | representation of an enum value.</li> | |
532 | <li>JIRA:XSTR-618: Add Oracle as vendor used for recent JRockit versions and former Sun JDK.</li> | |
533 | <li>JIRA:XSTR-656: DomReader and Dom4JReader do not escape attribute names retrieving their values.</li> | |
534 | <li>JIRA:XSTR-604: StringConverter's cache may cause an OutOfMemoryException.</li> | |
535 | <li>JIRA:XSTR-577: Skip UTF-8 BOM in XmlHeaderAwareReader.</li> | |
536 | <li>The XppReader no longer uses a BufferedReader.</li> | |
537 | <li>JIRA:XSTR-543: Better deserialization support of the defined-in system attribute in combination with field | |
538 | aliases.</li> | |
539 | <li>JIRA:XSTR-551: Deprecated XStream.InitializationException still thrown instead of InitializationException.</li> | |
540 | <li>JIRA:XSTR-655: JsonWriter generates invalid JSON for Externalizable types.</li> | |
541 | <li>JIRA:XSTR-540: Support Jettison-based configuration of JettisonMappedXmlDriver (by Doug Daniels).</li> | |
542 | <li>JIRA:XSTR-633: JettisonMappedXmlDriver escaped property names according escape rules for XML tag names.</li> | |
543 | <li>JIRA:XSTR-625: Optionally ignore XStream's hints for Jettison to generate JSON arrays (by Dejan Bosanac).</li> | |
544 | <li>JIRA:XSTR-605: Upgrade to Jettison 1.2 (for Java 5 or higher).</li> | |
545 | <li>New JsonWriter.EXPLICIT_MODE generating JSON that enforces property sequence.</li> | |
546 | <li>JIRA:XSTR-552: Improve performance of ReflectionProvider (by Keith Kowalczykowski).</li> | |
547 | <li>JIRA:XSTR-559: Improve performance of Sun14ReflectionProvider (by Keith Kowalczykowski).</li> | |
548 | <li>JIRA:XSTR-564: Improve performance of AnnotationMapper (by Keith Kowalczykowski).</li> | |
549 | <li>JIRA:XSTR-563: Use ReferenceQueue for cleaning-up WeakReferences in ObjectIdDictionary (by Keith | |
550 | Kowalczykowski).</li> | |
551 | <li>JIRA:XSTR-646: Cache of Sun14ReflectionProvider consumes more PermGen space than necessary.</li> | |
552 | <li>JIRA:XSTR-636: Ineffective cache in FieldDictionary using WeakHashMap with WeakReference values.</li> | |
553 | <li>Ineffective cache for SerializationMethodInvoker (related to JIRA:XSTR-636).</li> | |
554 | <li>Introduction of Caching interface implemented by all types in XStream that create local caches that may | |
555 | have to be flushed manually.</li> | |
556 | <li>Avoid excessive creation of AbstractPullReader.Event objects by using a pool.</li> | |
557 | <li>Possibility to generate XPath expressions that select always a single node instead of a node list.</li> | |
558 | <li>Cannot reference replaced object using ID references.</li> | |
559 | <li>Implicit collection functionality will no longer use custom collection converters that may write tags that are not | |
560 | recognized at deserialization time again.</li> | |
561 | <li>JIRA:XSTR-654: Unmarshal fails when an implicit collection is defined and an element is named equal to the field.</li> | |
562 | <li>JIRA:XSTR-574: AbstractReferenceUnmarshaller cannot handle null values for references.</li> | |
563 | <li>Improve exception output in case of a missing field.</li> | |
564 | <li>JIRA:XSTR-555: StAX driver tests do not honor repairing mode.</li> | |
565 | <li>JIRA:XSTR-570: The @XStreamConverter provides now also the current type as possible constructor argument.</li> | |
566 | <li>JIRA:XSTR-629: Deserialization of Externalizable with non-accessible default constructor fails.</li> | |
567 | <li>JIRA:XSTR-571: Cannot serialize synchronized RandomAccessList types.</li> | |
568 | <li>JIRA:XSTR-583: BinaryDriver fails to handle Strings with more than 64K bytes.</li> | |
569 | <li>JIRA:XSTR-639: Cannot omit field at deserialization if the field has a class attribute.</li> | |
570 | <li>JIRA:XSTR-599: EncodedByteArrayConverter should implement SingleValueConverter.</li> | |
571 | <li>JIRA:XSTR-584: Race condition in XmlFriendlyReplacer.</li> | |
572 | <li>JIRA:XSTR-623: XmlFriendlyReplacer may write illegal name characters (by Michael Schnell).</li> | |
573 | <li>The ConversionException hides information if its ErrorWriter contains the added key already.</li> | |
574 | <li>JIRA:XSTR-598: Attribute "defined-in" was wrongly evaluated for other attributes.</li> | |
575 | <li>JIRA:XSTR-650: Possible NullPointerException at initialization on platforms like Android that do not | |
576 | support all types of the JDK.</li> | |
577 | <li>JIRA:XSTR-652: Initialization of XStream fails if DurationConverter constructor throws a | |
578 | javax.xml.datatype.DatatypeConfigurationException. Converter will no longer handle Duration types if no | |
579 | instance of the internal DatatypeFactory can be created.</li> | |
580 | <li>Constructor DocumentWriter(Element) forgets the provided element.</li> | |
581 | <li>JIRA:XSTR-597: Optimize AbstractReflectionConverter.</li> | |
582 | <li>Introduce Caching interface to flush the internal cache of specific components.</li> | |
583 | <li>Support JIRA:XSTR-407 also for IBM JRE 1.6 and greater.</li> | |
584 | <li>java.nio.charset.Charset's converter was added as immutable type instead of the type itself.</li> | |
585 | <li>java.util.Currency added as immutable type.</li> | |
586 | <li>Fix selection of same parameter types in DependencyInjectionFactory.</li> | |
587 | <li>Deprecation of c.t.x.javabean.PropertyDictionary has been countermanded.</li> | |
588 | </ul> | |
589 | ||
590 | <h2>API changes</h2> | |
591 | ||
592 | <ul> | |
593 | <li>Any deprecated stuff of the 1.2.x releases has been removed.</li> | |
594 | <li>Deprecated constructors of c.t.x.converters.reflection.SerializableConverter, c.t.x.converters.reflection.ExternalizableConverter | |
595 | and c.t.x.converters.reflection.CGLIBEnhancedConverter; new versions take an additional argument for class loader (as a result | |
596 | for JIRA:XSTR-547).</li> | |
597 | <li>Deprecated constructors of c.t.x.io.xml.XppReader, new versions take an additional argument for the XmlPullParser.</li> | |
598 | <li>Deprecated c.t.x.io.xml.XppReader.createParser(), the XPP parser is now created by the driver.</li> | |
599 | <li>Package c.t.x.io.xml.xppdom is now part of the official API.</li> | |
600 | <li>c.t.x.io.xml.xppdom.Xpp3Dom and c.t.x.io.xmlxpp.dom.Xpp3DomBuilder have been deprecated. Functionality is | |
601 | merged in c.t.x.io.xml.xppdom.XppDom.</li> | |
602 | <li>Deprecated c.t.x.mapper.XStream11XmlFriendlyMapper and c.t.x.mapper.AbstractXmlFriendlyMapper.</li> | |
603 | <li>Added interface c.t.x.core.ReferencingMarshallingContext which is implemented by all referencing marshallers.</li> | |
604 | <li>Added interface c.t.x.io.naming.NameCoder and implementations.</li> | |
605 | <li>Deprecated c.t.x.io.xml.XmlFriendlyReplacer, c.t.x.io.xml.XmlFriendlyReader and c.t.x.io.xml.XmlFriendlyWriter.</li> | |
606 | <li>Deprecated c.t.x.io.xml.AbstractXmlDriver, c.t.x.io.xml.AbstractXmlReader and c.t.x.io.xml.AbstractXmlWriter, added | |
607 | c.t.x.io.AbstractDriver, c.t.x.io.AbstractReader and c.t.x.io.AbstractWriter instead.</li> | |
608 | <li>Deprecated all constructors of Driver, Reader and Writer implementations that take a XmlFriendlyReplacer as argument, | |
609 | added constructors taking a NameCoder instead.</li> | |
610 | <li>Added interface com.thoughtworks.xstream.converters.ErrorReporter to allow other types to report | |
611 | also errors (apart from a HierarchicalStreamReader). Any converter and the parent object of the currently deserialized | |
612 | element may provide additional error information now.</li> | |
613 | </ul> | |
614 | ||
615 | <h1 id="1.3.1">1.3.1</h1> | |
616 | ||
617 | <p>Released December 6, 2008.</p> | |
618 | ||
619 | <p class="highlight">CGLIB support must be explicitly activated now. The decision has been made due to possible problems using an own | |
620 | classloader and because of ongoing complaints about occurring exceptions in the CGLIBEnhancedConverter at XStream initialization although | |
621 | they are caused by incompatible ASM versions on the user's classpath (JIRA:XSTR-469, JIRA:XSTR-513 and JIRA:XSTR-518).</p> | |
622 | ||
623 | <p class="highlight">XStream uses some attributes on its own. Until now it was possible to use XStream.aliasAttribute to define a different | |
624 | name. This does still work but is deprecated for system attributes. Use the new call XStream.aliasSystemAttribute for such an alias.</p> | |
625 | ||
626 | <h2>Major changes</h2> | |
627 | ||
628 | <ul> | |
629 | <li>JIRA:XSTR-515: CGLIB support is no longer activated automatically and has to be | |
630 | <a href="faq.html#Serialization_CGLIB">explicitly turned on</a>.</li> | |
631 | <li>JIRA:XSTR-448: Separated system attributes and user defined attributes for aliases.</li> | |
632 | <li>JIRA:XSTR-55: Ability to alias a package name.</li> | |
633 | <li>JIRA:XSTR-434: New JsonWriter instead of JsonHierarchicalStreamWriter with mode to strip root node of generated JSON (by Paul Hammant).</li> | |
634 | <li>Support for Diablo JDK on FreeBSD (by Reto Bachmann-Gmür).</li> | |
635 | <li>JIRA:XSTR-495: New PersistenceStrategy instead of StreamStrategy (based on the code and comments by Alexander Radzin).</li> | |
636 | </ul> | |
637 | ||
638 | <h2>Minor changes</h2> | |
639 | ||
640 | <ul> | |
641 | <li>Support special Jettison functionality for JSON to detect collections or arrays with one element introduced with Jettison 1.0.</li> | |
642 | <li>JIRA:XSTR-493: Using attributes for fields with XML-unfriendly names results in NPE at deserialization.</li> | |
643 | <li>JIRA:XSTR-497: Unsafe operation with WeakHashMap can raise a NPE in Sun14ReflectionProvider.</li> | |
644 | <li>JIRA:XSTR-423: Support of CGLIB enhanced proxies with multiple callbacks if the proxy uses a factory (CGLIB default).</li> | |
645 | <li>JIRA:XSTR-536: XStream silently ignores unknown elements.</li> | |
646 | <li>JIRA:XSTR-503: Omitted properties in JavaBeans are requested at serialization (by Kevin Conaway).</li> | |
647 | <li>Fix possible memory leak in ObjectIdMap for JVMs that provide real distinct identity hash codes (happened on amd64 system).</li> | |
648 | <li>JIRA:XSTR-480: Aliasing of array types.</li> | |
649 | <li>JIRA:XSTR-515: The SubjectConverter and DurationConverter are only registered if the converted class is part of the JDK, | |
650 | otherwise they must be registered now explicitly.</li> | |
651 | <li>JIRA:XSTR-504: XmlHeaderAwareReader fails with improper sized PushbackInputStream.</li> | |
652 | <li>JIRA:XSTR-489: @XStreamConverter supports now also SingleValueConverter implementations.</li> | |
653 | <li>JIRA:XSTR-481: @XStreamConverter and @XStreamAsAttribute can be used together (as a result of JIRA:XSTR-489).</li> | |
654 | <li>JIRA:XSTR-519: New annotation @XStreamInclude to force annotation detection of included types (by Seven Sparling).</li> | |
655 | <li>JIRA:XSTR-469: Support custom converters for enum types.</li> | |
656 | <li>JIRA:XSTR-502: ClassNotFoundException even if writeReplace returns proper object.</li> | |
657 | <li>JIRA:XSTR-529: NullPointerException for null elements in implicit lists.</li> | |
658 | <li>JIRA:XSTR-517: Miscellaneous performance improvements (by Tatu Saloranta).</li> | |
659 | <li>JIRA:XSTR-525: JsonHierarchicalStreamDriver writes invalid JSON in case of system attribute.</li> | |
660 | <li>JIRA:XSTR-535: Mode to allow plain values as result for JSON without root node.</li> | |
661 | <li>JIRA:XSTR-531: Possibility to omit system attributes.</li> | |
662 | <li>JIRA:XSTR-508: Fix marshalling error for nested serializable objects with own writeReplace/readResolve methods.</li> | |
663 | <li>JIRA:XSTR-507: Advanced ReferenceByIdMarshaller uses id of the current object if available.</li> | |
664 | <li>JIRA:XSTR-485: Check reference for valid object when deserializing.</li> | |
665 | <li>Fix classloader problem, Xpp3 parser cannot be loaded within a web application.</li> | |
666 | <li>Dependencies have been updated to latest versions of JDOM, Jettison, Joda Time, and Woodstox. Note for Maven | |
667 | builds that the <em>groupId</em> of JDOM has changed.</li> | |
668 | <li>Fix possible IndexOutOfBoundsException creating returning the message for a ConversionException.</li> | |
669 | <li>JIRA:XSTR-495: StreamStrategy cannot handle key with value <em>null</em>.</li> | |
670 | </ul> | |
671 | ||
672 | <h2>API changes</h2> | |
673 | ||
674 | <ul> | |
675 | <li>Deprecated c.t.x.io.json.JsonHierarchicalStreamWriter in favour of c.t.x.io.json.JsonWriter.</li> | |
676 | <li>c.t.x.mapper.EnumMapper no longer derives from the c.t.x.mapper.AttributeMapper as it has been before version 1.3. Therefore the new | |
677 | constructor has been deprecated in favour of the old one.</li> | |
678 | <li>c.t.x.mapper.Mapper.getConverterFromAttribute(Class, String) has been deprecated in favour of | |
679 | c.t.x.mapper.Mapper.getConverterFromAttribute(Class, String, Class) taking the type as third argument that should be handled by the | |
680 | converter.</li> | |
681 | <li>c.t.x.core.ReferenceByIdMarshaller.IdGenerator.next() has now the current object as argument.</li> | |
682 | <li>New c.t.x.persistence.PersistenceStrategy and c.t.x.persistence.FilePersistenceStrategy.</li> | |
683 | <li>Deprecated c.t.x.persistence.StreamStrategy and c.t.x.persistence.FileStreamStrategy.</li> | |
684 | </ul> | |
685 | ||
686 | <h1 id="1.3">1.3</h1> | |
687 | ||
688 | <p>Released February 27, 2008.</p> | |
689 | ||
690 | <h2>Major changes</h2> | |
691 | ||
692 | <ul> | |
693 | <li>ReflectionConverter writes now the fields of the parent classes first.</li> | |
694 | <li>Support for Converter definition at field level.</li> | |
695 | <li>Refactoring of Annotation support, invent auto-detection mode.</li> | |
696 | <li>Annotated converters are no longer detected automatically, all annotations are now handled in the same way.</li> | |
697 | <li>JIRA:XSTR-334: XStream will deserialize directly from a file or URL. Some parser take advantage of these objects to | |
698 | define a SystemId used to resolve further references in XML, schema or DTD. Appropriate createReader methods have been | |
699 | added to c.t.x.io.HierarchicalStreamDriver.</li> | |
700 | <li>JIRA:XSTR-261: All c.t.x.io.HierarchicalStreamDriver implementations respect now the encoding of an XML header | |
701 | if read from an InputStream.</li> | |
702 | <li>DomDriver does no longer use explicitly UTF-8 by default, DomReader will therefore respect the encoding defined | |
703 | in the XML header or use native encoding</li> | |
704 | <li>JIRA:XSTR-415: JavaBeanConverter uses now BeanIntrospection (by Hinse ter Schuur).</li> | |
705 | <li>JIRA:XSTR-424: DateConverter uses now by default SimpleDateFormat instances in non-lenient mode.</li> | |
706 | <li>JIRA:XSTR-386: SingleValueConverter that utilizes PropertyEditor implementations (by Jukka Lindström).</li> | |
707 | <li>JIRA:XSTR-427: Converter for javax.xml.datatype.Duration (by John Kristian).</li> | |
708 | <li>JIRA:XSTR-305: Field alias inheritance (by David Blevins).</li> | |
709 | <li>XStream failed to initialize in environments without AWT or SQL classes.</li> | |
710 | <li>JIRA:XSTR-420: XPath of references are not XmlFriendly encoded.</li> | |
711 | <li>JIRA:XSTR-473: String "\0" serialized as invalid XML, support compliant behaviour according XML version.</li> | |
712 | <li>JIRA:XSTR-431: Direct support of enhanced mode for SAP JVM (thanks to Norbert Kuck by SAP).</li> | |
713 | <li>JIRA:XSTR-437: Static cache in annotation processing causes failing OSGi bundles.</li> | |
714 | <li>JIRA:XSTR-279+JIRA:XSTR-335: Annotations are not inherited from parent class.</li> | |
715 | <li>Fix StringConverter using a WeakHashMap with strong references in its value.</li> | |
716 | <li>JIRA:XSTR-403: Attributes are no longer written with JSONHierarchicalStreamDriver if current object is a collection.</li> | |
717 | <li>JIRA:XSTR-456: New LookAndFeelConverter handling LookAndFeel implementations with reflection.</li> | |
718 | <li>JIRA:XSTR-462: CachingMapper keeps direct class references.</li> | |
719 | <li>JIRA:XSTR-411: JsonHierarchicalStreamDriver does not escape characters according RFC 4627.</li> | |
720 | <li>JsonHierarchicalStreamDriver writes wrong brackets around complex Java types with a single value.</li> | |
721 | <li>JsonHierarchicalStreamDriver writes attribute names with a leading '@'.</li> | |
722 | <li>JsonHierarchicalStreamDriver supports Map implementations.</li> | |
723 | </ul> | |
724 | ||
725 | <h2>Minor changes</h2> | |
726 | ||
727 | <ul> | |
728 | <li>Added converter for java.lang.StringBuilder instances.</li> | |
729 | <li>Added converter for java.util.UUID instances.</li> | |
730 | <li>JIRA:XSTR-430: Fields written as attributes could not be omitted.</li> | |
731 | <li>JIRA:XSTR-407: Comparator might access uninitialized elements for TreeSet and TreeMap. A deserialized | |
732 | Comparator is no longer called, the converters expect the elements now in a sorted order.</li> | |
733 | <li>JIRA:XSTR-404, @XStreamImplicit() for ArrayList<ArrayList<Type>> throws ClassCastException.</li> | |
734 | <li>@XStreamContainedType() for ArrayList<ArrayList<Type>> throws ClassCastException.</li> | |
735 | <li>XStreamer did not persist a FieldKeySorter instance.</li> | |
736 | <li>JIRA:XSTR-241: JavaBeanConverter now supports customized BeanProvider.</li> | |
737 | <li>JIRA:XSTR-280: JavaBeanConverter now supports aliasField and omitField (by Hinse ter Schuur).</li> | |
738 | <li>JIRA:XSTR-280: SerializationConverter now supports aliasField and omitField.</li> | |
739 | <li>JIRA:XSTR-429: XmlFriendlyReplacer support for SaxWriter and TraxSource (by Adrian Wilkens).</li> | |
740 | <li>JIRA:XSTR-421: Characters cannot be written as attribute.</li> | |
741 | <li>JIRA:XSTR-426: java.swt.KeyStroke not properly serialized because of a character undefined in unicode.</li> | |
742 | <li>JIRA:XSTR-352: Strings with arbitrary ISO control characters are not properly serialized.</li> | |
743 | <li>JIRA:XSTR-428: An attribute named like a transient field did abort deserialization of following fields.</li> | |
744 | <li>JIRA:XSTR-443: XStream.createObjectOutputStream does not use the given driver to create the HierarchicalStreamWriter.</li> | |
745 | <li>JIRA:XSTR-440: Implicit collections can be declared for fields that are not of Collection type.</li> | |
746 | <li>JIRA:XSTR-446: Handle all primitives and their boxed counterpart for JsonHierarchicalStreamDriver.</li> | |
747 | <li>JIRA:XSTR-447: Fix deserialization of Array class types in JDK 6 (see JDK bug 6500212).</li> | |
748 | <li>JIRA:XSTR-450: @XStreamAlias is ignored if attributes should be used for the field type.</li> | |
749 | <li>JIRA:XSTR-418: Inherited @XStreamAlias is ignored if field should be rendered as attribute.</li> | |
750 | <li>JIRA:XSTR-393: Annotation processing is not consistent.</li> | |
751 | <li>JIRA:XSTR-412: @XStreamImplicit throws NPE for untyped collections.</li> | |
752 | <li>JIRA:XSTR-463: Cannot provide own default Mapper chain.</li> | |
753 | <li>JIRA:XSTR-464: Cannot provide a ClassLoader that is used in all cases.</li> | |
754 | <li>JIRA:XSTR-394: Allow enums as attributes.</li> | |
755 | <li>JIRA:XSTR-413: Support @XStreamAsAttribute for enums.</li> | |
756 | <li>JIRA:XSTR-478: Cannot specify default implementation for polymorphic enum.</li> | |
757 | <li>JIRA:XSTR-419: Treat enums as immutable types.</li> | |
758 | <li>Update annotation tutorial, explain limitations of auto-detection mode.</li> | |
759 | <li>Added copyright notices to all files.</li> | |
760 | <li>StaxWriter.flush did close Stax' XMLStreamWriter instead of flushing it.</li> | |
761 | <li>JIRA:XSTR-471: XStream POMs do no longer declare a repository at all.</li> | |
762 | <li>Calendar object could not be rendered with JSONHierarchicalStreamDriver.</li> | |
763 | <li>JIRA:XSTR-476: Properties can be sorted by key.</li> | |
764 | <li>XStream.createObjectInputStream and XStream.createObjectOutputStream | |
765 | overloaded to support a binary InputStream or OutputStream.</li> | |
766 | <li>JIRA:XSTR-470: Allow transient fields to be optionally deserialized.</li> | |
767 | </ul> | |
768 | ||
769 | <h2>API changes</h2> | |
770 | ||
771 | <ul> | |
772 | <li>c.t.x.annotation.Annotations, c.t.x.annotation.AnnotationReflectionConverter and c.t.x.annotation.AnnotationProvider deprecated. | |
773 | Functionality is integrated in new c.t.x.mapper.AnnotationMapper and accessible with new methods c.t.x.XStream.processAnnotations().</li> | |
774 | <li>New auto-detection mode for annotations, that can be turned on with c.t.x.XStream.autodetectAnnotations()</li> | |
775 | <li>c.t.x.annotation.@XStreamContainedType deprecated, the behaviour is now always active and the annotation therefore superfluous.</li> | |
776 | <li>Due to JIRA:XSTR-421 null characters are no longer written as tag with an attribute (<char null="true"/>), | |
777 | but as empty tag. The old representation is still supported at deserialization.</li> | |
778 | <li>Characters that are not defined in unicode or ISO control characters (expect TAB and LF) are written as numerical entity now.</li> | |
779 | <li>XPath references are now also XML-friendly encoded to match the path exactly. Unencoded references will normally work anyway, | |
780 | but in special cases the exact behaviour of XStream 1.2.x might be necessary. See acceptance tests for XStream 1.2.x compatibility.</li> | |
781 | <li>c.t.x.core.BaseException deprecated in favour of c.t.x.XStreamException as base exception for all exceptions XStream throws.</li> | |
782 | <li>c.t.x.XStream.InitializerException deprecated in favour of c.t.x.InitializerException.</li> | |
783 | <li>New methods get() and keys() in interface c.t.x.converter.ErrorWriter.</li> | |
784 | <li>c.t.x.mapper.XmlFriendlyMapper deprecated, technology is replaced since version 1.2 by c.t.x.io.xml.XmlFriendlyReplacer as part of the | |
785 | different XmlWriter implementations.</li> | |
786 | <li>c.t.x.mapper.Mapper.aliasForAttribute() and c.t.x.mapper.Mapper.attributeForAlias() deprecated, since it provided in reality the combined | |
787 | functionality of c.t.x.mapper.Mapper.serializedMember()/realMember() and c.t.x.mapper.Mapper.getConverterFromItemType().</li> | |
788 | <li>c.t.x.XStream(ReflectionProvider, Mapper, HierarchicalStreamDriver) deprecated, in favour of | |
789 | c.t.x.XStream(ReflectionProvider, HierarchicalStreamDriver, Mapper, ClassLoader).</li> | |
790 | <li>New interface c.t.x.converter.ConverterRegistry to express explicit functionality managing the converters.</li> | |
791 | <li>c.t.x.core.DefaultConverterLookup no longer uses a c.t.x.mapper.Mapper. Therefore the old constructor has been deprecated in favour | |
792 | of a default constructor.</li> | |
793 | <li>Overloaded methods of c.t.x.mapper.Mapper.getConverterFromItemType and c.t.x.mapper.Mapper.getConverterFromAttribute have been | |
794 | deprecated. Only one version has been kept, the implementation can handle all cases now at once and therefore multiple calls to the mapper chain | |
795 | are avoided.</li> | |
796 | <li>c.t.x.mapper.EnumMapper derives now from the c.t.x.mapper.AttributeMapper to support enums as attributes. Therefore the old constructor | |
797 | has been deprecated in favour of one taking an additional c.t.x.converters.ConverterLookup that has to be passed to the new parent.</li> | |
798 | </ul> | |
799 | ||
800 | <p class="highlight">Note, to support a representation of null values in some way, it is absolutely necessary that each converter can handle a null | |
801 | value in its marshalling methods. If you have implemented your own custom converters, try to handle such a case also to prevent incompatibilities | |
802 | in case XStream will provide such values with its next major version.</p> | |
803 | ||
804 | <h1 id="1.2.2">Version 1.2.2</h1> | |
805 | ||
806 | <p>Released May 24, 2007.</p> | |
807 | ||
808 | <p class="hightlight">Note, that next version of XStream will behave slightly different by default. XStream emits | |
809 | all fields in declaration order like Java serialization. But in contrast to Java it will omit the fields of parent | |
810 | classes last while Java serialization emits them first. This makes it difficult to match a given XML schema that | |
811 | defined inherited types or leads sometimes to obscure initialization problems. However, XStream itself will not be | |
812 | affected by the changed order of elements in the XML, any deserialization of current XML representations will work | |
813 | fine. Anyway we will provide with XStream 1.3 a FieldKeySorter implementation that mimics the old behaviour. In | |
814 | the meanwhile you can enforce the new field sorting by installing the NaturalFieldKeySorter.</p> | |
815 | ||
816 | <h2>Major changes</h2> | |
817 | ||
818 | <ul> | |
819 | <li>JIRA:XSTR-391, Support for writing (and reading) JSON by the new JettisonMappedXmlDriver (by Dejan Bosanac).</li> | |
820 | <li>New FieldKeySorter interface allows a custom sort order of the XML elements.</li> | |
821 | <li>JIRA:XSTR-68 and JIRA:XSTR-210, OmitField is now respected at deserialization to ignore removed fields.</li> | |
822 | </ul> | |
823 | ||
824 | <h2>Minor changes</h2> | |
825 | ||
826 | <ul> | |
827 | <li>JIRA:XSTR-387, Fix aliasing of inherited fields.</li> | |
828 | <li>JIRA:XSTR-395, Fix StringConverter allocating PermGen space.</li> | |
829 | <li>JIRA:XSTR-368, @XStreamConverter converters should be cached inside the AnnotationReflectionConverter.</li> | |
830 | <li>JIRA:XSTR-392, @XStreamOmitField can be used to omit fields from the resulting XML (contributed by Chung-Onn Cheong).</li> | |
831 | <li>JIRA:XSTR-371, Fix JSONWriter that omits a closing bracket for for fields with null value.</li> | |
832 | <li>JIRA:XSTR-398, DomDriver ignores given XmlFriendlyReplacer.</li> | |
833 | <li>JIRA:XSTR-370, Buildable with JDK 6, fix FontConverter for JDK 6.</li> | |
834 | <li>JIRA:XSTR-382, Support hex and octal number values.</li> | |
835 | <li>DateConverter did not respect change in TimeZone after first usage.</li> | |
836 | <li>JIRA:XSTR-375, Support for aliasing native types.</li> | |
837 | <li>JIRA:XSTR-243 again, XML elements for transient fields are now ignored completely at deserialization.</li> | |
838 | <li>Release unused object references to keep memory print low.</li> | |
839 | <li>Support for AWT and SQL is now optional: XStream now works on embedded virtual machines lacking such APIs (by Nicolas Gros d'Aillon).</li> | |
840 | <li>Support raw bytes read from the ObjectInputStream.</li> | |
841 | <li>JIRA:XSTR-373, Support for Hitachi JVM (tested by Yuji Yamano).</li> | |
842 | <li>JIRA:XSTR-378 and JIRA:XSTR-379, Fix TextAttributeConverter and EnumSetConverter failing on Apache Harmony.</li> | |
843 | <li>JIRA:XSTR-363, Support of native field order i.e. fields are processed in declaration order base classes first.</li> | |
844 | <li>JIRA:XSTR-320, Static field in child may hide non-static field in parent.</li> | |
845 | </ul> | |
846 | ||
847 | <h2>API changes</h2> | |
848 | ||
849 | <ul> | |
850 | <li>JIRA:XSTR-365, Multiple implicit collections with annotations. Deprecated @XStreamImclicitCollection in favour of @XStreamImplicit | |
851 | declared at field level.</li> | |
852 | </ul> | |
853 | ||
854 | <h1 id="1.2.1">Version 1.2.1</h1> | |
855 | ||
856 | <p>Released November 11, 2006.</p> | |
857 | ||
858 | <h2>Major changes</h2> | |
859 | ||
860 | <ul> | |
861 | <li>Introduced DocumentWriter interface and generalized functionality for all writer implementations | |
862 | creating a DOM structure (DOM4J, DOM, JDom, Xom, Xpp3Dom).</li> | |
863 | <li>Refactored build system to use Maven 2. Ant still supported on XStream Core.</li> | |
864 | <li>Created separate XStream Benchmark module</li> | |
865 | </ul> | |
866 | ||
867 | <h2>Minor changes</h2> | |
868 | ||
869 | <ul> | |
870 | <li>JIRA:XSTR-346, XStream.getClassMapper() does not return a ClassMapper for the current Mapper.</li> | |
871 | <li>Fix problem with fields containing a double underscore.</li> | |
872 | <li>JIRA:XSTR-345, Dom4JWriter adds up attributes.</li> | |
873 | <li>JIRA:XSTR-336, XStream fails to reference an implicit element.</li> | |
874 | <li>JIRA:XSTR-337, Annotation cycle bug.</li> | |
875 | <li>Fix packaging error for the resulting jar building with Maven2.</li> | |
876 | <li>JIRA:XSTR-339, NPE for attribute null values.</li> | |
877 | <li>JIRA:XSTR-338, NPE in JSON writer for converters using non-extended HierarchicalStreamWriter.</li> | |
878 | <li>JIRA:XSTR-357, Fix escaping of values in JSON writer.</li> | |
879 | <li>JIRA:XSTR-356, Fix unmarshaling error for fields containing proxies.</li> | |
880 | <li>JIRA:XSTR-349, Fix backward compatibility of Dom4jWriter.</li> | |
881 | <li>JIRA:XSTR-309, More versatile boolean conversion options (contributed by David Blevins).</li> | |
882 | <li>Add XStream.getReflectionProvider() to retrieve ReflectionProvider in use.</li> | |
883 | <li>JIRA:XSTR-358, @XStreamConverter annotation does not call converter constructor.</li> | |
884 | <li>Website generated using <a href="http://xsite.codehaus.org">XSite</a></li> | |
885 | </ul> | |
886 | ||
887 | <h2>API changes</h2> | |
888 | ||
889 | <ul> | |
890 | <li>Deprecate JDomWriter.getResult() in favour of DocumentWriter.getTopLevelNodes().</li> | |
891 | <li>Deprecate ThreadSafeSimpleDateFormat, since this is an internal helper and not part of XStream API.</li> | |
892 | </ul> | |
893 | ||
894 | <h1 id="1.2">Version 1.2</h1> | |
895 | ||
896 | <p>Released August 18, 2006.</p> | |
897 | ||
898 | <h2>Major changes</h2> | |
899 | ||
900 | <ul> | |
901 | <li>JIRA:XSTR-269, Using attributes for fields (contributed by Paul Hammant and Ian Cartwright).</li> | |
902 | <li>Aliasing of arbitrary attributes.</li> | |
903 | <li>JIRA:XSTR-50, XStream can now serialize another XStream instance.</li> | |
904 | <li>JIRA:XSTR-227, XStream has now the XStreamer, that serializes an object together with its XStream instance.</li> | |
905 | <li>JIRA:XSTR-278, AnnotationConverter for fields (contributed by Guilherme Silveira).</li> | |
906 | <li>JIRA:XSTR-256, PureJavaReflectionProvider supports now final fields starting with JDK 1.5</li> | |
907 | <li>JIRA:XSTR-258, Any Collection type can now be declared implicit, the default implementation will be respected for unmarshaling.</li> | |
908 | <li>JIRA:XSTR-88, XStream can now write all references as absolute XPath expression.</li> | |
909 | <li>JIRA:XSTR-62 and JIRA:XSTR-211, New SingeValueConverter allows light weight converters if the value can be represented by a unique string.</li> | |
910 | <li>Aliasing of classes of a specific type.</li> | |
911 | <li>JIRA:XSTR-239, Support for certain types of proxies generated with the CGLIB Enhancer.</li> | |
912 | <li>JIRA:XSTR-90 and JIRA:XSTR-311, Support for BEA JRockit starting with R25.1.0 (contributed by Henrik Ståhl of BEA).</li> | |
913 | </ul> | |
914 | ||
915 | <h2>Technology preview</h2> | |
916 | ||
917 | <ul> | |
918 | <li>Experimental binary reader and writer.</li> | |
919 | <li>Experimental HierarichicalStreamCopier allows streams to be copied from one format to another without the overhead of serialization.</li> | |
920 | <li>Experimental JSON support allows streams to be copied from one format to another without the overhead of serialization (contributed by Paul Hammant).</li> | |
921 | </ul> | |
922 | ||
923 | <h2>Minor changes</h2> | |
924 | ||
925 | <ul> | |
926 | <li>JIRA:XSTR-266, XStream fails to serialize elements of a unserializable class, that is a base class of a derived class</li> | |
927 | <li>JIRA:XSTR-236, Priority constants for converter registration are now public</li> | |
928 | <li>JIRA:XSTR-215, XStream writes now fields in declaration order even for JVMs reporting them in reverse order like IBM JDK.</li> | |
929 | <li>JIRA:XSTR-276 and JIRA:XSTR-283, XStream does no longer attempt to create references to implicit element.</li> | |
930 | <li>JIRA:XSTR-244, Closing a Writer can now be done twice, but any write attempt will later on fail.</li> | |
931 | <li>JIRA:XSTR-243, Transient fields were unmarshalled from XML.</li> | |
932 | <li>JIRA:XSTR-250, Providing a mapper to the XStream constructor will no longer result in a NPE.</li> | |
933 | <li>JIRA:XSTR-281, After registering a new converter, the internal converter cache is now cleared.</li> | |
934 | <li>JIRA:XSTR-284, XStream checks the object returned by a converter for compatibility.</li> | |
935 | <li>XStream no longer fails serializing a Throwable without cause when no references shall be written.</li> | |
936 | <li>Converter for java.awt.font.TextAttribute.</li> | |
937 | <li>Converter for java.nio.charset.Charset.</li> | |
938 | <li>JIRA:XSTR-286, XStream detects impossible self serialization and throws now an appropriate ConversionException.</li> | |
939 | <li>JIRA:XSTR-291, XomDriver implementation added.</li> | |
940 | <li>JIRA:XSTR-299, Fix for implicit collections with items using the same name as the field name of the underlying collection.</li> | |
941 | <li>JIRA:XSTR-245, Broken XML with custom serialization in certain cases (patch contributed by Cyrille Le Clerc).</li> | |
942 | <li>JIRA:XSTR-304, Bad handling of repairing namespace flag for StaxDriver (patch contributed by John Kristian).</li> | |
943 | </ul> | |
944 | ||
945 | <h2>API changes</h2> | |
946 | ||
947 | <ul> | |
948 | <li>JIRA:XSTR-252, Refactored support for XML friendly character mapping.</li> | |
949 | <li>JIRA:XSTR-69, Refactored ReflectionConverter allows simpler subclassing.</li> | |
950 | <li>Unmarshalling context has now an overloaded version of the method convertAnother to provide the Converter directly.</li> | |
951 | <li>Deprecate ClassMapper for Mapper. All methods with a ClassMapper parameter have now a duplicate taking only a Mapper. The variant with the ClassMapper is deprecated.</li> | |
952 | <li>Deprecate c.t.x.alias.CannotResolveClassException for c.t.x.mapper.CannotResolveClassException.</li> | |
953 | <li>Deprecate NameMapper (was not used within XStream anymore anyway).</li> | |
954 | <li>Deprecate constructor of DefaultMapper taking an alternative name for the class attribute. Use the aliasAttribute method.</li> | |
955 | <li>Deprecate attributeForImplementationClass, attributeForClassDefiningField, attributeForReadResolveField, and attributeForEnumType in favour of the generalized aliasForAttribute in the Mapper interface.</li> | |
956 | <li>Removed all deprecated stuff from 1.1.x and 1.0.x</li> | |
957 | <li>JIRA:XSTR-211, A lot of existing (basic) Converters have been refactored to use the new SingleValueConverter interface.</li> | |
958 | <li>Dom4JWriter uses now a DocumentFactory and a XMLWriter as constructor arguments.</li> | |
959 | </ul> | |
960 | ||
961 | <h1 id="1.1.3">Version 1.1.3</h1> | |
962 | ||
963 | <p>Released January 13, 2006.</p> | |
964 | ||
965 | <h2>Major changes</h2> | |
966 | ||
967 | <ul> | |
968 | <li>Added XStream.toXML(OutputStream) and XStream.fromXML(InputStream).</li> | |
969 | <li>Ability to prevent fields from being serialized by calling XStream.omitField() or by implementing Mapper.shouldSerializeMember().</li> | |
970 | <li>Added Converter for Enum, EnumMap and EnumSet</li> | |
971 | <li>JIRA:XSTR-186, Added BeanConverter (contributed by Andrea Aime)</li> | |
972 | <li>JIRA:XSTR-246, Added ISO8601SqlTimestampConverter (contributed by Cheong, Chung-Onn)</li> | |
973 | <li>Added ISO8601GregorianCaledarConverter</li> | |
974 | <li>JIRA:XSTR-215, Fixed support for IBM JVM (contributed by Gabor Liptak)</li> | |
975 | <li>Enhanced mode support for Blackdown JDK</li> | |
976 | <li>JIRA:XSTR-265, support for javax.security.auth.Subject</li> | |
977 | <li>JIRA:XSTR-233, support for Integer[] arrays</li> | |
978 | </ul> | |
979 | ||
980 | <h2>Minor changes</h2> | |
981 | ||
982 | <ul> | |
983 | <li>Remove unnecessary PrintWriter wrapper in default writers (pointed out by Mathieu Champlon)</li> | |
984 | <li>Bugfix: EnumSet converter can now deal with empty sets (contributed by Baba Buehler)</li> | |
985 | <li>Update ISO8601DateConverter to use Joda 1.0</li> | |
986 | <li>JIRA:XSTR-242, GregorianCalenderConverter saves now the timezone</li> | |
987 | <li>JIRA:XSTR-247, ISO8601DateConverter now independent on timezone</li> | |
988 | <li>JIRA:XSTR-263, Circular references with Externalizable objects fail</li> | |
989 | </ul> | |
990 | ||
991 | <h2>API changes</h2> | |
992 | ||
993 | <ul> | |
994 | <li>None.</li> | |
995 | </ul> | |
996 | ||
997 | <h1 id="1.1.2">Version 1.1.2</h1> | |
998 | ||
999 | <p>Released April 30, 2005. Most popular feature requests implemented. Java 5 Enum support. Serialization of JavaBeans | |
1000 | using accessors. Aliasing of fields. StAX integration, with namespaces. Improved support on JDK 1.3 and IBM JDK. </p> | |
1001 | ||
1002 | <h2>Major changes</h2> | |
1003 | ||
1004 | <ul> | |
1005 | <li>JIRA:XSTR-186, Option to serialize JavaBeans using public accessors, rather than private fields (contributed by Andrea Aime).</li> | |
35 | <h1 id="1.4.11.1">1.4.11.1</h1> | |
36 | ||
37 | <p>Released October 27, 2018.</p> | |
38 | ||
39 | <h2>Hot fix</h2> | |
40 | ||
41 | <ul> | |
42 | <li>GHI:#133: XStream 1.4.11 fails to run on a Java Runtime < 8.</li> | |
43 | </ul> | |
44 | ||
45 | <h1 id="1.4.11">1.4.11</h1> | |
46 | ||
47 | <p>Released October 23, 2018.</p> | |
48 | ||
49 | <p class="highlight">This maintenance release addresses again the security vulnerability <a href="CVE-2013-7285.html"> | |
50 | CVE-2013-7285</a>, an arbitrary execution of commands when unmarshalling for XStream instances with | |
51 | uninitialized security framework. Only 1.4.10 uninitialized security framework was affected.</p> | |
52 | ||
53 | <h2>Minor changes</h2> | |
54 | ||
55 | <ul> | |
56 | <li>GHPR:#91, GHPR:#106: Clean-up data stacks in UnmarshallingContext implementations in case of exception (by | |
57 | Märt Bakhoff).</li> | |
58 | <li>GHI:#2: Unneeded contention in DefaultConverterLookup.</li> | |
59 | <li>GHI:#94: Fix PathConverter containing absolute Windows paths.</li> | |
60 | <li>GHI:#105: XStream's ObjectInputStream returns wrong values for readUnsignedByte and readUnsignedShort.</li> | |
61 | <li>JIRA:XSTR-616 and GHPR:#93: Introduce StringCodec interface to support arbitrary Base64 codec | |
62 | implementations for EncodedByteArrayConverter. Prefer Base64 codec implementations of the Java runtime over | |
63 | XStream's own one.</li> | |
64 | <li>GHI:#97: Support to run out of the box in a Java 1.4 runtime is established again.</li> | |
65 | <li>Provide methods in AbstractCollectionConverter that read and write in a balanced way from and to the | |
66 | hierarchical stream.</li> | |
67 | <li>New future-proof method JVM.isVersion to detect major version of Java runtime (incl. Java 10) as | |
68 | replacement for individual JVM.isXY methods.</li> | |
69 | <li>GHI:#115: Dom4JDriver ignores character set of Dom4J configuration creating a Writer.</li> | |
70 | <li>GHI:#116: Make converters null safe.</li> | |
71 | <li>GHI:#123 and GHPR:#124: Declare XPP dependencies for OSGi as optional.</li> | |
72 | <li>Add XppDriver.createDefaultParser for a simpler access to the default XmlPullParserFactory.</li> | |
73 | <li>Old BEA reference implementation of StAX is outdated, unmaintained and has security issues, therefore | |
74 | XStream's driver has been deprecated.</li> | |
75 | <li>Support for JaCoCo: FieldDictionary ignores synthetic fields starting with <em>$jacoco</em> as name.</li> | |
76 | </ul> | |
77 | ||
78 | <h2>Stream compatibility</h2> | |
79 | ||
80 | <ul> | |
81 | <li>The EncodedByteArrayConverter will now use an encoder by default that does no longer add line breaks as | |
82 | normally required by the RFC 1521 after 76 characters, making it also easier to use the converter for | |
83 | attributes. This will not affect XStream's Base64 decoder.</li> | |
84 | </ul> | |
85 | ||
86 | <h2>API changes</h2> | |
87 | ||
88 | <ul> | |
89 | <li>Added c.t.x.converters.collection.AbstractCollectionConverter.readBareItem(HierarchicalStreamReader, UnmarshallingContext, Object).</li> | |
90 | <li>Added c.t.x.converters.collection.AbstractCollectionConverter.readCompleteItem(HierarchicalStreamReader, UnarshallingContext, Object).</li> | |
91 | <li>Deprecated c.t.x.converters.collection.AbstractCollectionConverter.readItem(HierarchicalStreamReader, UnmarshallingContext, Object).</li> | |
92 | <li>Added c.t.x.converters.collection.AbstractCollectionConverter.writeBareItem(Object, MarshallingContext, HierarchicalStreamWriter).</li> | |
93 | <li>Added c.t.x.converters.collection.AbstractCollectionConverter.writeCompleteItem(Object, MarshallingContext, HierarchicalStreamWriter).</li> | |
94 | <li>Deprecated c.t.x.converters.collection.AbstractCollectionConverter.writeItem(Object, MarshallingContext, HierarchicalStreamWriter).</li> | |
95 | <li>Added c.t.x.converters.collection.AbstractCollectionConverter.writeNullItem(MarshallingContext, HierarchicalStreamWriter).</li> | |
96 | <li>Added c.t.x.converters.extended.EncodedByteArrayConverter(StingCodec).</li> | |
97 | <li>Added c.t.x.converters.extended.NamedCollectionConverter.readBareItem(HierarchicalStreamReader, UnmarshallingContext, Object).</li> | |
98 | <li>Deprecated c.t.x.converters.extended.NamedCollectionConverter.readItem(HierarchicalStreamReader, UnmarshallingContext, Object).</li> | |
99 | <li>Added c.t.x.converters.extended.NamedCollectionConverter.writeCompleteItem(Object, MarshallingContext, HierarchicalStreamWriter).</li> | |
100 | <li>Deprecated c.t.x.converters.extended.NamedCollectionConverter.writeItem(Object, MarshallingContext, HierarchicalStreamWriter).</li> | |
101 | <li>Added c.t.x.core.DefaultConverterLookup(Map).</li> | |
102 | <li>Added c.t.x.core.util.JVM.getBase64Codec().</li> | |
103 | <li>Added c.t.x.core.util.JVM.isVersion().</li> | |
104 | <li>Deprecated c.t.x.core.util.JVM.is18().</li> | |
105 | <li>Deprecated c.t.x.core.util.JVM.is9().</li> | |
106 | <li>Deprecated c.t.x.io.ExtendedHierarchicalStreamReader.</li> | |
107 | <li>Deprecated c.t.x.io.ExtendedHierarchicalStreamWriter.</li> | |
108 | <li>Deprecated c.t.x.io.ExtendedHierarchicalStreamWriterHelper.</li> | |
109 | <li>Deprecated c.t.x.io.xml.BEAStaxDriver.</li> | |
110 | <li>Added c.t.x.io.xml.Dom4JReader.Dom4JReader(Branch).</li> | |
111 | <li>Added c.t.x.io.xml.XppDriver.createDefaultParser().</li> | |
112 | <li>Added c.t.x.core.util.StingCodec.</li> | |
113 | </ul> | |
114 | ||
115 | <h1 id="1.4.10">1.4.10</h1> | |
116 | ||
117 | <p>Released May 23, 2017.</p> | |
118 | ||
119 | <p class="highlight">This maintenance release addresses also the security vulnerability <a href="CVE-2017-7957.html"> | |
120 | CVE-2017-7957</a>, used for a Denial of Service attack by crashing the Java runtime.</p> | |
121 | ||
122 | <h2>Major changes</h2> | |
123 | ||
124 | <ul> | |
125 | <li>GHI:#84: New XStream artifact with <em>-java7</em> appended as version suffix for a library explicitly | |
126 | without the Java 8 stuff (lambda expression support, converters for java.time.* package).</li> | |
127 | <li>Fix PrimitiveTypePermission to reject type <em>void</em> to prevent CVE-2017-7957 with an initialized | |
128 | security framework.</li> | |
129 | <li>Improve performance by minimizing call stack of mapper chain.</li> | |
130 | <li>GHPR:#82, JIRA:XSTR-774: Add converters for types of java.time, java.time.chrono, and java.time.temporal | |
131 | packages (converters for LocalDate, LocalDateTime, LocalTime, OffsetDateTime, and ZonedDateTime by Matej Cimbora).</li> | |
132 | <li>GHI:#29: JavaBeanConverter does not respect ignored unknown elements.</li> | |
133 | <li>Add XStream.setupDefaultSecurity to initialize security framework with defaults of XStream 1.5.x.</li> | |
134 | <li>Emit error warning if security framework has not been initialized and the XStream instance is vulnerable to | |
135 | known exploits.</li> | |
136 | </ul> | |
137 | ||
138 | <h2>Stream Compatibility</h2> | |
139 | ||
140 | <ul> | |
141 | <li>The alias <em>duration</em> for type <em>javax.xml.datatype.Duration</em> has changed to <em>xml-duration</em> | |
142 | due to the support of the classes in the java.time package. <em>duration</em> is now used for type <em>java.time.Duration</em>. | |
143 | Simply register the alias <em>duration</em> again for type <em>javax.xml.datatype.Duration</em> if backward | |
144 | compatibility is required for this type. | |
145 | </li> | |
146 | <li>All types of the java.time packages that have been written with previous versions of XStream can still be | |
147 | deserialized.</li> | |
148 | </ul> | |
149 | ||
150 | <h2>Minor changes</h2> | |
151 | ||
152 | <ul> | |
153 | <li>GHI:#54: Fix BeanProvider.canInstantiate(Class), method may not throw exception.</li> | |
154 | <li>GHI:#76 and GHPR:#77: Missing support for cascaded writeReplace calls.</li> | |
155 | <li>GHI:#61: Regression in 1.4.9: Performance drop in ImplicitCollectionMapper.</li> | |
156 | <li>GHI:#52: PathConverter fails for file paths with spaces.</li> | |
157 | <li>PathConverter uses always forward slashes as path separator.</li> | |
158 | <li>GHI:#53: SqlTimestampConverter cannot parse values without fraction.</li> | |
159 | <li>GHI:#45: Support different time zones for SqlTimestampConverter.</li> | |
160 | <li>GHI:#67 and GHPR:#68: Allow usage of DataHolder for createObjectInputStream and createObjectOutputStream.</li> | |
161 | <li>GHI:#75: Use java.time.* package instead of Joda-Time.</li> | |
162 | <li>Dom4JXmlWriter does not flush writer at endDocument().</li> | |
163 | <li>Path is an immutable type.</li> | |
164 | <li>GHPR:#65: Protect converter lookup against runtime errors.</li> | |
165 | <li>Current Java 9 implementation reports itself as version 9 now.</li> | |
166 | </ul> | |
167 | ||
168 | <h2>API changes</h2> | |
169 | ||
170 | <ul> | |
171 | <li>Added c.t.x.util.JVM.is9().</li> | |
172 | <li>Added c.t.x.XStream.setupDefaultSecurity(XStream).</li> | |
173 | <li>Added c.t.x.XStream.createObjectInputStream(HierarchicalStreamReader, DataHolder) and | |
174 | c.t.x.XStream.createObjectOutputStream(HierarchicalStreamWriter, String, DataHolder).</li> | |
175 | <li>Added c.t.x.converters.javabean.PropertyDictionary.propertyDescriptorOrNull(Class, String).</li> | |
176 | <li>Added method c.t.x.mapper.Mapper.IsIgnoredElement(String)</li> | |
177 | <li>Added c.t.x.mapper.ElementIgnoringMapper.</li> | |
178 | <li>Deprecated method c.t.x.mapper.FieldAliasingMapper.addFieldsToIgnore(Pattern).</li> | |
179 | <li>Deprecated method c.t.x.mapper.FieldAliasingMapper.omitField(Class, String).</li> | |
180 | <li>Deprecated method c.t.x.core.util.JVM.is17().</li> | |
181 | <li>Deprecated method c.t.x.core.util.JVM.is19().</li> | |
182 | </ul> | |
183 | ||
184 | <h1 id="1.4.9">1.4.9</h1> | |
185 | ||
186 | <p>Released March 15, 2016.</p> | |
187 | ||
188 | <p class="highlight">This maintenance release addresses also the security vulnerability <a href="CVE-2016-3674.html"> | |
189 | CVE-2016-3674</a>, known as XXE vulnerability that can be used to expose arbitrary data from the file system | |
190 | when unmarshalling.</p> | |
191 | ||
192 | <h2>Major changes</h2> | |
193 | ||
194 | <ul> | |
195 | <li>GHI:#25: Fix <a href="https://www.owasp.org/index.php/XML_External_Entity_%28XXE%29_Processing">XXE | |
196 | vulnerability (CVE-2016-3674)</a>: Fixed affected drivers were Dom4JDriver, DomDriver, JDomDriver, JDom2Driver, | |
197 | SjsxpDriver, StandardStaxDriver and WstxDriver. Still vulnerable are BEAStaxDriver and XomDriver. Processing of | |
198 | (external) entities has been disabled. See <a href="faq.html#Security_XXEVulnerability">FAQ</a> for more information. | |
199 | </li> | |
200 | <li>Benchmark module has been deprecated in favor of <a href="http://openjdk.java.net/projects/code-tools/jmh/"> | |
201 | JMH (Java Microbenchmarking Harness)</a>. | |
202 | </li> | |
203 | <li>GHI:#33 and GHPR:#38: Add converter for java.nio.file.Path (by Aaron Jonson).</li> | |
204 | </ul> | |
205 | ||
206 | <h2>Minor changes</h2> | |
207 | ||
208 | <ul> | |
209 | <li>GHI:#35: AnnotationMapper dropped silently constructor arguments for converters if they were equal.</li> | |
210 | <li>Fix: Possible concurrency problem with XomDriver.</li> | |
211 | <li>JIRA:XSTR-773, GHPR:#3: Minimize memory footprint by not keeping internal references to instances of | |
212 | immutable types.</li> | |
213 | <li>Drop automatic reference support at deserialization time for immutable types before version 1.4 (primitive | |
214 | types and their boxed counterpart, java.lang.Class, java.lang.String, java.math.BigDecimal, java.math.BigInteger, | |
215 | java.io.File, java.net.URL, and java.awt.font.TextAttribute).</li> | |
216 | <li>Fix: Implicit collection declaration is erroneously inherited or propagated to hidden field of same name.</li> | |
217 | <li>XStreamConverter annotation supports null values as arguments for converter instantiation.</li> | |
218 | <li>GHI:#5: Support null values for JavaBean properties.</li> | |
219 | <li>GHI:#36: Fix NamedMapConverter, does not use SingleValueConverter of value if value is text of entry element.</li> | |
220 | <li>GHI:#13: Own converter for javax.activation.ActivationDataFlavor, because ExternalizableConverter cannot | |
221 | handle a type that violates the Java specification.</li> | |
222 | <li>GHPR:#18: Minimize synchronized block in FieldDictionary.</li> | |
223 | <li>JIRA:XSTR-769: Synthetic fields with references to outer class use compiler dependent names.</li> | |
224 | <li>JIRA:XSTR-771: UUID is an immutable type by default.</li> | |
225 | <li>GHPR:#23: Constructor of AbstractXppDriver swallows causing exception.</li> | |
226 | <li>GHI:#28: Fix functionality of ClassAliaslingMapper.itemTypeAsAttributes(Class).</li> | |
227 | <li>GHI:#37: Historical Java 1.3 support suppresses causing exception of a thrown InvocationTargetException.</li> | |
228 | <li>GHI:#41: Cannot instantiate ToAttributedValueConverter with null value for valueFieldName using | |
229 | XStreamConverter annotation.</li> | |
230 | <li>Fix example code in description of security framework.</li> | |
231 | <li>Clean-up usage of exceptions.</li> | |
232 | </ul> | |
233 | ||
234 | <h2>API changes</h2> | |
235 | ||
236 | <ul> | |
237 | <li>Added c.t.x.XStream.addImmutableType(Class, boolean) and deprecated c.t.x.XStream.addImmutableType(Class).</li> | |
238 | <li>Added c.t.x.mapper.Mapper.isReferenceable(Class).</li> | |
239 | <li>Added c.t.x.mapper.ImmutableTypesMapper.addImmutableType(Class, boolean) and deprecated | |
240 | c.t.x.mapper.ImmutableTypesMapper.addImmutableType(Class).</li> | |
241 | <li>Added c.t.x.io.xml.Dom4JDriver.createReader().</li> | |
242 | <li>Added c.t.x.io.xml.DomDriver.createDocumentBuilderFactory().</li> | |
243 | <li>Added c.t.x.io.xml.JDomDriver.createBuilder().</li> | |
244 | <li>Added c.t.x.io.xml.JDom2Driver.createBuilder().</li> | |
245 | <li>Added c.t.x.io.xml.XomDriver.createBuilder().</li> | |
246 | <li>Added constructor c.t.x.converter.extended.ToAttributedValueConverter.ToAttributedValueConverter(Class, | |
247 | Mapper, ReflectionProvider, ConverterLookup).</li> | |
248 | <li>Added abstract c.t.x.converter.ErrorWritingException as common base for c.t.x.converter.ConversionException | |
249 | and c.t.x.converter.reflection.ObjectAccessException.</li> | |
250 | <li>Deprecated c.t.x.io.xml.XomDriver(Builder), c.t.x.io.xml.XomDriver(Builder, NameCoder) and | |
251 | c.t.x.io.xml.XomDriver.getBuilder().</li> | |
252 | <li>Deprecated c.t.x.mapper.ClassAliaslingMapper.itemTypeAsAttributes(Class) and | |
253 | c.t.x.mapper.ClassAliaslingMapper.aliasIsAttribute(String). Methods never called, left-over from old refactoring.</li> | |
254 | </ul> | |
255 | ||
256 | <h1 id="1.4.8">1.4.8</h1> | |
257 | ||
258 | <p>Released February 18, 2015.</p> | |
259 | ||
260 | <h2>Major changes</h2> | |
261 | ||
262 | <ul> | |
263 | <li>Support for serializable lambda expressions and handling of non-serializable ones.</li> | |
264 | </ul> | |
265 | ||
266 | <h2>Minor changes</h2> | |
267 | ||
268 | <ul> | |
269 | <li>Detect Java 9 runtime.</li> | |
270 | <li>JIRA:XSTR-767: Deserialization of referenced lambda expressions fail.</li> | |
271 | <li>JIRA:XSTR-762: Private method readResolve() called on base classes.</li> | |
272 | <li>JIRA:XSTR-761: Support ignored serialPersistentField at deserialization time.</li> | |
273 | <li>JIRA:XSTR-755: ExternalizableConverter does not respect writeReplace and readResolve.</li> | |
274 | <li>JIRA:XSTR-757: Deserialized TreeSet does not honor remove(Object) return value contract.</li> | |
275 | <li>JIRA:XSTR-759: Support deserialization of <a href="http://www.w3.org/TR/NOTE-datetime">W3C datetime | |
276 | format</a> in DateConverter with Java 7 runtime. | |
277 | </li> | |
278 | <li>Fix: DateConverter ignores provided locale.</li> | |
279 | <li>JIRA:XSTR-768: ISO8601GregorianCalendarConverter may set invalid time zone for Joda-Time.</li> | |
280 | <li>Fix: WeakCache.entrySet().iterator().next.setValue(value) returns the reference instead of the old value.</li> | |
281 | <li>Fix: SqlTimestampConverter throws IllegalArgumentException instead of ConversionException on fromString().</li> | |
282 | <li>Fix: CGLIBEnhancedConverter does not initialize transient members of parent after deserialization.</li> | |
283 | <li>JIRA:XSTR-763: Set scope of org.json:json to test instead declaring the dependency as optional.</li> | |
284 | </ul> | |
285 | ||
286 | <h2>API changes</h2> | |
287 | ||
288 | <ul> | |
289 | <li>Added c.t.x.util.JVM.is19().</li> | |
290 | <li>Added c.t.x.converter.reflection.LambdaConverter and c.t.x.mapper.LambdaMapper.</li> | |
291 | <li>Declare c.t.x.XStream.ignoreUnknownElements(Pattern) as public.</li> | |
292 | <li>c.t.x.converters.reflection.AbstractReflectionConverter.readResolve() is protected now.</li> | |
293 | <li>c.t.x.mapper.AbstractAttributeAliasingMapper.readResolve() is protected now.</li> | |
294 | <li>Deprecated c.t.x.converters.extended.StackTraceElementFactory, it is an internal helper class.</li> | |
295 | <li>Deprecated c.t.x.converters.reflection.SerializationMethodInvoker, it is an internal helper class.</li> | |
296 | <li>Deprecated c.t.x.io.AttributeNameIterator, it is an internal helper class.</li> | |
297 | <li>Deprecated c.t.x.XStream.useXStream11XmlFriendlyMapper(), corresponding | |
298 | c.t.x.mapper.XStream11XmlFriendlyMapper has been deprecated long ago.</li> | |
299 | <li>Deprecated c.t.x.converter.basic.BooleanConverter.shouldConvert(Class,Object), undetected remainder of | |
300 | ancient XStream version.</li> | |
301 | </ul> | |
302 | ||
303 | <h1 id="1.4.7">1.4.7</h1> | |
304 | ||
305 | <p>Released February 8, 2014.</p> | |
306 | ||
307 | <p class="highlight">This maintenance release addresses mainly the security vulnerability <a href="CVE-2013-7285.html"> | |
308 | CVE-2013-7285</a>, an arbitrary execution of commands when unmarshalling.</p> | |
309 | ||
310 | <h2>Major changes</h2> | |
311 | ||
312 | <ul> | |
313 | <li>Add <a href="security.html#framework">security framework</a> to limit handled types while unmarshalling. | |
314 | </li> | |
315 | <li>java.bean.EventHandler no longer handled automatically because of severe security vulnerability.</li> | |
316 | <li>JIRA:XSTR-751: New SunLimitedUnsafeReflectionProvider that uses undocumented features only to allocate new | |
317 | instances as required on Dalvik.</li> | |
318 | <li>Fix instantiation of AnnotationMapper that requires ConverterLookup and ConverterRegistry to be the same | |
319 | instance.</li> | |
320 | </ul> | |
321 | ||
322 | <h2>Minor changes</h2> | |
323 | ||
324 | <ul> | |
325 | <li>XSTR-749: NPE if ReflectionConverter.canConvert(type) is called with null as argument.</li> | |
326 | <li>XSTR-753: NPE if SerializationConverter.canConvert(type) is called with an interface type as argument that | |
327 | extends Serializable.</li> | |
328 | <li>Add constructor to ReflectionConverter taking an additional type to create an instance that is dedicated to a | |
329 | specific type only.</li> | |
330 | <li>The ConverterLookup used by default cannot be casted to a ConverterRegistry anymore.</li> | |
331 | </ul> | |
332 | ||
333 | <h2>API changes</h2> | |
334 | ||
335 | <ul> | |
336 | <li>Added package c.t.x.security with interface TypePermission, all its implementations and | |
337 | ForbiddenClassException.</li> | |
338 | <li>Added c.t.x.mapper.SecurityMapper handling the new type permissions.</li> | |
339 | <li>Added methods addPermission, denyPermission, allowTypesXXX and denyTypesXXX to c.t.x.XStream to setup | |
340 | security at unmarshalling time.</li> | |
341 | <li>Added c.t.x.converters.reflection.SunLimitedUnsafeReflectionProvider.</li> | |
342 | <li>Deprecated c.t.x.converters.reflection.Sun14ReflectionProvider in favor of new | |
343 | c.t.x.converters.reflection.SunUnsafeReflectionProvider.</li> | |
344 | <li>Added c.t.x.converters.reflection.ReflectionConverter(Mapper,ReflectionProvider,Class).</li> | |
345 | </ul> | |
346 | ||
347 | <h1 id="1.4.6">1.4.6</h1> | |
348 | ||
349 | <p>Released December 12, 2013.</p> | |
350 | ||
351 | <h2>Major changes</h2> | |
352 | ||
353 | <ul> | |
354 | <li>JIRA:XSTR-566 and JIRA:XSTR-200: Better compatibility with GAE and environments with active SecurityManager | |
355 | (i.e. in an Applet). XStream converters try now to ensure already in the canConvert methods that they can handle the | |
356 | requested type in practice and not only theoretically. Additionally the implementations even better take care, that | |
357 | the initialization of a converter will not break the setup of XStream itself. Following modifications have been done | |
358 | for these topics: | |
359 | <ul> | |
360 | <li>ReflectionConverter, SerializationConverter and LookAndFieldConverter will check if they can access the | |
361 | fields by reflection for a requested type.</li> | |
362 | <li>SerializationConverter and ExternalizableConverter will check if they can create an instance of a derived | |
363 | OutputObjectStream first.</li> | |
364 | <li>BeanProvider does no longer use reflection to locate default constructor.</li> | |
365 | <li>AbstractAttributedCharacterIteratorAttributeConverter (and therefore TextAttributeConverter) will check | |
366 | first if it can access the possible constants of the type by reflection.</li> | |
367 | <li>NoClassDefFoundError raised in GAE accessing the fields of restricted types by reflection will be handled.</li> | |
368 | <li>StackTraceElementConverter uses constructor for StackTraceElement instances in Java 5 and GEA.</li> | |
369 | </ul> | |
370 | </li> | |
371 | <li>JIRA:XSTR-739 and JIRA:XSTR-746: OrderRetainingMap fails if HashMap.putAll(Map) of Java Runtime is not | |
372 | implemented calling put for every element within the map.</li> | |
373 | <li>New NamedArrayConverter to define names of inner elements.</li> | |
374 | </ul> | |
375 | ||
376 | <h2>Minor changes</h2> | |
377 | ||
378 | <ul> | |
379 | <li>JIRA:XSTR-747: All constructors of StaxDriver derived classes take erroneously a XmlFriendlyNameCoder instead | |
380 | of a plain NameCoder.</li> | |
381 | </ul> | |
382 | ||
383 | <h2>API changes</h2> | |
384 | ||
385 | <ul> | |
386 | <li>Added c.t.x.converters.extended.NamedArrayConverter for free element names in arrays.</li> | |
387 | <li>Added constructors to c.t.x.io.xml.StandardStaxDriver taking NameCoder instead of XmlFriendlyNameCoder.</li> | |
388 | <li>Deprecated constructors of c.t.x.io.xml.StandardStaxDriver taking a XmlFriendlyNameCoder.</li> | |
389 | <li>Added constructors to c.t.x.io.xml.BEAStaxDriver taking NameCoder instead of XmlFriendlyNameCoder.</li> | |
390 | <li>Deprecated constructors of c.t.x.io.xml.BEAStaxDriver taking a XmlFriendlyNameCoder.</li> | |
391 | <li>Added constructors to c.t.x.io.xml.WstxDriver taking NameCoder instead of XmlFriendlyNameCoder.</li> | |
392 | <li>Deprecated constructors of c.t.x.io.xml.WstxDriver taking a XmlFriendlyNameCoder.</li> | |
393 | <li>Added method canAccess to c.t.x.converter.reflection.AbstractReflectionConverter.</li> | |
394 | <li>Added static method canCreateDerivedObjectOutputStream to c.t.x.core.JVM.</li> | |
395 | <li>Deprecated unused member c.t.x.converter.javabean.BeanProvider.NO_PARAMS.</li> | |
396 | <li>Deprecated unused method c.t.x.converter.javabean.BeanProvider.getDefaultConstrutor(Class).</li> | |
397 | </ul> | |
398 | ||
399 | ||
400 | <h1 id="1.4.5">1.4.5</h1> | |
401 | ||
402 | <p>Released September 18, 2013.</p> | |
403 | ||
404 | <h2>Major changes</h2> | |
405 | ||
406 | <ul> | |
407 | <li>JIRA:XSTR-732: Use a referencing implementation for the ClassLoader to support environments where no new | |
408 | ClassLoader can be instantiated due to security restrictions.</li> | |
409 | <li>JIRA:XSTR-691: Allow unknown XML elements to be ignored using new method XStream.ignoreUnknownElements.</li> | |
410 | <li>JIRA:XSTR-728: XStream creates invalid JSON with JsonHierarchicalStreamDriver for custom converters since | |
411 | XStream 1.4.</li> | |
412 | <li>JIRA:XSTR-300: New EnumToStringConverter to support custom string representations of Enum values.</li> | |
413 | <li>JIRA:XSTR-292 and JIRA:XSTR-405: New NamedMapConverter and NamedCollectionConverter to define names of inner | |
414 | elements.</li> | |
415 | <li>JIRA:XSTR-726: New annotation XStreamAliasType to support declarative definition of XStream.aliasType().</li> | |
416 | <li>JIRA:XSTR-735: Support for JDOM2 with JDom2Driver, JDom2Reader and JDom2Writer.</li> | |
417 | <li>Optimized XML structure for java.awt.Font.</li> | |
418 | <li>Fix: ToAttributedValueConverter silently appends fields without attribute support to the value producing | |
419 | mixed-mode XML.</li> | |
420 | <li>JIRA:XSTR-566 and JIRA:XSTR-249: Better compatibility with Google AppEngine and J2ME, setup no longer fails | |
421 | for unavailable converters.</li> | |
422 | </ul> | |
423 | ||
424 | <h2>Minor changes</h2> | |
425 | ||
426 | <ul> | |
427 | <li>Fix missing manifest information.</li> | |
428 | <li>JIRA:XSTR-729: Add OSGi information to manifests.</li> | |
429 | <li>JIRA:XSTR-723: XStream will now detect a working enhanced mode dynamically instead using lists of known | |
430 | vendors. This allows enhanced support for JamVM if it is bundled with OpenJDK. It will currently fail on a runtime | |
431 | based on GNU Classpath (at least up to version 0.98).</li> | |
432 | <li>JIRA:XSTR-541: JavaScript compatibility problem with 64-bit integers in JSON.</li> | |
433 | <li>JIRA:XSTR-719: Support replacement of default converter in any case.</li> | |
434 | <li>JIRA:XSTR-725: processAnnotation performance improvement in concurrent situation.</li> | |
435 | <li>JIRA:XSTR-721: EnumConverter is more lenient while parsing constants.</li> | |
436 | <li>New constructors for CollectionConverter and MapConverter to allow registration for an individual type.</li> | |
437 | <li>JIRA:XSTR-724: Cache class name lookup failures.</li> | |
438 | <li>Current IBM JDK for Java 1.4.2 no longer has a reverse field ordering.</li> | |
439 | <li>LongConverter supports now positive hex and octal numbers over Long.MAX_VALUE within 64 bit.</li> | |
440 | <li>Fix: Sun14RefectionProvider ignores a provided FieldDictionary.</li> | |
441 | <li>JIRA:XSTR-457: Do not write 'defined-in' attribute if not needed.</li> | |
442 | <li>JettisonMappedXmlDriver provides better support to overwrite its create methods.</li> | |
443 | <li>JIRA:XSTR-685: StAX based drivers (StaxDriver and JettisonMappedXmlDriver) are not closing internal input | |
444 | stream reading from file or URL.</li> | |
445 | <li>JIRA:XSTR-736: XStream.unmarshal may throw NPE if version info of manifest is missing.</li> | |
446 | <li>JIRA:XSTR-733: Implicit elements that match multiple defined implicit collections will be assigned to the map | |
447 | with the nearest matching element type.</li> | |
448 | <li>JIRA:XSTR-740: ISO8601GregorianCalendarConverter creates Calendar instance with wrong Locale in Java 7 if the | |
449 | Locale for the LocaleCategory.FORMAT is different to the global default Locale.</li> | |
450 | <li>JIRA:XSTR-578: Implement support for aliasing in JavaClasConverter, JavaFieldConverter and | |
451 | JavaMethodConverter. While it is not possible to enable this in general, new constructors have been added to these | |
452 | converters and an example in the acceptance tests (AliasTest).</li> | |
453 | <li>JIRA:XSTR-742: Register CompositeClassLoader in Java 7 as parallel capable.</li> | |
454 | <li>JIRA:XSTR-743: Support proxy collections of Hibernate Envers.</li> | |
455 | <li>Fix NPE in AttributeMapper.shouldLookForSingleValueConverter if parameters fieldName and definedIn are null.</li> | |
456 | <li>Implicit type argument can be omitted when registering converters with @XStreamConverter annotation.</li> | |
457 | </ul> | |
458 | ||
459 | <h2>API changes</h2> | |
460 | ||
461 | <ul> | |
462 | <li>Added c.t.x.converters.extended.NamedCollectionConverter for free element names in collections.</li> | |
463 | <li>Added c.t.x.converters.extended.NamedMapConverter for free element names in maps.</li> | |
464 | <li>Added c.t.x.io.xml.StandardStaxDriver to use the StAX implementation delivered with the Java 6 runtime.</li> | |
465 | <li>Deprecated c.t.x.io.xml.SjsxpStaxDriver to select the internal StAX implementation of Oracle.</li> | |
466 | <li>Added static methods getStaxInputFactory and getStaxOutputFactory to c.t.x.core.JVM as returning the | |
467 | implementations of javax.xml.stream.XMLInputFactory (resp. javax.xml.stream.XMLOutputFactory) delivered with the Java | |
468 | Runtime since Java 6.</li> | |
469 | <li>Added c.t.x.core.ClassLoaderReference.</li> | |
470 | <li>Added constructors taking an additional Class argument for c.t.x.converters.collections.CollectionConverter | |
471 | and c.t.x.converters.collections.MapConverter.</li> | |
472 | <li>Added constructors taking a ClassLoaderReference instead of a ClassLoader and deprecated the ones taking the | |
473 | ClassLoader: | |
474 | <ul> | |
475 | <li>c.t.x.XStream</li> | |
476 | <li>c.t.x.converters.extended.DynamicProxyConverter</li> | |
477 | <li>c.t.x.converters.extended.JavaClassConverter</li> | |
478 | <li>c.t.x.converters.extended.JavaFieldConverter</li> | |
479 | <li>c.t.x.converters.extended.JavaMethodConverter</li> | |
480 | <li>c.t.x.converters.reflection.CGLIBEnhancedConverter</li> | |
481 | <li>c.t.x.converters.reflection.ExternalizableConverter</li> | |
482 | <li>c.t.x.converters.reflection.SerializableConverter</li> | |
483 | <li>c.t.x.mapper.AnnotationMapper</li> | |
484 | <li>c.t.x.mapper.DefaultMapper</li> | |
485 | </ul> | |
486 | </li> | |
487 | <li>Added static methods newReflectionProvider, isAWTAvailable, isSQLAvailable and isSwingAvailable to | |
488 | c.t.x.core.JVM as replacement for the deprecated non-static methods.</li> | |
489 | <li>Deprecated c.t.x.core.JVM() and all non-static methods.</li> | |
490 | <li>Added method useImplicitType to c.t.x.annotations.XStreamConverter.</li> | |
491 | <li>JIRA:XSTR-722: Added c.t.x.converters.reflection.ReflectionProvider.getFieldOrNull(Class, String).</li> | |
492 | <li>Deprecated c.t.x.converters.reflection.ReflectionProvider.fieldDefinedInClass(Class, String) in favor of new | |
493 | c.t.x.converters.reflection.ReflectionProvider.getFieldOrNull(Class, String).</li> | |
494 | <li>Deprecated constructor c.t.x.converters.extended.RegexPatternConverter(Converter) in favor of | |
495 | c.t.x.converters.extended.RegexPatternConverter().</li> | |
496 | <li>Deprecated default constructor of c.t.x.converters.extended.FontConverter in favor of | |
497 | c.t.x.converters.extended.FontConverter(Mapper).</li> | |
498 | <li>Deprecated constructor c.t.x.converters.extended.ThrowableConverter(Converter) in favor of | |
499 | c.t.x.converters.extended.ThrowableConverter(ConverterLookup).</li> | |
500 | <li>Deprecated class c.t.x.converters.reflection.SelfStreamingInstanceChecker and moved original implementation | |
501 | into c.t.x.core.util, since it is internal.</li> | |
502 | <li>Deprecated interface c.t.x.mapper.AnnotationConfiguration.</li> | |
503 | </ul> | |
504 | ||
505 | <h1 id="1.4.4">1.4.4</h1> | |
506 | ||
507 | <p>Released January 19, 2013.</p> | |
508 | ||
509 | <h2>Minor changes</h2> | |
510 | ||
511 | <ul> | |
512 | <li>JIRA:XSTR-709: Locks up on Mac with Apple JVM due to unwanted initialization of AWT.</li> | |
513 | <li>JIRA:XSTR-711: DateConverter cannot handle dates in different era.</li> | |
514 | <li>JIRA:XSTR-741: ToAttributedValueConverter fails to write enums as attributes.</li> | |
515 | <li>JIRA:XSTR-712: HibernateMapper throws NPE if a collection contains null.</li> | |
516 | <li>DateConverter supports now localized formats.</li> | |
517 | <li>JIRA:XSTR-710: JsonWriter does not write BigInteger and BigDecimal as number values.</li> | |
518 | <li>JIRA:XSTR-708: SqlTimestampConverter does not ignore timezone.</li> | |
519 | <li>JIRA:XSTR-707: Creation of XmllPullParser with the XmlPullParserFactory may fail in OSGi environment.</li> | |
520 | <li>JIRA:XSTR-705: Unnecessary synchronization accessing the field cache decreases performance.</li> | |
521 | <li>JIRA:XSTR-714: Fields not found when XStream12FieldKeySorter used.</li> | |
522 | </ul> | |
523 | ||
524 | <h2>API changes</h2> | |
525 | ||
526 | <ul> | |
527 | <li>Deprecated method c.t.x.core.util.JVM.is14(), c.t.x.core.util.JVM.is15() and c.t.x.core.util.JVM.is16().</li> | |
528 | </ul> | |
529 | ||
530 | <h1 id="1.4.3">1.4.3</h1> | |
531 | ||
532 | <p>Released July 17, 2012.</p> | |
533 | ||
534 | <h2>Major changes</h2> | |
535 | ||
536 | <ul> | |
537 | <li>Support java.util.concurrent.ConcurrentHashMap with the MapConverter. This will also avoid a bug in JRockit | |
538 | JDK reported in JIRA:XSTR-608.</li> | |
539 | <li>JIRA:XSTR-699: Support for Hibernate 4 with XStream's Hibernate module as default for Java 6 or higher.</li> | |
540 | </ul> | |
541 | ||
542 | <h2>Minor changes</h2> | |
543 | ||
544 | <ul> | |
545 | <li>JVM.loadClass will now also initialize the loaded class and ignore any occurring LinkageError.</li> | |
546 | <li>JIRA:XSTR-596: SubjectConverter will be no longer registered if initialization of javax.security.auth.Subject | |
547 | fails.</li> | |
548 | <li>JIRA:XSTR-683: Inheritance of implicit collections, arrays or maps is dependent on declaration sequence.</li> | |
549 | <li>Inherited implicit collections, arrays or maps can be overwritten with own definition in subtype.</li> | |
550 | <li>JIRA:XSTR-688: Cannot omit XML elements from derived fields.</li> | |
551 | <li>JIRA:XSTR-696: Ill-formed JSON generated, because JSON writer is fed with type of declaring field instead of | |
552 | the real object's type.</li> | |
553 | <li>JIRA:XSTR-685: Deserialization from file or URL keeps stream open.</li> | |
554 | <li>JIRA:XSTR-684: XML 1.0 character validation fails for characters from 0x10 to 0x1f.</li> | |
555 | <li>JavaBeanConverter supports now instantiation for a specific type and can therefore be used in | |
556 | @XStreamConverter annotation.</li> | |
557 | <li>SerializableConverter is broken if the serialized type is the default implementation.</li> | |
558 | <li>Method marshalUnserializableParent of SerializableConverter is protected now to skip the default mechanism in | |
559 | a derived converter that uses the default constructor to create the original type (as an alternative for | |
560 | JIRA:XSTR-695).</li> | |
561 | <li>FieldDictionary may call sort of FieldKeySorter implementation with wrong type as key.</li> | |
562 | <li>Sometimes DependencyInjectionFactory tries to instantiate objects with mismatching constructor arguments.</li> | |
563 | <li>HSQLDB has to be a test dependency only for XStream's Hibernate module.</li> | |
564 | </ul> | |
565 | ||
566 | <h1 id="1.4.2">1.4.2</h1> | |
567 | ||
568 | <p>Released November 3, 2011.</p> | |
569 | ||
570 | <h2>Major changes</h2> | |
571 | ||
572 | <ul> | |
573 | <li>XStream libraries can be used now directly in Android, therefore support of Java 1.4.2 has been stopped with | |
574 | the delivery. Anyone who needs a version for Java 1.4.2 can build it easily from source, this build is still | |
575 | supported and part of CI.</li> | |
576 | <li>JIRA:XSTR-675: New extended HierarchicalStreamReader interface with peekNextChild method. All XStream readers | |
577 | implement the new interface (by Nikita Levyankov).</li> | |
578 | <li>JIRA:XSTR-673: Collections.EMPTY_LIST, Collections.EMPTY_SET and Collections.EMPTY_MAP supported with own | |
579 | alias and defined as immutable.</li> | |
580 | <li>JIRA:XSTR-631: Collections.singletonList(), Collections.singletonSet() and Collections.singletonMap() | |
581 | supported with own alias and own converters.</li> | |
582 | <li>JIRA:XSTR-406 + JIRA:XSTR-663: Support additional parameters for XStreamConverter annotation (e.g. to declare | |
583 | a ToAttributedValueConverter).</li> | |
584 | </ul> | |
585 | ||
586 | <h2>Minor changes</h2> | |
587 | ||
588 | <ul> | |
589 | <li>WstxDriver did not trigger Woodstox, but BEA StAX implementation.</li> | |
590 | <li>JIRA:XSTR-260: PrettyPrintWriter does not handle tab and new line characters in attributes.</li> | |
591 | <li>JIRA:XSTR-667: Cannot serialize empty list with JsonHierarchicalStreamDriver.</li> | |
592 | <li>JIRA:XSTR-661: TreeMarshaller.CircularReference is not a ConversionException.</li> | |
593 | <li>JIRA:XSTR-562: StAX: Namespace attribute is not written in non-repairing mode for second sibling.</li> | |
594 | <li>JIRA:XSTR-664: ClassCastException in HibernatePersistentSortedSetConverter and | |
595 | HibernatePersistentSortedMapConverter.</li> | |
596 | <li>JIRA:XSTR-674: Recreate binary compatibility with 1.3.x series for method | |
597 | CustomObjectInputStream.getInstance(...).</li> | |
598 | <li>JIRA:XSTR-671: CannotResolveClassException should accept cause.</li> | |
599 | <li>JIRA:XSTR-672: Collections.EMPTY_LIST, Collections.EMPTY_SET and Collections.EMPTY_MAP used for in implicit | |
600 | collection should not throw ReferencedImplicitElementException.</li> | |
601 | <li>JIRA:XSTR-676: Introduce MissingFieldException thrown at deserialization time indicating a missing field or | |
602 | property (by Nikita Levyankov).</li> | |
603 | <li>Add length limit for cached strings in StringConverter, 38 characters by default.</li> | |
604 | <li>The JsonHierarchicalStreamDriver and the JsonWriter did not support the inherited NameCoder instance.</li> | |
605 | <li>Add BinaryStreamDriver.</li> | |
606 | <li>NPE in XppDomComparator.</li> | |
607 | <li>Dom4JXmlWriter fails to flush the underlying writer.</li> | |
608 | <li>Known control characters are not encoded with JsonWriter as proposed at json.org.</li> | |
609 | <li>Detect duplicate property processing in JavaBeanConverter and throw DuplicatePropertyException instead of | |
610 | clobbering silently.</li> | |
611 | <li>Allow access to Mapper and JavaBeanProvider in derived instances of JavaBeanConverter.</li> | |
612 | <li>DependencyInjectionFactory failed to create instance when a matching constructor was found, but a default | |
613 | constructor was also present.</li> | |
614 | </ul> | |
615 | ||
616 | <h2>API changes</h2> | |
617 | ||
618 | <ul> | |
619 | <li>Added interface c.t.x.io.ExtendedHierarchicalStreamReader extending c.t.x.io.HierarchicalStreamReader. All | |
620 | implementations of c.t.x.io.HierarchicalStreamReader will implement also the extended interface.</li> | |
621 | <li>Added c.t.x.converters.reflection.MissingFieldException derived from | |
622 | c.t.x.converters.reflection.ObjectAccessException and used instead when the unmarshalling process should write a | |
623 | field or property that is missing and does not exist.</li> | |
624 | <li>Added methods c.t.x.io.path.PathTracker.peekElement(), c.t.x.io.path.PathTracker.peekElement(int), and | |
625 | c.t.x.io.path.PathTracker.depth().</li> | |
626 | <li>Deprecated method c.t.x.core.ReferencingMarshallingContext.currentPath(). Wrong approach.</li> | |
627 | </ul> | |
628 | ||
629 | <h1 id="1.4.1">1.4.1</h1> | |
630 | ||
631 | <p>Released August 11, 2011.</p> | |
632 | ||
633 | <h2>Major changes</h2> | |
634 | ||
635 | <ul> | |
636 | <li>JIRA:XSTR-659: Use again Xpp3 as default parser, now with additional XmlPullParser API as regular dependency | |
637 | for the XPP factory. Only standard kXML2 package contains the XPP factory, but not the minimal kXML2 version.</li> | |
638 | </ul> | |
639 | ||
640 | <h2>Minor changes</h2> | |
641 | ||
642 | <ul> | |
643 | <li>Add utility class c.t.x.io.xml.xppdom.XppFactory and a path tracking comparator for XppDom.</li> | |
644 | </ul> | |
645 | ||
646 | <h1 id="1.4">1.4</h1> | |
647 | ||
648 | <p>Released August 6, 2011.</p> | |
649 | ||
650 | <h2>Major changes</h2> | |
651 | ||
652 | <ul> | |
653 | <li>Java 7 is detected and supported.</li> | |
654 | <li>JIRA:XSTR-542: The XppDriver uses now the official XmlPullParser API to locate an available parser using the | |
655 | XmlPullParserFactory. This allows the usage of XPP technology with XStream in Android.</li> | |
656 | <li>Additional explicit XPP drivers for the Xpp3 and kXML2 implementations.</li> | |
657 | <li>Additional explicit XPP DOM drivers for the Xpp3 and kXML2 implementations.</li> | |
658 | <li>kXML2 is now the preferred parser implementation, Xpp3 is optional.</li> | |
659 | <li>Additional explicit StAX drivers for Woodstox, BEA StAX and SJSXP of the JDK 6 implementations.</li> | |
660 | <li>JDK 1.3 is no longer officially supported.</li> | |
661 | <li>JIRA:XSTR-377+JIRA:XSTR-226: New artifact xstream-hibernate with converters and mapper to process Hibernate | |
662 | object graphs (by Costin Leau, Konstantin Pribluda and in special Jaime Metcher).</li> | |
663 | <li>New NameCoder interface and implementations to support a generic name translation between names from the | |
664 | object graph and a target format. The new XmlFriendlyNameCoder replaces the XmlFriendlyReplacer used for XML only.</li> | |
665 | <li>JIRA:XSTR-553: Support annotations in Android.</li> | |
666 | <li>JIRA:XSTR-556: DateConverter uses format with 3-letter time zones that are ambiguous. Therefore it will now | |
667 | always use UTC to write dates. Unmarshalled dates are not affected as long as they contain a time zone.</li> | |
668 | <li>The type java.lang.reflect.Field is now handled by an own converter, that can still read the old format.</li> | |
669 | <li>JIRA:XSTR-490: Provide path in Converter for contexts that track the path.</li> | |
670 | <li>JIRA:XSTR-592+JIRA:XSTR-579: OmitField respected at deserialization time even for existing fields.</li> | |
671 | <li>JIRA:XSTR-593: Direct support for java.net.URI instances (by Carlos Roman).</li> | |
672 | <li>JIRA:XSTR-615+JIRA:XSTR-580: Dynamic proxies cannot be referenced recursively.</li> | |
673 | <li>JIRA:XSTR-547: Wrong class loader used for Serializable types deserialized with an ObjectInputStream.</li> | |
674 | <li>JIRA:XSTR-341: Support of implicit arrays.</li> | |
675 | <li>JIRA:XSTR-306+JIRA:XSTR-406: Support of implicit maps.</li> | |
676 | <li>JIRA:XSTR-344: New ToAttributedValueConverter to allow conversion of an element with string body and | |
677 | attributes.</li> | |
678 | <li>JIRA:XSTR-573: SortedSet added with TreeSet as the default implementation.</li> | |
679 | <li>JIRA:XSTR-576: TreeMap and TreeSet no longer add an element without comparator (by Jason Greanya), solves | |
680 | also invalid format with JSON for such objects (JIRA:XSTR-640).</li> | |
681 | </ul> | |
682 | ||
683 | <h2>Minor changes</h2> | |
684 | ||
685 | <ul> | |
686 | <li>JIRA:XSTR-612: Improve extensibility of c.t.x.javabean.* package by reintroducing a PropertyDictionary with | |
687 | the additional interface PropertySorter.</li> | |
688 | <li>JIRA:XSTR-591: EnumSingleValueConverter did use toString() instead of name() to create the String | |
689 | representation of an enum value.</li> | |
690 | <li>JIRA:XSTR-618: Add Oracle as vendor used for recent JRockit versions and former Sun JDK.</li> | |
691 | <li>JIRA:XSTR-656: DomReader and Dom4JReader do not escape attribute names retrieving their values.</li> | |
692 | <li>JIRA:XSTR-604: StringConverter's cache may cause an OutOfMemoryException.</li> | |
693 | <li>JIRA:XSTR-577: Skip UTF-8 BOM in XmlHeaderAwareReader.</li> | |
694 | <li>The XppReader no longer uses a BufferedReader.</li> | |
695 | <li>JIRA:XSTR-543: Better deserialization support of the defined-in system attribute in combination with field | |
696 | aliases.</li> | |
697 | <li>JIRA:XSTR-551: Deprecated XStream.InitializationException still thrown instead of InitializationException.</li> | |
698 | <li>JIRA:XSTR-655: JsonWriter generates invalid JSON for Externalizable types.</li> | |
699 | <li>JIRA:XSTR-540: Support Jettison-based configuration of JettisonMappedXmlDriver (by Doug Daniels).</li> | |
700 | <li>JIRA:XSTR-633: JettisonMappedXmlDriver escaped property names according escape rules for XML tag names.</li> | |
701 | <li>JIRA:XSTR-625: Optionally ignore XStream's hints for Jettison to generate JSON arrays (by Dejan Bosanac).</li> | |
702 | <li>JIRA:XSTR-605: Upgrade to Jettison 1.2 (for Java 5 or higher).</li> | |
703 | <li>New JsonWriter.EXPLICIT_MODE generating JSON that enforces property sequence.</li> | |
704 | <li>JIRA:XSTR-552: Improve performance of ReflectionProvider (by Keith Kowalczykowski).</li> | |
705 | <li>JIRA:XSTR-559: Improve performance of Sun14ReflectionProvider (by Keith Kowalczykowski).</li> | |
706 | <li>JIRA:XSTR-564: Improve performance of AnnotationMapper (by Keith Kowalczykowski).</li> | |
707 | <li>JIRA:XSTR-563: Use ReferenceQueue for cleaning-up WeakReferences in ObjectIdDictionary (by Keith | |
708 | Kowalczykowski).</li> | |
709 | <li>JIRA:XSTR-646: Cache of Sun14ReflectionProvider consumes more PermGen space than necessary.</li> | |
710 | <li>JIRA:XSTR-636: Ineffective cache in FieldDictionary using WeakHashMap with WeakReference values.</li> | |
711 | <li>Ineffective cache for SerializationMethodInvoker (related to JIRA:XSTR-636).</li> | |
712 | <li>Introduction of Caching interface implemented by all types in XStream that create local caches that may have | |
713 | to be flushed manually.</li> | |
714 | <li>Avoid excessive creation of AbstractPullReader.Event objects by using a pool.</li> | |
715 | <li>Possibility to generate XPath expressions that select always a single node instead of a node list.</li> | |
716 | <li>Cannot reference replaced object using ID references.</li> | |
717 | <li>Implicit collection functionality will no longer use custom collection converters that may write tags that | |
718 | are not recognized at deserialization time again.</li> | |
719 | <li>JIRA:XSTR-654: Unmarshal fails when an implicit collection is defined and an element is named equal to the | |
720 | field.</li> | |
721 | <li>JIRA:XSTR-574: AbstractReferenceUnmarshaller cannot handle null values for references.</li> | |
722 | <li>Improve exception output in case of a missing field.</li> | |
723 | <li>JIRA:XSTR-555: StAX driver tests do not honor repairing mode.</li> | |
724 | <li>JIRA:XSTR-570: The @XStreamConverter provides now also the current type as possible constructor argument.</li> | |
725 | <li>JIRA:XSTR-629: Deserialization of Externalizable with non-accessible default constructor fails.</li> | |
726 | <li>JIRA:XSTR-571: Cannot serialize synchronized RandomAccessList types.</li> | |
727 | <li>JIRA:XSTR-583: BinaryDriver fails to handle Strings with more than 64K bytes.</li> | |
728 | <li>JIRA:XSTR-639: Cannot omit field at deserialization if the field has a class attribute.</li> | |
729 | <li>JIRA:XSTR-599: EncodedByteArrayConverter should implement SingleValueConverter.</li> | |
730 | <li>JIRA:XSTR-584: Race condition in XmlFriendlyReplacer.</li> | |
731 | <li>JIRA:XSTR-623: XmlFriendlyReplacer may write illegal name characters (by Michael Schnell).</li> | |
732 | <li>The ConversionException hides information if its ErrorWriter contains the added key already.</li> | |
733 | <li>JIRA:XSTR-598: Attribute "defined-in" was wrongly evaluated for other attributes.</li> | |
734 | <li>JIRA:XSTR-650: Possible NullPointerException at initialization on platforms like Android that do not support | |
735 | all types of the JDK.</li> | |
736 | <li>JIRA:XSTR-652: Initialization of XStream fails if DurationConverter constructor throws a | |
737 | javax.xml.datatype.DatatypeConfigurationException. Converter will no longer handle Duration types if no instance of | |
738 | the internal DatatypeFactory can be created.</li> | |
739 | <li>Constructor DocumentWriter(Element) forgets the provided element.</li> | |
740 | <li>JIRA:XSTR-597: Optimize AbstractReflectionConverter.</li> | |
741 | <li>Introduce Caching interface to flush the internal cache of specific components.</li> | |
742 | <li>Support JIRA:XSTR-407 also for IBM JRE 1.6 and greater.</li> | |
743 | <li>java.nio.charset.Charset's converter was added as immutable type instead of the type itself.</li> | |
744 | <li>java.util.Currency added as immutable type.</li> | |
745 | <li>Fix selection of same parameter types in DependencyInjectionFactory.</li> | |
746 | <li>Deprecation of c.t.x.javabean.PropertyDictionary has been countermanded.</li> | |
747 | </ul> | |
748 | ||
749 | <h2>API changes</h2> | |
750 | ||
751 | <ul> | |
752 | <li>Any deprecated stuff of the 1.2.x releases has been removed.</li> | |
753 | <li>Deprecated constructors of c.t.x.converters.reflection.SerializableConverter, | |
754 | c.t.x.converters.reflection.ExternalizableConverter and c.t.x.converters.reflection.CGLIBEnhancedConverter; new | |
755 | versions take an additional argument for class loader (as a result for JIRA:XSTR-547).</li> | |
756 | <li>Deprecated constructors of c.t.x.io.xml.XppReader, new versions take an additional argument for the | |
757 | XmlPullParser.</li> | |
758 | <li>Deprecated c.t.x.io.xml.XppReader.createParser(), the XPP parser is now created by the driver.</li> | |
759 | <li>Package c.t.x.io.xml.xppdom is now part of the official API.</li> | |
760 | <li>c.t.x.io.xml.xppdom.Xpp3Dom and c.t.x.io.xmlxpp.dom.Xpp3DomBuilder have been deprecated. Functionality is | |
761 | merged in c.t.x.io.xml.xppdom.XppDom.</li> | |
762 | <li>Deprecated c.t.x.mapper.XStream11XmlFriendlyMapper and c.t.x.mapper.AbstractXmlFriendlyMapper.</li> | |
763 | <li>Added interface c.t.x.core.ReferencingMarshallingContext which is implemented by all referencing marshallers.</li> | |
764 | <li>Added interface c.t.x.io.naming.NameCoder and implementations.</li> | |
765 | <li>Deprecated c.t.x.io.xml.XmlFriendlyReplacer, c.t.x.io.xml.XmlFriendlyReader and | |
766 | c.t.x.io.xml.XmlFriendlyWriter.</li> | |
767 | <li>Deprecated c.t.x.io.xml.AbstractXmlDriver, c.t.x.io.xml.AbstractXmlReader and c.t.x.io.xml.AbstractXmlWriter, | |
768 | added c.t.x.io.AbstractDriver, c.t.x.io.AbstractReader and c.t.x.io.AbstractWriter instead.</li> | |
769 | <li>Deprecated all constructors of Driver, Reader and Writer implementations that take a XmlFriendlyReplacer as | |
770 | argument, added constructors taking a NameCoder instead.</li> | |
771 | <li>Added interface com.thoughtworks.xstream.converters.ErrorReporter to allow other types to report also errors | |
772 | (apart from a HierarchicalStreamReader). Any converter and the parent object of the currently deserialized element | |
773 | may provide additional error information now.</li> | |
774 | </ul> | |
775 | ||
776 | <h1 id="1.3.1">1.3.1</h1> | |
777 | ||
778 | <p>Released December 6, 2008.</p> | |
779 | ||
780 | <p class="highlight">CGLIB support must be explicitly activated now. The decision has been made due to possible | |
781 | problems using an own classloader and because of ongoing complaints about occurring exceptions in the | |
782 | CGLIBEnhancedConverter at XStream initialization although they are caused by incompatible ASM versions on the user's | |
783 | classpath (JIRA:XSTR-469, JIRA:XSTR-513 and JIRA:XSTR-518).</p> | |
784 | ||
785 | <p class="highlight">XStream uses some attributes on its own. Until now it was possible to use | |
786 | XStream.aliasAttribute to define a different name. This does still work but is deprecated for system attributes. Use | |
787 | the new call XStream.aliasSystemAttribute for such an alias.</p> | |
788 | ||
789 | <h2>Major changes</h2> | |
790 | ||
791 | <ul> | |
792 | <li>JIRA:XSTR-515: CGLIB support is no longer activated automatically and has to be <a | |
793 | href="faq.html#Serialization_CGLIB">explicitly turned on</a>. | |
794 | </li> | |
795 | <li>JIRA:XSTR-448: Separated system attributes and user defined attributes for aliases.</li> | |
796 | <li>JIRA:XSTR-55: Ability to alias a package name.</li> | |
797 | <li>JIRA:XSTR-434: New JsonWriter instead of JsonHierarchicalStreamWriter with mode to strip root node of | |
798 | generated JSON (by Paul Hammant).</li> | |
799 | <li>Support for Diablo JDK on FreeBSD (by Reto Bachmann-Gmür).</li> | |
800 | <li>JIRA:XSTR-495: New PersistenceStrategy instead of StreamStrategy (based on the code and comments by Alexander | |
801 | Radzin).</li> | |
802 | </ul> | |
803 | ||
804 | <h2>Minor changes</h2> | |
805 | ||
806 | <ul> | |
807 | <li>Support special Jettison functionality for JSON to detect collections or arrays with one element introduced | |
808 | with Jettison 1.0.</li> | |
809 | <li>JIRA:XSTR-493: Using attributes for fields with XML-unfriendly names results in NPE at deserialization.</li> | |
810 | <li>JIRA:XSTR-497: Unsafe operation with WeakHashMap can raise a NPE in Sun14ReflectionProvider.</li> | |
811 | <li>JIRA:XSTR-423: Support of CGLIB enhanced proxies with multiple callbacks if the proxy uses a factory (CGLIB | |
812 | default).</li> | |
813 | <li>JIRA:XSTR-536: XStream silently ignores unknown elements.</li> | |
814 | <li>JIRA:XSTR-503: Omitted properties in JavaBeans are requested at serialization (by Kevin Conaway).</li> | |
815 | <li>Fix possible memory leak in ObjectIdMap for JVMs that provide real distinct identity hash codes (happened on | |
816 | amd64 system).</li> | |
817 | <li>JIRA:XSTR-480: Aliasing of array types.</li> | |
818 | <li>JIRA:XSTR-515: The SubjectConverter and DurationConverter are only registered if the converted class is part | |
819 | of the JDK, otherwise they must be registered now explicitly.</li> | |
820 | <li>JIRA:XSTR-504: XmlHeaderAwareReader fails with improper sized PushbackInputStream.</li> | |
821 | <li>JIRA:XSTR-489: @XStreamConverter supports now also SingleValueConverter implementations.</li> | |
822 | <li>JIRA:XSTR-481: @XStreamConverter and @XStreamAsAttribute can be used together (as a result of JIRA:XSTR-489).</li> | |
823 | <li>JIRA:XSTR-519: New annotation @XStreamInclude to force annotation detection of included types (by Seven | |
824 | Sparling).</li> | |
825 | <li>JIRA:XSTR-469: Support custom converters for enum types.</li> | |
826 | <li>JIRA:XSTR-502: ClassNotFoundException even if writeReplace returns proper object.</li> | |
827 | <li>JIRA:XSTR-529: NullPointerException for null elements in implicit lists.</li> | |
828 | <li>JIRA:XSTR-517: Miscellaneous performance improvements (by Tatu Saloranta).</li> | |
829 | <li>JIRA:XSTR-525: JsonHierarchicalStreamDriver writes invalid JSON in case of system attribute.</li> | |
830 | <li>JIRA:XSTR-535: Mode to allow plain values as result for JSON without root node.</li> | |
831 | <li>JIRA:XSTR-531: Possibility to omit system attributes.</li> | |
832 | <li>JIRA:XSTR-508: Fix marshalling error for nested serializable objects with own writeReplace/readResolve | |
833 | methods.</li> | |
834 | <li>JIRA:XSTR-507: Advanced ReferenceByIdMarshaller uses id of the current object if available.</li> | |
835 | <li>JIRA:XSTR-485: Check reference for valid object when deserializing.</li> | |
836 | <li>Fix classloader problem, Xpp3 parser cannot be loaded within a web application.</li> | |
837 | <li>Dependencies have been updated to latest versions of JDOM, Jettison, Joda Time, and Woodstox. Note for Maven | |
838 | builds that the <em>groupId</em> of JDOM has changed. | |
839 | </li> | |
840 | <li>Fix possible IndexOutOfBoundsException creating returning the message for a ConversionException.</li> | |
841 | <li>JIRA:XSTR-495: StreamStrategy cannot handle key with value <em>null</em>. | |
842 | </li> | |
843 | </ul> | |
844 | ||
845 | <h2>API changes</h2> | |
846 | ||
847 | <ul> | |
848 | <li>Deprecated c.t.x.io.json.JsonHierarchicalStreamWriter in favour of c.t.x.io.json.JsonWriter.</li> | |
849 | <li>c.t.x.mapper.EnumMapper no longer derives from the c.t.x.mapper.AttributeMapper as it has been before version | |
850 | 1.3. Therefore the new constructor has been deprecated in favour of the old one.</li> | |
851 | <li>c.t.x.mapper.Mapper.getConverterFromAttribute(Class, String) has been deprecated in favour of | |
852 | c.t.x.mapper.Mapper.getConverterFromAttribute(Class, String, Class) taking the type as third argument that should be | |
853 | handled by the converter.</li> | |
854 | <li>c.t.x.core.ReferenceByIdMarshaller.IdGenerator.next() has now the current object as argument.</li> | |
855 | <li>New c.t.x.persistence.PersistenceStrategy and c.t.x.persistence.FilePersistenceStrategy.</li> | |
856 | <li>Deprecated c.t.x.persistence.StreamStrategy and c.t.x.persistence.FileStreamStrategy.</li> | |
857 | </ul> | |
858 | ||
859 | <h1 id="1.3">1.3</h1> | |
860 | ||
861 | <p>Released February 27, 2008.</p> | |
862 | ||
863 | <h2>Major changes</h2> | |
864 | ||
865 | <ul> | |
866 | <li>ReflectionConverter writes now the fields of the parent classes first.</li> | |
867 | <li>Support for Converter definition at field level.</li> | |
868 | <li>Refactoring of Annotation support, invent auto-detection mode.</li> | |
869 | <li>Annotated converters are no longer detected automatically, all annotations are now handled in the same way.</li> | |
870 | <li>JIRA:XSTR-334: XStream will deserialize directly from a file or URL. Some parser take advantage of these | |
871 | objects to define a SystemId used to resolve further references in XML, schema or DTD. Appropriate createReader | |
872 | methods have been added to c.t.x.io.HierarchicalStreamDriver.</li> | |
873 | <li>JIRA:XSTR-261: All c.t.x.io.HierarchicalStreamDriver implementations respect now the encoding of an XML | |
874 | header if read from an InputStream.</li> | |
875 | <li>DomDriver does no longer use explicitly UTF-8 by default, DomReader will therefore respect the encoding | |
876 | defined in the XML header or use native encoding</li> | |
877 | <li>JIRA:XSTR-415: JavaBeanConverter uses now BeanIntrospection (by Hinse ter Schuur).</li> | |
878 | <li>JIRA:XSTR-424: DateConverter uses now by default SimpleDateFormat instances in non-lenient mode.</li> | |
879 | <li>JIRA:XSTR-386: SingleValueConverter that utilizes PropertyEditor implementations (by Jukka Lindström).</li> | |
880 | <li>JIRA:XSTR-427: Converter for javax.xml.datatype.Duration (by John Kristian).</li> | |
881 | <li>JIRA:XSTR-305: Field alias inheritance (by David Blevins).</li> | |
882 | <li>XStream failed to initialize in environments without AWT or SQL classes.</li> | |
883 | <li>JIRA:XSTR-420: XPath of references are not XmlFriendly encoded.</li> | |
884 | <li>JIRA:XSTR-473: String "\0" serialized as invalid XML, support compliant behaviour according XML | |
885 | version.</li> | |
886 | <li>JIRA:XSTR-431: Direct support of enhanced mode for SAP JVM (thanks to Norbert Kuck by SAP).</li> | |
887 | <li>JIRA:XSTR-437: Static cache in annotation processing causes failing OSGi bundles.</li> | |
888 | <li>JIRA:XSTR-279+JIRA:XSTR-335: Annotations are not inherited from parent class.</li> | |
889 | <li>Fix StringConverter using a WeakHashMap with strong references in its value.</li> | |
890 | <li>JIRA:XSTR-403: Attributes are no longer written with JSONHierarchicalStreamDriver if current object is a | |
891 | collection.</li> | |
892 | <li>JIRA:XSTR-456: New LookAndFeelConverter handling LookAndFeel implementations with reflection.</li> | |
893 | <li>JIRA:XSTR-462: CachingMapper keeps direct class references.</li> | |
894 | <li>JIRA:XSTR-411: JsonHierarchicalStreamDriver does not escape characters according RFC 4627.</li> | |
895 | <li>JsonHierarchicalStreamDriver writes wrong brackets around complex Java types with a single value.</li> | |
896 | <li>JsonHierarchicalStreamDriver writes attribute names with a leading '@'.</li> | |
897 | <li>JsonHierarchicalStreamDriver supports Map implementations.</li> | |
898 | </ul> | |
899 | ||
900 | <h2>Minor changes</h2> | |
901 | ||
902 | <ul> | |
903 | <li>Added converter for java.lang.StringBuilder instances.</li> | |
904 | <li>Added converter for java.util.UUID instances.</li> | |
905 | <li>JIRA:XSTR-430: Fields written as attributes could not be omitted.</li> | |
906 | <li>JIRA:XSTR-407: Comparator might access uninitialized elements for TreeSet and TreeMap. A deserialized | |
907 | Comparator is no longer called, the converters expect the elements now in a sorted order.</li> | |
908 | <li>JIRA:XSTR-404, @XStreamImplicit() for ArrayList<ArrayList<Type>> throws ClassCastException.</li> | |
909 | <li>@XStreamContainedType() for ArrayList<ArrayList<Type>> throws ClassCastException.</li> | |
910 | <li>XStreamer did not persist a FieldKeySorter instance.</li> | |
911 | <li>JIRA:XSTR-241: JavaBeanConverter now supports customized BeanProvider.</li> | |
912 | <li>JIRA:XSTR-280: JavaBeanConverter now supports aliasField and omitField (by Hinse ter Schuur).</li> | |
913 | <li>JIRA:XSTR-280: SerializationConverter now supports aliasField and omitField.</li> | |
914 | <li>JIRA:XSTR-429: XmlFriendlyReplacer support for SaxWriter and TraxSource (by Adrian Wilkens).</li> | |
915 | <li>JIRA:XSTR-421: Characters cannot be written as attribute.</li> | |
916 | <li>JIRA:XSTR-426: java.swt.KeyStroke not properly serialized because of a character undefined in unicode.</li> | |
917 | <li>JIRA:XSTR-352: Strings with arbitrary ISO control characters are not properly serialized.</li> | |
918 | <li>JIRA:XSTR-428: An attribute named like a transient field did abort deserialization of following fields.</li> | |
919 | <li>JIRA:XSTR-443: XStream.createObjectOutputStream does not use the given driver to create the | |
920 | HierarchicalStreamWriter.</li> | |
921 | <li>JIRA:XSTR-440: Implicit collections can be declared for fields that are not of Collection type.</li> | |
922 | <li>JIRA:XSTR-446: Handle all primitives and their boxed counterpart for JsonHierarchicalStreamDriver.</li> | |
923 | <li>JIRA:XSTR-447: Fix deserialization of Array class types in JDK 6 (see JDK bug 6500212).</li> | |
924 | <li>JIRA:XSTR-450: @XStreamAlias is ignored if attributes should be used for the field type.</li> | |
925 | <li>JIRA:XSTR-418: Inherited @XStreamAlias is ignored if field should be rendered as attribute.</li> | |
926 | <li>JIRA:XSTR-393: Annotation processing is not consistent.</li> | |
927 | <li>JIRA:XSTR-412: @XStreamImplicit throws NPE for untyped collections.</li> | |
928 | <li>JIRA:XSTR-463: Cannot provide own default Mapper chain.</li> | |
929 | <li>JIRA:XSTR-464: Cannot provide a ClassLoader that is used in all cases.</li> | |
930 | <li>JIRA:XSTR-394: Allow enums as attributes.</li> | |
931 | <li>JIRA:XSTR-413: Support @XStreamAsAttribute for enums.</li> | |
932 | <li>JIRA:XSTR-478: Cannot specify default implementation for polymorphic enum.</li> | |
933 | <li>JIRA:XSTR-419: Treat enums as immutable types.</li> | |
934 | <li>Update annotation tutorial, explain limitations of auto-detection mode.</li> | |
935 | <li>Added copyright notices to all files.</li> | |
936 | <li>StaxWriter.flush did close Stax' XMLStreamWriter instead of flushing it.</li> | |
937 | <li>JIRA:XSTR-471: XStream POMs do no longer declare a repository at all.</li> | |
938 | <li>Calendar object could not be rendered with JSONHierarchicalStreamDriver.</li> | |
939 | <li>JIRA:XSTR-476: Properties can be sorted by key.</li> | |
940 | <li>XStream.createObjectInputStream and XStream.createObjectOutputStream overloaded to support a binary | |
941 | InputStream or OutputStream.</li> | |
942 | <li>JIRA:XSTR-470: Allow transient fields to be optionally deserialized.</li> | |
943 | </ul> | |
944 | ||
945 | <h2>API changes</h2> | |
946 | ||
947 | <ul> | |
948 | <li>c.t.x.annotation.Annotations, c.t.x.annotation.AnnotationReflectionConverter and | |
949 | c.t.x.annotation.AnnotationProvider deprecated. Functionality is integrated in new c.t.x.mapper.AnnotationMapper and | |
950 | accessible with new methods c.t.x.XStream.processAnnotations().</li> | |
951 | <li>New auto-detection mode for annotations, that can be turned on with c.t.x.XStream.autodetectAnnotations()</li> | |
952 | <li>c.t.x.annotation.@XStreamContainedType deprecated, the behaviour is now always active and the annotation | |
953 | therefore superfluous.</li> | |
954 | <li>Due to JIRA:XSTR-421 null characters are no longer written as tag with an attribute (<char | |
955 | null="true"/>), but as empty tag. The old representation is still supported at deserialization.</li> | |
956 | <li>Characters that are not defined in unicode or ISO control characters (expect TAB and LF) are written as | |
957 | numerical entity now.</li> | |
958 | <li>XPath references are now also XML-friendly encoded to match the path exactly. Unencoded references will | |
959 | normally work anyway, but in special cases the exact behaviour of XStream 1.2.x might be necessary. See acceptance | |
960 | tests for XStream 1.2.x compatibility.</li> | |
961 | <li>c.t.x.core.BaseException deprecated in favour of c.t.x.XStreamException as base exception for all exceptions | |
962 | XStream throws.</li> | |
963 | <li>c.t.x.XStream.InitializerException deprecated in favour of c.t.x.InitializerException.</li> | |
964 | <li>New methods get() and keys() in interface c.t.x.converter.ErrorWriter.</li> | |
965 | <li>c.t.x.mapper.XmlFriendlyMapper deprecated, technology is replaced since version 1.2 by | |
966 | c.t.x.io.xml.XmlFriendlyReplacer as part of the different XmlWriter implementations.</li> | |
967 | <li>c.t.x.mapper.Mapper.aliasForAttribute() and c.t.x.mapper.Mapper.attributeForAlias() deprecated, since it | |
968 | provided in reality the combined functionality of c.t.x.mapper.Mapper.serializedMember()/realMember() and | |
969 | c.t.x.mapper.Mapper.getConverterFromItemType().</li> | |
970 | <li>c.t.x.XStream(ReflectionProvider, Mapper, HierarchicalStreamDriver) deprecated, in favour of | |
971 | c.t.x.XStream(ReflectionProvider, HierarchicalStreamDriver, Mapper, ClassLoader).</li> | |
972 | <li>New interface c.t.x.converter.ConverterRegistry to express explicit functionality managing the converters.</li> | |
973 | <li>c.t.x.core.DefaultConverterLookup no longer uses a c.t.x.mapper.Mapper. Therefore the old constructor has | |
974 | been deprecated in favour of a default constructor.</li> | |
975 | <li>Overloaded methods of c.t.x.mapper.Mapper.getConverterFromItemType and | |
976 | c.t.x.mapper.Mapper.getConverterFromAttribute have been deprecated. Only one version has been kept, the | |
977 | implementation can handle all cases now at once and therefore multiple calls to the mapper chain are avoided.</li> | |
978 | <li>c.t.x.mapper.EnumMapper derives now from the c.t.x.mapper.AttributeMapper to support enums as attributes. | |
979 | Therefore the old constructor has been deprecated in favour of one taking an additional | |
980 | c.t.x.converters.ConverterLookup that has to be passed to the new parent.</li> | |
981 | </ul> | |
982 | ||
983 | <p class="highlight">Note, to support a representation of null values in some way, it is absolutely necessary that | |
984 | each converter can handle a null value in its marshalling methods. If you have implemented your own custom converters, | |
985 | try to handle such a case also to prevent incompatibilities in case XStream will provide such values with its next | |
986 | major version.</p> | |
987 | ||
988 | <h1 id="1.2.2">Version 1.2.2</h1> | |
989 | ||
990 | <p>Released May 24, 2007.</p> | |
991 | ||
992 | <p class="hightlight">Note, that next version of XStream will behave slightly different by default. XStream emits | |
993 | all fields in declaration order like Java serialization. But in contrast to Java it will omit the fields of parent | |
994 | classes last while Java serialization emits them first. This makes it difficult to match a given XML schema that | |
995 | defined inherited types or leads sometimes to obscure initialization problems. However, XStream itself will not be | |
996 | affected by the changed order of elements in the XML, any deserialization of current XML representations will work | |
997 | fine. Anyway we will provide with XStream 1.3 a FieldKeySorter implementation that mimics the old behaviour. In the | |
998 | meanwhile you can enforce the new field sorting by installing the NaturalFieldKeySorter.</p> | |
999 | ||
1000 | <h2>Major changes</h2> | |
1001 | ||
1002 | <ul> | |
1003 | <li>JIRA:XSTR-391, Support for writing (and reading) JSON by the new JettisonMappedXmlDriver (by Dejan Bosanac).</li> | |
1004 | <li>New FieldKeySorter interface allows a custom sort order of the XML elements.</li> | |
1005 | <li>JIRA:XSTR-68 and JIRA:XSTR-210, OmitField is now respected at deserialization to ignore removed fields.</li> | |
1006 | </ul> | |
1007 | ||
1008 | <h2>Minor changes</h2> | |
1009 | ||
1010 | <ul> | |
1011 | <li>JIRA:XSTR-387, Fix aliasing of inherited fields.</li> | |
1012 | <li>JIRA:XSTR-395, Fix StringConverter allocating PermGen space.</li> | |
1013 | <li>JIRA:XSTR-368, @XStreamConverter converters should be cached inside the AnnotationReflectionConverter.</li> | |
1014 | <li>JIRA:XSTR-392, @XStreamOmitField can be used to omit fields from the resulting XML (contributed by Chung-Onn | |
1015 | Cheong).</li> | |
1016 | <li>JIRA:XSTR-371, Fix JSONWriter that omits a closing bracket for for fields with null value.</li> | |
1017 | <li>JIRA:XSTR-398, DomDriver ignores given XmlFriendlyReplacer.</li> | |
1018 | <li>JIRA:XSTR-370, Buildable with JDK 6, fix FontConverter for JDK 6.</li> | |
1019 | <li>JIRA:XSTR-382, Support hex and octal number values.</li> | |
1020 | <li>DateConverter did not respect change in TimeZone after first usage.</li> | |
1021 | <li>JIRA:XSTR-375, Support for aliasing native types.</li> | |
1022 | <li>JIRA:XSTR-243 again, XML elements for transient fields are now ignored completely at deserialization.</li> | |
1023 | <li>Release unused object references to keep memory print low.</li> | |
1024 | <li>Support for AWT and SQL is now optional: XStream now works on embedded virtual machines lacking such APIs (by | |
1025 | Nicolas Gros d'Aillon).</li> | |
1026 | <li>Support raw bytes read from the ObjectInputStream.</li> | |
1027 | <li>JIRA:XSTR-373, Support for Hitachi JVM (tested by Yuji Yamano).</li> | |
1028 | <li>JIRA:XSTR-378 and JIRA:XSTR-379, Fix TextAttributeConverter and EnumSetConverter failing on Apache Harmony.</li> | |
1029 | <li>JIRA:XSTR-363, Support of native field order i.e. fields are processed in declaration order base classes | |
1030 | first.</li> | |
1031 | <li>JIRA:XSTR-320, Static field in child may hide non-static field in parent.</li> | |
1032 | </ul> | |
1033 | ||
1034 | <h2>API changes</h2> | |
1035 | ||
1036 | <ul> | |
1037 | <li>JIRA:XSTR-365, Multiple implicit collections with annotations. Deprecated @XStreamImclicitCollection in | |
1038 | favour of @XStreamImplicit declared at field level.</li> | |
1039 | </ul> | |
1040 | ||
1041 | <h1 id="1.2.1">Version 1.2.1</h1> | |
1042 | ||
1043 | <p>Released November 11, 2006.</p> | |
1044 | ||
1045 | <h2>Major changes</h2> | |
1046 | ||
1047 | <ul> | |
1048 | <li>Introduced DocumentWriter interface and generalized functionality for all writer implementations creating a | |
1049 | DOM structure (DOM4J, DOM, JDom, Xom, Xpp3Dom).</li> | |
1050 | <li>Refactored build system to use Maven 2. Ant still supported on XStream Core.</li> | |
1051 | <li>Created separate XStream Benchmark module</li> | |
1052 | </ul> | |
1053 | ||
1054 | <h2>Minor changes</h2> | |
1055 | ||
1056 | <ul> | |
1057 | <li>JIRA:XSTR-346, XStream.getClassMapper() does not return a ClassMapper for the current Mapper.</li> | |
1058 | <li>Fix problem with fields containing a double underscore.</li> | |
1059 | <li>JIRA:XSTR-345, Dom4JWriter adds up attributes.</li> | |
1060 | <li>JIRA:XSTR-336, XStream fails to reference an implicit element.</li> | |
1061 | <li>JIRA:XSTR-337, Annotation cycle bug.</li> | |
1062 | <li>Fix packaging error for the resulting jar building with Maven2.</li> | |
1063 | <li>JIRA:XSTR-339, NPE for attribute null values.</li> | |
1064 | <li>JIRA:XSTR-338, NPE in JSON writer for converters using non-extended HierarchicalStreamWriter.</li> | |
1065 | <li>JIRA:XSTR-357, Fix escaping of values in JSON writer.</li> | |
1066 | <li>JIRA:XSTR-356, Fix unmarshaling error for fields containing proxies.</li> | |
1067 | <li>JIRA:XSTR-349, Fix backward compatibility of Dom4jWriter.</li> | |
1068 | <li>JIRA:XSTR-309, More versatile boolean conversion options (contributed by David Blevins).</li> | |
1069 | <li>Add XStream.getReflectionProvider() to retrieve ReflectionProvider in use.</li> | |
1070 | <li>JIRA:XSTR-358, @XStreamConverter annotation does not call converter constructor.</li> | |
1071 | <li>Website generated using <a href="http://xsite.codehaus.org">XSite</a></li> | |
1072 | </ul> | |
1073 | ||
1074 | <h2>API changes</h2> | |
1075 | ||
1076 | <ul> | |
1077 | <li>Deprecate JDomWriter.getResult() in favour of DocumentWriter.getTopLevelNodes().</li> | |
1078 | <li>Deprecate ThreadSafeSimpleDateFormat, since this is an internal helper and not part of XStream API.</li> | |
1079 | </ul> | |
1080 | ||
1081 | <h1 id="1.2">Version 1.2</h1> | |
1082 | ||
1083 | <p>Released August 18, 2006.</p> | |
1084 | ||
1085 | <h2>Major changes</h2> | |
1086 | ||
1087 | <ul> | |
1088 | <li>JIRA:XSTR-269, Using attributes for fields (contributed by Paul Hammant and Ian Cartwright).</li> | |
1089 | <li>Aliasing of arbitrary attributes.</li> | |
1090 | <li>JIRA:XSTR-50, XStream can now serialize another XStream instance.</li> | |
1091 | <li>JIRA:XSTR-227, XStream has now the XStreamer, that serializes an object together with its XStream instance.</li> | |
1092 | <li>JIRA:XSTR-278, AnnotationConverter for fields (contributed by Guilherme Silveira).</li> | |
1093 | <li>JIRA:XSTR-256, PureJavaReflectionProvider supports now final fields starting with JDK 1.5</li> | |
1094 | <li>JIRA:XSTR-258, Any Collection type can now be declared implicit, the default implementation will be respected | |
1095 | for unmarshaling.</li> | |
1096 | <li>JIRA:XSTR-88, XStream can now write all references as absolute XPath expression.</li> | |
1097 | <li>JIRA:XSTR-62 and JIRA:XSTR-211, New SingeValueConverter allows light weight converters if the value can be | |
1098 | represented by a unique string.</li> | |
1099 | <li>Aliasing of classes of a specific type.</li> | |
1100 | <li>JIRA:XSTR-239, Support for certain types of proxies generated with the CGLIB Enhancer.</li> | |
1101 | <li>JIRA:XSTR-90 and JIRA:XSTR-311, Support for BEA JRockit starting with R25.1.0 (contributed by Henrik | |
1102 | Ståhl of BEA).</li> | |
1103 | </ul> | |
1104 | ||
1105 | <h2>Technology preview</h2> | |
1106 | ||
1107 | <ul> | |
1108 | <li>Experimental binary reader and writer.</li> | |
1109 | <li>Experimental HierarichicalStreamCopier allows streams to be copied from one format to another without the | |
1110 | overhead of serialization.</li> | |
1111 | <li>Experimental JSON support allows streams to be copied from one format to another without the overhead of | |
1112 | serialization (contributed by Paul Hammant).</li> | |
1113 | </ul> | |
1114 | ||
1115 | <h2>Minor changes</h2> | |
1116 | ||
1117 | <ul> | |
1118 | <li>JIRA:XSTR-266, XStream fails to serialize elements of a unserializable class, that is a base class of a | |
1119 | derived class</li> | |
1120 | <li>JIRA:XSTR-236, Priority constants for converter registration are now public</li> | |
1121 | <li>JIRA:XSTR-215, XStream writes now fields in declaration order even for JVMs reporting them in reverse order | |
1122 | like IBM JDK.</li> | |
1123 | <li>JIRA:XSTR-276 and JIRA:XSTR-283, XStream does no longer attempt to create references to implicit element.</li> | |
1124 | <li>JIRA:XSTR-244, Closing a Writer can now be done twice, but any write attempt will later on fail.</li> | |
1125 | <li>JIRA:XSTR-243, Transient fields were unmarshalled from XML.</li> | |
1126 | <li>JIRA:XSTR-250, Providing a mapper to the XStream constructor will no longer result in a NPE.</li> | |
1127 | <li>JIRA:XSTR-281, After registering a new converter, the internal converter cache is now cleared.</li> | |
1128 | <li>JIRA:XSTR-284, XStream checks the object returned by a converter for compatibility.</li> | |
1129 | <li>XStream no longer fails serializing a Throwable without cause when no references shall be written.</li> | |
1130 | <li>Converter for java.awt.font.TextAttribute.</li> | |
1131 | <li>Converter for java.nio.charset.Charset.</li> | |
1132 | <li>JIRA:XSTR-286, XStream detects impossible self serialization and throws now an appropriate | |
1133 | ConversionException.</li> | |
1134 | <li>JIRA:XSTR-291, XomDriver implementation added.</li> | |
1135 | <li>JIRA:XSTR-299, Fix for implicit collections with items using the same name as the field name of the | |
1136 | underlying collection.</li> | |
1137 | <li>JIRA:XSTR-245, Broken XML with custom serialization in certain cases (patch contributed by Cyrille Le Clerc).</li> | |
1138 | <li>JIRA:XSTR-304, Bad handling of repairing namespace flag for StaxDriver (patch contributed by John Kristian).</li> | |
1139 | </ul> | |
1140 | ||
1141 | <h2>API changes</h2> | |
1142 | ||
1143 | <ul> | |
1144 | <li>JIRA:XSTR-252, Refactored support for XML friendly character mapping.</li> | |
1145 | <li>JIRA:XSTR-69, Refactored ReflectionConverter allows simpler subclassing.</li> | |
1146 | <li>Unmarshalling context has now an overloaded version of the method convertAnother to provide the Converter | |
1147 | directly.</li> | |
1148 | <li>Deprecate ClassMapper for Mapper. All methods with a ClassMapper parameter have now a duplicate taking only a | |
1149 | Mapper. The variant with the ClassMapper is deprecated.</li> | |
1150 | <li>Deprecate c.t.x.alias.CannotResolveClassException for c.t.x.mapper.CannotResolveClassException.</li> | |
1151 | <li>Deprecate NameMapper (was not used within XStream anymore anyway).</li> | |
1152 | <li>Deprecate constructor of DefaultMapper taking an alternative name for the class attribute. Use the | |
1153 | aliasAttribute method.</li> | |
1154 | <li>Deprecate attributeForImplementationClass, attributeForClassDefiningField, attributeForReadResolveField, and | |
1155 | attributeForEnumType in favour of the generalized aliasForAttribute in the Mapper interface.</li> | |
1156 | <li>Removed all deprecated stuff from 1.1.x and 1.0.x</li> | |
1157 | <li>JIRA:XSTR-211, A lot of existing (basic) Converters have been refactored to use the new SingleValueConverter | |
1158 | interface.</li> | |
1159 | <li>Dom4JWriter uses now a DocumentFactory and a XMLWriter as constructor arguments.</li> | |
1160 | </ul> | |
1161 | ||
1162 | <h1 id="1.1.3">Version 1.1.3</h1> | |
1163 | ||
1164 | <p>Released January 13, 2006.</p> | |
1165 | ||
1166 | <h2>Major changes</h2> | |
1167 | ||
1168 | <ul> | |
1169 | <li>Added XStream.toXML(OutputStream) and XStream.fromXML(InputStream).</li> | |
1170 | <li>Ability to prevent fields from being serialized by calling XStream.omitField() or by implementing | |
1171 | Mapper.shouldSerializeMember().</li> | |
1172 | <li>Added Converter for Enum, EnumMap and EnumSet</li> | |
1173 | <li>JIRA:XSTR-186, Added BeanConverter (contributed by Andrea Aime)</li> | |
1174 | <li>JIRA:XSTR-246, Added ISO8601SqlTimestampConverter (contributed by Cheong, Chung-Onn)</li> | |
1175 | <li>Added ISO8601GregorianCaledarConverter</li> | |
1176 | <li>JIRA:XSTR-215, Fixed support for IBM JVM (contributed by Gabor Liptak)</li> | |
1177 | <li>Enhanced mode support for Blackdown JDK</li> | |
1178 | <li>JIRA:XSTR-265, support for javax.security.auth.Subject</li> | |
1179 | <li>JIRA:XSTR-233, support for Integer[] arrays</li> | |
1180 | </ul> | |
1181 | ||
1182 | <h2>Minor changes</h2> | |
1183 | ||
1184 | <ul> | |
1185 | <li>Remove unnecessary PrintWriter wrapper in default writers (pointed out by Mathieu Champlon)</li> | |
1186 | <li>Bugfix: EnumSet converter can now deal with empty sets (contributed by Baba Buehler)</li> | |
1187 | <li>Update ISO8601DateConverter to use Joda 1.0</li> | |
1188 | <li>JIRA:XSTR-242, GregorianCalenderConverter saves now the timezone</li> | |
1189 | <li>JIRA:XSTR-247, ISO8601DateConverter now independent on timezone</li> | |
1190 | <li>JIRA:XSTR-263, Circular references with Externalizable objects fail</li> | |
1191 | </ul> | |
1192 | ||
1193 | <h2>API changes</h2> | |
1194 | ||
1195 | <ul> | |
1196 | <li>None.</li> | |
1197 | </ul> | |
1198 | ||
1199 | <h1 id="1.1.2">Version 1.1.2</h1> | |
1200 | ||
1201 | <p>Released April 30, 2005. Most popular feature requests implemented. Java 5 Enum support. Serialization of | |
1202 | JavaBeans using accessors. Aliasing of fields. StAX integration, with namespaces. Improved support on JDK 1.3 and IBM | |
1203 | JDK.</p> | |
1204 | ||
1205 | <h2>Major changes</h2> | |
1206 | ||
1207 | <ul> | |
1208 | <li>JIRA:XSTR-186, Option to serialize JavaBeans using public accessors, rather than private fields (contributed | |
1209 | by Andrea Aime).</li> | |
1006 | 1210 | <li>Ability to alias fields as well as classes, using XStream.addFieldAlias().</li> |
1007 | 1211 | <li>JIRA:XSTR-70, JIRA:XSTR-204 Support for JDK 5 enums (contributed by Eric Snell and Bryan Coleman).</li> |
1008 | 1212 | <li>JIRA:XSTR-206 Clean representation of JDK 5 EnumMap and EnumSet.</li> |
1009 | 1213 | <li>XStream can now be built using JDK 1.3 (previously it required JDK 1.4 to compile, but 1.3 to run).</li> |
1010 | <li>JIRA:XSTR-215, Enhanced mode is now supported on the IBM 1.4 JDK.</li> | |
1011 | <li>The default HierarchicalStreamWriter implementation is supplied by the HierarichicalStreamDriver (as well as the reader).</li> | |
1012 | </ul> | |
1013 | ||
1014 | <h2>Minor changes</h2> | |
1015 | ||
1016 | <ul> | |
1017 | <li>JIRA:XSTR-104 HierarchicalStreamReader now exposes all available attributes to the Converter implementations (contributed by Trygve Laugstol).</li> | |
1018 | <li>Bugfix: Externalizable deserialization supported for objects not at the root of tree.</li> | |
1019 | <li>JavaMethodConverter handles non public methods/constructors (contributed by Kevin Ring).</li> | |
1020 | <li>PropertiesConverter also serializes default properties, if present (contributed by Kevin Ring).</li> | |
1021 | <li>Bugfix: In some cases, XppReader and StaxReader would get confused when calling hasMoreChildren() and getValue() on the same node.</li> | |
1022 | <li>JIRA:XSTR-217, ISO8601DateConverter now requires joda-time-1.2.1</li> | |
1023 | <li>PrettyPrintWriter and CompactWriter may have their text/attribute escaping rules customized by overriding writeText() and writeAttributeValue().</li> | |
1024 | </ul> | |
1025 | ||
1026 | <h2>API changes</h2> | |
1027 | ||
1028 | <ul> | |
1029 | <li>HierarchicalStreamDriver implementations now require a createWriter() method. The simplest implementation is to return a new PrettyPrintWriter.</li> | |
1030 | <li>Introduced ReaderWrapper/WriterWrapper classes to make it easier to wrap (decorate) HierarchicalStreamReader/Writer instances.</li> | |
1031 | </ul> | |
1032 | ||
1033 | <h1 id="1.1.1">Version 1.1.1</h1> | |
1034 | ||
1035 | <p>Released March 7, 2005. Mostly bugfixes and minor feature enhancements.</p> | |
1036 | ||
1037 | <h2>Major changes</h2> | |
1038 | ||
1039 | <ul> | |
1040 | <li>Converters can be registered with a priority, allowing more <i>generic</i> filters to handle classes that don't have more specific converters.</li> | |
1041 | <li>Converters can now access underlying HierarchicalStreamReader/Writer implementations to make implementation specific calls.</li> | |
1214 | <li>JIRA:XSTR-215, Enhanced mode is now supported on the IBM 1.4 JDK.</li> | |
1215 | <li>The default HierarchicalStreamWriter implementation is supplied by the HierarichicalStreamDriver (as well as | |
1216 | the reader).</li> | |
1217 | </ul> | |
1218 | ||
1219 | <h2>Minor changes</h2> | |
1220 | ||
1221 | <ul> | |
1222 | <li>JIRA:XSTR-104 HierarchicalStreamReader now exposes all available attributes to the Converter implementations | |
1223 | (contributed by Trygve Laugstol).</li> | |
1224 | <li>Bugfix: Externalizable deserialization supported for objects not at the root of tree.</li> | |
1225 | <li>JavaMethodConverter handles non public methods/constructors (contributed by Kevin Ring).</li> | |
1226 | <li>PropertiesConverter also serializes default properties, if present (contributed by Kevin Ring).</li> | |
1227 | <li>Bugfix: In some cases, XppReader and StaxReader would get confused when calling hasMoreChildren() and | |
1228 | getValue() on the same node.</li> | |
1229 | <li>JIRA:XSTR-217, ISO8601DateConverter now requires joda-time-1.2.1</li> | |
1230 | <li>PrettyPrintWriter and CompactWriter may have their text/attribute escaping rules customized by overriding | |
1231 | writeText() and writeAttributeValue().</li> | |
1232 | </ul> | |
1233 | ||
1234 | <h2>API changes</h2> | |
1235 | ||
1236 | <ul> | |
1237 | <li>HierarchicalStreamDriver implementations now require a createWriter() method. The simplest implementation is | |
1238 | to return a new PrettyPrintWriter.</li> | |
1239 | <li>Introduced ReaderWrapper/WriterWrapper classes to make it easier to wrap (decorate) | |
1240 | HierarchicalStreamReader/Writer instances.</li> | |
1241 | </ul> | |
1242 | ||
1243 | <h1 id="1.1.1">Version 1.1.1</h1> | |
1244 | ||
1245 | <p>Released March 7, 2005. Mostly bugfixes and minor feature enhancements.</p> | |
1246 | ||
1247 | <h2>Major changes</h2> | |
1248 | ||
1249 | <ul> | |
1250 | <li>Converters can be registered with a priority, allowing more <i>generic</i> filters to handle classes that | |
1251 | don't have more specific converters. | |
1252 | </li> | |
1253 | <li>Converters can now access underlying HierarchicalStreamReader/Writer implementations to make implementation | |
1254 | specific calls.</li> | |
1042 | 1255 | <li>Improved support for classes using ObjectInputFields to follow the serialization specification.</li> |
1043 | 1256 | <li>JIRA:XSTR-179 Support for ObjectInputStream.registerValidation(ObjectInputValidation).</li> |
1044 | 1257 | <li>JIRA:XSTR-178 Serialized inner class now maintains reference to outer class.</li> |
1047 | 1260 | |
1048 | 1261 | <h2>Minor changes</h2> |
1049 | 1262 | |
1050 | <ul> | |
1051 | <li>Bugfix: Thread context classloader is loaded by the correct thread. (Thanks to Padraic Renaghan for pointing this out).</li> | |
1052 | <li>Bugfix: Default implementations of aliased classes were not being deserialized by SerializableConverter.</li> | |
1053 | <li>Bugfix: JIRA:XSTR-180 Serializable objects support defaultReadObject() even when no default fields available.</li> | |
1054 | <li>Bugfix: For serialized objects class hierarchy is serialized starting with superclass (as per Java Object Serialization).</li> | |
1263 | <ul> | |
1264 | <li>Bugfix: Thread context classloader is loaded by the correct thread. (Thanks to Padraic Renaghan for pointing | |
1265 | this out).</li> | |
1266 | <li>Bugfix: Default implementations of aliased classes were not being deserialized by SerializableConverter.</li> | |
1267 | <li>Bugfix: JIRA:XSTR-180 Serializable objects support defaultReadObject() even when no default fields available.</li> | |
1268 | <li>Bugfix: For serialized objects class hierarchy is serialized starting with superclass (as per Java Object | |
1269 | Serialization).</li> | |
1055 | 1270 | <li>Bugfix: readObject() is now called for classes containing only transient fields.</li> |
1056 | 1271 | <li>Bugfix: Order of fields are maintained when calling ObjectOutputStream.putFields().</li> |
1057 | 1272 | <li>Bugfix: FontConverter extended to support FontUIResource which does some awkward native calls.</li> |
1058 | <li>Bugfix: Deserialization of very complicated graphs (such as Swing components) sometimes resulted in broken object references. Now fixed.</li> | |
1273 | <li>Bugfix: Deserialization of very complicated graphs (such as Swing components) sometimes resulted in broken | |
1274 | object references. Now fixed.</li> | |
1059 | 1275 | <li>Bugfix: JIRA:XSTR-188 Classes that use readResolve()/writeReplace() can now return different types.</li> |
1060 | <li>Bugfix: JIRA:XSTR-185, JIRA:XSTR-195 Support for loading of array classes for classes that have not yet been loaded. (Thanks to Henri Tremblay and Simon Daniel)</li> | |
1276 | <li>Bugfix: JIRA:XSTR-185, JIRA:XSTR-195 Support for loading of array classes for classes that have not yet been | |
1277 | loaded. (Thanks to Henri Tremblay and Simon Daniel)</li> | |
1061 | 1278 | <li>Bugfix: JIRA:XSTR-190 PrettyPrintWriter and CompactWriter escape characters in XML attributes.</li> |
1062 | <li>Bugfix: JIRA:XSTR-176, JIRA:XSTR-196 The XStream ObjectInputStream and ObjectOutputStream implementations now propegate the flush() and close() events to the underlying streams.</li> | |
1279 | <li>Bugfix: JIRA:XSTR-176, JIRA:XSTR-196 The XStream ObjectInputStream and ObjectOutputStream implementations now | |
1280 | propegate the flush() and close() events to the underlying streams.</li> | |
1063 | 1281 | <li>Bugfix: JIRA:XSTR-192 Implicit collection mappings are now supported in inheritance hierarchies.</li> |
1064 | </ul> | |
1065 | ||
1066 | <h2>API changes</h2> | |
1067 | ||
1068 | <ul> | |
1069 | <li>ClassMapper is now deprecated. Replaced with MapperWrapper.</li> | |
1070 | <li>HierarchicalStreamWriter implementations must now implement close(), flush() and underlyingWriter().</li> | |
1071 | <li>HierarchicalStreamReader implementations must now implement close() and underlyingReader().</li> | |
1072 | </ul> | |
1073 | ||
1074 | <h1 id="1.1">Version 1.1</h1> | |
1075 | ||
1076 | <p>Released January 15, 2005. Focus on support for objects defining custom serialization using the standard | |
1077 | <a href="http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/serialTOC.html">Java serialization</a> mechanism.</p> | |
1078 | ||
1079 | <h2>Major changes</h2> | |
1080 | ||
1081 | <ul> | |
1082 | <li>Provides drop in replacement for ObjectInputStream and ObjectOutputStream, using XStream.createObjectInputStream() and | |
1083 | XStream.createObjectOutputStream() and XStream.createObjectInputStream(). This provides support for streaming objects.</li> | |
1084 | <li>Support for objects that specify their own serialization schemes by implementing readObject() and writeObject() | |
1085 | (as in Java serialization spec). This includes support for ObjectInputStream.getFields() and ObjectOuputStream.putFields().</li> | |
1086 | <li>Support for objects to serialize other objects to the stream by implementing writeReplace() (as in Java serialization spec).</li> | |
1087 | <li>Support for any object that performs custom serialization by implementing java.io.Externalizable (as in Java serialization spec).</li> | |
1088 | <li>Implicit collections can be specified for classes, allowing the element wrapping the collection to be skipped.</li> | |
1089 | <li>New writer implementations to allow XStream to serialize directly to a SAX stream or TrAX pipeline.</li> | |
1090 | <li>The MarshallingContext and UnmarshallingContext interfaces now extend DataHolder, allowing arbitrary data to be stored | |
1091 | by the user whilst walking the object graph and passed around to Converters. DataHolders can also be passed into | |
1092 | XStream from the outside.</li> | |
1093 | <li>Includes new DomWriter implementation to serialize directly to a W3C DOM tree (to complement the existing DomReader).</li> | |
1094 | <li>Better support for instantiating objects on non Sun 1.4+ JVMs, including non-public constructors, private static inner classes and | |
1095 | ANY class that implements java.io.Serializable.</li> | |
1096 | <li>DOM, DOM4J, JDOM, XOM, Electric-XML, SAX, STAX</li> | |
1097 | <li>Specific ClassLoaders can be passed into XStream, to allow for greater compatibility in J2EE containers.</li> | |
1098 | <li>Ability to change the default converter</li> | |
1099 | <li>Added optional ISO8601DateConverter for full ISO8601 date format support. The converter is not registered by default | |
1100 | as it requires the joda-time dependency (http://joda-time.sf.net). To use, ensure joda-time is in classpath and register explicitly.</li> | |
1101 | <li>Enhanced mode is now supported on the Apple 1.4 JDK.</li> | |
1102 | </ul> | |
1103 | ||
1104 | <h2>Minor changes</h2> | |
1105 | ||
1106 | <ul> | |
1107 | <li>PrettyPrintWriter only flushes stream when necessary - large performance improvement for serialization.</li> | |
1108 | <li>Added XStream.fromXml(xml, root) convenience methods for deserializing into an existing root object.</li> | |
1109 | <li>JDK 1.3 compatibility: Added mechanism for accessing nested exception.</li> | |
1110 | <li>JDK 1.3 compatibility: GregorianCalendarConverter only calls Calendar.getTimeInMillis() the JDK supports it.</li> | |
1111 | <li>Bugfix: All caches are now synchronized - there were some thread safety issues.</li> | |
1112 | <li>Bugfix: Only <i>immutable</i> basic types will have references ignored in XML (for clarity).</li> | |
1113 | <li>Bugfix: Class names can contain underscores.</li> | |
1114 | <li>Bugfix: Support for '\0' char.</li> | |
1115 | <li>Bugfix: PropertyConverter no longer attempts to serialize subclasses of Properties.</li> | |
1116 | <li>Bugfix: JVM detection uses system properties, which is more accurate than searching the classpath.</li> | |
1117 | </ul> | |
1118 | ||
1119 | <h2>API changes</h2> | |
1120 | ||
1121 | <ul> | |
1122 | <li>XStream.addDefaultCollection() has been deprecated. Use XStream.addImplicitCollection() instead.</li> | |
1123 | </ul> | |
1124 | ||
1125 | <h1 id="1.0.2">Version 1.0.2</h1> | |
1126 | ||
1127 | <p>Released August 7, 2004. Focus on improving the converters bundled with XStream to support a wider range of types.</p> | |
1128 | ||
1129 | <h2>Major changes</h2> | |
1130 | ||
1131 | <ul> | |
1132 | <li>XML elements are written in order they are defined in class, rather than alphabetical.</li> | |
1133 | <li>Converters for java.io.File, java.sql.Timestamp, java.awt.Color, and dynamic proxies are now | |
1134 | registered by default.</li> | |
1135 | <li>EncodedByteArrayConverter is now registered by default and uses a single Base64 string to store the contents | |
1136 | of a byte[]. This now works on all JVMs as it no longer relies on Sun specific classes. This converter will also | |
1137 | unmarshal byte[] that have been serialized without it, for backwards compatability.</li> | |
1138 | <li>New converters for java.sql.Time, java.sql.Date, java.util.Locale, java.util.Currency, java.util.Calendar | |
1139 | and java.awt.Font.</li> | |
1140 | <li>All caching is done in XStream instance instead of statics, allowing applications that use hot redeployment | |
1141 | of classes to use XStream in a parent classloader.</li> | |
1142 | <li>XStream will fail fast if a field value is defined more than once in XML when deserializing.</li> | |
1143 | </ul> | |
1144 | ||
1145 | <h2>Minor changes</h2> | |
1146 | ||
1147 | <ul> | |
1148 | <li>The <entry> element used in Maps can now be specified by creating an alias for java.util.Map.Entry.</li> | |
1149 | <li>Bugfix: Fields with characters that generate invalid XML (such as $ signs) are now escaped.</li> | |
1150 | <li>Bugfix: Pre-instantiated objects can be unmarshalled through multiple levels.</li> | |
1151 | </ul> | |
1152 | ||
1153 | <h2>API changes</h2> | |
1154 | ||
1155 | <ul> | |
1156 | <li>None.</li> | |
1157 | </ul> | |
1158 | ||
1159 | <h1 id="1.0.1">Version 1.0.1</h1> | |
1160 | ||
1161 | <p>Released May 30, 2004. Misc features and bugfixes.</p> | |
1162 | ||
1163 | <h2>Major changes</h2> | |
1164 | ||
1165 | <ul> | |
1166 | <li>Support for multidimensional arrays.</li> | |
1167 | <li>Object with readResolve() method will be treated the same way native serialization treats them.</li> | |
1168 | </ul> | |
1169 | ||
1170 | <h2>Minor changes</h2> | |
1171 | ||
1172 | <ul> | |
1173 | <li>New converters for Throwable and StackTraceElement that retain stack trace (JDK 1.4 only)</li> | |
1174 | <li>Bugfix: System.identityHashCode() is not guaranteed to be unique. Ensure reference checking is used as well.</li> | |
1175 | <li>Bugfix: Allows user classes to be defined in WEB-INF/classes in Servlet environments. Tries to use context classloader if available.</li> | |
1176 | <li>Support for java.util.Currency (through readResolve()).</li> | |
1177 | <li>Instances of Jakarta Commons Lang Enum are now reused (through readResolve()).</li> | |
1178 | <li>Bugfix: JavaClassConverter handles primitive type classes (contributed by Matthew Sandoz).</li> | |
1179 | </ul> | |
1180 | ||
1181 | <h2>API changes</h2> | |
1182 | ||
1183 | <ul> | |
1184 | <li>Additional method: ConverterLookup.defaultConverter(). Custom implementations of this class should implement | |
1185 | this new method.</li> | |
1186 | </ul> | |
1187 | ||
1188 | <h1 id="1.0">Version 1.0</h1> | |
1189 | ||
1190 | <p>Released May 14, 2004. Focusses on finalizing the API for 1.0 release.</p> | |
1191 | ||
1192 | <h2>Major changes</h2> | |
1193 | ||
1194 | <ul> | |
1195 | <li>Supports fields of same name, hidden by inheritance.</li> | |
1196 | </ul> | |
1197 | ||
1198 | <h2>Minor changes</h2> | |
1199 | ||
1200 | <ul> | |
1201 | <li>JavaDoc for most important parts of API.</li> | |
1202 | </ul> | |
1203 | ||
1204 | <h2>API changes</h2> | |
1205 | ||
1206 | <ul> | |
1207 | <li>The ReflectionConverter and ReflectionProviders have had an overhaul to support | |
1208 | hidden fields. Most methods now take an extra argument to specify which class a field | |
1209 | is declared in.</li> | |
1210 | </ul> | |
1211 | ||
1212 | <h1 id="1.0RC1">Version 1.0 (release candidate 1)</h1> | |
1213 | ||
1214 | <p>Released May 9, 2004. Focusses on finalizing the API for 1.0 release.</p> | |
1215 | ||
1216 | <h2>Major changes</h2> | |
1217 | ||
1218 | <ul> | |
1219 | <li>JDK 1.3 compatibility.</li> | |
1220 | <li>Informative error messages.</li> | |
1221 | <li>Defaults to using faster XPP based parser.</li> | |
1222 | <li>Serializes final field under JDK 1.4.</li> | |
1223 | <li>Fail fast when trying to serialize final field if not Sun 1.4 JRE.</li> | |
1224 | </ul> | |
1225 | ||
1226 | <h2>Minor changes</h2> | |
1227 | ||
1228 | <ul> | |
1229 | <li>Misc performance improvements.</li> | |
1230 | <li>Converters for TreeMap and TreeSet that store the Comparator.</li> | |
1231 | </ul> | |
1232 | ||
1233 | <h2>API changes</h2> | |
1234 | ||
1235 | <ul> | |
1236 | <li>Default constructor for XStream class uses XppDriver instead of DomDriver. | |
1237 | To use DomDriver, explicitly pass it in to the constructor.</li> | |
1238 | <li>Exception is thrown if trying to serialize an object that contains a | |
1239 | final field if not Sun 1.4 JRE.</li> | |
1240 | </ul> | |
1241 | ||
1242 | <p><a href="versioning.html">About XStream version numbers...</a></p> | |
1243 | ||
1244 | <h1 id="0.6">Version 0.6</h1> | |
1245 | ||
1246 | <p>Released May 7, 2004. Focusses on providing full object graph support.</p> | |
1247 | ||
1248 | <h2>Major changes</h2> | |
1249 | ||
1250 | <ul> | |
1251 | <li>None.</li> | |
1252 | </ul> | |
1253 | ||
1254 | <h2>Minor changes</h2> | |
1255 | ||
1256 | <ul> | |
1257 | <li>Bugfix: Objects that had no children could not be derefenced properly (thanks to Brian Slesinsky and Nick Pomfret).</li> | |
1258 | <li>Bugfix: DateConverter is now thread safe.</li> | |
1259 | <li>Optimization: String instances are reused as much as possible.</li> | |
1260 | <li>Converters for BigInteger and BigDecimal.</li> | |
1261 | <li>IntConverter now recognises hexadecimal and octal notations (thanks to Konstantin Pribluda).</li> | |
1262 | </ul> | |
1263 | ||
1264 | <h2>API changes</h2> | |
1265 | ||
1266 | <ul> | |
1267 | <li>None.</li> | |
1268 | </ul> | |
1269 | ||
1270 | <h1 id="0.6RC1">Version 0.6 (release candidate 1)</h1> | |
1271 | ||
1272 | <p>Released April 19, 2004. Focusses on providing full object graph support.</p> | |
1273 | ||
1274 | <h2>Major changes</h2> | |
1275 | ||
1276 | <ul> | |
1277 | <li>Full support for object graphs, including duplicate references of same object and | |
1278 | circular references.</li> | |
1279 | <li>References can be identified using XPath (default), unique-IDs or disabled.</li> | |
1280 | </ul> | |
1281 | ||
1282 | <h2>Minor changes</h2> | |
1283 | ||
1284 | <ul> | |
1285 | <li>Release includes Ant build file.</li> | |
1286 | <li>Converters for non standard collections such as Collections.EMPTY_LIST, syncronizedList(), unmodifiableMap(), etc.</li> | |
1287 | <li>Converter for nulls.</li> | |
1288 | <li>Converter for dynamic proxies.</li> | |
1289 | <li>Converter for java.net.URL.</li> | |
1290 | <li>Converters for java.util.LinkedHashMap and java.util.LinkedHashSet.</li> | |
1291 | <li>Converters for java.lang.reflect.Method and java.lang.reflect.Constructor.</li> | |
1292 | <li>If duplicate reference support is disabled and a circular reference is encountered, an exception will be thrown.</li> | |
1293 | </ul> | |
1294 | ||
1295 | <h2>API changes</h2> | |
1296 | ||
1297 | <ul> | |
1298 | <li>None.</li> | |
1299 | </ul> | |
1300 | ||
1301 | <h1 id="0.5">Version 0.5</h1> | |
1302 | ||
1303 | <p>Released March 8, 2004. Focussed on performance.</p> | |
1304 | ||
1305 | <h2>Major changes</h2> | |
1306 | ||
1307 | <ul> | |
1308 | <li>Massive performance improvements. Up to 3 times faster for serialization and 22 | |
1309 | times faster for deserialization!</li> | |
1310 | <li>Non-DOM building pull parser based reader. Results in much smaller memory footprint, | |
1311 | particularly when deserializing large object models.</li> | |
1312 | </ul> | |
1313 | ||
1314 | <h2>Minor changes</h2> | |
1315 | ||
1316 | <ul> | |
1317 | <li>Misc performance improvements.</li> | |
1318 | <li>Misc bugfixes.</li> | |
1319 | <li>Alternate encodings can be used with DomDriver.</li> | |
1320 | </ul> | |
1321 | ||
1322 | <h2>API changes</h2> | |
1323 | ||
1324 | <ul> | |
1325 | <li>Renamed XMLReader/Writer to HierarchicalStreamReader/Writer as XStream is not | |
1326 | actually coupled to serializing just to XML.</li> | |
1327 | <li>Cleaned up the public API.</li> | |
1328 | <li>Moved internal XStream implementation classes to core package.</li> | |
1329 | <li>Misc package/class renames to make more sense. Dumped lots of dead code.</li> | |
1330 | </ul> | |
1331 | ||
1332 | <h1 id="0.4">Version 0.4</h1> | |
1333 | ||
1334 | <p>This version was never publicly released. All changes were made available in 0.5. Focussed on making it easier to create custom converters.</p> | |
1335 | ||
1336 | <h2>Major changes</h2> | |
1337 | ||
1338 | <ul> | |
1339 | <li>Overhaul of interface for Converters. Makes Converters much cleaner to write.</li> | |
1340 | </ul> | |
1341 | ||
1342 | <h2>Minor changes</h2> | |
1343 | ||
1344 | <ul> | |
1345 | <li>Added custom converters for java.io.File, java.util.Properties, java.util.Vector, java.util.Hashtable, java.util.BitSet | |
1346 | byte[] (Base64 encoded), char[].</li> | |
1347 | <li>Misc bugfixes.</li> | |
1348 | </ul> | |
1349 | ||
1350 | <h2>API changes</h2> | |
1351 | ||
1352 | <ul> | |
1353 | <li>New interface to be implemented by custom converters.</li> | |
1354 | </ul> | |
1355 | ||
1356 | <h1 id="0.3">Version 0.3</h1> | |
1357 | ||
1358 | <p>Released January 1, 2004.</p> | |
1359 | ||
1360 | <h2>Major changes</h2> | |
1361 | ||
1362 | <ul> | |
1363 | <li>Added ElementMapper interface and default implementations to allow fine | |
1364 | grained control over element name to class mapper operations.</li> | |
1365 | <li>Added an XPP based reader and writer that uses a pull-parser to create a lightweight DOM tree.</li> | |
1366 | </ul> | |
1367 | ||
1368 | <h2>Minor changes</h2> | |
1369 | ||
1370 | <ul> | |
1371 | <li>Added XStream.fromXML(XMLReader xmlReader,Object root) method to | |
1372 | allow the population of an object graph starting with a live object root.</li> | |
1373 | <li>Added XMLReader.peek() method to allow access to the underlying hierarchical | |
1374 | object being unmarshalled.</li> | |
1375 | </ul> | |
1376 | ||
1377 | <h2>API changes</h2> | |
1378 | ||
1379 | <ul> | |
1380 | <li>Aligned the the methods in XStream to use the specified ObjectFactory in the constructor | |
1381 | instead of creating a SunReflectionObjectFactory.</li> | |
1382 | </ul> | |
1383 | ||
1384 | <h1 id="older">Older versions</h1> | |
1385 | ||
1386 | <p>Changes in XStream prior to version 0.3 were not logged.</p> | |
1387 | ||
1388 | </body> | |
1282 | </ul> | |
1283 | ||
1284 | <h2>API changes</h2> | |
1285 | ||
1286 | <ul> | |
1287 | <li>ClassMapper is now deprecated. Replaced with MapperWrapper.</li> | |
1288 | <li>HierarchicalStreamWriter implementations must now implement close(), flush() and underlyingWriter().</li> | |
1289 | <li>HierarchicalStreamReader implementations must now implement close() and underlyingReader().</li> | |
1290 | </ul> | |
1291 | ||
1292 | <h1 id="1.1">Version 1.1</h1> | |
1293 | ||
1294 | <p> | |
1295 | Released January 15, 2005. Focus on support for objects defining custom serialization using the standard <a | |
1296 | href="http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/serialTOC.html">Java serialization</a> mechanism. | |
1297 | </p> | |
1298 | ||
1299 | <h2>Major changes</h2> | |
1300 | ||
1301 | <ul> | |
1302 | <li>Provides drop in replacement for ObjectInputStream and ObjectOutputStream, using | |
1303 | XStream.createObjectInputStream() and XStream.createObjectOutputStream() and XStream.createObjectInputStream(). This | |
1304 | provides support for streaming objects.</li> | |
1305 | <li>Support for objects that specify their own serialization schemes by implementing readObject() and | |
1306 | writeObject() (as in Java serialization spec). This includes support for ObjectInputStream.getFields() and | |
1307 | ObjectOuputStream.putFields().</li> | |
1308 | <li>Support for objects to serialize other objects to the stream by implementing writeReplace() (as in Java | |
1309 | serialization spec).</li> | |
1310 | <li>Support for any object that performs custom serialization by implementing java.io.Externalizable (as in Java | |
1311 | serialization spec).</li> | |
1312 | <li>Implicit collections can be specified for classes, allowing the element wrapping the collection to be | |
1313 | skipped.</li> | |
1314 | <li>New writer implementations to allow XStream to serialize directly to a SAX stream or TrAX pipeline.</li> | |
1315 | <li>The MarshallingContext and UnmarshallingContext interfaces now extend DataHolder, allowing arbitrary data to | |
1316 | be stored by the user whilst walking the object graph and passed around to Converters. DataHolders can also be passed | |
1317 | into XStream from the outside.</li> | |
1318 | <li>Includes new DomWriter implementation to serialize directly to a W3C DOM tree (to complement the existing | |
1319 | DomReader).</li> | |
1320 | <li>Better support for instantiating objects on non Sun 1.4+ JVMs, including non-public constructors, private | |
1321 | static inner classes and ANY class that implements java.io.Serializable.</li> | |
1322 | <li>DOM, DOM4J, JDOM, XOM, Electric-XML, SAX, STAX</li> | |
1323 | <li>Specific ClassLoaders can be passed into XStream, to allow for greater compatibility in J2EE containers.</li> | |
1324 | <li>Ability to change the default converter</li> | |
1325 | <li>Added optional ISO8601DateConverter for full ISO8601 date format support. The converter is not registered by | |
1326 | default as it requires the joda-time dependency (http://joda-time.sf.net). To use, ensure joda-time is in classpath | |
1327 | and register explicitly.</li> | |
1328 | <li>Enhanced mode is now supported on the Apple 1.4 JDK.</li> | |
1329 | </ul> | |
1330 | ||
1331 | <h2>Minor changes</h2> | |
1332 | ||
1333 | <ul> | |
1334 | <li>PrettyPrintWriter only flushes stream when necessary - large performance improvement for serialization.</li> | |
1335 | <li>Added XStream.fromXml(xml, root) convenience methods for deserializing into an existing root object.</li> | |
1336 | <li>JDK 1.3 compatibility: Added mechanism for accessing nested exception.</li> | |
1337 | <li>JDK 1.3 compatibility: GregorianCalendarConverter only calls Calendar.getTimeInMillis() the JDK supports it.</li> | |
1338 | <li>Bugfix: All caches are now synchronized - there were some thread safety issues.</li> | |
1339 | <li>Bugfix: Only <i>immutable</i> basic types will have references ignored in XML (for clarity). | |
1340 | </li> | |
1341 | <li>Bugfix: Class names can contain underscores.</li> | |
1342 | <li>Bugfix: Support for '\0' char.</li> | |
1343 | <li>Bugfix: PropertyConverter no longer attempts to serialize subclasses of Properties.</li> | |
1344 | <li>Bugfix: JVM detection uses system properties, which is more accurate than searching the classpath.</li> | |
1345 | </ul> | |
1346 | ||
1347 | <h2>API changes</h2> | |
1348 | ||
1349 | <ul> | |
1350 | <li>XStream.addDefaultCollection() has been deprecated. Use XStream.addImplicitCollection() instead.</li> | |
1351 | </ul> | |
1352 | ||
1353 | <h1 id="1.0.2">Version 1.0.2</h1> | |
1354 | ||
1355 | <p>Released August 7, 2004. Focus on improving the converters bundled with XStream to support a wider range of | |
1356 | types.</p> | |
1357 | ||
1358 | <h2>Major changes</h2> | |
1359 | ||
1360 | <ul> | |
1361 | <li>XML elements are written in order they are defined in class, rather than alphabetical.</li> | |
1362 | <li>Converters for java.io.File, java.sql.Timestamp, java.awt.Color, and dynamic proxies are now registered by | |
1363 | default.</li> | |
1364 | <li>EncodedByteArrayConverter is now registered by default and uses a single Base64 string to store the contents | |
1365 | of a byte[]. This now works on all JVMs as it no longer relies on Sun specific classes. This converter will also | |
1366 | unmarshal byte[] that have been serialized without it, for backwards compatability.</li> | |
1367 | <li>New converters for java.sql.Time, java.sql.Date, java.util.Locale, java.util.Currency, java.util.Calendar and | |
1368 | java.awt.Font.</li> | |
1369 | <li>All caching is done in XStream instance instead of statics, allowing applications that use hot redeployment | |
1370 | of classes to use XStream in a parent classloader.</li> | |
1371 | <li>XStream will fail fast if a field value is defined more than once in XML when deserializing.</li> | |
1372 | </ul> | |
1373 | ||
1374 | <h2>Minor changes</h2> | |
1375 | ||
1376 | <ul> | |
1377 | <li>The <entry> element used in Maps can now be specified by creating an alias for java.util.Map.Entry.</li> | |
1378 | <li>Bugfix: Fields with characters that generate invalid XML (such as $ signs) are now escaped.</li> | |
1379 | <li>Bugfix: Pre-instantiated objects can be unmarshalled through multiple levels.</li> | |
1380 | </ul> | |
1381 | ||
1382 | <h2>API changes</h2> | |
1383 | ||
1384 | <ul> | |
1385 | <li>None.</li> | |
1386 | </ul> | |
1387 | ||
1388 | <h1 id="1.0.1">Version 1.0.1</h1> | |
1389 | ||
1390 | <p>Released May 30, 2004. Misc features and bugfixes.</p> | |
1391 | ||
1392 | <h2>Major changes</h2> | |
1393 | ||
1394 | <ul> | |
1395 | <li>Support for multidimensional arrays.</li> | |
1396 | <li>Object with readResolve() method will be treated the same way native serialization treats them.</li> | |
1397 | </ul> | |
1398 | ||
1399 | <h2>Minor changes</h2> | |
1400 | ||
1401 | <ul> | |
1402 | <li>New converters for Throwable and StackTraceElement that retain stack trace (JDK 1.4 only)</li> | |
1403 | <li>Bugfix: System.identityHashCode() is not guaranteed to be unique. Ensure reference checking is used as well.</li> | |
1404 | <li>Bugfix: Allows user classes to be defined in WEB-INF/classes in Servlet environments. Tries to use context | |
1405 | classloader if available.</li> | |
1406 | <li>Support for java.util.Currency (through readResolve()).</li> | |
1407 | <li>Instances of Jakarta Commons Lang Enum are now reused (through readResolve()).</li> | |
1408 | <li>Bugfix: JavaClassConverter handles primitive type classes (contributed by Matthew Sandoz).</li> | |
1409 | </ul> | |
1410 | ||
1411 | <h2>API changes</h2> | |
1412 | ||
1413 | <ul> | |
1414 | <li>Additional method: ConverterLookup.defaultConverter(). Custom implementations of this class should implement | |
1415 | this new method.</li> | |
1416 | </ul> | |
1417 | ||
1418 | <h1 id="1.0">Version 1.0</h1> | |
1419 | ||
1420 | <p>Released May 14, 2004. Focusses on finalizing the API for 1.0 release.</p> | |
1421 | ||
1422 | <h2>Major changes</h2> | |
1423 | ||
1424 | <ul> | |
1425 | <li>Supports fields of same name, hidden by inheritance.</li> | |
1426 | </ul> | |
1427 | ||
1428 | <h2>Minor changes</h2> | |
1429 | ||
1430 | <ul> | |
1431 | <li>JavaDoc for most important parts of API.</li> | |
1432 | </ul> | |
1433 | ||
1434 | <h2>API changes</h2> | |
1435 | ||
1436 | <ul> | |
1437 | <li>The ReflectionConverter and ReflectionProviders have had an overhaul to support hidden fields. Most methods | |
1438 | now take an extra argument to specify which class a field is declared in.</li> | |
1439 | </ul> | |
1440 | ||
1441 | <h1 id="1.0RC1">Version 1.0 (release candidate 1)</h1> | |
1442 | ||
1443 | <p>Released May 9, 2004. Focusses on finalizing the API for 1.0 release.</p> | |
1444 | ||
1445 | <h2>Major changes</h2> | |
1446 | ||
1447 | <ul> | |
1448 | <li>JDK 1.3 compatibility.</li> | |
1449 | <li>Informative error messages.</li> | |
1450 | <li>Defaults to using faster XPP based parser.</li> | |
1451 | <li>Serializes final field under JDK 1.4.</li> | |
1452 | <li>Fail fast when trying to serialize final field if not Sun 1.4 JRE.</li> | |
1453 | </ul> | |
1454 | ||
1455 | <h2>Minor changes</h2> | |
1456 | ||
1457 | <ul> | |
1458 | <li>Misc performance improvements.</li> | |
1459 | <li>Converters for TreeMap and TreeSet that store the Comparator.</li> | |
1460 | </ul> | |
1461 | ||
1462 | <h2>API changes</h2> | |
1463 | ||
1464 | <ul> | |
1465 | <li>Default constructor for XStream class uses XppDriver instead of DomDriver. To use DomDriver, explicitly pass | |
1466 | it in to the constructor.</li> | |
1467 | <li>Exception is thrown if trying to serialize an object that contains a final field if not Sun 1.4 JRE.</li> | |
1468 | </ul> | |
1469 | ||
1470 | <p> | |
1471 | <a href="versioning.html">About XStream version numbers...</a> | |
1472 | </p> | |
1473 | ||
1474 | <h1 id="0.6">Version 0.6</h1> | |
1475 | ||
1476 | <p>Released May 7, 2004. Focusses on providing full object graph support.</p> | |
1477 | ||
1478 | <h2>Major changes</h2> | |
1479 | ||
1480 | <ul> | |
1481 | <li>None.</li> | |
1482 | </ul> | |
1483 | ||
1484 | <h2>Minor changes</h2> | |
1485 | ||
1486 | <ul> | |
1487 | <li>Bugfix: Objects that had no children could not be derefenced properly (thanks to Brian Slesinsky and Nick | |
1488 | Pomfret).</li> | |
1489 | <li>Bugfix: DateConverter is now thread safe.</li> | |
1490 | <li>Optimization: String instances are reused as much as possible.</li> | |
1491 | <li>Converters for BigInteger and BigDecimal.</li> | |
1492 | <li>IntConverter now recognises hexadecimal and octal notations (thanks to Konstantin Pribluda).</li> | |
1493 | </ul> | |
1494 | ||
1495 | <h2>API changes</h2> | |
1496 | ||
1497 | <ul> | |
1498 | <li>None.</li> | |
1499 | </ul> | |
1500 | ||
1501 | <h1 id="0.6RC1">Version 0.6 (release candidate 1)</h1> | |
1502 | ||
1503 | <p>Released April 19, 2004. Focusses on providing full object graph support.</p> | |
1504 | ||
1505 | <h2>Major changes</h2> | |
1506 | ||
1507 | <ul> | |
1508 | <li>Full support for object graphs, including duplicate references of same object and circular references.</li> | |
1509 | <li>References can be identified using XPath (default), unique-IDs or disabled.</li> | |
1510 | </ul> | |
1511 | ||
1512 | <h2>Minor changes</h2> | |
1513 | ||
1514 | <ul> | |
1515 | <li>Release includes Ant build file.</li> | |
1516 | <li>Converters for non standard collections such as Collections.EMPTY_LIST, syncronizedList(), unmodifiableMap(), | |
1517 | etc.</li> | |
1518 | <li>Converter for nulls.</li> | |
1519 | <li>Converter for dynamic proxies.</li> | |
1520 | <li>Converter for java.net.URL.</li> | |
1521 | <li>Converters for java.util.LinkedHashMap and java.util.LinkedHashSet.</li> | |
1522 | <li>Converters for java.lang.reflect.Method and java.lang.reflect.Constructor.</li> | |
1523 | <li>If duplicate reference support is disabled and a circular reference is encountered, an exception will be | |
1524 | thrown.</li> | |
1525 | </ul> | |
1526 | ||
1527 | <h2>API changes</h2> | |
1528 | ||
1529 | <ul> | |
1530 | <li>None.</li> | |
1531 | </ul> | |
1532 | ||
1533 | <h1 id="0.5">Version 0.5</h1> | |
1534 | ||
1535 | <p>Released March 8, 2004. Focussed on performance.</p> | |
1536 | ||
1537 | <h2>Major changes</h2> | |
1538 | ||
1539 | <ul> | |
1540 | <li>Massive performance improvements. Up to 3 times faster for serialization and 22 times faster for | |
1541 | deserialization!</li> | |
1542 | <li>Non-DOM building pull parser based reader. Results in much smaller memory footprint, particularly when | |
1543 | deserializing large object models.</li> | |
1544 | </ul> | |
1545 | ||
1546 | <h2>Minor changes</h2> | |
1547 | ||
1548 | <ul> | |
1549 | <li>Misc performance improvements.</li> | |
1550 | <li>Misc bugfixes.</li> | |
1551 | <li>Alternate encodings can be used with DomDriver.</li> | |
1552 | </ul> | |
1553 | ||
1554 | <h2>API changes</h2> | |
1555 | ||
1556 | <ul> | |
1557 | <li>Renamed XMLReader/Writer to HierarchicalStreamReader/Writer as XStream is not actually coupled to serializing | |
1558 | just to XML.</li> | |
1559 | <li>Cleaned up the public API.</li> | |
1560 | <li>Moved internal XStream implementation classes to core package.</li> | |
1561 | <li>Misc package/class renames to make more sense. Dumped lots of dead code.</li> | |
1562 | </ul> | |
1563 | ||
1564 | <h1 id="0.4">Version 0.4</h1> | |
1565 | ||
1566 | <p>This version was never publicly released. All changes were made available in 0.5. Focussed on making it easier | |
1567 | to create custom converters.</p> | |
1568 | ||
1569 | <h2>Major changes</h2> | |
1570 | ||
1571 | <ul> | |
1572 | <li>Overhaul of interface for Converters. Makes Converters much cleaner to write.</li> | |
1573 | </ul> | |
1574 | ||
1575 | <h2>Minor changes</h2> | |
1576 | ||
1577 | <ul> | |
1578 | <li>Added custom converters for java.io.File, java.util.Properties, java.util.Vector, java.util.Hashtable, | |
1579 | java.util.BitSet byte[] (Base64 encoded), char[].</li> | |
1580 | <li>Misc bugfixes.</li> | |
1581 | </ul> | |
1582 | ||
1583 | <h2>API changes</h2> | |
1584 | ||
1585 | <ul> | |
1586 | <li>New interface to be implemented by custom converters.</li> | |
1587 | </ul> | |
1588 | ||
1589 | <h1 id="0.3">Version 0.3</h1> | |
1590 | ||
1591 | <p>Released January 1, 2004.</p> | |
1592 | ||
1593 | <h2>Major changes</h2> | |
1594 | ||
1595 | <ul> | |
1596 | <li>Added ElementMapper interface and default implementations to allow fine grained control over element name to | |
1597 | class mapper operations.</li> | |
1598 | <li>Added an XPP based reader and writer that uses a pull-parser to create a lightweight DOM tree.</li> | |
1599 | </ul> | |
1600 | ||
1601 | <h2>Minor changes</h2> | |
1602 | ||
1603 | <ul> | |
1604 | <li>Added XStream.fromXML(XMLReader xmlReader,Object root) method to allow the population of an object graph | |
1605 | starting with a live object root.</li> | |
1606 | <li>Added XMLReader.peek() method to allow access to the underlying hierarchical object being unmarshalled.</li> | |
1607 | </ul> | |
1608 | ||
1609 | <h2>API changes</h2> | |
1610 | ||
1611 | <ul> | |
1612 | <li>Aligned the the methods in XStream to use the specified ObjectFactory in the constructor instead of creating | |
1613 | a SunReflectionObjectFactory.</li> | |
1614 | </ul> | |
1615 | ||
1616 | <h1 id="older">Older versions</h1> | |
1617 | ||
1618 | <p>Changes in XStream prior to version 0.3 were not logged.</p> | |
1619 | ||
1620 | </body> | |
1389 | 1621 | </html> |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | 2 | Copyright (C) 2005, 2006 Joe Walnes. |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013, 2014, 2015, 2016 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013, 2014, 2015, 2016, 2017 XStream committers. | |
4 | 4 | All rights reserved. |
5 | 5 | |
6 | 6 | The software in this package is published under the terms of the BSD |
165 | 165 | <td><a href="javadoc/com/thoughtworks/xstream/converters/basic/StringBuildererConverter.html">StringBuilderConverter</a></td> |
166 | 166 | <td>java.lang.StringBuilder</td> |
167 | 167 | <td class="example"><string-builder>hello world</string-builder></td> |
168 | <td>Available under Java 1.5 or greater.</td> | |
168 | <td>Available with Java 1.5 or greater.</td> | |
169 | 169 | <td>normal</td> |
170 | 170 | </tr> |
171 | 171 | <tr> |
182 | 182 | </stack-trace><br/> |
183 | 183 | </java.io.IOException> |
184 | 184 | </td> |
185 | <td>This is only available under Java 1.4 or greater. It retains the full stack trace, including that of any | |
185 | <td>This is only available with Java 1.4 or greater. It retains the full stack trace, including that of any | |
186 | 186 | nested exceptions. The stack trace elements are handled by the |
187 | 187 | <a href="javadoc/com/thoughtworks/xstream/converters/extended/StackTraceElementConverter.html">StackTraceElementConverter</a>.</td> |
188 | 188 | <td>normal</td> |
191 | 191 | <td><a href="javadoc/com/thoughtworks/xstream/converters/enums/EnumConverter.html">EnumConverter</a></td> |
192 | 192 | <td>java.lang.Enum</td> |
193 | 193 | <td class="example"><java.lang.annotation.RetentionPolicy><br/>CLASS<br/></java.lang.annotation.RetentionPolicy></td> |
194 | <td>Available under Java 1.5 or greater.</td> | |
194 | <td>Available with Java 1.5 or greater.</td> | |
195 | 195 | <td>normal</td> |
196 | 196 | </tr> |
197 | 197 | <tr> |
199 | 199 | <td>java.lang.Enum</td> |
200 | 200 | <td>The Converter must be initialized with an Enum type and an optional mapping between strings and enum values. By default |
201 | 201 | it will use the Enum's string representation as value.</td> |
202 | <td>Available under Java 1.5 or greater. Must be registered explicitly for the Enum type or locally.</td> | |
202 | <td>Available with Java 1.5 or greater. Must be registered explicitly for the Enum type or locally.</td> | |
203 | 203 | <td> </td> |
204 | 204 | </tr> |
205 | 205 | |
385 | 385 | <td><a href="javadoc/com/thoughtworks/xstream/converters/extended/ISO8601DateConverter.html">ISO8601DateConverter</a></td> |
386 | 386 | <td>java.util.Date</td> |
387 | 387 | <td class="example"><date>2006-07-28T12:06:17.654-03:00</date></td> |
388 | <td>Not automatically registered, can be used globally or locally. Implementation needs joda-time.</td> | |
388 | <td>Not automatically registered, can be used globally or locally. Implementation needs joda-time for JDK 1.7 or below.</td> | |
389 | 389 | <td> </td> |
390 | 390 | </tr> |
391 | 391 | <tr> |
396 | 396 | 2006-07-28T12:07:02.788-03:00<br/> |
397 | 397 | </gregorian-calendar> |
398 | 398 | </td> |
399 | <td>Not automatically registered, can be used globally or locally. Implementation needs joda-time.</td> | |
399 | <td>Not automatically registered, can be used globally or locally. Implementation needs joda-time for JDK 1.7 or below.</td> | |
400 | 400 | <td> </td> |
401 | 401 | </tr> |
402 | 402 | <tr> |
410 | 410 | <td><a href="javadoc/com/thoughtworks/xstream/converters/extended/CurrencyConverter.html">CurrencyConverter</a></td> |
411 | 411 | <td>java.util.Currency</td> |
412 | 412 | <td class="example"><currency>USD</currency></td> |
413 | <td>Available under Java 1.4 or greater.</td> | |
413 | <td>Available with Java 1.4 or greater.</td> | |
414 | 414 | <td>normal</td> |
415 | 415 | </tr> |
416 | 416 | <tr> |
417 | 417 | <td><a href="javadoc/com/thoughtworks/xstream/converters/basic/UUIDConverter.html">UUIDConverter</a></td> |
418 | 418 | <td>java.util.UUID</td> |
419 | 419 | <td class="example"><uuid>ca05f023-e07f-4956-a6ef-14ddd23df47b</uuid></td> |
420 | <td>Available under Java 1.5 or greater.</td> | |
420 | <td>Available with Java 1.5 or greater.</td> | |
421 | 421 | <td>normal</td> |
422 | 422 | </tr> |
423 | 423 | <tr> |
434 | 434 | <string>sky</string><br/> |
435 | 435 | </entry><br/> |
436 | 436 | </enum-map></td> |
437 | <td>Available under Java 1.5 or greater.</td> | |
437 | <td>Available with Java 1.5 or greater.</td> | |
438 | 438 | <td>normal</td> |
439 | 439 | </tr> |
440 | 440 | <tr> |
444 | 444 | <enum-set enum-type="simple"><br/> |
445 | 445 | GREEN,BLUE<br/> |
446 | 446 | </enum-set></td> |
447 | <td>Available under Java 1.5 or greater.</td> | |
447 | <td>Available with Java 1.5 or greater.</td> | |
448 | 448 | <td>normal</td> |
449 | 449 | </tr> |
450 | 450 | <tr> |
456 | 456 | <flags>0</flags><br/> |
457 | 457 | </java.util.regex.Pattern> |
458 | 458 | </td> |
459 | <td>Available under Java 1.4 or greater.</td> | |
459 | <td>Available with Java 1.4 or greater.</td> | |
460 | <td>normal</td> | |
461 | </tr> | |
462 | ||
463 | <!-- .................................................................................................. --> | |
464 | <tr> | |
465 | <td colspan="5" class="headerRow"><h1 id="java.time">java.time</h1></td> | |
466 | </tr> | |
467 | <tr> | |
468 | <th>Converter</th> | |
469 | <th>Supported types</th> | |
470 | <th>Example</th> | |
471 | <th>Notes</th> | |
472 | <th>Prio</th> | |
473 | </tr> | |
474 | <tr> | |
475 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/DurationConverter.html">DurationConverter</a></td> | |
476 | <td>java.time.Duration</td> | |
477 | <td class="example"> | |
478 | <duration>PT24000H</duration> | |
479 | </td> | |
480 | <td>Available with Java 8 or greater.</td> | |
481 | <td>normal</td> | |
482 | </tr> | |
483 | <tr> | |
484 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/InstantConverter.html">InstantConverter</a></td> | |
485 | <td>java.time.Instant</td> | |
486 | <td class="example"> | |
487 | <instant>2017-07-30T20:40:00Z</instant> | |
488 | </td> | |
489 | <td>Available with Java 8 or greater.</td> | |
490 | <td>normal</td> | |
491 | </tr> | |
492 | <tr> | |
493 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/LocalDateConverter.html">LocalDateConverter</a></td> | |
494 | <td>java.time.LocalDate</td> | |
495 | <td class="example"> | |
496 | <local-date>2017-10-30</local-date> | |
497 | </td> | |
498 | <td>Available with Java 8 or greater.</td> | |
499 | <td>normal</td> | |
500 | </tr> | |
501 | <tr> | |
502 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/LocalDateTimeConverter.html">LocalDateTimeConverter</a></td> | |
503 | <td>java.time.LocalDateTime</td> | |
504 | <td class="example"> | |
505 | <local-date-time>2017-10-30T20:40:15</local-date-time> | |
506 | </td> | |
507 | <td>Available with Java 8 or greater.</td> | |
508 | <td>normal</td> | |
509 | </tr> | |
510 | <tr> | |
511 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/LocalTimeConverter.html">LocalTimeConverter</a></td> | |
512 | <td>java.time.LocalTime</td> | |
513 | <td class="example"> | |
514 | <local-time>20:40:15</local-time> | |
515 | </td> | |
516 | <td>Available with Java 8 or greater.</td> | |
517 | <td>normal</td> | |
518 | </tr> | |
519 | <tr> | |
520 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/MonthDayConverter.html">MonthDayConverter</a></td> | |
521 | <td>java.time.MonthDay</td> | |
522 | <td class="example"> | |
523 | <month-day>--01-13</month-day> | |
524 | </td> | |
525 | <td>Available with Java 8 or greater.</td> | |
526 | <td>normal</td> | |
527 | </tr> | |
528 | <tr> | |
529 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/OffsetDateTimeConverter.html">OffsetDateTimeConverter</a></td> | |
530 | <td>java.time.OffsetDateTime</td> | |
531 | <td class="example"> | |
532 | <offset-date-time>2017-07-30T20:40:00Z</offset-date-time> | |
533 | </td> | |
534 | <td>Available with Java 8 or greater.</td> | |
535 | <td>normal</td> | |
536 | </tr> | |
537 | <tr> | |
538 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/OffsetTimeConverter.html">OffsetTimeConverter</a></td> | |
539 | <td>java.time.OffsetTime</td> | |
540 | <td class="example"> | |
541 | <offset-time>20:40:15+01:00</offset-time> | |
542 | </td> | |
543 | <td>Available with Java 8 or greater.</td> | |
544 | <td>normal</td> | |
545 | </tr> | |
546 | <tr> | |
547 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/PeriodConverter.html">PeriodConverter</a></td> | |
548 | <td>java.time.Period</td> | |
549 | <td class="example"> | |
550 | <period>P1000D</period> | |
551 | </td> | |
552 | <td>Available with Java 8 or greater.</td> | |
553 | <td>normal</td> | |
554 | </tr> | |
555 | <tr> | |
556 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/SystemClockConverter.html">SystemClockConverter</a></td> | |
557 | <td>java.time.Clock$SystemClock</td> | |
558 | <td class="example"> | |
559 | <system-clock> | |
560 | <zone>Europe/Berlin</zone> | |
561 | </system-clock> | |
562 | </td> | |
563 | <td>Available with Java 8 or greater.</td> | |
564 | <td>normal</td> | |
565 | </tr> | |
566 | <tr> | |
567 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/YearConverter.html">YearConverter</a></td> | |
568 | <td>java.time.Year</td> | |
569 | <td class="example"> | |
570 | <year>2017</year> | |
571 | </td> | |
572 | <td>Available with Java 8 or greater.</td> | |
573 | <td>normal</td> | |
574 | </tr> | |
575 | <tr> | |
576 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/YearMonthConverter.html">YearMonthConverter</a></td> | |
577 | <td>java.time.YearMonth</td> | |
578 | <td class="example"> | |
579 | <year-month>2017-02</year-month> | |
580 | </td> | |
581 | <td>Available with Java 8 or greater.</td> | |
582 | <td>normal</td> | |
583 | </tr> | |
584 | <tr> | |
585 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/ZonedDateTimeConverter.html">ZonedDateTimeConverter</a></td> | |
586 | <td>java.time.ZonedDateTime</td> | |
587 | <td class="example"> | |
588 | <zoned-date-time>2017-10-30T20:40:00Z[Europe/London]</zoned-date-time> | |
589 | </td> | |
590 | <td>Available with Java 8 or greater.</td> | |
591 | <td>normal</td> | |
592 | </tr> | |
593 | <tr> | |
594 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/ZoneIdConverter.html">ZoneIdConverter</a></td> | |
595 | <td>java.time.ZoneId<br/>java.time.ZoneOffset<br/>java.time.ZoneRegion</td> | |
596 | <td class="example"> | |
597 | <zone-id>Z</zone-id> | |
598 | </td> | |
599 | <td>Available with Java 8 or greater.</td> | |
600 | <td>normal</td> | |
601 | </tr> | |
602 | ||
603 | <!-- .................................................................................................. --> | |
604 | <tr> | |
605 | <td colspan="5" class="headerRow"><h1 id="java.time.chrono">java.time.chrono</h1></td> | |
606 | </tr> | |
607 | <tr> | |
608 | <th>Converter</th> | |
609 | <th>Supported types</th> | |
610 | <th>Example</th> | |
611 | <th>Notes</th> | |
612 | <th>Prio</th> | |
613 | </tr> | |
614 | <tr> | |
615 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/ChronologyConverter.html">ChronologyConverter</a></td> | |
616 | <td>java.time.chrono.Chronology implementations</td> | |
617 | <td class="example"> | |
618 | <chronology>ISO</chronology> | |
619 | </td> | |
620 | <td>Available with Java 8 or greater.</td> | |
621 | <td>normal</td> | |
622 | </tr> | |
623 | <tr> | |
624 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/HijrahDateConverter.html">HijrahDateConverter</a></td> | |
625 | <td>java.time.chrono.HijrahDate</td> | |
626 | <td class="example"> | |
627 | <hijrah-date>Hijrah-umalqura AH 1438-11-07</hijrah-date> | |
628 | </td> | |
629 | <td>Available with Java 8 or greater.</td> | |
630 | <td>normal</td> | |
631 | </tr> | |
632 | <tr> | |
633 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/JapaneseDateConverter.html">JapaneseDateConverter</a></td> | |
634 | <td>java.time.chrono.JapaneseDate</td> | |
635 | <td class="example"> | |
636 | <japanese-date>Japanese Heisei 29-07-30</japanese-date> | |
637 | </td> | |
638 | <td>Available with Java 8 or greater.</td> | |
639 | <td>normal</td> | |
640 | </tr> | |
641 | <tr> | |
642 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/JapaneseEraConverter.html">JapaneseEraConverter</a></td> | |
643 | <td>java.time.chrono.JapaneseEra</td> | |
644 | <td class="example"> | |
645 | <japanese-era>Taisho</japanese-era> | |
646 | </td> | |
647 | <td>Available with Java 8 or greater.</td> | |
648 | <td>normal</td> | |
649 | </tr> | |
650 | <tr> | |
651 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/MinguoDateConverter.html">MinguoDateConverter</a></td> | |
652 | <td>java.time.chrono.MinguoDate</td> | |
653 | <td class="example"> | |
654 | <minguo-date>Minguo ROC 106-07-30</minguo-date> | |
655 | </td> | |
656 | <td>Available with Java 8 or greater.</td> | |
657 | <td>normal</td> | |
658 | </tr> | |
659 | <tr> | |
660 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/ThaiBuddhistDateConverter.html">ThaiBuddhistDateConverter</a></td> | |
661 | <td>java.time.chrono.ThaiBuddhistDate</td> | |
662 | <td class="example"> | |
663 | <thai-buddhist-date>haiBuddhist BE 2560-07-30</thai-buddhist-date> | |
664 | </td> | |
665 | <td>Available with Java 8 or greater.</td> | |
666 | <td>normal</td> | |
667 | </tr> | |
668 | ||
669 | <!-- .................................................................................................. --> | |
670 | <tr> | |
671 | <td colspan="5" class="headerRow"><h1 id="java.time.temporal">java.time.temporal</h1></td> | |
672 | </tr> | |
673 | <tr> | |
674 | <th>Converter</th> | |
675 | <th>Supported types</th> | |
676 | <th>Example</th> | |
677 | <th>Notes</th> | |
678 | <th>Prio</th> | |
679 | </tr> | |
680 | <tr> | |
681 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/ValueRangeConverter.html">ValueRangeConverter</a></td> | |
682 | <td>java.time.temporal.ValueRange</td> | |
683 | <td class="example"> | |
684 | <temporal-value-range><br/> | |
685 | <maxLargest>45</maxLargest><br/> | |
686 | <maxSmallest>30</maxSmallest><br/> | |
687 | <minLargest>1</minLargest><br/> | |
688 | <minSmallest>0</minSmallest><br/> | |
689 | </temporal-value-range> | |
690 | </td> | |
691 | <td>Available with Java 8 or greater.</td> | |
692 | <td>normal</td> | |
693 | </tr> | |
694 | <tr> | |
695 | <td><a href="javadoc/com/thoughtworks/xstream/converters/time/WeekFieldsConverter.html">WeekFieldsConverter</a></td> | |
696 | <td>java.time.temporal.WeekFields</td> | |
697 | <td class="example"> | |
698 | <week-fields><br/> | |
699 | <minimalDays>2</minimalDays><br/> | |
700 | <firstDayOfWeek>MONDAY</firstDayOfWeek><br/> | |
701 | </week-fields> | |
702 | </td> | |
703 | <td>Available with Java 8 or greater.</td> | |
460 | 704 | <td>normal</td> |
461 | 705 | </tr> |
462 | 706 | |
496 | 740 | <td><a href="javadoc/com/thoughtworks/xstream/converters/extended/ISO8601SqlTimestampConverter.html">ISO8601SqlTimestampConverter</a></td> |
497 | 741 | <td>java.sql.Timestamp</td> |
498 | 742 | <td class="example"><sql-timestamp>2006-07-28T12:06:17.654000000-03:00</sql-timestamp></td> |
499 | <td>Not automatically registered, can be used globally or locally. Implementation needs joda-time.</td> | |
743 | <td>Not automatically registered, can be used globally or locally. Implementation needs joda-time for JDK 1.7 or below.</td> | |
500 | 744 | <td> </td> |
501 | 745 | </tr> |
502 | 746 | |
606 | 850 | <td><a href="javadoc/com/thoughtworks/xstream/converters/extended/CharsetConverter.html">CharsetConverter</a></td> |
607 | 851 | <td>java.nio.charset.Charset</td> |
608 | 852 | <td class="example"><charset>US-ASCII</charset></td> |
609 | <td>Available under Java 1.4 or greater.</td> | |
853 | <td>Available with Java 1.4 or greater.</td> | |
610 | 854 | <td>normal</td> |
611 | 855 | </tr> |
612 | 856 | <tr> |
613 | 857 | <td><a href="javadoc/com/thoughtworks/xstream/converters/extended/PathConverter.html">PathConverter</a></td> |
614 | 858 | <td>java.nio.file.Path</td> |
615 | 859 | <td class="example"><path>../dir/file.txt</path></td> |
616 | <td>Available under Java 1.7 or greater.</td> | |
860 | <td>Available with Java 7 or greater.</td> | |
617 | 861 | <td>normal</td> |
618 | 862 | </tr> |
619 | 863 | |
632 | 876 | <td><a href="javadoc/com/thoughtworks/xstream/converters/extended/JavaClassConverter.html">JavaClassConverter</a></td> |
633 | 877 | <td>java.lang.Class</td> |
634 | 878 | <td class="example"><class>com.foo.MyThing</class></td> |
635 | <td>This converter uses the ClassLoaderReference of the XStream insatance. Can be regisreted with | |
879 | <td>This converter uses the ClassLoaderReference of the XStream instance. Can be registered with | |
636 | 880 | Mapper globally or locally to respect type aliases.</td> |
637 | 881 | <td>normal</td> |
638 | 882 | </tr> |
645 | 889 | <class>com.foo.MyThing</class><br/> |
646 | 890 | </field> |
647 | 891 | </td> |
648 | <td>This converter uses the ClassLoaderReference of the XStream insatance. Can be regisreted with | |
892 | <td>This converter uses the ClassLoaderReference of the XStream instance. Can be registered with | |
649 | 893 | Mapper globally or locally to respect type aliases.</td> |
650 | 894 | <td>normal</td> |
651 | 895 | </tr> |
752 | 996 | |
753 | 997 | <!-- .................................................................................................. --> |
754 | 998 | <tr> |
755 | <td colspan="5" class="headerRow"><h1 id="java.awt.font">java.awt.font</h1></td> | |
999 | <td colspan="5" class="headerRow"><h1 id="javax.activation">javax.activation</h1></td> | |
756 | 1000 | </tr> |
757 | 1001 | <tr> |
758 | 1002 | <th>Converter</th> |
771 | 1015 | <representationClass>java.io.InputStream</representationClass><br/> |
772 | 1016 | </activation-data-flavor> |
773 | 1017 | </td> |
774 | <td>Available under Java 1.6 or greater. Only automatically registered if runtime has AWT support.<br/> | |
1018 | <td>Available with Java 6, 7 and 8. Requires module <em>java.activation</em> with Java 9 or greater.<br/> | |
775 | 1019 | <td>normal</td> |
776 | 1020 | </tr> |
777 | 1021 | |
816 | 1060 | <readOnly>false</readOnly><br/> |
817 | 1061 | </auth-subject><br/> |
818 | 1062 | </td> |
819 | <td>Available under Java 1.4 or greater. This converter does not serialize any credentials but only the principals.</td> | |
1063 | <td>Available with Java 1.4 or greater. This converter does not serialize any credentials but only the principals.</td> | |
820 | 1064 | <td>normal</td> |
821 | 1065 | </tr> |
822 | 1066 | |
835 | 1079 | <td><a href="javadoc/com/thoughtworks/xstream/converters/extended/DurationConverter.html">DurationConverter</a></td> |
836 | 1080 | <td>javax.xml.datatype.Duration</td> |
837 | 1081 | <td class="example"><duration>PT1H2M</duration></td> |
838 | <td>Available under Java 1.5 or greater.</td> | |
1082 | <td>Available with Java 1.5 or greater.</td> | |
839 | 1083 | <td>normal</td> |
840 | 1084 | </tr> |
841 | 1085 | |
875 | 1119 | <tr> |
876 | 1120 | <td><a href="javadoc/com/thoughtworks/xstream/converters/reflection/ExternalizableConverter.html">ExternalizableConverter</a></td> |
877 | 1121 | <td>java.io.Externalizable</td> |
878 | <td>The Converter is used for any JDK-externalizable types, if not handled by a specialized Converter.</td> | |
1122 | <td>The Converter is used for any externalizable type, if not handled by a specialized Converter.</td> | |
879 | 1123 | <td> </td> |
880 | 1124 | <td>low</td> |
881 | 1125 | </tr> |
882 | 1126 | <tr> |
883 | 1127 | <td><a href="javadoc/com/thoughtworks/xstream/converters/reflection/LambdaConverter.html">LambdaConverter</a></td> |
884 | <td>For serializable and non-serializable lambda types. Noon-serialzable lambda instances will be mapped to null, since they | |
885 | contain no information for recreation. Serializable lambda types have such info, but it is specific to compiler vendor and | |
886 | occurrence in the code. Never assume that you can deserialize such an element when you use a different version of your code | |
887 | or a different compiler.</td> | |
888 | <td> </td> | |
889 | <td>Only automatically registered for Java 8.</td> | |
1128 | <td>For serializable lambda types.</td> | |
1129 | <td>Non-serializable lambda instances will be mapped to null, since they contain no information for recreation. Serializable | |
1130 | lambda types have such info, but it is specific to compiler vendor and occurrence in the code. Never assume that you can | |
1131 | deserialize such an element when you use a different version of your code or a different compiler.</td> | |
1132 | <td>Available with Java 8 or greater.</td> | |
890 | 1133 | <td>normal</td> |
891 | 1134 | </tr> |
892 | 1135 | <tr> |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | 2 | Copyright (C) 2005, 2006 Joe Walnes. |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2015, 2016 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2015, 2016, 2017, 2018 XStream committers. | |
4 | 4 | All rights reserved. |
5 | 5 | |
6 | 6 | The software in this package is published under the terms of the BSD |
17 | 17 | |
18 | 18 | <p><a href="versioning.html">About XStream version numbers...</a></p> |
19 | 19 | |
20 | <h1 id="stable">Stable Version: <span class="version">1.4.9</span></h1> | |
20 | <h1 id="stable">Stable Version: <span class="version">1.4.11.1</span></h1> | |
21 | 21 | |
22 | 22 | <ul> |
23 | <li><b><a href="http://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream-distribution/1.4.9/xstream-distribution-1.4.9-bin.zip">Binary distribution:</a></b> | |
23 | <li><b><a href="http://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream-distribution/1.4.11.1/xstream-distribution-1.4.11.1-bin.zip">Binary distribution:</a></b> | |
24 | 24 | Contains the XStream jar files, the Hibernate and Benchmark modules and all the dependencies.</li> |
25 | <li><b><a href="http://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream-distribution/1.4.9/xstream-distribution-1.4.9-src.zip">Source distribution:</a></b> | |
25 | <li><b><a href="http://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream-distribution/1.4.11.1/xstream-distribution-1.4.11.1-src.zip">Source distribution:</a></b> | |
26 | 26 | Contains the complete XStream project as if checked out from the Subversion version tag.</li> |
27 | <li><b><a href="http://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream/1.4.9/xstream-1.4.9.jar">XStream Core only:</a> | |
27 | <li><b><a href="http://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream/1.4.11.1/xstream-1.4.11.1.jar">XStream Core only:</a> | |
28 | 28 | The xstream.jar only as it is downloaded automatically when it is referenced as Maven dependency.</b></li> |
29 | <li><b><a href="http://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream-hibernate/1.4.9/xstream-hibernate-1.4.9.jar">XStream Hibernate module:</a></b> | |
29 | <li><b><a href="http://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream-hibernate/1.4.11.1/xstream-hibernate-1.4.11.1.jar">XStream Hibernate module:</a></b> | |
30 | 30 | The xstream-hibernate.jar as it is downloaded automatically when it is referenced as Maven dependency.</li> |
31 | <li><b><a href="http://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream-benchmark/1.4.9/xstream-jmh-1.4.9.jar">XStream JMH module:</a></b> | |
32 | The xstream-jmh.jar as it is downloaded automatically when it is referenced as Maven dependency.</li> | |
31 | <li><b><a href="http://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream-jmh/1.4.11.1/xstream-jmh-1.4.11.1-app.zip">XStream JMH module:</a></b> | |
32 | The xstream-jmh-app.zip as standalone application with start scripts and all required libraries.</li> | |
33 | <li><b><a href="http://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream/1.4.11-java7/xstream-1.4.11-java7.jar">XStream Core for Java 7 only:</a> | |
34 | The xstream.jar only <a href="faq.html#Compatibility_Android">without the Java 8 stuff</a> as it is downloaded automatically when it is referenced as Maven dependency.</b></li> | |
33 | 35 | </ul> |
34 | ||
35 | <!-- | |
36 | <h1 id="snapshot">Latest Snapshot HEAD revision</h1> | |
37 | ||
38 | <p>Below are builds of the latest HEAD version of XStream from the <a href="repository.html">repository</a>.</p> | |
39 | ||
40 | <ul> | |
41 | <li><a href="https://nexus.codehaus.org/content/groups/public/com/thoughtworks/xstream/xstream-distribution/1.5.0-SNAPSHOT/">Complete distributions</a></li> | |
42 | <li><a href="https://nexus.codehaus.org/content/groups/public/com/thoughtworks/xstream/xstream/1.5.0-SNAPSHOT/">XStream Core only</a></li> | |
43 | <li><a href="https://nexus.codehaus.org/content/groups/public/com/thoughtworks/xstream/xstream-hibernate/1.5.0-SNAPSHOT/">XStream Hibernate module</a></li> | |
44 | <li><a href="https://nexus.codehaus.org/content/groups/public/com/thoughtworks/xstream/xstream-benchmark/1.5.0-SNAPSHOT/">XStream Benchmark module</a></li> | |
45 | </ul> | |
46 | ||
47 | <h1 id="snapshot-1.4.x">Latest Snapshot 1.4.x BRANCH revision</h1> | |
48 | ||
49 | <p>Below are builds of the latest 1.4.x branch version of XStream from the <a href="repository.html">repository</a>.</p> | |
50 | ||
51 | <ul> | |
52 | <li><a href="https://nexus.codehaus.org/content/groups/public/com/thoughtworks/xstream/xstream-distribution/1.4.10-SNAPSHOT/">Complete distributions (1.4.x)</a></li> | |
53 | <li><a href="https://nexus.codehaus.org/content/groups/public/com/thoughtworks/xstream/xstream/1.4.10-SNAPSHOT/">XStream Core only (1.4.x)</a></li> | |
54 | <li><a href="https://nexus.codehaus.org/content/groups/public/com/thoughtworks/xstream/xstream-hibernate/1.4.10-SNAPSHOT/">XStream Hibernate module (1.4.x)</a></li> | |
55 | <li><a href="https://nexus.codehaus.org/content/groups/public/com/thoughtworks/xstream/xstream-jmh/1.4.10-SNAPSHOT/">XStream JMH module (1.4.x)</a></li> | |
56 | </ul> | |
57 | --> | |
58 | 36 | |
59 | 37 | <h1 id="previous-releases">Previous Releases</h1> |
60 | 38 | |
67 | 45 | |
68 | 46 | <h1 id="optional-deps">Optional Dependencies</h1> |
69 | 47 | |
48 | <p>Note, that all those dependencies can be optional. XStream uses by default the XPP API in combination with the | |
49 | Xpp3 implementation. Therefore are these dependencies not declared as optional in Maven. However, depending on your | |
50 | choice of the XML parser, you can exclude the dependencies for the XPP API (e.g. by selecting Xpp3 directly) or | |
51 | Xpp3 (e.g. by selecting StAX). You will then have to declare the dependencies for the alternative XML parser | |
52 | yourself unless you use a parser form the Java runtime.</p> | |
53 | ||
70 | 54 | <ul> |
71 | 55 | <li>Supported XML parsers and packages: |
72 | 56 | <ul> |
83 | 67 | </li> |
84 | 68 | <li>Other optional 3rd party dependencies: |
85 | 69 | <ul> |
86 | <li><a href="http://downloads.sourceforge.net/joda-time/joda-time-1.6.zip">Joda Time</a> for optional ISO8601 date/time formats.</li> | |
70 | <li><a href="http://repo.maven.apache.org/maven2/javax/activation/activation/1.1.1/activation-1.1.1.jar">Java Activation module</a> for the ActivationDataFlavorConverter. The dependency is required for the Java 11 runtime.</li> | |
71 | <li><a href="http://downloads.sourceforge.net/joda-time/joda-time-1.6.zip">Joda Time</a> for optional ISO8601 date/time converters in JDK 1.7 or below.</li> | |
87 | 72 | <li><a href="http://downloads.sourceforge.net/cglib/cglib-nodep-2.2.jar">CGLIB</a> for optional support of some proxies generated with the CGLIB Enhancer.</li> |
88 | 73 | <li><a href="http://repo.maven.apache.org/maven2/org/codehaus/jettison/jettison/1.2/jettison-1.2.jar">Jettison</a> for serialization and deserialization support with JSON. Note, that newer versions 1.3.x are no longer compatible with XStream.</li> |
89 | 74 | <li><a href="http://repo.maven.apache.org/maven2/org/codehaus/jettison/jettison/1.0/jettison-1.0.jar">Jettison 1.0.1</a> for serialization and deserialization support with JSON in JDK 1.4. Note, that newer version 1.1 is not compatible with XStream.</li> |
114 | 99 | <ul> |
115 | 100 | <li>JMH dependencies: |
116 | 101 | <ul> |
117 | <li><a href="http://repo.maven.apache.org/maven2/org/openjdk/jmh-core/1.11.1/jmh-core-1.11.1.jar">JMH Core 1.11.1</a>, for Java 6 or higher.</li> | |
118 | <li><a href="http://repo.maven.apache.org/maven2/org/openjdk/jmh-generator-annprocess/1.11.1/jmh-generator-annprocess-1.11.1.jar">JMH Generator Annotation Processor 1.11.1</a>, for Java 6 or higher.</li> | |
102 | <li><a href="http://repo.maven.apache.org/maven2/org/openjdk/jmh-core/1.19/jmh-core-1.19.jar">JMH Core 1.19</a>, for Java 6 or higher.</li> | |
103 | <li><a href="http://repo.maven.apache.org/maven2/org/openjdk/jmh-generator-annprocess/1.19/jmh-generator-annprocess-1.19.jar">JMH Generator Annotation Processor 1.19</a>, for Java 6 or higher.</li> | |
119 | 104 | </ul> |
120 | 105 | </li> |
121 | 106 | </ul> |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | 2 | Copyright (C) 2005, 2006 Joe Walnes. |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 XStream committers. | |
4 | 4 | All rights reserved. |
5 | 5 | |
6 | 6 | The software in this package is published under the terms of the BSD |
30 | 30 | <h1 id="Compatibility">Compatibility</h1> |
31 | 31 | |
32 | 32 | <!-- ...................................................... --> |
33 | <h2 id="Compatibility_JDK">Which JDK is required to use XStream?</h2> | |
34 | <p>1.4 or later.</p> | |
33 | <h2 id="Compatibility_JRE">Which Java runtime is required to run XStream?</h2> | |
34 | <p>XStream 1.4.x requires Java 1.4 or later. Note, that the XStream libraries contains class files targeting | |
35 | different Java runtime versions or Java features. These classes are loaded by reflection and only used if XStream | |
36 | is running on an appropriate runtime environment.</p> | |
37 | <p>Environments that load all class files of a Java archive can fail with this approach, the | |
38 | <a href="#Compatibility_Android">Android runtime</a> is such an example. You can build your own version of XStream | |
39 | with a <a href="#Compatibility_JDK">lower JDK</a> then.</p> | |
40 | <p>For Java 9 and later you will currently have to permit the now illegal access for XStream to operate.</p> | |
41 | ||
42 | <!-- ...................................................... --> | |
43 | <h2 id="Compatibility_JDK">Which JDK is required to build XStream?</h2> | |
44 | <p>XStream 1.4.x can be build still with JDK 1.4 (see BUILD.txt). However, to support the latest features it | |
45 | requires currently a JDK of Java 8. Otherwise the resulting jar file will miss some class files not available on | |
46 | earlier runtimes. Depending on the target environment this can be useful (e.g. for Android or GAE).</p> | |
47 | <p>Note, that such Java archives will fail on higher Java runtimes then.</p> | |
35 | 48 | |
36 | 49 | <!-- ...................................................... --> |
37 | 50 | <h2 id="Compatibility_Dependencies">Which dependencies are required to run XStream?</h2> |
39 | 52 | However it depends on the use case. XStream will run without dependencies using the DOM driver on all Java runtimes |
40 | 53 | or the StAX driver in combination with Java 6 or greater. See the list of <a |
41 | 54 | href="download.html#optional-deps">optional dependencies</a>.</p> |
55 | <p>Note, that XStream's manifest contains OSGi entries that declare all dependencies as optional.</p> | |
42 | 56 | |
43 | 57 | <!-- ...................................................... --> |
44 | 58 | <h2 id="Compatibility_JVMs">Does XStream behave differently across different JVMs?</h2> |
51 | 65 | <!-- ...................................................... --> |
52 | 66 | <h2 id="Compatibility_enhanced_mode_jvm">Which JVMs allow XStream to operate in enhanced mode?</h2> |
53 | 67 | |
54 | <p>XStream will check since version 1.4.5 a working enhanced mode dynamically if it is available based on | |
55 | undocumented internal Java runtime classes. This enhanced mode is known to be working on the Oracle/Sun, Apple, HP, | |
56 | IBM and Blackdown 1.4 JVMs and onwards, for IcedTea 6 and onwards, for Hitachi, SAP and Diablo from 1.5 and | |
57 | onwards, for BEA JRockit starting with R25.1.0. Generally it works for all modern Java runtimes based on OpenJDK. | |
58 | Android basically supports the enhanced mode as well as the Google ApplicationEngine, but the latter's security | |
59 | model limits the types that can be handled. Note, that an active SecurityManager might prevent the usage of the | |
60 | enhanced mode also.</p> | |
68 | <p>XStream checks since version 1.4.5 automatically for a working enhanced mode - based on undocumented internal | |
69 | Java runtime classes. This enhanced mode is known to be working on the Oracle/Sun, Apple, HP, IBM and Blackdown | |
70 | 1.4 JVMs and onwards, for IcedTea 6 and onwards, for Hitachi, SAP and Diablo from 1.5 and onwards, for BEA JRockit | |
71 | starting with R25.1.0. Generally it works for all modern Java runtimes based on OpenJDK. Android basically supports | |
72 | the enhanced mode as well as the Google Application Engine, but the latter's security model limits the types that | |
73 | can be handled. Note, that an active SecurityManager might prevent the usage of the enhanced mode also.</p> | |
74 | <p>Since Java 9 it is required to permit the now illegal access.</p> | |
61 | 75 | |
62 | 76 | <!-- ...................................................... --> |
63 | 77 | <h2 id="Compatibility_enhanced_mode_advantage">What are the advantages of using enhanced mode over pure Java mode?</h2> |
80 | 94 | </table> |
81 | 95 | |
82 | 96 | <!-- ...................................................... --> |
97 | <h2 id="Compatibility_illegal_reflective_access">Java runtime warns me about an illegal reflective access by XStream!</h2> | |
98 | ||
99 | <p>Yes, this is normal. A big part of XStream is reflection based and there is currently no replacement for the | |
100 | complete required functionality. You will have to permit this access currently, otherwise XStream will not work.</p> | |
101 | ||
102 | <!-- ...................................................... --> | |
103 | <h2 id="Compatibility_no_module">Why does XStream not even declare an automated module name?</h2> | |
104 | ||
105 | <p>Such a declaration would move XStream automatically into the module class path. However, in this environment a | |
106 | lot of functionality does no longer work. Therefore it is on purpose that XStream stays currently in the unnamed | |
107 | module.</p> | |
108 | ||
109 | <!-- ...................................................... --> | |
110 | <h2 id="Compatibility_JPMS">Will XStream support the Java Platform Module System (JPMS)?</h2> | |
111 | ||
112 | <p>At some point definitely. However, you will have to accept a limited functionality only, comparable to the pure | |
113 | Java mode. The access model is very restrictive and XStream will no longer be able to marshal all types of the Java | |
114 | runtime like now.</p> | |
115 | ||
116 | <!-- ...................................................... --> | |
83 | 117 | <h2 id="Compatibility_XPP">Why is my application not able to create a XmlPullParser with the XppDriver since XStream 1.4?</h2> |
84 | 118 | |
85 | 119 | <p>The <a href="http://www.xmlpull.org/">XML Pull Parser API</a> defines an own mechanism to load the factory for |
98 | 132 | the JavaBeanConverter. Note, that Android provides an XML Pull Parser, therefore XStream can work without |
99 | 133 | additional dependencies.</p> |
100 | 134 | |
135 | <p>XStream contains class files targeting different Java runtime versions. Depending on the target version of | |
136 | Android, it is not possible to use the original XStream library directly, because it tries to convert all classes | |
137 | of XStream to the Dalvik runtime. You might have to build a custom version of XStream (see BUILD.txt) with a JDK | |
138 | that is equivalent to the Java level supported by the target version of Android.</p> | |
139 | ||
140 | <p>Since XStream 1.4.10 an additional artifact is deployed to the Central Maven Repository with <em>-java7</em> | |
141 | appended to the version that explicitly does not contain any Java 8 related stuff. Note that this version will fail | |
142 | on higher runtimes.</p> | |
143 | ||
101 | 144 | <!-- ...................................................... --> |
102 | 145 | <h2 id="Compatibility_GAE">Which limits exists for XStream in Google's Application Engine (GAE)?</h2> |
103 | 146 | |
134 | 177 | for details. Actually XStream's converters try to check since version 1.4.6 any critical operation, before they |
135 | 178 | claim to be able to handle a type. As consequence XStream can behave differently running under a SecurityManager. |
136 | 179 | E.g. if the SecurityManager does not permit to create an instance for a derived class of ObjectOutputStream, the |
137 | SerializationConverter will not handle any type and the ReflecitonConverter will take over (as long it has proper | |
180 | SerializationConverter will not handle any type and the ReflectionConverter will take over (as long it has proper | |
138 | 181 | rights for its own reflection-based operations).</p> |
139 | 182 | |
140 | 183 | <!-- ...................................................... --> |
171 | 214 | <a href="#Serialization_sort_fields">sort the fields</a> according XStream 1.2.2.</p> |
172 | 215 | |
173 | 216 | <!-- ...................................................... --> |
174 | <h2 id="Compatibility_WebSphere_8">WebShere 8 can no longer use XStream 1.4.x?</h2> | |
217 | <h2 id="Compatibility_WebSphere_8">WebSphere 8 can no longer use XStream 1.4.x?</h2> | |
175 | 218 | |
176 | 219 | <p>XStream has a long history to support types from recent JDKs without dropping backward compatibility. Therefore it contains class files targeting different JDKs. |
177 | 220 | However, WebShpere scans by default all JAR files in its classpath for annotations to support CDI independent of the presence of a beans.xml file in META-INF. This |
679 | 722 | <!-- ...................................................... --> |
680 | 723 | <h2 id="Security_EventHandler">Why does XStream not convert an java.beans.EventHandler?</h2> |
681 | 724 | |
682 | <p>Since XStream verison 1.4.7 it does no longer handle an | |
725 | <p>Since XStream version 1.4.7 it does no longer handle an | |
683 | 726 | <a href="http://docs.oracle.com/javase/7/docs/api/java/beans/EventHandler.html">EventHandler</a> automatically. |
684 | Such an instance can be used to initiate calls on arbitray instances at deserialization time e.g. | |
727 | Such an instance can be used to initiate calls on arbitrary instances at deserialization time e.g. | |
685 | 728 | <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html#start()">ProcessBuilder.start()</a> |
686 | 729 | You can register a ReflectionConverter instance explicitly for the EventHandler if you need support for such |
687 | 730 | instances.</p> |
706 | 749 | </ul> |
707 | 750 | |
708 | 751 | <!-- ...................................................... --> |
709 | <h2 id="Security_XXEVulnerability">Is XStream XXE vulnerable?</h2> | |
752 | <h2 id="Security_VulnerabilityWarning">XStream suddenly emits a vulnerability warning!</h2> | |
753 | ||
754 | <p>If the security framework has not been initialized, XStream will emit such a warning since version 1.4.10. You | |
755 | use the <a href="security.html">security rules</a> to setup a white list of class types that will be processed.</p> | |
756 | ||
757 | <p>For XStream 1.4.x you may call the setupDefaultSecurity method to initialize a XStream instance in the same way | |
758 | as it will be done for XStream 1.5.x. This means also a compatibility preparation for XStream 1.5.x.</p> | |
759 | ||
760 | <!-- ...................................................... --> | |
761 | <h2 id="Security_XXEVulnerability">Is XStream XXE vulnerable (CVE-2016-3674)?</h2> | |
710 | 762 | |
711 | 763 | <p>XStream does not contain an own XML parser, therefore it depends on the parser selected with the |
712 | 764 | <a href="javadoc/com/thoughtworks/xstream/io/HierarchicalStreamDriver.html">HierarchicalStreamDriver</a> |
713 | 765 | if the current XStream instance is <a href="https://www.owasp.org/index.php/XML_External_Entity_%28XXE%29_Processing"> |
714 | XXE vulnerable</a> at deserialization time. However, XStream tries to deactivate the processing of external | |
766 | XXE vulnerable</a> at deserialization time. However, XStream tries to deactivate the processing of external | |
715 | 767 | entities by default. Status for the different supported XML parsers:</p> |
716 | 768 | |
717 | 769 | <table summary="Comparison of drivers regarding XEE vulnerability"> |
722 | 774 | <tr><td>Dom4JDriver</td><td>no</td><td>Driver turns off DOCTYPE processing to suppress handling of external |
723 | 775 | entities with SAX reader in use.</td></tr> |
724 | 776 | <tr><td>DomDriver</td><td>no, Java 6 or higher<br/>yes, Java 5</td><td>Driver turns off DOCTYPE processing with |
725 | Java 7 runtime or higher to suppress handling of external entities with SAX reader in use. Suppress external | |
777 | Java 7 runtime or higher to suppress handling of external entities with SAX reader in use. Suppress external | |
726 | 778 | entities only for Java 6 or lower, fails for parameterized entities.</td></tr> |
727 | 779 | <tr><td>JDomDriver</td><td>no</td><td>Driver turns off DOCTYPE processing to suppress handling of external |
728 | 780 | entities with SAX reader in use.</td></tr> |
731 | 783 | <tr><td>KXml2DomDriver</td><td>no</td><td>kXML2 parser does not support entities.</td></tr> |
732 | 784 | <tr><td>KXml2Driver</td><td>no</td><td>kXML2 parser does not support entities.</td></tr> |
733 | 785 | <tr><td>SjsxpDriver</td><td>no, Java 7 or higher<br/>yes, Java 6</td><td>Driver turns off support for external |
734 | entities for the internal StaX parser of the Sun JDK, but fails for parameter entities in a Java 6 runtime.</td></tr> | |
735 | <tr><td>StandardStaxDriver</td><td>?</td><td>Driver tries to turns off support for external entities for | |
736 | the internal StaX parser of the Java runtime. Save for Oracle JDK 7 or higher.</td></tr> | |
786 | entities for the internal StaX parser of the Sun JDK, but fails for parameter entities in a Java 6 runtime.</td></tr> | |
787 | <tr><td>StandardStaxDriver</td><td>?</td><td>Driver tries to turn off support for external entities for | |
788 | the internal StaX parser of the Java runtime. Save for Oracle JDK 7 or higher.</td></tr> | |
737 | 789 | <tr><td>StaxDriver</td><td>?</td><td>Driver tries to turns off support for external entities for the |
738 | standard StaX parser. However, the finally used StAX implementation is defined externally (see JDK | |
790 | standard StaX parser. However, the finally used StAX implementation is defined externally (see JDK | |
739 | 791 | documentation) and a test should be made on the target platform to ensure that the parser respects the setting.</td></tr> |
740 | 792 | <tr><td>WstxDriver</td><td>no</td><td>Driver turns off support for external entities for the Woodstox StAX |
741 | 793 | parser.</td></tr> |
744 | 796 | </table> |
745 | 797 | |
746 | 798 | <p class="highlight">Note: Only a HierarchicalStreamReader created with the HierarchicalStreamDriver is setup to |
747 | avoid the XXE vulnerability. If you create such driver instances on your own, it is your task to setup the XML | |
748 | parser instance on your own.</p> | |
799 | avoid the XXE vulnerability. If you create such driver instances on your own, it is also your task to setup the XML | |
800 | parser instance properly.</p> | |
749 | 801 | |
750 | 802 | <!-- ****************************************************** --> |
751 | 803 | <h1 id="Other_Products">Comparison to other products</h1> |
774 | 826 | allowing objects to be serialized/deserialized concurrently (unless you enable the |
775 | 827 | <a href="annotations-tutorial.html#AutoDetect">auto-detection</a> to process annotations on-the-fly). Actually the |
776 | 828 | creation and initialization of XStream is quite expensive, therefore it is recommended to keep the XStream instance |
777 | itself. If you abolutely have to rely on annotation processing on the fly, you will have to use separate XStream | |
778 | instances for each thread - either by using everytime a new instance or by a shared pool.</p> | |
829 | itself. If you absolutely have to rely on annotation processing on the fly, you will have to use separate XStream | |
830 | instances for each thread - either by using every time a new instance or by a shared pool.</p> | |
779 | 831 | |
780 | 832 | <!-- ...................................................... --> |
781 | 833 | <h2 id="Scalability_Memory">How much memory does XStream consume?</h2> |
831 | 883 | <!-- ...................................................... --> |
832 | 884 | <h2 id="Uses_Generate_Code">Can XStream generate classes from XSD?</h2> |
833 | 885 | |
834 | <p>No. For this kind of work a data binding tool such as <a href="http://xmlbeans.apache.org">XMLBeans</a> is appropriate.</p> | |
886 | <p>No. For this kind of work data binding tools such as JAXB or <a href="http://xmlbeans.apache.org">XMLBeans</a> are | |
887 | appropriate.</p> | |
835 | 888 | |
836 | 889 | <!-- ...................................................... --> |
837 | 890 | <h2 id="Uses_No_SAX_Reader">Why is there no SaxReader?</h2> |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | 2 | Copyright (C) 2005, 2006 Joe Walnes. |
3 | Copyright (C) 2006, 2007, 2008, 2011, 2012, 2013, 2014, 2015, 2016 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2008, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 XStream committers. | |
4 | 4 | All rights reserved. |
5 | 5 | |
6 | 6 | The software in this package is published under the terms of the BSD |
72 | 72 | |
73 | 73 | <h1 id="news">Latest News</h1> |
74 | 74 | |
75 | <h2 id="1.4.9"><b>March 15, 2016</b> XStream 1.4.9 released</h2> | |
75 | <h2 id="1.4.11.1"><b>October 27, 2018</b> XStream 1.4.11.1 released</h2> | |
76 | 76 | |
77 | <p>Maintenance release 1.4.9 of XStream with bug fixes eliminating XXE vulnerability and new benchmark module.</p> | |
77 | <p class="highlight">Hot fix for XStream 1.4.11: Accidental breakage of Java runtimes %lt; 8.</p> | |
78 | 78 | |
79 | <p>Several parsers were vulnerable by processing external entities (XXE vulnerability). This has been turned off as far as possible.</p> | |
79 | <p class="highlight">This maintenance release addresses again the security vulnerability <a href="CVE-2013-7285.html"> | |
80 | CVE-2013-7285</a>, an arbitrary execution of commands when unmarshalling for XStream instances with | |
81 | uninitialized security framework. Only 1.4.10 with uninitialized security framework was affected.</p> | |
80 | 82 | |
81 | <p>The home-grown benchmark module has been replaced using an implementation based on JMH.</p> | |
83 | <p>New future-proof method JVM.isVersion to detect major version of Java runtime (incl. Java 10) as | |
84 | replacement for individual JVM.isXY methods.</p> | |
82 | 85 | |
83 | <p>XStream supports now java.nio.Path with a specialized converter.</p> | |
86 | <p>View the complete <a href="changes.html">change log</a> and <a href="download.html">download</a>.</p> | |
84 | 87 | |
85 | 88 | <p>Note, the next major release 1.5 will require Java 7.</p> |
86 | 89 |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | 2 | Copyright (C) 2005, 2006 Joe Walnes. |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 2013, 2014, 2015, 2016 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 XStream committers. | |
4 | 4 | All rights reserved. |
5 | 5 | |
6 | 6 | The software in this package is published under the terms of the BSD |
15 | 15 | |
16 | 16 | <body> |
17 | 17 | |
18 | ||
19 | <h2 id="1.4.11"><b>October 23, 2018</b> XStream 1.4.11 released</h2> | |
20 | ||
21 | <p class="highlight">This maintenance release addresses again the security vulnerability <a href="CVE-2013-7285.html"> | |
22 | CVE-2013-7285</a>, an arbitrary execution of commands when unmarshalling for XStream instances with | |
23 | uninitialized security framework. Only 1.4.10 uninitialized security framework was affected.</p> | |
24 | ||
25 | <p>New future-proof method JVM.isVersion to detect major version of Java runtime (incl. Java 10) as | |
26 | replacement for individual JVM.isXY methods.</p> | |
27 | ||
28 | <p>View the complete <a href="changes.html">change log</a> and <a href="download.html">download</a>.</p> | |
29 | ||
30 | <p>Note, the next major release 1.5 will require Java 7.</p> | |
31 | ||
32 | <h2 id="1.4.10"><b>May 23, 2017</b> XStream 1.4.10 released</h2> | |
33 | ||
34 | <p class="highlight">This maintenance release addresses the security vulnerability <a href="CVE-2017-7957.html"> | |
35 | CVE-2017-7957</a>, a possibility for a denial of service attack. All previous versions are affected.</p> | |
36 | ||
37 | <p>XStream supports now the java.time.* package of Java 8 with various new converters.</p> | |
38 | ||
39 | <p>Emit warning message if XStream instance is still running with an uninitialized security framework.</p> | |
40 | ||
41 | <p>Provide separate XStream artifact without stuff for Java 8.</p> | |
42 | ||
43 | <p>View the complete <a href="changes.html">change log</a> and <a href="download.html">download</a>.</p> | |
44 | ||
45 | <p>Note, the next major release 1.5 will require Java 7.</p> | |
46 | ||
18 | 47 | <h2 id="1.4.9"><b>March 15, 2016</b> XStream 1.4.9 released</h2> |
19 | 48 | |
20 | <p>Maintenance release 1.4.9 of XStream with bug fixes eliminating XXE vulnerability and new benchmark module.</p> | |
21 | ||
22 | <p>Several parsers were vulnerable by processing external entities (XXE vulnerability). This has been turned off as far as possible.</p> | |
49 | <p>Maintenance release 1.4.9 of XStream with bug fixes eliminating <a href="CVE-2016-3674.html">XXE | |
50 | vulnerability</a> and new benchmark module.</p> | |
51 | ||
52 | <p class="highlight"><a href="CVE-2016-3674.html">CVE-2016-3674</a>: Several parsers were vulnerable by | |
53 | processing external entities (XXE vulnerability). This has been turned off as far as possible.</p> | |
23 | 54 | |
24 | 55 | <p>The home-grown benchmark module has been replaced using an implementation based on JMH.</p> |
25 | 56 | |
56 | 87 | |
57 | 88 | <h2 id="1.4.7"><b>February 8, 2014</b> XStream 1.4.7 released</h2> |
58 | 89 | |
59 | <p class="highlight">This maintenance release addresses mainly the security vulnerability CVE-2013-7285, an | |
60 | arbitrary execution of commands when unmarshalling. All previous versions are affected running at least Java 5.</p> | |
90 | <p class="highlight">This maintenance release addresses mainly the security vulnerability | |
91 | <a href="CVE-2013-7285.html">CVE-2013-7285</a>, an arbitrary execution of commands when unmarshalling. All | |
92 | previous versions are affected running at least Java 5.</p> | |
61 | 93 | |
62 | 94 | <p>XStream contains now a security framework to fine-control the unmarshalled types.</p> |
63 | 95 |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | Copyright (C) 2014, 2015 XStream committers. | |
2 | Copyright (C) 2014, 2015, 2017 XStream committers. | |
3 | 3 | All rights reserved. |
4 | 4 | |
5 | 5 | The software in this package is published under the terms of the BSD |
17 | 17 | XML, and XML to Java objects. As a result, it is possible to create an instance of XStream with the default |
18 | 18 | constructor, call a method to convert an object into XML, then call another method to turn the XML back into an |
19 | 19 | equivalent Java object. By design, there are few limits to the type of objects XStream can handle.</p> |
20 | ||
21 | <p>This flexibility comes at a price. XStream applies various techniques under the hood to ensure it is able to | |
20 | ||
21 | <p class=highlight>Note: XStream supports other data formats than XML, e.g. JSON. Those formats can be used for | |
22 | the same attacks.</p> | |
23 | ||
24 | <p>This flexibility comes at a price. XStream applies various techniques under the hood to ensure it is able to | |
22 | 25 | handle all types of objects. This includes using undocumented Java features and reflection. The XML generated by |
23 | 26 | XStream includes all information required to build objects of almost any type. This introduces a potential |
24 | 27 | security problem.</p> |
25 | ||
26 | <p>The XML provided to XStream for conversion to a Java object can be manipulated to inject objects into the | |
27 | unmarshalled object graph, which were not present at marshalling time. An attacker could exploit this to execute | |
28 | arbitrary code or shell commands in the context of the server running the XStream process. This issue is | |
29 | identified by CVE-2013-7285.</p> | |
30 | ||
31 | <p>Note that the XML data could be manipulated on different levels. For example, manipulating values on existing | |
28 | ||
29 | <p>The provided XML data is used by XStream to unmarshal Java objects. This data can be manipulated by injecting | |
30 | the XML representation of other objects, that were not present at marshalling time. An attacker could take | |
31 | advantage of this to execute arbitrary code or shell commands in the context of the server running the XStream | |
32 | process. A concrete case is described in <a href="CVE-2013-7285.html">CVE-2013-7285</a>.</p> | |
33 | ||
34 | <p>Note that the XML data can be manipulated on different levels. For example, manipulating values on existing | |
32 | 35 | objects (such as a price value), or breaking the format and causing the XML parser to fail. The latter case will |
33 | 36 | raise an exception, but the former case must be handled by validity checks in any application which processes |
34 | user-supplied XML. The worst case scenario is injection of arbitrary code or shell commands, as noted above.</p> | |
37 | user-supplied XML. A worst case scenario is the injection of arbitrary code or shell commands, as noted above. | |
38 | Even worse, <a href="CVE-2017-7957.html">CVE-2017-7957</a> describes a case to crash the Java Virtual Machine | |
39 | causing a Denial of Service.</p> | |
35 | 40 | |
36 | 41 | <h2 id="external">External Security</h2> |
37 | 42 | |
46 | 51 | <h2 id="implicit">Implicit Security</h2> |
47 | 52 | |
48 | 53 | <p>As explained above, it is possible to inject other object instances if an attacker is able to define the data |
49 | used to deserialize the Java objects (typically XML, but XStream supports other formats like JSON). A known | |
50 | exploit can be created with the help of the Java runtime library using the Java Bean | |
51 | <a href="http://docs.oracle.com/javase/7/docs/api/java/beans/EventHandler.html">EventHandler</a>. As an instance | |
52 | for the <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/InvocationHandler.html">InvocationHandler</a> | |
53 | of a dynamic proxy, it can be used to install a redirect for an arbitrary call to the original object to the method | |
54 | of a completely different instance of an embedded object of the EventHandler itself.</p> | |
55 | ||
56 | <p>This scenario can be used perfectly to replace/inject a dynamic proxy with such an EventHandler at any location | |
57 | in the XML where its parent expects an object of such an interface's type or a simple object instance (any list | |
58 | element will suffice). The usage of a ProcessBuilder as an embedded element, coupled with the redirection of any | |
59 | call to the ProcessBuilder's <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html#start()">start()</a> | |
60 | method allows an attacker to call shell commands. Knowing how to define such an attack is the only prerequisite.</p> | |
61 | ||
54 | used to deserialize the Java objects. E.g. a known exploit can be created with the help of the Java runtime | |
55 | library using the Java Bean <a href="http://docs.oracle.com/javase/7/docs/api/java/beans/EventHandler.html">EventHandler</a> | |
56 | as described in <a href="CVE-2013-7285.html">CVE-2013-7285</a>. This scenario can be used perfectly to | |
57 | replace/inject a dynamic proxy with such an EventHandler at any location in the XML where its parent expects an | |
58 | object of such an interface's type or a simple object instance (any list element will suffice). The usage of a | |
59 | ProcessBuilder as an embedded element, coupled with the redirection of any call to the ProcessBuilder's | |
60 | <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html#start()">start()</a> method allows | |
61 | an attacker to call shell commands. Knowing how to define such an attack is the only prerequisite.</p> | |
62 | ||
63 | <p>More scenarios have been identified for types that are already delivered with the Java runtime. Looking at | |
64 | well-known and commonly used Java libraries libraries such as ASM, CGLIB, or Groovy, the possibility for more | |
65 | exploits is very high.</p> | |
66 | ||
67 | <p class="hightlight">Therefore creates a black list for special classes only a scenario for a false security, | |
68 | because no-one can assure, that no other scenario arise. A better approach is white listing i.e. the allowed class | |
69 | types are setup explicitly. This will be the default for XStream 1.5.x.</p> | |
70 | ||
62 | 71 | <p>Starting with XStream 1.4.7, an instance of the EventHandler is no longer handled by default. You have to |
63 | 72 | explicitly register a ReflectionConverter for the EventHandler type, if your application has the requirement to |
64 | persist such an object. However, you still have to take special care regarding the location of the persisted data, | |
65 | and how your application can ensure its integrity.</p> | |
66 | ||
67 | <p class=highlight>Note: this vulnerability is not even a special problem of XStream. XML being deserialized by | |
73 | persist such an object. Starting with XStream 1.4.10 the list of revoked types is enhanced by all types of the | |
74 | java.crypto package and any inner class named LazyIterator. On top you still have to take special care regarding | |
75 | the location of the persisted data, and how your application can ensure its integrity.</p> | |
76 | ||
77 | <p class=highlight>Note: This vulnerability is not even a special problem of XStream. XML being deserialized by | |
68 | 78 | XStream acts here like a script, and the scenario above can be created with any script that is executed within a |
69 | 79 | Java runtime (e.g. using its JavaScript interpreter) if someone is able to manipulate it externally. The key |
70 | 80 | message for application developers is that deserializing arbitrary user-supplied content is a dangerous proposition |
71 | in all cases.</p> | |
81 | in all cases. The best approach to prevent such an attach is a <a href="#example">white list</a>, i.e. the | |
82 | deserialization mechanism should only allow explicit types.</p> | |
72 | 83 | |
73 | 84 | <h2 id="explicit">Explicit Security</h2> |
74 | ||
75 | <p>While XStream implicitly avoids the vulnerability scenario with the EventHandler class, there might be other | |
76 | combinations with types from well-known and commonly-used Java libraries such as ASM, CGLIB, Groovy, or even in | |
77 | the Java runtime, that are currently simply unknown.</p> | |
78 | 85 | |
79 | 86 | <p>Starting with XStream 1.4.7, it is possible to define <a href="#framework">permissions</a> for types, to check |
80 | the type of an object that should be unmarshalled. Those permissions can be used to allow or deny types explicitly. | |
81 | With these permissions it is at least not possible to inject unexpected types into an object graph. Any application | |
82 | that deserializes data from an external source should at least use this feature to limit the danger of arbitrary | |
83 | command execution.</p> | |
87 | the type of an object that should be unmarshalled. Those permissions can be used to allow or deny types explicitly | |
88 | With these permissions it is at least not possible to inject unexpected types into an object graph. The security | |
89 | framework supports the setup of a black or white listing scenario. Any application should use this feature to | |
90 | limit the danger of arbitrary command execution if it deserializes data from an external source.</p> | |
91 | ||
92 | <p>XStream itself sets up a black list by default, i.e. it blocks all currently known critical classes of the Java | |
93 | runtime. Main reason for the black list is compatibility, because otherwise newer versions of XStream 1.4.x can no | |
94 | longer be used as drop-in replacement. Unfortunately this provides a false sense of security. Every XStream | |
95 | client should therefore switch to a white listing on its own as soon as possible. XStream itself will use white | |
96 | listing as default starting with 1.5.x and only clients that have also changed their setup will be able to use this | |
97 | newer version again as drop-in replacement.</p> | |
84 | 98 | |
85 | 99 | <p class=highlight>Apart from value manipulations, this implementation still allows the injection of allowed |
86 | 100 | objects at wrong locations, e.g. inserting an integer into a list of strings.</p> |
91 | 105 | <h2 id="validation">XML Validation</h2> |
92 | 106 | |
93 | 107 | <p>XML itself supports input validation using a schema and a validating parser. With XStream, you can use e.g. a |
94 | StAX parser for validation, but it will take some effort to ensure that the XML read and written by XStream matches | |
95 | the schema in first place. Typically you will have to write some custom converters, but it can be worth the effort | |
96 | depending on the use case.</p> | |
108 | DOM parser for validation, but it will take some effort to ensure that the XML read and written by XStream matches | |
109 | the schema in first place, because XStream uses additionally own attributes. Typically you will have to write some | |
110 | custom converters, but it can be worth the effort depending on the use case.</p> | |
97 | 111 | |
98 | 112 | <h1 id="framework">Security Framework</h1> |
99 | 113 | |
201 | 215 | </tr> |
202 | 216 | <tr> |
203 | 217 | <td><a href="javadoc/com/thoughtworks/xstream/security/PrimitiveTypePermission.html">PrimitiveTypePermission</a></td> |
204 | <td>Allow any primitive type and its boxed counterpart (incl void). You may use the PRIMITIVES instance directly.</td> | |
218 | <td>Allow any primitive type and its boxed counterpart (excluding void). You may use the PRIMITIVES instance | |
219 | directly.</td> | |
205 | 220 | <td> </td> |
206 | 221 | <td>no</td> |
207 | 222 | </tr> |
231 | 246 | </tr> |
232 | 247 | </table> |
233 | 248 | |
234 | <h2 id="example">Example Code</h2> | |
249 | <h2 id="example">Example Code White Listing</h2> | |
235 | 250 | |
236 | 251 | <p>XStream uses the AnyTypePermission by default, i.e. any type is accepted. You have to clear out this default |
237 | 252 | and register your own permissions to activate the security framework (the Blog type is from the |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | 2 | Copyright (C) 2005, 2006 Joe Walnes. |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2015, 2016 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2015, 2016, 2017 XStream committers. | |
4 | 4 | All rights reserved. |
5 | 5 | |
6 | 6 | The software in this package is published under the terms of the BSD |
120 | 120 | <li>David Jorm</li> |
121 | 121 | <li>Geoff Groos</li> |
122 | 122 | <li>Aaron Johnson</li> |
123 | <li>Stefan Cordes</li> | |
124 | <li>Carsten Hammer</li> | |
125 | <li>Matej Cimbora</li> | |
126 | <li>Baptiste Mesta</li> | |
123 | 127 | </ul> |
124 | 128 | |
125 | 129 | <p>Please direct all correspondence about XStream to the <a href="mailing-lists.html">mailing list</a> |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | 2 | Copyright (C) 2005, 2006 Joe Walnes. |
3 | Copyright (C) 2006, 2007, 2011, 2012 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2011, 2012, 2018 XStream committers. | |
4 | 4 | All rights reserved. |
5 | 5 | |
6 | 6 | The software in this package is published under the terms of the BSD |
63 | 63 | <div class="Source Java"><pre>xstream.alias("person", Person.class); |
64 | 64 | xstream.alias("phonenumber", PhoneNumber.class);</pre></div> |
65 | 65 | |
66 | <p><b>Note:</b> This is an optional step. Without it XStream would work fine, but the XML element names would | |
66 | <p class="highlight"><b>Note:</b> This is an optional step. Without it XStream would work fine, but the XML element names would | |
67 | 67 | contain the fully qualified name of each class (including package) which would bulk up the XML a bit. See the |
68 | 68 | <a href="alias-tutorial.html">Alias Tutorial</a> a more complete introduction.</p> |
69 | 69 | |
103 | 103 | <div class="Source Java"><pre>Person newJoe = (Person)xstream.fromXML(xml);</pre></div> |
104 | 104 | |
105 | 105 | <p>And that's how simple XStream is!</p> |
106 | ||
107 | <p class="highlight">Note, it is an annoying task to tweak an XStream instance until it can read a given XML format. | |
108 | You will have a much easier job, if you tweak XStream, until it writes the required XML format. NOrmallyt it will | |
109 | then also be able to read it.</p> | |
106 | 110 | |
107 | 111 | <h1 id="summary">Summary</h1> |
108 | 112 |
40 | 40 | <name>Javadoc</name> |
41 | 41 | <link title="XStream Core">javadoc/index.html</link> |
42 | 42 | <link title="Hibernate Extensions">hibernate-javadoc/index.html</link> |
43 | <link title="JMH Module">benchmark-jmh/index.html</link> | |
43 | <link title="JMH Module">jmh-javadoc/index.html</link> | |
44 | </section> | |
45 | <section> | |
46 | <name>Vulnerabilities</name> | |
47 | <page>CVE-2017-7957.html</page> | |
48 | <page>CVE-2016-3674.html</page> | |
49 | <page>CVE-2013-7285.html</page> | |
44 | 50 | </section> |
45 | 51 | <section> |
46 | 52 | <name>Tutorials</name> |
0 | 0 | <?xml version="1.0"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> |
1 | 1 | <!-- |
2 | Copyright (C) 2011, 2012, 2013, 2015 XStream committers. | |
2 | Copyright (C) 2011, 2012, 2013, 2015, 2017 XStream committers. | |
3 | 3 | All rights reserved. |
4 | 4 | |
5 | 5 | The software in this package is published under the terms of the BSD |
12 | 12 | <parent> |
13 | 13 | <groupId>com.thoughtworks.xstream</groupId> |
14 | 14 | <artifactId>xstream-parent</artifactId> |
15 | <version>1.4.9</version> | |
15 | <version>1.4.11.1</version> | |
16 | 16 | </parent> |
17 | 17 | <artifactId>xstream-hibernate</artifactId> |
18 | 18 | <packaging>jar</packaging> |
23 | 23 | |
24 | 24 | <profiles> |
25 | 25 | <profile> |
26 | <id>jdk18-ge</id> | |
26 | <id>jdk19-ge</id> | |
27 | 27 | <activation> |
28 | <jdk>[1.8,)</jdk> | |
28 | <jdk>[9,)</jdk> | |
29 | </activation> | |
30 | <properties> | |
31 | <surefire.argline>--illegal-access=${surefire.illegal.access}</surefire.argline> | |
32 | </properties> | |
33 | </profile> | |
34 | <profile> | |
35 | <id>jdk18</id> | |
36 | <activation> | |
37 | <jdk>1.8</jdk> | |
29 | 38 | </activation> |
30 | 39 | <build> |
31 | 40 | <plugins> |
46 | 55 | <detectJavaApiLink>false</detectJavaApiLink> |
47 | 56 | <source>${version.java.source}</source> |
48 | 57 | <links> |
49 | <link>${link.javadoc.javase}</link> | |
58 | <link>${javadoc.link.javase}</link> | |
50 | 59 | </links> |
51 | 60 | </configuration> |
52 | 61 | </plugin> |
114 | 123 | <version>${version.plugin.maven.surefire}</version> |
115 | 124 | </plugin> |
116 | 125 | <plugin> |
117 | <groupId>org.codehaus.mojo</groupId> | |
118 | <artifactId>cobertura-maven-plugin</artifactId> | |
119 | <version>${version.plugin.mojo.cobertura}</version> | |
126 | <groupId>org.jacoco</groupId> | |
127 | <artifactId>jacoco-maven-plugin</artifactId> | |
128 | <version>${version.plugin.jacoco}</version> | |
129 | <reportSets> | |
130 | <reportSet> | |
131 | <reports> | |
132 | <report>report</report> | |
133 | </reports> | |
134 | </reportSet> | |
135 | </reportSets> | |
120 | 136 | </plugin> |
121 | 137 | </plugins> |
122 | 138 | </reporting> |
+2
-2
0 | 0 | /* |
1 | * Copyright (C) 2007, 2011 XStream Committers. | |
1 | * Copyright (C) 2007, 2011, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
29 | 29 | public class HibernateProxyConverter implements Converter { |
30 | 30 | public boolean canConvert(final Class clazz) { |
31 | 31 | // be responsible for Hibernate proxy. |
32 | return HibernateProxy.class.isAssignableFrom(clazz); | |
32 | return clazz != null && HibernateProxy.class.isAssignableFrom(clazz); | |
33 | 33 | } |
34 | 34 | |
35 | 35 | public void marshal(final Object object, final HierarchicalStreamWriter writer, |
0 | 0 | /* |
1 | * Copyright (C) 2012, 2013 Joerg Schaible. | |
1 | * Copyright (C) 2012, 2013, 2018 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * Created on 08.06.2012 by Joerg Schaible |
46 | 46 | |
47 | 47 | private static Class loadHibernateEnversType(String name) { |
48 | 48 | Class type = null; |
49 | if (JVM.is15()) { | |
49 | if (JVM.isVersion(5)) { | |
50 | 50 | try { |
51 | 51 | type = HibernateProxy.class.getClassLoader().loadClass(name); |
52 | 52 | } catch (ClassNotFoundException e) { |
0 | 0 | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> |
1 | 1 | <!-- |
2 | Copyright (C) 2015 XStream committers. | |
2 | Copyright (C) 2015, 2017 XStream committers. | |
3 | 3 | All rights reserved. |
4 | 4 | |
5 | 5 | The software in this package is published under the terms of the BSD |
12 | 12 | <parent> |
13 | 13 | <groupId>com.thoughtworks.xstream</groupId> |
14 | 14 | <artifactId>xstream-parent</artifactId> |
15 | <version>1.4.9</version> | |
15 | <version>1.4.11.1</version> | |
16 | 16 | </parent> |
17 | 17 | <artifactId>xstream-jmh</artifactId> |
18 | 18 | <packaging>jar</packaging> |
21 | 21 | |
22 | 22 | <profiles> |
23 | 23 | <profile> |
24 | <id>jdk18-ge</id> | |
25 | <activation> | |
26 | <jdk>[1.8,)</jdk> | |
24 | <id>jdk11-ge</id> | |
25 | <activation> | |
26 | <jdk>[11,)</jdk> | |
27 | </activation> | |
28 | <build> | |
29 | <plugins> | |
30 | <plugin> | |
31 | <groupId>org.apache.maven.plugins</groupId> | |
32 | <artifactId>maven-compiler-plugin</artifactId> | |
33 | <configuration> | |
34 | <fork>true</fork> | |
35 | </configuration> | |
36 | <dependencies> | |
37 | <dependency> | |
38 | <groupId>javax.annotation</groupId> | |
39 | <artifactId>javax.annotation-api</artifactId> | |
40 | <version>${version.javax.annotation.api}</version> | |
41 | </dependency> | |
42 | </dependencies> | |
43 | </plugin> | |
44 | </plugins> | |
45 | </build> | |
46 | </profile> | |
47 | <profile> | |
48 | <id>jdk9-ge-jdk10</id> | |
49 | <activation> | |
50 | <jdk>[9,11)</jdk> | |
51 | </activation> | |
52 | <build> | |
53 | <plugins> | |
54 | <plugin> | |
55 | <groupId>org.apache.maven.plugins</groupId> | |
56 | <artifactId>maven-compiler-plugin</artifactId> | |
57 | <configuration> | |
58 | <fork>true</fork> | |
59 | <compilerArgs> | |
60 | <arg>-J--add-modules</arg> | |
61 | <arg>-Jjava.xml.ws.annotation</arg> | |
62 | </compilerArgs> | |
63 | </configuration> | |
64 | </plugin> | |
65 | </plugins> | |
66 | </build> | |
67 | </profile> | |
68 | <profile> | |
69 | <id>jdk18</id> | |
70 | <activation> | |
71 | <jdk>1.8</jdk> | |
27 | 72 | </activation> |
28 | 73 | <build> |
29 | 74 | <plugins> |
44 | 89 | <detectJavaApiLink>false</detectJavaApiLink> |
45 | 90 | <source>${version.java.source}</source> |
46 | 91 | <links> |
47 | <link>${link.javadoc.javase}</link> | |
92 | <link>${javadoc.link.javase}</link> | |
48 | 93 | </links> |
49 | 94 | </configuration> |
50 | 95 | </plugin> |
51 | 96 | </plugins> |
52 | 97 | </reporting> |
98 | </profile> | |
99 | <profile> | |
100 | <id>jdk17-le</id> | |
101 | <activation> | |
102 | <jdk>(,1.7]</jdk> | |
103 | </activation> | |
104 | <build> | |
105 | <plugins> | |
106 | <plugin> | |
107 | <groupId>org.apache.maven.plugins</groupId> | |
108 | <artifactId>maven-compiler-plugin</artifactId> | |
109 | <configuration> | |
110 | <excludes> | |
111 | <exclude>**/Base64**</exclude> | |
112 | </excludes> | |
113 | </configuration> | |
114 | </plugin> | |
115 | </plugins> | |
116 | </build> | |
53 | 117 | </profile> |
54 | 118 | </profiles> |
55 | 119 | |
100 | 164 | <groupId>org.openjdk.jmh</groupId> |
101 | 165 | <artifactId>jmh-generator-annprocess</artifactId> |
102 | 166 | </dependency> |
167 | <dependency> | |
168 | <groupId>commons-codec</groupId> | |
169 | <artifactId>commons-codec</artifactId> | |
170 | </dependency> | |
171 | <dependency> | |
172 | <groupId>com.brsanthu</groupId> | |
173 | <artifactId>migbase64</artifactId> | |
174 | </dependency> | |
103 | 175 | <!-- parser --> |
104 | 176 | <dependency> |
105 | 177 | <groupId>xpp3</groupId> |
150 | 222 | <groupId>org.codehaus.jettison</groupId> |
151 | 223 | <artifactId>jettison</artifactId> |
152 | 224 | <scope>runtime</scope> |
225 | </dependency> | |
226 | <dependency> | |
227 | <groupId>javax.xml.bind</groupId> | |
228 | <artifactId>jaxb-api</artifactId> | |
153 | 229 | </dependency> |
154 | 230 | </dependencies> |
155 | 231 | <properties> |
45 | 45 | |
46 | 46 | @REM * Set options |
47 | 47 | @REM ************* |
48 | set JAVA_OPTS=%JAVA_OPTS% -Xmx1024m | |
48 | set JAVA_OPTS=%JAVA_OPTS% -Xmx2048m -Xss4m | |
49 | 49 | |
50 | 50 | |
51 | 51 | @REM * Main class |
42 | 42 | |
43 | 43 | # * Set options |
44 | 44 | # ************* |
45 | JAVA_OPTS="$JAVA_OPTS -Xmx1024m" | |
45 | JAVA_OPTS="$JAVA_OPTS -Xmx2048m -Xss4m" | |
46 | 46 | |
47 | 47 | # * Main class |
48 | 48 | # ************ |
0 | /* | |
1 | * Copyright (C) 2017, 2018 XStream Committers. | |
2 | * All rights reserved. | |
3 | * | |
4 | * The software in this package is published under the terms of the BSD | |
5 | * style license a copy of which has been included with this distribution in | |
6 | * the LICENSE.txt file. | |
7 | * | |
8 | * Created on 29. July 2017 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.benchmark.jmh; | |
11 | ||
12 | import java.nio.charset.StandardCharsets; | |
13 | import java.util.Arrays; | |
14 | import java.util.EnumSet; | |
15 | import java.util.concurrent.TimeUnit; | |
16 | ||
17 | import javax.xml.bind.DatatypeConverter; | |
18 | ||
19 | import org.openjdk.jmh.annotations.Benchmark; | |
20 | import org.openjdk.jmh.annotations.BenchmarkMode; | |
21 | import org.openjdk.jmh.annotations.Fork; | |
22 | import org.openjdk.jmh.annotations.Measurement; | |
23 | import org.openjdk.jmh.annotations.Mode; | |
24 | import org.openjdk.jmh.annotations.OutputTimeUnit; | |
25 | import org.openjdk.jmh.annotations.Param; | |
26 | import org.openjdk.jmh.annotations.Scope; | |
27 | import org.openjdk.jmh.annotations.State; | |
28 | import org.openjdk.jmh.annotations.Threads; | |
29 | import org.openjdk.jmh.annotations.Warmup; | |
30 | ||
31 | import com.thoughtworks.xstream.core.StringCodec; | |
32 | import com.thoughtworks.xstream.core.util.Base64Encoder; | |
33 | ||
34 | ||
35 | /** | |
36 | * Benchmark for different Base64 encoder and decoder implementations. Each implementation can be used by the | |
37 | * EncodedByteArrayConverter. | |
38 | * | |
39 | * @author Jörg Schaible | |
40 | * @since 1.4.11 | |
41 | */ | |
42 | @BenchmarkMode(Mode.AverageTime) | |
43 | @Fork(value = 1) | |
44 | @Measurement(iterations = 16) | |
45 | @OutputTimeUnit(TimeUnit.NANOSECONDS) | |
46 | @State(Scope.Benchmark) | |
47 | @Threads(4) | |
48 | @Warmup(iterations = 5) | |
49 | public class Base64Benchmark { | |
50 | ||
51 | /** | |
52 | * Enumeration for the operation of the base 64 coder. | |
53 | * | |
54 | * @since 1.4.11 | |
55 | */ | |
56 | public static enum Operation { | |
57 | /** | |
58 | * Encoding operation. | |
59 | */ | |
60 | encode, | |
61 | /** | |
62 | * Decoding operation. | |
63 | */ | |
64 | decode | |
65 | } | |
66 | ||
67 | /** | |
68 | * Enumeration for the different base 64 coder. | |
69 | * | |
70 | * @since 1.4.11 | |
71 | */ | |
72 | public static enum Codec implements StringCodec { | |
73 | /** | |
74 | * XStream's own codec. | |
75 | */ | |
76 | xstreamInternal { | |
77 | final private Base64Encoder codec = new Base64Encoder(false); | |
78 | ||
79 | @Override | |
80 | public byte[] decode(final String base64) { | |
81 | return codec.decode(base64); | |
82 | } | |
83 | ||
84 | @Override | |
85 | public String encode(final byte[] data) { | |
86 | return codec.encode(data); | |
87 | } | |
88 | }, | |
89 | /** | |
90 | * Codec of JAXB, part of the Java runtime since 1.6. | |
91 | */ | |
92 | dataTypeConverter { | |
93 | ||
94 | @Override | |
95 | public byte[] decode(final String base64) { | |
96 | return DatatypeConverter.parseBase64Binary(base64); | |
97 | } | |
98 | ||
99 | @Override | |
100 | public String encode(final byte[] data) { | |
101 | return DatatypeConverter.printBase64Binary(data); | |
102 | } | |
103 | ||
104 | }, | |
105 | /** | |
106 | * Official codec of the Java runtime since 1.8. | |
107 | */ | |
108 | javaUtil { | |
109 | final private java.util.Base64.Decoder decoder = java.util.Base64.getDecoder(); | |
110 | final private java.util.Base64.Encoder encoder = java.util.Base64.getEncoder(); | |
111 | ||
112 | @Override | |
113 | public byte[] decode(final String base64) { | |
114 | return decoder.decode(base64); | |
115 | } | |
116 | ||
117 | @Override | |
118 | public String encode(final byte[] data) { | |
119 | return encoder.encodeToString(data); | |
120 | } | |
121 | }, | |
122 | /** | |
123 | * Codec of Apache Commons Codec. | |
124 | */ | |
125 | commonsCodec { | |
126 | ||
127 | @Override | |
128 | public byte[] decode(final String base64) { | |
129 | return org.apache.commons.codec.binary.Base64.decodeBase64(base64); | |
130 | } | |
131 | ||
132 | @Override | |
133 | public String encode(final byte[] data) { | |
134 | return org.apache.commons.codec.binary.Base64.encodeBase64String(data); | |
135 | } | |
136 | }, | |
137 | /** | |
138 | * Codec of MiGBase64, repackaged by brsanthu. | |
139 | */ | |
140 | migBase { | |
141 | ||
142 | @Override | |
143 | public byte[] decode(final String base64) { | |
144 | return com.migcomponents.migbase64.Base64.decode(base64); | |
145 | } | |
146 | ||
147 | @Override | |
148 | public String encode(final byte[] data) { | |
149 | return com.migcomponents.migbase64.Base64.encodeToString(data, false); | |
150 | } | |
151 | ||
152 | }; | |
153 | ||
154 | // to please Eclipse with JDK 5 target | |
155 | public abstract byte[] decode(String encoded); | |
156 | public abstract String encode(byte[] data); | |
157 | } | |
158 | ||
159 | /** | |
160 | * Enumeration for the different data sets. | |
161 | * | |
162 | * @since 1.4.11 | |
163 | */ | |
164 | public static enum Data { | |
165 | /** | |
166 | * Small data (16 bytes). | |
167 | */ | |
168 | small(16), | |
169 | /** | |
170 | * Medium data (4KB) | |
171 | */ | |
172 | medium(4096), | |
173 | /** | |
174 | * Big data (1MB) | |
175 | */ | |
176 | big(1024 * 1024); | |
177 | private Data(final int length) { | |
178 | data = getRandomBytes(length); | |
179 | base64 = Codec.xstreamInternal.encode(data); | |
180 | } | |
181 | ||
182 | private final String base64; | |
183 | private final byte[] data; | |
184 | ||
185 | /** | |
186 | * Get the encoded data as string. | |
187 | * | |
188 | * @return the encoded string | |
189 | * @since 1.4.11 | |
190 | */ | |
191 | public String getBase64() { | |
192 | return base64; | |
193 | } | |
194 | ||
195 | /** | |
196 | * Get the data to encode | |
197 | * | |
198 | * @return the data | |
199 | * @since 1.4.11 | |
200 | */ | |
201 | public byte[] getData() { | |
202 | return data; | |
203 | } | |
204 | ||
205 | static { | |
206 | final int lengths[] = {0, 1, 2, 3, 8, 65, 256, 4095, 1000000}; | |
207 | final byte data[][] = new byte[lengths.length][]; | |
208 | final String base64[] = new String[lengths.length]; | |
209 | for (int i = 0; i < lengths.length; ++i) { | |
210 | final int length = lengths[i]; | |
211 | final byte[] orig = getRandomBytes(length); | |
212 | for (final Codec codec : EnumSet.allOf(Codec.class)) { | |
213 | if (base64[i] == null) { | |
214 | base64[i] = codec.encode(orig); | |
215 | data[i] = codec.decode(base64[i]); | |
216 | assert Arrays.equals(data[i], orig); | |
217 | } else { | |
218 | assert base64[i].equals(codec.encode(orig)) : "Base64 differs for " | |
219 | + codec | |
220 | + ": <" | |
221 | + base64[i] | |
222 | + "> vs. <" | |
223 | + codec.encode(orig) | |
224 | + ">"; | |
225 | } | |
226 | } | |
227 | } | |
228 | } | |
229 | ||
230 | private static byte[] getRandomBytes(final int length) { | |
231 | final char[] ch = new char[length]; | |
232 | for (int j = 0; j < length; ++j) { | |
233 | ch[j] = Character.valueOf((char)(Math.round(Math.random() * 254) + 1)); | |
234 | } | |
235 | final byte[] orig = new String(ch).getBytes(StandardCharsets.UTF_8); | |
236 | return orig; | |
237 | } | |
238 | } | |
239 | ||
240 | @Param | |
241 | private Codec codec; | |
242 | @Param | |
243 | private Operation operation; | |
244 | @Param | |
245 | private Data data; | |
246 | ||
247 | /** | |
248 | * Encode and decode data. | |
249 | * | |
250 | * @since 1.4.11 | |
251 | */ | |
252 | @Benchmark | |
253 | public void run() { | |
254 | switch (operation) { | |
255 | case encode: | |
256 | codec.encode(data.getData()); | |
257 | break; | |
258 | case decode: | |
259 | codec.decode(data.getBase64()); | |
260 | break; | |
261 | } | |
262 | } | |
263 | } |
+8
-2
0 | 0 | /* |
1 | * Copyright (C) 2015 XStream Committers. | |
1 | * Copyright (C) 2015, 2017 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
37 | 37 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
38 | 38 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; |
39 | 39 | import com.thoughtworks.xstream.io.xml.Xpp3Driver; |
40 | import com.thoughtworks.xstream.security.ArrayTypePermission; | |
41 | import com.thoughtworks.xstream.security.NoTypePermission; | |
42 | import com.thoughtworks.xstream.security.PrimitiveTypePermission; | |
40 | 43 | |
41 | 44 | |
42 | 45 | /** |
227 | 230 | @Setup(Level.Trial) |
228 | 231 | public void setUp(final BenchmarkParams params) { |
229 | 232 | xstream = new XStream(new Xpp3Driver()); |
230 | xstream.allowTypes(new Class[]{Model.class}); | |
233 | xstream.addPermission(NoTypePermission.NONE); | |
234 | xstream.addPermission(ArrayTypePermission.ARRAYS); | |
235 | xstream.addPermission(PrimitiveTypePermission.PRIMITIVES); | |
236 | xstream.allowTypes(new Class[]{Model.class, String.class, BigInteger.class, UUID.class}); | |
231 | 237 | final String benchmark = params.getBenchmark(); |
232 | 238 | final String name = benchmark.substring(ConverterTypeBenchmark.class.getName().length() + 1); |
233 | 239 | if (name.equals("reflection")) { |
0 | 0 | /* |
1 | * Copyright (C) 2015 XStream Committers. | |
1 | * Copyright (C) 2015, 2017 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
31 | 31 | import com.thoughtworks.xstream.io.naming.NameCoder; |
32 | 32 | import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder; |
33 | 33 | import com.thoughtworks.xstream.io.xml.Xpp3Driver; |
34 | import com.thoughtworks.xstream.security.ArrayTypePermission; | |
35 | import com.thoughtworks.xstream.security.NoTypePermission; | |
36 | import com.thoughtworks.xstream.security.PrimitiveTypePermission; | |
34 | 37 | |
35 | 38 | |
36 | 39 | /** |
265 | 268 | throw new IllegalStateException("Unsupported benchmark type: " + benchmark); |
266 | 269 | } |
267 | 270 | xstream = new XStream(new Xpp3Driver(nameCoder)); |
268 | xstream.allowTypes(new Class[]{_1._2._3._4._5.Unfriendly.class}); | |
271 | xstream.addPermission(NoTypePermission.NONE); | |
272 | xstream.addPermission(ArrayTypePermission.ARRAYS); | |
273 | xstream.addPermission(PrimitiveTypePermission.PRIMITIVES); | |
274 | xstream.allowTypes(new Class[]{_1._2._3._4._5.Unfriendly.class, String.class}); | |
269 | 275 | if (nameCoder.getClass() == NoNameCoder.class) { |
270 | 276 | xstream.alias(_1._2._3._4._5.Unfriendly.class.getName().replace('$', '\u00b7'), |
271 | 277 | _1._2._3._4._5.Unfriendly.class); |
0 | 0 | /* |
1 | * Copyright (C) 2015 XStream Committers. | |
1 | * Copyright (C) 2015, 2017 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
48 | 48 | import com.thoughtworks.xstream.io.xml.WstxDriver; |
49 | 49 | import com.thoughtworks.xstream.io.xml.XomDriver; |
50 | 50 | import com.thoughtworks.xstream.io.xml.Xpp3Driver; |
51 | import com.thoughtworks.xstream.security.ArrayTypePermission; | |
52 | import com.thoughtworks.xstream.security.NoTypePermission; | |
53 | import com.thoughtworks.xstream.security.PrimitiveTypePermission; | |
51 | 54 | |
52 | 55 | |
53 | 56 | /** |
114 | 117 | * @since 1.4.9 |
115 | 118 | */ |
116 | 119 | DOM4J(new Dom4JDriver() { // XML writer of DOM4J fails |
120 | @Override | |
117 | 121 | public HierarchicalStreamWriter createWriter(final Writer out) { |
118 | 122 | return new PrettyPrintWriter(out, getNameCoder()); |
119 | 123 | } |
223 | 227 | * @since 1.4.9 |
224 | 228 | */ |
225 | 229 | NestedElements { |
226 | private static final int DEPTH = 500; | |
230 | private static final int DEPTH = 1000; | |
227 | 231 | private List<Integer> list; |
228 | 232 | |
229 | 233 | @Override |
314 | 318 | @Setup |
315 | 319 | public void init() { |
316 | 320 | xstream = new XStream(); |
321 | xstream.addPermission(NoTypePermission.NONE); | |
322 | xstream.addPermission(ArrayTypePermission.ARRAYS); | |
323 | xstream.addPermission(PrimitiveTypePermission.PRIMITIVES); | |
324 | xstream.allowTypes(new Class[]{List.class, String.class}); | |
317 | 325 | xstream.setMode(XStream.NO_REFERENCES); |
318 | 326 | driver = driverFactory.getDriver(); |
319 | 327 | } |
+6
-1
0 | 0 | /* |
1 | * Copyright (C) 2015 XStream Committers. | |
1 | * Copyright (C) 2015, 2017 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
38 | 38 | import com.thoughtworks.xstream.io.xml.CompactWriter; |
39 | 39 | import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; |
40 | 40 | import com.thoughtworks.xstream.io.xml.Xpp3Driver; |
41 | import com.thoughtworks.xstream.security.ArrayTypePermission; | |
42 | import com.thoughtworks.xstream.security.NoTypePermission; | |
41 | 43 | |
42 | 44 | |
43 | 45 | /** |
255 | 257 | throw new IllegalStateException("Unsupported benchmark type: " + benchmark); |
256 | 258 | } |
257 | 259 | xstream = new XStream(new Xpp3Driver()); |
260 | xstream.addPermission(NoTypePermission.NONE); | |
261 | xstream.addPermission(ArrayTypePermission.ARRAYS); | |
262 | xstream.allowTypes(new Class[] {String.class}); | |
258 | 263 | xstream.registerConverter(converter); |
259 | 264 | } |
260 | 265 |
0 | Benchmark (codec) (data) (operation) Mode Cnt Score Error Units | |
1 | Base64Benchmark.run xstreamInternal small encode avgt 16 370.353 ± 26.364 ns/op | |
2 | Base64Benchmark.run xstreamInternal small decode avgt 16 387.549 ± 2.753 ns/op | |
3 | Base64Benchmark.run xstreamInternal medium encode avgt 16 75746.500 ± 388.028 ns/op | |
4 | Base64Benchmark.run xstreamInternal medium decode avgt 16 69507.593 ± 4615.284 ns/op | |
5 | Base64Benchmark.run xstreamInternal big encode avgt 16 21809550.623 ± 287457.190 ns/op | |
6 | Base64Benchmark.run xstreamInternal big decode avgt 16 22860405.161 ± 116129.778 ns/op | |
7 | Base64Benchmark.run dataTypeConverter small encode avgt 16 113.739 ± 6.015 ns/op | |
8 | Base64Benchmark.run dataTypeConverter small decode avgt 16 146.704 ± 7.826 ns/op | |
9 | Base64Benchmark.run dataTypeConverter medium encode avgt 16 27994.835 ± 250.706 ns/op | |
10 | Base64Benchmark.run dataTypeConverter medium decode avgt 16 31775.991 ± 997.564 ns/op | |
11 | Base64Benchmark.run dataTypeConverter big encode avgt 16 11212057.101 ± 316407.971 ns/op | |
12 | Base64Benchmark.run dataTypeConverter big decode avgt 16 7831267.697 ± 26381.875 ns/op | |
13 | Base64Benchmark.run javaUtil small encode avgt 16 119.151 ± 0.623 ns/op | |
14 | Base64Benchmark.run javaUtil small decode avgt 16 222.355 ± 10.904 ns/op | |
15 | Base64Benchmark.run javaUtil medium encode avgt 16 19877.310 ± 1172.332 ns/op | |
16 | Base64Benchmark.run javaUtil medium decode avgt 16 32920.559 ± 274.879 ns/op | |
17 | Base64Benchmark.run javaUtil big encode avgt 16 9205883.279 ± 269329.433 ns/op | |
18 | Base64Benchmark.run javaUtil big decode avgt 16 8964062.065 ± 394932.790 ns/op | |
19 | Base64Benchmark.run commonsCodec small encode avgt 16 3416.205 ± 3.382 ns/op | |
20 | Base64Benchmark.run commonsCodec small decode avgt 16 3514.384 ± 11.939 ns/op | |
21 | Base64Benchmark.run commonsCodec medium encode avgt 16 78348.010 ± 2924.398 ns/op | |
22 | Base64Benchmark.run commonsCodec medium decode avgt 16 74262.708 ± 3031.596 ns/op | |
23 | Base64Benchmark.run commonsCodec big encode avgt 16 22347368.903 ± 178585.361 ns/op | |
24 | Base64Benchmark.run commonsCodec big decode avgt 16 23798441.056 ± 195917.888 ns/op | |
25 | Base64Benchmark.run migBase small encode avgt 16 113.382 ± 5.283 ns/op | |
26 | Base64Benchmark.run migBase small decode avgt 16 171.957 ± 1.520 ns/op | |
27 | Base64Benchmark.run migBase medium encode avgt 16 25132.013 ± 313.813 ns/op | |
28 | Base64Benchmark.run migBase medium decode avgt 16 34109.501 ± 834.604 ns/op | |
29 | Base64Benchmark.run migBase big encode avgt 16 10762327.746 ± 32072.333 ns/op | |
30 | Base64Benchmark.run migBase big decode avgt 16 8194853.894 ± 34107.972 ns/op |
0 | 0 | Benchmark Mode Cnt Score Error Units |
1 | ConverterTypeBenchmark.custom avgt 16 11276718.384 ± 660395.171 ns/op | |
2 | ConverterTypeBenchmark.javaBean avgt 16 28878706.293 ± 2718745.446 ns/op | |
3 | ConverterTypeBenchmark.reflection avgt 16 40085786.696 ± 2712102.798 ns/op | |
1 | ConverterTypeBenchmark.custom avgt 16 9176744.283 ± 596076.907 ns/op | |
2 | ConverterTypeBenchmark.javaBean avgt 16 18353984.976 ± 1308243.279 ns/op | |
3 | ConverterTypeBenchmark.reflection avgt 16 23371721.858 ± 145348.676 ns/op |
0 | 0 | Benchmark Mode Cnt Score Error Units |
1 | NameCoderBenchmark.cachedEscapedUnderscoreCoding avgt 25 7867671.962 ± 513789.786 ns/op | |
2 | NameCoderBenchmark.dollarCoding avgt 25 7767196.902 ± 594898.960 ns/op | |
3 | NameCoderBenchmark.escapedUnderscoreCoding avgt 25 9894393.289 ± 556251.884 ns/op | |
4 | NameCoderBenchmark.noCoding avgt 25 7299475.975 ± 363895.593 ns/op | |
5 | NameCoderBenchmark.xmlFriendlyCoding avgt 25 8635501.208 ± 703145.664 ns/op | |
1 | NameCoderBenchmark.cachedEscapedUnderscoreCoding avgt 25 4350643.046 ± 24055.209 ns/op | |
2 | NameCoderBenchmark.dollarCoding avgt 25 4621025.135 ± 248574.503 ns/op | |
3 | NameCoderBenchmark.escapedUnderscoreCoding avgt 25 5896886.514 ± 44560.928 ns/op | |
4 | NameCoderBenchmark.noCoding avgt 25 4190972.243 ± 149611.494 ns/op | |
5 | NameCoderBenchmark.xmlFriendlyCoding avgt 25 4938586.549 ± 181401.642 ns/op |
0 | 0 | Benchmark (driverFactory) Mode Cnt Score Error Units |
1 | ParserBenchmark.parseBigText Xpp3 avgt 15 2109341.076 ± 19369.901 ns/op | |
2 | ParserBenchmark.parseBigText kXML2 avgt 15 3391204.266 ± 31040.727 ns/op | |
3 | ParserBenchmark.parseBigText JDKStax avgt 15 7366387.272 ± 132117.523 ns/op | |
4 | ParserBenchmark.parseBigText Woodstox avgt 15 1884858.525 ± 29364.633 ns/op | |
5 | ParserBenchmark.parseBigText BEAStax avgt 15 3108517.699 ± 44905.395 ns/op | |
6 | ParserBenchmark.parseBigText DOM avgt 15 10037380.795 ± 402305.418 ns/op | |
7 | ParserBenchmark.parseBigText DOM4J avgt 15 7816280.084 ± 244809.864 ns/op | |
8 | ParserBenchmark.parseBigText JDom avgt 15 6368317.636 ± 180516.662 ns/op | |
9 | ParserBenchmark.parseBigText JDom2 avgt 15 5767640.105 ± 56112.801 ns/op | |
10 | ParserBenchmark.parseBigText Xom avgt 15 7950778.533 ± 74710.412 ns/op | |
11 | ParserBenchmark.parseBigText Binary avgt 15 1144243.750 ± 18924.227 ns/op | |
12 | ParserBenchmark.parseBigText Jettison avgt 15 3002547.220 ± 39676.507 ns/op | |
13 | ParserBenchmark.parseManyChildren Xpp3 avgt 15 1309607.210 ± 18539.487 ns/op | |
14 | ParserBenchmark.parseManyChildren kXML2 avgt 15 1514514.680 ± 30170.502 ns/op | |
15 | ParserBenchmark.parseManyChildren JDKStax avgt 15 1334398.501 ± 19324.267 ns/op | |
16 | ParserBenchmark.parseManyChildren Woodstox avgt 15 1240767.393 ± 9572.885 ns/op | |
17 | ParserBenchmark.parseManyChildren BEAStax avgt 15 1310406.961 ± 15256.069 ns/op | |
18 | ParserBenchmark.parseManyChildren DOM avgt 15 54234293.351 ± 400240.973 ns/op | |
19 | ParserBenchmark.parseManyChildren DOM4J avgt 15 92998322.952 ± 741924.537 ns/op | |
20 | ParserBenchmark.parseManyChildren JDom avgt 15 7910979.223 ± 101267.507 ns/op | |
21 | ParserBenchmark.parseManyChildren JDom2 avgt 15 10570210.653 ± 590365.314 ns/op | |
22 | ParserBenchmark.parseManyChildren Xom avgt 15 38704485.310 ± 485342.779 ns/op | |
23 | ParserBenchmark.parseManyChildren Binary avgt 15 1062031.901 ± 16391.974 ns/op | |
24 | ParserBenchmark.parseManyChildren Jettison avgt 15 1159238.555 ± 18479.230 ns/op | |
25 | ParserBenchmark.parseNestedElements Xpp3 avgt 15 3301732.767 ± 94076.135 ns/op | |
26 | ParserBenchmark.parseNestedElements kXML2 avgt 15 8105934.241 ± 103517.648 ns/op | |
27 | ParserBenchmark.parseNestedElements JDKStax avgt 15 688229.709 ± 2873.173 ns/op | |
28 | ParserBenchmark.parseNestedElements Woodstox avgt 15 650470.623 ± 7920.722 ns/op | |
29 | ParserBenchmark.parseNestedElements BEAStax avgt 15 669111.164 ± 10692.266 ns/op | |
30 | ParserBenchmark.parseNestedElements DOM avgt 15 1917332.056 ± 31699.337 ns/op | |
31 | ParserBenchmark.parseNestedElements DOM4J avgt 15 2108075.646 ± 98269.758 ns/op | |
32 | ParserBenchmark.parseNestedElements JDom avgt 15 3862796.027 ± 74010.953 ns/op | |
33 | ParserBenchmark.parseNestedElements JDom2 avgt 15 2980906.727 ± 43315.160 ns/op | |
34 | ParserBenchmark.parseNestedElements Xom avgt 15 2471019.743 ± 45829.109 ns/op | |
35 | ParserBenchmark.parseNestedElements Binary avgt 15 496839.565 ± 7180.978 ns/op | |
36 | ParserBenchmark.parseNestedElements Jettison avgt 15 682182.733 ± 9614.467 ns/op | |
1 | ParserBenchmark.parseBigText Xpp3 avgt 15 2155470.575 ± 23234.958 ns/op | |
2 | ParserBenchmark.parseBigText kXML2 avgt 15 3663477.841 ± 25428.211 ns/op | |
3 | ParserBenchmark.parseBigText JDKStax avgt 15 7444273.102 ± 58755.804 ns/op | |
4 | ParserBenchmark.parseBigText Woodstox avgt 15 1845769.311 ± 4622.237 ns/op | |
5 | ParserBenchmark.parseBigText BEAStax avgt 15 2879876.995 ± 59633.850 ns/op | |
6 | ParserBenchmark.parseBigText DOM avgt 15 9710278.896 ± 31003.340 ns/op | |
7 | ParserBenchmark.parseBigText DOM4J avgt 15 7452345.867 ± 23882.243 ns/op | |
8 | ParserBenchmark.parseBigText JDom avgt 15 6387821.035 ± 84970.337 ns/op | |
9 | ParserBenchmark.parseBigText JDom2 avgt 15 5921949.583 ± 34834.810 ns/op | |
10 | ParserBenchmark.parseBigText Xom avgt 15 8204769.944 ± 114956.192 ns/op | |
11 | ParserBenchmark.parseBigText Binary avgt 15 1129812.942 ± 16087.727 ns/op | |
12 | ParserBenchmark.parseBigText Jettison avgt 15 3016232.225 ± 25147.822 ns/op | |
13 | ParserBenchmark.parseManyChildren Xpp3 avgt 15 661082.180 ± 6313.751 ns/op | |
14 | ParserBenchmark.parseManyChildren kXML2 avgt 15 854613.418 ± 23502.923 ns/op | |
15 | ParserBenchmark.parseManyChildren JDKStax avgt 15 706572.092 ± 4563.202 ns/op | |
16 | ParserBenchmark.parseManyChildren Woodstox avgt 15 632147.776 ± 10452.976 ns/op | |
17 | ParserBenchmark.parseManyChildren BEAStax avgt 15 666062.149 ± 2243.640 ns/op | |
18 | ParserBenchmark.parseManyChildren DOM avgt 15 53954694.751 ± 64528.143 ns/op | |
19 | ParserBenchmark.parseManyChildren DOM4J avgt 15 93099746.029 ± 1777192.772 ns/op | |
20 | ParserBenchmark.parseManyChildren JDom avgt 15 6898339.792 ± 94446.669 ns/op | |
21 | ParserBenchmark.parseManyChildren JDom2 avgt 15 8723291.385 ± 91814.554 ns/op | |
22 | ParserBenchmark.parseManyChildren Xom avgt 15 42486494.920 ± 833304.520 ns/op | |
23 | ParserBenchmark.parseManyChildren Binary avgt 15 383203.739 ± 3522.118 ns/op | |
24 | ParserBenchmark.parseManyChildren Jettison avgt 15 555908.503 ± 2937.376 ns/op | |
25 | ParserBenchmark.parseNestedElements Xpp3 avgt 15 12444913.194 ± 216691.144 ns/op | |
26 | ParserBenchmark.parseNestedElements kXML2 avgt 15 34372562.351 ± 393544.126 ns/op | |
27 | ParserBenchmark.parseNestedElements JDKStax avgt 15 617636.917 ± 3232.109 ns/op | |
28 | ParserBenchmark.parseNestedElements Woodstox avgt 15 604788.852 ± 12685.186 ns/op | |
29 | ParserBenchmark.parseNestedElements BEAStax avgt 15 572549.126 ± 4791.275 ns/op | |
30 | ParserBenchmark.parseNestedElements DOM avgt 15 5148010.389 ± 46007.206 ns/op | |
31 | ParserBenchmark.parseNestedElements DOM4J avgt 15 5533035.930 ± 101440.131 ns/op | |
32 | ParserBenchmark.parseNestedElements JDom avgt 15 14111857.552 ± 448478.887 ns/op | |
33 | ParserBenchmark.parseNestedElements JDom2 avgt 15 10579620.188 ± 55254.011 ns/op | |
34 | ParserBenchmark.parseNestedElements Xom avgt 15 8086714.065 ± 57941.667 ns/op | |
35 | ParserBenchmark.parseNestedElements Binary avgt 15 260233.635 ± 4080.416 ns/op | |
36 | ParserBenchmark.parseNestedElements Jettison avgt 15 619961.028 ± 7869.358 ns/op |
0 | 0 | Benchmark Mode Cnt Score Error Units |
1 | StringConverterBenchmark.intern avgt 16 23060982.052 ± 1760952.641 ns/op | |
2 | StringConverterBenchmark.limitedConcurrentMap avgt 16 21796001.298 ± 2092865.246 ns/op | |
3 | StringConverterBenchmark.limitedSynchronizedWeakCache avgt 16 21838410.801 ± 981634.755 ns/op | |
4 | StringConverterBenchmark.nonCaching avgt 16 19626160.696 ± 1456804.584 ns/op | |
5 | StringConverterBenchmark.unlimitedConcurrentMap avgt 16 21378299.003 ± 1913288.565 ns/op | |
6 | StringConverterBenchmark.unlimitedSynchronizedWeakCache avgt 16 22011251.691 ± 1713892.622 ns/op | |
1 | StringConverterBenchmark.intern avgt 16 12576002.757 ± 850369.771 ns/op | |
2 | StringConverterBenchmark.limitedConcurrentMap avgt 16 10411028.373 ± 76602.128 ns/op | |
3 | StringConverterBenchmark.limitedSynchronizedWeakCache avgt 16 10948390.386 ± 84458.276 ns/op | |
4 | StringConverterBenchmark.nonCaching avgt 16 9422597.717 ± 39021.126 ns/op | |
5 | StringConverterBenchmark.unlimitedConcurrentMap avgt 16 10666492.267 ± 285717.245 ns/op | |
6 | StringConverterBenchmark.unlimitedSynchronizedWeakCache avgt 16 11917404.787 ± 1224543.882 ns/op |