Imported Upstream version 1.4.9
Emmanuel Bourg
8 years ago
0 | * text=auto | |
1 | ||
2 | *.css text | |
3 | *.diff text | |
4 | *.htm* text | |
5 | *.java text | |
6 | *.js text | |
7 | *.md text | |
8 | *.patch text | |
9 | *.txt text | |
10 | *.xml text | |
11 | ||
12 | *.gif binary | |
13 | *.jpg binary | |
14 | *.png binary | |
15 | *.psp binary | |
16 | *.vsd binary |
0 | language: java | |
1 | jdk: | |
2 | - oraclejdk8 | |
3 | - oraclejdk7 | |
4 | - openjdk6 | |
5 | install: true | |
6 | script: "mvn -V -B -e clean package" | |
7 | cache: | |
8 | directories: | |
9 | - $HOME/.m2 |
0 | For Java 5 or higher build with Maven 2.2 or 3 | |
0 | For Java 6 or higher build with Maven 3.2.5 or higher | |
1 | For Java 5 build with Maven 3.0.5 | |
1 | 2 | For Java 1.4 build with Maven 2.0.11 |
2 | 3 | |
3 | 4 | Before building: |
8 | 9 | |
9 | 10 | Before deploying: |
10 | 11 | |
11 | copy settings-template.xml to ~/.m2/settings.xml adding your Codehaus DAV username and passwords. | |
12 | copy settings-template.xml to ~/.m2/settings.xml adding your Sonatype OSSRH | |
13 | username and passwords. | |
12 | 14 | |
13 | 15 | To deploy (optionally adding sources and javadoc jars): |
14 | 16 | mvn deploy |
0 | 0 | (BSD Style License) |
1 | 1 | |
2 | 2 | Copyright (c) 2003-2006, Joe Walnes |
3 | Copyright (c) 2006-2011, XStream Committers | |
3 | Copyright (c) 2006-2015, XStream Committers | |
4 | 4 | All rights reserved. |
5 | 5 | |
6 | 6 | Redistribution and use in source and binary forms, with or without |
0 | [![Build Status](https://travis-ci.org/x-stream/xstream.svg?branch=v-1.4.x)](https://travis-ci.org/x-stream/xstream) | |
1 | ---- | |
2 | # XStream | |
3 | _Java to XML Serialization, and back again_ | |
4 | ||
5 | ## Binaries | |
6 | All binary artifacts are bundled in the -bin archive. It includes | |
7 | the XStream jars and any other library used at build time, or | |
8 | optional runtime extras. Xpp3 is recommend for use as it will | |
9 | greatly improve the performance of XStream. | |
10 | ||
11 | ## Documentation | |
12 | Documentation can be found at [GitHub](http://x-stream.github.io). This | |
13 | includes: | |
14 | * Introduction and tutorial | |
15 | * JavaDoc | |
16 | * Change log | |
17 | * Frequently asked questions | |
18 | ||
19 | ## Source | |
20 | The complete source for XStream is bundled in the -src archive. This includes: | |
21 | * 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] | |
26 |
7 | 7 | |
8 | 8 | --[ Binaries ]----------------------------------------------- |
9 | 9 | |
10 | All binary artifacts are in the 'lib' directory. These include the | |
11 | xstream jars and any other library used at build time, | |
12 | or optional runtime extras. kXML2 is recommend for use as it will | |
10 | All binary artifacts are bundled in the -bin archive. It includes | |
11 | the XStream jars and any other library used at build time, or | |
12 | optional runtime extras. Xpp3 is recommend for use as it will | |
13 | 13 | greatly improve the performance of XStream. |
14 | 14 | |
15 | 15 | --[ Documentation ]------------------------------------------ |
16 | 16 | |
17 | Documentation can be found in docs/index.html. This includes: | |
17 | Documentation can be found at http://x-stream.github.io. This | |
18 | includes: | |
18 | 19 | * Introduction and tutorial |
19 | 20 | * JavaDoc |
20 | 21 | * Change log |
22 | 23 | |
23 | 24 | --[ Source ]------------------------------------------------- |
24 | 25 | |
25 | The complete source for XStream is bundled. This includes: | |
26 | * Main API [src/java] | |
27 | * Unit tests [src/test] | |
26 | The complete source for XStream is bundled in the -src archive. | |
27 | This includes: | |
28 | * Main API [xstream/src/java] | |
29 | * Unit tests [xstream/src/test] | |
28 | 30 | * Maven build files [pom.xml] |
29 | * Dependencies [lib] | |
31 | * Hibernate module [xstream-hibernate] | |
32 | * Web site [xstream-distribution] | |
30 | 33 | |
31 | 34 | ------------------------------------------------------------- |
32 | 35 | |
33 | -XStream Ccommitters | |
36 | - XStream Committers | |
34 | 37 | |
35 | http://xstream.codehaus.org/ | |
38 | http://x-stream.github.io/ | |
36 | 39 |
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 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2015, 2016 XStream committers. | |
4 | 4 | All rights reserved. |
5 | 5 | |
6 | 6 | The software in this package is published under the terms of the BSD |
10 | 10 | Created on 29. July 2006 by Mauro Talevi |
11 | 11 | --> |
12 | 12 | <modelVersion>4.0.0</modelVersion> |
13 | <parent> | |
14 | <groupId>org.codehaus</groupId> | |
15 | <artifactId>codehaus-parent</artifactId> | |
16 | <version>3</version><!-- 4 required Java 5 --> | |
17 | <relativePath /> | |
18 | </parent> | |
19 | 13 | <groupId>com.thoughtworks.xstream</groupId> |
20 | 14 | <artifactId>xstream-parent</artifactId> |
21 | 15 | <packaging>pom</packaging> |
22 | <version>1.4.8</version> | |
16 | <version>1.4.9</version> | |
23 | 17 | <name>XStream Parent</name> |
18 | <url>http://x-stream.github.io</url> | |
24 | 19 | <description> |
25 | 20 | XStream is a serialization library from Java objects to XML and back. |
26 | 21 | </description> |
28 | 23 | <inceptionYear>2004</inceptionYear> |
29 | 24 | <organization> |
30 | 25 | <name>XStream</name> |
31 | <url>http://xstream.codehaus.org</url> | |
26 | <url>http://x-stream.github.io</url> | |
32 | 27 | </organization> |
28 | ||
29 | <developers> | |
30 | <developer> | |
31 | <id>xstream</id> | |
32 | <name>XStream Committers</name> | |
33 | <url>http://x-stream.github.io/team.html</url> | |
34 | </developer> | |
35 | </developers> | |
33 | 36 | |
34 | 37 | <profiles> |
35 | 38 | <profile> |
52 | 55 | </properties> |
53 | 56 | </profile> |
54 | 57 | <profile> |
55 | <id>jdk15-ge</id> | |
58 | <!-- build with Maven 3.2.5 !!! --> | |
59 | <id>jdk16-ge</id> | |
56 | 60 | <activation> |
57 | <jdk>[1.5,)</jdk> | |
61 | <jdk>[1.6,)</jdk> | |
58 | 62 | </activation> |
59 | <build> | |
60 | <plugins> | |
61 | <plugin> | |
62 | <groupId>org.apache.felix</groupId> | |
63 | <artifactId>maven-bundle-plugin</artifactId> | |
64 | <executions> | |
65 | <execution> | |
66 | <id>bundle-manifest</id> | |
67 | <phase>process-classes</phase> | |
68 | <goals> | |
69 | <goal>manifest</goal> | |
70 | </goals> | |
71 | </execution> | |
72 | </executions> | |
73 | </plugin> | |
74 | </plugins> | |
75 | </build> | |
76 | 63 | <modules> |
77 | <!--module>xstream-builder</module--> | |
64 | <module>xstream-jmh</module> | |
65 | <module>xstream-distribution</module> | |
78 | 66 | </modules> |
79 | 67 | </profile> |
80 | 68 | <profile> |
69 | <!-- build with Maven 3.0.5 !!! --> | |
81 | 70 | <id>jdk15</id> |
82 | 71 | <activation> |
83 | 72 | <jdk>1.5</jdk> |
96 | 85 | <properties> |
97 | 86 | <version.java.source>1.3</version.java.source> |
98 | 87 | <version.java.target>1.3</version.java.target> |
88 | <version.plugin.maven.enforcer>1.0-beta-1</version.plugin.maven.enforcer> | |
99 | 89 | <link.javadoc.javase>http://docs.oracle.com/javase/1.4.2/docs/api/</link.javadoc.javase> |
100 | 90 | <!-- repeat Hibernate version dependencies, JDK intervals in activation is not supported with M2.0.x --> |
101 | 91 | <version.hsqldb>1.8.0.10</version.hsqldb> |
112 | 102 | </activation> |
113 | 103 | <build> |
114 | 104 | <plugins> |
105 | <plugin> | |
106 | <groupId>org.apache.maven.plugins</groupId> | |
107 | <artifactId>maven-source-plugin</artifactId> | |
108 | </plugin> | |
115 | 109 | <plugin> |
116 | 110 | <groupId>org.apache.maven.plugins</groupId> |
117 | 111 | <artifactId>maven-enforcer-plugin</artifactId> |
137 | 131 | </build> |
138 | 132 | </profile> |
139 | 133 | <profile> |
134 | <id>osgi</id> | |
135 | <activation> | |
136 | <jdk>[1.6,)</jdk> | |
137 | <file> | |
138 | <exists>profiles/osgi</exists> | |
139 | </file> | |
140 | </activation> | |
141 | <build> | |
142 | <plugins> | |
143 | <plugin> | |
144 | <groupId>org.apache.felix</groupId> | |
145 | <artifactId>maven-bundle-plugin</artifactId> | |
146 | <executions> | |
147 | <execution> | |
148 | <id>bundle-manifest</id> | |
149 | <phase>process-classes</phase> | |
150 | <goals> | |
151 | <goal>manifest</goal> | |
152 | </goals> | |
153 | </execution> | |
154 | </executions> | |
155 | <configuration> | |
156 | <instructions combine.children="append"> | |
157 | <Export-Package>${bundle.export.package}</Export-Package> | |
158 | </instructions> | |
159 | </configuration> | |
160 | </plugin> | |
161 | <plugin> | |
162 | <groupId>org.apache.maven.plugins</groupId> | |
163 | <artifactId>maven-jar-plugin</artifactId> | |
164 | <executions> | |
165 | <execution> | |
166 | <id>default-jar</id> | |
167 | <goals> | |
168 | <goal>jar</goal> | |
169 | </goals> | |
170 | <configuration> | |
171 | <archive combine.children="append"> | |
172 | <manifestFile>${project.build.directory}/OSGi/MANIFEST.MF</manifestFile> | |
173 | </archive> | |
174 | </configuration> | |
175 | </execution> | |
176 | </executions> | |
177 | </plugin> | |
178 | </plugins> | |
179 | </build> | |
180 | <properties> | |
181 | <bundle.export.package>${project.groupId}.*;-noimport:=true</bundle.export.package> | |
182 | </properties> | |
183 | </profile> | |
184 | <profile> | |
140 | 185 | <id>xstream-release</id> |
141 | 186 | <properties> |
142 | 187 | <version.java.enforced>[1.8,1.9)</version.java.enforced> |
165 | 210 | <module>xstream</module> |
166 | 211 | <module>xstream-hibernate</module> |
167 | 212 | <module>xstream-benchmark</module> |
168 | <module>xstream-distribution</module> | |
169 | 213 | </modules> |
170 | 214 | |
171 | 215 | <licenses> |
172 | 216 | <license> |
173 | 217 | <name>BSD style</name> |
174 | <url>http://xstream.codehaus.org/license.html</url> | |
218 | <url>http://x-stream.github.io/license.html</url> | |
175 | 219 | <distribution>repo</distribution> |
176 | 220 | </license> |
177 | 221 | </licenses> |
178 | 222 | |
223 | <issueManagement> | |
224 | <system>github</system> | |
225 | <url>https://github.com/x-stream/xstream/issues/</url> | |
226 | </issueManagement> | |
227 | <ciManagement> | |
228 | <system>Travis</system> | |
229 | <url>https://travis-ci.org/x-stream/xstream</url> | |
230 | </ciManagement> | |
231 | <mailingLists> | |
232 | <mailingList> | |
233 | <name>XStream Users List</name> | |
234 | <subscribe>xstream-user+subscribe@googlegroups.com</subscribe> | |
235 | <unsubscribe>xstream-user+unsubscribe@googlegroups.com</unsubscribe> | |
236 | <post>xstream-user@googlegroups.com</post> | |
237 | <archive>https://groups.google.com/forum/#!forum/xstream-user</archive> | |
238 | <otherArchives> | |
239 | <otherArchive>http://news.gmane.org/gmane.comp.java.xstream.user</otherArchive> | |
240 | <otherArchive>http://markmail.org/search/list:org.codehaus.xstream.user</otherArchive> | |
241 | </otherArchives> | |
242 | </mailingList> | |
243 | <mailingList> | |
244 | <name>XStream Notifications List</name> | |
245 | <subscribe>xstream-notifications+subscribe@googlegroups.com</subscribe> | |
246 | <unsubscribe>xstream-notifications+unsubscribe@googlegroups.com</unsubscribe> | |
247 | <post>xstream-notifications@googlegroups.com</post> | |
248 | <archive>https://groups.google.com/forum/#!forum/xstream-notifications</archive> | |
249 | <otherArchives> | |
250 | <otherArchive>http://news.gmane.org/gmane.comp.java.xstream.scm</otherArchive> | |
251 | </otherArchives> | |
252 | </mailingList> | |
253 | <mailingList> | |
254 | <name>Former (pre-2015-06) Development List</name> | |
255 | <archive>http://news.gmane.org/gmane.comp.java.xstream.dev</archive> | |
256 | <otherArchives> | |
257 | <otherArchive>http://markmail.org/search/list:org.codehaus.xstream.dev</otherArchive> | |
258 | </otherArchives> | |
259 | </mailingList> | |
260 | <mailingList> | |
261 | <name>Former (pre-2015-06) Announcements List</name> | |
262 | <archive>http://markmail.org/search/list:org.codehaus.xstream.announce</archive> | |
263 | </mailingList> | |
264 | </mailingLists> | |
265 | ||
179 | 266 | <dependencyManagement> |
180 | 267 | <dependencies> |
181 | 268 | <dependency> |
182 | 269 | <groupId>com.thoughtworks.xstream</groupId> |
183 | 270 | <artifactId>xstream</artifactId> |
184 | <version>1.4.8</version> | |
271 | <version>1.4.9</version> | |
185 | 272 | </dependency> |
186 | 273 | <dependency> |
187 | 274 | <groupId>com.thoughtworks.xstream</groupId> |
188 | 275 | <artifactId>xstream</artifactId> |
189 | <version>1.4.8</version> | |
276 | <version>1.4.9</version> | |
190 | 277 | <classifier>tests</classifier> |
191 | 278 | <type>test-jar</type> |
192 | 279 | <scope>test</scope> |
194 | 281 | <dependency> |
195 | 282 | <groupId>com.thoughtworks.xstream</groupId> |
196 | 283 | <artifactId>xstream</artifactId> |
197 | <version>1.4.8</version> | |
284 | <version>1.4.9</version> | |
198 | 285 | <classifier>javadoc</classifier> |
199 | 286 | <scope>provided</scope> |
200 | 287 | </dependency> |
201 | 288 | <dependency> |
202 | 289 | <groupId>com.thoughtworks.xstream</groupId> |
203 | 290 | <artifactId>xstream-hibernate</artifactId> |
204 | <version>1.4.8</version> | |
291 | <version>1.4.9</version> | |
205 | 292 | </dependency> |
206 | 293 | <dependency> |
207 | 294 | <groupId>com.thoughtworks.xstream</groupId> |
208 | 295 | <artifactId>xstream-hibernate</artifactId> |
209 | <version>1.4.8</version> | |
296 | <version>1.4.9</version> | |
210 | 297 | <classifier>javadoc</classifier> |
211 | 298 | <scope>provided</scope> |
212 | 299 | </dependency> |
213 | 300 | <dependency> |
214 | 301 | <groupId>com.thoughtworks.xstream</groupId> |
215 | <artifactId>xstream-benchmark</artifactId> | |
216 | <version>1.4.8</version> | |
302 | <artifactId>xstream-jmh</artifactId> | |
303 | <version>1.4.9</version> | |
304 | </dependency> | |
305 | <dependency> | |
306 | <groupId>com.thoughtworks.xstream</groupId> | |
307 | <artifactId>xstream-jmh</artifactId> | |
308 | <version>1.4.9</version> | |
309 | <classifier>javadoc</classifier> | |
310 | <scope>provided</scope> | |
217 | 311 | </dependency> |
218 | 312 | <dependency> |
219 | 313 | <groupId>com.thoughtworks.xstream</groupId> |
220 | 314 | <artifactId>xstream-benchmark</artifactId> |
221 | <version>1.4.8</version> | |
315 | <version>1.4.9</version> | |
316 | </dependency> | |
317 | <dependency> | |
318 | <groupId>com.thoughtworks.xstream</groupId> | |
319 | <artifactId>xstream-benchmark</artifactId> | |
320 | <version>1.4.9</version> | |
222 | 321 | <classifier>javadoc</classifier> |
223 | 322 | <scope>provided</scope> |
224 | 323 | </dependency> |
386 | 485 | </dependency> |
387 | 486 | |
388 | 487 | <dependency> |
488 | <groupId>javax.activation</groupId> | |
489 | <artifactId>activation</artifactId> | |
490 | <version>${version.javax.activation}</version> | |
491 | <scope>provided</scope> | |
492 | </dependency> | |
493 | ||
494 | <dependency> | |
389 | 495 | <groupId>org.hibernate</groupId> |
390 | 496 | <artifactId>hibernate-core</artifactId> |
391 | 497 | <version>${version.org.hibernate.core}</version> |
419 | 525 | <scope>runtime</scope> |
420 | 526 | </dependency> |
421 | 527 | |
528 | <dependency> | |
529 | <groupId>org.openjdk.jmh</groupId> | |
530 | <artifactId>jmh-core</artifactId> | |
531 | <version>${version.org.openjdk.jmh}</version> | |
532 | </dependency> | |
533 | <dependency> | |
534 | <groupId>org.openjdk.jmh</groupId> | |
535 | <artifactId>jmh-generator-annprocess</artifactId> | |
536 | <version>${version.org.openjdk.jmh}</version> | |
537 | <scope>provided</scope> | |
538 | </dependency> | |
539 | ||
422 | 540 | <!-- always test-scoped --> |
423 | 541 | <dependency> |
424 | 542 | <groupId>junit</groupId> |
426 | 544 | <version>${version.junit}</version> |
427 | 545 | <scope>test</scope> |
428 | 546 | </dependency> |
429 | ||
430 | 547 | <dependency> |
431 | 548 | <groupId>jmock</groupId> |
432 | 549 | <artifactId>jmock</artifactId> |
574 | 691 | <artifactId>maven-release-plugin</artifactId> |
575 | 692 | <version>${version.plugin.maven.release}</version> |
576 | 693 | <configuration> |
694 | <mavenExecutorId>forked-path</mavenExecutorId> | |
577 | 695 | <goals>deploy</goals> |
578 | 696 | <autoVersionSubmodules>true</autoVersionSubmodules> |
579 | <!-- overwrite codehaus-parent --> | |
697 | <useReleaseProfile>false</useReleaseProfile> | |
580 | 698 | <arguments>-Pxstream-release</arguments> |
581 | 699 | </configuration> |
582 | 700 | </plugin> |
738 | 856 | </build> |
739 | 857 | |
740 | 858 | <distributionManagement> |
741 | <!-- | |
742 | The server id codehaus-nexus-snapshots, codehaus-nexus-staging, and | |
743 | codehaus.org must appear ~/.m2/settings.xml cf. settings-template.xml. | |
744 | http://hausmates.codehaus.org/Codehaus+Maven+Repository+Usage+Guide | |
745 | --> | |
746 | <site> | |
747 | <id>codehaus.org</id> | |
748 | <name>Codehaus XStream Site</name> | |
749 | <url>dav:https://dav.codehaus.org/xstream</url> | |
750 | </site> | |
859 | <repository> | |
860 | <id>ossrh-staging</id> | |
861 | <url>http://oss.sonatype.org/service/local/staging/deploy/maven2</url> | |
862 | </repository> | |
863 | <snapshotRepository> | |
864 | <id>ossrh-snapshots</id> | |
865 | <url>http://oss.sonatype.org/content/repositories/snapshots</url> | |
866 | </snapshotRepository> | |
867 | <!--site> | |
868 | <id>github</id> | |
869 | <url>scm:git:ssh://git@github.com/x-stream/x-stream.github.io.git</url> | |
870 | </site--> | |
751 | 871 | </distributionManagement> |
752 | 872 | |
753 | 873 | <scm> |
754 | <connection>scm:svn:http://svn.codehaus.org/xstream/tags/XSTREAM_1_4_8</connection> | |
755 | <developerConnection>scm:svn:https://svn.codehaus.org/xstream/tags/XSTREAM_1_4_8</developerConnection> | |
756 | <url>http://fisheye.codehaus.org/browse/xstream/tags/XSTREAM_1_4_8</url> | |
874 | <url>http://github.com/x-stream/xstream</url> | |
875 | <developerConnection>scm:git:https://github.com/x-stream/xstream.git</developerConnection> | |
876 | <connection>scm:git:https://github.com/x-stream/xstream.git</connection> | |
877 | <tag>v-1.4.x</tag> | |
757 | 878 | </scm> |
758 | 879 | |
759 | 880 | <properties> |
881 | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
882 | ||
760 | 883 | <version.java.source>1.5</version.java.source> |
761 | 884 | <version.java.target>1.5</version.java.target> |
762 | 885 | <version.java.enforced>[1.4,)</version.java.enforced> |
793 | 916 | <version.dom4j>1.6.1</version.dom4j> |
794 | 917 | <version.hsqldb>2.2.8</version.hsqldb> |
795 | 918 | <version.javaassist>3.12.1.GA</version.javaassist> |
919 | <version.javax.activation>1.1.1</version.javax.activation> | |
796 | 920 | <version.jmock>1.0.1</version.jmock> |
797 | 921 | <version.joda-time>1.6</version.joda-time> |
798 | 922 | <version.junit>3.8.1</version.junit> |
804 | 928 | <version.org.jdom>1.1.3</version.org.jdom> |
805 | 929 | <version.org.jdom2>2.0.5</version.org.jdom2> |
806 | 930 | <version.org.json>20080701</version.org.json> |
931 | <version.org.openjdk.jmh>1.11.1</version.org.openjdk.jmh> | |
807 | 932 | <version.org.slf4j>1.6.1</version.org.slf4j> |
808 | 933 | <version.oro>2.0.8</version.oro> |
809 | 934 | <version.stax>1.2.0</version.stax> |
0 | 0 | <?xml version="1.0" encoding="UTF-8"?> |
1 | 1 | <!-- |
2 | Copyright (C) 2006, 2007, 2010 XStream committers. | |
2 | Copyright (C) 2006, 2007, 2010, 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 | <settings> |
12 | 12 | <servers> |
13 | 13 | <server> |
14 | <id>codehaus-nexus-snapshots</id> | |
15 | <username>your-xircles-id</username> | |
16 | <password>your-xircles-pwd</password> | |
14 | <id>ossrh-snapshots</id> | |
15 | <username>your-sonatype.org-id</username> | |
16 | <password>your-sonatype.org-pwd</password> | |
17 | 17 | </server> |
18 | 18 | <server> |
19 | <id>codehaus-nexus-staging</id> | |
20 | <username>your-xircles-id</username> | |
21 | <password>your-xircles-pwd</password> | |
19 | <id>ossrh-staging</id> | |
20 | <username>your-sonatype.org-id</username> | |
21 | <password>your-sonatype.org-pwd</password> | |
22 | 22 | </server> |
23 | <server> | |
24 | <id>codehaus.org</id> | |
25 | <username></username> | |
26 | <password></password> | |
27 | </server> | |
28 | 23 | </servers> |
29 | 24 | </settings> |
0 | [auto-props] | |
1 | *.apt = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
2 | *.c = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
3 | *.c++ = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
4 | *.cpp = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
5 | *.cs = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
6 | *.css = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
7 | *.dtd = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
8 | *.ent = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
9 | *.fml = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
10 | *.groovy = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
11 | *.h = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
12 | *.h++ = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
13 | *.hpp = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
14 | *.html = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
15 | *.idl = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
16 | *.include = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
17 | *.java = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
18 | *.js = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
19 | *.jsp = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
20 | *.ldf = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
21 | *.ldif = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
22 | *.mak = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
23 | *.mdo = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
24 | *.php = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
25 | *.rb = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
26 | *.rtf = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
27 | *.sql = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
28 | *.svg = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
29 | *.t2t = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
30 | *.vm = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
31 | *.xhtml = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
32 | *.xml = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
33 | *.xsd = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
34 | *.xsl = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
35 | *.xslt = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
36 | Makefile = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision | |
37 | ||
38 | *.launch = svn:eol-style=native | |
39 | *.MF = svn:eol-style=native | |
40 | *.properties = svn:eol-style=native | |
41 | *.script = svn:eol-style=native | |
42 | *.txt = svn:eol-style=native | |
43 | ||
44 | *.dsp = svn:eol-style=CRLF | |
45 | *.dsw = svn:eol-style=CRLF | |
46 | ||
47 | *.iml = svn:eol-style=LF | |
48 | ||
49 | *.bat = svn:eol-style=CRLF;svn:executable;svn:keywords=Author Date Id HeadURL Revision | |
50 | *.cmd = svn:eol-style=CRLF;svn:executable;svn:keywords=Author Date Id HeadURL Revision | |
51 | ||
52 | *.ksh = svn:eol-style=LF;svn:executable;svn:keywords=Author Date Id HeadURL Revision | |
53 | *.sh = svn:eol-style=LF;svn:executable;svn:keywords=Author Date Id HeadURL Revision | |
54 | ||
55 | *.pl = svn:eol-style=native;svn:executable;svn:keywords=Author Date Id HeadURL Revision | |
56 | *.py = svn:eol-style=native;svn:executable;svn:keywords=Author Date Id HeadURL Revision | |
57 | ||
58 | *.bmp = svn:mime-type=image/bmp;svn:needs-lock=* | |
59 | *.gif = svn:mime-type=image/gif;svn:needs-lock=* | |
60 | *.ico = svn:mime-type=image/x-icon;svn:needs-lock=* | |
61 | *.jpeg = svn:mime-type=image/jpeg;svn:needs-lock=* | |
62 | *.jpg = svn:mime-type=image/jpeg;svn:needs-lock=* | |
63 | *.png = svn:mime-type=image/png;svn:needs-lock=* | |
64 | *.tif = svn:mime-type=image/tiff;svn:needs-lock=* | |
65 | *.tiff = svn:mime-type=image/tiff;svn:needs-lock=* | |
66 | ||
67 | *.doc = svn:mime-type=application/msword;svn:needs-lock=* | |
68 | *.jar = svn:mime-type=application/octet-stream;svn:needs-lock=* | |
69 | *.odc = svn:mime-type=application/vnd.oasis.opendocument.chart;svn:needs-lock=* | |
70 | *.odf = svn:mime-type=application/vnd.oasis.opendocument.formula;svn:needs-lock=* | |
71 | *.odg = svn:mime-type=application/vnd.oasis.opendocument.graphics;svn:needs-lock=* | |
72 | *.odi = svn:mime-type=application/vnd.oasis.opendocument.image;svn:needs-lock=* | |
73 | *.odp = svn:mime-type=application/vnd.oasis.opendocument.presentation;svn:needs-lock=* | |
74 | *.ods = svn:mime-type=application/vnd.oasis.opendocument.spreadsheet;svn:needs-lock=* | |
75 | *.odt = svn:mime-type=application/vnd.oasis.opendocument.text;svn:needs-lock=* | |
76 | *.pdf = svn:mime-type=application/pdf;svn:needs-lock=* | |
77 | *.ppt = svn:mime-type=application/vnd.ms-powerpoint;svn:needs-lock=* | |
78 | *.ser = svn:mime-type=application/octet-stream;svn:needs-lock=* | |
79 | *.swf = svn:mime-type=application/x-shockwave-flash;svn:needs-lock=* | |
80 | *.vsd = svn:mime-type=application/x-visio;svn:needs-lock=* | |
81 | *.xls = svn:mime-type=application/vnd.ms-excel;svn:needs-lock=* | |
82 | *.zip = svn:mime-type=application/zip;svn:needs-lock=* | |
83 |
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 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 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.8</version> | |
16 | <version>1.4.9</version> | |
17 | 17 | </parent> |
18 | 18 | <artifactId>xstream</artifactId> |
19 | 19 | <packaging>jar</packaging> |
99 | 99 | <groupId>org.codehaus.jettison</groupId> |
100 | 100 | <artifactId>jettison</artifactId> |
101 | 101 | <optional>true</optional> |
102 | </dependency> | |
103 | ||
104 | <dependency> | |
105 | <groupId>javax.activation</groupId> | |
106 | <artifactId>activation</artifactId> | |
102 | 107 | </dependency> |
103 | 108 | |
104 | 109 | <!-- test-scoped --> |
309 | 314 | </compilerArgs> |
310 | 315 | <excludes> |
311 | 316 | <exclude>**/Lambda**</exclude> |
317 | <exclude>**/extended/PathConverter*</exclude> | |
312 | 318 | </excludes> |
313 | 319 | <testExcludes> |
314 | 320 | <exclude>**/Lambda**</exclude> |
321 | <exclude>**/acceptance/Extended17TypesTest*</exclude> | |
315 | 322 | <exclude>**/extended/*17Test*</exclude> |
316 | 323 | </testExcludes> |
317 | 324 | </configuration> |
380 | 387 | <exclude>**/basic/UUID*</exclude> |
381 | 388 | <exclude>**/core/util/Types*</exclude> |
382 | 389 | <exclude>**/extended/*15*</exclude> |
390 | <exclude>**/extended/PathConverter*</exclude> | |
383 | 391 | <exclude>**/io/xml/JDom2*</exclude> |
384 | 392 | </excludes> |
385 | 393 | <testExcludes> |
392 | 400 | <exclude>**/io/xml/JDom2*Test*</exclude> |
393 | 401 | <exclude>**/acceptance/Basic15TypesTest*</exclude> |
394 | 402 | <exclude>**/acceptance/Concurrent15TypesTest*</exclude> |
403 | <exclude>**/acceptance/Extended17TypesTest*</exclude> | |
395 | 404 | </testExcludes> |
396 | 405 | </configuration> |
397 | 406 | </plugin> |
428 | 437 | </plugins> |
429 | 438 | </reporting> |
430 | 439 | |
440 | <properties> | |
441 | <bundle.export.package>!com.thoughtworks.xstream.core.util,com.thoughtworks.xstream.*;-noimport:=true</bundle.export.package> | |
442 | </properties> | |
443 | ||
431 | 444 | </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 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 |
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 26. September 2003 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream; |
342 | 342 | * The instance will use the {@link XppDriver} as default and tries to determine the best |
343 | 343 | * match for the {@link ReflectionProvider} on its own. |
344 | 344 | * </p> |
345 | * | |
345 | * | |
346 | 346 | * @throws InitializationException in case of an initialization problem |
347 | 347 | */ |
348 | 348 | public XStream() { |
369 | 369 | * The instance will tries to determine the best match for the {@link ReflectionProvider} on |
370 | 370 | * its own. |
371 | 371 | * </p> |
372 | * | |
372 | * | |
373 | 373 | * @param hierarchicalStreamDriver the driver instance |
374 | 374 | * @throws InitializationException in case of an initialization problem |
375 | 375 | */ |
599 | 599 | mapper = new LocalConversionMapper(mapper); |
600 | 600 | mapper = new ImmutableTypesMapper(mapper); |
601 | 601 | if (JVM.is18()) { |
602 | mapper = buildMapperDynamically("com.thoughtworks.xstream.mapper.LambdaMapper", new Class[]{Mapper.class}, | |
603 | new Object[]{mapper}); | |
602 | mapper = | |
603 | buildMapperDynamically("com.thoughtworks.xstream.mapper.LambdaMapper", new Class[]{Mapper.class}, | |
604 | new Object[]{mapper}); | |
604 | 605 | } |
605 | 606 | mapper = new SecurityMapper(mapper); |
606 | 607 | if (JVM.is15()) { |
733 | 734 | alias("awt-color", JVM.loadClassForName("java.awt.Color", false)); |
734 | 735 | alias("awt-font", JVM.loadClassForName("java.awt.Font", false)); |
735 | 736 | 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 | } | |
736 | 743 | } |
737 | 744 | |
738 | 745 | if (JVM.isSQLAvailable()) { |
762 | 769 | alias("string-builder", JVM.loadClassForName("java.lang.StringBuilder")); |
763 | 770 | alias("uuid", JVM.loadClassForName("java.util.UUID")); |
764 | 771 | } |
772 | ||
773 | if (JVM.is17()) { | |
774 | aliasType("path", JVM.loadClassForName("java.nio.file.Path")); | |
775 | } | |
776 | ||
765 | 777 | if (JVM.loadClassForName("java.lang.invoke.SerializedLambda") != null) { |
766 | 778 | aliasDynamically("serialized-lambda", "java.lang.invoke.SerializedLambda"); |
767 | 779 | } |
892 | 904 | "com.thoughtworks.xstream.converters.basic.UUIDConverter", PRIORITY_NORMAL, |
893 | 905 | null, null); |
894 | 906 | } |
907 | if (JVM.loadClassForName("javax.activation.ActivationDataFlavor") != null) { | |
908 | registerConverterDynamically("com.thoughtworks.xstream.converters.extended.ActivationDataFlavorConverter", | |
909 | PRIORITY_NORMAL, null, null); | |
910 | } | |
911 | if (JVM.is17()) { | |
912 | registerConverterDynamically("com.thoughtworks.xstream.converters.extended.PathConverter", | |
913 | PRIORITY_NORMAL, null, null); | |
914 | } | |
895 | 915 | if (JVM.is18()) { |
896 | 916 | registerConverterDynamically("com.thoughtworks.xstream.converters.reflection.LambdaConverter", |
897 | 917 | PRIORITY_NORMAL, new Class[]{Mapper.class, ReflectionProvider.class, ClassLoaderReference.class}, |
928 | 948 | } |
929 | 949 | |
930 | 950 | // primitives are always immutable |
931 | addImmutableType(boolean.class); | |
932 | addImmutableType(Boolean.class); | |
933 | addImmutableType(byte.class); | |
934 | addImmutableType(Byte.class); | |
935 | addImmutableType(char.class); | |
936 | addImmutableType(Character.class); | |
937 | addImmutableType(double.class); | |
938 | addImmutableType(Double.class); | |
939 | addImmutableType(float.class); | |
940 | addImmutableType(Float.class); | |
941 | addImmutableType(int.class); | |
942 | addImmutableType(Integer.class); | |
943 | addImmutableType(long.class); | |
944 | addImmutableType(Long.class); | |
945 | addImmutableType(short.class); | |
946 | addImmutableType(Short.class); | |
951 | addImmutableType(boolean.class, false); | |
952 | addImmutableType(Boolean.class, false); | |
953 | addImmutableType(byte.class, false); | |
954 | addImmutableType(Byte.class, false); | |
955 | addImmutableType(char.class, false); | |
956 | addImmutableType(Character.class, false); | |
957 | addImmutableType(double.class, false); | |
958 | addImmutableType(Double.class, false); | |
959 | addImmutableType(float.class, false); | |
960 | addImmutableType(Float.class, false); | |
961 | addImmutableType(int.class, false); | |
962 | addImmutableType(Integer.class, false); | |
963 | addImmutableType(long.class, false); | |
964 | addImmutableType(Long.class, false); | |
965 | addImmutableType(short.class, false); | |
966 | addImmutableType(Short.class, false); | |
947 | 967 | |
948 | 968 | // additional types |
949 | addImmutableType(Mapper.Null.class); | |
950 | addImmutableType(BigDecimal.class); | |
951 | addImmutableType(BigInteger.class); | |
952 | addImmutableType(String.class); | |
953 | addImmutableType(URI.class); | |
954 | addImmutableType(URL.class); | |
955 | addImmutableType(File.class); | |
956 | addImmutableType(Class.class); | |
957 | ||
958 | addImmutableType(Collections.EMPTY_LIST.getClass()); | |
959 | addImmutableType(Collections.EMPTY_SET.getClass()); | |
960 | addImmutableType(Collections.EMPTY_MAP.getClass()); | |
969 | addImmutableType(Mapper.Null.class, false); | |
970 | addImmutableType(BigDecimal.class, false); | |
971 | addImmutableType(BigInteger.class, false); | |
972 | addImmutableType(String.class, false); | |
973 | addImmutableType(URL.class, false); | |
974 | addImmutableType(File.class, false); | |
975 | addImmutableType(Class.class, false); | |
961 | 976 | |
962 | 977 | if (JVM.isAWTAvailable()) { |
963 | addImmutableTypeDynamically("java.awt.font.TextAttribute"); | |
978 | addImmutableTypeDynamically("java.awt.font.TextAttribute", false); | |
964 | 979 | } |
965 | 980 | |
966 | 981 | if (JVM.is14()) { |
967 | 982 | // late bound types - allows XStream to be compiled on earlier JDKs |
968 | addImmutableTypeDynamically("java.nio.charset.Charset"); | |
969 | addImmutableTypeDynamically("java.util.Currency"); | |
970 | } | |
971 | } | |
972 | ||
973 | private void addImmutableTypeDynamically(String className) { | |
983 | addImmutableTypeDynamically("java.nio.charset.Charset", true); | |
984 | addImmutableTypeDynamically("java.util.Currency", true); | |
985 | } | |
986 | ||
987 | if (JVM.is15()) { | |
988 | addImmutableTypeDynamically("java.util.UUID", true); | |
989 | } | |
990 | ||
991 | addImmutableType(URI.class, true); | |
992 | addImmutableType(Collections.EMPTY_LIST.getClass(), true); | |
993 | addImmutableType(Collections.EMPTY_SET.getClass(), true); | |
994 | addImmutableType(Collections.EMPTY_MAP.getClass(), true); | |
995 | } | |
996 | ||
997 | private void addImmutableTypeDynamically(String className, boolean isReferenceable) { | |
974 | 998 | Class type = JVM.loadClassForName(className); |
975 | 999 | if (type != null) { |
976 | addImmutableType(type); | |
1000 | addImmutableType(type, isReferenceable); | |
977 | 1001 | } |
978 | 1002 | } |
979 | 1003 | |
983 | 1007 | |
984 | 1008 | /** |
985 | 1009 | * Serialize an object to a pretty-printed XML String. |
986 | * | |
1010 | * | |
987 | 1011 | * @throws XStreamException if the object cannot be serialized |
988 | 1012 | */ |
989 | 1013 | public String toXML(Object obj) { |
1024 | 1048 | |
1025 | 1049 | /** |
1026 | 1050 | * Serialize and object to a hierarchical data structure (such as XML). |
1027 | * | |
1051 | * | |
1028 | 1052 | * @throws XStreamException if the object cannot be serialized |
1029 | 1053 | */ |
1030 | 1054 | public void marshal(Object obj, HierarchicalStreamWriter writer) { |
1044 | 1068 | |
1045 | 1069 | /** |
1046 | 1070 | * Deserialize an object from an XML String. |
1047 | * | |
1071 | * | |
1048 | 1072 | * @throws XStreamException if the object cannot be deserialized |
1049 | 1073 | */ |
1050 | 1074 | public Object fromXML(String xml) { |
1053 | 1077 | |
1054 | 1078 | /** |
1055 | 1079 | * Deserialize an object from an XML Reader. |
1056 | * | |
1080 | * | |
1057 | 1081 | * @throws XStreamException if the object cannot be deserialized |
1058 | 1082 | */ |
1059 | 1083 | public Object fromXML(Reader reader) { |
1062 | 1086 | |
1063 | 1087 | /** |
1064 | 1088 | * Deserialize an object from an XML InputStream. |
1065 | * | |
1089 | * | |
1066 | 1090 | * @throws XStreamException if the object cannot be deserialized |
1067 | 1091 | */ |
1068 | 1092 | public Object fromXML(InputStream input) { |
1170 | 1194 | |
1171 | 1195 | /** |
1172 | 1196 | * Deserialize an object from a hierarchical data structure (such as XML). |
1173 | * | |
1197 | * | |
1174 | 1198 | * @throws XStreamException if the object cannot be deserialized |
1175 | 1199 | */ |
1176 | 1200 | public Object unmarshal(HierarchicalStreamReader reader) { |
1215 | 1239 | |
1216 | 1240 | /** |
1217 | 1241 | * Alias a Class to a shorter name to be used in XML elements. |
1218 | * | |
1242 | * | |
1219 | 1243 | * @param name Short name |
1220 | 1244 | * @param type Type to be aliased |
1221 | 1245 | * @throws InitializationException if no {@link ClassAliasingMapper} is available |
1249 | 1273 | |
1250 | 1274 | /** |
1251 | 1275 | * Alias a Class to a shorter name to be used in XML elements. |
1252 | * | |
1276 | * | |
1253 | 1277 | * @param name Short name |
1254 | 1278 | * @param type Type to be aliased |
1255 | 1279 | * @param defaultImplementation Default implementation of type to use if no other specified. |
1263 | 1287 | |
1264 | 1288 | /** |
1265 | 1289 | * Alias a package to a shorter name to be used in XML elements. |
1266 | * | |
1290 | * | |
1267 | 1291 | * @param name Short name |
1268 | 1292 | * @param pkgName package to be aliased |
1269 | 1293 | * @throws InitializationException if no {@link DefaultImplementationsMapper} or no |
1281 | 1305 | |
1282 | 1306 | /** |
1283 | 1307 | * Create an alias for a field name. |
1284 | * | |
1308 | * | |
1285 | 1309 | * @param alias the alias itself |
1286 | 1310 | * @param definedIn the type that declares the field |
1287 | 1311 | * @param fieldName the name of the field |
1298 | 1322 | |
1299 | 1323 | /** |
1300 | 1324 | * Create an alias for an attribute |
1301 | * | |
1325 | * | |
1302 | 1326 | * @param alias the alias itself |
1303 | 1327 | * @param attributeName the name of the attribute |
1304 | 1328 | * @throws InitializationException if no {@link AttributeAliasingMapper} is available |
1334 | 1358 | |
1335 | 1359 | /** |
1336 | 1360 | * Create an alias for an attribute. |
1337 | * | |
1361 | * | |
1338 | 1362 | * @param definedIn the type where the attribute is defined |
1339 | 1363 | * @param attributeName the name of the attribute |
1340 | 1364 | * @param alias the alias itself |
1348 | 1372 | |
1349 | 1373 | /** |
1350 | 1374 | * Use an attribute for a field or a specific type. |
1351 | * | |
1375 | * | |
1352 | 1376 | * @param fieldName the name of the field |
1353 | 1377 | * @param type the Class of the type to be rendered as XML attribute |
1354 | 1378 | * @throws InitializationException if no {@link AttributeMapper} is available |
1365 | 1389 | |
1366 | 1390 | /** |
1367 | 1391 | * Use an attribute for a field declared in a specific type. |
1368 | * | |
1392 | * | |
1369 | 1393 | * @param fieldName the name of the field |
1370 | 1394 | * @param definedIn the Class containing such field |
1371 | 1395 | * @throws InitializationException if no {@link AttributeMapper} is available |
1382 | 1406 | |
1383 | 1407 | /** |
1384 | 1408 | * Use an attribute for an arbitrary type. |
1385 | * | |
1409 | * | |
1386 | 1410 | * @param type the Class of the type to be rendered as XML attribute |
1387 | 1411 | * @throws InitializationException if no {@link AttributeMapper} is available |
1388 | 1412 | * @since 1.2 |
1415 | 1439 | } |
1416 | 1440 | |
1417 | 1441 | /** |
1418 | * Add immutable types. The value of the instances of these types will always be written | |
1419 | * into the stream even if they appear multiple times. | |
1420 | * | |
1442 | * Add immutable types. The value of the instances of these types will always be written into the stream even if | |
1443 | * they appear multiple times. However, references are still supported at deserialization time. | |
1444 | * | |
1421 | 1445 | * @throws InitializationException if no {@link ImmutableTypesMapper} is available |
1446 | * @deprecated As of 1.4.9 use {@link #addImmutableType(Class, boolean)} | |
1422 | 1447 | */ |
1423 | 1448 | public void addImmutableType(Class type) { |
1449 | addImmutableType(type, true); | |
1450 | } | |
1451 | ||
1452 | /** | |
1453 | * Add immutable types. The value of the instances of these types will always be written into the stream even if | |
1454 | * they appear multiple times. | |
1455 | * <p> | |
1456 | * Note, while a reference-keeping marshaller will not write references for immutable types into the stream, a | |
1457 | * reference-keeping unmarshaller can still support such references in the stream for compatibility reasons at the | |
1458 | * expense of memory consumption. Therefore declare these types only as referenceable if your already persisted | |
1459 | * streams do contain such references. Otherwise you may waste a lot of memory during deserialization. | |
1460 | * </p> | |
1461 | * | |
1462 | * @param isReferenceable <code>true</code> if support at deserialization time is required for compatibility at the | |
1463 | * cost of a higher memory footprint, <code>false</code> otherwise | |
1464 | * @throws InitializationException if no {@link ImmutableTypesMapper} is available | |
1465 | * @since 1.4.9 | |
1466 | */ | |
1467 | public void addImmutableType(final Class type, final boolean isReferenceable) { | |
1424 | 1468 | if (immutableTypesMapper == null) { |
1425 | 1469 | throw new com.thoughtworks.xstream.InitializationException("No " |
1426 | 1470 | + ImmutableTypesMapper.class.getName() |
1427 | 1471 | + " available"); |
1428 | 1472 | } |
1429 | immutableTypesMapper.addImmutableType(type); | |
1473 | immutableTypesMapper.addImmutableType(type, isReferenceable); | |
1430 | 1474 | } |
1431 | 1475 | |
1432 | 1476 | public void registerConverter(Converter converter) { |
1452 | 1496 | |
1453 | 1497 | /** |
1454 | 1498 | * Register a local {@link Converter} for a field. |
1455 | * | |
1499 | * | |
1456 | 1500 | * @param definedIn the class type the field is defined in |
1457 | 1501 | * @param fieldName the field name |
1458 | 1502 | * @param converter the converter to use |
1469 | 1513 | |
1470 | 1514 | /** |
1471 | 1515 | * Register a local {@link SingleValueConverter} for a field. |
1472 | * | |
1516 | * | |
1473 | 1517 | * @param definedIn the class type the field is defined in |
1474 | 1518 | * @param fieldName the field name |
1475 | 1519 | * @param converter the converter to use |
1494 | 1538 | |
1495 | 1539 | /** |
1496 | 1540 | * Retrieve the {@link ReflectionProvider} in use. |
1497 | * | |
1541 | * | |
1498 | 1542 | * @return the mapper |
1499 | 1543 | * @since 1.2.1 |
1500 | 1544 | */ |
1550 | 1594 | |
1551 | 1595 | /** |
1552 | 1596 | * Adds a default implicit collection which is used for any unmapped XML tag. |
1553 | * | |
1597 | * | |
1554 | 1598 | * @param ownerType class owning the implicit collection |
1555 | 1599 | * @param fieldName name of the field in the ownerType. This field must be a concrete |
1556 | 1600 | * collection type or matching the default implementation type of the collection |
1562 | 1606 | |
1563 | 1607 | /** |
1564 | 1608 | * Adds implicit collection which is used for all items of the given itemType. |
1565 | * | |
1609 | * | |
1566 | 1610 | * @param ownerType class owning the implicit collection |
1567 | 1611 | * @param fieldName name of the field in the ownerType. This field must be a concrete |
1568 | 1612 | * collection type or matching the default implementation type of the collection |
1593 | 1637 | |
1594 | 1638 | /** |
1595 | 1639 | * Adds an implicit array. |
1596 | * | |
1640 | * | |
1597 | 1641 | * @param ownerType class owning the implicit array |
1598 | 1642 | * @param fieldName name of the array field |
1599 | 1643 | * @since 1.4 |
1633 | 1677 | |
1634 | 1678 | /** |
1635 | 1679 | * Adds an implicit map. |
1636 | * | |
1680 | * | |
1637 | 1681 | * @param ownerType class owning the implicit map |
1638 | 1682 | * @param fieldName name of the field in the ownerType. This field must be a concrete |
1639 | 1683 | * map type or matching the default implementation type of the map |
1648 | 1692 | |
1649 | 1693 | /** |
1650 | 1694 | * Adds an implicit map. |
1651 | * | |
1695 | * | |
1652 | 1696 | * @param ownerType class owning the implicit map |
1653 | 1697 | * @param fieldName name of the field in the ownerType. This field must be a concrete |
1654 | 1698 | * map type or matching the default implementation type of the map |
1672 | 1716 | * Create a DataHolder that can be used to pass data to the converters. The DataHolder is |
1673 | 1717 | * provided with a call to {@link #marshal(Object, HierarchicalStreamWriter, DataHolder)} or |
1674 | 1718 | * {@link #unmarshal(HierarchicalStreamReader, Object, DataHolder)}. |
1675 | * | |
1719 | * | |
1676 | 1720 | * @return a new {@link DataHolder} |
1677 | 1721 | */ |
1678 | 1722 | public DataHolder newDataHolder() { |
1775 | 1819 | * be incomplete. |
1776 | 1820 | * </p> |
1777 | 1821 | * <h3>Example</h3> |
1778 | * | |
1822 | * | |
1779 | 1823 | * <pre> |
1780 | 1824 | * ObjectOutputStream out = xstream.createObjectOutputStream(aWriter, "things"); |
1781 | 1825 | * out.writeInt(123); |
1783 | 1827 | * out.writeObject(someObject) |
1784 | 1828 | * out.close(); |
1785 | 1829 | * </pre> |
1786 | * | |
1830 | * | |
1787 | 1831 | * @param writer The writer to serialize the objects to. |
1788 | 1832 | * @param rootNodeName The name of the root node enclosing the stream of objects. |
1789 | 1833 | * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader) |
1907 | 1951 | |
1908 | 1952 | /** |
1909 | 1953 | * Retrieve the ClassLoader XStream uses to load classes. |
1910 | * | |
1954 | * | |
1911 | 1955 | * @since 1.1.1 |
1912 | 1956 | */ |
1913 | 1957 | public ClassLoader getClassLoader() { |
1944 | 1988 | |
1945 | 1989 | /** |
1946 | 1990 | * Ignore all unknown elements. |
1947 | * | |
1991 | * | |
1948 | 1992 | * @since 1.4.5 |
1949 | 1993 | */ |
1950 | 1994 | public void ignoreUnknownElements() { |
1953 | 1997 | |
1954 | 1998 | /** |
1955 | 1999 | * Add pattern for unknown element names to ignore. |
1956 | * | |
2000 | * | |
1957 | 2001 | * @param pattern the name pattern as regular expression |
1958 | 2002 | * @since 1.4.5 |
1959 | 2003 | */ |
1963 | 2007 | |
1964 | 2008 | /** |
1965 | 2009 | * Add pattern for unknown element names to ignore. |
1966 | * | |
2010 | * | |
1967 | 2011 | * @param pattern the name pattern as regular expression |
1968 | 2012 | * @since 1.4.5 |
1969 | 2013 | */ |
1978 | 2022 | |
1979 | 2023 | /** |
1980 | 2024 | * Process the annotations of the given types and configure the XStream. |
1981 | * | |
2025 | * | |
1982 | 2026 | * @param types the types with XStream annotations |
1983 | 2027 | * @since 1.3 |
1984 | 2028 | */ |
2024 | 2068 | * Permissions are evaluated in the added sequence. An instance of {@link NoTypePermission} or |
2025 | 2069 | * {@link AnyTypePermission} will implicitly wipe any existing permission. |
2026 | 2070 | * </p> |
2027 | * | |
2071 | * | |
2028 | 2072 | * @param permission the permission to add |
2029 | 2073 | * @since 1.4.7 |
2030 | 2074 | */ |
2036 | 2080 | |
2037 | 2081 | /** |
2038 | 2082 | * Add security permission for explicit types by name. |
2039 | * | |
2083 | * | |
2040 | 2084 | * @param names the type names to allow |
2041 | 2085 | * @since 1.4.7 |
2042 | 2086 | */ |
2046 | 2090 | |
2047 | 2091 | /** |
2048 | 2092 | * Add security permission for explicit types. |
2049 | * | |
2093 | * | |
2050 | 2094 | * @param types the types to allow |
2051 | 2095 | * @since 1.4.7 |
2052 | 2096 | */ |
2056 | 2100 | |
2057 | 2101 | /** |
2058 | 2102 | * Add security permission for a type hierarchy. |
2059 | * | |
2103 | * | |
2060 | 2104 | * @param type the base type to allow |
2061 | 2105 | * @since 1.4.7 |
2062 | 2106 | */ |
2066 | 2110 | |
2067 | 2111 | /** |
2068 | 2112 | * Add security permission for types matching one of the specified regular expressions. |
2069 | * | |
2113 | * | |
2070 | 2114 | * @param regexps the regular expressions to allow type names |
2071 | 2115 | * @since 1.4.7 |
2072 | 2116 | */ |
2076 | 2120 | |
2077 | 2121 | /** |
2078 | 2122 | * Add security permission for types matching one of the specified regular expressions. |
2079 | * | |
2123 | * | |
2080 | 2124 | * @param regexps the regular expressions to allow type names |
2081 | 2125 | * @since 1.4.7 |
2082 | 2126 | */ |
2094 | 2138 | * <li>*: arbitrary number of non-control characters except separator, e.g. for types in a package like 'java.lang.*'</li> |
2095 | 2139 | * <li>**: arbitrary number of non-control characters including separator, e.g. for types in a package and subpackages like 'java.lang.**'</li> |
2096 | 2140 | * </ul> |
2097 | * | |
2141 | * | |
2098 | 2142 | * @param patterns the patterns to allow type names |
2099 | 2143 | * @since 1.4.7 |
2100 | 2144 | */ |
2104 | 2148 | |
2105 | 2149 | /** |
2106 | 2150 | * Add security permission denying another one. |
2107 | * | |
2151 | * | |
2108 | 2152 | * @param permission the permission to deny |
2109 | 2153 | * @since 1.4.7 |
2110 | 2154 | */ |
2114 | 2158 | |
2115 | 2159 | /** |
2116 | 2160 | * Add security permission forbidding explicit types by name. |
2117 | * | |
2161 | * | |
2118 | 2162 | * @param names the type names to forbid |
2119 | 2163 | * @since 1.4.7 |
2120 | 2164 | */ |
2124 | 2168 | |
2125 | 2169 | /** |
2126 | 2170 | * Add security permission forbidding explicit types. |
2127 | * | |
2171 | * | |
2128 | 2172 | * @param types the types to forbid |
2129 | 2173 | * @since 1.4.7 |
2130 | 2174 | */ |
2134 | 2178 | |
2135 | 2179 | /** |
2136 | 2180 | * Add security permission forbidding a type hierarchy. |
2137 | * | |
2181 | * | |
2138 | 2182 | * @param type the base type to forbid |
2139 | 2183 | * @since 1.4.7 |
2140 | 2184 | */ |
2144 | 2188 | |
2145 | 2189 | /** |
2146 | 2190 | * Add security permission forbidding types matching one of the specified regular expressions. |
2147 | * | |
2191 | * | |
2148 | 2192 | * @param regexps the regular expressions to forbid type names |
2149 | 2193 | * @since 1.4.7 |
2150 | 2194 | */ |
2154 | 2198 | |
2155 | 2199 | /** |
2156 | 2200 | * Add security permission forbidding types matching one of the specified regular expressions. |
2157 | * | |
2201 | * | |
2158 | 2202 | * @param regexps the regular expressions to forbid type names |
2159 | 2203 | * @since 1.4.7 |
2160 | 2204 | */ |
2172 | 2216 | * <li>*: arbitrary number of non-control characters except separator, e.g. for types in a package like 'java.lang.*'</li> |
2173 | 2217 | * <li>**: arbitrary number of non-control characters including separator, e.g. for types in a package and subpackages like 'java.lang.**'</li> |
2174 | 2218 | * </ul> |
2175 | * | |
2219 | * | |
2176 | 2220 | * @param patterns the patterns to forbid names |
2177 | 2221 | * @since 1.4.7 |
2178 | 2222 | */ |
0 | 0 | /* |
1 | * Copyright (C) 2007, 2008 XStream Committers. | |
1 | * Copyright (C) 2007, 2008, 2016 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 | |
14 | 14 | |
15 | 15 | /** |
16 | * Base exception for all thrown exceptions with XStream. JDK 1.3 friendly cause handling. | |
16 | * Base exception for all thrown exceptions with XStream. | |
17 | 17 | * |
18 | 18 | * @author Joe Walnes |
19 | 19 | * @author Jörg Schaible |
20 | 20 | * @since 1.3 |
21 | 21 | */ |
22 | 22 | public class XStreamException extends BaseException { |
23 | ||
24 | private Throwable cause; | |
25 | 23 | |
26 | 24 | /** |
27 | 25 | * Default constructor. |
61 | 59 | * @since 1.3 |
62 | 60 | */ |
63 | 61 | public XStreamException(String message, Throwable cause) { |
64 | super(message + (cause == null ? "" : " : " + cause.getMessage())); | |
65 | this.cause = cause; | |
62 | super(message, cause); | |
66 | 63 | } |
67 | ||
68 | public Throwable getCause() { | |
69 | return cause; | |
70 | } | |
71 | ||
72 | 64 | } |
0 | 0 | /* |
1 | * Copyright (C) 2006, 2007, 2014 XStream Committers. | |
1 | * Copyright (C) 2006, 2007, 2014, 2016 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
20 | 20 | |
21 | 21 | import javax.xml.datatype.DatatypeFactory; |
22 | 22 | |
23 | import com.thoughtworks.xstream.converters.ConversionException; | |
24 | 23 | import com.thoughtworks.xstream.converters.ConverterLookup; |
25 | 24 | import com.thoughtworks.xstream.converters.ConverterMatcher; |
26 | 25 | import com.thoughtworks.xstream.converters.ConverterRegistry; |
32 | 31 | import com.thoughtworks.xstream.core.JVM; |
33 | 32 | import com.thoughtworks.xstream.io.HierarchicalStreamDriver; |
34 | 33 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
34 | import com.thoughtworks.xstream.io.StreamException; | |
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; |
84 | 84 | } catch (final ObjectStreamException e) { |
85 | 85 | throw e; |
86 | 86 | } catch (final IOException e) { |
87 | throw new ConversionException("Unexpected IO error from a StringWriter", e); | |
87 | throw new StreamException("Unexpected IO error from a StringWriter", e); | |
88 | 88 | } |
89 | 89 | return writer.toString(); |
90 | 90 | } |
134 | 134 | } catch (final ObjectStreamException e) { |
135 | 135 | throw e; |
136 | 136 | } catch (final IOException e) { |
137 | throw new ConversionException("Unexpected IO error from a StringReader", e); | |
137 | throw new StreamException("Unexpected IO error from a StringReader", e); | |
138 | 138 | } |
139 | 139 | } |
140 | 140 | |
156 | 156 | } catch (final ObjectStreamException e) { |
157 | 157 | throw e; |
158 | 158 | } catch (final IOException e) { |
159 | throw new ConversionException("Unexpected IO error from a StringReader", e); | |
159 | throw new StreamException("Unexpected IO error from a StringReader", e); | |
160 | 160 | } |
161 | 161 | } |
162 | 162 | |
178 | 178 | } catch (final ObjectStreamException e) { |
179 | 179 | throw e; |
180 | 180 | } catch (final IOException e) { |
181 | throw new ConversionException("Unexpected IO error from a StringReader", e); | |
181 | throw new StreamException("Unexpected IO error from a StringReader", e); | |
182 | 182 | } |
183 | 183 | } |
184 | 184 | |
201 | 201 | } catch (final ObjectStreamException e) { |
202 | 202 | throw e; |
203 | 203 | } catch (final IOException e) { |
204 | throw new ConversionException("Unexpected IO error from a StringReader", e); | |
204 | throw new StreamException("Unexpected IO error from a StringReader", e); | |
205 | 205 | } |
206 | 206 | } |
207 | 207 |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 2013, 2014 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 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 |
105 | 105 | double[] doubles() default {}; |
106 | 106 | |
107 | 107 | boolean[] booleans() default {}; |
108 | ||
109 | /** | |
110 | * Provide null types as arguments for the converter's constructor arguments. | |
111 | * | |
112 | * @return the types provided as null values | |
113 | * @since 1.4.9 | |
114 | */ | |
115 | Class<?>[] nulls() default {}; | |
108 | 116 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 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 |
9 | 9 | * Created on 26. September 2003 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.converters; |
12 | ||
13 | import com.thoughtworks.xstream.XStreamException; | |
14 | import com.thoughtworks.xstream.core.util.OrderRetainingMap; | |
15 | ||
16 | import java.util.Iterator; | |
17 | import java.util.Map; | |
18 | 12 | |
19 | 13 | /** |
20 | 14 | * Thrown by {@link Converter} implementations when they cannot convert an object |
28 | 22 | * |
29 | 23 | * @see ErrorWriter |
30 | 24 | */ |
31 | public class ConversionException extends XStreamException implements ErrorWriter { | |
32 | ||
33 | private static final String SEPARATOR = "\n-------------------------------"; | |
34 | private Map stuff = new OrderRetainingMap(); | |
25 | public class ConversionException extends ErrorWritingException { | |
35 | 26 | |
36 | 27 | public ConversionException(String msg, Throwable cause) { |
37 | 28 | super(msg, cause); |
38 | if (msg != null) { | |
39 | add("message", msg); | |
40 | } | |
41 | if (cause != null) { | |
42 | add("cause-exception", cause.getClass().getName()); | |
43 | add("cause-message", cause instanceof ConversionException ? ((ConversionException)cause).getShortMessage() : cause.getMessage()); | |
44 | } | |
45 | 29 | } |
46 | 30 | |
47 | 31 | public ConversionException(String msg) { |
49 | 33 | } |
50 | 34 | |
51 | 35 | public ConversionException(Throwable cause) { |
52 | this(cause.getMessage(), cause); | |
53 | } | |
54 | ||
55 | public String get(String errorKey) { | |
56 | return (String) stuff.get(errorKey); | |
57 | } | |
58 | ||
59 | public void add(String name, String information) { | |
60 | String key = name; | |
61 | int i = 0; | |
62 | while (stuff.containsKey(key)) { | |
63 | String value = (String)stuff.get(key); | |
64 | if (information.equals(value)) | |
65 | return; | |
66 | key = name + "[" + ++i +"]"; | |
67 | } | |
68 | stuff.put(key, information); | |
69 | } | |
70 | ||
71 | public void set(String name, String information) { | |
72 | String key = name; | |
73 | int i = 0; | |
74 | stuff.put(key, information); // keep order | |
75 | while (stuff.containsKey(key)) { | |
76 | if (i != 0) { | |
77 | stuff.remove(key); | |
78 | } | |
79 | key = name + "[" + ++i +"]"; | |
80 | } | |
81 | } | |
82 | ||
83 | public Iterator keys() { | |
84 | return stuff.keySet().iterator(); | |
85 | } | |
86 | ||
87 | public String getMessage() { | |
88 | StringBuffer result = new StringBuffer(); | |
89 | if (super.getMessage() != null) { | |
90 | result.append(super.getMessage()); | |
91 | } | |
92 | if (!result.toString().endsWith(SEPARATOR)) { | |
93 | result.append("\n---- Debugging information ----"); | |
94 | } | |
95 | for (Iterator iterator = keys(); iterator.hasNext();) { | |
96 | String k = (String) iterator.next(); | |
97 | String v = get(k); | |
98 | result.append('\n').append(k); | |
99 | result.append(" ".substring(Math.min(20, k.length()))); | |
100 | result.append(": ").append(v); | |
101 | } | |
102 | result.append(SEPARATOR); | |
103 | return result.toString(); | |
104 | } | |
105 | ||
106 | public String getShortMessage() { | |
107 | return super.getMessage(); | |
36 | super(cause); | |
108 | 37 | } |
109 | 38 | } |
0 | /* | |
1 | * Copyright (C) 2003, 2004, 2005 Joe Walnes. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2016 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 24. February 2016 by Joerg Schaible, factored out of ConversionException. | |
10 | */ | |
11 | package com.thoughtworks.xstream.converters; | |
12 | ||
13 | import java.util.Iterator; | |
14 | import java.util.Map; | |
15 | ||
16 | import com.thoughtworks.xstream.XStreamException; | |
17 | import com.thoughtworks.xstream.core.util.OrderRetainingMap; | |
18 | ||
19 | ||
20 | /** | |
21 | * Abstract base class for exceptions supporting an ErrorWriter. It can be passed around to things accepting an | |
22 | * ErrorWriter to add diagnostics. | |
23 | * | |
24 | * @author Jörg Schaible | |
25 | * @see ErrorWriter | |
26 | * @since 1.4.9 | |
27 | */ | |
28 | public abstract class ErrorWritingException extends XStreamException implements ErrorWriter { | |
29 | ||
30 | private static final String SEPARATOR = "\n-------------------------------"; | |
31 | private final Map stuff = new OrderRetainingMap(); | |
32 | ||
33 | /** | |
34 | * Constructs a ErrorWritingException. | |
35 | * | |
36 | * @param message the error message | |
37 | * @since 1.4.9 | |
38 | */ | |
39 | public ErrorWritingException(String message) { | |
40 | super(message); | |
41 | addData(message, null); | |
42 | } | |
43 | ||
44 | /** | |
45 | * Constructs a ErrorWritingException. | |
46 | * | |
47 | * @param cause the causing exception | |
48 | * @since 1.4.9 | |
49 | */ | |
50 | public ErrorWritingException(Throwable cause) { | |
51 | super(cause); | |
52 | addData(null, cause); | |
53 | } | |
54 | ||
55 | /** | |
56 | * Constructs a ErrorWritingException. | |
57 | * | |
58 | * @param message the error message | |
59 | * @param cause the causing exception | |
60 | * @since 1.4.9 | |
61 | */ | |
62 | public ErrorWritingException(String message, Throwable cause) { | |
63 | super(message, cause); | |
64 | addData(message, cause); | |
65 | } | |
66 | ||
67 | private void addData(String msg, Throwable cause) { | |
68 | if (msg != null) { | |
69 | add("message", msg); | |
70 | } | |
71 | if (cause != null) { | |
72 | add("cause-exception", cause.getClass().getName()); | |
73 | add("cause-message", cause instanceof ErrorWritingException ? ((ErrorWritingException)cause).getShortMessage() : cause.getMessage()); | |
74 | } | |
75 | } | |
76 | ||
77 | public String get(String errorKey) { | |
78 | return (String) stuff.get(errorKey); | |
79 | } | |
80 | ||
81 | public void add(String name, String information) { | |
82 | String key = name; | |
83 | int i = 0; | |
84 | while (stuff.containsKey(key)) { | |
85 | String value = (String)stuff.get(key); | |
86 | if (information.equals(value)) | |
87 | return; | |
88 | key = name + "[" + ++i +"]"; | |
89 | } | |
90 | stuff.put(key, information); | |
91 | } | |
92 | ||
93 | public void set(String name, String information) { | |
94 | String key = name; | |
95 | int i = 0; | |
96 | stuff.put(key, information); // keep order | |
97 | while (stuff.containsKey(key)) { | |
98 | if (i != 0) { | |
99 | stuff.remove(key); | |
100 | } | |
101 | key = name + "[" + ++i +"]"; | |
102 | } | |
103 | } | |
104 | ||
105 | public Iterator keys() { | |
106 | return stuff.keySet().iterator(); | |
107 | } | |
108 | ||
109 | public String getMessage() { | |
110 | StringBuffer result = new StringBuffer(); | |
111 | if (super.getMessage() != null) { | |
112 | result.append(super.getMessage()); | |
113 | } | |
114 | if (!result.toString().endsWith(SEPARATOR)) { | |
115 | result.append("\n---- Debugging information ----"); | |
116 | } | |
117 | for (Iterator iterator = keys(); iterator.hasNext();) { | |
118 | String k = (String) iterator.next(); | |
119 | String v = get(k); | |
120 | result.append('\n').append(k); | |
121 | result.append(" ".substring(Math.min(20, k.length()))); | |
122 | result.append(": ").append(v); | |
123 | } | |
124 | result.append(SEPARATOR); | |
125 | return result.toString(); | |
126 | } | |
127 | ||
128 | public String getShortMessage() { | |
129 | return super.getMessage(); | |
130 | } | |
131 | ||
132 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 2013, 2014, 2015 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 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 |
226 | 226 | } |
227 | 227 | } |
228 | 228 | // no dateFormats left to try |
229 | throw new ConversionException("Cannot parse date " + str); | |
229 | ConversionException exception = new ConversionException("Cannot parse date"); | |
230 | exception.add("date", str); | |
231 | throw exception; | |
230 | 232 | } |
231 | 233 | |
232 | 234 | public String toString(Object obj) { |
+9
-3
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 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 |
12 | 12 | |
13 | 13 | import com.thoughtworks.xstream.converters.ConversionException; |
14 | 14 | import com.thoughtworks.xstream.converters.Converter; |
15 | import com.thoughtworks.xstream.converters.ErrorWritingException; | |
15 | 16 | import com.thoughtworks.xstream.converters.MarshallingContext; |
16 | 17 | import com.thoughtworks.xstream.converters.UnmarshallingContext; |
18 | import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; | |
17 | 19 | import com.thoughtworks.xstream.core.util.HierarchicalStreams; |
18 | 20 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
19 | 21 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; |
71 | 73 | } |
72 | 74 | |
73 | 75 | protected Object createCollection(Class type) { |
76 | ErrorWritingException ex = null; | |
74 | 77 | Class defaultType = mapper().defaultImplementationOf(type); |
75 | 78 | try { |
76 | 79 | return defaultType.newInstance(); |
77 | 80 | } catch (InstantiationException e) { |
78 | throw new ConversionException("Cannot instantiate " + defaultType.getName(), e); | |
81 | ex = new ConversionException("Cannot instantiate default collection", e); | |
79 | 82 | } catch (IllegalAccessException e) { |
80 | throw new ConversionException("Cannot instantiate " + defaultType.getName(), e); | |
83 | ex = new ObjectAccessException("Cannot instantiate default collection", e); | |
81 | 84 | } |
85 | ex.add("collection-type", type.getName()); | |
86 | ex.add("default-type", defaultType.getName()); | |
87 | throw ex; | |
82 | 88 | } |
83 | 89 | } |
+3
-3
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2010, 2011, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2010, 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 |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.converters.collections; |
12 | 12 | |
13 | import com.thoughtworks.xstream.converters.ConversionException; | |
14 | 13 | import com.thoughtworks.xstream.converters.MarshallingContext; |
15 | 14 | import com.thoughtworks.xstream.converters.UnmarshallingContext; |
15 | import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; | |
16 | 16 | import com.thoughtworks.xstream.core.JVM; |
17 | 17 | import com.thoughtworks.xstream.core.util.Fields; |
18 | 18 | import com.thoughtworks.xstream.core.util.HierarchicalStreams; |
127 | 127 | result.putAll(sortedMap); // will use comparator for already sorted map |
128 | 128 | } |
129 | 129 | } catch (final IllegalAccessException e) { |
130 | throw new ConversionException("Cannot set comparator of TreeMap", e); | |
130 | throw new ObjectAccessException("Cannot set comparator of TreeMap", e); | |
131 | 131 | } |
132 | 132 | } |
133 | 133 | } |
+3
-3
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2010, 2011, 2013, 2014 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2010, 2011, 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 |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.converters.collections; |
12 | 12 | |
13 | import com.thoughtworks.xstream.converters.ConversionException; | |
14 | 13 | import com.thoughtworks.xstream.converters.MarshallingContext; |
15 | 14 | import com.thoughtworks.xstream.converters.UnmarshallingContext; |
15 | import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; | |
16 | 16 | import com.thoughtworks.xstream.core.JVM; |
17 | 17 | import com.thoughtworks.xstream.core.util.Fields; |
18 | 18 | import com.thoughtworks.xstream.core.util.PresortedSet; |
98 | 98 | try { |
99 | 99 | backingMap = sortedMapField.get(possibleResult); |
100 | 100 | } catch (IllegalAccessException e) { |
101 | throw new ConversionException("Cannot get backing map of TreeSet", e); | |
101 | throw new ObjectAccessException("Cannot get backing map of TreeSet", e); | |
102 | 102 | } |
103 | 103 | if (backingMap instanceof TreeMap) { |
104 | 104 | treeMap = (TreeMap)backingMap; |
+8
-9
0 | 0 | /* |
1 | * Copyright (C) 2013 XStream Committers. | |
1 | * Copyright (C) 2013, 2016 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.EnumMap; |
13 | 13 | import java.util.EnumSet; |
14 | 14 | import java.util.HashMap; |
15 | import java.util.Iterator; | |
16 | 15 | import java.util.Map; |
17 | 16 | |
17 | import com.thoughtworks.xstream.InitializationException; | |
18 | 18 | import com.thoughtworks.xstream.converters.ConversionException; |
19 | 19 | import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; |
20 | 20 | |
52 | 52 | Map<String, T> strings = new HashMap<String, T>(values.size()); |
53 | 53 | for (T value : values) { |
54 | 54 | if (strings.put(value.toString(), value) != null) { |
55 | throw new IllegalArgumentException("Enum type " | |
55 | throw new InitializationException("Enum type " | |
56 | 56 | + type.getName() |
57 | 57 | + " does not have unique string representations for its values"); |
58 | 58 | } |
62 | 62 | |
63 | 63 | private static <T> void checkType(Class<T> type) { |
64 | 64 | if (!Enum.class.isAssignableFrom(type) && type != Enum.class) { |
65 | throw new IllegalArgumentException("Converter can only handle enum types"); | |
65 | throw new InitializationException("Converter can only handle enum types"); | |
66 | 66 | } |
67 | 67 | } |
68 | 68 | |
93 | 93 | } |
94 | 94 | T result = strings.get(str); |
95 | 95 | if (result == null) { |
96 | throw new ConversionException("Invalid string representation for enum type " | |
97 | + enumType.getName() | |
98 | + ": <" | |
99 | + str | |
100 | + ">"); | |
96 | ConversionException exception = new ConversionException("Invalid string representation for enum type"); | |
97 | exception.add("enum-type", enumType.getName()); | |
98 | exception.add("enum-string", str); | |
99 | throw exception; | |
101 | 100 | } |
102 | 101 | return result; |
103 | 102 | } |
+94
-0
0 | /* | |
1 | * Copyright (C) 2015 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.06.2015 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.extended; | |
11 | ||
12 | import javax.activation.ActivationDataFlavor; | |
13 | ||
14 | import com.thoughtworks.xstream.converters.ConversionException; | |
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.HierarchicalStreamReader; | |
19 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; | |
20 | ||
21 | ||
22 | /** | |
23 | * Converts an {@link ActivationDataFlavor}. | |
24 | * | |
25 | * @author Jörg Schaible | |
26 | * @since 1.4.9 | |
27 | */ | |
28 | public class ActivationDataFlavorConverter implements Converter { | |
29 | ||
30 | public boolean canConvert(final Class type) { | |
31 | return type == ActivationDataFlavor.class; | |
32 | } | |
33 | ||
34 | public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { | |
35 | final ActivationDataFlavor dataFlavor = (ActivationDataFlavor)source; | |
36 | final String mimeType = dataFlavor.getMimeType(); | |
37 | if (mimeType != null) { | |
38 | writer.startNode("mimeType"); | |
39 | writer.setValue(mimeType); | |
40 | writer.endNode(); | |
41 | } | |
42 | final String name = dataFlavor.getHumanPresentableName(); | |
43 | if (name != null) { | |
44 | writer.startNode("humanRepresentableName"); | |
45 | writer.setValue(name); | |
46 | writer.endNode(); | |
47 | } | |
48 | final Class representationClass = dataFlavor.getRepresentationClass(); | |
49 | if (representationClass != null) { | |
50 | writer.startNode("representationClass"); | |
51 | context.convertAnother(representationClass); | |
52 | writer.endNode(); | |
53 | } | |
54 | } | |
55 | ||
56 | public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { | |
57 | String mimeType = null; | |
58 | String name = null; | |
59 | Class type = null; | |
60 | while (reader.hasMoreChildren()) { | |
61 | reader.moveDown(); | |
62 | ||
63 | final String elementName = reader.getNodeName(); | |
64 | if (elementName.equals("mimeType")) { | |
65 | mimeType = reader.getValue(); | |
66 | } else if (elementName.equals("humanRepresentableName")) { | |
67 | name = reader.getValue(); | |
68 | } else if (elementName.equals("representationClass")) { | |
69 | type = (Class)context.convertAnother(null, Class.class); | |
70 | } else { | |
71 | final ConversionException exception = new ConversionException("Unknown child element"); | |
72 | exception.add("element", reader.getNodeName()); | |
73 | throw exception; | |
74 | } | |
75 | reader.moveUp(); | |
76 | } | |
77 | ActivationDataFlavor dataFlavor = null; | |
78 | try { | |
79 | if (type == null) { | |
80 | dataFlavor = new ActivationDataFlavor(mimeType, name); | |
81 | } else if (mimeType == null) { | |
82 | dataFlavor = new ActivationDataFlavor(type, name); | |
83 | } else { | |
84 | dataFlavor = new ActivationDataFlavor(type, mimeType, name); | |
85 | } | |
86 | } catch (final IllegalArgumentException ex) { | |
87 | throw new ConversionException(ex); | |
88 | } catch (final NullPointerException ex) { | |
89 | throw new ConversionException(ex); | |
90 | } | |
91 | return dataFlavor; | |
92 | } | |
93 | } |
+4
-2
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2011, 2013, 2014, 2015 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2011, 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 |
108 | 108 | // try with next formatter |
109 | 109 | } |
110 | 110 | } |
111 | throw new ConversionException("Cannot parse date " + str); | |
111 | ConversionException exception = new ConversionException("Cannot parse date"); | |
112 | exception.add("date", str); | |
113 | throw exception; | |
112 | 114 | } |
113 | 115 | |
114 | 116 | public String toString(Object obj) { |
+8
-8
0 | 0 | /* |
1 | * Copyright (C) 2013 XStream Committers. | |
1 | * Copyright (C) 2013, 2016 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
246 | 246 | SingleValueConverter keyConverter = null; |
247 | 247 | SingleValueConverter valueConverter = null; |
248 | 248 | if (keyAsAttribute) { |
249 | keyConverter = getSingleValueConverter(keyType); | |
249 | keyConverter = getSingleValueConverter(keyType, "key"); | |
250 | 250 | } |
251 | 251 | if (valueAsAttribute || valueName == null) { |
252 | valueConverter = getSingleValueConverter(valueType); | |
252 | valueConverter = getSingleValueConverter(valueType, "value"); | |
253 | 253 | } |
254 | 254 | for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) { |
255 | 255 | Map.Entry entry = (Map.Entry)iterator.next(); |
286 | 286 | SingleValueConverter keyConverter = null; |
287 | 287 | SingleValueConverter valueConverter = null; |
288 | 288 | if (keyAsAttribute) { |
289 | keyConverter = getSingleValueConverter(keyType); | |
289 | keyConverter = getSingleValueConverter(keyType, "key"); | |
290 | 290 | } |
291 | 291 | if (valueAsAttribute || valueName == null) { |
292 | valueConverter = getSingleValueConverter(valueType); | |
292 | valueConverter = getSingleValueConverter(valueType, "value"); | |
293 | 293 | } |
294 | 294 | |
295 | 295 | while (reader.hasMoreChildren()) { |
335 | 335 | } |
336 | 336 | reader.moveUp(); |
337 | 337 | } else if (!valueAsAttribute) { |
338 | value = reader.getValue(); | |
338 | value = valueConverter.fromString(reader.getValue()); | |
339 | 339 | } |
340 | 340 | |
341 | 341 | target.put(key, value); |
346 | 346 | } |
347 | 347 | } |
348 | 348 | |
349 | private SingleValueConverter getSingleValueConverter(Class type) { | |
349 | private SingleValueConverter getSingleValueConverter(Class type, String part) { | |
350 | 350 | SingleValueConverter conv = UseAttributeForEnumMapper.isEnum(type) ? enumMapper |
351 | 351 | .getConverterFromItemType(null, type, null) : mapper().getConverterFromItemType( |
352 | 352 | null, type, null); |
355 | 355 | if (converter instanceof SingleValueConverter) { |
356 | 356 | conv = (SingleValueConverter)converter; |
357 | 357 | } else { |
358 | throw new ConversionException("No SingleValueConverter for key available"); | |
358 | throw new ConversionException("No SingleValueConverter for " + part + " available"); | |
359 | 359 | } |
360 | 360 | } |
361 | 361 | return conv; |
0 | /* | |
1 | * Copyright (C) 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 7. February 2016 by Aaron Johnson | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.extended; | |
11 | ||
12 | import java.net.URI; | |
13 | import java.net.URISyntaxException; | |
14 | import java.nio.file.FileSystems; | |
15 | import java.nio.file.Path; | |
16 | import java.nio.file.Paths; | |
17 | ||
18 | import com.thoughtworks.xstream.converters.ConversionException; | |
19 | import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; | |
20 | ||
21 | ||
22 | /** | |
23 | * Converts a {@link Path} to string. | |
24 | * | |
25 | * @author Aaron Johnson | |
26 | * @author Jörg Schaible | |
27 | */ | |
28 | public class PathConverter extends AbstractSingleValueConverter { | |
29 | ||
30 | @Override | |
31 | public boolean canConvert(final Class type) { | |
32 | return Path.class.isAssignableFrom(type); | |
33 | } | |
34 | ||
35 | @Override | |
36 | public Object fromString(final String str) { | |
37 | try { | |
38 | final URI uri = new URI(str); | |
39 | if (uri.getScheme() == null) { | |
40 | return Paths.get(str); | |
41 | } else { | |
42 | return Paths.get(uri); | |
43 | } | |
44 | } catch (final URISyntaxException e) { | |
45 | throw new ConversionException(e); | |
46 | } | |
47 | } | |
48 | ||
49 | @Override | |
50 | public String toString(final Object obj) { | |
51 | final Path path = (Path)obj; | |
52 | if (path.getFileSystem() == FileSystems.getDefault()) { | |
53 | return path.toString(); | |
54 | } else { | |
55 | return path.toUri().toString(); | |
56 | } | |
57 | } | |
58 | } |
+16
-19
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2014 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 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 |
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. May 2004 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.converters.extended; |
12 | 12 | |
13 | import com.thoughtworks.xstream.converters.ConversionException; | |
14 | ||
15 | 13 | import java.lang.reflect.Field; |
16 | 14 | |
15 | import com.thoughtworks.xstream.core.util.Fields; | |
16 | ||
17 | ||
17 | 18 | /** |
18 | * Factory for creating StackTraceElements. | |
19 | 19 | * Factory for creating StackTraceElements. |
20 | 20 | * |
21 | 21 | * @author <a href="mailto:boxley@thoughtworks.com">B. K. Oxley (binkley)</a> |
24 | 24 | */ |
25 | 25 | public class StackTraceElementFactory { |
26 | 26 | |
27 | public StackTraceElement nativeMethodElement(String declaringClass, String methodName) { | |
27 | public StackTraceElement nativeMethodElement(final String declaringClass, final String methodName) { | |
28 | 28 | return create(declaringClass, methodName, "Native Method", -2); |
29 | 29 | } |
30 | 30 | |
31 | public StackTraceElement unknownSourceElement(String declaringClass, String methodName) { | |
31 | public StackTraceElement unknownSourceElement(final String declaringClass, final String methodName) { | |
32 | 32 | return create(declaringClass, methodName, "Unknown Source", -1); |
33 | 33 | } |
34 | 34 | |
35 | public StackTraceElement element(String declaringClass, String methodName, String fileName) { | |
35 | public StackTraceElement element(final String declaringClass, final String methodName, final String fileName) { | |
36 | 36 | return create(declaringClass, methodName, fileName, -1); |
37 | 37 | } |
38 | 38 | |
39 | public StackTraceElement element(String declaringClass, String methodName, String fileName, int lineNumber) { | |
39 | public StackTraceElement element(final String declaringClass, final String methodName, final String fileName, | |
40 | final int lineNumber) { | |
40 | 41 | return create(declaringClass, methodName, fileName, lineNumber); |
41 | 42 | } |
42 | 43 | |
43 | protected StackTraceElement create(String declaringClass, String methodName, String fileName, int lineNumber) { | |
44 | StackTraceElement result = new Throwable().getStackTrace()[0]; | |
44 | protected StackTraceElement create(final String declaringClass, final String methodName, final String fileName, | |
45 | final int lineNumber) { | |
46 | final StackTraceElement result = new Throwable().getStackTrace()[0]; | |
45 | 47 | setField(result, "declaringClass", declaringClass); |
46 | 48 | setField(result, "methodName", methodName); |
47 | 49 | setField(result, "fileName", fileName); |
49 | 51 | return result; |
50 | 52 | } |
51 | 53 | |
52 | private void setField(StackTraceElement element, String fieldName, Object value) { | |
53 | try { | |
54 | final Field field = StackTraceElement.class.getDeclaredField(fieldName); | |
55 | field.setAccessible(true); | |
56 | field.set(element, value); | |
57 | } catch (Exception e) { | |
58 | throw new ConversionException(e); | |
59 | } | |
54 | private void setField(final StackTraceElement element, final String fieldName, final Object value) { | |
55 | final Field field = Fields.find(StackTraceElement.class, fieldName); | |
56 | Fields.write(field, element, value); | |
60 | 57 | } |
61 | 58 | |
62 | 59 | } |
+18
-1
0 | 0 | /* |
1 | * Copyright (C) 2011, 2013 XStream Committers. | |
1 | * Copyright (C) 2011, 2013, 2016 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
59 | 59 | /** |
60 | 60 | * Creates a new ToAttributedValueConverter instance. |
61 | 61 | * |
62 | * All field elements will be attributes, the element itself will have no value. | |
63 | * | |
64 | * @param type the type that is handled by this converter instance | |
65 | * @param mapper the mapper in use | |
66 | * @param reflectionProvider the reflection provider in use | |
67 | * @param lookup the converter lookup in use | |
68 | * @since 1.4.9 | |
69 | */ | |
70 | public ToAttributedValueConverter( | |
71 | final Class type, final Mapper mapper, final ReflectionProvider reflectionProvider, | |
72 | final ConverterLookup lookup) { | |
73 | this(type, mapper, reflectionProvider, lookup, null, null); | |
74 | } | |
75 | ||
76 | /** | |
77 | * Creates a new ToAttributedValueConverter instance. | |
78 | * | |
62 | 79 | * @param type the type that is handled by this converter instance |
63 | 80 | * @param mapper the mapper in use |
64 | 81 | * @param reflectionProvider the reflection provider in use |
+5
-3
0 | 0 | /* |
1 | * Copyright (C) 2006, 2007 XStream Committers. | |
1 | * Copyright (C) 2006, 2007, 2016 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 com.thoughtworks.xstream.converters.ConversionException; |
13 | 13 | import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; |
14 | import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; | |
14 | 15 | |
15 | 16 | import java.lang.reflect.Constructor; |
16 | 17 | import java.lang.reflect.InvocationTargetException; |
25 | 26 | * @author Paul Hammant |
26 | 27 | */ |
27 | 28 | public class ToStringConverter extends AbstractSingleValueConverter { |
29 | private static final Class[] STRING_PARAMETER = {String.class}; | |
28 | 30 | private final Class clazz; |
29 | 31 | private final Constructor ctor; |
30 | 32 | |
31 | 33 | public ToStringConverter(Class clazz) throws NoSuchMethodException { |
32 | 34 | this.clazz = clazz; |
33 | ctor = clazz.getConstructor(new Class[] {String.class}); | |
35 | ctor = clazz.getConstructor(STRING_PARAMETER); | |
34 | 36 | } |
35 | 37 | public boolean canConvert(Class type) { |
36 | 38 | return type.equals(clazz); |
45 | 47 | } catch (InstantiationException e) { |
46 | 48 | throw new ConversionException("Unable to instantiate single String param constructor", e); |
47 | 49 | } catch (IllegalAccessException e) { |
48 | throw new ConversionException("Unable to access single String param constructor", e); | |
50 | throw new ObjectAccessException("Unable to access single String param constructor", e); | |
49 | 51 | } catch (InvocationTargetException e) { |
50 | 52 | throw new ConversionException("Unable to target single String param constructor", e.getTargetException()); |
51 | 53 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2010, 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 |
20 | 20 | import java.util.Iterator; |
21 | 21 | import java.util.List; |
22 | 22 | |
23 | import com.thoughtworks.xstream.converters.ConversionException; | |
24 | import com.thoughtworks.xstream.converters.ErrorWritingException; | |
23 | 25 | import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; |
24 | 26 | |
25 | 27 | |
59 | 61 | } |
60 | 62 | |
61 | 63 | public Object newInstance(Class type) { |
64 | ErrorWritingException ex = null; | |
62 | 65 | try { |
63 | 66 | return type.newInstance(); |
64 | 67 | } catch (InstantiationException e) { |
65 | throw new ObjectAccessException("Cannot construct " + type.getName(), e); | |
68 | ex = new ConversionException("Cannot construct type", e); | |
66 | 69 | } catch (IllegalAccessException e) { |
67 | throw new ObjectAccessException("Cannot construct " + type.getName(), e); | |
70 | ex = new ObjectAccessException("Cannot construct type", e); | |
68 | 71 | } catch (SecurityException e) { |
69 | throw new ObjectAccessException("Cannot construct " + type.getName(), e); | |
72 | ex = new ObjectAccessException("Cannot construct type", e); | |
70 | 73 | } catch (ExceptionInInitializerError e) { |
71 | throw new ObjectAccessException("Cannot construct " + type.getName(), e); | |
74 | ex = new ConversionException("Cannot construct type", e); | |
72 | 75 | } |
76 | ex.add("construction-type", type.getName()); | |
77 | throw ex; | |
73 | 78 | } |
74 | 79 | |
75 | 80 | public void visitSerializableProperties(Object object, JavaBeanProvider.Visitor visitor) { |
76 | 81 | PropertyDescriptor[] propertyDescriptors = getSerializableProperties(object); |
77 | 82 | for (int i = 0; i < propertyDescriptors.length; i++ ) { |
83 | ErrorWritingException ex = null; | |
78 | 84 | PropertyDescriptor property = propertyDescriptors[i]; |
79 | 85 | try { |
80 | 86 | Method readMethod = property.getReadMethod(); |
85 | 91 | visitor.visit(name, property.getPropertyType(), definedIn, value); |
86 | 92 | } |
87 | 93 | } catch (IllegalArgumentException e) { |
88 | throw new ObjectAccessException("Could not get property " | |
89 | + object.getClass() | |
90 | + "." | |
91 | + property.getName(), e); | |
94 | ex = new ConversionException("Cannot get property", e); | |
92 | 95 | } catch (IllegalAccessException e) { |
93 | throw new ObjectAccessException("Could not get property " | |
94 | + object.getClass() | |
95 | + "." | |
96 | + property.getName(), e); | |
96 | ex = new ObjectAccessException("Cannot access property", e); | |
97 | 97 | } catch (InvocationTargetException e) { |
98 | throw new ObjectAccessException("Could not get property " | |
99 | + object.getClass() | |
100 | + "." | |
101 | + property.getName(), e); | |
98 | ex = new ConversionException("Cannot get property", e.getTargetException()); | |
99 | } | |
100 | if (ex != null) { | |
101 | ex.add("property", object.getClass() + "." + property.getName()); | |
102 | throw ex; | |
102 | 103 | } |
103 | 104 | } |
104 | 105 | } |
105 | 106 | |
106 | 107 | public void writeProperty(Object object, String propertyName, Object value) { |
108 | ErrorWritingException ex = null; | |
107 | 109 | PropertyDescriptor property = getProperty(propertyName, object.getClass()); |
108 | 110 | try { |
109 | 111 | property.getWriteMethod().invoke(object, new Object[]{value}); |
110 | 112 | } catch (IllegalArgumentException e) { |
111 | throw new ObjectAccessException("Could not set property " | |
112 | + object.getClass() | |
113 | + "." | |
114 | + property.getName(), e); | |
113 | ex = new ConversionException("Cannot set property", e); | |
115 | 114 | } catch (IllegalAccessException e) { |
116 | throw new ObjectAccessException("Could not set property " | |
117 | + object.getClass() | |
118 | + "." | |
119 | + property.getName(), e); | |
115 | ex = new ObjectAccessException("Cannot access property", e); | |
120 | 116 | } catch (InvocationTargetException e) { |
121 | throw new ObjectAccessException("Could not set property " | |
122 | + object.getClass() | |
123 | + "." | |
124 | + property.getName(), e); | |
117 | ex = new ConversionException("Cannot set property", e.getTargetException()); | |
118 | } | |
119 | if (ex != null) { | |
120 | ex.add("property", object.getClass() + "." + property.getName()); | |
121 | throw ex; | |
125 | 122 | } |
126 | 123 | } |
127 | 124 |
+19
-9
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 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 12. April 2005 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.converters.javabean; |
19 | 19 | import com.thoughtworks.xstream.converters.UnmarshallingContext; |
20 | 20 | import com.thoughtworks.xstream.converters.reflection.MissingFieldException; |
21 | 21 | import com.thoughtworks.xstream.core.util.FastField; |
22 | import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; | |
22 | 23 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
23 | 24 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; |
24 | import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; | |
25 | 25 | import com.thoughtworks.xstream.mapper.Mapper; |
26 | 26 | |
27 | ||
27 | 28 | /** |
28 | * Can convert any bean with a public default constructor. The {@link BeanProvider} used as | |
29 | * default is based on {@link java.beans.BeanInfo}. Indexed properties are currently not supported. | |
29 | * Can convert any bean with a public default constructor. The {@link BeanProvider} used as default is based on | |
30 | * {@link java.beans.BeanInfo}. Indexed properties are currently not supported. | |
30 | 31 | */ |
31 | 32 | public class JavaBeanConverter implements Converter { |
32 | 33 | |
81 | 82 | } |
82 | 83 | |
83 | 84 | public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { |
84 | final String classAttributeName = classAttributeIdentifier != null ? classAttributeIdentifier : mapper.aliasForSystemAttribute("class"); | |
85 | final String classAttributeName = mapper.aliasForSystemAttribute("class"); | |
85 | 86 | beanProvider.visitSerializableProperties(source, new JavaBeanProvider.Visitor() { |
86 | 87 | public boolean shouldVisit(String name, Class definedIn) { |
87 | 88 | return mapper.shouldSerializeMember(definedIn, name); |
89 | 90 | |
90 | 91 | public void visit(String propertyName, Class fieldType, Class definedIn, Object newObj) { |
91 | 92 | if (newObj != null) { |
92 | writeField(propertyName, fieldType, newObj, definedIn); | |
93 | writeField(propertyName, fieldType, newObj); | |
94 | } else { | |
95 | writeNullField(propertyName); | |
93 | 96 | } |
94 | 97 | } |
95 | 98 | |
96 | private void writeField(String propertyName, Class fieldType, Object newObj, Class definedIn) { | |
99 | private void writeField(String propertyName, Class fieldType, Object newObj) { | |
97 | 100 | Class actualType = newObj.getClass(); |
98 | 101 | Class defaultType = mapper.defaultImplementationOf(fieldType); |
99 | 102 | String serializedMember = mapper.serializedMember(source.getClass(), propertyName); |
100 | ExtendedHierarchicalStreamWriterHelper.startNode(writer, serializedMember, actualType); | |
103 | ExtendedHierarchicalStreamWriterHelper.startNode(writer, serializedMember, actualType); | |
101 | 104 | if (!actualType.equals(defaultType) && classAttributeName != null) { |
102 | 105 | writer.addAttribute(classAttributeName, mapper.serializedClass(actualType)); |
103 | 106 | } |
104 | 107 | context.convertAnother(newObj); |
105 | 108 | |
109 | writer.endNode(); | |
110 | } | |
111 | ||
112 | private void writeNullField(final String propertyName) { | |
113 | final String serializedMember = mapper.serializedMember(source.getClass(), propertyName); | |
114 | ExtendedHierarchicalStreamWriterHelper.startNode(writer, serializedMember, Mapper.Null.class); | |
115 | writer.addAttribute(classAttributeName, mapper.serializedClass(Mapper.Null.class)); | |
106 | 116 | writer.endNode(); |
107 | 117 | } |
108 | 118 | }); |
+4
-3
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 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 |
106 | 106 | try { |
107 | 107 | beanInfo = Introspector.getBeanInfo(type, Object.class); |
108 | 108 | } catch (IntrospectionException e) { |
109 | throw new ObjectAccessException( | |
110 | "Cannot get BeanInfo of type " + type.getName(), e); | |
109 | ObjectAccessException oaex = new ObjectAccessException("Cannot get BeanInfo of type", e); | |
110 | oaex.add("bean-type", type.getName()); | |
111 | throw oaex; | |
111 | 112 | } |
112 | 113 | nameMap = new OrderRetainingMap(); |
113 | 114 | PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); |
+8
-3
0 | 0 | /* |
1 | * Copyright (C) 2007, 2013 XStream Committers. | |
1 | * Copyright (C) 2007, 2013, 2016 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 | if (s.startsWith(className)) { |
89 | 89 | return s.substring(className.length()+1, s.length()-1); |
90 | 90 | } |
91 | throw new ConversionException("Cannot find name of attribute of type " + className, ex); | |
91 | ConversionException exception = new ConversionException("Cannot find name of attribute", ex); | |
92 | exception.add("attribute-type", className); | |
93 | throw exception; | |
92 | 94 | } |
93 | 95 | |
94 | 96 | public Object fromString(final String str) { |
95 | 97 | if (attributeMap.containsKey(str)) { |
96 | 98 | return attributeMap.get(str); |
97 | 99 | } |
98 | throw new ConversionException("Cannot find attribute of type " + type.getName() + " with name " + str); | |
100 | ConversionException exception = new ConversionException("Cannot find attribute"); | |
101 | exception.add("attribute-type", type.getName()); | |
102 | exception.add("attribute-name", str); | |
103 | throw exception; | |
99 | 104 | } |
100 | 105 | |
101 | 106 | private Object readResolve() { |
+113
-60
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, 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 02. March 2006 by Joerg Schaible |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.converters.reflection; |
19 | 19 | import com.thoughtworks.xstream.core.ReferencingMarshallingContext; |
20 | 20 | import com.thoughtworks.xstream.core.util.ArrayIterator; |
21 | 21 | import com.thoughtworks.xstream.core.util.FastField; |
22 | import com.thoughtworks.xstream.core.util.Fields; | |
22 | 23 | import com.thoughtworks.xstream.core.util.HierarchicalStreams; |
23 | 24 | import com.thoughtworks.xstream.core.util.Primitives; |
24 | 25 | import com.thoughtworks.xstream.core.util.SerializationMembers; |
93 | 94 | final MarshallingContext context) { |
94 | 95 | final List fields = new ArrayList(); |
95 | 96 | final Map defaultFieldDefinition = new HashMap(); |
97 | final Class sourceType = source.getClass(); | |
96 | 98 | |
97 | 99 | // Attributes might be preferred to child elements ... |
98 | 100 | reflectionProvider.visitSerializableFields(source, new ReflectionProvider.Visitor() { |
105 | 107 | if (!defaultFieldDefinition.containsKey(fieldName)) { |
106 | 108 | Class lookupType = source.getClass(); |
107 | 109 | // See XSTR-457 and OmitFieldsTest |
108 | if (definedIn != source.getClass() | |
110 | if (definedIn != sourceType | |
109 | 111 | && !mapper.shouldSerializeMember(lookupType, fieldName)) { |
110 | 112 | lookupType = definedIn; |
111 | 113 | } |
119 | 121 | final String attribute = mapper.aliasForAttribute(mapper.serializedMember( |
120 | 122 | definedIn, fieldName)); |
121 | 123 | if (value != null) { |
122 | if (writtenAttributes.contains(fieldName)) { // TODO: use attribute | |
123 | throw new ConversionException("Cannot write field with name '" | |
124 | + fieldName | |
125 | + "' twice as attribute for object of type " | |
126 | + source.getClass().getName()); | |
124 | if (writtenAttributes.contains(fieldName)) { | |
125 | ConversionException exception = | |
126 | new ConversionException("Cannot write field as attribute for object, attribute name already in use"); | |
127 | exception.add("field-name", fieldName); | |
128 | exception.add("object-type", sourceType.getName()); | |
129 | throw exception; | |
127 | 130 | } |
128 | 131 | final String str = converter.toString(value); |
129 | 132 | if (str != null) { |
130 | 133 | writer.addAttribute(attribute, str); |
131 | 134 | } |
132 | 135 | } |
133 | writtenAttributes.add(fieldName); // TODO: use attribute | |
136 | writtenAttributes.add(fieldName); | |
134 | 137 | } else { |
135 | 138 | fields.add(new FieldInfo(fieldName, type, definedIn, value)); |
136 | 139 | } |
139 | 142 | |
140 | 143 | new Object() { |
141 | 144 | { |
145 | final Map hiddenMappers = new HashMap(); | |
142 | 146 | for (Iterator fieldIter = fields.iterator(); fieldIter.hasNext();) { |
143 | 147 | FieldInfo info = (FieldInfo)fieldIter.next(); |
144 | 148 | if (info.value != null) { |
149 | final Field defaultField = (Field)defaultFieldDefinition.get(info.fieldName); | |
145 | 150 | Mapper.ImplicitCollectionMapping mapping = mapper |
146 | 151 | .getImplicitCollectionDefForFieldName( |
147 | source.getClass(), info.fieldName); | |
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 | } | |
148 | 166 | if (mapping != null) { |
149 | 167 | if (context instanceof ReferencingMarshallingContext) { |
150 | 168 | if (info.value != Collections.EMPTY_LIST |
204 | 222 | Class actualType = newObj != null ? newObj.getClass() : fieldType; |
205 | 223 | ExtendedHierarchicalStreamWriterHelper.startNode(writer, aliasName != null |
206 | 224 | ? aliasName |
207 | : mapper.serializedMember(source.getClass(), fieldName), actualType); | |
225 | : mapper.serializedMember(sourceType, fieldName), actualType); | |
208 | 226 | |
209 | 227 | if (newObj != null) { |
210 | 228 | Class defaultType = mapper.defaultImplementationOf(fieldType); |
299 | 317 | type = Primitives.box(type); |
300 | 318 | } |
301 | 319 | if (value != null && !type.isAssignableFrom(value.getClass())) { |
302 | throw new ConversionException("Cannot convert type " | |
303 | + value.getClass().getName() | |
304 | + " to type " | |
305 | + type.getName()); | |
320 | ConversionException exception = new ConversionException("Cannot convert type"); | |
321 | exception.add("source-type", value.getClass().getName()); | |
322 | exception.add("target-type", type.getName()); | |
323 | throw exception; | |
306 | 324 | } |
307 | 325 | seenFields.add(new FastField(classDefiningField, attrName)); |
308 | 326 | reflectionProvider.writeField(result, attrName, value, classDefiningField); |
331 | 349 | field = reflectionProvider.getFieldOrNull(fieldDeclaringClass, fieldName); |
332 | 350 | if (field == null) { |
333 | 351 | // it is not a field ... do we have a field alias? |
334 | Class itemType = mapper.getItemTypeForItemFieldName(resultType, fieldName); | |
352 | Class itemType = mapper.getItemTypeForItemFieldName(fieldDeclaringClass, fieldName); | |
335 | 353 | if (itemType != null) { |
336 | 354 | String classAttribute = HierarchicalStreams.readClassAttribute( |
337 | 355 | reader, mapper); |
346 | 364 | try { |
347 | 365 | type = mapper.realClass(originalNodeName); |
348 | 366 | implicitFieldName = mapper.getFieldNameForItemTypeAndName( |
349 | context.getRequiredType(), type, originalNodeName); | |
367 | fieldDeclaringClass, type, originalNodeName); | |
350 | 368 | } catch (CannotResolveClassException e) { |
351 | 369 | // type stays null ... |
352 | 370 | } |
354 | 372 | // either not a type or element is a type alias, but does not |
355 | 373 | // belong to an implicit field |
356 | 374 | handleUnknownField( |
357 | explicitDeclaringClass, fieldName, resultType, originalNodeName); | |
375 | explicitDeclaringClass, fieldName, fieldDeclaringClass, originalNodeName); | |
358 | 376 | |
359 | 377 | // element is unknown in declaring class, ignore it now |
360 | 378 | type = null; |
399 | 417 | if (field != null |
400 | 418 | && (fieldAlreadyChecked || (shouldUnmarshalField(field) && mapper |
401 | 419 | .shouldSerializeMember(field.getDeclaringClass(), fieldName)))) { |
402 | ||
403 | 420 | String classAttribute = HierarchicalStreams.readClassAttribute( |
404 | 421 | reader, mapper); |
405 | 422 | if (classAttribute != null) { |
445 | 462 | if (implicitFieldName == null) { |
446 | 463 | // look for implicit field |
447 | 464 | implicitFieldName = mapper.getFieldNameForItemTypeAndName( |
448 | context.getRequiredType(), | |
465 | fieldDeclaringClass, | |
449 | 466 | value != null ? value.getClass() : Mapper.Null.class, |
450 | 467 | originalNodeName); |
451 | 468 | } |
453 | 470 | implicitCollectionsForCurrentObject = new HashMap(); |
454 | 471 | } |
455 | 472 | writeValueToImplicitCollection( |
456 | value, implicitCollectionsForCurrentObject, result, implicitFieldName); | |
473 | value, implicitCollectionsForCurrentObject, result, new FieldLocation( | |
474 | implicitFieldName, fieldDeclaringClass)); | |
457 | 475 | } |
458 | 476 | |
459 | 477 | reader.moveUp(); |
466 | 484 | Object value = entry.getValue(); |
467 | 485 | if (value instanceof ArraysList) { |
468 | 486 | Object array = ((ArraysList)value).toPhysicalArray(); |
469 | reflectionProvider.writeField(result, (String)entry.getKey(), array, null); | |
487 | final FieldLocation fieldLocation = (FieldLocation)entry.getKey(); | |
488 | final Field field = reflectionProvider.getFieldOrNull(fieldLocation.definedIn, | |
489 | fieldLocation.fieldName); | |
490 | reflectionProvider.writeField(result, fieldLocation.fieldName, array, field != null | |
491 | ? field.getDeclaringClass() | |
492 | : null); | |
470 | 493 | } |
471 | 494 | } |
472 | 495 | } |
500 | 523 | throw new UnknownFieldException(resultType.getName(), fieldName); |
501 | 524 | } |
502 | 525 | |
503 | private void writeValueToImplicitCollection(Object value, Map implicitCollections, Object result, String implicitFieldName) { | |
504 | Collection collection = (Collection)implicitCollections.get(implicitFieldName); | |
526 | private void writeValueToImplicitCollection(Object value, Map implicitCollections, Object result, final FieldLocation fieldLocation) { | |
527 | Collection collection = (Collection)implicitCollections.get(fieldLocation); | |
505 | 528 | if (collection == null) { |
506 | Class physicalFieldType = reflectionProvider.getFieldType( | |
507 | result, implicitFieldName, null); | |
529 | final Field field = reflectionProvider.getFieldOrNull(fieldLocation.definedIn, fieldLocation.fieldName); | |
530 | Class physicalFieldType = field != null | |
531 | ? field.getType() | |
532 | : reflectionProvider.getFieldType(result, fieldLocation.fieldName, null); | |
508 | 533 | if (physicalFieldType.isArray()) { |
509 | 534 | collection = new ArraysList(physicalFieldType); |
510 | 535 | } else { |
511 | 536 | Class fieldType = mapper.defaultImplementationOf(physicalFieldType); |
512 | 537 | if (!(Collection.class.isAssignableFrom(fieldType) || Map.class |
513 | 538 | .isAssignableFrom(fieldType))) { |
514 | throw new ObjectAccessException( | |
515 | "Field " | |
516 | + implicitFieldName | |
517 | + " of " | |
518 | + result.getClass().getName() | |
519 | + " is configured for an implicit Collection or Map, but field is of type " | |
520 | + fieldType.getName()); | |
539 | ObjectAccessException oaex = new ObjectAccessException( | |
540 | "Field is configured for an implicit Collection or Map, but is of an incompatible type"); | |
541 | oaex.add("field", result.getClass().getName() + "."+fieldLocation.fieldName); | |
542 | oaex.add("field-type", fieldType.getName()); | |
543 | throw oaex; | |
521 | 544 | } |
522 | 545 | if (pureJavaReflectionProvider == null) { |
523 | 546 | pureJavaReflectionProvider = new PureJavaReflectionProvider(); |
527 | 550 | collection = (Collection)instance; |
528 | 551 | } else { |
529 | 552 | Mapper.ImplicitCollectionMapping implicitCollectionMapping = mapper |
530 | .getImplicitCollectionDefForFieldName(result.getClass(), implicitFieldName); | |
553 | .getImplicitCollectionDefForFieldName(fieldLocation.definedIn, fieldLocation.fieldName); | |
531 | 554 | collection = new MappingList( |
532 | 555 | (Map)instance, implicitCollectionMapping.getKeyFieldName()); |
533 | 556 | } |
534 | reflectionProvider.writeField(result, implicitFieldName, instance, null); | |
535 | } | |
536 | implicitCollections.put(implicitFieldName, collection); | |
557 | reflectionProvider.writeField(result, fieldLocation.fieldName, instance, field != null | |
558 | ? field.getDeclaringClass() | |
559 | : null); | |
560 | } | |
561 | implicitCollections.put(fieldLocation, collection); | |
537 | 562 | } |
538 | 563 | collection.add(value); |
539 | 564 | } |
583 | 608 | } |
584 | 609 | } |
585 | 610 | |
586 | private static class FieldInfo { | |
611 | private static class FieldLocation { | |
587 | 612 | final String fieldName; |
613 | final Class definedIn; | |
614 | ||
615 | FieldLocation(final String fieldName, final Class definedIn) { | |
616 | this.fieldName = fieldName; | |
617 | this.definedIn = definedIn; | |
618 | } | |
619 | ||
620 | public int hashCode() { | |
621 | final int prime = 7; | |
622 | int result = 1; | |
623 | result = prime * result + (definedIn == null ? 0 : definedIn.getName().hashCode()); | |
624 | result = prime * result + (fieldName == null ? 0 : fieldName.hashCode()); | |
625 | return result; | |
626 | } | |
627 | ||
628 | public boolean equals(final Object obj) { | |
629 | if (this == obj) { | |
630 | return true; | |
631 | } | |
632 | if (obj == null) { | |
633 | return false; | |
634 | } | |
635 | if (getClass() != obj.getClass()) { | |
636 | return false; | |
637 | } | |
638 | final FieldLocation other = (FieldLocation)obj; | |
639 | if (definedIn != other.definedIn) { | |
640 | return false; | |
641 | } | |
642 | if (fieldName == null) { | |
643 | if (other.fieldName != null) { | |
644 | return false; | |
645 | } | |
646 | } else if (!fieldName.equals(other.fieldName)) { | |
647 | return false; | |
648 | } | |
649 | return true; | |
650 | } | |
651 | } | |
652 | ||
653 | private static class FieldInfo extends FieldLocation { | |
588 | 654 | final Class type; |
589 | final Class definedIn; | |
590 | 655 | final Object value; |
591 | 656 | |
592 | FieldInfo(String fieldName, Class type, Class definedIn, Object value) { | |
593 | this.fieldName = fieldName; | |
657 | FieldInfo(final String fieldName, final Class type, final Class definedIn, final Object value) { | |
658 | super(fieldName, definedIn); | |
594 | 659 | this.type = type; |
595 | this.definedIn = definedIn; | |
596 | 660 | this.value = value; |
597 | 661 | } |
598 | 662 | } |
645 | 709 | fieldCache.put(itemType, field); |
646 | 710 | } |
647 | 711 | if (field != null) { |
648 | try { | |
649 | Object key = field.get(object); | |
650 | return map.put(key, object) == null; | |
651 | } catch (IllegalArgumentException e) { | |
652 | throw new ObjectAccessException("Could not get field " | |
653 | + field.getClass() | |
654 | + "." | |
655 | + field.getName(), e); | |
656 | } catch (IllegalAccessException e) { | |
657 | throw new ObjectAccessException("Could not get field " | |
658 | + field.getClass() | |
659 | + "." | |
660 | + field.getName(), e); | |
661 | } | |
712 | Object key = Fields.read(field, object); | |
713 | return map.put(key, object) == null; | |
662 | 714 | } |
663 | 715 | } else if (object instanceof Map.Entry) { |
664 | 716 | final Map.Entry entry = (Map.Entry)object; |
665 | 717 | return map.put(entry.getKey(), entry.getValue()) == null; |
666 | 718 | } |
667 | 719 | |
668 | throw new ConversionException("Element of type " | |
669 | + object.getClass().getName() | |
670 | + " is not defined as entry for map of type " | |
671 | + map.getClass().getName()); | |
720 | ConversionException exception = | |
721 | new ConversionException("Element is not defined as entry for implicit map"); | |
722 | exception.add("map-type", map.getClass().getName()); | |
723 | exception.add("element-type", object.getClass().getName()); | |
724 | throw exception; | |
672 | 725 | } |
673 | 726 | |
674 | 727 | public Object get(int index) { |
+15
-18
0 | 0 | /* |
1 | * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2013, 2014, 2015 XStream Committers. | |
1 | * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2013, 2014, 2015, 2016 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
124 | 124 | } else { |
125 | 125 | ConversionException exception = new ConversionException( |
126 | 126 | "Cannot handle CGLIB enhanced proxies without factory that have multiple callbacks"); |
127 | exception.add("proxy superclass", type.getSuperclass().getName()); | |
128 | exception.add("number of callbacks", String.valueOf(callbacks.length)); | |
127 | exception.add("proxy-superclass", type.getSuperclass().getName()); | |
128 | exception.add("number-of-callbacks", String.valueOf(callbacks.length)); | |
129 | 129 | throw exception; |
130 | 130 | } |
131 | 131 | writer.startNode("callbacks"); |
165 | 165 | } catch (NoSuchFieldException e) { |
166 | 166 | // OK, ignore |
167 | 167 | } catch (IllegalAccessException e) { |
168 | throw new ObjectAccessException("Access to serialVersionUID of " | |
169 | + type.getName() | |
170 | + " not allowed", e); | |
168 | ObjectAccessException exception = new ObjectAccessException("Cannot access field", e); | |
169 | exception.add("field", type.getName() + ".serialVersionUID"); | |
170 | throw exception; | |
171 | 171 | } |
172 | 172 | if (hasInterceptor) { |
173 | 173 | writer.startNode("instance"); |
201 | 201 | Object callback = field.get(source); |
202 | 202 | list.add(callback); |
203 | 203 | } catch (IllegalAccessException e) { |
204 | throw new ObjectAccessException("Access to " | |
205 | + type.getName() | |
206 | + "." | |
207 | + CALLBACK_MARKER | |
208 | + i | |
209 | + " not allowed", e); | |
204 | ObjectAccessException exception = new ObjectAccessException("Cannot access field", e); | |
205 | exception.add("field", type.getName() + "." + CALLBACK_MARKER + i); | |
206 | throw exception; | |
210 | 207 | } |
211 | 208 | } |
212 | 209 | return (Callback[])list.toArray(new Callback[list.size()]); |
268 | 265 | ? (Object[])null |
269 | 266 | : createNullArguments(parameterTypes)); |
270 | 267 | } catch (IllegalAccessException e) { |
271 | throw new ObjectAccessException("Access to " | |
272 | + calledMethod | |
273 | + " not allowed", e); | |
268 | ObjectAccessException exception = new ObjectAccessException("Cannot access method", e); | |
269 | exception.add("method", calledMethod.toString()); | |
270 | throw exception; | |
274 | 271 | } catch (InvocationTargetException e) { |
275 | 272 | // OK, ignore |
276 | 273 | } catch (NoSuchMethodException e) { |
277 | 274 | ConversionException exception = new ConversionException( |
278 | 275 | "CGLIB enhanced proxies wit abstract nethod that has not been implemented"); |
279 | exception.add("proxy superclass", type.getSuperclass().getName()); | |
276 | exception.add("proxy-superclass", type.getSuperclass().getName()); | |
280 | 277 | exception.add("method", method.toString()); |
281 | 278 | throw exception; |
282 | 279 | } |
335 | 332 | if (iface == Callback.class) { |
336 | 333 | ConversionException exception = new ConversionException( |
337 | 334 | "Cannot handle CGLIB callback"); |
338 | exception.add("CGLIB callback type", callback.getClass().getName()); | |
335 | exception.add("CGLIB-callback-type", callback.getClass().getName()); | |
339 | 336 | throw exception; |
340 | 337 | } |
341 | 338 | interfaces = iface.getInterfaces(); |
487 | 484 | if (!callbackIndexMap.containsKey(method)) { |
488 | 485 | ConversionException exception = new ConversionException( |
489 | 486 | "CGLIB callback not detected in reverse engineering"); |
490 | exception.add("CGLIB callback", method.toString()); | |
487 | exception.add("CGLIB-callback", method.toString()); | |
491 | 488 | throw exception; |
492 | 489 | } |
493 | 490 | return ((Integer)callbackIndexMap.get(method)).intValue(); |
+9
-8
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005, 2006 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 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 | import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; |
25 | 25 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
26 | 26 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; |
27 | import com.thoughtworks.xstream.io.StreamException; | |
27 | 28 | import com.thoughtworks.xstream.mapper.Mapper; |
28 | 29 | |
29 | 30 | import java.io.Externalizable; |
123 | 124 | externalizable.writeExternal(objectOutput); |
124 | 125 | objectOutput.popCallback(); |
125 | 126 | } catch (IOException e) { |
126 | throw new ConversionException("Cannot serialize " + source.getClass().getName() + " using Externalization", e); | |
127 | throw new StreamException("Cannot serialize " + source.getClass().getName() + " using Externalization", e); | |
127 | 128 | } |
128 | 129 | } |
129 | 130 | } |
167 | 168 | objectInput.popCallback(); |
168 | 169 | return serializationMembers.callReadResolve(externalizable); |
169 | 170 | } catch (NoSuchMethodException e) { |
170 | throw new ConversionException("Cannot construct " + type.getClass() + ", missing default constructor", e); | |
171 | throw new ConversionException("Missing default constructor of type", e); | |
171 | 172 | } catch (InvocationTargetException e) { |
172 | throw new ConversionException("Cannot construct " + type.getClass(), e); | |
173 | throw new ConversionException("Cannot construct type", e); | |
173 | 174 | } catch (InstantiationException e) { |
174 | throw new ConversionException("Cannot construct " + type.getClass(), e); | |
175 | throw new ConversionException("Cannot construct type", e); | |
175 | 176 | } catch (IllegalAccessException e) { |
176 | throw new ConversionException("Cannot construct " + type.getClass(), e); | |
177 | throw new ObjectAccessException("Cannot construct type", e); | |
177 | 178 | } catch (IOException e) { |
178 | throw new ConversionException("Cannot externalize " + type.getClass(), e); | |
179 | throw new StreamException("Cannot externalize " + type.getClass(), e); | |
179 | 180 | } catch (ClassNotFoundException e) { |
180 | throw new ConversionException("Cannot externalize " + type.getClass(), e); | |
181 | throw new ConversionException("Cannot construct type", e); | |
181 | 182 | } |
182 | 183 | } |
183 | 184 |
+114
-91
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | * | |
5 | 4 | * The software in this package is published under the terms of the BSD |
6 | 5 | * style license a copy of which has been included with this distribution in |
7 | 6 | * the LICENSE.txt file. |
8 | * | |
9 | 7 | * Created on 14. May 2004 by Joe Walnes |
10 | 8 | */ |
11 | 9 | package com.thoughtworks.xstream.converters.reflection; |
12 | 10 | |
13 | 11 | import java.lang.reflect.Field; |
14 | 12 | import java.lang.reflect.Modifier; |
15 | import java.util.ArrayList; | |
16 | 13 | import java.util.Collections; |
17 | 14 | import java.util.HashMap; |
18 | 15 | import java.util.Iterator; |
19 | import java.util.List; | |
16 | import java.util.LinkedList; | |
20 | 17 | import java.util.Map; |
21 | import java.util.Set; | |
22 | 18 | |
23 | 19 | import com.thoughtworks.xstream.core.Caching; |
24 | 20 | import com.thoughtworks.xstream.core.JVM; |
27 | 23 | |
28 | 24 | /** |
29 | 25 | * A field dictionary instance caches information about classes fields. |
30 | * | |
26 | * | |
31 | 27 | * @author Joe Walnes |
32 | 28 | * @author Jörg Schaible |
33 | 29 | * @author Guilherme Silveira |
34 | 30 | */ |
35 | 31 | public class FieldDictionary implements Caching { |
36 | 32 | |
37 | private transient Map keyedByFieldNameCache; | |
38 | private transient Map keyedByFieldKeyCache; | |
33 | private static final DictionaryEntry OBJECT_DICTIONARY_ENTRY = new DictionaryEntry(Collections.EMPTY_MAP, | |
34 | Collections.EMPTY_MAP); | |
35 | ||
36 | private transient Map dictionaryEntries; | |
39 | 37 | private final FieldKeySorter sorter; |
40 | 38 | |
41 | 39 | public FieldDictionary() { |
42 | 40 | this(new ImmutableFieldKeySorter()); |
43 | 41 | } |
44 | 42 | |
45 | public FieldDictionary(FieldKeySorter sorter) { | |
43 | public FieldDictionary(final FieldKeySorter sorter) { | |
46 | 44 | this.sorter = sorter; |
47 | 45 | init(); |
48 | 46 | } |
49 | 47 | |
50 | 48 | private void init() { |
51 | keyedByFieldNameCache = new HashMap(); | |
52 | keyedByFieldKeyCache = new HashMap(); | |
53 | keyedByFieldNameCache.put(Object.class, Collections.EMPTY_MAP); | |
54 | keyedByFieldKeyCache.put(Object.class, Collections.EMPTY_MAP); | |
49 | dictionaryEntries = new HashMap(); | |
55 | 50 | } |
56 | 51 | |
57 | 52 | /** |
58 | 53 | * Returns an iterator for all fields for some class |
59 | * | |
54 | * | |
60 | 55 | * @param cls the class you are interested on |
61 | 56 | * @return an iterator for its fields |
62 | 57 | * @deprecated As of 1.3, use {@link #fieldsFor(Class)} instead |
63 | 58 | */ |
64 | public Iterator serializableFieldsFor(Class cls) { | |
59 | public Iterator serializableFieldsFor(final Class cls) { | |
65 | 60 | return fieldsFor(cls); |
66 | 61 | } |
67 | 62 | |
68 | 63 | /** |
69 | 64 | * Returns an iterator for all fields for some class |
70 | * | |
65 | * | |
71 | 66 | * @param cls the class you are interested on |
72 | 67 | * @return an iterator for its fields |
73 | 68 | */ |
76 | 71 | } |
77 | 72 | |
78 | 73 | /** |
79 | * Returns an specific field of some class. If definedIn is null, it searches for the field | |
80 | * named 'name' inside the class cls. If definedIn is different than null, tries to find the | |
81 | * specified field name in the specified class cls which should be defined in class | |
82 | * definedIn (either equals cls or a one of it's superclasses) | |
83 | * | |
74 | * Returns an specific field of some class. If definedIn is null, it searches for the field named 'name' inside the | |
75 | * class cls. If definedIn is different than null, tries to find the specified field name in the specified class cls | |
76 | * which should be defined in class definedIn (either equals cls or a one of it's superclasses) | |
77 | * | |
84 | 78 | * @param cls the class where the field is to be searched |
85 | 79 | * @param name the field name |
86 | 80 | * @param definedIn the superclass (or the class itself) of cls where the field was defined |
87 | 81 | * @return the field itself |
88 | 82 | * @throws ObjectAccessException if no field can be found |
89 | 83 | */ |
90 | public Field field(Class cls, String name, Class definedIn) { | |
91 | Field field = fieldOrNull(cls, name, definedIn); | |
84 | public Field field(final Class cls, final String name, final Class definedIn) { | |
85 | final Field field = fieldOrNull(cls, name, definedIn); | |
92 | 86 | if (field == null) { |
93 | 87 | throw new MissingFieldException(cls.getName(), name); |
94 | 88 | } else { |
97 | 91 | } |
98 | 92 | |
99 | 93 | /** |
100 | * Returns an specific field of some class. If definedIn is null, it searches for the field | |
101 | * named 'name' inside the class cls. If definedIn is different than null, tries to find the | |
102 | * specified field name in the specified class cls which should be defined in class | |
103 | * definedIn (either equals cls or a one of it's superclasses) | |
104 | * | |
94 | * Returns an specific field of some class. If definedIn is null, it searches for the field named 'name' inside the | |
95 | * class cls. If definedIn is different than null, tries to find the specified field name in the specified class cls | |
96 | * which should be defined in class definedIn (either equals cls or a one of it's superclasses) | |
97 | * | |
105 | 98 | * @param cls the class where the field is to be searched |
106 | 99 | * @param name the field name |
107 | 100 | * @param definedIn the superclass (or the class itself) of cls where the field was defined |
108 | 101 | * @return the field itself or <code>null</code> |
109 | 102 | * @since 1.4 |
110 | 103 | */ |
111 | public Field fieldOrNull(Class cls, String name, Class definedIn) { | |
112 | Map fields = buildMap(cls, definedIn != null); | |
113 | Field field = (Field)fields.get(definedIn != null | |
104 | public Field fieldOrNull(final Class cls, final String name, final Class definedIn) { | |
105 | final Map fields = buildMap(cls, definedIn != null); | |
106 | final Field field = (Field)fields.get(definedIn != null | |
114 | 107 | ? (Object)new FieldKey(name, definedIn, -1) |
115 | 108 | : (Object)name); |
116 | 109 | return field; |
117 | 110 | } |
118 | 111 | |
119 | private Map buildMap(final Class type, boolean tupleKeyed) { | |
112 | private Map buildMap(final Class type, final boolean tupleKeyed) { | |
113 | ||
120 | 114 | Class cls = type; |
121 | synchronized (this) { | |
122 | if (!keyedByFieldNameCache.containsKey(type)) { | |
123 | final List superClasses = new ArrayList(); | |
124 | while (!Object.class.equals(cls) && cls != null) { | |
125 | superClasses.add(0, cls); | |
126 | cls = cls.getSuperclass(); | |
115 | ||
116 | DictionaryEntry lastDictionaryEntry = null; | |
117 | final LinkedList superClasses = new LinkedList(); | |
118 | while (lastDictionaryEntry == null) { | |
119 | if (Object.class.equals(cls) || cls == null) { | |
120 | lastDictionaryEntry = OBJECT_DICTIONARY_ENTRY; | |
121 | } else { | |
122 | lastDictionaryEntry = getDictionaryEntry(cls); | |
123 | } | |
124 | if (lastDictionaryEntry == null) { | |
125 | superClasses.addFirst(cls); | |
126 | cls = cls.getSuperclass(); | |
127 | } | |
128 | } | |
129 | ||
130 | for (final Iterator iter = superClasses.iterator(); iter.hasNext();) { | |
131 | cls = (Class)iter.next(); | |
132 | DictionaryEntry newDictionaryEntry = buildDictionaryEntryForClass(cls, lastDictionaryEntry); | |
133 | synchronized (this) { | |
134 | final DictionaryEntry concurrentEntry = getDictionaryEntry(cls); | |
135 | if (concurrentEntry == null) { | |
136 | dictionaryEntries.put(cls, newDictionaryEntry); | |
137 | } else { | |
138 | newDictionaryEntry = concurrentEntry; | |
127 | 139 | } |
128 | Map lastKeyedByFieldName = Collections.EMPTY_MAP; | |
129 | Map lastKeyedByFieldKey = Collections.EMPTY_MAP; | |
130 | for (final Iterator iter = superClasses.iterator(); iter.hasNext();) { | |
131 | cls = (Class)iter.next(); | |
132 | if (!keyedByFieldNameCache.containsKey(cls)) { | |
133 | final Map keyedByFieldName = new HashMap(lastKeyedByFieldName); | |
134 | final Map keyedByFieldKey = new OrderRetainingMap(lastKeyedByFieldKey); | |
135 | Field[] fields = cls.getDeclaredFields(); | |
136 | if (JVM.reverseFieldDefinition()) { | |
137 | for (int i = fields.length >> 1; i-- > 0;) { | |
138 | final int idx = fields.length - i - 1; | |
139 | final Field field = fields[i]; | |
140 | fields[i] = fields[idx]; | |
141 | fields[idx] = field; | |
142 | } | |
143 | } | |
144 | for (int i = 0; i < fields.length; i++ ) { | |
145 | Field field = fields[i]; | |
146 | if (!field.isAccessible()) { | |
147 | field.setAccessible(true); | |
148 | } | |
149 | FieldKey fieldKey = new FieldKey( | |
150 | field.getName(), field.getDeclaringClass(), i); | |
151 | Field existent = (Field)keyedByFieldName.get(field.getName()); | |
152 | if (existent == null | |
153 | // do overwrite statics | |
154 | || ((existent.getModifiers() & Modifier.STATIC) != 0) | |
155 | // overwrite non-statics with non-statics only | |
156 | || (existent != null && ((field.getModifiers() & Modifier.STATIC) == 0))) { | |
157 | keyedByFieldName.put(field.getName(), field); | |
158 | } | |
159 | keyedByFieldKey.put(fieldKey, field); | |
160 | } | |
161 | final Map sortedFieldKeys = sorter.sort(cls, keyedByFieldKey); | |
162 | keyedByFieldNameCache.put(cls, keyedByFieldName); | |
163 | keyedByFieldKeyCache.put(cls, sortedFieldKeys); | |
164 | lastKeyedByFieldName = keyedByFieldName; | |
165 | lastKeyedByFieldKey = sortedFieldKeys; | |
166 | } else { | |
167 | lastKeyedByFieldName = (Map)keyedByFieldNameCache.get(cls); | |
168 | lastKeyedByFieldKey = (Map)keyedByFieldKeyCache.get(cls); | |
169 | } | |
170 | } | |
171 | return tupleKeyed ? lastKeyedByFieldKey : lastKeyedByFieldName; | |
172 | } | |
173 | } | |
174 | return (Map)(tupleKeyed | |
175 | ? keyedByFieldKeyCache.get(type) | |
176 | : keyedByFieldNameCache.get(type)); | |
140 | } | |
141 | lastDictionaryEntry = newDictionaryEntry; | |
142 | } | |
143 | ||
144 | return tupleKeyed ? lastDictionaryEntry.getKeyedByFieldKey() : lastDictionaryEntry.getKeyedByFieldName(); | |
145 | ||
146 | } | |
147 | ||
148 | private DictionaryEntry buildDictionaryEntryForClass(final Class cls, final DictionaryEntry lastDictionaryEntry) { | |
149 | final Map keyedByFieldName = new HashMap(lastDictionaryEntry.getKeyedByFieldName()); | |
150 | final Map keyedByFieldKey = new OrderRetainingMap(lastDictionaryEntry.getKeyedByFieldKey()); | |
151 | final Field[] fields = cls.getDeclaredFields(); | |
152 | if (JVM.reverseFieldDefinition()) { | |
153 | for (int i = fields.length >> 1; i-- > 0;) { | |
154 | final int idx = fields.length - i - 1; | |
155 | final Field field = fields[i]; | |
156 | fields[i] = fields[idx]; | |
157 | fields[idx] = field; | |
158 | } | |
159 | } | |
160 | for (int i = 0; i < fields.length; i++) { | |
161 | final Field field = fields[i]; | |
162 | if (!field.isAccessible()) { | |
163 | field.setAccessible(true); | |
164 | } | |
165 | final FieldKey fieldKey = new FieldKey(field.getName(), field.getDeclaringClass(), i); | |
166 | final Field existent = (Field)keyedByFieldName.get(field.getName()); | |
167 | if (existent == null | |
168 | // do overwrite statics | |
169 | || (existent.getModifiers() & Modifier.STATIC) != 0 | |
170 | // overwrite non-statics with non-statics only | |
171 | || (existent != null && (field.getModifiers() & Modifier.STATIC) == 0)) { | |
172 | keyedByFieldName.put(field.getName(), field); | |
173 | } | |
174 | keyedByFieldKey.put(fieldKey, field); | |
175 | } | |
176 | final Map sortedFieldKeys = sorter.sort(cls, keyedByFieldKey); | |
177 | return new DictionaryEntry(keyedByFieldName, sortedFieldKeys); | |
178 | } | |
179 | ||
180 | private synchronized DictionaryEntry getDictionaryEntry(final Class cls) { | |
181 | return (DictionaryEntry)dictionaryEntries.get(cls); | |
177 | 182 | } |
178 | 183 | |
179 | 184 | public synchronized void flushCache() { |
180 | Set objectTypeSet = Collections.singleton(Object.class); | |
181 | keyedByFieldNameCache.keySet().retainAll(objectTypeSet); | |
182 | keyedByFieldKeyCache.keySet().retainAll(objectTypeSet); | |
185 | dictionaryEntries.clear(); | |
183 | 186 | if (sorter instanceof Caching) { |
184 | 187 | ((Caching)sorter).flushCache(); |
185 | 188 | } |
189 | 192 | init(); |
190 | 193 | return this; |
191 | 194 | } |
195 | ||
196 | private static final class DictionaryEntry { | |
197 | ||
198 | private final Map keyedByFieldName; | |
199 | private final Map keyedByFieldKey; | |
200 | ||
201 | public DictionaryEntry(final Map keyedByFieldName, final Map keyedByFieldKey) { | |
202 | super(); | |
203 | this.keyedByFieldName = keyedByFieldName; | |
204 | this.keyedByFieldKey = keyedByFieldKey; | |
205 | } | |
206 | ||
207 | public Map getKeyedByFieldName() { | |
208 | return keyedByFieldName; | |
209 | } | |
210 | ||
211 | public Map getKeyedByFieldKey() { | |
212 | return keyedByFieldKey; | |
213 | } | |
214 | } | |
192 | 215 | } |
+3
-2
0 | 0 | /* |
1 | * Copyright (C) 2011 XStream Committers. | |
1 | * Copyright (C) 2011, 2016 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
28 | 28 | * @since 1.4.2 |
29 | 29 | */ |
30 | 30 | public MissingFieldException(final String className, final String fieldName) { |
31 | super("No field '" + fieldName + "' found in class '" + className + "'"); | |
31 | super("Field not found in class."); | |
32 | 32 | this.className = className; |
33 | 33 | this.fieldName = fieldName; |
34 | add("field", className + "." + fieldName); | |
34 | 35 | } |
35 | 36 | |
36 | 37 | /** |
+3
-3
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 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.converters.reflection; |
12 | 12 | |
13 | import com.thoughtworks.xstream.XStreamException; | |
13 | import com.thoughtworks.xstream.converters.ErrorWritingException; | |
14 | 14 | |
15 | public class ObjectAccessException extends XStreamException { | |
15 | public class ObjectAccessException extends ErrorWritingException { | |
16 | 16 | public ObjectAccessException(String message) { |
17 | 17 | super(message); |
18 | 18 | } |
+20
-26
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2009, 2011, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2009, 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 |
11 | 11 | package com.thoughtworks.xstream.converters.reflection; |
12 | 12 | |
13 | 13 | import com.thoughtworks.xstream.core.JVM; |
14 | import com.thoughtworks.xstream.core.util.Fields; | |
14 | 15 | |
15 | 16 | import java.io.ByteArrayInputStream; |
16 | 17 | import java.io.ByteArrayOutputStream; |
56 | 57 | } |
57 | 58 | |
58 | 59 | public Object newInstance(Class type) { |
60 | ObjectAccessException oaex = null; | |
59 | 61 | try { |
60 | 62 | Constructor[] constructors = type.getDeclaredConstructors(); |
61 | 63 | for (int i = 0; i < constructors.length; i++) { |
70 | 72 | if (Serializable.class.isAssignableFrom(type)) { |
71 | 73 | return instantiateUsingSerialization(type); |
72 | 74 | } else { |
73 | throw new ObjectAccessException("Cannot construct " + type.getName() | |
74 | + " as it does not have a no-args constructor"); | |
75 | oaex = new ObjectAccessException("Cannot construct type as it does not have a no-args constructor"); | |
75 | 76 | } |
76 | 77 | } catch (InstantiationException e) { |
77 | throw new ObjectAccessException("Cannot construct " + type.getName(), e); | |
78 | oaex = new ObjectAccessException("Cannot construct type", e); | |
78 | 79 | } catch (IllegalAccessException e) { |
79 | throw new ObjectAccessException("Cannot construct " + type.getName(), e); | |
80 | oaex = new ObjectAccessException("Cannot construct type", e); | |
80 | 81 | } catch (InvocationTargetException e) { |
81 | 82 | if (e.getTargetException() instanceof RuntimeException) { |
82 | 83 | throw (RuntimeException)e.getTargetException(); |
83 | 84 | } else if (e.getTargetException() instanceof Error) { |
84 | 85 | throw (Error)e.getTargetException(); |
85 | 86 | } else { |
86 | throw new ObjectAccessException("Constructor for " + type.getName() + " threw an exception", e.getTargetException()); | |
87 | } | |
88 | } | |
87 | oaex = new ObjectAccessException("Constructor for type threw an exception", e.getTargetException()); | |
88 | } | |
89 | } | |
90 | oaex.add("construction-type", type.getName()); | |
91 | throw oaex; | |
89 | 92 | } |
90 | 93 | |
91 | 94 | private Object instantiateUsingSerialization(final Class type) { |
95 | ObjectAccessException oaex = null; | |
92 | 96 | try { |
93 | 97 | synchronized (serializedDataCache) { |
94 | 98 | byte[] data = (byte[]) serializedDataCache.get(type); |
118 | 122 | return in.readObject(); |
119 | 123 | } |
120 | 124 | } catch (IOException e) { |
121 | throw new ObjectAccessException("Cannot create " + type.getName() + " by JDK serialization", e); | |
125 | oaex = new ObjectAccessException("Cannot create type by JDK serialization", e); | |
122 | 126 | } catch (ClassNotFoundException e) { |
123 | throw new ObjectAccessException("Cannot find class " + e.getMessage(), e); | |
124 | } | |
127 | oaex = new ObjectAccessException("Cannot find class", e); | |
128 | } | |
129 | oaex.add("construction-type", type.getName()); | |
130 | throw oaex; | |
125 | 131 | } |
126 | 132 | |
127 | 133 | public void visitSerializableFields(Object object, ReflectionProvider.Visitor visitor) { |
131 | 137 | continue; |
132 | 138 | } |
133 | 139 | validateFieldAccess(field); |
134 | try { | |
135 | Object value = field.get(object); | |
136 | visitor.visit(field.getName(), field.getType(), field.getDeclaringClass(), value); | |
137 | } catch (IllegalArgumentException e) { | |
138 | throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); | |
139 | } catch (IllegalAccessException e) { | |
140 | throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); | |
141 | } | |
140 | Object value = Fields.read(field, object); | |
141 | visitor.visit(field.getName(), field.getType(), field.getDeclaringClass(), value); | |
142 | 142 | } |
143 | 143 | } |
144 | 144 | |
145 | 145 | public void writeField(Object object, String fieldName, Object value, Class definedIn) { |
146 | 146 | Field field = fieldDictionary.field(object.getClass(), fieldName, definedIn); |
147 | 147 | validateFieldAccess(field); |
148 | try { | |
149 | field.set(object, value); | |
150 | } catch (IllegalArgumentException e) { | |
151 | throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), e); | |
152 | } catch (IllegalAccessException e) { | |
153 | throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), e); | |
154 | } | |
148 | Fields.write(field, object, value); | |
155 | 149 | } |
156 | 150 | |
157 | 151 | public Class getFieldType(Object object, String fieldName, Class definedIn) { |
+9
-21
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 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 | import com.thoughtworks.xstream.core.JVM; |
32 | 32 | import com.thoughtworks.xstream.core.util.CustomObjectInputStream; |
33 | 33 | import com.thoughtworks.xstream.core.util.CustomObjectOutputStream; |
34 | import com.thoughtworks.xstream.core.util.Fields; | |
34 | 35 | import com.thoughtworks.xstream.core.util.HierarchicalStreams; |
35 | 36 | import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; |
36 | 37 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
37 | 38 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; |
39 | import com.thoughtworks.xstream.io.StreamException; | |
38 | 40 | import com.thoughtworks.xstream.mapper.Mapper; |
39 | 41 | |
40 | 42 | /** |
150 | 152 | ObjectStreamField field = objectStreamClass.getField(name); |
151 | 153 | Object value = fields.get(name); |
152 | 154 | if (field == null) { |
153 | throw new ObjectAccessException("Class " + value.getClass().getName() | |
154 | + " may not write a field named '" + name + "'"); | |
155 | throw new MissingFieldException(value.getClass().getName(), name); | |
155 | 156 | } |
156 | 157 | if (value != null) { |
157 | 158 | ExtendedHierarchicalStreamWriterHelper.startNode( |
279 | 280 | } |
280 | 281 | } |
281 | 282 | } catch (IOException e) { |
282 | throw new ObjectAccessException("Could not call defaultWriteObject()", e); | |
283 | throw new StreamException("Cannot write defaults", e); | |
283 | 284 | } |
284 | 285 | } |
285 | 286 | |
290 | 291 | } |
291 | 292 | |
292 | 293 | private Object readField(ObjectStreamField field, Class type, Object instance) { |
293 | try { | |
294 | Field javaField = type.getDeclaredField(field.getName()); | |
295 | if (!javaField.isAccessible()) { | |
296 | javaField.setAccessible(true); | |
297 | } | |
298 | return javaField.get(instance); | |
299 | } catch (IllegalArgumentException e) { | |
300 | throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); | |
301 | } catch (IllegalAccessException e) { | |
302 | throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); | |
303 | } catch (NoSuchFieldException e) { | |
304 | throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); | |
305 | } catch (SecurityException e) { | |
306 | throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); | |
307 | } | |
294 | Field javaField = Fields.find(type, field.getName()); | |
295 | return Fields.read(javaField, instance); | |
308 | 296 | } |
309 | 297 | |
310 | 298 | protected List hierarchyFor(Class type) { |
425 | 413 | try { |
426 | 414 | validation.validateObject(); |
427 | 415 | } catch (InvalidObjectException e) { |
428 | throw new ObjectAccessException("Cannot validate object : " + e.getMessage(), e); | |
416 | throw new ObjectAccessException("Cannot validate object", e); | |
429 | 417 | } |
430 | 418 | } |
431 | 419 | }, priority); |
457 | 445 | try { |
458 | 446 | callback.defaultReadObject(); |
459 | 447 | } catch (IOException e) { |
460 | throw new ObjectAccessException("Could not call defaultWriteObject()", e); | |
448 | throw new StreamException("Cannot read defaults", e); | |
461 | 449 | } |
462 | 450 | } |
463 | 451 | } |
+31
-27
0 | 0 | /* |
1 | * Copyright (C) 2007, 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2007, 2009, 2011, 2016 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
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 |
6 | 6 | * the LICENSE.txt file. |
7 | * | |
7 | * | |
8 | 8 | * Created on 10. April 2007 by Guilherme Silveira |
9 | 9 | */ |
10 | 10 | package com.thoughtworks.xstream.converters.reflection; |
11 | ||
12 | import com.thoughtworks.xstream.core.Caching; | |
13 | import com.thoughtworks.xstream.core.util.OrderRetainingMap; | |
14 | import com.thoughtworks.xstream.io.StreamException; | |
15 | 11 | |
16 | 12 | import java.util.Arrays; |
17 | 13 | import java.util.Comparator; |
18 | 14 | import java.util.HashMap; |
19 | 15 | import java.util.Map; |
20 | 16 | |
17 | import com.thoughtworks.xstream.converters.ConversionException; | |
18 | import com.thoughtworks.xstream.core.Caching; | |
19 | import com.thoughtworks.xstream.core.util.OrderRetainingMap; | |
20 | ||
21 | 21 | |
22 | 22 | /** |
23 | * The default implementation for sorting fields. Invoke registerFieldOrder in order to set the | |
24 | * field order for an specific type. | |
25 | * | |
23 | * The default implementation for sorting fields. Invoke registerFieldOrder in order to set the field order for an | |
24 | * specific type. | |
25 | * | |
26 | 26 | * @author Guilherme Silveira |
27 | 27 | * @since 1.2.2 |
28 | 28 | */ |
29 | 29 | public class SortableFieldKeySorter implements FieldKeySorter, Caching { |
30 | 30 | |
31 | private final static FieldKey[] EMPTY_FIELD_KEY_ARRAY = {}; | |
31 | 32 | private final Map map = new HashMap(); |
32 | 33 | |
33 | public Map sort(Class type, Map keyedByFieldKey) { | |
34 | public Map sort(final Class type, final Map keyedByFieldKey) { | |
34 | 35 | if (map.containsKey(type)) { |
35 | Map result = new OrderRetainingMap(); | |
36 | FieldKey[] fieldKeys = (FieldKey[])keyedByFieldKey.keySet().toArray( | |
37 | new FieldKey[keyedByFieldKey.size()]); | |
36 | final Map result = new OrderRetainingMap(); | |
37 | final FieldKey[] fieldKeys = (FieldKey[])keyedByFieldKey.keySet().toArray(EMPTY_FIELD_KEY_ARRAY); | |
38 | 38 | Arrays.sort(fieldKeys, (Comparator)map.get(type)); |
39 | 39 | for (int i = 0; i < fieldKeys.length; i++ ) { |
40 | 40 | result.put(fieldKeys[i], keyedByFieldKey.get(fieldKeys[i])); |
46 | 46 | } |
47 | 47 | |
48 | 48 | /** |
49 | * Registers the field order to use for a specific type. This will not affect any of the | |
50 | * type's super or sub classes. If you skip a field which will be serialized, XStream will | |
51 | * thrown an StreamException during the serialization process. | |
52 | * | |
49 | * Registers the field order to use for a specific type. This will not affect any of the type's super or sub | |
50 | * classes. If you skip a field which will be serialized, XStream will thrown a {@link ConversionException} during | |
51 | * the serialization process. | |
52 | * | |
53 | 53 | * @param type the type |
54 | 54 | * @param fields the field order |
55 | 55 | */ |
56 | public void registerFieldOrder(Class type, String[] fields) { | |
57 | map.put(type, new FieldComparator(fields)); | |
56 | public void registerFieldOrder(final Class type, final String[] fields) { | |
57 | map.put(type, new FieldComparator(type, fields)); | |
58 | 58 | } |
59 | 59 | |
60 | 60 | private class FieldComparator implements Comparator { |
61 | 61 | |
62 | 62 | private final String[] fieldOrder; |
63 | private final Class type; | |
63 | 64 | |
64 | public FieldComparator(String[] fields) { | |
65 | this.fieldOrder = fields; | |
65 | public FieldComparator(final Class type, final String[] fields) { | |
66 | this.type = type; | |
67 | fieldOrder = fields; | |
66 | 68 | } |
67 | 69 | |
68 | public int compare(String first, String second) { | |
70 | public int compare(final String first, final String second) { | |
69 | 71 | int firstPosition = -1, secondPosition = -1; |
70 | for (int i = 0; i < fieldOrder.length; i++ ) { | |
72 | for (int i = 0; i < fieldOrder.length; i++) { | |
71 | 73 | if (fieldOrder[i].equals(first)) { |
72 | 74 | firstPosition = i; |
73 | 75 | } |
77 | 79 | } |
78 | 80 | if (firstPosition == -1 || secondPosition == -1) { |
79 | 81 | // field not defined!!! |
80 | throw new StreamException( | |
81 | "You have not given XStream a list of all fields to be serialized."); | |
82 | final ConversionException exception = new ConversionException( | |
83 | "Incomplete list of serialized fields for type"); | |
84 | exception.add("sort-type", type.getName()); | |
85 | throw exception; | |
82 | 86 | } |
83 | 87 | return firstPosition - secondPosition; |
84 | 88 | } |
85 | 89 | |
86 | public int compare(Object firstObject, Object secondObject) { | |
87 | FieldKey first = (FieldKey)firstObject, second = (FieldKey)secondObject; | |
90 | public int compare(final Object firstObject, final Object secondObject) { | |
91 | final FieldKey first = (FieldKey)firstObject, second = (FieldKey)secondObject; | |
88 | 92 | return compare(first.getFieldName(), second.getFieldName()); |
89 | 93 | } |
90 | 94 |
+13
-5
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2011, 2013, 2014 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2011, 2013, 2014, 2016 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * Created on 08. January 2014 by Joerg Schaible, factored out from SunUnsafeReflectionProvider |
7 | 7 | package com.thoughtworks.xstream.converters.reflection; |
8 | 8 | |
9 | 9 | import java.lang.reflect.Field; |
10 | ||
11 | import com.thoughtworks.xstream.converters.ConversionException; | |
12 | import com.thoughtworks.xstream.converters.ErrorWritingException; | |
10 | 13 | |
11 | 14 | import sun.misc.Unsafe; |
12 | 15 | |
69 | 72 | |
70 | 73 | public Object newInstance(Class type) { |
71 | 74 | if (exception != null) { |
72 | throw new ObjectAccessException("Cannot construct " + type.getName(), exception); | |
75 | ObjectAccessException ex = new ObjectAccessException("Cannot construct type", exception); | |
76 | ex.add("construction-type", type.getName()); | |
77 | throw ex; | |
73 | 78 | } |
79 | ErrorWritingException ex = null; | |
74 | 80 | try { |
75 | 81 | return unsafe.allocateInstance(type); |
76 | 82 | } catch (SecurityException e) { |
77 | throw new ObjectAccessException("Cannot construct " + type.getName(), e); | |
83 | ex = new ObjectAccessException("Cannot construct type", e); | |
78 | 84 | } catch (InstantiationException e) { |
79 | throw new ObjectAccessException("Cannot construct " + type.getName(), e); | |
85 | ex = new ConversionException("Cannot construct type", e); | |
80 | 86 | } catch (IllegalArgumentException e) { |
81 | throw new ObjectAccessException("Cannot construct " + type.getName(), e); | |
87 | ex = new ObjectAccessException("Cannot construct type", e); | |
82 | 88 | } |
89 | ex.add("construction-type", type.getName()); | |
90 | throw ex; | |
83 | 91 | } |
84 | 92 | |
85 | 93 | protected void validateFieldAccess(Field field) { |
+11
-10
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2011, 2013, 2014 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2011, 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 |
57 | 57 | |
58 | 58 | private void write(Field field, Object object, Object value) { |
59 | 59 | if (exception != null) { |
60 | throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), | |
61 | exception); | |
60 | ObjectAccessException ex = new ObjectAccessException("Cannot set field", exception); | |
61 | ex.add("field", object.getClass() + "." + field.getName()); | |
62 | throw ex; | |
62 | 63 | } |
63 | 64 | try { |
64 | 65 | long offset = getFieldOffset(field); |
81 | 82 | } else if (type.equals(Boolean.TYPE)) { |
82 | 83 | unsafe.putBoolean(object, offset, ((Boolean)value).booleanValue()); |
83 | 84 | } else { |
84 | throw new ObjectAccessException("Could not set field " | |
85 | + object.getClass() | |
86 | + "." | |
87 | + field.getName() | |
88 | + ": Unknown type " | |
89 | + type); | |
85 | ObjectAccessException ex = new ObjectAccessException("Cannot set field of unknown type", exception); | |
86 | ex.add("field", object.getClass() + "." + field.getName()); | |
87 | ex.add("unknown-type", type.getName()); | |
88 | throw ex; | |
90 | 89 | } |
91 | 90 | } else { |
92 | 91 | unsafe.putObject(object, offset, value); |
93 | 92 | } |
94 | 93 | |
95 | 94 | } catch (IllegalArgumentException e) { |
96 | throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), e); | |
95 | ObjectAccessException ex = new ObjectAccessException("Cannot set field", e); | |
96 | ex.add("field", object.getClass() + "." + field.getName()); | |
97 | throw ex; | |
97 | 98 | } |
98 | 99 | } |
99 | 100 |
0 | 0 | /* |
1 | * Copyright (C) 2006, 2007, 2008, 2011 XStream Committers. | |
1 | * Copyright (C) 2006, 2007, 2008, 2011, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
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 |
6 | 6 | * the LICENSE.txt file. |
7 | * | |
7 | * | |
8 | 8 | * Created on 15. March 2007 by Joerg Schaible |
9 | 9 | */ |
10 | 10 | package com.thoughtworks.xstream.core; |
21 | 21 | |
22 | 22 | /** |
23 | 23 | * Abstract base class for a TreeUnmarshaller, that resolves references. |
24 | * | |
24 | * | |
25 | 25 | * @author Joe Walnes |
26 | 26 | * @author Jörg Schaible |
27 | 27 | * @author Mauro Talevi |
48 | 48 | } |
49 | 49 | } |
50 | 50 | final Object result; |
51 | String attributeName = getMapper().aliasForSystemAttribute("reference"); | |
52 | String reference = attributeName == null ? null : reader.getAttribute(attributeName); | |
51 | final String attributeName = getMapper().aliasForSystemAttribute("reference"); | |
52 | final String reference = attributeName == null ? null : reader.getAttribute(attributeName); | |
53 | final boolean isReferenceable = getMapper().isReferenceable(type); | |
53 | 54 | if (reference != null) { |
54 | Object cache = values.get(getReferenceKey(reference)); | |
55 | final Object cache = isReferenceable ? values.get(getReferenceKey(reference)) : null; | |
55 | 56 | if (cache == null) { |
56 | 57 | final ConversionException ex = new ConversionException("Invalid reference"); |
57 | 58 | ex.add("reference", reference); |
59 | ex.add("referenced-type", type.getName()); | |
60 | ex.add("referenceable", Boolean.toString(isReferenceable)); | |
58 | 61 | throw ex; |
59 | 62 | } |
60 | 63 | result = cache == NULL ? null : cache; |
64 | } else if (!isReferenceable) { | |
65 | result = super.convert(parent, type, converter); | |
61 | 66 | } else { |
62 | 67 | Object currentReferenceKey = getCurrentReferenceKey(); |
63 | 68 | parentStack.push(currentReferenceKey); |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 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.XStreamException; |
14 | 14 | |
15 | 15 | /** |
16 | * JDK1.3 friendly exception that retains cause. | |
17 | 16 | * @deprecated As of 1.3, use {@link XStreamException} instead |
18 | 17 | */ |
19 | 18 | public abstract class BaseException extends RuntimeException { |
22 | 21 | super(message); |
23 | 22 | } |
24 | 23 | |
25 | public abstract Throwable getCause(); | |
24 | protected BaseException(String message, Throwable cause) { | |
25 | super(message, cause); | |
26 | } | |
26 | 27 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 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 |
57 | 57 | return converter; |
58 | 58 | } |
59 | 59 | } |
60 | throw new ConversionException("No converter specified for " + type); | |
60 | ConversionException exception = new ConversionException("No converter specified"); | |
61 | exception.add("type", type.getName()); | |
62 | throw exception; | |
61 | 63 | } |
62 | 64 | |
63 | 65 | public void registerConverter(Converter converter, int priority) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2010, 2011, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2010, 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 java.io.StreamCorruptedException; |
20 | 20 | import java.util.Map; |
21 | 21 | |
22 | import com.thoughtworks.xstream.converters.ConversionException; | |
23 | 22 | import com.thoughtworks.xstream.converters.DataHolder; |
23 | import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; | |
24 | 24 | import com.thoughtworks.xstream.core.ClassLoaderReference; |
25 | import com.thoughtworks.xstream.io.StreamException; | |
25 | 26 | |
26 | 27 | public class CustomObjectInputStream extends ObjectInputStream { |
27 | 28 | |
62 | 63 | result.pushCallback(callback); |
63 | 64 | } |
64 | 65 | return result; |
66 | } catch (SecurityException e) { | |
67 | throw new ObjectAccessException("Cannot create CustomObjectStream", e); | |
65 | 68 | } catch (IOException e) { |
66 | throw new ConversionException("Cannot create CustomObjectStream", e); | |
69 | throw new StreamException("Cannot create CustomObjectStream", e); | |
67 | 70 | } |
68 | 71 | } |
69 | 72 |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 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 |
15 | 15 | import java.io.ObjectOutputStream; |
16 | 16 | import java.util.Map; |
17 | 17 | |
18 | import com.thoughtworks.xstream.converters.ConversionException; | |
19 | 18 | import com.thoughtworks.xstream.converters.DataHolder; |
19 | import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; | |
20 | import com.thoughtworks.xstream.io.StreamException; | |
20 | 21 | |
21 | 22 | public class CustomObjectOutputStream extends ObjectOutputStream { |
22 | 23 | |
35 | 36 | result.pushCallback(callback); |
36 | 37 | } |
37 | 38 | return result; |
39 | } catch (SecurityException e) { | |
40 | throw new ObjectAccessException("Cannot create CustomObjectStream", e); | |
38 | 41 | } catch (IOException e) { |
39 | throw new ConversionException("Cannot create CustomObjectStream", e); | |
42 | throw new StreamException("Cannot create CustomObjectStream", e); | |
40 | 43 | } |
41 | 44 | } |
42 | 45 |
+32
-28
0 | 0 | /* |
1 | * Copyright (c) 2007, 2009, 2010, 2011, 2012, 2013 XStream Committers. | |
1 | * Copyright (c) 2007, 2009, 2010, 2011, 2012, 2013, 2016 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
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 |
6 | 6 | * the LICENSE.txt file. |
7 | * | |
7 | * | |
8 | 8 | * Created on 30. March 2007 by Joerg Schaible |
9 | 9 | */ |
10 | 10 | package com.thoughtworks.xstream.core.util; |
22 | 22 | |
23 | 23 | /** |
24 | 24 | * A dependency injection factory. |
25 | * | |
25 | * | |
26 | 26 | * @author Jörg Schaible |
27 | 27 | * @since 1.2.2 |
28 | 28 | */ |
34 | 34 | * matching the sequence of the dependencies' types match first. Otherwise all the types of the dependencies must |
35 | 35 | * match one of the the parameters although no dependency is used twice. Use a {@link TypedNull} instance to inject |
36 | 36 | * <code>null</code> as parameter. |
37 | * | |
37 | * | |
38 | 38 | * @param type the type to create an instance of |
39 | 39 | * @param dependencies the possible dependencies |
40 | 40 | * @return the instantiated object |
45 | 45 | public static Object newInstance(final Class type, final Object[] dependencies) { |
46 | 46 | return newInstance(type, dependencies, null); |
47 | 47 | } |
48 | ||
48 | ||
49 | 49 | /** |
50 | 50 | * Create an instance with dependency injection. The given dependencies are used to match the parameters of the |
51 | 51 | * constructors of the type. Constructors with most parameters are examined first. A parameter type sequence |
52 | 52 | * matching the sequence of the dependencies' types match first. Otherwise all the types of the dependencies must |
53 | 53 | * match one of the the parameters although no dependency is used twice. Use a {@link TypedNull} instance to inject |
54 | 54 | * <code>null</code> as parameter. |
55 | * | |
55 | * | |
56 | 56 | * @param type the type to create an instance of |
57 | 57 | * @param dependencies the possible dependencies |
58 | 58 | * @param usedDependencies bit mask set by the method for all used dependencies (may be <code>null</code>) |
84 | 84 | } |
85 | 85 | |
86 | 86 | final TypedValue[] typedDependencies = new TypedValue[dependencies.length]; |
87 | for (int i = 0; i < dependencies.length; i++ ) { | |
87 | for (int i = 0; i < dependencies.length; i++) { | |
88 | 88 | Object dependency = dependencies[i]; |
89 | 89 | Class depType = dependency.getClass(); |
90 | 90 | if (depType.isPrimitive()) { |
99 | 99 | |
100 | 100 | Constructor possibleCtor = null; |
101 | 101 | int arity = Integer.MAX_VALUE; |
102 | for (int i = 0; bestMatchingCtor == null && i < ctors.length; i++ ) { | |
102 | for (int i = 0; bestMatchingCtor == null && i < ctors.length; i++) { | |
103 | 103 | final Constructor constructor = ctors[i]; |
104 | 104 | final Class[] parameterTypes = constructor.getParameterTypes(); |
105 | 105 | if (parameterTypes.length > dependencies.length) { |
117 | 117 | arity = parameterTypes.length; |
118 | 118 | } |
119 | 119 | |
120 | for (int j = 0; j < parameterTypes.length; j++ ) { | |
120 | for (int j = 0; j < parameterTypes.length; j++) { | |
121 | 121 | if (parameterTypes[j].isPrimitive()) { |
122 | 122 | parameterTypes[j] = Primitives.box(parameterTypes[j]); |
123 | 123 | } |
128 | 128 | matchingDependencies.clear(); |
129 | 129 | usedDeps = 0; |
130 | 130 | for (int j = 0, k = 0; j < parameterTypes.length |
131 | && parameterTypes.length + k - j <= typedDependencies.length; k++ ) { | |
131 | && parameterTypes.length + k - j <= typedDependencies.length; k++) { | |
132 | 132 | if (parameterTypes[j].isAssignableFrom(typedDependencies[k].type)) { |
133 | 133 | matchingDependencies.add(typedDependencies[k].value); |
134 | usedDeps |= 1L << k; | |
135 | if ( ++j == parameterTypes.length) { | |
134 | usedDeps |= 1L << k; | |
135 | if (++j == parameterTypes.length) { | |
136 | 136 | bestMatchingCtor = constructor; |
137 | 137 | break; |
138 | 138 | } |
150 | 150 | usedDeps = 0; |
151 | 151 | for (int j = 0; j < parameterTypes.length; j++ ) { |
152 | 152 | int assignable = -1; |
153 | for (int k = 0; k < deps.length; k++ ) { | |
153 | for (int k = 0; k < deps.length; k++) { | |
154 | 154 | if (deps[k] == null) { |
155 | 155 | continue; |
156 | 156 | } |
161 | 161 | } else if (parameterTypes[j].isAssignableFrom(deps[k].type)) { |
162 | 162 | // use most specific type |
163 | 163 | if (assignable < 0 |
164 | || (deps[assignable].type != deps[k].type && deps[assignable].type | |
165 | .isAssignableFrom(deps[k].type))) { | |
164 | || deps[assignable].type != deps[k].type | |
165 | && deps[assignable].type.isAssignableFrom(deps[k].type)) { | |
166 | 166 | assignable = k; |
167 | 167 | } |
168 | 168 | } |
177 | 177 | break; |
178 | 178 | } |
179 | 179 | } |
180 | ||
180 | ||
181 | 181 | if (possible) { |
182 | 182 | // the smaller the value, the smaller the indices in the deps array |
183 | 183 | if (possibleCtor != null && usedDeps >= possibleUsedDeps) { |
193 | 193 | if (bestMatchingCtor == null) { |
194 | 194 | if (possibleCtor == null) { |
195 | 195 | usedDeps = 0; |
196 | throw new ObjectAccessException("Cannot construct " | |
197 | + type.getName() | |
198 | + ", none of the dependencies match any constructor's parameters"); | |
196 | final ObjectAccessException ex = new ObjectAccessException( | |
197 | "Cannot construct type, none of the arguments match any constructor's parameters"); | |
198 | ex.add("construction-type", type.getName()); | |
199 | throw ex; | |
199 | 200 | } else { |
200 | 201 | bestMatchingCtor = possibleCtor; |
201 | 202 | matchingDependencies.clear(); |
205 | 206 | } |
206 | 207 | } |
207 | 208 | |
209 | Throwable th = null; | |
208 | 210 | try { |
209 | 211 | final Object instance; |
210 | 212 | if (bestMatchingCtor == null) { |
215 | 217 | if (usedDependencies != null) { |
216 | 218 | usedDependencies.clear(); |
217 | 219 | int i = 0; |
218 | for(long l = 1; l < usedDeps; l <<= 1, ++i) { | |
220 | for (long l = 1; l < usedDeps; l <<= 1, ++i) { | |
219 | 221 | if ((usedDeps & l) > 0) { |
220 | 222 | usedDependencies.set(i); |
221 | 223 | } |
223 | 225 | } |
224 | 226 | return instance; |
225 | 227 | } catch (final InstantiationException e) { |
226 | throw new ObjectAccessException("Cannot construct " + type.getName(), e); | |
228 | th = e; | |
227 | 229 | } catch (final IllegalAccessException e) { |
228 | throw new ObjectAccessException("Cannot construct " + type.getName(), e); | |
230 | th = e; | |
229 | 231 | } catch (final InvocationTargetException e) { |
230 | throw new ObjectAccessException("Cannot construct " + type.getName(), e); | |
232 | th = e.getCause(); | |
231 | 233 | } catch (final SecurityException e) { |
232 | throw new ObjectAccessException("Cannot construct " + type.getName(), e); | |
234 | th = e; | |
233 | 235 | } catch (final ExceptionInInitializerError e) { |
234 | throw new ObjectAccessException("Cannot construct " + type.getName(), e); | |
235 | } | |
236 | th = e; | |
237 | } | |
238 | final ObjectAccessException ex = new ObjectAccessException("Cannot construct type", th); | |
239 | ex.add("construction-type", type.getName()); | |
240 | throw ex; | |
236 | 241 | } |
237 | 242 | |
238 | 243 | private static class TypedValue { |
245 | 250 | this.value = value; |
246 | 251 | } |
247 | 252 | |
248 | public String toString() | |
249 | { | |
253 | public String toString() { | |
250 | 254 | return type.getName() + ":" + value; |
251 | 255 | } |
252 | 256 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 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 |
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. April 2004 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.core.util; |
15 | 15 | |
16 | 16 | import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; |
17 | 17 | |
18 | ||
18 | 19 | /** |
19 | * Slightly nicer way to find, get and set fields in classes. Wraps standard java.lang.reflect.Field calls but wraps | |
20 | * wraps exception in XStreamExceptions. | |
20 | * Slightly nicer way to find, get and set fields in classes. Wraps standard java.lang.reflect.Field calls and turns | |
21 | * exceptions into XStreamExceptions. | |
21 | 22 | * |
22 | 23 | * @author Joe Walnes |
23 | 24 | * @author Jörg Schaible |
24 | 25 | */ |
25 | 26 | public class Fields { |
26 | public static Field locate(Class definedIn, Class fieldType, boolean isStatic) { | |
27 | public static Field locate(final Class definedIn, final Class fieldType, final boolean isStatic) { | |
27 | 28 | Field field = null; |
28 | 29 | try { |
29 | Field[] fields = definedIn.getDeclaredFields(); | |
30 | final Field[] fields = definedIn.getDeclaredFields(); | |
30 | 31 | for(int i = 0; i < fields.length; ++i) { |
31 | 32 | if (Modifier.isStatic(fields[i].getModifiers()) == isStatic) { |
32 | 33 | if (fieldType.isAssignableFrom(fields[i].getType())) { |
37 | 38 | if (field != null && !field.isAccessible()) { |
38 | 39 | field.setAccessible(true); |
39 | 40 | } |
40 | } catch (SecurityException e) { | |
41 | } catch (final SecurityException e) { | |
41 | 42 | // active SecurityManager |
42 | } catch (NoClassDefFoundError e) { | |
43 | } catch (final NoClassDefFoundError e) { | |
43 | 44 | // restricted type in GAE |
44 | 45 | } |
45 | 46 | return field; |
46 | 47 | } |
47 | 48 | |
48 | public static Field find(Class type, String name) { | |
49 | public static Field find(final Class type, final String name) { | |
49 | 50 | try { |
50 | Field result = type.getDeclaredField(name); | |
51 | final Field result = type.getDeclaredField(name); | |
51 | 52 | if (!result.isAccessible()) { |
52 | 53 | result.setAccessible(true); |
53 | 54 | } |
54 | 55 | return result; |
55 | } catch (NoSuchFieldException e) { | |
56 | throw new IllegalArgumentException("Could not access " + type.getName() + "." + name + " field: " + e.getMessage()); | |
57 | } catch (NoClassDefFoundError e) { | |
58 | throw new ObjectAccessException("Could not access " + type.getName() + "." + name + " field: " + e.getMessage()); | |
56 | } catch (final SecurityException e) { | |
57 | throw wrap("Cannot access field", type, name, e); | |
58 | } catch (final NoSuchFieldException e) { | |
59 | throw wrap("Cannot access field", type, name, e); | |
60 | } catch (final NoClassDefFoundError e) { | |
61 | throw wrap("Cannot access field", type, name, e); | |
59 | 62 | } |
60 | 63 | } |
61 | 64 | |
62 | public static void write(Field field, Object instance, Object value) { | |
65 | public static void write(final Field field, final Object instance, final Object value) { | |
63 | 66 | try { |
64 | 67 | field.set(instance, value); |
65 | } catch (IllegalAccessException e) { | |
66 | throw new ObjectAccessException("Could not write " + field.getType().getName() + "." + field.getName() + " field", e); | |
67 | } catch (NoClassDefFoundError e) { | |
68 | throw new ObjectAccessException("Could not write " + field.getType().getName() + "." + field.getName() + " field", e); | |
68 | } catch (final SecurityException e) { | |
69 | throw wrap("Cannot write field", field.getType(), field.getName(), e); | |
70 | } catch (final IllegalArgumentException e) { | |
71 | throw wrap("Cannot write field", field.getType(), field.getName(), e); | |
72 | } catch (final IllegalAccessException e) { | |
73 | throw wrap("Cannot write field", field.getType(), field.getName(), e); | |
74 | } catch (final NoClassDefFoundError e) { | |
75 | throw wrap("Cannot write field", field.getType(), field.getName(), e); | |
69 | 76 | } |
70 | 77 | } |
71 | 78 | |
72 | public static Object read(Field field, Object instance) { | |
79 | public static Object read(final Field field, final Object instance) { | |
73 | 80 | try { |
74 | 81 | return field.get(instance); |
75 | } catch (IllegalAccessException e) { | |
76 | throw new ObjectAccessException("Could not read " + field.getType().getName() + "." + field.getName() + " field", e); | |
77 | } catch (NoClassDefFoundError e) { | |
78 | throw new ObjectAccessException("Could not read " + field.getType().getName() + "." + field.getName() + " field", e); | |
82 | } catch (final SecurityException e) { | |
83 | throw wrap("Cannot read field", field.getType(), field.getName(), e); | |
84 | } catch (final IllegalArgumentException e) { | |
85 | throw wrap("Cannot read field", field.getType(), field.getName(), e); | |
86 | } catch (final IllegalAccessException e) { | |
87 | throw wrap("Cannot read field", field.getType(), field.getName(), e); | |
88 | } catch (final NoClassDefFoundError e) { | |
89 | throw wrap("Cannot read field", field.getType(), field.getName(), e); | |
79 | 90 | } |
80 | 91 | } |
92 | ||
93 | private static ObjectAccessException wrap(final String message, final Class type, final String name, | |
94 | final Throwable ex) { | |
95 | final ObjectAccessException exception = new ObjectAccessException(message, ex); | |
96 | exception.add("field", type.getName() + "." + name); | |
97 | return exception; | |
98 | } | |
81 | 99 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2014, 2015 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2010, 2011, 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 |
23 | 23 | import java.util.Map; |
24 | 24 | |
25 | 25 | import com.thoughtworks.xstream.converters.ConversionException; |
26 | import com.thoughtworks.xstream.converters.ErrorWritingException; | |
26 | 27 | import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; |
27 | 28 | import com.thoughtworks.xstream.core.Caching; |
28 | 29 | |
71 | 72 | final Class resultType = result.getClass(); |
72 | 73 | final Method readResolveMethod = getRRMethod(resultType, "readResolve"); |
73 | 74 | if (readResolveMethod != null) { |
75 | ErrorWritingException ex = null; | |
74 | 76 | try { |
75 | 77 | return readResolveMethod.invoke(result, EMPTY_ARGS); |
76 | 78 | } catch (IllegalAccessException e) { |
77 | throw new ObjectAccessException("Could not call " | |
78 | + resultType.getName() | |
79 | + ".readResolve()", e); | |
79 | ex = new ObjectAccessException("Cannot access method", e); | |
80 | 80 | } catch (InvocationTargetException e) { |
81 | throw new ObjectAccessException("Could not call " | |
82 | + resultType.getName() | |
83 | + ".readResolve()", e.getTargetException()); | |
84 | } | |
81 | ex = new ConversionException("Failed calling method", e.getTargetException()); | |
82 | } | |
83 | ex.add("method", resultType.getName() + ".readResolve()"); | |
84 | throw ex; | |
85 | 85 | } else { |
86 | 86 | return result; |
87 | 87 | } |
95 | 95 | final Class objectType = object.getClass(); |
96 | 96 | final Method writeReplaceMethod = getRRMethod(objectType, "writeReplace"); |
97 | 97 | if (writeReplaceMethod != null) { |
98 | ErrorWritingException ex = null; | |
98 | 99 | try { |
99 | 100 | return writeReplaceMethod.invoke(object, EMPTY_ARGS); |
100 | 101 | } catch (IllegalAccessException e) { |
101 | throw new ObjectAccessException("Could not call " | |
102 | + objectType.getName() | |
103 | + ".writeReplace()", e); | |
102 | ex = new ObjectAccessException("Cannot access method", e); | |
104 | 103 | } catch (InvocationTargetException e) { |
105 | throw new ObjectAccessException("Could not call " | |
106 | + objectType.getName() | |
107 | + ".writeReplace()", e.getTargetException()); | |
108 | } | |
104 | ex = new ConversionException("Failed calling method", e.getTargetException()); | |
105 | } | |
106 | ex.add("method", objectType.getName() + ".writeReplace()"); | |
107 | throw ex; | |
109 | 108 | } else { |
110 | 109 | return object; |
111 | 110 | } |
118 | 117 | } |
119 | 118 | |
120 | 119 | public void callReadObject(final Class type, final Object object, final ObjectInputStream stream) { |
120 | ErrorWritingException ex = null; | |
121 | 121 | try { |
122 | 122 | Method readObjectMethod = getMethod( |
123 | 123 | type, "readObject", new Class[]{ObjectInputStream.class}, false); |
124 | 124 | readObjectMethod.invoke(object, new Object[]{stream}); |
125 | 125 | } catch (IllegalAccessException e) { |
126 | throw new ConversionException("Could not call " | |
127 | + object.getClass().getName() | |
128 | + ".readObject()", e); | |
126 | ex = new ObjectAccessException("Cannot access method", e); | |
129 | 127 | } catch (InvocationTargetException e) { |
130 | throw new ConversionException("Could not call " | |
131 | + object.getClass().getName() | |
132 | + ".readObject()", e.getTargetException()); | |
128 | ex = new ConversionException("Failed calling method", e.getTargetException()); | |
129 | } | |
130 | if (ex != null) { | |
131 | ex.add("method", object.getClass().getName() + ".readObject()"); | |
132 | throw ex; | |
133 | 133 | } |
134 | 134 | } |
135 | 135 | |
139 | 139 | } |
140 | 140 | |
141 | 141 | public void callWriteObject(final Class type, final Object instance, final ObjectOutputStream stream) { |
142 | ErrorWritingException ex = null; | |
142 | 143 | try { |
143 | 144 | Method readObjectMethod = getMethod( |
144 | 145 | type, "writeObject", new Class[]{ObjectOutputStream.class}, false); |
145 | 146 | readObjectMethod.invoke(instance, new Object[]{stream}); |
146 | 147 | } catch (IllegalAccessException e) { |
147 | throw new ConversionException("Could not call " | |
148 | + instance.getClass().getName() | |
149 | + ".writeObject()", e); | |
148 | ex = new ObjectAccessException("Cannot access method", e); | |
150 | 149 | } catch (InvocationTargetException e) { |
151 | throw new ConversionException("Could not call " | |
152 | + instance.getClass().getName() | |
153 | + ".writeObject()", e.getTargetException()); | |
150 | ex = new ConversionException("Failed calling method", e.getTargetException()); | |
151 | } | |
152 | if (ex != null) { | |
153 | ex.add("method", instance.getClass().getName() + ".writeObject()"); | |
154 | throw ex; | |
154 | 155 | } |
155 | 156 | } |
156 | 157 | |
209 | 210 | } |
210 | 211 | Map result = (Map)fieldCache.get(type.getName()); |
211 | 212 | if (result == null) { |
213 | ErrorWritingException ex = null; | |
212 | 214 | try { |
213 | 215 | final Field field = type.getDeclaredField("serialPersistentFields"); |
214 | 216 | if ((field.getModifiers() & PERSISTENT_FIELDS_MODIFIER) == PERSISTENT_FIELDS_MODIFIER) { |
223 | 225 | } |
224 | 226 | } catch (final NoSuchFieldException e) { |
225 | 227 | } catch (final IllegalAccessException e) { |
226 | throw new ObjectAccessException("Cannot get " + type.getName() + ".serialPersistentFields.", e); | |
228 | ex = new ObjectAccessException("Cannot get field", e); | |
227 | 229 | } catch (final ClassCastException e) { |
228 | throw new ObjectAccessException("Cannot get " + type.getName() + ".serialPersistentFields.", e); | |
230 | ex = new ConversionException("Incompatible field type", e); | |
231 | } | |
232 | if (ex != null) { | |
233 | ex.add("field", type.getName() + ".serialPersistentFields"); | |
234 | throw ex; | |
229 | 235 | } |
230 | 236 | if (result == null) { |
231 | 237 | result = NO_FIELDS; |
0 | 0 | /* |
1 | * Copyright (c) 2007, 2008 XStream Committers. | |
1 | * Copyright (c) 2007, 2008, 2016 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.core.util; |
11 | 11 | |
12 | import com.thoughtworks.xstream.converters.ConversionException; | |
13 | import com.thoughtworks.xstream.converters.ErrorWritingException; | |
12 | 14 | import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; |
13 | 15 | |
14 | 16 | import java.beans.PropertyEditor; |
43 | 45 | editorType = type; |
44 | 46 | pool = new Pool(initialPoolSize, maxPoolSize, new Pool.Factory() { |
45 | 47 | public Object newInstance() { |
48 | ErrorWritingException ex = null; | |
46 | 49 | try { |
47 | 50 | return editorType.newInstance(); |
48 | 51 | } catch (InstantiationException e) { |
49 | throw new ObjectAccessException("Could not call default constructor of " | |
50 | + editorType.getName(), e); | |
52 | ex = new ConversionException("Faild to call default constructor", e); | |
51 | 53 | } catch (IllegalAccessException e) { |
52 | throw new ObjectAccessException("Could not call default constructor of " | |
53 | + editorType.getName(), e); | |
54 | ex = new ObjectAccessException("Cannot call default constructor", e); | |
54 | 55 | } |
56 | ex.add("construction-type", editorType.getName()); | |
57 | throw ex; | |
55 | 58 | } |
56 | 59 | |
57 | 60 | }); |
0 | 0 | /* |
1 | * Copyright (C) 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2009, 2011, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
51 | 51 | public HierarchicalStreamReader createReader(Reader in) { |
52 | 52 | try { |
53 | 53 | return new XppReader(in, createParser(), getNameCoder()); |
54 | } catch (XmlPullParserException e) { | |
55 | throw new StreamException("Cannot create XmlPullParser"); | |
54 | } catch (final XmlPullParserException e) { | |
55 | throw new StreamException("Cannot create XmlPullParser", e); | |
56 | 56 | } |
57 | 57 | } |
58 | 58 |
0 | 0 | /* |
1 | * Copyright (C) 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2009, 2011, 2014, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
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 |
6 | 6 | * the LICENSE.txt file. |
7 | * | |
7 | * | |
8 | 8 | * Created on 29. April 2009 by Joerg Schaible |
9 | 9 | */ |
10 | 10 | package com.thoughtworks.xstream.io.xml; |
18 | 18 | |
19 | 19 | /** |
20 | 20 | * A driver using the BEA StAX implementation. |
21 | * | |
21 | * | |
22 | 22 | * @author Jörg Schaible |
23 | 23 | * @since 1.4 |
24 | 24 | */ |
61 | 61 | } |
62 | 62 | |
63 | 63 | protected XMLInputFactory createInputFactory() { |
64 | return new MXParserFactory(); | |
64 | final XMLInputFactory instance = new MXParserFactory(); | |
65 | instance.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); | |
66 | // if (instance.isPropertySupported(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES)) | |
67 | // throw new IllegalStateException("Should not support external entities now!"); | |
68 | return instance; | |
65 | 69 | } |
66 | 70 | |
67 | 71 | protected XMLOutputFactory createOutputFactory() { |
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, 2014, 2015 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 org.dom4j.io.OutputFormat; |
26 | 26 | import org.dom4j.io.SAXReader; |
27 | 27 | import org.dom4j.io.XMLWriter; |
28 | import org.xml.sax.SAXException; | |
28 | 29 | |
29 | 30 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
30 | 31 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; |
88 | 89 | |
89 | 90 | public HierarchicalStreamReader createReader(Reader text) { |
90 | 91 | try { |
91 | SAXReader reader = new SAXReader(); | |
92 | Document document = reader.read(text); | |
92 | final Document document = createReader().read(text); | |
93 | 93 | return new Dom4JReader(document, getNameCoder()); |
94 | 94 | } catch (DocumentException e) { |
95 | 95 | throw new StreamException(e); |
98 | 98 | |
99 | 99 | public HierarchicalStreamReader createReader(InputStream in) { |
100 | 100 | try { |
101 | SAXReader reader = new SAXReader(); | |
102 | Document document = reader.read(in); | |
101 | final Document document = createReader().read(in); | |
103 | 102 | return new Dom4JReader(document, getNameCoder()); |
104 | 103 | } catch (DocumentException e) { |
105 | 104 | throw new StreamException(e); |
111 | 110 | */ |
112 | 111 | public HierarchicalStreamReader createReader(URL in) { |
113 | 112 | try { |
114 | SAXReader reader = new SAXReader(); | |
115 | Document document = reader.read(in); | |
113 | final Document document = createReader().read(in); | |
116 | 114 | return new Dom4JReader(document, getNameCoder()); |
117 | 115 | } catch (DocumentException e) { |
118 | 116 | throw new StreamException(e); |
124 | 122 | */ |
125 | 123 | public HierarchicalStreamReader createReader(File in) { |
126 | 124 | try { |
127 | SAXReader reader = new SAXReader(); | |
128 | Document document = reader.read(in); | |
125 | final Document document = createReader().read(in); | |
129 | 126 | return new Dom4JReader(document, getNameCoder()); |
130 | 127 | } catch (DocumentException e) { |
131 | 128 | throw new StreamException(e); |
147 | 144 | final Writer writer = new OutputStreamWriter(out); |
148 | 145 | return createWriter(writer); |
149 | 146 | } |
147 | ||
148 | /** | |
149 | * Create and initialize the SAX reader. | |
150 | * | |
151 | * @return the SAX reader instance. | |
152 | * @throws DocumentException if DOCTYPE processing cannot be disabled | |
153 | * @since 1.4.9 | |
154 | */ | |
155 | protected SAXReader createReader() throws DocumentException { | |
156 | final SAXReader reader = new SAXReader(); | |
157 | try { | |
158 | reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); | |
159 | } catch (SAXException e) { | |
160 | throw new DocumentException("Cannot disable DOCTYPE processing", e); | |
161 | } | |
162 | return reader; | |
163 | } | |
150 | 164 | } |
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, 2014, 2015 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; |
18 | 18 | import java.io.Reader; |
19 | 19 | import java.io.UnsupportedEncodingException; |
20 | 20 | import java.io.Writer; |
21 | import java.lang.reflect.InvocationTargetException; | |
22 | import java.lang.reflect.Method; | |
21 | 23 | import java.net.URL; |
22 | 24 | |
23 | 25 | import javax.xml.parsers.DocumentBuilder; |
29 | 31 | import org.xml.sax.InputSource; |
30 | 32 | import org.xml.sax.SAXException; |
31 | 33 | |
34 | import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; | |
35 | import com.thoughtworks.xstream.core.JVM; | |
32 | 36 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
33 | 37 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; |
34 | 38 | import com.thoughtworks.xstream.io.StreamException; |
38 | 42 | public class DomDriver extends AbstractXmlDriver { |
39 | 43 | |
40 | 44 | private final String encoding; |
41 | private final DocumentBuilderFactory documentBuilderFactory; | |
45 | private DocumentBuilderFactory documentBuilderFactory; | |
42 | 46 | |
43 | 47 | /** |
44 | 48 | * Construct a DomDriver. |
60 | 64 | */ |
61 | 65 | public DomDriver(String encoding, NameCoder nameCoder) { |
62 | 66 | super(nameCoder); |
63 | documentBuilderFactory = DocumentBuilderFactory.newInstance(); | |
64 | 67 | this.encoding = encoding; |
65 | 68 | } |
66 | 69 | |
90 | 93 | |
91 | 94 | private HierarchicalStreamReader createReader(InputSource source) { |
92 | 95 | try { |
93 | DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); | |
96 | if (documentBuilderFactory == null) { | |
97 | synchronized (this) { | |
98 | if (documentBuilderFactory == null) { | |
99 | documentBuilderFactory = createDocumentBuilderFactory(); | |
100 | } | |
101 | } | |
102 | } | |
103 | final DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); | |
94 | 104 | if (encoding != null) { |
95 | 105 | source.setEncoding(encoding); |
96 | 106 | } |
120 | 130 | throw new StreamException(e); |
121 | 131 | } |
122 | 132 | } |
133 | ||
134 | /** | |
135 | * Create the DocumentBuilderFactory instance. | |
136 | * | |
137 | * @return the new instance | |
138 | * @since 1.4.9 | |
139 | */ | |
140 | protected DocumentBuilderFactory createDocumentBuilderFactory() { | |
141 | final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | |
142 | if (JVM.is15()) { | |
143 | try { | |
144 | Method method = DocumentBuilderFactory.class.getMethod("setFeature", | |
145 | new Class[]{ String.class, boolean.class }); | |
146 | method.invoke(factory, new Object[]{ "http://apache.org/xml/features/disallow-doctype-decl", Boolean.TRUE }); | |
147 | } catch (NoSuchMethodException e) { | |
148 | // Ignore | |
149 | } catch (IllegalAccessException e) { | |
150 | throw new ObjectAccessException("Cannot set feature of DocumentBuilderFactory.", e); | |
151 | } catch (InvocationTargetException e) { | |
152 | Throwable cause = e.getCause(); | |
153 | if (JVM.is16() | |
154 | || (cause instanceof ParserConfigurationException | |
155 | && cause.getMessage().indexOf("disallow-doctype-decl") < 0)) { | |
156 | throw new StreamException(cause); | |
157 | } | |
158 | } | |
159 | } | |
160 | factory.setExpandEntityReferences(false); | |
161 | return factory; | |
162 | } | |
123 | 163 | } |
0 | 0 | /* |
1 | * Copyright (C) 2013 XStream Committers. | |
1 | * Copyright (C) 2013, 2015 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 | public HierarchicalStreamReader createReader(Reader reader) { |
48 | 48 | try { |
49 | SAXBuilder builder = new SAXBuilder(); | |
50 | Document document = builder.build(reader); | |
49 | final SAXBuilder builder = createBuilder(); | |
50 | final Document document = builder.build(reader); | |
51 | 51 | return new JDom2Reader(document, getNameCoder()); |
52 | 52 | } catch (IOException e) { |
53 | 53 | throw new StreamException(e); |
58 | 58 | |
59 | 59 | public HierarchicalStreamReader createReader(InputStream in) { |
60 | 60 | try { |
61 | SAXBuilder builder = new SAXBuilder(); | |
62 | Document document = builder.build(in); | |
61 | final SAXBuilder builder = createBuilder(); | |
62 | final Document document = builder.build(in); | |
63 | 63 | return new JDom2Reader(document, getNameCoder()); |
64 | 64 | } catch (IOException e) { |
65 | 65 | throw new StreamException(e); |
70 | 70 | |
71 | 71 | public HierarchicalStreamReader createReader(URL in) { |
72 | 72 | try { |
73 | SAXBuilder builder = new SAXBuilder(); | |
74 | Document document = builder.build(in); | |
73 | final SAXBuilder builder = createBuilder(); | |
74 | final Document document = builder.build(in); | |
75 | 75 | return new JDom2Reader(document, getNameCoder()); |
76 | 76 | } catch (IOException e) { |
77 | 77 | throw new StreamException(e); |
82 | 82 | |
83 | 83 | public HierarchicalStreamReader createReader(File in) { |
84 | 84 | try { |
85 | SAXBuilder builder = new SAXBuilder(); | |
86 | Document document = builder.build(in); | |
85 | final SAXBuilder builder = createBuilder(); | |
86 | final Document document = builder.build(in); | |
87 | 87 | return new JDom2Reader(document, getNameCoder()); |
88 | 88 | } catch (IOException e) { |
89 | 89 | throw new StreamException(e); |
99 | 99 | public HierarchicalStreamWriter createWriter(OutputStream out) { |
100 | 100 | return new PrettyPrintWriter(new OutputStreamWriter(out)); |
101 | 101 | } |
102 | ||
103 | /** | |
104 | * Create and initialize the SAX builder. | |
105 | * | |
106 | * @return the SAX builder instance. | |
107 | * @since 1.4.9 | |
108 | */ | |
109 | protected SAXBuilder createBuilder() { | |
110 | final SAXBuilder builder = new SAXBuilder(); | |
111 | builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); | |
112 | return builder; | |
113 | } | |
102 | 114 | } |
103 | 115 |
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, 2015 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
54 | 54 | |
55 | 55 | public HierarchicalStreamReader createReader(Reader reader) { |
56 | 56 | try { |
57 | SAXBuilder builder = new SAXBuilder(); | |
58 | Document document = builder.build(reader); | |
57 | final SAXBuilder builder = createBuilder(); | |
58 | final Document document = builder.build(reader); | |
59 | 59 | return new JDomReader(document, getNameCoder()); |
60 | 60 | } catch (IOException e) { |
61 | 61 | throw new StreamException(e); |
66 | 66 | |
67 | 67 | public HierarchicalStreamReader createReader(InputStream in) { |
68 | 68 | try { |
69 | SAXBuilder builder = new SAXBuilder(); | |
70 | Document document = builder.build(in); | |
69 | final SAXBuilder builder = createBuilder(); | |
70 | final Document document = builder.build(in); | |
71 | 71 | return new JDomReader(document, getNameCoder()); |
72 | 72 | } catch (IOException e) { |
73 | 73 | throw new StreamException(e); |
78 | 78 | |
79 | 79 | public HierarchicalStreamReader createReader(URL in) { |
80 | 80 | try { |
81 | SAXBuilder builder = new SAXBuilder(); | |
82 | Document document = builder.build(in); | |
81 | final SAXBuilder builder = createBuilder(); | |
82 | final Document document = builder.build(in); | |
83 | 83 | return new JDomReader(document, getNameCoder()); |
84 | 84 | } catch (IOException e) { |
85 | 85 | throw new StreamException(e); |
90 | 90 | |
91 | 91 | public HierarchicalStreamReader createReader(File in) { |
92 | 92 | try { |
93 | SAXBuilder builder = new SAXBuilder(); | |
94 | Document document = builder.build(in); | |
93 | final SAXBuilder builder = createBuilder(); | |
94 | final Document document = builder.build(in); | |
95 | 95 | return new JDomReader(document, getNameCoder()); |
96 | 96 | } catch (IOException e) { |
97 | 97 | throw new StreamException(e); |
108 | 108 | return new PrettyPrintWriter(new OutputStreamWriter(out)); |
109 | 109 | } |
110 | 110 | |
111 | /** | |
112 | * Create and initialize the SAX builder. | |
113 | * | |
114 | * @return the SAX builder instance. | |
115 | * @since 1.4.9 | |
116 | */ | |
117 | protected SAXBuilder createBuilder() { | |
118 | final SAXBuilder builder = new SAXBuilder(); | |
119 | builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); | |
120 | return builder; | |
121 | } | |
122 | ||
111 | 123 | } |
112 | 124 |
21 | 21 | * allowing class aliases and namespace aware mappings of QNames to class names. |
22 | 22 | * |
23 | 23 | * @author James Strachan |
24 | * @version $Revision: 1345 $ | |
24 | * @version $Revision$ | |
25 | 25 | */ |
26 | 26 | public class QNameMap { |
27 | 27 |
0 | 0 | /* |
1 | * Copyright (C) 2009, 2011, 2013 XStream Committers. | |
1 | * Copyright (C) 2009, 2011, 2013, 2014, 2015 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 | protected XMLInputFactory createInputFactory() { |
58 | 58 | Exception exception = null; |
59 | 59 | try { |
60 | return (XMLInputFactory)Class.forName("com.sun.xml.internal.stream.XMLInputFactoryImpl").newInstance(); | |
61 | } catch (InstantiationException e) { | |
60 | final XMLInputFactory instance = (XMLInputFactory)Class.forName("com.sun.xml.internal.stream.XMLInputFactoryImpl").newInstance(); | |
61 | instance.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); | |
62 | return instance; | |
63 | } catch (final InstantiationException e) { | |
62 | 64 | exception = e; |
63 | 65 | } catch (IllegalAccessException e) { |
64 | 66 | exception = e; |
0 | 0 | /* |
1 | * Copyright (C) 2013 XStream Committers. | |
1 | * Copyright (C) 2013, 2014, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
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 |
6 | 6 | * the LICENSE.txt file. |
7 | * | |
7 | * | |
8 | 8 | * Created on 27. July 2013 by Joerg Schaible |
9 | 9 | */ |
10 | 10 | package com.thoughtworks.xstream.io.xml; |
27 | 27 | * implementations configured in <em>lib/stax.properties</em> or registered with the Service |
28 | 28 | * API. |
29 | 29 | * </p> |
30 | * | |
30 | * | |
31 | 31 | * @author Jörg Schaible |
32 | 32 | * @since 1.4.5 |
33 | 33 | */ |
74 | 74 | try { |
75 | 75 | Class staxInputFactory = JVM.getStaxInputFactory(); |
76 | 76 | if (staxInputFactory != null) { |
77 | return (XMLInputFactory)staxInputFactory.newInstance(); | |
77 | final XMLInputFactory instance = (XMLInputFactory)staxInputFactory.newInstance(); | |
78 | instance.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); | |
79 | return instance; | |
78 | 80 | } else { |
79 | 81 | throw new StreamException("Java runtime has no standard XMLInputFactory implementation.", exception); |
80 | 82 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2009, 2011, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2009, 2011, 2013, 2014, 2015 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 | * @author James Strachan |
41 | 41 | * @author Jörg Schaible |
42 | * @version $Revision: 2116 $ | |
42 | * @version $Revision$ | |
43 | 43 | */ |
44 | 44 | public class StaxDriver extends AbstractXmlDriver { |
45 | 45 | |
237 | 237 | * @since 1.4 |
238 | 238 | */ |
239 | 239 | protected XMLInputFactory createInputFactory() { |
240 | return XMLInputFactory.newInstance(); | |
240 | final XMLInputFactory instance = XMLInputFactory.newInstance(); | |
241 | instance.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); | |
242 | return instance; | |
241 | 243 | } |
242 | 244 | |
243 | 245 | /** |
23 | 23 | * A reader using the StAX API. |
24 | 24 | * |
25 | 25 | * @author James Strachan |
26 | * @version $Revision: 1861 $ | |
26 | * @version $Revision$ | |
27 | 27 | */ |
28 | 28 | public class StaxReader extends AbstractPullReader { |
29 | 29 |
22 | 22 | * A stream writing that outputs to a StAX stream writer |
23 | 23 | * |
24 | 24 | * @author James Strachan |
25 | * @version $Revision: 1906 $ | |
25 | * @version $Revision$ | |
26 | 26 | */ |
27 | 27 | public class StaxWriter extends AbstractXmlWriter { |
28 | 28 |
0 | 0 | /* |
1 | * Copyright (C) 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2009, 2011, 2014, 2015 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 | } |
62 | 62 | |
63 | 63 | protected XMLInputFactory createInputFactory() { |
64 | return new WstxInputFactory(); | |
64 | final XMLInputFactory instance = new WstxInputFactory(); | |
65 | instance.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); | |
66 | return instance; | |
65 | 67 | } |
66 | 68 | |
67 | 69 | protected XMLOutputFactory createOutputFactory() { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 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 |
34 | 34 | private final Builder builder; |
35 | 35 | |
36 | 36 | public XomDriver() { |
37 | this(new Builder()); | |
37 | this(new XmlFriendlyNameCoder()); | |
38 | 38 | } |
39 | 39 | |
40 | /** | |
41 | * @deprecated As of 1.4.9, use {@link #XomDriver()} and overload {@link #createBuilder()} instead | |
42 | */ | |
40 | 43 | public XomDriver(Builder builder) { |
41 | 44 | this(builder, new XmlFriendlyNameCoder()); |
42 | 45 | } |
45 | 48 | * @since 1.4 |
46 | 49 | */ |
47 | 50 | public XomDriver(NameCoder nameCoder) { |
48 | this(new Builder(), nameCoder); | |
51 | super(nameCoder); | |
52 | this.builder = null; | |
49 | 53 | } |
50 | 54 | |
51 | 55 | /** |
52 | 56 | * @since 1.4 |
57 | * @deprecated As of 1.4.9, use {@link #XomDriver(NameCoder)} and overload {@link #createBuilder()} instead | |
53 | 58 | */ |
54 | 59 | public XomDriver(Builder builder, NameCoder nameCoder) { |
55 | super(nameCoder); | |
60 | super(nameCoder); | |
56 | 61 | this.builder = builder; |
57 | 62 | } |
58 | 63 | |
59 | 64 | /** |
60 | 65 | * @since 1.2 |
61 | * @deprecated As of 1.4, use {@link #XomDriver(Builder, NameCoder)} instead | |
66 | * @deprecated As of 1.4, use {@link #XomDriver(NameCoder)} instead | |
62 | 67 | */ |
63 | 68 | public XomDriver(XmlFriendlyReplacer replacer) { |
64 | this(new Builder(), replacer); | |
69 | this((NameCoder)replacer); | |
65 | 70 | } |
66 | 71 | |
67 | 72 | /** |
68 | 73 | * @since 1.2 |
69 | * @deprecated As of 1.4, use {@link #XomDriver(Builder, NameCoder)} instead | |
74 | * @deprecated As of 1.4, use {@link #XomDriver(NameCoder)} and overload {@link #createBuilder()} instead | |
70 | 75 | */ |
71 | 76 | public XomDriver(Builder builder, XmlFriendlyReplacer replacer) { |
72 | this((NameCoder)replacer); | |
77 | this(builder, (NameCoder)replacer); | |
73 | 78 | } |
74 | 79 | |
80 | /** | |
81 | * @deprecated As of 1.4.9, overload {@link #createBuilder()} instead | |
82 | */ | |
75 | 83 | protected Builder getBuilder() { |
76 | 84 | return this.builder; |
77 | 85 | } |
78 | 86 | |
87 | /** | |
88 | * Create the Builder instance. | |
89 | * | |
90 | * A XOM builder is a wrapper around a {@link org.xml.sax.XMLReader} | |
91 | * instance which is not thread-safe by definition. Therefore each reader | |
92 | * should use its own builder instance to avoid concurrency problems. | |
93 | * | |
94 | * Overload this method to configure the generated builder instances e.g. | |
95 | * to activate validation. | |
96 | * | |
97 | * @return the new builder | |
98 | * @since 1.4.9 | |
99 | */ | |
100 | protected Builder createBuilder() { | |
101 | final Builder builder = getBuilder(); | |
102 | return builder != null ? builder : new Builder(); | |
103 | } | |
104 | ||
79 | 105 | public HierarchicalStreamReader createReader(Reader text) { |
80 | 106 | try { |
81 | Document document = builder.build(text); | |
107 | final Document document = createBuilder().build(text); | |
82 | 108 | return new XomReader(document, getNameCoder()); |
83 | 109 | } catch (ValidityException e) { |
84 | 110 | throw new StreamException(e); |
91 | 117 | |
92 | 118 | public HierarchicalStreamReader createReader(InputStream in) { |
93 | 119 | try { |
94 | Document document = builder.build(in); | |
120 | final Document document = createBuilder().build(in); | |
95 | 121 | return new XomReader(document, getNameCoder()); |
96 | 122 | } catch (ValidityException e) { |
97 | 123 | throw new StreamException(e); |
104 | 130 | |
105 | 131 | public HierarchicalStreamReader createReader(URL in) { |
106 | 132 | try { |
107 | Document document = builder.build(in.toExternalForm()); | |
133 | final Document document = createBuilder().build(in.toExternalForm()); | |
108 | 134 | return new XomReader(document, getNameCoder()); |
109 | 135 | } catch (ValidityException e) { |
110 | 136 | throw new StreamException(e); |
117 | 143 | |
118 | 144 | public HierarchicalStreamReader createReader(File in) { |
119 | 145 | try { |
120 | Document document = builder.build(in); | |
146 | final Document document = createBuilder().build(in); | |
121 | 147 | return new XomReader(document, getNameCoder()); |
122 | 148 | } catch (ValidityException e) { |
123 | 149 | throw new StreamException(e); |
0 | 0 | /* |
1 | * Copyright (C) 2007, 2008, 2009, 2011, 2012, 2013 XStream Committers. | |
1 | * Copyright (C) 2007, 2008, 2009, 2011, 2012, 2013, 2016 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
504 | 504 | if (array != null) { |
505 | 505 | int length = Array.getLength(array); |
506 | 506 | for (int i = 0; i < length; i++ ) { |
507 | Object object = Array.get(array, i); | |
508 | if (!parameter.contains(object)) { | |
509 | parameter.add(object); | |
510 | } | |
511 | } | |
512 | } | |
507 | parameter.add(Array.get(array, i)); | |
508 | } | |
509 | } | |
510 | } | |
511 | for (final Class<?> type : annotation.nulls()) { | |
512 | final TypedNull nullType = new TypedNull(type); | |
513 | parameter.add(nullType); | |
513 | 514 | } |
514 | 515 | final Class<? extends ConverterMatcher> converterType = annotation.value(); |
515 | 516 | Map<List<Object>, Converter> converterMapping = converterCache.get(converterType); |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2015 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
78 | 78 | return super.realClass(elementName); |
79 | 79 | } |
80 | 80 | |
81 | /** | |
82 | * @deprecated As of 1.4.9 | |
83 | */ | |
81 | 84 | public boolean itemTypeAsAttribute(Class clazz) { |
82 | return classToName.containsKey(clazz); | |
85 | return classToName.containsKey(clazz.getName()); | |
83 | 86 | } |
84 | 87 | |
88 | /** | |
89 | * @deprecated As of 1.4.9 | |
90 | */ | |
85 | 91 | public boolean aliasIsAttribute(String name) { |
86 | 92 | return nameToType.containsKey(name); |
87 | 93 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013, 2015 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 22. January 2005 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.mapper; |
17 | 17 | |
18 | 18 | |
19 | 19 | /** |
20 | * Default mapper implementation with 'vanilla' functionality. To build up the functionality required, wrap this mapper | |
21 | * with other mapper implementations. | |
20 | * Default mapper implementation with 'vanilla' functionality. | |
21 | * <p> | |
22 | * To build up the functionality required, wrap this mapper with other mapper implementations. | |
23 | * </p> | |
22 | 24 | * |
23 | 25 | * @author Joe Walnes |
24 | 26 | * @author Jörg Schaible |
37 | 39 | |
38 | 40 | /** |
39 | 41 | * Construct a DefaultMapper. |
40 | * | |
42 | * | |
41 | 43 | * @param classLoaderReference the reference to the classloader used by the XStream instance. |
42 | 44 | * @since 1.4.5 |
43 | 45 | */ |
47 | 49 | |
48 | 50 | /** |
49 | 51 | * Construct a DefaultMapper. |
50 | * | |
52 | * | |
51 | 53 | * @param classLoader the ClassLoader used by the XStream instance. |
52 | 54 | * @deprecated As of 1.4.5 use {@link #DefaultMapper(ClassLoaderReference)} |
53 | 55 | */ |
97 | 99 | |
98 | 100 | public boolean isImmutableValueType(Class type) { |
99 | 101 | return false; |
102 | } | |
103 | ||
104 | public boolean isReferenceable(final Class type) { | |
105 | return true; | |
100 | 106 | } |
101 | 107 | |
102 | 108 | public String getFieldNameForItemTypeAndName(Class definedIn, Class itemType, String itemFieldName) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2015 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 20. March 2005 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.mapper; |
21 | 21 | |
22 | 22 | |
23 | 23 | /** |
24 | * Mapper that handles the special case of polymorphic enums in Java 1.5. This renames MyEnum$1 | |
25 | * to MyEnum making it less bloaty in the XML and avoiding the need for an alias per enum value | |
26 | * to be specified. Additionally every enum is treated automatically as immutable type and can | |
27 | * be written as attribute. | |
28 | * | |
24 | * Mapper that handles the special case of polymorphic enums in Java 1.5. This renames MyEnum$1 to MyEnum making it less | |
25 | * bloaty in the XML and avoiding the need for an alias per enum value to be specified. Additionally every enum is | |
26 | * treated automatically as immutable and non-refrenceable type that can be written as attribute. | |
27 | * | |
29 | 28 | * @author Joe Walnes |
30 | 29 | * @author Jörg Schaible |
31 | 30 | */ |
68 | 67 | } |
69 | 68 | |
70 | 69 | @Override |
70 | public boolean isReferenceable(final Class type) { | |
71 | if (type != null && Enum.class.isAssignableFrom(type)) { | |
72 | return false; | |
73 | } else { | |
74 | return super.isReferenceable(type); | |
75 | } | |
76 | } | |
77 | ||
78 | @Override | |
71 | 79 | public SingleValueConverter getConverterFromItemType(String fieldName, Class type, |
72 | Class definedIn) { | |
73 | SingleValueConverter converter = getLocalConverter(fieldName, type, definedIn); | |
74 | return converter == null | |
75 | ? super.getConverterFromItemType(fieldName, type, definedIn) | |
76 | : converter; | |
80 | Class definedIn) { | |
81 | SingleValueConverter converter = getLocalConverter(fieldName, type, definedIn); | |
82 | return converter == null | |
83 | ? super.getConverterFromItemType(fieldName, type, definedIn) | |
84 | : converter; | |
77 | 85 | } |
78 | 86 | |
79 | 87 | @Override |
87 | 95 | |
88 | 96 | private SingleValueConverter getLocalConverter(String fieldName, Class type, Class definedIn) { |
89 | 97 | if (attributeMapper != null |
90 | && Enum.class.isAssignableFrom(type) | |
91 | && attributeMapper.shouldLookForSingleValueConverter(fieldName, type, definedIn)) { | |
98 | && Enum.class.isAssignableFrom(type) | |
99 | && attributeMapper.shouldLookForSingleValueConverter(fieldName, type, definedIn)) { | |
92 | 100 | synchronized (enumConverterMap) { |
93 | 101 | SingleValueConverter singleValueConverter = enumConverterMap.get(type); |
94 | 102 | if (singleValueConverter == null) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2009 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2009, 2015 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 22. January 2005 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.mapper; |
16 | 16 | /** |
17 | 17 | * Mapper that specifies which types are basic immutable types. Types that are marked as immutable will be written |
18 | 18 | * multiple times in the serialization stream without using references. |
19 | * <p> | |
20 | * Note, that an already persisted stream might still contain references for immutable types. They can be dereferenced | |
21 | * at deserialization time, unless the type is explicitly declared as unreferenceable. However, this is only possible at | |
22 | * the expense of memory book-keeping all instances. | |
23 | * </p> | |
19 | 24 | * |
20 | 25 | * @author Joe Walnes |
21 | 26 | */ |
22 | 27 | public class ImmutableTypesMapper extends MapperWrapper { |
23 | 28 | |
29 | private final Set unreferenceableTypes = new HashSet(); | |
24 | 30 | private final Set immutableTypes = new HashSet(); |
25 | 31 | |
26 | 32 | public ImmutableTypesMapper(Mapper wrapped) { |
27 | 33 | super(wrapped); |
28 | 34 | } |
29 | 35 | |
36 | /** | |
37 | * @deprecated As of 1.4.9 use {@link #addImmutableType(Class, boolean)} | |
38 | */ | |
30 | 39 | public void addImmutableType(Class type) { |
40 | addImmutableType(type, true); | |
41 | } | |
42 | ||
43 | /** | |
44 | * Declare a type as immutable. | |
45 | * | |
46 | * @param type the immutable type | |
47 | * @param isReferenceable flag for possible references | |
48 | * @since 1.4.9 | |
49 | */ | |
50 | public void addImmutableType(final Class type, final boolean isReferenceable) { | |
31 | 51 | immutableTypes.add(type); |
52 | if (!isReferenceable) { | |
53 | unreferenceableTypes.add(type); | |
54 | } else { | |
55 | unreferenceableTypes.remove(type); | |
56 | } | |
32 | 57 | } |
33 | 58 | |
34 | 59 | public boolean isImmutableValueType(Class type) { |
39 | 64 | } |
40 | 65 | } |
41 | 66 | |
67 | public boolean isReferenceable(final Class type) { | |
68 | if (unreferenceableTypes.contains(type)) { | |
69 | return false; | |
70 | } else { | |
71 | return super.isReferenceable(type); | |
72 | } | |
73 | } | |
42 | 74 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2009, 2011, 2012, 2013, 2014 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2009, 2011, 2012, 2013, 2014, 2015 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 16. February 2005 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.mapper; |
14 | 14 | import com.thoughtworks.xstream.core.util.Primitives; |
15 | 15 | |
16 | 16 | import java.lang.reflect.Field; |
17 | import java.lang.reflect.Modifier; | |
17 | 18 | import java.util.Collection; |
18 | 19 | import java.util.HashMap; |
19 | 20 | import java.util.Iterator; |
29 | 30 | // { definedIn (Class) -> (ImplicitCollectionMapperForClass) } |
30 | 31 | private final Map classNameToMapper = new HashMap(); |
31 | 32 | |
32 | private ImplicitCollectionMapperForClass getMapper(Class definedIn) { | |
33 | private ImplicitCollectionMapperForClass getMapper(final Class declaredFor, final String fieldName) { | |
34 | Class definedIn = declaredFor; | |
33 | 35 | while (definedIn != null) { |
34 | 36 | ImplicitCollectionMapperForClass mapper = (ImplicitCollectionMapperForClass)classNameToMapper |
35 | 37 | .get(definedIn); |
36 | 38 | if (mapper != null) { |
37 | 39 | 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 | } | |
38 | 54 | } |
39 | 55 | definedIn = definedIn.getSuperclass(); |
40 | 56 | } |
53 | 69 | |
54 | 70 | public String getFieldNameForItemTypeAndName(Class definedIn, Class itemType, |
55 | 71 | String itemFieldName) { |
56 | ImplicitCollectionMapperForClass mapper = getMapper(definedIn); | |
72 | ImplicitCollectionMapperForClass mapper = getMapper(definedIn, null); | |
57 | 73 | if (mapper != null) { |
58 | 74 | return mapper.getFieldNameForItemTypeAndName(itemType, itemFieldName); |
59 | 75 | } else { |
62 | 78 | } |
63 | 79 | |
64 | 80 | public Class getItemTypeForItemFieldName(Class definedIn, String itemFieldName) { |
65 | ImplicitCollectionMapperForClass mapper = getMapper(definedIn); | |
81 | ImplicitCollectionMapperForClass mapper = getMapper(definedIn, null); | |
66 | 82 | if (mapper != null) { |
67 | 83 | return mapper.getItemTypeForItemFieldName(itemFieldName); |
68 | 84 | } else { |
72 | 88 | |
73 | 89 | public ImplicitCollectionMapping getImplicitCollectionDefForFieldName(Class itemType, |
74 | 90 | String fieldName) { |
75 | ImplicitCollectionMapperForClass mapper = getMapper(itemType); | |
91 | ImplicitCollectionMapperForClass mapper = getMapper(itemType, fieldName); | |
76 | 92 | if (mapper != null) { |
77 | 93 | return mapper.getImplicitCollectionDefForFieldName(fieldName); |
78 | 94 | } else { |
90 | 106 | |
91 | 107 | public void add(Class definedIn, String fieldName, String itemFieldName, Class itemType, String keyFieldName) { |
92 | 108 | Field field = null; |
93 | Class declaredIn = definedIn; | |
94 | while (declaredIn != Object.class && definedIn != null) { | |
95 | try { | |
96 | field = declaredIn.getDeclaredField(fieldName); | |
97 | break; | |
98 | } catch (SecurityException e) { | |
99 | throw new InitializationException( | |
100 | "Access denied for field with implicit collection", e); | |
101 | } catch (NoSuchFieldException e) { | |
102 | declaredIn = declaredIn.getSuperclass(); | |
109 | if (definedIn != null) { | |
110 | Class declaredIn = definedIn; | |
111 | while (declaredIn != Object.class) { | |
112 | try { | |
113 | field = declaredIn.getDeclaredField(fieldName); | |
114 | if (!Modifier.isStatic(field.getModifiers())) { | |
115 | break; | |
116 | } | |
117 | field = null; | |
118 | } catch (final SecurityException e) { | |
119 | throw new InitializationException("Access denied for field with implicit collection", e); | |
120 | } catch (final NoSuchFieldException e) { | |
121 | declaredIn = declaredIn.getSuperclass(); | |
122 | } | |
103 | 123 | } |
104 | 124 | } |
105 | 125 | if (field == null) { |
176 | 196 | if (unnamed != null) { |
177 | 197 | return unnamed.getFieldName(); |
178 | 198 | } else { |
179 | ImplicitCollectionMapperForClass mapper = ImplicitCollectionMapper.this.getMapper(definedIn.getSuperclass()); | |
199 | ImplicitCollectionMapperForClass mapper = ImplicitCollectionMapper.this.getMapper(definedIn.getSuperclass(), null); | |
180 | 200 | return mapper != null ? mapper.getFieldNameForItemTypeAndName(itemType, itemFieldName) : null; |
181 | 201 | } |
182 | 202 | } |
186 | 206 | if (def != null) { |
187 | 207 | return def.getItemType(); |
188 | 208 | } else { |
189 | ImplicitCollectionMapperForClass mapper = ImplicitCollectionMapper.this.getMapper(definedIn.getSuperclass()); | |
209 | ImplicitCollectionMapperForClass mapper = ImplicitCollectionMapper.this.getMapper(definedIn.getSuperclass(), null); | |
190 | 210 | return mapper != null ? mapper.getItemTypeForItemFieldName(itemFieldName) : null; |
191 | 211 | } |
192 | 212 | } |
200 | 220 | if (mapping != null) { |
201 | 221 | return mapping; |
202 | 222 | } else { |
203 | ImplicitCollectionMapperForClass mapper = ImplicitCollectionMapper.this.getMapper(definedIn.getSuperclass()); | |
223 | ImplicitCollectionMapperForClass mapper = ImplicitCollectionMapper.this.getMapper(definedIn.getSuperclass(), null); | |
204 | 224 | return mapper != null ? mapper.getImplicitCollectionDefByItemFieldName(itemFieldName) : null; |
205 | 225 | } |
206 | 226 | } |
211 | 231 | if (mapping != null) { |
212 | 232 | return mapping; |
213 | 233 | } else { |
214 | ImplicitCollectionMapperForClass mapper = ImplicitCollectionMapper.this.getMapper(definedIn.getSuperclass()); | |
234 | ImplicitCollectionMapperForClass mapper = ImplicitCollectionMapper.this.getMapper(definedIn.getSuperclass(), null); | |
215 | 235 | return mapper != null ? mapper.getImplicitCollectionDefForFieldName(fieldName) : null; |
216 | 236 | } |
217 | 237 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2015 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 22. January 2005 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.mapper; |
40 | 40 | String realMember(Class type, String serialized); |
41 | 41 | |
42 | 42 | /** |
43 | * Whether this type is a simple immutable value (int, boolean, String, URL, etc. | |
44 | * Immutable types will be repeatedly written in the serialized stream, instead of using object references. | |
43 | * Whether this type is a simple immutable value (int, boolean, String, URL, etc). Immutable types will be | |
44 | * repeatedly written in the serialized stream, instead of using object references. | |
45 | 45 | */ |
46 | 46 | boolean isImmutableValueType(Class type); |
47 | ||
48 | /** | |
49 | * Whether this type is referenceable in a stream. | |
50 | * | |
51 | * @since 1.4.9 | |
52 | */ | |
53 | boolean isReferenceable(Class type); | |
47 | 54 | |
48 | 55 | Class defaultImplementationOf(Class type); |
49 | 56 | |
50 | 57 | /** |
51 | 58 | * Get the alias for an attribute's name. |
52 | * | |
59 | * | |
53 | 60 | * @param attribute the attribute |
54 | 61 | * @return the alias |
55 | 62 | * @since 1.2 |
58 | 65 | |
59 | 66 | /** |
60 | 67 | * Get the attribute's name for an alias. |
61 | * | |
68 | * | |
62 | 69 | * @param alias the alias |
63 | 70 | * @return the attribute's name |
64 | 71 | * @since 1.2 |
67 | 74 | |
68 | 75 | /** |
69 | 76 | * Get the alias for a system attribute's name. |
70 | * | |
77 | * | |
71 | 78 | * @param attribute the system attribute |
72 | 79 | * @return the alias |
73 | 80 | * @since 1.3.1 |
77 | 84 | /** |
78 | 85 | * Get the name of the field that acts as the default collection for an object, or return null if there is none. |
79 | 86 | * |
80 | * @param definedIn owning type | |
81 | * @param itemType item type | |
87 | * @param definedIn owning type | |
88 | * @param itemType item type | |
82 | 89 | * @param itemFieldName optional item element name |
83 | 90 | */ |
84 | 91 | String getFieldNameForItemTypeAndName(Class definedIn, Class itemType, String itemFieldName); |
122 | 129 | |
123 | 130 | /** |
124 | 131 | * Returns a single value converter to be used in a specific field. |
125 | * | |
132 | * | |
126 | 133 | * @param fieldName the field name |
127 | 134 | * @param type the field type |
128 | 135 | * @param definedIn the type which defines this field |
156 | 163 | |
157 | 164 | /** |
158 | 165 | * Returns which converter to use for an specific attribute in a type. |
159 | * | |
166 | * | |
160 | 167 | * @param definedIn the field's parent |
161 | 168 | * @param attribute the attribute name |
162 | 169 | * @deprecated As of 1.3.1, use {@link #getConverterFromAttribute(Class, String, Class)} |
165 | 172 | |
166 | 173 | /** |
167 | 174 | * Returns which converter to use for an specific attribute in a type. |
168 | * | |
175 | * | |
169 | 176 | * @param definedIn the field's parent |
170 | 177 | * @param attribute the attribute name |
171 | 178 | * @param type the type the converter should create |
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, 2015 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 | public boolean isImmutableValueType(Class type) { |
41 | 41 | return wrapped.isImmutableValueType(type); |
42 | } | |
43 | ||
44 | public boolean isReferenceable(Class type) { | |
45 | return wrapped.isReferenceable(type); | |
42 | 46 | } |
43 | 47 | |
44 | 48 | public Class defaultImplementationOf(Class type) { |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2009 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2009, 2015 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 31. January 2005 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.mapper; |
12 | ||
13 | import java.lang.reflect.Field; | |
14 | import java.util.Collections; | |
15 | import java.util.HashMap; | |
16 | import java.util.Map; | |
17 | ||
18 | import com.thoughtworks.xstream.core.Caching; | |
19 | ||
12 | 20 | |
13 | 21 | /** |
14 | 22 | * Mapper that uses a more meaningful alias for the field in an inner class (this$0) that refers to the outer class. |
15 | 23 | * |
16 | 24 | * @author Joe Walnes |
17 | 25 | */ |
18 | public class OuterClassMapper extends MapperWrapper { | |
26 | public class OuterClassMapper extends MapperWrapper implements Caching { | |
19 | 27 | |
28 | private static final String[] EMPTY_NAMES = new String[0]; | |
20 | 29 | private final String alias; |
30 | private final Map innerFields; | |
21 | 31 | |
22 | 32 | public OuterClassMapper(Mapper wrapped) { |
23 | 33 | this(wrapped, "outer-class"); |
26 | 36 | public OuterClassMapper(Mapper wrapped, String alias) { |
27 | 37 | super(wrapped); |
28 | 38 | this.alias = alias; |
39 | innerFields = Collections.synchronizedMap(new HashMap()); | |
40 | innerFields.put(Object.class.getName(), EMPTY_NAMES); | |
29 | 41 | } |
30 | 42 | |
31 | 43 | public String serializedMember(Class type, String memberName) { |
32 | if (memberName.equals("this$0")) { | |
33 | return alias; | |
34 | } else { | |
35 | return super.serializedMember(type, memberName); | |
44 | if (memberName.startsWith("this$")) { | |
45 | final String[] innerFieldNames = getInnerFieldNames(type); | |
46 | for (int i = 0; i < innerFieldNames.length; ++i) { | |
47 | if (innerFieldNames[i].equals(memberName)) { | |
48 | return i == 0 ? alias : alias + '-' + i; | |
49 | } | |
50 | } | |
36 | 51 | } |
52 | return super.serializedMember(type, memberName); | |
37 | 53 | } |
38 | 54 | |
39 | 55 | public String realMember(Class type, String serialized) { |
40 | if (serialized.equals(alias)) { | |
41 | return "this$0"; | |
42 | } else { | |
43 | return super.realMember(type, serialized); | |
56 | if (serialized.startsWith(alias)) { | |
57 | int idx = -1; | |
58 | final int len = alias.length(); | |
59 | if (len == serialized.length()) { | |
60 | idx = 0; | |
61 | } else if (serialized.length() > len + 1 && serialized.charAt(len) == '-') { | |
62 | idx = Integer.valueOf(serialized.substring(len + 1)).intValue(); | |
63 | } | |
64 | if (idx >= 0) { | |
65 | final String[] innerFieldNames = getInnerFieldNames(type); | |
66 | if (idx < innerFieldNames.length) { | |
67 | return innerFieldNames[idx]; | |
68 | } | |
69 | } | |
44 | 70 | } |
71 | return super.realMember(type, serialized); | |
72 | } | |
73 | ||
74 | private String[] getInnerFieldNames(final Class type) { | |
75 | String[] innerFieldNames = (String[])innerFields.get(type.getName()); | |
76 | if (innerFieldNames == null) { | |
77 | innerFieldNames = getInnerFieldNames(type.getSuperclass()); | |
78 | Field[] declaredFields = type.getDeclaredFields(); | |
79 | for (int i = 0; i < declaredFields.length; i++) { | |
80 | final Field field = declaredFields[i]; | |
81 | if (field.getName().startsWith("this$")) { | |
82 | String[] temp = new String[innerFieldNames.length+1]; | |
83 | System.arraycopy(innerFieldNames, 0, temp, 0, innerFieldNames.length); | |
84 | innerFieldNames = temp; | |
85 | innerFieldNames[innerFieldNames.length - 1] = field.getName(); | |
86 | } | |
87 | } | |
88 | innerFields.put(type.getName(), innerFieldNames); | |
89 | } | |
90 | return innerFieldNames; | |
91 | } | |
92 | ||
93 | public void flushCache() { | |
94 | innerFields.keySet().retainAll(Collections.singletonList(Object.class.getName())); | |
45 | 95 | } |
46 | 96 | } |
+39
-42
0 | 0 | /* |
1 | * Copyright (C) 2008 XStream Committers. | |
1 | * Copyright (C) 2008, 2016 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
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 |
6 | 6 | * the LICENSE.txt file. |
7 | * | |
7 | * | |
8 | 8 | * Created on 20. November 2008 by Joerg Schaible |
9 | 9 | */ |
10 | 10 | package com.thoughtworks.xstream.persistence; |
11 | 11 | |
12 | import java.io.File; | |
13 | ||
12 | 14 | import com.thoughtworks.xstream.XStream; |
15 | import com.thoughtworks.xstream.converters.ConversionException; | |
13 | 16 | import com.thoughtworks.xstream.converters.Converter; |
14 | 17 | import com.thoughtworks.xstream.converters.SingleValueConverter; |
15 | import com.thoughtworks.xstream.io.StreamException; | |
16 | 18 | import com.thoughtworks.xstream.io.xml.DomDriver; |
17 | ||
18 | import java.io.File; | |
19 | 19 | |
20 | 20 | |
21 | 21 | /** |
22 | * PersistenceStrategy to assign keys with single value to objects persisted in files. The | |
23 | * default naming strategy is based on the key's type and its {@link SingleValueConverter}. It | |
24 | * escapes all characters that are normally illegal in the most common file systems. Such a | |
25 | * character is escaped with percent escaping as it is done by URL encoding. The XStream used to | |
26 | * marshal the values is also requested for the key's SingleValueConverter. A | |
27 | * {@link StreamException} is thrown if no such converter is registered. | |
28 | * | |
22 | * PersistenceStrategy to assign keys with single value to objects persisted in files. The default naming strategy is | |
23 | * based on the key's type and its {@link SingleValueConverter}. It escapes all characters that are normally illegal in | |
24 | * the most common file systems. Such a character is escaped with percent escaping as it is done by URL encoding. The | |
25 | * XStream used to marshal the values is also requested for the key's SingleValueConverter. A | |
26 | * {@link ConversionException} is thrown if no such converter is registered. | |
27 | * | |
29 | 28 | * @author Jörg Schaible |
30 | 29 | * @author Guilherme Silveira |
31 | 30 | * @since 1.3.1 |
35 | 34 | private final String illegalChars; |
36 | 35 | |
37 | 36 | /** |
38 | * Create a new FilePersistenceStrategy. Use a standard XStream instance with a | |
39 | * {@link DomDriver}. | |
40 | * | |
37 | * Create a new FilePersistenceStrategy. Use a standard XStream instance with a {@link DomDriver}. | |
38 | * | |
41 | 39 | * @param baseDirectory the directory for the serialized values |
42 | 40 | * @since 1.3.1 |
43 | 41 | */ |
47 | 45 | |
48 | 46 | /** |
49 | 47 | * Create a new FilePersistenceStrategy with a provided XStream instance. |
50 | * | |
48 | * | |
51 | 49 | * @param baseDirectory the directory for the serialized values |
52 | 50 | * @param xstream the XStream instance to use for (de)serialization |
53 | 51 | * @since 1.3.1 |
57 | 55 | } |
58 | 56 | |
59 | 57 | /** |
60 | * Create a new FilePersistenceStrategy with a provided XStream instance and the characters | |
61 | * to encode. | |
62 | * | |
58 | * Create a new FilePersistenceStrategy with a provided XStream instance and the characters to encode. | |
59 | * | |
63 | 60 | * @param baseDirectory the directory for the serialized values |
64 | 61 | * @param xstream the XStream instance to use for (de)serialization |
65 | 62 | * @param encoding encoding used to write the files |
66 | * @param illegalChars illegal characters for file names (should always include '%' as long | |
67 | * as you do not overwrite the (un)escape methods) | |
63 | * @param illegalChars illegal characters for file names (should always include '%' as long as you do not overwrite | |
64 | * the (un)escape methods) | |
68 | 65 | * @since 1.3.1 |
69 | 66 | */ |
70 | 67 | public FilePersistenceStrategy( |
71 | final File baseDirectory, final XStream xstream, final String encoding, | |
72 | final String illegalChars) { | |
68 | final File baseDirectory, final XStream xstream, final String encoding, final String illegalChars) { | |
73 | 69 | super(baseDirectory, xstream, encoding); |
74 | 70 | this.illegalChars = illegalChars; |
75 | 71 | } |
80 | 76 | |
81 | 77 | /** |
82 | 78 | * Given a filename, the unescape method returns the key which originated it. |
83 | * | |
79 | * | |
84 | 80 | * @param name the filename |
85 | 81 | * @return the original key |
86 | 82 | */ |
89 | 85 | if ("null@null".equals(key)) { |
90 | 86 | return null; |
91 | 87 | } |
92 | int idx = key.indexOf('@'); | |
88 | final int idx = key.indexOf('@'); | |
93 | 89 | if (idx < 0) { |
94 | throw new StreamException("Not a valid key: " + key); | |
90 | final ConversionException exception = new ConversionException("No valid key"); | |
91 | exception.add("key", key); | |
92 | throw exception; | |
95 | 93 | } |
96 | Class type = getMapper().realClass(key.substring(0, idx)); | |
97 | Converter converter = getConverterLookup().lookupConverterForType(type); | |
94 | final Class type = getMapper().realClass(key.substring(0, idx)); | |
95 | final Converter converter = getConverterLookup().lookupConverterForType(type); | |
98 | 96 | if (converter instanceof SingleValueConverter) { |
99 | 97 | final SingleValueConverter svConverter = (SingleValueConverter)converter; |
100 | 98 | return svConverter.fromString(key.substring(idx + 1)); |
101 | 99 | } else { |
102 | throw new StreamException("No SingleValueConverter for type " | |
103 | + type.getName() | |
104 | + " available"); | |
100 | final ConversionException exception = new ConversionException( | |
101 | "No SingleValueConverter available for key type"); | |
102 | exception.add("key-type", type.getName()); | |
103 | throw exception; | |
105 | 104 | } |
106 | 105 | } |
107 | 106 | |
109 | 108 | final StringBuffer buffer = new StringBuffer(); |
110 | 109 | for (int idx = name.indexOf('%'); idx >= 0; idx = name.indexOf('%')) { |
111 | 110 | buffer.append(name.substring(0, idx)); |
112 | int c = Integer.parseInt(name.substring(idx + 1, idx + 3), 16); | |
111 | final int c = Integer.parseInt(name.substring(idx + 1, idx + 3), 16); | |
113 | 112 | buffer.append((char)c); |
114 | 113 | name = name.substring(idx + 3); |
115 | 114 | } |
119 | 118 | |
120 | 119 | /** |
121 | 120 | * Given a key, the escape method returns the filename which shall be used. |
122 | * | |
121 | * | |
123 | 122 | * @param key the key |
124 | 123 | * @return the desired and escaped filename |
125 | 124 | */ |
127 | 126 | if (key == null) { |
128 | 127 | return "null@null.xml"; |
129 | 128 | } |
130 | Class type = key.getClass(); | |
131 | Converter converter = getConverterLookup().lookupConverterForType(type); | |
129 | final Class type = key.getClass(); | |
130 | final Converter converter = getConverterLookup().lookupConverterForType(type); | |
132 | 131 | if (converter instanceof SingleValueConverter) { |
133 | 132 | final SingleValueConverter svConverter = (SingleValueConverter)converter; |
134 | return getMapper().serializedClass(type) | |
135 | + '@' | |
136 | + escape(svConverter.toString(key)) | |
137 | + ".xml"; | |
133 | return getMapper().serializedClass(type) + '@' + escape(svConverter.toString(key)) + ".xml"; | |
138 | 134 | } else { |
139 | throw new StreamException("No SingleValueConverter for type " | |
140 | + type.getName() | |
141 | + " available"); | |
135 | final ConversionException exception = new ConversionException( | |
136 | "No SingleValueConverter available for key type"); | |
137 | exception.add("key-type", type.getName()); | |
138 | throw exception; | |
142 | 139 | } |
143 | 140 | } |
144 | 141 |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2003, 2004, 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2014 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2014, 2015 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 | Class type = Class.forName(driver); |
71 | 71 | return (HierarchicalStreamDriver) type.newInstance(); |
72 | 72 | } |
73 | } | |
74 | catch (Exception e) { | |
75 | throw new RuntimeException("Could not load driver: " + driver); | |
73 | } catch (final Exception e) { | |
74 | throw new RuntimeException("Could not load driver: " + driver, e); | |
76 | 75 | } |
77 | 76 | return new XppDriver(); |
78 | 77 | } |
120 | 119 | |
121 | 120 | return resultRoot; |
122 | 121 | |
123 | } catch (TransformerException e) { | |
124 | throw new AssertionFailedError("Cannot normalize XML: " + e.getMessage()); | |
125 | // .initCause(e); ... still JDK 1.3 | |
122 | } catch (final TransformerException e) { | |
123 | final AssertionFailedError error = new AssertionFailedError("Cannot normalize XML: " + e.getMessage()); | |
124 | error.initCause(e); | |
125 | throw error; | |
126 | 126 | } |
127 | 127 | } |
128 | 128 |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2009, 2010, 2011, 2014 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2009, 2010, 2011, 2014, 2015 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
65 | 65 | Thing t0 = (Thing)result.get(0); |
66 | 66 | Thing t1 = (Thing)result.get(1); |
67 | 67 | Thing t2 = (Thing)result.get(2); |
68 | ||
69 | assertSame(t0, t1); | |
68 | 70 | |
69 | 71 | t0.field = "bye"; |
70 | 72 | |
471 | 473 | String xml = xstream.toXML(emails); |
472 | 474 | assertEquals(emails, xstream.fromXML(xml)); |
473 | 475 | } |
476 | ||
477 | public void testImmutableInstancesAreNotReferenced() { | |
478 | xstream.addImmutableType(Thing.class, false); | |
479 | ||
480 | Thing sameThing = new Thing("hello"); | |
481 | Thing anotherThing = new Thing("hello"); | |
482 | ||
483 | List list = new ArrayList(); | |
484 | list.add(sameThing); | |
485 | list.add(sameThing); | |
486 | list.add(anotherThing); | |
487 | ||
488 | String xml = xstream.toXML(list); | |
489 | List result = (List)xstream.fromXML(xml); | |
490 | ||
491 | Thing t0 = (Thing)result.get(0); | |
492 | Thing t1 = (Thing)result.get(1); | |
493 | Thing t2 = (Thing)result.get(2); | |
494 | ||
495 | assertEquals(t0, t1); | |
496 | assertNotSame(t0, t1); | |
497 | } | |
498 | ||
499 | public void testImmutableInstancesCanBeDereferenced() { | |
500 | ||
501 | Thing sameThing = new Thing("hello"); | |
502 | Thing anotherThing = new Thing("hello"); | |
503 | ||
504 | List list = new ArrayList(); | |
505 | list.add(sameThing); | |
506 | list.add(sameThing); | |
507 | list.add(anotherThing); | |
508 | ||
509 | String xml = xstream.toXML(list); | |
510 | ||
511 | xstream.addImmutableType(Thing.class, false); | |
512 | ||
513 | try { | |
514 | xstream.fromXML(xml); | |
515 | fail("Thrown " + ConversionException.class.getName() + " expected"); | |
516 | } catch (final ConversionException e) { | |
517 | assertEquals(Thing.class.getName(), e.get("referenced-type")); | |
518 | } | |
519 | ||
520 | xstream.addImmutableType(Thing.class, true); | |
521 | ||
522 | List result = (List)xstream.fromXML(xml); | |
523 | ||
524 | Thing t0 = (Thing)result.get(0); | |
525 | Thing t1 = (Thing)result.get(1); | |
526 | Thing t2 = (Thing)result.get(2); | |
527 | ||
528 | assertEquals(t0, t1); | |
529 | assertSame(t0, t1); | |
530 | } | |
474 | 531 | } |
0 | /* | |
1 | * Copyright (C) 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 7. February 2016 by Aaron Johnson | |
9 | */ | |
10 | package com.thoughtworks.acceptance; | |
11 | ||
12 | import java.io.IOException; | |
13 | import java.net.URI; | |
14 | import java.nio.file.FileSystem; | |
15 | import java.nio.file.FileSystems; | |
16 | import java.nio.file.Path; | |
17 | import java.nio.file.Paths; | |
18 | import java.util.HashMap; | |
19 | import java.util.Map; | |
20 | ||
21 | import com.thoughtworks.xstream.XStream; | |
22 | ||
23 | ||
24 | /** | |
25 | * @author Aaron Johnson | |
26 | * @author Jörg Schaible | |
27 | */ | |
28 | public class Extended17TypesTest extends AbstractAcceptanceTest { | |
29 | ||
30 | @Override | |
31 | protected void setupSecurity(final XStream xstream) { | |
32 | super.setupSecurity(xstream); | |
33 | xstream.allowTypeHierarchy(Path.class); | |
34 | } | |
35 | ||
36 | public void testPathOfDefaultFileSystem() { | |
37 | assertBothWays(Paths.get("../a/relative/path"), "<path>../a/relative/path</path>"); | |
38 | assertBothWays(Paths.get("/an/absolute/path"), "<path>/an/absolute/path</path>"); | |
39 | ||
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>"); | |
43 | } | |
44 | ||
45 | public void testPathOfNonDefaultFileSystem() throws IOException { | |
46 | final Map<String, String> env = new HashMap<String, String>(); | |
47 | env.put("create", "true"); | |
48 | final URI uri = URI.create("jar:file://" | |
49 | + Paths.get("target/lib/proxytoys-0.2.1.jar").toAbsolutePath().toString()); | |
50 | ||
51 | FileSystem zipfs = null; | |
52 | try { | |
53 | zipfs = FileSystems.newFileSystem(uri, env); | |
54 | final String entry = "/com/thoughtworks/proxy/kit/SimpleReference.class"; | |
55 | final Path path = zipfs.getPath(entry); | |
56 | assertBothWays(path, "<path>" + uri.toString() + "!" + entry + "</path>"); | |
57 | } finally { | |
58 | if (zipfs != null) { | |
59 | zipfs.close(); | |
60 | } | |
61 | } | |
62 | } | |
63 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2013, 2014 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 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 |
44 | 44 | } |
45 | 45 | } catch (ObjectAccessException expectedException) { |
46 | 46 | assertEquals("Invalid final field " + ThingWithFinalField.class.getName() + ".number", |
47 | expectedException.getMessage()); | |
47 | expectedException.get("message")); | |
48 | 48 | } |
49 | 49 | } |
50 | 50 | } |
0 | 0 | /* |
1 | * Copyright (C) 2011, 2012, 2013 XStream Committers. | |
1 | * Copyright (C) 2011, 2012, 2013, 2014, 2015 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 | xstream.alias("farm", Farm.class); |
27 | 27 | xstream.alias("animal", Animal.class); |
28 | 28 | xstream.alias("MEGA-farm", MegaFarm.class); |
29 | xstream.alias("area", Area.class); | |
30 | xstream.alias("country", Country.class); | |
29 | 31 | xstream.ignoreUnknownElements(); |
30 | 32 | } |
31 | 33 | |
482 | 484 | assertBothWays(farm, expected); |
483 | 485 | } |
484 | 486 | |
487 | public static class Area extends Farm { | |
488 | Animal[] animals; | |
489 | } | |
490 | ||
491 | public void testWithHiddenArray() { | |
492 | Area area = new Area(); | |
493 | ((Farm)area).animals = new Animal[2]; | |
494 | ((Farm)area).animals[0] = new Animal("Cow"); | |
495 | ((Farm)area).animals[1] = new Animal("Sheep"); | |
496 | area.animals = new Animal[2]; | |
497 | area.animals[0] = new Animal("Falcon"); | |
498 | area.animals[1] = new Animal("Sparrow"); | |
499 | ||
500 | String expected = "" + | |
501 | "<area>\n" + | |
502 | " <animal defined-in=\"farm\">\n" + | |
503 | " <name>Cow</name>\n" + | |
504 | " </animal>\n" + | |
505 | " <animal defined-in=\"farm\">\n" + | |
506 | " <name>Sheep</name>\n" + | |
507 | " </animal>\n" + | |
508 | " <animal>\n" + | |
509 | " <name>Falcon</name>\n" + | |
510 | " </animal>\n" + | |
511 | " <animal>\n" + | |
512 | " <name>Sparrow</name>\n" + | |
513 | " </animal>\n" + | |
514 | "</area>"; | |
515 | ||
516 | xstream.addImplicitArray(Farm.class, "animals"); | |
517 | xstream.addImplicitArray(Area.class, "animals"); | |
518 | assertBothWays(area, expected); | |
519 | } | |
520 | ||
521 | public void testWithHiddenArrayAndDifferentAlias() { | |
522 | Area area = new Area(); | |
523 | ((Farm)area).animals = new Animal[2]; | |
524 | ((Farm)area).animals[0] = new Animal("Cow"); | |
525 | ((Farm)area).animals[1] = new Animal("Sheep"); | |
526 | area.animals = new Animal[2]; | |
527 | area.animals[0] = new Animal("Falcon"); | |
528 | area.animals[1] = new Animal("Sparrow"); | |
529 | ||
530 | String expected = "" + | |
531 | "<area>\n" + | |
532 | " <domesticated defined-in=\"farm\">\n" + | |
533 | " <name>Cow</name>\n" + | |
534 | " </domesticated>\n" + | |
535 | " <domesticated defined-in=\"farm\">\n" + | |
536 | " <name>Sheep</name>\n" + | |
537 | " </domesticated>\n" + | |
538 | " <wild>\n" + | |
539 | " <name>Falcon</name>\n" + | |
540 | " </wild>\n" + | |
541 | " <wild>\n" + | |
542 | " <name>Sparrow</name>\n" + | |
543 | " </wild>\n" + | |
544 | "</area>"; | |
545 | ||
546 | xstream.addImplicitArray(Farm.class, "animals", "domesticated"); | |
547 | xstream.addImplicitArray(Area.class, "animals", "wild"); | |
548 | assertBothWays(area, expected); | |
549 | } | |
550 | ||
551 | public void testDoesNotInheritFromHiddenArrayOfSuperclass() { | |
552 | Area area = new Area(); | |
553 | ((Farm)area).animals = new Animal[2]; | |
554 | ((Farm)area).animals[0] = new Animal("Cow"); | |
555 | ((Farm)area).animals[1] = new Animal("Sheep"); | |
556 | area.animals = new Animal[2]; | |
557 | area.animals[0] = new Animal("Falcon"); | |
558 | area.animals[1] = new Animal("Sparrow"); | |
559 | ||
560 | String expected = "" + | |
561 | "<area>\n" + | |
562 | " <animal defined-in=\"farm\">\n" + | |
563 | " <name>Cow</name>\n" + | |
564 | " </animal>\n" + | |
565 | " <animal defined-in=\"farm\">\n" + | |
566 | " <name>Sheep</name>\n" + | |
567 | " </animal>\n" + | |
568 | " <animals>\n" + | |
569 | " <animal>\n" + | |
570 | " <name>Falcon</name>\n" + | |
571 | " </animal>\n" + | |
572 | " <animal>\n" + | |
573 | " <name>Sparrow</name>\n" + | |
574 | " </animal>\n" + | |
575 | " </animals>\n" + | |
576 | "</area>"; | |
577 | ||
578 | xstream.addImplicitArray(Farm.class, "animals"); | |
579 | assertBothWays(area, expected); | |
580 | } | |
581 | ||
582 | public void testDoesNotPropagateToHiddenArrayOfSuperclass() { | |
583 | Area area = new Area(); | |
584 | ((Farm)area).animals = new Animal[2]; | |
585 | ((Farm)area).animals[0] = new Animal("Cow"); | |
586 | ((Farm)area).animals[1] = new Animal("Sheep"); | |
587 | area.animals = new Animal[2]; | |
588 | area.animals[0] = new Animal("Falcon"); | |
589 | area.animals[1] = new Animal("Sparrow"); | |
590 | ||
591 | String expected = "" + | |
592 | "<area>\n" + | |
593 | " <animals defined-in=\"farm\">\n" + | |
594 | " <animal>\n" + | |
595 | " <name>Cow</name>\n" + | |
596 | " </animal>\n" + | |
597 | " <animal>\n" + | |
598 | " <name>Sheep</name>\n" + | |
599 | " </animal>\n" + | |
600 | " </animals>\n" + | |
601 | " <animal>\n" + | |
602 | " <name>Falcon</name>\n" + | |
603 | " </animal>\n" + | |
604 | " <animal>\n" + | |
605 | " <name>Sparrow</name>\n" + | |
606 | " </animal>\n" + | |
607 | "</area>"; | |
608 | ||
609 | xstream.addImplicitArray(Area.class, "animals"); | |
610 | assertBothWays(area, expected); | |
611 | } | |
612 | ||
613 | public static class County extends Area { | |
614 | } | |
615 | ||
616 | public static class Country extends County { | |
617 | Animal[] animals; | |
618 | } | |
619 | ||
620 | public void testWithDoubleHiddenArray() { | |
621 | Country country = new Country(); | |
622 | ((Farm)country).animals = new Animal[2]; | |
623 | ((Farm)country).animals[0] = new Animal("Cow"); | |
624 | ((Farm)country).animals[1] = new Animal("Sheep"); | |
625 | ((Area)country).animals = new Animal[2]; | |
626 | ((Area)country).animals[0] = new Animal("Falcon"); | |
627 | ((Area)country).animals[1] = new Animal("Sparrow"); | |
628 | country.animals = new Animal[2]; | |
629 | country.animals[0] = new Animal("Wale"); | |
630 | country.animals[1] = new Animal("Dolphin"); | |
631 | ||
632 | String expected = "" + | |
633 | "<country>\n" + | |
634 | " <animal defined-in=\"farm\">\n" + | |
635 | " <name>Cow</name>\n" + | |
636 | " </animal>\n" + | |
637 | " <animal defined-in=\"farm\">\n" + | |
638 | " <name>Sheep</name>\n" + | |
639 | " </animal>\n" + | |
640 | " <animal defined-in=\"area\">\n" + | |
641 | " <name>Falcon</name>\n" + | |
642 | " </animal>\n" + | |
643 | " <animal defined-in=\"area\">\n" + | |
644 | " <name>Sparrow</name>\n" + | |
645 | " </animal>\n" + | |
646 | " <animal>\n" + | |
647 | " <name>Wale</name>\n" + | |
648 | " </animal>\n" + | |
649 | " <animal>\n" + | |
650 | " <name>Dolphin</name>\n" + | |
651 | " </animal>\n" + | |
652 | "</country>"; | |
653 | ||
654 | xstream.addImplicitArray(Farm.class, "animals"); | |
655 | xstream.addImplicitArray(Area.class, "animals"); | |
656 | xstream.addImplicitArray(Country.class, "animals"); | |
657 | assertBothWays(country, expected); | |
658 | } | |
659 | ||
485 | 660 | static class PrimitiveArray { |
486 | 661 | int[] ints; |
487 | 662 | }; |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 2013, 2014, 2015 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
56 | 56 | xstream.alias("room", Room.class); |
57 | 57 | xstream.alias("house", House.class); |
58 | 58 | xstream.alias("person", Person.class); |
59 | xstream.alias("area", Area.class); | |
60 | xstream.alias("country", Country.class); | |
59 | 61 | xstream.ignoreUnknownElements(); |
60 | 62 | } |
61 | 63 | |
548 | 550 | xstream.addImplicitCollection(Farm.class, "animals", "beast", Animal.class); |
549 | 551 | assertBothWays(farm, expected); |
550 | 552 | } |
553 | ||
554 | public static class Area extends Farm { | |
555 | ||
556 | List animals = new ArrayList(); | |
557 | ||
558 | public Area(int size) { | |
559 | super(size); | |
560 | } | |
561 | ||
562 | } | |
563 | ||
564 | public void testWithHiddenList() { | |
565 | Area area = new Area(1000); | |
566 | area.add(new Animal("Cow")); | |
567 | area.add(new Animal("Sheep")); | |
568 | area.animals.add(new Animal("Falcon")); | |
569 | area.animals.add(new Animal("Sparrow")); | |
570 | ||
571 | String expected = "" + | |
572 | "<area>\n" + | |
573 | " <size>1000</size>\n" + | |
574 | " <animal defined-in=\"farm\">\n" + | |
575 | " <name>Cow</name>\n" + | |
576 | " </animal>\n" + | |
577 | " <animal defined-in=\"farm\">\n" + | |
578 | " <name>Sheep</name>\n" + | |
579 | " </animal>\n" + | |
580 | " <animal>\n" + | |
581 | " <name>Falcon</name>\n" + | |
582 | " </animal>\n" + | |
583 | " <animal>\n" + | |
584 | " <name>Sparrow</name>\n" + | |
585 | " </animal>\n" + | |
586 | "</area>"; | |
587 | ||
588 | xstream.addImplicitCollection(Farm.class, "animals"); | |
589 | xstream.addImplicitCollection(Area.class, "animals"); | |
590 | assertBothWays(area, expected); | |
591 | } | |
592 | ||
593 | public void testWithHiddenListAndDifferentAlias() { | |
594 | Area area = new Area(1000); | |
595 | area.add(new Animal("Cow")); | |
596 | area.add(new Animal("Sheep")); | |
597 | area.animals.add(new Animal("Falcon")); | |
598 | area.animals.add(new Animal("Sparrow")); | |
599 | ||
600 | String expected = "" + | |
601 | "<area>\n" + | |
602 | " <size>1000</size>\n" + | |
603 | " <domesticated defined-in=\"farm\">\n" + | |
604 | " <name>Cow</name>\n" + | |
605 | " </domesticated>\n" + | |
606 | " <domesticated defined-in=\"farm\">\n" + | |
607 | " <name>Sheep</name>\n" + | |
608 | " </domesticated>\n" + | |
609 | " <wild>\n" + | |
610 | " <name>Falcon</name>\n" + | |
611 | " </wild>\n" + | |
612 | " <wild>\n" + | |
613 | " <name>Sparrow</name>\n" + | |
614 | " </wild>\n" + | |
615 | "</area>"; | |
616 | ||
617 | xstream.addImplicitCollection(Farm.class, "animals", "domesticated", Animal.class); | |
618 | xstream.addImplicitCollection(Area.class, "animals", "wild", Animal.class); | |
619 | assertBothWays(area, expected); | |
620 | } | |
621 | ||
622 | public void testDoesNotInheritFromHiddenListOfSuperclass() { | |
623 | Area area = new Area(1000); | |
624 | area.add(new Animal("Cow")); | |
625 | area.add(new Animal("Sheep")); | |
626 | area.animals.add(new Animal("Falcon")); | |
627 | area.animals.add(new Animal("Sparrow")); | |
628 | ||
629 | String expected = "" + | |
630 | "<area>\n" + | |
631 | " <size>1000</size>\n" + | |
632 | " <animal defined-in=\"farm\">\n" + | |
633 | " <name>Cow</name>\n" + | |
634 | " </animal>\n" + | |
635 | " <animal defined-in=\"farm\">\n" + | |
636 | " <name>Sheep</name>\n" + | |
637 | " </animal>\n" + | |
638 | " <animals>\n" + | |
639 | " <animal>\n" + | |
640 | " <name>Falcon</name>\n" + | |
641 | " </animal>\n" + | |
642 | " <animal>\n" + | |
643 | " <name>Sparrow</name>\n" + | |
644 | " </animal>\n" + | |
645 | " </animals>\n" + | |
646 | "</area>"; | |
647 | ||
648 | xstream.addImplicitCollection(Farm.class, "animals"); | |
649 | assertBothWays(area, expected); | |
650 | } | |
651 | ||
652 | public void testDoesNotPropagateToHiddenListOfSuperclass() { | |
653 | Area area = new Area(1000); | |
654 | area.add(new Animal("Cow")); | |
655 | area.add(new Animal("Sheep")); | |
656 | area.animals.add(new Animal("Falcon")); | |
657 | area.animals.add(new Animal("Sparrow")); | |
658 | ||
659 | String expected = "" + | |
660 | "<area>\n" + | |
661 | " <size>1000</size>\n" + | |
662 | " <animals defined-in=\"farm\">\n" + | |
663 | " <animal>\n" + | |
664 | " <name>Cow</name>\n" + | |
665 | " </animal>\n" + | |
666 | " <animal>\n" + | |
667 | " <name>Sheep</name>\n" + | |
668 | " </animal>\n" + | |
669 | " </animals>\n" + | |
670 | " <animal>\n" + | |
671 | " <name>Falcon</name>\n" + | |
672 | " </animal>\n" + | |
673 | " <animal>\n" + | |
674 | " <name>Sparrow</name>\n" + | |
675 | " </animal>\n" + | |
676 | "</area>"; | |
677 | ||
678 | xstream.addImplicitCollection(Area.class, "animals"); | |
679 | assertBothWays(area, expected); | |
680 | } | |
681 | ||
682 | public static class County extends Area { | |
683 | ||
684 | public County() { | |
685 | super(10); | |
686 | } | |
687 | } | |
688 | ||
689 | public static class Country extends County { | |
690 | List animals = new ArrayList(); | |
691 | } | |
692 | ||
693 | public void testWithDoubleHiddenList() { | |
694 | Country country = new Country(); | |
695 | country.add(new Animal("Cow")); | |
696 | country.add(new Animal("Sheep")); | |
697 | ((Area)country).animals.add(new Animal("Falcon")); | |
698 | ((Area)country).animals.add(new Animal("Sparrow")); | |
699 | country.animals.add(new Animal("Wale")); | |
700 | country.animals.add(new Animal("Dolphin")); | |
701 | ||
702 | String expected = "" + | |
703 | "<country>\n" + | |
704 | " <size>10</size>\n" + | |
705 | " <animal defined-in=\"farm\">\n" + | |
706 | " <name>Cow</name>\n" + | |
707 | " </animal>\n" + | |
708 | " <animal defined-in=\"farm\">\n" + | |
709 | " <name>Sheep</name>\n" + | |
710 | " </animal>\n" + | |
711 | " <animal defined-in=\"area\">\n" + | |
712 | " <name>Falcon</name>\n" + | |
713 | " </animal>\n" + | |
714 | " <animal defined-in=\"area\">\n" + | |
715 | " <name>Sparrow</name>\n" + | |
716 | " </animal>\n" + | |
717 | " <animal>\n" + | |
718 | " <name>Wale</name>\n" + | |
719 | " </animal>\n" + | |
720 | " <animal>\n" + | |
721 | " <name>Dolphin</name>\n" + | |
722 | " </animal>\n" + | |
723 | "</country>"; | |
724 | ||
725 | xstream.addImplicitCollection(Farm.class, "animals"); | |
726 | xstream.addImplicitCollection(Area.class, "animals"); | |
727 | xstream.addImplicitCollection(Country.class, "animals"); | |
728 | assertBothWays(country, expected); | |
729 | } | |
551 | 730 | } |
0 | 0 | /* |
1 | * Copyright (C) 2011, 2012, 2013 XStream Committers. | |
1 | * Copyright (C) 2011, 2012, 2013, 2014, 2015 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 com.thoughtworks.acceptance.objects.Product; |
14 | 14 | import com.thoughtworks.acceptance.objects.SampleMaps; |
15 | 15 | import com.thoughtworks.acceptance.objects.Software; |
16 | import com.thoughtworks.acceptance.objects.StandardObject; | |
17 | 16 | import com.thoughtworks.xstream.converters.collections.MapConverter; |
18 | import com.thoughtworks.xstream.core.util.OrderRetainingMap; | |
19 | 17 | |
20 | 18 | import java.util.ArrayList; |
21 | 19 | import java.util.Collections; |
20 | import java.util.LinkedHashMap; | |
22 | 21 | import java.util.List; |
23 | 22 | import java.util.Map; |
24 | 23 | import java.util.TreeMap; |
25 | 24 | |
26 | 25 | public class ImplicitMapTest extends AbstractAcceptanceTest { |
27 | ||
28 | public static class Farm extends StandardObject { | |
29 | int size; | |
30 | List animals = new ArrayList(); | |
31 | ||
32 | public Farm(int size) { | |
33 | this.size = size; | |
34 | } | |
35 | ||
36 | public void add(Animal animal) { | |
37 | animals.add(animal); | |
38 | } | |
39 | } | |
40 | ||
41 | public static class Animal extends StandardObject implements Comparable { | |
42 | String name; | |
43 | ||
44 | public Animal(String name) { | |
45 | this.name = name; | |
46 | } | |
47 | ||
48 | public int compareTo(Object o) { | |
49 | return name.compareTo(((Animal)o).name); | |
50 | } | |
51 | } | |
52 | 26 | |
53 | 27 | protected void setUp() throws Exception { |
54 | 28 | super.setUp(); |
55 | 29 | xstream.registerConverter(new MapConverter(xstream.getMapper()) { |
56 | 30 | public boolean canConvert(Class type) { |
57 | return type == OrderRetainingMap.class; | |
31 | return type == LinkedHashMap.class; | |
58 | 32 | } |
59 | 33 | }); |
60 | xstream.addDefaultImplementation(OrderRetainingMap.class, Map.class); | |
34 | xstream.addDefaultImplementation(LinkedHashMap.class, Map.class); | |
61 | 35 | xstream.alias("sample", SampleMaps.class); |
62 | 36 | xstream.alias("software", Software.class); |
63 | 37 | xstream.alias("hardware", Hardware.class); |
64 | 38 | xstream.alias("product", Product.class); |
39 | xstream.alias("sample2", SampleMaps2.class); | |
40 | xstream.alias("sample3", SampleMaps3.class); | |
65 | 41 | xstream.ignoreUnknownElements(); |
66 | 42 | } |
67 | 43 | |
68 | 44 | public void testWithout() { |
69 | 45 | SampleMaps sample = new SampleMaps(); |
70 | sample.good = new OrderRetainingMap(); | |
46 | sample.good = new LinkedHashMap(); | |
71 | 47 | sample.good.put("Windows", new Software("Microsoft", "Windows")); |
72 | 48 | sample.good.put("Linux", new Software("Red Hat", "Linux")); |
73 | 49 | |
97 | 73 | |
98 | 74 | public void testWithMap() { |
99 | 75 | SampleMaps sample = new SampleMaps(); |
100 | sample.good = new OrderRetainingMap(); | |
76 | sample.good = new LinkedHashMap(); | |
101 | 77 | sample.good.put("Windows", new Software("Microsoft", "Windows")); |
102 | 78 | sample.good.put("Linux", new Software("Red Hat", "Linux")); |
103 | 79 | |
120 | 96 | |
121 | 97 | public static class MegaSampleMaps extends SampleMaps { |
122 | 98 | String separator = "---"; |
123 | Map other = new OrderRetainingMap(); | |
99 | Map other = new LinkedHashMap(); | |
124 | 100 | { |
125 | good = new OrderRetainingMap(); | |
126 | bad = new OrderRetainingMap(); | |
101 | good = new LinkedHashMap(); | |
102 | bad = new LinkedHashMap(); | |
127 | 103 | } |
128 | 104 | } |
129 | 105 | |
370 | 346 | |
371 | 347 | public void testWithExplicitItemNameMatchingTheNameOfTheFieldWithTheMap() { |
372 | 348 | SampleMaps sample = new SampleMaps(); |
373 | sample.bad = new OrderRetainingMap(); | |
349 | sample.bad = new LinkedHashMap(); | |
374 | 350 | sample.bad.put("Windows", new Software("Microsoft", "Windows")); |
375 | 351 | sample.bad.put("Linux", new Software("Red Hat", "Linux")); |
376 | 352 | |
393 | 369 | |
394 | 370 | public void testWithImplicitNameMatchingTheNameOfTheFieldWithTheMap() { |
395 | 371 | SampleMaps sample = new SampleMaps(); |
396 | sample.bad = new OrderRetainingMap(); | |
372 | sample.bad = new LinkedHashMap(); | |
397 | 373 | sample.bad.put("Windows", new Software("Microsoft", "Windows")); |
398 | 374 | sample.bad.put("Linux", new Software("Red Hat", "Linux")); |
399 | 375 | |
417 | 393 | |
418 | 394 | public void testWithAliasedItemNameMatchingTheAliasedNameOfTheFieldWithTheMap() { |
419 | 395 | SampleMaps sample = new SampleMaps(); |
420 | sample.bad = new OrderRetainingMap(); | |
396 | sample.bad = new LinkedHashMap(); | |
421 | 397 | sample.bad.put("Windows", new Software("Microsoft", "Windows")); |
422 | 398 | sample.bad.put("Linux", new Software("Red Hat", "Linux")); |
423 | 399 | |
441 | 417 | |
442 | 418 | public void testWithNullElement() { |
443 | 419 | SampleMaps sample = new SampleMaps(); |
444 | sample.good = new OrderRetainingMap(); | |
420 | sample.good = new LinkedHashMap(); | |
445 | 421 | sample.good.put(null, null); |
446 | 422 | sample.good.put("Linux", new Software("Red Hat", "Linux")); |
447 | 423 | |
461 | 437 | |
462 | 438 | public void testWithAliasAndNullElement() { |
463 | 439 | SampleMaps sample = new SampleMaps(); |
464 | sample.good = new OrderRetainingMap(); | |
440 | sample.good = new LinkedHashMap(); | |
465 | 441 | sample.good.put(null, null); |
466 | 442 | sample.good.put("Linux", new Software("Red Hat", "Linux")); |
467 | 443 | |
478 | 454 | xstream.addImplicitMap(SampleMaps.class, "good", "code", Software.class, "name"); |
479 | 455 | assertBothWays(sample, expected); |
480 | 456 | } |
457 | ||
458 | public static class SampleMaps2 extends SampleMaps { | |
459 | public Map good = new LinkedHashMap(); | |
460 | } | |
461 | ||
462 | public void testWithHiddenMap() { | |
463 | SampleMaps2 sample = new SampleMaps2(); | |
464 | ((SampleMaps)sample).good = new LinkedHashMap(); | |
465 | ((SampleMaps)sample).good.put("Windows", new Software("Microsoft", "Windows")); | |
466 | ((SampleMaps)sample).good.put("Linux", new Software("Red Hat", "Linux")); | |
467 | sample.good.put("Android", new Software("Google", "Android")); | |
468 | sample.good.put("iOS", new Software("Apple", "iOS")); | |
469 | sample.bad = null; | |
470 | ||
471 | String expected = "" + | |
472 | "<sample2>\n" + | |
473 | " <software defined-in=\"sample\">\n" + | |
474 | " <vendor>Microsoft</vendor>\n" + | |
475 | " <name>Windows</name>\n" + | |
476 | " </software>\n" + | |
477 | " <software defined-in=\"sample\">\n" + | |
478 | " <vendor>Red Hat</vendor>\n" + | |
479 | " <name>Linux</name>\n" + | |
480 | " </software>\n" + | |
481 | " <software>\n" + | |
482 | " <vendor>Google</vendor>\n" + | |
483 | " <name>Android</name>\n" + | |
484 | " </software>\n" + | |
485 | " <software>\n" + | |
486 | " <vendor>Apple</vendor>\n" + | |
487 | " <name>iOS</name>\n" + | |
488 | " </software>\n" + | |
489 | "</sample2>"; | |
490 | ||
491 | xstream.addImplicitMap(SampleMaps.class, "good", Software.class, "name"); | |
492 | xstream.addImplicitMap(SampleMaps2.class, "good", Software.class, "name"); | |
493 | assertBothWays(sample, expected); | |
494 | } | |
495 | ||
496 | public void testWithHiddenMapAndDifferentAlias() { | |
497 | SampleMaps2 sample = new SampleMaps2(); | |
498 | ((SampleMaps)sample).good = new LinkedHashMap(); | |
499 | ((SampleMaps)sample).good.put("Windows", new Software("Microsoft", "Windows")); | |
500 | ((SampleMaps)sample).good.put("Linux", new Software("Red Hat", "Linux")); | |
501 | sample.good.put("Android", new Software("Google", "Android")); | |
502 | sample.good.put("iOS", new Software("Apple", "iOS")); | |
503 | sample.bad = null; | |
504 | ||
505 | String expected = "" + | |
506 | "<sample2>\n" + | |
507 | " <code defined-in=\"sample\">\n" + | |
508 | " <vendor>Microsoft</vendor>\n" + | |
509 | " <name>Windows</name>\n" + | |
510 | " </code>\n" + | |
511 | " <code defined-in=\"sample\">\n" + | |
512 | " <vendor>Red Hat</vendor>\n" + | |
513 | " <name>Linux</name>\n" + | |
514 | " </code>\n" + | |
515 | " <mobile>\n" + | |
516 | " <vendor>Google</vendor>\n" + | |
517 | " <name>Android</name>\n" + | |
518 | " </mobile>\n" + | |
519 | " <mobile>\n" + | |
520 | " <vendor>Apple</vendor>\n" + | |
521 | " <name>iOS</name>\n" + | |
522 | " </mobile>\n" + | |
523 | "</sample2>"; | |
524 | ||
525 | xstream.addImplicitMap(SampleMaps.class, "good", "code", Software.class, "name"); | |
526 | xstream.addImplicitMap(SampleMaps2.class, "good", "mobile", Software.class, "name"); | |
527 | } | |
528 | ||
529 | public void testDoesNotInheritFromHiddenMapOfSuperclass() { | |
530 | SampleMaps2 sample = new SampleMaps2(); | |
531 | ((SampleMaps)sample).good = new LinkedHashMap(); | |
532 | ((SampleMaps)sample).good.put("Windows", new Software("Microsoft", "Windows")); | |
533 | ((SampleMaps)sample).good.put("Linux", new Software("Red Hat", "Linux")); | |
534 | sample.good.put("Android", new Software("Google", "Android")); | |
535 | sample.good.put("iOS", new Software("Apple", "iOS")); | |
536 | sample.bad = null; | |
537 | ||
538 | String expected = "" + | |
539 | "<sample2>\n" + | |
540 | " <software defined-in=\"sample\">\n" + | |
541 | " <vendor>Microsoft</vendor>\n" + | |
542 | " <name>Windows</name>\n" + | |
543 | " </software>\n" + | |
544 | " <software defined-in=\"sample\">\n" + | |
545 | " <vendor>Red Hat</vendor>\n" + | |
546 | " <name>Linux</name>\n" + | |
547 | " </software>\n" + | |
548 | " <good>\n" + | |
549 | " <entry>\n" + | |
550 | " <string>Android</string>\n" + | |
551 | " <software>\n" + | |
552 | " <vendor>Google</vendor>\n" + | |
553 | " <name>Android</name>\n" + | |
554 | " </software>\n" + | |
555 | " </entry>\n" + | |
556 | " <entry>\n" + | |
557 | " <string>iOS</string>\n" + | |
558 | " <software>\n" + | |
559 | " <vendor>Apple</vendor>\n" + | |
560 | " <name>iOS</name>\n" + | |
561 | " </software>\n" + | |
562 | " </entry>\n" + | |
563 | " </good>\n" + | |
564 | "</sample2>"; | |
565 | ||
566 | xstream.addImplicitMap(SampleMaps.class, "good", Software.class, "name"); | |
567 | assertBothWays(sample, expected); | |
568 | } | |
569 | ||
570 | public void testDoesNotPropagateToHiddenMapOfSuperclass() { | |
571 | SampleMaps2 sample = new SampleMaps2(); | |
572 | ((SampleMaps)sample).good = new LinkedHashMap(); | |
573 | ((SampleMaps)sample).good.put("Windows", new Software("Microsoft", "Windows")); | |
574 | ((SampleMaps)sample).good.put("Linux", new Software("Red Hat", "Linux")); | |
575 | sample.good.put("Android", new Software("Google", "Android")); | |
576 | sample.good.put("iOS", new Software("Apple", "iOS")); | |
577 | sample.bad = null; | |
578 | ||
579 | String expected = "" + | |
580 | "<sample2>\n" + | |
581 | " <good defined-in=\"sample\">\n" + | |
582 | " <entry>\n" + | |
583 | " <string>Windows</string>\n" + | |
584 | " <software>\n" + | |
585 | " <vendor>Microsoft</vendor>\n" + | |
586 | " <name>Windows</name>\n" + | |
587 | " </software>\n" + | |
588 | " </entry>\n" + | |
589 | " <entry>\n" + | |
590 | " <string>Linux</string>\n" + | |
591 | " <software>\n" + | |
592 | " <vendor>Red Hat</vendor>\n" + | |
593 | " <name>Linux</name>\n" + | |
594 | " </software>\n" + | |
595 | " </entry>\n" + | |
596 | " </good>\n" + | |
597 | " <software>\n" + | |
598 | " <vendor>Google</vendor>\n" + | |
599 | " <name>Android</name>\n" + | |
600 | " </software>\n" + | |
601 | " <software>\n" + | |
602 | " <vendor>Apple</vendor>\n" + | |
603 | " <name>iOS</name>\n" + | |
604 | " </software>\n" + | |
605 | "</sample2>"; | |
606 | ||
607 | xstream.addImplicitMap(SampleMaps2.class, "good", Software.class, "name"); | |
608 | assertBothWays(sample, expected); | |
609 | } | |
610 | ||
611 | public static class IntermediateMaps extends SampleMaps2 { | |
612 | } | |
613 | ||
614 | public static class SampleMaps3 extends IntermediateMaps { | |
615 | Map good = new LinkedHashMap(); | |
616 | } | |
617 | ||
618 | public void testWithDoubleHiddenList() { | |
619 | SampleMaps3 sample = new SampleMaps3(); | |
620 | ((SampleMaps)sample).good = new LinkedHashMap(); | |
621 | ((SampleMaps)sample).good.put("Windows", new Software("Microsoft", "Windows")); | |
622 | ((SampleMaps)sample).good.put("Linux", new Software("Red Hat", "Linux")); | |
623 | ((SampleMaps2)sample).good.put("Android", new Software("Google", "Android")); | |
624 | ((SampleMaps2)sample).good.put("iOS", new Software("Apple", "iOS")); | |
625 | sample.good.put("Oracle", new Software("Oracle", "Oracle")); | |
626 | sample.good.put("Hana", new Software("SAP", "Hana")); | |
627 | sample.bad = null; | |
628 | ||
629 | String expected = "" + | |
630 | "<sample3>\n" + | |
631 | " <software defined-in=\"sample\">\n" + | |
632 | " <vendor>Microsoft</vendor>\n" + | |
633 | " <name>Windows</name>\n" + | |
634 | " </software>\n" + | |
635 | " <software defined-in=\"sample\">\n" + | |
636 | " <vendor>Red Hat</vendor>\n" + | |
637 | " <name>Linux</name>\n" + | |
638 | " </software>\n" + | |
639 | " <software defined-in=\"sample2\">\n" + | |
640 | " <vendor>Google</vendor>\n" + | |
641 | " <name>Android</name>\n" + | |
642 | " </software>\n" + | |
643 | " <software defined-in=\"sample2\">\n" + | |
644 | " <vendor>Apple</vendor>\n" + | |
645 | " <name>iOS</name>\n" + | |
646 | " </software>\n" + | |
647 | " <software>\n" + | |
648 | " <vendor>Oracle</vendor>\n" + | |
649 | " <name>Oracle</name>\n" + | |
650 | " </software>\n" + | |
651 | " <software>\n" + | |
652 | " <vendor>SAP</vendor>\n" + | |
653 | " <name>Hana</name>\n" + | |
654 | " </software>\n" + | |
655 | "</sample3>"; | |
656 | ||
657 | xstream.addImplicitMap(SampleMaps.class, "good", Software.class, "name"); | |
658 | xstream.addImplicitMap(SampleMaps2.class, "good", Software.class, "name"); | |
659 | xstream.addImplicitMap(SampleMaps3.class, "good", Software.class, "name"); | |
660 | assertBothWays(sample, expected); | |
661 | } | |
481 | 662 | |
482 | 663 | public void testCollectsDifferentTypesWithFieldOfSameName() { |
483 | 664 | SampleMaps sample = new SampleMaps(); |
484 | sample.good = new OrderRetainingMap(); | |
665 | sample.good = new LinkedHashMap(); | |
485 | 666 | sample.good.put("iPhone", new Product("iPhone", "i", 399.99)); |
486 | 667 | sample.good.put("Linux", new Software("Red Hat", "Linux")); |
487 | 668 | sample.good.put("Intel", new Hardware("i386", "Intel")); |
510 | 691 | |
511 | 692 | public void testSeparatesItemsBasedOnItemName() { |
512 | 693 | SampleMaps sample = new SampleMaps(); |
513 | sample.good = new OrderRetainingMap(); | |
694 | sample.good = new LinkedHashMap(); | |
514 | 695 | sample.good.put("Chrome", new Software("Google", "Chrome")); |
515 | sample.bad = new OrderRetainingMap(); | |
696 | sample.bad = new LinkedHashMap(); | |
516 | 697 | sample.bad.put("Linux", new Software("Red Hat", "Linux")); |
517 | 698 | sample.bad.put("Windows", new Software("Microsoft", "Windows")); |
518 | 699 | |
539 | 720 | |
540 | 721 | public void testWithoutKeyField() { |
541 | 722 | SampleMaps sample = new SampleMaps(); |
542 | sample.good = new OrderRetainingMap(); | |
723 | sample.good = new LinkedHashMap(); | |
543 | 724 | sample.good.put("Windows", new Software("Microsoft", "Windows")); |
544 | 725 | sample.good.put("Linux", new Software("Red Hat", "Linux")); |
545 | 726 | |
568 | 749 | |
569 | 750 | public void testCanUsePrimitiveAsKey() { |
570 | 751 | SampleMaps sample = new SampleMaps(); |
571 | sample.good = new OrderRetainingMap(); | |
752 | sample.good = new LinkedHashMap(); | |
572 | 753 | sample.good.put(new Double(399.99), new Product("iPhone", "i", 399.99)); |
573 | 754 | |
574 | 755 | String expected = "" + |
0 | 0 | /* |
1 | * Copyright (C) 2013 XStream Committers. | |
1 | * Copyright (C) 2013, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
10 | 10 | package com.thoughtworks.acceptance; |
11 | 11 | |
12 | 12 | import java.util.ArrayList; |
13 | import java.util.LinkedHashMap; | |
13 | 14 | import java.util.List; |
14 | 15 | import java.util.Map; |
15 | 16 | |
140 | 141 | c.val = new Integer(6); |
141 | 142 | implicits.cMap.put(c.val, c); |
142 | 143 | assertBothWays(implicits, expected); |
144 | implicits.separator1 = implicits.separator2 = null; | |
145 | assertBothWays(implicits, stripSeparator(expected)); | |
146 | implicits.separator1 = implicits.separator2 = null; | |
147 | assertBothWays(implicits, stripSeparator(expected)); | |
143 | 148 | } |
144 | 149 | |
145 | 150 | public void testAllImplicitTypesAtOnceWithExplicitElementNames() |
189 | 194 | c.val = new Integer(6); |
190 | 195 | implicits.cMap.put(c.val, c); |
191 | 196 | assertBothWays(implicits, expected); |
197 | implicits.separator1 = implicits.separator2 = null; | |
198 | assertBothWays(implicits, stripSeparator(expected)); | |
199 | } | |
200 | ||
201 | private String stripSeparator(String s) { | |
202 | return s.replaceAll(" *<separator.+</separator.+\n", ""); | |
203 | } | |
204 | ||
205 | public static class AllHidingTypes extends AllImplicitTypes { | |
206 | public String separator = "--X--"; | |
207 | public String aArray = "a"; | |
208 | public String bList = "b"; | |
209 | public String cMap = "c"; | |
210 | } | |
211 | ||
212 | public static class AllHidingImplicitTypes extends AllHidingTypes { | |
213 | public String separator = "--H--"; | |
214 | public A[] aArray = new A[2]; | |
215 | public List bList = new ArrayList(); | |
216 | public Map cMap = new LinkedHashMap(); | |
217 | } | |
218 | ||
219 | public void testHiddenImplicitTypesAtOnceWithExplicitElementNames() | |
220 | { | |
221 | xstream.alias("implicits", AllHidingImplicitTypes.class); | |
222 | xstream.alias("hiding", AllHidingTypes.class); | |
223 | xstream.alias("hidden", AllImplicitTypes.class); | |
224 | xstream.addDefaultImplementation(LinkedHashMap.class, Map.class); | |
225 | xstream.addImplicitArray(AllImplicitTypes.class, "aArray", "aHidden"); | |
226 | xstream.addImplicitArray(AllHidingImplicitTypes.class, "aArray", "a"); | |
227 | xstream.addImplicitCollection(AllImplicitTypes.class, "bList", "bHidden", AllImplicitTypes.B.class); | |
228 | xstream.addImplicitCollection(AllHidingImplicitTypes.class, "bList", "b", AllImplicitTypes.B.class); | |
229 | xstream.addImplicitMap(AllImplicitTypes.class, "cMap", "cHidden", AllImplicitTypes.C.class, "val"); | |
230 | xstream.addImplicitMap(AllHidingImplicitTypes.class, "cMap", "c", AllImplicitTypes.C.class, "val"); | |
231 | String expected = "" | |
232 | + "<implicits>\n" | |
233 | + " <aHidden defined-in=\"hidden\">\n" | |
234 | + " <val>1</val>\n" | |
235 | + " </aHidden>\n" | |
236 | + " <aHidden defined-in=\"hidden\">\n" | |
237 | + " <val>2</val>\n" | |
238 | + " </aHidden>\n" | |
239 | + " <separator1>--1--</separator1>\n" | |
240 | + " <bHidden defined-in=\"hidden\">\n" | |
241 | + " <val>3</val>\n" | |
242 | + " </bHidden>\n" | |
243 | + " <bHidden defined-in=\"hidden\">\n" | |
244 | + " <val>4</val>\n" | |
245 | + " </bHidden>\n" | |
246 | + " <separator2>--2--</separator2>\n" | |
247 | + " <cHidden defined-in=\"hidden\">\n" | |
248 | + " <val>5</val>\n" | |
249 | + " </cHidden>\n" | |
250 | + " <cHidden defined-in=\"hidden\">\n" | |
251 | + " <val>6</val>\n" | |
252 | + " </cHidden>\n" | |
253 | + " <separator defined-in=\"hiding\">--X--</separator>\n" | |
254 | + " <aArray defined-in=\"hiding\">a</aArray>\n" | |
255 | + " <bList defined-in=\"hiding\">b</bList>\n" | |
256 | + " <cMap defined-in=\"hiding\">c</cMap>\n" | |
257 | + " <separator>--H--</separator>\n" | |
258 | + " <a>\n" | |
259 | + " <val>7</val>\n" | |
260 | + " </a>\n" | |
261 | + " <a>\n" | |
262 | + " <val>8</val>\n" | |
263 | + " </a>\n" | |
264 | + " <b>\n" | |
265 | + " <val>9</val>\n" | |
266 | + " </b>\n" | |
267 | + " <b>\n" | |
268 | + " <val>10</val>\n" | |
269 | + " </b>\n" | |
270 | + " <c>\n" | |
271 | + " <val>11</val>\n" | |
272 | + " </c>\n" | |
273 | + " <c>\n" | |
274 | + " <val>12</val>\n" | |
275 | + " </c>\n" | |
276 | + "</implicits>"; | |
277 | ||
278 | AllHidingImplicitTypes implicits = new AllHidingImplicitTypes(); | |
279 | ((AllImplicitTypes)implicits).aArray[0] = new AllImplicitTypes.A(); | |
280 | ((AllImplicitTypes)implicits).aArray[0].val = 1; | |
281 | ((AllImplicitTypes)implicits).aArray[1] = new AllImplicitTypes.A(); | |
282 | ((AllImplicitTypes)implicits).aArray[1].val = 2; | |
283 | implicits.aArray[0] = new AllImplicitTypes.A(); | |
284 | implicits.aArray[0].val = 7; | |
285 | implicits.aArray[1] = new AllImplicitTypes.A(); | |
286 | implicits.aArray[1].val = 8; | |
287 | ((AllImplicitTypes)implicits).bList.add(new AllImplicitTypes.B()); | |
288 | ((AllImplicitTypes.B)((AllImplicitTypes)implicits).bList.get(0)).val = 3; | |
289 | ((AllImplicitTypes)implicits).bList.add(new AllImplicitTypes.B()); | |
290 | ((AllImplicitTypes.B)((AllImplicitTypes)implicits).bList.get(1)).val = 4; | |
291 | implicits.bList.add(new AllImplicitTypes.B()); | |
292 | ((AllImplicitTypes.B)implicits.bList.get(0)).val = 9; | |
293 | implicits.bList.add(new AllImplicitTypes.B()); | |
294 | ((AllImplicitTypes.B)implicits.bList.get(1)).val = 10; | |
295 | AllImplicitTypes.C c = new AllImplicitTypes.C(); | |
296 | c.val = new Integer(5); | |
297 | ((AllImplicitTypes)implicits).cMap.put(c.val, c); | |
298 | c = new AllImplicitTypes.C(); | |
299 | c.val = new Integer(6); | |
300 | ((AllImplicitTypes)implicits).cMap.put(c.val, c); | |
301 | c = new AllImplicitTypes.C(); | |
302 | c.val = new Integer(11); | |
303 | implicits.cMap.put(c.val, c); | |
304 | c = new AllImplicitTypes.C(); | |
305 | c.val = new Integer(12); | |
306 | implicits.cMap.put(c.val, c); | |
307 | assertBothWays(implicits, expected); | |
308 | implicits.separator1 = implicits.separator2 = ((AllHidingTypes)implicits).separator = implicits.separator = null; | |
309 | assertBothWays(implicits, stripSeparator(expected)); | |
192 | 310 | } |
193 | 311 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005, 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2014 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2014, 2015 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 31. January 2005 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.acceptance; |
12 | ||
13 | import com.thoughtworks.xstream.core.JVM; | |
12 | 14 | |
13 | 15 | public class InnerClassesTest extends AbstractAcceptanceTest { |
14 | 16 | |
15 | 17 | public void testSerializedInnerClassMaintainsReferenceToOuterClass() { |
16 | 18 | xstream.allowTypes(new Class[]{Outer.class, Outer.Inner.class}); |
17 | 19 | |
18 | Outer outer = new Outer("THE-OUTER-NAME", "THE-INNER-NAME"); | |
19 | Outer.Inner inner = outer.getInner(); | |
20 | final Outer outer = new Outer("THE-OUTER-NAME", "THE-INNER-NAME"); | |
21 | final Outer.Inner inner = outer.getInner(); | |
20 | 22 | |
21 | 23 | assertEquals("Hello from THE-INNER-NAME (inside THE-OUTER-NAME)", inner.getMessage()); |
22 | 24 | |
23 | String xml = xstream.toXML(inner); | |
25 | final String xml = xstream.toXML(inner); | |
24 | 26 | |
25 | String expectedXml = "" | |
27 | final String expectedXml = "" | |
26 | 28 | + "<com.thoughtworks.acceptance.Outer_-Inner>\n" |
27 | 29 | + " <innerName>THE-INNER-NAME</innerName>\n" |
28 | 30 | + " <outer-class>\n" |
32 | 34 | + "</com.thoughtworks.acceptance.Outer_-Inner>"; |
33 | 35 | assertEquals(expectedXml, xml); |
34 | 36 | |
35 | Outer.Inner newInner = (Outer.Inner) xstream.fromXML(xml); | |
37 | final Outer.Inner newInner = (Outer.Inner)xstream.fromXML(xml); | |
36 | 38 | |
37 | 39 | assertEquals("Hello from THE-INNER-NAME (inside THE-OUTER-NAME)", newInner.getMessage()); |
40 | } | |
41 | ||
42 | public static class OuterType { | |
43 | private final String outerName = "Outer Name"; | |
44 | public InnerType inner = new InnerType(); | |
45 | private final InnerType.Dynamic1 dyn1 = inner.new Dynamic1(); | |
46 | private final InnerType.Dynamic1.Dynamic2 dyn2 = dyn1.new Dynamic2(); | |
47 | private final InnerType.Dynamic3 dyn3 = inner.new Dynamic3(dyn1); | |
48 | ||
49 | public class InnerType { | |
50 | private final String innerName = "Inner Name"; | |
51 | ||
52 | public class Dynamic1 { | |
53 | private final String name1 = "Name 1"; | |
54 | ||
55 | public class Dynamic2 { | |
56 | private final String name2 = "Name 2"; | |
57 | } | |
58 | } | |
59 | ||
60 | public class Dynamic3 extends Dynamic1.Dynamic2 { | |
61 | private final String name3 = "Name 3"; | |
62 | final Dynamic1.Dynamic2 dyn4; | |
63 | ||
64 | public Dynamic3(final Dynamic1 outer) { | |
65 | outer.super(); | |
66 | class Dynamic4 extends Dynamic1.Dynamic2 { | |
67 | private final String name4 = "Name 4"; | |
68 | private final Dynamic5 dyn5 = new Dynamic5(); | |
69 | class Dynamic5 { | |
70 | private final String name5 = "Name 5"; | |
71 | } | |
72 | Dynamic4(Dynamic1 outer) { | |
73 | outer.super(); | |
74 | } | |
75 | } | |
76 | dyn4 = new Dynamic4(outer); | |
77 | } | |
78 | } | |
79 | } | |
80 | } | |
81 | ||
82 | public void testNestedDynamicTypes() { | |
83 | final OuterType outer = new OuterType(); | |
84 | ||
85 | xstream.alias("inner", OuterType.InnerType.class); | |
86 | xstream.alias("Dynamic4", outer.dyn3.dyn4.getClass()); | |
87 | ||
88 | String expectedXml = "" | |
89 | + "<inner>\n" | |
90 | + " <innerName>Inner Name</innerName>\n" | |
91 | + " <outer-class>\n" | |
92 | + " <outerName>Outer Name</outerName>\n" | |
93 | + " <inner reference=\"../..\"/>\n" | |
94 | + " <dyn1>\n" | |
95 | + " <name1>Name 1</name1>\n" | |
96 | + " <outer-class reference=\"../../..\"/>\n" | |
97 | + " </dyn1>\n" | |
98 | + " <dyn2>\n" | |
99 | + " <name2>Name 2</name2>\n" | |
100 | + " <outer-class reference=\"../../dyn1\"/>\n" | |
101 | + " </dyn2>\n" | |
102 | + " <dyn3>\n" | |
103 | + " <name2>Name 2</name2>\n" | |
104 | + " <outer-class reference=\"../../dyn1\"/>\n" | |
105 | + " <name3>Name 3</name3>\n" | |
106 | + " <dyn4 class=\"Dynamic4\">\n" | |
107 | + " <name2>Name 2</name2>\n" | |
108 | + " <outer-class defined-in=\"com.thoughtworks.acceptance.InnerClassesTest$OuterType$InnerType$Dynamic1$Dynamic2\" reference=\"../../../dyn1\"/>\n" | |
109 | + " <name4>Name 4</name4>\n" | |
110 | + " <dyn5>\n" | |
111 | + " <name5>Name 5</name5>\n" | |
112 | + " <outer-class reference=\"../..\"/>\n" | |
113 | + " </dyn5>\n" | |
114 | + " <outer-class reference=\"../..\"/>\n" | |
115 | + " </dyn4>\n" | |
116 | + " <outer-class-1 reference=\"../../..\"/>\n" | |
117 | + " </dyn3>\n" | |
118 | + " </outer-class>\n" | |
119 | + "</inner>"; | |
120 | ||
121 | assertBothWays(outer.inner, expectedXml); | |
38 | 122 | } |
39 | 123 | } |
40 | 124 | |
41 | 125 | class Outer { |
42 | 126 | |
43 | private Inner inner; | |
44 | private String outerName; | |
127 | private final Inner inner; | |
128 | private final String outerName; | |
45 | 129 | |
46 | public Outer(String outerName, String innerName) { | |
130 | public Outer(final String outerName, final String innerName) { | |
47 | 131 | inner = new Inner(innerName); |
48 | 132 | this.outerName = outerName; |
49 | 133 | } |
53 | 137 | } |
54 | 138 | |
55 | 139 | public class Inner { |
56 | private String innerName; | |
140 | private final String innerName; | |
57 | 141 | |
58 | public Inner(String innerName) { | |
142 | public Inner(final String innerName) { | |
59 | 143 | this.innerName = innerName; |
60 | 144 | } |
61 | 145 | |
64 | 148 | } |
65 | 149 | } |
66 | 150 | } |
67 | ||
68 |
0 | 0 | /* |
1 | * Copyright (C) 2013 XStream Committers. | |
1 | * Copyright (C) 2013, 2016 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
10 | 10 | package com.thoughtworks.acceptance; |
11 | 11 | |
12 | 12 | import java.util.ArrayList; |
13 | import java.util.Calendar; | |
14 | import java.util.Date; | |
13 | 15 | import java.util.LinkedHashMap; |
14 | 16 | import java.util.List; |
17 | import java.util.Locale; | |
15 | 18 | import java.util.Map; |
19 | import java.util.TimeZone; | |
16 | 20 | |
17 | 21 | import com.thoughtworks.acceptance.objects.Category; |
18 | 22 | import com.thoughtworks.acceptance.objects.SampleMaps; |
383 | 387 | public void testMapElementsUsingAttributeAndText() { |
384 | 388 | xstream.registerLocalConverter( |
385 | 389 | SampleMaps.class, "good", new NamedMapConverter( |
386 | xstream.getMapper(), "product", "name", String.class, null, String.class, | |
390 | xstream.getMapper(), "product", "name", String.class, null, Date.class, | |
387 | 391 | true, false, xstream.getConverterLookup())); |
388 | ||
389 | SampleMaps maps = new SampleMaps(); | |
390 | maps.bad = null; | |
391 | maps.good = new LinkedHashMap(); | |
392 | maps.good.put("SiteMesh", "com.opensymphony"); | |
393 | maps.good.put("XStream", "com.thoughtworks"); | |
394 | ||
395 | String expected = ("" | |
396 | + "<maps>\n" | |
397 | + " <products>\n" | |
398 | + " <product name='SiteMesh'>com.opensymphony</product>\n" | |
399 | + " <product name='XStream'>com.thoughtworks</product>\n" | |
392 | ||
393 | Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.GERMANY); | |
394 | cal.clear(); | |
395 | cal.set(2016, Calendar.FEBRUARY, 8, 20, 11, 10); | |
396 | SampleMaps maps = new SampleMaps(); | |
397 | maps.bad = null; | |
398 | maps.good = new LinkedHashMap(); | |
399 | maps.good.put("SiteMesh", cal.getTime()); | |
400 | cal.add(Calendar.DAY_OF_MONTH, 1); | |
401 | maps.good.put("XStream", cal.getTime()); | |
402 | ||
403 | String expected = ("" | |
404 | + "<maps>\n" | |
405 | + " <products>\n" | |
406 | + " <product name='SiteMesh'>2016-02-08 20:11:10.0 UTC</product>\n" | |
407 | + " <product name='XStream'>2016-02-09 20:11:10.0 UTC</product>\n" | |
400 | 408 | + " </products>\n" |
401 | 409 | + "</maps>").replace('\'', '"'); |
402 | 410 |
0 | 0 | /* |
1 | * Copyright (C) 2006, 2007, 2009, 2010, 2013 XStream Committers. | |
1 | * Copyright (C) 2006, 2007, 2009, 2010, 2013, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
183 | 183 | sm.addPermission(source, new PropertyPermission("jdk.xml.maxGeneralEntitySizeLimit", "read")); |
184 | 184 | sm.addPermission(source, new PropertyPermission("jdk.xml.maxParameterEntitySizeLimit", "read")); |
185 | 185 | sm.addPermission(source, new PropertyPermission("jdk.xml.maxOccurLimit", "read")); |
186 | sm.addPermission(source, new PropertyPermission("jdk.xml.maxXMLNameLimit", "read")); | |
186 | 187 | sm.addPermission(source, new PropertyPermission("jdk.xml.totalEntitySizeLimit", "read")); |
187 | 188 | sm.addPermission(source, new PropertyPermission("maxOccurLimit", "read")); |
188 | 189 | sm.addPermission(source, new PropertyPermission("sun.boot.class.path", "read")); |
0 | 0 | <?xml version="1.0"?> |
1 | 1 | <!-- |
2 | Copyright (C) 2006, 2007, 2008, 2014 XStream Committers. | |
2 | Copyright (C) 2006, 2007, 2008, 2014, 2015 XStream Committers. | |
3 | 3 | All rights reserved. |
4 | 4 | |
5 | 5 | The software in this package is published under the terms of the BSD |
9 | 9 | Created on 30. March 2006 by Joerg Schaible |
10 | 10 | --> |
11 | 11 | <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> |
12 | <xsl:template match="immutableTypes"> | |
12 | <xsl:template match="immutableTypes|unreferenceableTypes"> | |
13 | 13 | <xsl:copy> |
14 | 14 | <xsl:apply-templates select="java-class"> |
15 | 15 | <xsl:sort/> |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 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.acceptance.annotations; |
12 | 12 | |
13 | 13 | import com.thoughtworks.acceptance.AbstractAcceptanceTest; |
14 | import com.thoughtworks.xstream.InitializationException; | |
14 | 15 | import com.thoughtworks.xstream.XStream; |
16 | import com.thoughtworks.xstream.XStreamException; | |
15 | 17 | import com.thoughtworks.xstream.annotations.XStreamAsAttribute; |
16 | 18 | import com.thoughtworks.xstream.annotations.XStreamConverter; |
17 | 19 | import com.thoughtworks.xstream.converters.Converter; |
18 | 20 | import com.thoughtworks.xstream.converters.MarshallingContext; |
19 | 21 | import com.thoughtworks.xstream.converters.SingleValueConverter; |
20 | 22 | import com.thoughtworks.xstream.converters.UnmarshallingContext; |
23 | import com.thoughtworks.xstream.converters.enums.EnumToStringConverter; | |
21 | 24 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
22 | 25 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; |
23 | 26 | |
229 | 232 | assertEquals(before + 1, after); |
230 | 233 | } |
231 | 234 | |
235 | @XStreamConverter(EnumToStringConverter.class) | |
236 | public static class InvalidForConverter { | |
237 | } | |
238 | ||
239 | public void testCausingExceptionIsNotSuppressed() { | |
240 | try { | |
241 | toXML(new InvalidForConverter()); | |
242 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
243 | } catch (final XStreamException e) { | |
244 | Throwable th = e.getCause(); | |
245 | for(;;) { | |
246 | th = th.getCause(); | |
247 | assertNotNull("No causing InitializationException.", th); | |
248 | if (th instanceof InitializationException) { | |
249 | assertTrue("No hint for enum types only", th.getMessage().indexOf(" enum ") >= 0); | |
250 | break; | |
251 | } | |
252 | } | |
253 | } | |
254 | } | |
232 | 255 | } |
+96
-1
0 | 0 | /* |
1 | * Copyright (C) 2008, 2009, 2011, 2012, 2013 XStream Committers. | |
1 | * Copyright (C) 2008, 2009, 2011, 2012, 2013, 2015, 2016 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
10 | 10 | package com.thoughtworks.acceptance.annotations; |
11 | 11 | |
12 | 12 | import java.math.BigDecimal; |
13 | import java.util.ArrayList; | |
14 | import java.util.Arrays; | |
13 | 15 | import java.util.HashMap; |
14 | 16 | import java.util.LinkedHashMap; |
17 | import java.util.List; | |
15 | 18 | import java.util.Map; |
16 | 19 | |
17 | 20 | import com.thoughtworks.acceptance.AbstractAcceptanceTest; |
23 | 26 | import com.thoughtworks.xstream.annotations.XStreamInclude; |
24 | 27 | import com.thoughtworks.xstream.converters.basic.BooleanConverter; |
25 | 28 | import com.thoughtworks.xstream.converters.collections.MapConverter; |
29 | import com.thoughtworks.xstream.converters.extended.NamedCollectionConverter; | |
26 | 30 | import com.thoughtworks.xstream.converters.extended.NamedMapConverter; |
27 | 31 | import com.thoughtworks.xstream.converters.extended.ToAttributedValueConverter; |
28 | 32 | import com.thoughtworks.xstream.converters.extended.ToStringConverter; |
52 | 56 | xstream.alias("decimal", Decimal.class); |
53 | 57 | xstream.alias("type", Type.class); |
54 | 58 | xstream.processAnnotations(MyMap.class); |
59 | xstream.processAnnotations(MyType.class); | |
55 | 60 | xstream.processAnnotations(DerivedType.class); |
61 | xstream.processAnnotations(DerivedType2.class); | |
56 | 62 | xstream.processAnnotations(SimpleBean.class); |
57 | 63 | xstream.processAnnotations(ContainsMap.class); |
64 | xstream.processAnnotations(ContainsMap2.class); | |
65 | xstream.processAnnotations(ContainsCollection.class); | |
58 | 66 | } |
59 | 67 | |
60 | 68 | public void testAnnotationForConvertersWithParameters() { |
140 | 148 | } |
141 | 149 | } |
142 | 150 | |
151 | public void testConverterRequiringNull() { | |
152 | final Type value = new DerivedType(new Decimal("1.5"), new Boolean(true), DerivedType.E.FOO); | |
153 | String expected = "<dtype boolean='true' agreement='yes' enum='FOO'>1.5</dtype>".replace('\'', '"'); | |
154 | assertBothWays(value, expected); | |
155 | } | |
156 | ||
157 | @XStreamAlias("mytype") | |
158 | @XStreamConverter(value=ToAttributedValueConverter.class, types={Type.class}, nulls={String.class}) | |
159 | public static class MyType extends Type { | |
160 | public MyType(Decimal decimal, Boolean bool) { | |
161 | super(decimal, bool); | |
162 | } | |
163 | } | |
164 | ||
143 | 165 | public void testConverterWithSecondTypeParameter() { |
144 | 166 | final Type value = new DerivedType(new Decimal("1.5"), new Boolean(true), DerivedType.E.FOO); |
145 | 167 | String expected = "<dtype boolean='true' agreement='yes' enum='FOO'>1.5</dtype>".replace('\'', '"'); |
154 | 176 | private E e; |
155 | 177 | |
156 | 178 | public DerivedType(Decimal decimal, Boolean bool, E e) { |
179 | super(decimal, bool); | |
180 | this.e = e; | |
181 | } | |
182 | } | |
183 | ||
184 | public void testConverterWithAllAttributes() { | |
185 | final Type value = new DerivedType2(new Decimal("1.5"), new Boolean(true), DerivedType2.E.FOO); | |
186 | String expected = "<dtype2 decimal='1.5' boolean='true' agreement='yes' enum='FOO'/>".replace('\'', '"'); | |
187 | assertBothWays(value, expected); | |
188 | } | |
189 | ||
190 | @XStreamAlias("dtype2") | |
191 | @XStreamConverter(value=ToAttributedValueConverter.class) | |
192 | public static class DerivedType2 extends Type { | |
193 | public enum E { FOO, BAR }; | |
194 | @XStreamAlias("enum") | |
195 | private E e; | |
196 | ||
197 | public DerivedType2(Decimal decimal, Boolean bool, E e) { | |
157 | 198 | super(decimal, bool); |
158 | 199 | this.e = e; |
159 | 200 | } |
213 | 254 | this.map = map; |
214 | 255 | } |
215 | 256 | } |
257 | ||
258 | public void testAnnotatedNamedMapConverterWithMultipleSameArguments() { | |
259 | xstream.addDefaultImplementation(LinkedHashMap.class, Map.class); | |
260 | ||
261 | final Map<String, String> map = new LinkedHashMap<String, String>(); | |
262 | map.put("FOO", "foo"); | |
263 | map.put("BAR", "bar"); | |
264 | final ContainsMap2 value = new ContainsMap2(map); | |
265 | String expected = ("" | |
266 | + "<container-map>\n" | |
267 | + " <map>\n" | |
268 | + " <key>FOO</key>\n" | |
269 | + " <value>foo</value>\n" | |
270 | + " <key>BAR</key>\n" | |
271 | + " <value>bar</value>\n" | |
272 | + " </map>\n" | |
273 | + "</container-map>").replace('\'', '"'); | |
274 | assertBothWays(value, expected); | |
275 | } | |
276 | ||
277 | @XStreamAlias("container-map") | |
278 | public static class ContainsMap2 extends StandardObject { | |
279 | @XStreamConverter(value = NamedMapConverter.class, strings = {"", "key", "value"}, types = { | |
280 | LinkedHashMap.class, String.class, String.class}, booleans = {false, false}, useImplicitType = false) | |
281 | private Map<String, String> map; | |
282 | ||
283 | public ContainsMap2(Map<String, String> map) { | |
284 | this.map = map; | |
285 | } | |
286 | } | |
216 | 287 | |
217 | 288 | @XStreamAlias("my-enums") |
218 | 289 | public static class MyEnumMap extends LinkedHashMap<ContainsMap.E, String> { |
219 | 290 | } |
291 | ||
292 | public void testAnnotatedNamedCollectionConverter() { | |
293 | List<String> names = new ArrayList<String>(Arrays.asList("joe", "joerg", "mauro")); | |
294 | final ContainsCollection container = new ContainsCollection(names); | |
295 | String expected = ("" | |
296 | + "<CollCont>\n" | |
297 | + " <names>\n" | |
298 | + " <name>joe</name>\n" | |
299 | + " <name>joerg</name>\n" | |
300 | + " <name>mauro</name>\n" | |
301 | + " </names>\n" | |
302 | + "</CollCont>").replace('\'', '"'); | |
303 | assertBothWays(container, expected); | |
304 | } | |
305 | ||
306 | @XStreamAlias("CollCont") | |
307 | public static class ContainsCollection extends StandardObject { | |
308 | @XStreamConverter(value=NamedCollectionConverter.class, strings={"name"}, types={String.class}, useImplicitType = false) | |
309 | private List<String> names; | |
310 | ||
311 | public ContainsCollection(List<String> names) { | |
312 | this.names = names; | |
313 | } | |
314 | } | |
220 | 315 | } |
15 | 15 | * |
16 | 16 | * @author <a href="mailto:jason@maven.org">Jason van Zyl</a> |
17 | 17 | * |
18 | * @version $Id: Handler.java 2034 2013-03-12 22:15:00Z joehni $ | |
18 | * @version $Id$ | |
19 | 19 | */ |
20 | 20 | public class Handler |
21 | 21 | { |
17 | 17 | * |
18 | 18 | * @author <a href="mailto:jason@maven.org">Jason van Zyl</a> |
19 | 19 | * |
20 | * @version $Id: HandlerManager.java 1345 2007-12-11 01:50:12Z joehni $ | |
20 | * @version $Id$ | |
21 | 21 | */ |
22 | 22 | public class HandlerManager |
23 | 23 | { |
15 | 15 | * |
16 | 16 | * @author <a href="mailto:jason@maven.org">Jason van Zyl</a> |
17 | 17 | * |
18 | * @version $Id: Protocol.java 2034 2013-03-12 22:15:00Z joehni $ | |
18 | * @version $Id$ | |
19 | 19 | */ |
20 | 20 | public class Protocol |
21 | 21 | { |
0 | 0 | /* |
1 | * Copyright (C) 2006, 2007 XStream Committers. | |
1 | * Copyright (C) 2006, 2007, 2016 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
42 | 42 | StringTokenizer tokenizer = new StringTokenizer(ex.getMessage(), "\n\r"); |
43 | 43 | tokenizer.nextToken(); |
44 | 44 | tokenizer.nextToken(); |
45 | assertEquals("message : Message", tokenizer.nextToken()); | |
45 | 46 | assertEquals("1st : first", tokenizer.nextToken()); |
46 | 47 | assertEquals("2nd : second", tokenizer.nextToken()); |
47 | 48 | assertEquals("3rd : third", tokenizer.nextToken()); |
+56
-0
0 | /* | |
1 | * Copyright (C) 2015 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 23.06.2015 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.converters.extended; | |
11 | ||
12 | import java.awt.datatransfer.DataFlavor; | |
13 | ||
14 | import javax.activation.ActivationDataFlavor; | |
15 | ||
16 | import com.thoughtworks.acceptance.AbstractAcceptanceTest; | |
17 | import com.thoughtworks.xstream.XStream; | |
18 | ||
19 | ||
20 | public class ActivationDataFlavorConverterTest extends AbstractAcceptanceTest { | |
21 | ||
22 | protected void setupSecurity(XStream xstream) { | |
23 | super.setupSecurity(xstream); | |
24 | xstream.allowTypeHierarchy(DataFlavor.class); | |
25 | } | |
26 | ||
27 | public void testMimeTypeOnly() { | |
28 | final String expected = "" | |
29 | + "<activation-data-flavor>\n" | |
30 | + " <mimeType>application/x-junit</mimeType>\n" | |
31 | + " <representationClass>java.io.InputStream</representationClass>\n" | |
32 | + "</activation-data-flavor>"; | |
33 | assertBothWays(new ActivationDataFlavor("application/x-junit", null), expected); | |
34 | } | |
35 | ||
36 | public void testMimeTypeAndRepresentation() { | |
37 | final String expected = "" | |
38 | + "<activation-data-flavor>\n" | |
39 | + " <mimeType>application/x-junit</mimeType>\n" | |
40 | + " <humanRepresentableName>JUnit</humanRepresentableName>\n" | |
41 | + " <representationClass>java.io.InputStream</representationClass>\n" | |
42 | + "</activation-data-flavor>"; | |
43 | assertBothWays(new ActivationDataFlavor("application/x-junit", "JUnit"), expected); | |
44 | } | |
45 | ||
46 | public void testWithAllArguments() { | |
47 | final String expected = "" | |
48 | + "<activation-data-flavor>\n" | |
49 | + " <mimeType>application/x-junit</mimeType>\n" | |
50 | + " <humanRepresentableName>JUnit</humanRepresentableName>\n" | |
51 | + " <representationClass>com.thoughtworks.xstream.converters.extended.ActivationDataFlavorConverterTest</representationClass>\n" | |
52 | + "</activation-data-flavor>"; | |
53 | assertBothWays(new ActivationDataFlavor(ActivationDataFlavorConverterTest.class, "application/x-junit", "JUnit"), expected); | |
54 | } | |
55 | } |
+1
-1
46 | 46 | /** |
47 | 47 | * Tests {@link ToAttributedValueConverter}. |
48 | 48 | * |
49 | * @author jos / last modified by $Author: joehni $ | |
49 | * @author jos / last modified by $Author$ | |
50 | 50 | */ |
51 | 51 | public class ToAttributedValueConverterTest extends TestCase { |
52 | 52 | private HierarchicalStreamDriver driver; |
+37
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2013, 2014, 2015 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 | assertEquals(expected, result); |
201 | 201 | } |
202 | 202 | |
203 | public void testSerializesNullValue() { | |
204 | World world = new World(); | |
205 | world.setAString(null); | |
206 | ||
207 | XStream xstream = new XStream(); | |
208 | xstream.registerConverter(new JavaBeanConverter(xstream.getMapper(), new BeanProvider( | |
209 | new StringComparator())), XStream.PRIORITY_LOW); | |
210 | xstream.alias("world", World.class); | |
211 | ||
212 | String expected = "" | |
213 | + "<world>\n" | |
214 | + " <ABool>true</ABool>\n" | |
215 | + " <ABoolean>false</ABoolean>\n" | |
216 | + " <AByte>4</AByte>\n" | |
217 | + " <AByteClass>5</AByteClass>\n" | |
218 | + " <AChar>a</AChar>\n" | |
219 | + " <ACharacter>w</ACharacter>\n" | |
220 | + " <AFloat>8.0</AFloat>\n" | |
221 | + " <AFloatClass>9.0</AFloatClass>\n" | |
222 | + " <ALong>10</ALong>\n" | |
223 | + " <ALongClass>11</ALongClass>\n" | |
224 | + " <anInt>1</anInt>\n" | |
225 | + " <anInteger>2</anInteger>\n" | |
226 | + " <AShort>6</AShort>\n" | |
227 | + " <AShortClass>7</AShortClass>\n" | |
228 | + " <AString class=\"null\"/>\n" | |
229 | + "</world>"; | |
230 | ||
231 | String result = xstream.toXML(world); | |
232 | ||
233 | assertEquals(expected, result); | |
234 | ||
235 | World world2 = (World) xstream.fromXML(result); | |
236 | assertEquals(null, world2.getAString()); | |
237 | } | |
238 | ||
203 | 239 | /** |
204 | 240 | * Only normal and trans are serializable properties, the field modifiers do not matter |
205 | 241 | */ |
+119
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2015 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 | |
15 | 15 | import java.lang.reflect.Field; |
16 | 16 | import java.lang.reflect.Modifier; |
17 | import java.util.ArrayList; | |
18 | import java.util.Arrays; | |
19 | import java.util.Collections; | |
20 | import java.util.HashMap; | |
17 | 21 | import java.util.Iterator; |
22 | import java.util.List; | |
23 | ||
24 | import com.thoughtworks.xstream.core.JVM; | |
18 | 25 | |
19 | 26 | public class FieldDictionaryTest extends TestCase { |
20 | 27 | |
77 | 84 | } |
78 | 85 | return field.getName(); |
79 | 86 | } |
87 | ||
88 | private static class AssertNoDuplicateHashMap extends HashMap { | |
89 | public Object put(final Object key, final Object value) { | |
90 | assertFalse("Attempt to insert duplicate key: " + key, containsKey(key)); | |
91 | return super.put(key, value); | |
92 | } | |
93 | } | |
94 | ||
95 | static class A { String a; } | |
96 | static class B extends A { String b; } | |
97 | static class C extends B { String c; } | |
98 | static class D extends C { String d; } | |
99 | static class E extends D { String e; } | |
100 | static class F extends E { String f; } | |
101 | static class G extends F { String g; } | |
102 | static class H extends G { String h; } | |
103 | static class I extends H { String i; } | |
104 | static class J extends I { String j; } | |
105 | static class BB extends B { String b; } | |
106 | static class CC extends C { String c; } | |
107 | static class DD extends D { String d; } | |
108 | static class EE extends E { String e; } | |
109 | static class FF extends F { String f; } | |
110 | static class GG extends G { String g; } | |
111 | static class HH extends H { String h; } | |
112 | static class II extends I { String i; } | |
113 | static class JJ extends J { String j; } | |
114 | static class JJJ extends JJ { String j; } | |
115 | ||
116 | public void testSynchronizedAccessShouldEnsureEachClassAddedOnceToCache() throws Exception { | |
117 | AssertNoDuplicateHashMap assertNoDuplicateHashMap = new AssertNoDuplicateHashMap(); | |
118 | ||
119 | Field field = FieldDictionary.class.getDeclaredField("dictionaryEntries"); | |
120 | field.setAccessible(true); | |
121 | field.set(fieldDictionary, assertNoDuplicateHashMap); | |
122 | ||
123 | final List exceptions = Collections.synchronizedList(new ArrayList()); | |
124 | ||
125 | final List types = | |
126 | Arrays.asList(new Class[] { | |
127 | A.class, B.class, C.class, E.class, F.class, G.class, H.class, I.class, J.class, | |
128 | BB.class, CC.class, DD.class, EE.class, FF.class, GG.class, HH.class, II.class, JJ.class, | |
129 | JJJ.class, FieldDictionaryTest.class | |
130 | }); | |
131 | final Thread[] threads = createThreads(types, exceptions); | |
132 | ||
133 | for (int i = 0; i < threads.length; ++i) { | |
134 | synchronized (threads[i]) { | |
135 | threads[i].start(); | |
136 | threads[i].wait(); | |
137 | } | |
138 | } | |
139 | ||
140 | for (int i = 0; i < threads.length; ++i) { | |
141 | synchronized (threads[i]) { | |
142 | threads[i].notifyAll(); | |
143 | } | |
144 | } | |
145 | ||
146 | Thread.sleep(1500); | |
147 | ||
148 | for (int i = 0; i < threads.length; ++i) { | |
149 | threads[i].interrupt(); | |
150 | } | |
151 | for (int i = 0; i < threads.length; ++i) { | |
152 | synchronized (threads[i]) { | |
153 | threads[i].join(); | |
154 | } | |
155 | } | |
156 | ||
157 | assertEquals("Assertions failed or exceptions thrown", Collections.EMPTY_LIST, exceptions); | |
158 | } | |
159 | ||
160 | private Thread[] createThreads(final List types, final List exceptions) { | |
161 | Collections.shuffle(types); | |
162 | final Thread[] threads = new Thread[types.size()]; | |
163 | for (int i = 0; i < types.size(); i++) { | |
164 | final Class type = (Class)types.get(i); | |
165 | threads[i] = new Thread() { | |
166 | public void run() { | |
167 | try { | |
168 | synchronized (this) { | |
169 | notifyAll(); | |
170 | wait(); | |
171 | } | |
172 | final Iterator fieldIterator = fieldDictionary.fieldsFor(type); | |
173 | int fieldCount = 0; | |
174 | while (fieldIterator.hasNext()) { | |
175 | Field field = (Field)fieldIterator.next(); | |
176 | if (JVM.is15() || !Modifier.isStatic(field.getModifiers())) { | |
177 | fieldCount++; | |
178 | } | |
179 | } | |
180 | ||
181 | if (type == FieldDictionaryTest.class) { | |
182 | assertEquals("fieldCount not equal for type " + type.getName(), 2, fieldCount); | |
183 | } else { | |
184 | int count = 0; | |
185 | for(Class cls = type; cls != null; count++, cls = cls.getSuperclass()); | |
186 | assertEquals("fieldCount not equal for type " + type.getName(), count-1, fieldCount); | |
187 | } | |
188 | } catch (final Exception e) { | |
189 | exceptions.add(e); | |
190 | } catch (final Error e) { | |
191 | exceptions.add(e); | |
192 | } | |
193 | } | |
194 | }; | |
195 | } | |
196 | return threads; | |
197 | } | |
80 | 198 | } |
+4
-4
0 | 0 | /* |
1 | * Copyright (C) 2007 XStream Committers. | |
1 | * Copyright (C) 2007, 2016 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.lang.reflect.Field; |
13 | 13 | import java.util.Map; |
14 | 14 | |
15 | import com.thoughtworks.xstream.converters.ConversionException; | |
15 | 16 | import com.thoughtworks.xstream.core.util.OrderRetainingMap; |
16 | import com.thoughtworks.xstream.io.StreamException; | |
17 | 17 | |
18 | 18 | import junit.framework.TestCase; |
19 | 19 | |
48 | 48 | try { |
49 | 49 | sorter.sort(Base.class, buildMap(Base.class)); |
50 | 50 | fail(); |
51 | } catch (StreamException ex) { | |
52 | // ok | |
51 | } catch (ConversionException ex) { | |
52 | assertEquals(Base.class.getName(), ex.get("sort-type")); | |
53 | 53 | } |
54 | 54 | } |
55 | 55 |
+143
-2
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2015 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.AbstractAcceptanceTest; |
14 | 14 | import com.thoughtworks.acceptance.objects.StandardObject; |
15 | 15 | import com.thoughtworks.xstream.XStream; |
16 | ||
16 | import com.thoughtworks.xstream.converters.ConverterLookup; | |
17 | import com.thoughtworks.xstream.core.util.ObjectIdDictionary; | |
18 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; | |
19 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; | |
20 | import com.thoughtworks.xstream.io.path.Path; | |
21 | import com.thoughtworks.xstream.mapper.Mapper; | |
22 | ||
23 | import java.lang.reflect.Field; | |
24 | import java.net.MalformedURLException; | |
25 | import java.net.URL; | |
17 | 26 | import java.util.ArrayList; |
18 | 27 | import java.util.List; |
28 | import java.util.Map; | |
19 | 29 | |
20 | 30 | |
21 | 31 | public class ReferenceByXPathMarshallingStrategyTest extends AbstractAcceptanceTest { |
87 | 97 | |
88 | 98 | assertBothWays(list, expected); |
89 | 99 | } |
100 | ||
101 | public class CountingXPathStrategy extends ReferenceByXPathMarshallingStrategy{ | |
102 | ||
103 | public CountingXPathStrategy() { | |
104 | super(ReferenceByXPathMarshallingStrategy.ABSOLUTE); | |
105 | } | |
106 | ||
107 | public ReferenceByXPathMarshaller requestedMarshaller; | |
108 | public ReferenceByXPathUnmarshaller requestedUnmarshaller; | |
109 | ||
110 | protected TreeUnmarshaller createUnmarshallingContext(Object root, | |
111 | HierarchicalStreamReader reader, | |
112 | ConverterLookup converterLookup, | |
113 | Mapper mapper) { | |
114 | ||
115 | assertNull("strategy can only make one unmarshaller", requestedUnmarshaller); | |
116 | requestedUnmarshaller = (ReferenceByXPathUnmarshaller) super.createUnmarshallingContext(root, reader, converterLookup, mapper); | |
117 | return requestedUnmarshaller; | |
118 | } | |
119 | ||
120 | protected TreeMarshaller createMarshallingContext(HierarchicalStreamWriter writer, | |
121 | ConverterLookup converterLookup, | |
122 | Mapper mapper) { | |
123 | ||
124 | assertNull("strategy can only make one marshaller", requestedMarshaller); | |
125 | requestedMarshaller = (ReferenceByXPathMarshaller) super.createMarshallingContext(writer, converterLookup, mapper); | |
126 | return requestedMarshaller; | |
127 | } | |
128 | } | |
129 | ||
130 | public void testDoNotKeepXPathMapForImmutablesOnMarshall() throws MalformedURLException { | |
131 | //configure XStream | |
132 | CountingXPathStrategy marshallingStrategy = new CountingXPathStrategy(); | |
133 | xstream.setMarshallingStrategy(marshallingStrategy); | |
134 | ||
135 | //setup document | |
136 | List list = new ArrayList(); | |
137 | URL url = new URL("http://jira.codehaus.org/browse"); | |
138 | list.add(url); | |
139 | list.add(url); | |
140 | ||
141 | //act | |
142 | String serialized = xstream.toXML(list); | |
143 | ||
144 | //assert | |
145 | ObjectIdDictionary trackedPathsOnMarshal = getReferences(marshallingStrategy.requestedMarshaller); | |
146 | ||
147 | assertTrue(trackedPathsOnMarshal.containsId(list)); | |
148 | assertEquals(1, trackedPathsOnMarshal.size()); | |
149 | } | |
150 | ||
151 | public void testDoNotKeepXPathMapForImmutablesOnUnmarshall() { | |
152 | //configure XStream | |
153 | CountingXPathStrategy marshallingStrategy = new CountingXPathStrategy(); | |
154 | xstream.setMarshallingStrategy(marshallingStrategy); | |
155 | ||
156 | //setup document | |
157 | String document = "" | |
158 | + "<list>" | |
159 | + " <url>http://jira.codehaus.org/browse</url>" | |
160 | + " <url>http://jira.codehaus.org/browse</url>" | |
161 | + "</list>"; | |
162 | ||
163 | //act | |
164 | Object result = xstream.fromXML(document); | |
165 | ||
166 | //assert | |
167 | Map trackedPathsOnUnmarshal = getReferences(marshallingStrategy.requestedUnmarshaller); | |
168 | ||
169 | assertTrue(trackedPathsOnUnmarshal.containsKey(new Path("/list"))); | |
170 | assertEquals(1, trackedPathsOnUnmarshal.size()); | |
171 | } | |
172 | ||
173 | public static class DomainType extends StandardObject{ | |
174 | public String value; | |
175 | ||
176 | public DomainType(String value){ | |
177 | this.value = value; | |
178 | } | |
179 | } | |
180 | ||
181 | public void testDoesKeepXPathMapForBackwardsCompatibleImmutablesOnUnmarshall() { | |
182 | //configure XStream | |
183 | CountingXPathStrategy marshallingStrategy = new CountingXPathStrategy(); | |
184 | xstream.setMarshallingStrategy(marshallingStrategy); | |
185 | xstream.addImmutableType(Thing.class, true); | |
186 | ||
187 | //setup document | |
188 | String document = "" | |
189 | + "<list>" | |
190 | + " <thing>" | |
191 | + " <name>JUnit</name>" | |
192 | + " </thing>" | |
193 | + " <thing>" | |
194 | + " <name>JUnit</name>" | |
195 | + " </thing>" | |
196 | + "</list>"; | |
197 | ||
198 | //act | |
199 | Object result = xstream.fromXML(document); | |
200 | ||
201 | //assert | |
202 | Map trackedPathsOnUnmarshal = getReferences(marshallingStrategy.requestedUnmarshaller); | |
203 | ||
204 | assertTrue(trackedPathsOnUnmarshal.containsKey(new Path("/list"))); | |
205 | assertTrue(trackedPathsOnUnmarshal.containsKey(new Path("/list/thing"))); | |
206 | assertTrue(trackedPathsOnUnmarshal.containsKey(new Path("/list/thing[2]"))); | |
207 | assertEquals(3, trackedPathsOnUnmarshal.size()); | |
208 | } | |
209 | ||
210 | private Map getReferences(ReferenceByXPathUnmarshaller requestedUnmarshaller) { | |
211 | try { | |
212 | Field field = AbstractReferenceUnmarshaller.class.getDeclaredField("values"); | |
213 | field.setAccessible(true); | |
214 | return (Map) field.get(requestedUnmarshaller); | |
215 | } | |
216 | catch (Exception e) { | |
217 | throw new RuntimeException(e); | |
218 | } | |
219 | } | |
220 | ||
221 | private ObjectIdDictionary getReferences(ReferenceByXPathMarshaller requestedMarshaller) { | |
222 | try { | |
223 | Field field = AbstractReferenceMarshaller.class.getDeclaredField("references"); | |
224 | field.setAccessible(true); | |
225 | return (ObjectIdDictionary) field.get(requestedMarshaller); | |
226 | } | |
227 | catch(Exception e){ | |
228 | throw new RuntimeException(e); | |
229 | } | |
230 | } | |
90 | 231 | } |
+12
-7
0 | 0 | /* |
1 | * Copyright (C) 2007, 2009, 2010, 2011, 2012 XStream Committers. | |
1 | * Copyright (C) 2007, 2009, 2010, 2011, 2012, 2016 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.core.util; |
11 | 11 | |
12 | import com.thoughtworks.xstream.converters.ErrorWriter; | |
12 | 13 | import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; |
13 | 14 | |
14 | 15 | import junit.framework.TestCase; |
23 | 24 | ObjectAccessException.class, new Object[]{ |
24 | 25 | "The message", this, new RuntimeException("JUnit")}, used); |
25 | 26 | assertTrue(exception instanceof ObjectAccessException); |
26 | assertEquals("The message : JUnit", exception.getMessage()); | |
27 | assertEquals("JUnit", ((ObjectAccessException)exception).getCause().getMessage()); | |
27 | assertEquals("The message", ((ErrorWriter)exception).get("message")); | |
28 | assertEquals("JUnit", ((ErrorWriter)exception).get("cause-message")); | |
28 | 29 | assertTrue(used.get(0)); |
29 | 30 | assertFalse(used.get(1)); |
30 | 31 | assertTrue(used.get(2)); |
44 | 45 | ObjectAccessException.class, new Object[]{ |
45 | 46 | new TypedNull(String.class), this, new RuntimeException("JUnit")}, used); |
46 | 47 | assertTrue(exception instanceof ObjectAccessException); |
47 | assertEquals("null : JUnit", exception.getMessage()); | |
48 | assertNull(((ErrorWriter)exception).get("message")); | |
49 | assertEquals("JUnit", ((ErrorWriter)exception).get("cause-message")); | |
48 | 50 | assertTrue(used.get(0)); |
49 | 51 | assertFalse(used.get(1)); |
50 | 52 | assertTrue(used.get(2)); |
68 | 70 | ObjectAccessException.class, new Object[]{ |
69 | 71 | new RuntimeException("JUnit"), this, "The message"}, used); |
70 | 72 | assertTrue(exception instanceof ObjectAccessException); |
71 | assertEquals("The message : JUnit", exception.getMessage()); | |
73 | assertEquals("The message", ((ErrorWriter)exception).get("message")); | |
74 | assertEquals("JUnit", ((ErrorWriter)exception).get("cause-message")); | |
72 | 75 | assertTrue(used.get(0)); |
73 | 76 | assertFalse(used.get(1)); |
74 | 77 | assertTrue(used.get(2)); |
81 | 84 | new RuntimeException("JUnit"), new IllegalArgumentException("foo"), this, |
82 | 85 | "The message"}, used); |
83 | 86 | assertTrue(exception instanceof ObjectAccessException); |
84 | assertEquals("The message : foo", exception.getMessage()); | |
87 | assertEquals("The message", ((ErrorWriter)exception).get("message")); | |
88 | assertEquals("foo", ((ErrorWriter)exception).get("cause-message")); | |
85 | 89 | assertFalse(used.get(0)); |
86 | 90 | assertTrue(used.get(1)); |
87 | 91 | assertFalse(used.get(2)); |
95 | 99 | new RuntimeException("JUnit"), "The message", "bar", |
96 | 100 | new IllegalArgumentException("foo"), this}, used); |
97 | 101 | assertTrue(exception instanceof ObjectAccessException); |
98 | assertEquals("The message : foo", exception.getMessage()); | |
102 | assertEquals("The message", ((ErrorWriter)exception).get("message")); | |
103 | assertEquals("foo", ((ErrorWriter)exception).get("cause-message")); | |
99 | 104 | assertFalse(used.get(0)); |
100 | 105 | assertTrue(used.get(1)); |
101 | 106 | assertFalse(used.get(2)); |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2011 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 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 |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.io.binary; |
12 | 12 | |
13 | import com.thoughtworks.xstream.XStreamException; | |
13 | 14 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
14 | 15 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; |
15 | 16 | import com.thoughtworks.xstream.io.copy.HierarchicalStreamCopier; |
75 | 76 | |
76 | 77 | } |
77 | 78 | |
79 | public void testIsXXEVulnerableWithExternalGeneralEntity() throws Exception { | |
80 | try { | |
81 | super.testIsXXEVulnerableWithExternalGeneralEntity(); | |
82 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
83 | } catch (final XStreamException e) { | |
84 | final String message = e.getCause().getMessage(); | |
85 | if (message.indexOf("resolve entity") < 0) { | |
86 | throw e; | |
87 | } | |
88 | } | |
89 | } | |
90 | ||
78 | 91 | } |
+14
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2011 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 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 |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.io.copy; |
12 | 12 | |
13 | import com.thoughtworks.xstream.XStreamException; | |
13 | 14 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
14 | 15 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; |
15 | 16 | import com.thoughtworks.xstream.io.xml.AbstractXMLReaderTest; |
57 | 58 | assertEquals(expected, buffer.toString()); |
58 | 59 | } |
59 | 60 | |
61 | public void testIsXXEVulnerableWithExternalGeneralEntity() throws Exception { | |
62 | try { | |
63 | super.testIsXXEVulnerableWithExternalGeneralEntity(); | |
64 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
65 | } catch (final XStreamException e) { | |
66 | final String message = e.getCause().getMessage(); | |
67 | if (message.indexOf("resolve entity") < 0) { | |
68 | throw e; | |
69 | } | |
70 | } | |
71 | } | |
72 | ||
60 | 73 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2011, 2012, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2011, 2012, 2013, 2015 XStream Committers. | |
3 | 3 | * All rights reserved. |
4 | 4 | * |
5 | 5 | * The software in this package is published under the terms of the BSD |
241 | 241 | assertEquals(content, xmlReader.getValue()); |
242 | 242 | } |
243 | 243 | |
244 | public void testIsXXEVulnerableWithExternalGeneralEntity() throws Exception { | |
245 | HierarchicalStreamReader xmlReader = createReader("" | |
246 | + "<?xml version=\"1.0\"?>\n" | |
247 | +"<!DOCTYPE root [\n" | |
248 | +"<!ELEMENT string (#PCDATA)>\n" | |
249 | +"<!ENTITY content SYSTEM \"file:src/test/$Package.java\">\n" | |
250 | // +"<!ENTITY content SYSTEM \"file:pom.xml\">\n" | |
251 | // +"<!ENTITY content SYSTEM \"file:/etc/passwd\">\n" | |
252 | +"]><string>&content;</string>"); | |
253 | assertEquals("", xmlReader.getValue()); | |
254 | } | |
255 | ||
256 | public void testIsXXEVulnerableWithExternalParameterEntity() throws Exception { | |
257 | HierarchicalStreamReader xmlReader = createReader("" | |
258 | + "<?xml version=\"1.0\"?>\n" | |
259 | +"<!DOCTYPE root [\n" | |
260 | +"<!ELEMENT string (#PCDATA)>\n" | |
261 | +"<!ENTITY % content SYSTEM \"file:src/test/$Package.java\">\n" | |
262 | // +"<!ENTITY % content SYSTEM \"file:pom.xml\">\n" | |
263 | // +"<!ENTITY % content SYSTEM \"file:/etc/passwd\">\n" | |
264 | +"%content;\n" | |
265 | +"]><string>test</string>"); | |
266 | assertEquals("test", xmlReader.getValue()); | |
267 | } | |
268 | ||
244 | 269 | // TODO: See XSTR-473 |
245 | 270 | public void todoTestCanReadNullValueInString() throws Exception { |
246 | 271 | HierarchicalStreamReader xmlReader = createReader("<string>�</string>"); |
0 | 0 | /* |
1 | * Copyright (C) 2011 XStream Committers. | |
1 | * Copyright (C) 2011, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
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 |
6 | 6 | * the LICENSE.txt file. |
7 | * | |
7 | * | |
8 | 8 | * Created on 30. September 2011 by Joerg Schaible |
9 | 9 | */ |
10 | 10 | package com.thoughtworks.xstream.io.xml; |
11 | 11 | |
12 | import java.io.StringReader; | |
13 | ||
12 | 14 | import com.thoughtworks.xstream.io.HierarchicalStreamDriver; |
13 | 15 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
14 | 16 | |
15 | import java.io.StringReader; | |
16 | 17 | |
17 | 18 | public class BEAStaxReaderTest extends AbstractXMLReaderTest { |
18 | ||
19 | private HierarchicalStreamDriver driver = new BEAStaxDriver(); | |
19 | ||
20 | private final HierarchicalStreamDriver driver = new BEAStaxDriver(); | |
20 | 21 | |
21 | 22 | // factory method |
22 | protected HierarchicalStreamReader createReader(String xml) throws Exception { | |
23 | protected HierarchicalStreamReader createReader(final String xml) throws Exception { | |
23 | 24 | return driver.createReader(new StringReader(xml)); |
25 | } | |
26 | ||
27 | public void testIsXXEVulnerableWithExternalParameterEntity() throws Exception { | |
28 | // Implementation ignores XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES set to false. | |
29 | // super.testIsXXEVulnerableWithExternalParameterEntity(); | |
24 | 30 | } |
25 | 31 | |
26 | 32 | // inherits tests from superclass |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 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.io.xml; |
12 | 12 | |
13 | import com.thoughtworks.xstream.XStreamException; | |
14 | import com.thoughtworks.xstream.core.JVM; | |
13 | 15 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
16 | ||
17 | import java.io.StringReader; | |
14 | 18 | |
15 | 19 | import org.dom4j.Document; |
16 | 20 | import org.dom4j.DocumentException; |
21 | 25 | |
22 | 26 | // factory method |
23 | 27 | protected HierarchicalStreamReader createReader(String xml) throws Exception { |
24 | return new Dom4JReader(DocumentHelper.parseText(xml)); | |
28 | return new Dom4JDriver().createReader(new StringReader(xml)); | |
25 | 29 | } |
26 | 30 | |
27 | 31 | public void testCanReadFromElementOfLargerDocument() throws DocumentException { |
41 | 45 | assertEquals("tiny", xmlReader.getNodeName()); |
42 | 46 | } |
43 | 47 | |
48 | public void testIsXXEVulnerableWithExternalGeneralEntity() throws Exception { | |
49 | try { | |
50 | super.testIsXXEVulnerableWithExternalGeneralEntity(); | |
51 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
52 | } catch (final XStreamException e) { | |
53 | final String message = e.getCause().getMessage(); | |
54 | if (message.indexOf("DOCTYPE") < 0) { | |
55 | if (JVM.is17() || (JVM.is16() && message.indexOf("Nested exception: null") < 0)) { | |
56 | throw e; | |
57 | } | |
58 | } | |
59 | } | |
60 | } | |
61 | ||
62 | public void testIsXXEVulnerableWithExternalParameterEntity() throws Exception { | |
63 | try { | |
64 | super.testIsXXEVulnerableWithExternalParameterEntity(); | |
65 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
66 | } catch (final XStreamException e) { | |
67 | final String message = e.getCause().getMessage(); | |
68 | if (message.indexOf("DOCTYPE") < 0) { | |
69 | if (JVM.is17() || (JVM.is16() && message.indexOf("Nested exception: null") < 0)) { | |
70 | throw e; | |
71 | } | |
72 | } | |
73 | } | |
74 | } | |
75 | ||
44 | 76 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 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.io.xml; |
12 | 12 | |
13 | import com.thoughtworks.xstream.XStreamException; | |
14 | import com.thoughtworks.xstream.core.JVM; | |
13 | 15 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
14 | 16 | |
15 | 17 | import org.w3c.dom.Document; |
19 | 21 | import javax.xml.parsers.DocumentBuilderFactory; |
20 | 22 | |
21 | 23 | import java.io.ByteArrayInputStream; |
24 | import java.io.StringReader; | |
22 | 25 | import java.util.HashMap; |
23 | 26 | import java.util.Map; |
24 | 27 | |
26 | 29 | |
27 | 30 | // factory method |
28 | 31 | protected HierarchicalStreamReader createReader(String xml) throws Exception { |
29 | return new DomReader(buildDocument(xml)); | |
32 | return new DomDriver().createReader(new StringReader(xml)); | |
30 | 33 | } |
31 | 34 | |
32 | 35 | private Document buildDocument(String xml) throws Exception { |
81 | 84 | assertEquals(0, xmlReader.getAttributeCount()); |
82 | 85 | } |
83 | 86 | |
87 | public void testIsXXEVulnerableWithExternalGeneralEntity() throws Exception { | |
88 | try { | |
89 | super.testIsXXEVulnerableWithExternalGeneralEntity(); | |
90 | if (JVM.is16()) { | |
91 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
92 | } | |
93 | } catch (final XStreamException e) { | |
94 | final String message = e.getCause().getMessage(); | |
95 | if (message.indexOf("DOCTYPE") < 0) { | |
96 | throw e; | |
97 | } | |
98 | } catch (final NullPointerException e) { | |
99 | // NPE only with Sun Java 1.6 runtime | |
100 | if (JVM.is17() || !JVM.is16()) { | |
101 | throw e; | |
102 | } | |
103 | } | |
104 | } | |
105 | ||
106 | public void testIsXXEVulnerableWithExternalParameterEntity() throws Exception { | |
107 | try { | |
108 | super.testIsXXEVulnerableWithExternalParameterEntity(); | |
109 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
110 | } catch (final XStreamException e) { | |
111 | final String message = e.getCause().getMessage(); | |
112 | if (message.indexOf("DOCTYPE") < 0) { | |
113 | // XXE vulnerable with Sun Java 1.6 runtime | |
114 | if (JVM.is16()) { | |
115 | throw e; | |
116 | } else { | |
117 | System.err.println("DomReader is vulnerable with Java 5 and 1.4!"); | |
118 | } | |
119 | } | |
120 | } catch (final NullPointerException e) { | |
121 | // NPE only with Sun Java 1.6 runtime | |
122 | if (JVM.is17() || !JVM.is16()) { | |
123 | throw e; | |
124 | } | |
125 | } | |
126 | } | |
84 | 127 | } |
0 | 0 | /* |
1 | * Copyright (C) 2013 XStream Committers. | |
1 | * Copyright (C) 2013, 2015, 2016 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.io.xml; |
11 | 11 | |
12 | import com.thoughtworks.xstream.XStreamException; | |
13 | import com.thoughtworks.xstream.core.JVM; | |
12 | 14 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
13 | 15 | |
14 | 16 | import org.jdom2.Document; |
17 | import org.jdom2.Element; | |
15 | 18 | import org.jdom2.input.SAXBuilder; |
16 | 19 | |
17 | 20 | import java.io.StringReader; |
20 | 23 | |
21 | 24 | // factory method |
22 | 25 | protected HierarchicalStreamReader createReader(String xml) throws Exception { |
26 | return new JDom2Driver().createReader(new StringReader(xml)); | |
27 | } | |
28 | ||
29 | public void testCanReadFromElementOfLargerDocument() throws Exception { | |
30 | String xml ="" + | |
31 | "<big>" + | |
32 | " <small>" + | |
33 | " <tiny/>" + | |
34 | " </small>" + | |
35 | " <small-two>" + | |
36 | " </small-two>" + | |
37 | "</big>"; | |
23 | 38 | Document document = new SAXBuilder().build(new StringReader(xml)); |
24 | return new JDom2Reader(document); | |
39 | Element element = document.getRootElement().getChild("small"); | |
40 | ||
41 | HierarchicalStreamReader xmlReader = new JDom2Reader(element); | |
42 | assertEquals("small", xmlReader.getNodeName()); | |
43 | xmlReader.moveDown(); | |
44 | assertEquals("tiny", xmlReader.getNodeName()); | |
45 | } | |
46 | ||
47 | public void testIsXXEVulnerableWithExternalGeneralEntity() throws Exception { | |
48 | try { | |
49 | super.testIsXXEVulnerableWithExternalGeneralEntity(); | |
50 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
51 | } catch (final XStreamException e) { | |
52 | final String message = e.getCause().getMessage(); | |
53 | if (!message.contains("DOCTYPE")) { | |
54 | throw e; | |
55 | } | |
56 | } catch (final NullPointerException e) { | |
57 | // NPE only with Sun Java 1.6 runtime | |
58 | if (JVM.is17()) { | |
59 | throw e; | |
60 | } | |
61 | } | |
62 | } | |
63 | ||
64 | public void testIsXXEVulnerableWithExternalParameterEntity() throws Exception { | |
65 | try { | |
66 | super.testIsXXEVulnerableWithExternalParameterEntity(); | |
67 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
68 | } catch (final XStreamException e) { | |
69 | final String message = e.getCause().getMessage(); | |
70 | if (!message.contains("DOCTYPE")) { | |
71 | throw e; | |
72 | } | |
73 | } catch (final NullPointerException e) { | |
74 | // NPE only with Sun Java 1.6 runtime | |
75 | if (JVM.is17()) { | |
76 | throw e; | |
77 | } | |
78 | } | |
25 | 79 | } |
26 | 80 | |
27 | 81 | // inherits tests from superclass |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 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.io.xml; |
12 | 12 | |
13 | import com.thoughtworks.xstream.XStreamException; | |
14 | import com.thoughtworks.xstream.core.JVM; | |
13 | 15 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
14 | 16 | |
15 | 17 | import org.jdom.Document; |
18 | import org.jdom.Element; | |
16 | 19 | import org.jdom.input.SAXBuilder; |
17 | 20 | |
18 | 21 | import java.io.StringReader; |
21 | 24 | |
22 | 25 | // factory method |
23 | 26 | protected HierarchicalStreamReader createReader(String xml) throws Exception { |
27 | return new JDomDriver().createReader(new StringReader(xml)); | |
28 | } | |
29 | ||
30 | public void testCanReadFromElementOfLargerDocument() throws Exception { | |
31 | String xml ="" + | |
32 | "<big>" + | |
33 | " <small>" + | |
34 | " <tiny/>" + | |
35 | " </small>" + | |
36 | " <small-two>" + | |
37 | " </small-two>" + | |
38 | "</big>"; | |
24 | 39 | Document document = new SAXBuilder().build(new StringReader(xml)); |
25 | return new JDomReader(document); | |
40 | Element element = document.getRootElement().getChild("small"); | |
41 | ||
42 | HierarchicalStreamReader xmlReader = new JDomReader(element); | |
43 | assertEquals("small", xmlReader.getNodeName()); | |
44 | xmlReader.moveDown(); | |
45 | assertEquals("tiny", xmlReader.getNodeName()); | |
46 | } | |
47 | ||
48 | public void testIsXXEVulnerableWithExternalGeneralEntity() throws Exception { | |
49 | try { | |
50 | super.testIsXXEVulnerableWithExternalGeneralEntity(); | |
51 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
52 | } catch (final XStreamException e) { | |
53 | final String message = e.getCause().getMessage(); | |
54 | if (message.indexOf("DOCTYPE") < 0) { | |
55 | throw e; | |
56 | } | |
57 | } catch (final NullPointerException e) { | |
58 | // NPE only with Sun Java 1.6 runtime | |
59 | if (JVM.is17()) { | |
60 | throw e; | |
61 | } | |
62 | } | |
63 | } | |
64 | ||
65 | public void testIsXXEVulnerableWithExternalParameterEntity() throws Exception { | |
66 | try { | |
67 | super.testIsXXEVulnerableWithExternalParameterEntity(); | |
68 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
69 | } catch (final XStreamException e) { | |
70 | final String message = e.getCause().getMessage(); | |
71 | if (message.indexOf("DOCTYPE") < 0) { | |
72 | throw e; | |
73 | } | |
74 | } catch (final NullPointerException e) { | |
75 | // NPE only with Sun Java 1.6 runtime | |
76 | if (JVM.is17()) { | |
77 | throw e; | |
78 | } | |
79 | } | |
26 | 80 | } |
27 | 81 | |
28 | 82 | // inherits tests from superclass |
0 | 0 | /* |
1 | * Copyright (C) 2011 XStream Committers. | |
1 | * Copyright (C) 2011, 2016 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.io.xml; |
11 | 11 | |
12 | import com.thoughtworks.xstream.XStreamException; | |
12 | 13 | import com.thoughtworks.xstream.io.HierarchicalStreamDriver; |
13 | 14 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
14 | 15 | |
27 | 28 | return driver.createReader(new StringReader(xml)); |
28 | 29 | } |
29 | 30 | |
31 | public void testIsXXEVulnerableWithExternalGeneralEntity() throws Exception { | |
32 | try { | |
33 | super.testIsXXEVulnerableWithExternalGeneralEntity(); | |
34 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
35 | } catch (final XStreamException e) { | |
36 | final String message = e.getCause().getMessage(); | |
37 | if (message.indexOf("unresolved") < 0) { | |
38 | throw e; | |
39 | } | |
40 | } | |
41 | } | |
42 | ||
30 | 43 | // inherits tests from superclass |
31 | 44 | } |
0 | 0 | /* |
1 | * Copyright (C) 2011 XStream Committers. | |
1 | * Copyright (C) 2011, 2015 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.io.xml; |
11 | 11 | |
12 | import com.thoughtworks.xstream.XStreamException; | |
13 | import com.thoughtworks.xstream.core.JVM; | |
12 | 14 | import com.thoughtworks.xstream.io.HierarchicalStreamDriver; |
13 | 15 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
14 | 16 | |
46 | 48 | return driver.createReader(new StringReader(xml)); |
47 | 49 | } |
48 | 50 | |
51 | public void testIsXXEVulnerableWithExternalParameterEntity() throws Exception { | |
52 | // Fails for Java 1.6 runtime | |
53 | if (JVM.is17()) { | |
54 | super.testIsXXEVulnerableWithExternalParameterEntity(); | |
55 | } | |
56 | } | |
57 | ||
49 | 58 | // inherits tests from superclass |
50 | 59 | } |
0 | /* | |
1 | * Copyright (C) 2015 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. September 2015 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.io.xml; | |
11 | ||
12 | import com.thoughtworks.xstream.core.JVM; | |
13 | import com.thoughtworks.xstream.io.HierarchicalStreamDriver; | |
14 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; | |
15 | ||
16 | import junit.framework.Test; | |
17 | import junit.framework.TestCase; | |
18 | import junit.framework.TestResult; | |
19 | import junit.framework.TestSuite; | |
20 | ||
21 | import java.io.StringReader; | |
22 | ||
23 | public class StandardStaxReaderTest extends AbstractXMLReaderTest { | |
24 | ||
25 | public static Test suite() { | |
26 | if (JVM.is16()) { | |
27 | return new TestSuite(StandardStaxReaderTest.class); | |
28 | } else { | |
29 | return new TestCase(StandardStaxReaderTest.class.getName() + ": not available") { | |
30 | ||
31 | public int countTestCases() { | |
32 | return 1; | |
33 | } | |
34 | ||
35 | public void run(TestResult result) { | |
36 | } | |
37 | }; | |
38 | } | |
39 | } | |
40 | ||
41 | private HierarchicalStreamDriver driver = new StandardStaxDriver(); | |
42 | ||
43 | // factory method | |
44 | protected HierarchicalStreamReader createReader(String xml) throws Exception { | |
45 | return driver.createReader(new StringReader(xml)); | |
46 | } | |
47 | ||
48 | public void testIsXXEVulnerableWithExternalParameterEntity() throws Exception { | |
49 | // fails for Sun JDK 1.6 runtime | |
50 | if (JVM.is17() || !JVM.getStaxInputFactory().getName().equals("com.sun.xml.internal.stream.XMLInputFactoryImpl")) { | |
51 | super.testIsXXEVulnerableWithExternalParameterEntity(); | |
52 | } | |
53 | } | |
54 | ||
55 | // inherits tests from superclass | |
56 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 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 29. September 2004 by James Strachan |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.io.xml; |
12 | 12 | |
13 | import java.io.StringReader; | |
14 | ||
15 | import com.thoughtworks.xstream.XStreamException; | |
16 | import com.thoughtworks.xstream.core.JVM; | |
13 | 17 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
14 | 18 | |
15 | import java.io.StringReader; | |
16 | 19 | |
17 | 20 | public class StaxReaderTest extends AbstractXMLReaderTest { |
18 | protected HierarchicalStreamReader createReader(String xml) throws Exception { | |
19 | StaxDriver driver = new StaxDriver(); | |
21 | protected HierarchicalStreamReader createReader(final String xml) throws Exception { | |
22 | final StaxDriver driver = new StaxDriver(); | |
20 | 23 | return driver.createReader(new StringReader(xml)); |
24 | } | |
25 | ||
26 | public void testIsXXEVulnerableWithExternalGeneralEntity() throws Exception { | |
27 | try { | |
28 | super.testIsXXEVulnerableWithExternalGeneralEntity(); | |
29 | } catch (final XStreamException e) { | |
30 | final String message = e.getCause().getMessage(); | |
31 | if (message.indexOf("external entity") < 0) { | |
32 | throw e; | |
33 | } | |
34 | } | |
35 | } | |
36 | ||
37 | public void testIsXXEVulnerableWithExternalParameterEntity() throws Exception { | |
38 | try { | |
39 | super.testIsXXEVulnerableWithExternalParameterEntity(); | |
40 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
41 | } catch (final XStreamException e) { | |
42 | final String message = e.getCause().getMessage(); | |
43 | if (JVM.is14() && message == null) { | |
44 | if (JVM.is16()) { | |
45 | throw e; | |
46 | } | |
47 | System.err.println("BEAStaxReader was selected as default StAX driver for StaxReaderTest!"); | |
48 | } else if (message.indexOf("external entity") < 0) { | |
49 | if (JVM.is16() && message.indexOf("com.wutka.dtd.DTDParseException") >= 0) { | |
50 | System.err.println("BEAStaxReader was selected as default StAX driver for StaxReaderTest!"); | |
51 | } else if (message.replaceAll("[:space:]", "").endsWith("null")) { | |
52 | System.err.println("BEAStaxReader was selected as default StAX driver for StaxReaderTest!"); | |
53 | } else { | |
54 | throw e; | |
55 | } | |
56 | } | |
57 | } | |
21 | 58 | } |
22 | 59 | |
23 | 60 | // inherits tests from superclass |
0 | 0 | /* |
1 | * Copyright (C) 2011 XStream Committers. | |
1 | * Copyright (C) 2011, 2015, 2016 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.io.xml; |
11 | 11 | |
12 | import com.thoughtworks.xstream.XStreamException; | |
12 | 13 | import com.thoughtworks.xstream.io.HierarchicalStreamDriver; |
13 | 14 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
14 | 15 | |
23 | 24 | return driver.createReader(new StringReader(xml)); |
24 | 25 | } |
25 | 26 | |
27 | public void testIsXXEVulnerableWithExternalGeneralEntity() throws Exception { | |
28 | try { | |
29 | super.testIsXXEVulnerableWithExternalGeneralEntity(); | |
30 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
31 | } catch (final XStreamException e) { | |
32 | final String message = e.getCause().getMessage(); | |
33 | if (message.indexOf("external entity") < 0) { | |
34 | throw e; | |
35 | } | |
36 | } | |
37 | } | |
38 | ||
39 | public void testIsXXEVulnerableWithExternalParameterEntity() throws Exception { | |
40 | try { | |
41 | super.testIsXXEVulnerableWithExternalParameterEntity(); | |
42 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
43 | } catch (final XStreamException e) { | |
44 | final String message = e.getCause().getMessage(); | |
45 | if (message.indexOf("external entity") < 0) { | |
46 | throw e; | |
47 | } | |
48 | } | |
49 | } | |
50 | ||
26 | 51 | // inherits tests from superclass |
27 | 52 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2015 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 02. September 2004 by Joe Walnes |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.io.xml; |
12 | 12 | |
13 | import java.io.StringReader; | |
14 | ||
15 | import com.thoughtworks.xstream.XStreamException; | |
13 | 16 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
14 | 17 | |
15 | 18 | import nu.xom.Builder; |
16 | 19 | import nu.xom.Document; |
20 | import nu.xom.Element; | |
17 | 21 | |
18 | import java.io.StringReader; | |
19 | 22 | |
20 | 23 | public class XomReaderTest extends AbstractXMLReaderTest { |
21 | 24 | |
22 | 25 | // factory method |
23 | protected HierarchicalStreamReader createReader(String xml) throws Exception { | |
24 | Document document = new Builder().build(new StringReader(xml)); | |
25 | return new XomReader(document); | |
26 | protected HierarchicalStreamReader createReader(final String xml) throws Exception { | |
27 | return new XomDriver().createReader(new StringReader(xml)); | |
28 | } | |
29 | ||
30 | public void testCanReadFromElementOfLargerDocument() throws Exception { | |
31 | final String xml = "" | |
32 | + "<big>" | |
33 | + " <small>" | |
34 | + " <tiny/>" | |
35 | + " </small>" | |
36 | + " <small-two>" | |
37 | + " </small-two>" | |
38 | + "</big>"; | |
39 | final Document document = new Builder().build(new StringReader(xml)); | |
40 | final Element element = document.getRootElement().getFirstChildElement("small"); | |
41 | ||
42 | final HierarchicalStreamReader xmlReader = new XomReader(element); | |
43 | assertEquals("small", xmlReader.getNodeName()); | |
44 | xmlReader.moveDown(); | |
45 | assertEquals("tiny", xmlReader.getNodeName()); | |
46 | } | |
47 | ||
48 | public void testIsXXEVulnerableWithExternalGeneralEntity() throws Exception { | |
49 | // No possibility to suppress support for external entities in XOM? | |
50 | // super.testIsXXEVulnerableWithExternalGeneralEntity(); | |
51 | } | |
52 | ||
53 | public void testIsXXEVulnerableWithExternalParameterEntity() throws Exception { | |
54 | // No possibility to suppress support for external entities in XOM? | |
55 | // super.testIsXXEVulnerableWithExternalParameterEntity(); | |
26 | 56 | } |
27 | 57 | |
28 | 58 | // inherits tests from superclass |
0 | 0 | /* |
1 | * Copyright (C) 2011 XStream Committers. | |
1 | * Copyright (C) 2011, 2015, 2016 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.io.xml; |
11 | 11 | |
12 | import com.thoughtworks.xstream.XStreamException; | |
12 | 13 | import com.thoughtworks.xstream.io.HierarchicalStreamDriver; |
13 | 14 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
14 | 15 | |
23 | 24 | return driver.createReader(new StringReader(xml)); |
24 | 25 | } |
25 | 26 | |
27 | public void testIsXXEVulnerableWithExternalGeneralEntity() throws Exception { | |
28 | try { | |
29 | super.testIsXXEVulnerableWithExternalGeneralEntity(); | |
30 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
31 | } catch (final XStreamException e) { | |
32 | final String message = e.getCause().getMessage(); | |
33 | if (message.indexOf("resolve entity") < 0) { | |
34 | throw e; | |
35 | } | |
36 | } | |
37 | } | |
38 | ||
26 | 39 | // inherits tests from superclass |
27 | 40 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004, 2005 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 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 |
10 | 10 | */ |
11 | 11 | package com.thoughtworks.xstream.io.xml; |
12 | 12 | |
13 | import com.thoughtworks.xstream.XStreamException; | |
13 | 14 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
14 | 15 | import com.thoughtworks.xstream.io.xml.xppdom.XppDom; |
15 | 16 | import com.thoughtworks.xstream.io.xml.xppdom.XppFactory; |
74 | 75 | assertEquals(0, xmlReader.getAttributeCount()); |
75 | 76 | } |
76 | 77 | |
78 | public void testIsXXEVulnerableWithExternalGeneralEntity() throws Exception { | |
79 | try { | |
80 | super.testIsXXEVulnerableWithExternalGeneralEntity(); | |
81 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
82 | } catch (final XStreamException e) { | |
83 | final String message = e.getCause().getMessage(); | |
84 | if (message.indexOf("resolve entity") < 0) { | |
85 | throw e; | |
86 | } | |
87 | } | |
88 | } | |
89 | ||
77 | 90 | } |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2004 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 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.io.xml; |
12 | 12 | |
13 | import com.thoughtworks.xstream.XStreamException; | |
13 | 14 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; |
14 | 15 | |
15 | 16 | import java.io.StringReader; |
19 | 20 | return new XppReader(new StringReader(xml)); |
20 | 21 | } |
21 | 22 | |
23 | public void testIsXXEVulnerableWithExternalGeneralEntity() throws Exception { | |
24 | try { | |
25 | super.testIsXXEVulnerableWithExternalGeneralEntity(); | |
26 | fail("Thrown " + XStreamException.class.getName() + " expected"); | |
27 | } catch (final XStreamException e) { | |
28 | final String message = e.getCause().getMessage(); | |
29 | if (message.indexOf("resolve entity") < 0) { | |
30 | throw e; | |
31 | } | |
32 | } | |
33 | } | |
34 | ||
22 | 35 | // inherits tests from superclass |
23 | 36 | } |
13 | 13 | <parent> |
14 | 14 | <groupId>com.thoughtworks.xstream</groupId> |
15 | 15 | <artifactId>xstream-parent</artifactId> |
16 | <version>1.4.8</version> | |
16 | <version>1.4.9</version> | |
17 | 17 | </parent> |
18 | 18 | <artifactId>xstream-benchmark</artifactId> |
19 | 19 | <packaging>jar</packaging> |
90 | 90 | <plugins> |
91 | 91 | <plugin> |
92 | 92 | <groupId>org.apache.maven.plugins</groupId> |
93 | <artifactId>maven-source-plugin</artifactId> | |
94 | </plugin> | |
95 | <plugin> | |
96 | <groupId>org.apache.maven.plugins</groupId> | |
97 | 93 | <artifactId>maven-surefire-plugin</artifactId> |
98 | 94 | <configuration> |
99 | 95 | <skip>true</skip> |
132 | 128 | <artifactId>junit</artifactId> |
133 | 129 | </dependency> |
134 | 130 | </dependencies> |
131 | ||
132 | <properties> | |
133 | <bundle.export.package>!com.thoughtworks.xstream.tools.benchmark.model,com.thoughtworks.xstream.tools.benchmark.*;-noimport:=true</bundle.export.package> | |
134 | </properties> | |
135 | 135 | </project> |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2013 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2013, 2015 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 | * </pre> |
53 | 53 | * |
54 | 54 | * @author Joe Walnes |
55 | * @deprecated As of 1.4.9 use JMH instead | |
55 | 56 | */ |
56 | 57 | public class Harness { |
57 | 58 |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2015 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 | * @author Joe Walnes |
21 | 21 | * @author Jörg Schaible |
22 | 22 | * @see Harness |
23 | * @deprecated As of 1.4.9 use JMH instead | |
23 | 24 | */ |
24 | 25 | public interface Metric { |
25 | 26 |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2015 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 | * |
20 | 20 | * @author Joe Walnes |
21 | 21 | * @see Harness |
22 | * @deprecated As of 1.4.9 use JMH instead | |
22 | 23 | */ |
23 | 24 | public interface Product { |
24 | 25 |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2015 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 | * |
31 | 31 | * @author Joe Walnes |
32 | 32 | * @see Harness |
33 | * @deprecated As of 1.4.9 use JMH instead | |
33 | 34 | */ |
34 | 35 | public interface Reporter { |
35 | 36 |
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2015 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 | * |
20 | 20 | * @author Joe Walnes |
21 | 21 | * @see Harness |
22 | * @deprecated As of 1.4.9 use JMH instead | |
22 | 23 | */ |
23 | 24 | public interface Target { |
24 | 25 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2007, 2008, 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2007, 2008, 2009, 2011, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
20 | 20 | * |
21 | 21 | * @author Jörg Schaible |
22 | 22 | * @since 1.4 |
23 | * @deprecated As of 1.4.9 use JMH instead | |
23 | 24 | */ |
24 | 25 | public class CharacterCountMetric implements Metric { |
25 | 26 |
+2
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2009, 2015 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 | * @author Jörg Schaible |
25 | 25 | * @see com.thoughtworks.xstream.tools.benchmark.Harness |
26 | 26 | * @see Metric |
27 | * @deprecated As of 1.4.9 use JMH instead | |
27 | 28 | */ |
28 | 29 | public class DeserializationSpeedMetric implements Metric { |
29 | 30 |
+2
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2015 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 | * @author Joe Walnes |
23 | 23 | * @see com.thoughtworks.xstream.tools.benchmark.Harness |
24 | 24 | * @see Metric |
25 | * @deprecated As of 1.4.9 use JMH instead | |
25 | 26 | */ |
26 | 27 | public class SerializationSpeedMetric implements Metric { |
27 | 28 |
+2
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2008 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2008, 2015 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 | * @author Joe Walnes |
23 | 23 | * @see com.thoughtworks.xstream.tools.benchmark.Harness |
24 | 24 | * @see Metric |
25 | * @deprecated As of 1.4.9 use JMH instead | |
25 | 26 | */ |
26 | 27 | public class SizeMetric implements Metric { |
27 | 28 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2007, 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2007, 2009, 2011, 2015 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 | * Class with 100 fields. |
14 | 14 | * |
15 | 15 | * @since 1.4 |
16 | * @deprecated As of 1.4.9 use JMH instead | |
16 | 17 | */ |
17 | 18 | public class A100Fields { |
18 | 19 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2007, 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2007, 2009, 2011, 2015 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 | * Class with 100 parents. |
14 | 14 | * |
15 | 15 | * @since 1.4 |
16 | * @deprecated As of 1.4.9 use JMH instead | |
16 | 17 | */ |
17 | 18 | public class A100Parents { |
18 | 19 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2007, 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2007, 2009, 2011, 2015 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 | * Class with inner classes 50 levels deep. |
14 | 14 | * |
15 | 15 | * @since 1.4 |
16 | * @deprecated As of 1.4.9 use JMH instead | |
16 | 17 | */ |
17 | 18 | public class A50InnerClasses { |
18 | 19 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2007, 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2007, 2009, 2011, 2015 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 | * Class with static inner classes 50 levels deep. |
14 | 14 | * |
15 | 15 | * @since 1.4 |
16 | * @deprecated As of 1.4.9 use JMH instead | |
16 | 17 | */ |
17 | 18 | public class A50StaticInnerClasses { |
18 | 19 |
0 | 0 | /* |
1 | * Copyright (C) 2008, 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2008, 2009, 2011, 2015 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 | * Class containing 5 basic types. |
15 | 15 | * |
16 | 16 | * @since 1.4 |
17 | * @deprecated As of 1.4.9 use JMH instead | |
17 | 18 | */ |
18 | 19 | public class Five extends One { |
19 | 20 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2009, 2011, 2015 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 | * JavaBean class containing 5 basic types. |
15 | 15 | * |
16 | 16 | * @since 1.4 |
17 | * @deprecated As of 1.4.9 use JMH instead | |
17 | 18 | */ |
18 | 19 | public class FiveBean extends OneBean { |
19 | 20 |
0 | 0 | /* |
1 | * Copyright (C) 2008, 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2008, 2009, 2011, 2015 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 | * Class containing one basic type. |
15 | 15 | * |
16 | 16 | * @since 1.4 |
17 | * @deprecated As of 1.4.9 use JMH instead | |
17 | 18 | */ |
18 | 19 | public class One { |
19 | 20 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2009, 2011, 2015 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 | * JavaBean class containing one basic type. |
15 | 15 | * |
16 | 16 | * @since 1.4 |
17 | * @deprecated As of 1.4.9 use JMH instead | |
17 | 18 | */ |
18 | 19 | public class OneBean { |
19 | 20 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2008, 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2008, 2009, 2011, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
17 | 17 | * Serializable class containing 5 basic types. |
18 | 18 | * |
19 | 19 | * @since 1.4 |
20 | * @deprecated As of 1.4.9 use JMH instead | |
20 | 21 | */ |
21 | 22 | public class SerializableFive extends SerializableOne { |
22 | 23 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2008, 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2008, 2009, 2011, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
18 | 18 | * Serializable class containing one basic types. |
19 | 19 | * |
20 | 20 | * @since 1.4 |
21 | * @deprecated As of 1.4.9 use JMH instead | |
21 | 22 | */ |
22 | 23 | public class SerializableOne implements Serializable { |
23 | 24 |
+2
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2015 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 | * @see Product |
26 | 26 | * @see ObjectOutputStream |
27 | 27 | * @see ObjectInputStream |
28 | * @deprecated As of 1.4.9 use JMH instead | |
28 | 29 | */ |
29 | 30 | public class JavaObjectSerialization implements Product { |
30 | 31 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2009 XStream Committers. | |
1 | * Copyright (C) 2009, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
20 | 20 | * @see com.thoughtworks.xstream.tools.benchmark.Product |
21 | 21 | * @see com.thoughtworks.xstream.XStream |
22 | 22 | * @see BEAStaxDriver |
23 | * @deprecated As of 1.4.9 use JMH instead | |
23 | 24 | */ |
24 | 25 | public class XStreamBEAStax extends XStreamDriver { |
25 | 26 |
+2
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2015 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 | * @see XStream |
28 | 28 | * @see BinaryStreamReader |
29 | 29 | * @see BinaryStreamWriter |
30 | * @deprecated As of 1.4.9 use JMH instead | |
30 | 31 | */ |
31 | 32 | public class XStreamBinary implements Product { |
32 | 33 |
+2
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2015 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 | * @see Product |
28 | 28 | * @see XStream |
29 | 29 | * @see CompactWriter |
30 | * @deprecated As of 1.4.9 use JMH instead | |
30 | 31 | */ |
31 | 32 | public class XStreamCompact implements Product { |
32 | 33 |
+2
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2009 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2009, 2015 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 | * @see com.thoughtworks.xstream.tools.benchmark.Product |
21 | 21 | * @see com.thoughtworks.xstream.XStream |
22 | 22 | * @see DomDriver |
23 | * @deprecated As of 1.4.9 use JMH instead | |
23 | 24 | */ |
24 | 25 | public class XStreamDom extends XStreamDriver { |
25 | 26 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2009 XStream Committers. | |
1 | * Copyright (C) 2009, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
24 | 24 | * @see com.thoughtworks.xstream.tools.benchmark.Product |
25 | 25 | * @see com.thoughtworks.xstream.XStream |
26 | 26 | * @see Dom4JDriver |
27 | * @deprecated As of 1.4.9 use JMH instead | |
27 | 28 | */ |
28 | 29 | public class XStreamDom4J extends XStreamDriver { |
29 | 30 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2009, 2011, 2015 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 | * @author Joe Walnes |
30 | 30 | * @author Jörg Schaible |
31 | 31 | * @since 1.4 |
32 | * @deprecated As of 1.4.9 use JMH instead | |
32 | 33 | */ |
33 | 34 | public class XStreamDriver implements Product { |
34 | 35 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2009 XStream Committers. | |
1 | * Copyright (C) 2009, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
20 | 20 | * @see com.thoughtworks.xstream.tools.benchmark.Product |
21 | 21 | * @see com.thoughtworks.xstream.XStream |
22 | 22 | * @see JDomDriver |
23 | * @deprecated As of 1.4.9 use JMH instead | |
23 | 24 | */ |
24 | 25 | public class XStreamJDom extends XStreamDriver { |
25 | 26 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2009 XStream Committers. | |
1 | * Copyright (C) 2009, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
20 | 20 | * @see com.thoughtworks.xstream.tools.benchmark.Product |
21 | 21 | * @see com.thoughtworks.xstream.XStream |
22 | 22 | * @see KXml2Driver |
23 | * @deprecated As of 1.4.9 use JMH instead | |
23 | 24 | */ |
24 | 25 | public class XStreamKXml2 extends XStreamDriver { |
25 | 26 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2009 XStream Committers. | |
1 | * Copyright (C) 2009, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
20 | 20 | * @see com.thoughtworks.xstream.tools.benchmark.Product |
21 | 21 | * @see com.thoughtworks.xstream.XStream |
22 | 22 | * @see KXml2DomDriver |
23 | * @deprecated As of 1.4.9 use JMH instead | |
23 | 24 | */ |
24 | 25 | public class XStreamKXml2DOM extends XStreamDriver { |
25 | 26 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2009 XStream Committers. | |
1 | * Copyright (C) 2009, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
20 | 20 | * @see com.thoughtworks.xstream.tools.benchmark.Product |
21 | 21 | * @see com.thoughtworks.xstream.XStream |
22 | 22 | * @see SjsxpDriver |
23 | * @deprecated As of 1.4.9 use JMH instead | |
23 | 24 | */ |
24 | 25 | public class XStreamSjsxp extends XStreamDriver { |
25 | 26 |
+2
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2009 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2009, 2015 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 | * @see com.thoughtworks.xstream.tools.benchmark.Product |
21 | 21 | * @see com.thoughtworks.xstream.XStream |
22 | 22 | * @see StaxDriver |
23 | * @deprecated As of 1.4.9 use JMH instead | |
23 | 24 | */ |
24 | 25 | public class XStreamStax extends XStreamDriver { |
25 | 26 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2009 XStream Committers. | |
1 | * Copyright (C) 2009, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
20 | 20 | * @see com.thoughtworks.xstream.tools.benchmark.Product |
21 | 21 | * @see com.thoughtworks.xstream.XStream |
22 | 22 | * @see WstxDriver |
23 | * @deprecated As of 1.4.9 use JMH instead | |
23 | 24 | */ |
24 | 25 | public class XStreamWoodstox extends XStreamDriver { |
25 | 26 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2009 XStream Committers. | |
1 | * Copyright (C) 2009, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
20 | 20 | * @see com.thoughtworks.xstream.tools.benchmark.Product |
21 | 21 | * @see com.thoughtworks.xstream.XStream |
22 | 22 | * @see XomDriver |
23 | * @deprecated As of 1.4.9 use JMH instead | |
23 | 24 | */ |
24 | 25 | public class XStreamXom extends XStreamDriver { |
25 | 26 |
+2
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007, 2009 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2009, 2015 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 | * @see com.thoughtworks.xstream.tools.benchmark.Product |
22 | 22 | * @see com.thoughtworks.xstream.XStream |
23 | 23 | * @see XppDriver |
24 | * @deprecated As of 1.4.9 use JMH instead | |
24 | 25 | */ |
25 | 26 | public class XStreamXpp extends XStreamDriver { |
26 | 27 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2009 XStream Committers. | |
1 | * Copyright (C) 2009, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
20 | 20 | * @see com.thoughtworks.xstream.tools.benchmark.Product |
21 | 21 | * @see com.thoughtworks.xstream.XStream |
22 | 22 | * @see Xpp3Driver |
23 | * @deprecated As of 1.4.9 use JMH instead | |
23 | 24 | */ |
24 | 25 | public class XStreamXpp3 extends XStreamDriver { |
25 | 26 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2009 XStream Committers. | |
1 | * Copyright (C) 2009, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
20 | 20 | * @see com.thoughtworks.xstream.tools.benchmark.Product |
21 | 21 | * @see com.thoughtworks.xstream.XStream |
22 | 22 | * @see Xpp3DomDriver |
23 | * @deprecated As of 1.4.9 use JMH instead | |
23 | 24 | */ |
24 | 25 | public class XStreamXpp3DOM extends XStreamDriver { |
25 | 26 |
+4
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2015 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 | import java.util.Iterator; |
25 | 25 | import java.util.Date; |
26 | 26 | |
27 | /** | |
28 | * @deprecated As of 1.4.9 use JMH instead | |
29 | */ | |
27 | 30 | public class HtmlReporter implements Reporter { |
28 | 31 | |
29 | 32 | private final PrettyPrintWriter out; |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2007, 2008 XStream Committers. | |
1 | * Copyright (C) 2007, 2008, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
19 | 19 | * |
20 | 20 | * @author Jörg Schaible |
21 | 21 | * @since 1.3 |
22 | * @deprecated As of 1.4.9 use JMH instead | |
22 | 23 | */ |
23 | 24 | public class MultiReporter implements Reporter { |
24 | 25 |
+2
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2015 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 | * @author Joe Walnes |
25 | 25 | * @see com.thoughtworks.xstream.tools.benchmark.Harness |
26 | 26 | * @see Reporter |
27 | * @deprecated As of 1.4.9 use JMH instead | |
27 | 28 | */ |
28 | 29 | public class TextReporter implements Reporter { |
29 | 30 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2008, 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2008, 2009, 2011, 2015 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.9 use JMH instead | |
24 | 25 | */ |
25 | 26 | public class BasicTarget implements Target { |
26 | 27 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2008, 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2008, 2009, 2011, 2015 XStream Committers. | |
2 | 2 | * All rights reserved. |
3 | 3 | * |
4 | 4 | * The software in this package is published under the terms of the BSD |
25 | 25 | * |
26 | 26 | * @author Jörg Schaible |
27 | 27 | * @since 1.4 |
28 | * @deprecated As of 1.4.9 use JMH instead | |
28 | 29 | */ |
29 | 30 | public class ExtendedTarget implements Target { |
30 | 31 |
+2
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2015 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 | * @see com.thoughtworks.xstream.tools.benchmark.Harness |
22 | 22 | * @see Target |
23 | 23 | * @see JTree |
24 | * @deprecated As of 1.4.9 use JMH instead | |
24 | 25 | */ |
25 | 26 | public class JTreeTarget implements Target { |
26 | 27 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2009, 2011, 2015 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.9 use JMH instead | |
24 | 25 | */ |
25 | 26 | public class JavaBeanTarget implements Target { |
26 | 27 |
+2
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2015 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 | * @author Joe Walnes |
22 | 22 | * @see com.thoughtworks.xstream.tools.benchmark.Harness |
23 | 23 | * @see Target |
24 | * @deprecated As of 1.4.9 use JMH instead | |
24 | 25 | */ |
25 | 26 | public class ListTarget implements Target { |
26 | 27 |
+2
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2015 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 | |
16 | 16 | /** |
17 | 17 | * @see UserDefinedClassTarget |
18 | * @deprecated As of 1.4.9 use JMH instead | |
18 | 19 | */ |
19 | 20 | public class Person implements Serializable { |
20 | 21 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2008, 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2008, 2009, 2011, 2015 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.9 use JMH instead | |
24 | 25 | */ |
25 | 26 | public class ReflectionTarget implements Target { |
26 | 27 |
+2
-1
0 | 0 | /* |
1 | * Copyright (C) 2008, 2009, 2011 XStream Committers. | |
1 | * Copyright (C) 2008, 2009, 2011, 2015 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.9 use JMH instead | |
24 | 25 | */ |
25 | 26 | public class SerializableTarget implements Target { |
26 | 27 |
+2
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2015 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 | * @author Joe Walnes |
19 | 19 | * @see com.thoughtworks.xstream.tools.benchmark.Harness |
20 | 20 | * @see Target |
21 | * @deprecated As of 1.4.9 use JMH instead | |
21 | 22 | */ |
22 | 23 | public class StringTarget implements Target { |
23 | 24 |
+2
-1
0 | 0 | /* |
1 | 1 | * Copyright (C) 2006 Joe Walnes. |
2 | * Copyright (C) 2006, 2007 XStream Committers. | |
2 | * Copyright (C) 2006, 2007, 2015 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 | * @author Joe Walnes |
21 | 21 | * @see com.thoughtworks.xstream.tools.benchmark.Harness |
22 | 22 | * @see Target |
23 | * @deprecated As of 1.4.9 use JMH instead | |
23 | 24 | */ |
24 | 25 | public class UserDefinedClassTarget implements Target { |
25 | 26 |
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, 2011, 2012, 2013, 2015 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 2013, 2015, 2016 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.8</version> | |
16 | <version>1.4.9</version> | |
17 | 17 | </parent> |
18 | 18 | <artifactId>xstream-distribution</artifactId> |
19 | 19 | <packaging>pom</packaging> |
31 | 31 | <dependency> |
32 | 32 | <groupId>com.thoughtworks.xstream</groupId> |
33 | 33 | <artifactId>xstream-hibernate</artifactId> |
34 | <scope>runtime</scope> | |
35 | </dependency> | |
36 | <dependency> | |
37 | <groupId>com.thoughtworks.xstream</groupId> | |
38 | <artifactId>xstream-jmh</artifactId> | |
34 | 39 | <scope>runtime</scope> |
35 | 40 | </dependency> |
36 | 41 | <dependency> |
113 | 118 | </dependency> |
114 | 119 | <dependency> |
115 | 120 | <groupId>com.thoughtworks.xstream</groupId> |
116 | <artifactId>xstream-benchmark</artifactId> | |
121 | <artifactId>xstream-jmh</artifactId> | |
117 | 122 | <classifier>javadoc</classifier> |
118 | 123 | </dependency> |
119 | 124 | </dependencies> |
169 | 174 | </configuration> |
170 | 175 | </execution> |
171 | 176 | <execution> |
172 | <id>unpack-benchmark</id> | |
177 | <id>unpack-jmh</id> | |
173 | 178 | <phase>package</phase> |
174 | 179 | <goals> |
175 | 180 | <goal>unpack-dependencies</goal> |
176 | 181 | </goals> |
177 | 182 | <configuration> |
178 | <outputDirectory>${project.build.directory}/xsite/benchmark-javadoc</outputDirectory> | |
183 | <outputDirectory>${project.build.directory}/xsite/jmh-javadoc</outputDirectory> | |
179 | 184 | <overWriteReleases>false</overWriteReleases> |
180 | 185 | <overWriteSnapshots>true</overWriteSnapshots> |
181 | <includeArtifactIds>xstream-benchmark</includeArtifactIds> | |
186 | <includeArtifactIds>xstream-jmh</includeArtifactIds> | |
182 | 187 | <includeClassifiers>javadoc</includeClassifiers> |
183 | 188 | <includeScope>provided</includeScope> |
184 | 189 | </configuration> |
0 | <html> | |
1 | <!-- | |
2 | Copyright (C) 2015, 2016 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 10. December 2015 by Joerg Schaible | |
10 | --> | |
11 | <head> | |
12 | <title>Benchmarks</title> | |
13 | <style type="text/css"> | |
14 | #content td { text-align: right;} | |
15 | #content dt { font-weight: bold;} | |
16 | </style> | |
17 | </head> | |
18 | ||
19 | <body> | |
20 | <h2 id="introduction">Introduction</h2> | |
21 | ||
22 | <p>Benchmark results are always dependent on a very individual setup. Normally it is not useful to generalize such results | |
23 | for every use case, but it can give you a hint. However, if you're really in the need of maximum performance, you should | |
24 | probably create an own benchmark with your objects or even use a profiler to detect the real hot spots in your application.</p> | |
25 | ||
26 | <p>XStream uses the Java Microbenchmark Harness (<a href="http://openjdk.java.net/projects/code-tools/jmh/">JMH</a>) | |
27 | of the JDK Tools as benchmark framework starting with version 1.4.9. As result it contains a ZIP file | |
28 | (xstream-jmh-<version>-app.zip) as new artifact containing anything required to run the benchmarks. Unpack | |
29 | the file and use the scripts in the <em>bin</em> directory to execute the benchmarks. Use option -h to look at the | |
30 | options provided by JMH. You may exchange the libraries in the <em>lib</em> directory with other versions of | |
31 | XStream or the individual parsers or you may even add new JMH benchmarks to the default ones of XStream.</p> | |
32 | ||
33 | <p>All benchmark values below measure the average throughput in nanosecond per operation. JMH provides additional | |
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 | |
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> | |
39 | ||
40 | <h2 id="parser">Parser Benchmark</h2> | |
41 | ||
42 | <p>The values represent the average throughput of 15 runs with a single thread. The benchmarks emphasis the parser | |
43 | efficiency for different structures.</p> | |
44 | ||
45 | <table summary="Benchmark for all parsers supported by XStream using different object structures"> | |
46 | <tr> | |
47 | <th>Parser</th> | |
48 | <th>Text</th> | |
49 | <th>Array</th> | |
50 | <th>Nested</th> | |
51 | </tr> | |
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> | |
57 | </tr> | |
58 | <tr> | |
59 | <th>JDOM (1.1.3)</th> | |
60 | <td>6368317.636</td> | |
61 | <td>7910979.223</td> | |
62 | <td>3862796.027</td> | |
63 | </tr> | |
64 | <tr> | |
65 | <th>JDOM 2 (2.0.5)</th> | |
66 | <td>5767640.105</td> | |
67 | <td>10570210.653</td> | |
68 | <td>2980906.727</td> | |
69 | </tr> | |
70 | <tr> | |
71 | <th>DOM4J (1.6.1)</th> | |
72 | <td>7816280.084</td> | |
73 | <td>92998322.952</td> | |
74 | <td>2108075.646</td> | |
75 | </tr> | |
76 | <tr> | |
77 | <th>XOM (1.1)</th> | |
78 | <td>7950778.533</td> | |
79 | <td>38704485.310</td> | |
80 | <td>2471019.743</td> | |
81 | </tr> | |
82 | <tr> | |
83 | <th>StAX (BEA 1.2.0)</th> | |
84 | <td>3108517.699</td> | |
85 | <td>1310406.961</td> | |
86 | <td>669111.164</td> | |
87 | </tr> | |
88 | <tr> | |
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> | |
99 | </tr> | |
100 | <tr> | |
101 | <th>XPP (Xpp3 min 1.1.4c)</th> | |
102 | <td>2109341.076</td> | |
103 | <td>1309607.210</td> | |
104 | <td>3301732.767</td> | |
105 | </tr> | |
106 | <tr> | |
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> | |
117 | </tr> | |
118 | <tr> | |
119 | <th>Jettison (1.2)</th> | |
120 | <td>3002547.220</td> | |
121 | <td>1159238.555</td> | |
122 | <td>682182.733</td> | |
123 | </tr> | |
124 | </table> | |
125 | ||
126 | <dl> | |
127 | <dt>Text</dt> | |
128 | <dd>A single element with a text of 100.000 characters.</dd> | |
129 | <dt>Array</dt> | |
130 | <dd>A single element with 1.000 child elements.</dd> | |
131 | <dt>Nested</dt> | |
132 | <dd>Nested elements in 500 levels.</dd> | |
133 | </dl> | |
134 | ||
135 | <h2 id="converterType">Converter Type Benchmark</h2> | |
136 | ||
137 | <p>The values represent the average throughput of 16 runs with four threads using the Xpp3 parser for a structure | |
138 | with 1.000 elements. The benchmarks demonstrate the different converter types that can be used for a standard Java | |
139 | class.</p> | |
140 | ||
141 | <table summary="Benchmark for different converter types of XStream"> | |
142 | <tr> | |
143 | <th>Converter Type</th> | |
144 | <th>Throughput</th> | |
145 | </tr> | |
146 | <tr> | |
147 | <th>Custom</th> | |
148 | <td>11276718.384</td> | |
149 | </tr> | |
150 | <tr> | |
151 | <th>Java Bean</th> | |
152 | <td>28878706.293</td> | |
153 | </tr> | |
154 | <tr> | |
155 | <th>Reflection</th> | |
156 | <td>40085786.696</td> | |
157 | </tr> | |
158 | </table> | |
159 | ||
160 | <dl> | |
161 | <dt>Custom</dt> | |
162 | <dd>A converter especially written for the Java type to convert.</dd> | |
163 | <dt>Java Bean</dt> | |
164 | <dd>Usage of the generic JavaBeanConverter, since the Java type respects the Java Bean contract.</dd> | |
165 | <dt>Reflection</dt> | |
166 | <dd>Usage of the generic converter based on reflection.</dd> | |
167 | </dl> | |
168 | ||
169 | <h2 id="stringConverter">String Converter Benchmark</h2> | |
170 | ||
171 | <p>The values represent the average throughput of 16 runs with four threads using the Xpp3 parser for a structure | |
172 | with 10.000 string elements of various sizes and duplicates. The benchmarks demonstrate different implementations | |
173 | and configurations of the StringConverter.</p> | |
174 | ||
175 | <table summary="Benchmark for different StringConverter strategies"> | |
176 | <tr> | |
177 | <th>StringConverter Strategy</th> | |
178 | <th>Throughput</th> | |
179 | </tr> | |
180 | <tr> | |
181 | <th>No Cache</th> | |
182 | <td>19626160.696</td> | |
183 | </tr> | |
184 | <tr> | |
185 | <th>Intern</th> | |
186 | <td>23060982.052</td> | |
187 | </tr> | |
188 | <tr> | |
189 | <th>ConcurrentMap (length limit)</th> | |
190 | <td>21796001.29</td> | |
191 | </tr> | |
192 | <tr> | |
193 | <th>ConcurrentMap (unlimited)</th> | |
194 | <td>21378299.003</td> | |
195 | </tr> | |
196 | <tr> | |
197 | <th>Sync'd WeakCache (length limit)</th> | |
198 | <td>21838410.801</td> | |
199 | </tr> | |
200 | <tr> | |
201 | <th>Sync'd WeakCache (unlimited)</th> | |
202 | <td>22011251.691</td> | |
203 | </tr> | |
204 | </table> | |
205 | ||
206 | <dl> | |
207 | <dt>No Cache</dt> | |
208 | <dd>An implementation that does not cache deserialized String values with the consequence that repeated values | |
209 | will always allocate separate memory.</dd> | |
210 | <dt>Intern</dt> | |
211 | <dd>An implementation that uses String.intern() to cache the individual values. The memory pool used for the | |
212 | values is dependent on the JDK version. Up to Java 7 this was the permanent generation space i.e. the memory has | |
213 | to be shared with all loaded classes. It is up to the garbage collection when these string values are freed | |
214 | again.</dd> | |
215 | <dt>ConcurrentMap (length limit)</dt> | |
216 | <dd>An implementation that uses a ConcurrentHashMap as cache for strings of limited length (38 characters). The | |
217 | lifetime of the cache is equivalent with the lifetime of the XStream instance.</dd> | |
218 | <dt>ConcurrentMap (unlimited)</dt> | |
219 | <dd>An implementation that uses a ConcurrentHashMap as cache for all strings. The lifetime of the cache is | |
220 | equivalent with the lifetime of the XStream instance.</dd> | |
221 | <dt>Sync'd WeakCache (length limit)</dt> | |
222 | <dd>An implementation that uses a WeakCache for strings of limited length (38 characters). This cache uses weak | |
223 | references for its keys and values. An entry is therefore only kept as long as the deserialized object structure | |
224 | is referencing it. This is XStream's default strategy.</dd> | |
225 | <dt>Syn'd WeakCache (unlimited)</dt> | |
226 | <dd>An implementation that uses a WeakCache for all strings. This cache uses weak references for its keys and | |
227 | values. An entry is therefore ony kept as long as the deserialized object structure is referencing it.</dd> | |
228 | </dl> | |
229 | ||
230 | <h2 id="nameCoder">Name Coder Benchmark</h2> | |
231 | ||
232 | <p>The values represent the average throughput of 25 runs with four threads using the Xpp3 parser for a structure | |
233 | with 250 nested elements using names invalid for XML elements. The benchmarks demonstrate different implementation | |
234 | strategies for a NameCoder to create valid tag names in XML.</p> | |
235 | ||
236 | <table summary="Benchmark for different NameCoder strategies"> | |
237 | <tr> | |
238 | <th>NameCoder Implementation</th> | |
239 | <th>Throughput</th> | |
240 | </tr> | |
241 | <tr> | |
242 | <th>No Coding</th> | |
243 | <td>7299475.975</td> | |
244 | </tr> | |
245 | <tr> | |
246 | <th>Dollar Coding</th> | |
247 | <td>7767196.902</td> | |
248 | </tr> | |
249 | <tr> | |
250 | <th>Escaped Underscore Coding</th> | |
251 | <td>9894393.289</td> | |
252 | </tr> | |
253 | <tr> | |
254 | <th>Cached Escaped Underscore Coding</th> | |
255 | <td>7867671.962</td> | |
256 | </tr> | |
257 | <tr> | |
258 | <th>Xml Friendly Coding</th> | |
259 | <td>8635501.208</td> | |
260 | </tr> | |
261 | </table> | |
262 | ||
263 | <dl> | |
264 | <dt>No Coding</dt> | |
265 | <dd>An implementation that does not encode the names of XML elements. It relies on the fact that the object graph | |
266 | does not contain elements with invalid XML names, because the name of the class types and members are either | |
267 | conforming or have been aliased.</dd> | |
268 | <dt>Dollar Coding</dt> | |
269 | <dd>An implementation that uses String.replace to replace any dollar sign with '·' (middle dot), a valid | |
270 | character normally not used for Java identifiers. In typical Java code there are no other invalid characters used | |
271 | for Java identifiers, however, Java allows identifiers to contain a wide range of UTF-8 characters and the JVM | |
272 | has even less restrictions.</dd> | |
273 | <dt>Escaped Underscore Coding</dt> | |
274 | <dd>An implementation that uses a StringBuilder to create the XML name by replacing any dollar sign with '_-' and | |
275 | escapes every plain underscore with two ones. The implementation will therefore only use characters in the | |
276 | standard ASCII range. It is not possible to use a simple minus sign as replacement because it is not a valid | |
277 | first character for XML names. However, the comments about Java identifiers and JVM identifiers from the Dollar | |
278 | Coding still apply.</dd> | |
279 | <dt>Cached Escaped Underscore Coding</dt> | |
280 | <dd>An implementation that implements a cache for the NameCoder that escapes the underscores.</dd> | |
281 | <dt>Xml Friendly Coding</dt> | |
282 | <dd>The default implementation of XStream using a StringBuilder and a cache, encoding any character that is | |
283 | invalid for XML names. It implements also the underscore escaping for compatibility reasons with XML created by | |
284 | earlier versions of XStream.</dd> | |
285 | </dl> | |
286 | </body> | |
287 | </html> | |
288 | ⏎ |
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 XStream committers. | |
4 | 4 | All rights reserved. |
5 | 5 | |
6 | 6 | The software in this package is published under the terms of the BSD |
22 | 22 | <li><b>API changes</b>: Any changes to the API that could impact existing users.</li> |
23 | 23 | </ul> |
24 | 24 | |
25 | <p>Full details can be found in Jira's | |
26 | <a href="http://jira.codehaus.org/browse/XSTR?report=com.atlassian.jira.plugin.system.project:roadmap-panel">Roadmap</a> and | |
27 | <a href="http://jira.codehaus.org/browse/XSTR?report=com.atlassian.jira.plugin.system.project:changelog-panel">Change Log</a>. | |
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. | |
28 | 28 | </p> |
29 | ||
29 | 30 | <!-- |
30 | 31 | <h1 id="upcoming-1.4.x">Upcoming 1.4.x maintenance release</h1> |
31 | 32 | |
32 | 33 | <p>Not yet released.</p> |
33 | 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 | ||
34 | 101 | <h1 id="1.4.8">1.4.8</h1> |
35 | 102 | |
36 | 103 | <p>Released February 18, 2015.</p> |
45 | 112 | |
46 | 113 | <ul> |
47 | 114 | <li>Detect Java 9 runtime.</li> |
48 | <li>XSTR-767: Deserialization of referenced lambda expressions fail.</li> | |
49 | <li>XSTR-762: Private method readResolve() called on base classes.</li> | |
50 | <li>XSTR-761: Support ignored serialPersistentField at deserialization time.</li> | |
51 | <li>XSTR-755: ExternalizableConverter does not respect writeReplace and readResolve.</li> | |
52 | <li>XSTR-757: Deserialized TreeSet does not honor remove(Object) return value contract.</li> | |
53 | <li>XSTR-759: Support deserialization of <a href="http://www.w3.org/TR/NOTE-datetime">W3C datetime format</a> | |
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> | |
54 | 121 | in DateConverter with Java 7 runtime.</li> |
55 | 122 | <li>Fix: DateConverter ignores provided locale.</li> |
56 | <li>XSTR-768: ISO8601GregorianCalendarConverter may set invalid time zone for Joda-Time.</li> | |
123 | <li>JIRA:XSTR-768: ISO8601GregorianCalendarConverter may set invalid time zone for Joda-Time.</li> | |
57 | 124 | <li>Fix: WeakCache.entrySet().iterator().next.setValue(value) returns the reference instead of the old value.</li> |
58 | 125 | <li>Fix: SqlTimestampConverter throws IllegalArgumentException instead of ConversionException on fromString().</li> |
59 | 126 | <li>Fix: CGLIBEnhancedConverter does not initialize transient members of parent after deserialization.</li> |
60 | <li>XSTR-763: Set scope of org.json:json to test instead declaring the dependency as optional.</li> | |
127 | <li>JIRA:XSTR-763: Set scope of org.json:json to test instead declaring the dependency as optional.</li> | |
61 | 128 | </ul> |
62 | 129 | |
63 | 130 | <h2>API changes</h2> |
211 | 278 | <li>Current IBM JDK for Java 1.4.2 no longer has a reverse field ordering.</li> |
212 | 279 | <li>LongConverter supports now positive hex and octal numbers over Long.MAX_VALUE within 64 bit.</li> |
213 | 280 | <li>Fix: Sun14RefectionProvider ignores a provided FieldDictionary.</li> |
214 | <li>JIRA:XSTR-457: Do not write 'defined-in' attribute it not needed.</li> | |
281 | <li>JIRA:XSTR-457: Do not write 'defined-in' attribute if not needed.</li> | |
215 | 282 | <li>JettisonMappedXmlDriver provides better support to overwrite its create methods.</li> |
216 | 283 | <li>JIRA:XSTR-685: StAX based drivers (StaxDriver and JettisonMappedXmlDriver) are not closing internal input |
217 | 284 | stream reading from file or URL.</li> |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | 2 | Copyright (C) 2005, 2006 Joe Walnes. |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013, 2014, 2015 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013, 2014, 2015, 2016 XStream committers. | |
4 | 4 | All rights reserved. |
5 | 5 | |
6 | 6 | The software in this package is published under the terms of the BSD |
127 | 127 | <td>normal</td> |
128 | 128 | </tr> |
129 | 129 | <tr> |
130 | <td><a href="javadoc/com/thoughtworks/xstream/converters/extended/NamedCollectionConverter.html">NamedArrayConverter</a></td> | |
130 | <td><a href="javadoc/com/thoughtworks/xstream/converters/extended/NamedArrayConverter.html">NamedArrayConverter</a></td> | |
131 | 131 | <td>any kind of array</td> |
132 | 132 | <td class="example"> |
133 | 133 | <<i>string</i>-array><br/> |
252 | 252 | <td><a href="javadoc/com/thoughtworks/xstream/converters/extended/NamedCollectionConverter.html">NamedCollectionConverter</a></td> |
253 | 253 | <td>java.util.ArrayList<br/>java.util.LinkedList<br/>java.util.HashSet<br/>java.util.Vector<br/>java.util.LinkedHashSet</td> |
254 | 254 | <td class="example"> |
255 | <linked-list><br/> | |
256 | <string>apple</string><br/> | |
257 | <string>banana</string><br/> | |
258 | <big-decimal>12345.4555</big-decimal><br/> | |
259 | </linked-list> | |
260 | </td> | |
261 | <td>The objects inside the collection can be any type of objects, including nested collections. Should | |
262 | be registered locally or for an individual Collection type.</td> | |
255 | <fruits><br/> | |
256 | <fruit>apple</fruit><br/> | |
257 | <fruit>banana</fruit><br/> | |
258 | <fruit>orange</fruit><br/> | |
259 | </fruits> | |
260 | </td> | |
261 | <td>The objects inside the collection can be of any type shared between the objects. Should be | |
262 | registered locally or for an individual Collection type.</td> | |
263 | 263 | <td> </td> |
264 | 264 | </tr> |
265 | 265 | <tr> |
279 | 279 | </td> |
280 | 280 | <td>Both key and values can be any type of objects. If key or value are written as attributes or if |
281 | 281 | the value is written as text of the entry element, those types must be handled by a |
282 | SingleValueConverter. Should be registered locally or for an individual Map type.</td> | |
282 | <a href="javadoc/com/thoughtworks/xstream/converters/SingleValueConverter.html">SingleValueConverter</a>. | |
283 | Should be registered locally or for an individual Map type.</td> | |
283 | 284 | <td> </td> |
284 | 285 | </tr> |
285 | 286 | <tr> |
608 | 609 | <td>Available under Java 1.4 or greater.</td> |
609 | 610 | <td>normal</td> |
610 | 611 | </tr> |
612 | <tr> | |
613 | <td><a href="javadoc/com/thoughtworks/xstream/converters/extended/PathConverter.html">PathConverter</a></td> | |
614 | <td>java.nio.file.Path</td> | |
615 | <td class="example"><path>../dir/file.txt</path></td> | |
616 | <td>Available under Java 1.7 or greater.</td> | |
617 | <td>normal</td> | |
618 | </tr> | |
611 | 619 | |
612 | 620 | <!-- .................................................................................................. --> |
613 | 621 | <tr> |
739 | 747 | </td> |
740 | 748 | <td>Only automatically registered if runtime has AWT support.<br/> |
741 | 749 | <b>Warning:</b> The AWT toolkit is definitely initialized when a TextAttribute is deserialized.</td> |
750 | <td>normal</td> | |
751 | </tr> | |
752 | ||
753 | <!-- .................................................................................................. --> | |
754 | <tr> | |
755 | <td colspan="5" class="headerRow"><h1 id="java.awt.font">java.awt.font</h1></td> | |
756 | </tr> | |
757 | <tr> | |
758 | <th>Converter</th> | |
759 | <th>Supported types</th> | |
760 | <th>Example</th> | |
761 | <th>Notes</th> | |
762 | <th>Prio</th> | |
763 | </tr> | |
764 | <tr> | |
765 | <td><a href="javadoc/com/thoughtworks/xstream/converters/extended/ActivationDataFlavorConverter.html">ActivationDataFlavorConverter</a></td> | |
766 | <td>javax.activation.ActivationDataFlavor</td> | |
767 | <td class="example"> | |
768 | <activation-data-flavor><br/> | |
769 | <mimeType>application/x-junit</mimeType><br/> | |
770 | <humanRepresentableName>JUnit</humanRepresentableName><br/> | |
771 | <representationClass>java.io.InputStream</representationClass><br/> | |
772 | </activation-data-flavor> | |
773 | </td> | |
774 | <td>Available under Java 1.6 or greater. Only automatically registered if runtime has AWT support.<br/> | |
742 | 775 | <td>normal</td> |
743 | 776 | </tr> |
744 | 777 |
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 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2015, 2016 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.8</span></h1> | |
20 | <h1 id="stable">Stable Version: <span class="version">1.4.9</span></h1> | |
21 | 21 | |
22 | 22 | <ul> |
23 | <li><b><a href="https://nexus.codehaus.org/content/repositories/releases/com/thoughtworks/xstream/xstream-distribution/1.4.8/xstream-distribution-1.4.8-bin.zip">Binary distribution:</a></b> | |
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> | |
24 | 24 | Contains the XStream jar files, the Hibernate and Benchmark modules and all the dependencies.</li> |
25 | <li><b><a href="https://nexus.codehaus.org/content/repositories/releases/com/thoughtworks/xstream/xstream-distribution/1.4.8/xstream-distribution-1.4.8-src.zip">Source distribution:</a></b> | |
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> | |
26 | 26 | Contains the complete XStream project as if checked out from the Subversion version tag.</li> |
27 | <li><b><a href="https://nexus.codehaus.org/content/repositories/releases/com/thoughtworks/xstream/xstream/1.4.8/xstream-1.4.8.jar">XStream Core only:</a> | |
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> | |
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="https://nexus.codehaus.org/content/repositories/releases/com/thoughtworks/xstream/xstream-hibernate/1.4.8/xstream-hibernate-1.4.8.jar">XStream Hibernate module:</a></b> | |
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> | |
30 | 30 | The xstream-hibernate.jar as it is downloaded automatically when it is referenced as Maven dependency.</li> |
31 | <li><b><a href="https://nexus.codehaus.org/content/repositories/releases/com/thoughtworks/xstream/xstream-benchmark/1.4.8/xstream-benchmark-1.4.8.jar">XStream Benchmark module:</a></b> | |
32 | The xstream-benchmark.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> | |
33 | 33 | </ul> |
34 | 34 | |
35 | <!-- | |
35 | 36 | <h1 id="snapshot">Latest Snapshot HEAD revision</h1> |
36 | 37 | |
37 | 38 | <p>Below are builds of the latest HEAD version of XStream from the <a href="repository.html">repository</a>.</p> |
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> |
49 | 50 | |
50 | 51 | <ul> |
51 | <li><a href="https://nexus.codehaus.org/content/groups/public/com/thoughtworks/xstream/xstream-distribution/1.4.9-SNAPSHOT/">Complete distributions (1.4.x)</a></li> | |
52 | <li><a href="https://nexus.codehaus.org/content/groups/public/com/thoughtworks/xstream/xstream/1.4.9-SNAPSHOT/">XStream Core only (1.4.x)</a></li> | |
53 | <li><a href="https://nexus.codehaus.org/content/groups/public/com/thoughtworks/xstream/xstream-hibernate/1.4.9-SNAPSHOT/">XStream Hibernate module (1.4.x)</a></li> | |
54 | <li><a href="https://nexus.codehaus.org/content/groups/public/com/thoughtworks/xstream/xstream-benchmark/1.4.9-SNAPSHOT/">XStream Benchmark module (1.4.x)</a></li> | |
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> | |
55 | 56 | </ul> |
57 | --> | |
56 | 58 | |
57 | 59 | <h1 id="previous-releases">Previous Releases</h1> |
58 | 60 | |
59 | 61 | <p>Previous releases of XStream are also available. However, use of the latest stable version is recommended.</p> |
60 | 62 | |
61 | 63 | <ul> |
62 | <li><a href="http://repo.maven.apache.org/maven2/com/thoughtworks/xstream/xstream/">Previous releases (>= 1.2)</a></li> | |
63 | <li><a href="http://repo.maven.apache.org/maven2/xstream/xstream/">Previous releases (<= 1.2)</a></li> | |
64 | <li><a href="http://repo.maven.apache.org/maven2/com/thoughtworks/xstream/xstream/">Previous releases (>= 1.2)</a></li> | |
65 | <li><a href="http://repo.maven.apache.org/maven2/xstream/xstream/">Previous releases (<= 1.2)</a></li> | |
64 | 66 | </ul> |
65 | 67 | |
66 | 68 | <h1 id="optional-deps">Optional Dependencies</h1> |
67 | 69 | |
68 | 70 | <ul> |
69 | <li>Supported XML parsers and packages: | |
70 | <ul> | |
71 | <li><a href="http://repo.maven.apache.org/maven2/xmlpull/xmlpull/1.1.3.1/xmlpull-1.1.3.1.jar">XmlPull</a>, the <a href="http://www.xmlpull.org/">XML pull parser API</a> and factory to detect available implementations.</li> | |
72 | <li><a href="http://www.extreme.indiana.edu/dist/java-repository/xpp3/jars/xpp3_min-1.1.4c.jar">Xpp3</a>, an XML pull parser (recommended).</li> | |
73 | <li><a href="http://downloads.sourceforge.net/kxml/kxml2-2.3.0.jar">kXML2</a> or <a href="http://downloads.sourceforge.net/kxml/kxml2-min-2.3.0.jar">kXML2-min</a>, an XML pull parser.</li> | |
74 | <li><a href="http://downloads.sourceforge.net/dom4j/dom4j-1.6.1.zip">DOM4J</a>, easy XML representation and manipulation framework.</li> | |
75 | <li><a href="http://www.jdom.org/dist/binary/archive/jdom-1.1.3.zip">JDOM</a>, easy XML representation and manipulation (requires Java 1.2, superseded by JDOM2).</li> | |
76 | <li><a href="http://www.jdom.org/dist/binary/jdom2-2.0.5.zip">JDOM2</a>, easy XML representation and manipulation, successor of JDOM (requires Java 5).</li> | |
77 | <li>StaX, the <a href="http://dist.codehaus.org/stax/jars/stax-1.2.0.jar">reference implementation</a> of the <a href="http://dist.codehaus.org/stax/jars/stax-api-1.0.1.jar">Streaming API for XML</a>.</li> | |
78 | <li><a href="http://woodstox.codehaus.org/3.2.7/wstx-asl-3.2.7.jar">Woodstox</a>, an alternate open source StaX implementation.</li> | |
79 | <li><a href="http://www.cafeconleche.org/XOM/xom-1.1.jar">XOM</a>, another alternative XML API.</li> | |
80 | </ul> | |
81 | </li> | |
82 | <li>Other optional 3rd party dependencies: | |
83 | <ul> | |
84 | <li><a href="http://downloads.sourceforge.net/joda-time/joda-time-1.6.zip">Joda Time</a> for optional ISO8601 date/time formats.</li> | |
85 | <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> | |
86 | <li><a href="http://repository.codehaus.org/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> | |
87 | <li><a href="http://repository.codehaus.org/org/codehaus/jettison/jettison/1.0.1/jettison-1.0.1.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> | |
88 | </ul> | |
89 | </li> | |
71 | <li>Supported XML parsers and packages: | |
72 | <ul> | |
73 | <li><a href="http://repo.maven.apache.org/maven2/xmlpull/xmlpull/1.1.3.1/xmlpull-1.1.3.1.jar">XmlPull</a>, the <a href="http://www.xmlpull.org/">XML pull parser API</a> and factory to detect available implementations.</li> | |
74 | <li><a href="http://www.extreme.indiana.edu/dist/java-repository/xpp3/jars/xpp3_min-1.1.4c.jar">Xpp3</a>, an XML pull parser (recommended).</li> | |
75 | <li><a href="http://downloads.sourceforge.net/kxml/kxml2-2.3.0.jar">kXML2</a> or <a href="http://downloads.sourceforge.net/kxml/kxml2-min-2.3.0.jar">kXML2-min</a>, an XML pull parser.</li> | |
76 | <li><a href="http://downloads.sourceforge.net/dom4j/dom4j-1.6.1.zip">DOM4J</a>, easy XML representation and manipulation framework.</li> | |
77 | <li><a href="http://www.jdom.org/dist/binary/archive/jdom-1.1.3.zip">JDOM</a>, easy XML representation and manipulation (requires Java 1.2, superseded by JDOM2).</li> | |
78 | <li><a href="http://www.jdom.org/dist/binary/jdom2-2.0.5.zip">JDOM2</a>, easy XML representation and manipulation, successor of JDOM (requires Java 5).</li> | |
79 | <li>StaX, the <a href="http://repo.maven.apache.org/maven2/stax/stax-1.2.0.jar">reference implementation</a> of the <a href="http://repo.maven.apache.org/maven2/stax/stax-api-1.0.1.jar">Streaming API for XML</a>.</li> | |
80 | <li><a href="http://repo.maven.apache.org/maven2/woodstox/wstx-asl-3.2.7.jar">Woodstox</a>, an alternate open source StaX implementation.</li> | |
81 | <li><a href="http://www.cafeconleche.org/XOM/xom-1.1.jar">XOM</a>, another alternative XML API.</li> | |
82 | </ul> | |
83 | </li> | |
84 | <li>Other optional 3rd party dependencies: | |
85 | <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> | |
87 | <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 | <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 | <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> | |
90 | </ul> | |
91 | </li> | |
90 | 92 | </ul> |
91 | 93 | |
92 | 94 | <h1 id="hibernate">Dependencies Hibernate Module</h1> |
107 | 109 | </li> |
108 | 110 | </ul> |
109 | 111 | |
112 | <h1 id="jmh">Dependencies JMH Module</h1> | |
113 | ||
114 | <ul> | |
115 | <li>JMH dependencies: | |
116 | <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> | |
119 | </ul> | |
120 | </li> | |
121 | </ul> | |
122 | ||
110 | 123 | </body> |
111 | 124 | </html> |
117 | 117 | |
118 | 118 | <!-- ...................................................... --> |
119 | 119 | <h2 id="Compatibility_unsupported_JVM">Are there plans to provide enhanced mode support to other JVMs?</h2> |
120 | <p>Yes. <a href="list-user.html">Let us know</a> which JVM you would like supported.</p> | |
120 | <p>Yes. <a href="mailing-lists.html">Let us know</a> which JVM you would like supported.</p> | |
121 | 121 | |
122 | 122 | <!-- ...................................................... --> |
123 | 123 | <h2 id="Compatibility_no_enhanced_mode">When should I use XStream not in enhanced mode?</h2> |
130 | 130 | <h2 id="Compatibility_SecurityManager">Which permissions does XStream need when running with an active SecurityManager?</h2> |
131 | 131 | |
132 | 132 | <p>This depends on the mode XStream is running in. Refer to the |
133 | <a href="http://svn.xstream.codehaus.org/browse/xstream/trunk/xstream/src/test/com/thoughtworks/acceptance/SecurityManagerTest.java">SecurityManagerTest</a> | |
133 | <a href="https://github.com/x-stream/xstream/blob/master/xstream/src/test/com/thoughtworks/acceptance/SecurityManagerTest.java">SecurityManagerTest</a> | |
134 | 134 | for details. Actually XStream's converters try to check since version 1.4.6 any critical operation, before they |
135 | 135 | claim to be able to handle a type. As consequence XStream can behave differently running under a SecurityManager. |
136 | 136 | E.g. if the SecurityManager does not permit to create an instance for a derived class of ObjectOutputStream, the |
169 | 169 | <p>Yes. This was announced with the last 1.2.x release and was done to support the type inheritance of XML schemas. However, XStream is delivered with the |
170 | 170 | <a href="javadoc/com/thoughtworks/xstream/io/HierarchicalStreamDriver.html">XStream12FieldKeySorter</a> that can be used to |
171 | 171 | <a href="#Serialization_sort_fields">sort the fields</a> according XStream 1.2.2.</p> |
172 | ||
173 | <!-- ...................................................... --> | |
174 | <h2 id="Compatibility_WebSphere_8">WebShere 8 can no longer use XStream 1.4.x?</h2> | |
175 | ||
176 | <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 | 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 | |
178 | scanning fails for class files targeting a higher JDK runtime as currently used by WebSphere. Please, consult your WebSphere documentation, how to turn off the | |
179 | scanning for individual files by providing an <a href="http://www-01.ibm.com/support/knowledgecenter/SSAW57_8.0.0/com.ibm.websphere.nd.doc/info/ae/ae/trun_app_reduce_annot.html?cp=SSAW57_8.0.0%2F1-8-12-0">amm.filter.proeprties</a> | |
180 | file.</p> | |
172 | 181 | |
173 | 182 | |
174 | 183 | <!-- ****************************************************** --> |
256 | 265 | always with the boxed types and converts to primitives types on the fly. However, for method and field type |
257 | 266 | signatures the difference is essential. Nevertheless it is possible to register derived versions of the converters |
258 | 267 | that are able to respect the aliasing with some minor effort. Following lines are taken from the AliasTest in the |
259 | acceptence tests:</p> | |
268 | acceptance tests:</p> | |
260 | 269 | <div class="Source Java"><pre>XStream xstream = new XStream(); |
261 | 270 | Mapper mapper = new MapperWrapper(xstream.getMapper().lookupMapperOfType(ArrayMapper.class)) { |
262 | 271 | public Class realClass(String elementName) { |
298 | 307 | <p>Yes.</p> |
299 | 308 | |
300 | 309 | <!-- ...................................................... --> |
310 | <h2 id="Serialization_referencing_immutable_types">Can immutable types be referenced?</h2> | |
311 | <p>Adding a type as immutable implies that a referencing marshaller strategy will write each occurrence of the same | |
312 | instance separately into the stream without referencing it, i.e. instance of those types are normally never referenced | |
313 | at deserialization time. Such referenced can exist though for persisted streams when a type is added as immutable in | |
314 | later versions. In such cases the type can be added as immutable, but still referenceable.</p> | |
315 | ||
316 | <p>Any immutable type could be dereferenced before version 1.4.9, but only at the cost of a large memory footprint. | |
317 | Since version 1.4.9 this is only possible if the immutable type has been explicitly declared as referenceable too. | |
318 | This should be done only if backward compatibility is required and a persisted stream may contain a reference of such | |
319 | an instance at all. Any type that has been declared as immutable by XStream itself before version 1.4 will not be | |
320 | referenceable now by default (all primitive types and their boxed counterparts, java.lang.Class, java.lang.String, | |
321 | java.math.BigInteger, java.math.BigDecimal, java.io.File, java.net.URL, and java.awt.font.TextAttribute). All other | |
322 | immutable types (java.util.Currency, java.util.UUID, java.net.URI, java.nio.charset.Charset and the empty collection | |
323 | types) will currently still be referenceable at deserialization time for compatibility reasons. This support by | |
324 | default will be dropped with the next major version of XStream. You can always overwrite the default by adding the same | |
325 | type again as immutable with a different value for the referenceable flag.</p> | |
326 | ||
327 | <!-- ...................................................... --> | |
301 | 328 | <h2 id="Serialization_lambda_null">My lambda expression is serialized to null!</h2> |
302 | 329 | <p>Non-serializable lambda expressions to not contain any information at all to recreate the instance at a later time again. These instances are treated as temporary |
303 | 330 | objects and as such XStream has no other possibility as to serialize null instead.</p> |
531 | 558 | path like "/doc/list/elem/field" XStream will then generate "/doc[1]/list[1]/elem[1]/field[1]". The two notations |
532 | 559 | are transparent at deserialization time.</p> |
533 | 560 | |
561 | <!-- ...................................................... --> | |
562 | <h2 id="XML_entities">Does XStream support entities?</h2> | |
563 | ||
564 | <p>Entity support is completely dependent on the XML parser. XStream uses by default the Xpp3 parser that does not | |
565 | support entities at all (like the kXML2 parser). Other parsers support entities, but they might have been turned | |
566 | off to avoid <a href="#Security_XXEVulnerability">XXE vulnerability</a>. To enable the entities again, you have to | |
567 | overload the individual method of the | |
568 | <a href="javadoc/com/thoughtworks/xstream/io/HierarchicalStreamDriver.html">HierarchicalStreamDriver</a> | |
569 | implementation that generated the parser factory.</p> | |
534 | 570 | |
535 | 571 | <!-- ****************************************************** --> |
536 | 572 | <h1 id="JSON">JSON specifics</h1> |
540 | 576 | |
541 | 577 | <p>As always, first for historical reasons! Main difference is that the |
542 | 578 | <a href="javadoc/com/thoughtworks/xstream/io/json/JettisonMappedXmlDriver.html">JettisonMappedXmlDriver</a> is a |
543 | thin wrapper around <a href="http://jettison.codehaus.org">Jettison</a> in combination with the | |
579 | thin wrapper around <a href="https://github.com/jettison-json">Jettison</a> in combination with the | |
544 | 580 | <a href="javadoc/com/thoughtworks/xstream/io/xml/StaxDriver.html">StaxDriver</a>, while the |
545 | 581 | <a href="javadoc/com/thoughtworks/xstream/io/json/JsonHierarchicalStreamDriver.html">JsonHierarchicalStreamDriver</a> |
546 | 582 | uses an own more flexible implementation, but can only be used to generate JSON, deserialization is not implemented.</p> |
660 | 696 | <ul> |
661 | 697 | <li>Prevent the usage of the reflection-based converters. Register an own converter with priority LOW that claims |
662 | 698 | to handle any type and throw a ConversionException in the marshal and unmarshal methods.</li> |
663 | <li>Overload XStream.setupConverters() and register only converters for the types that are allowd in your object | |
699 | <li>Overload XStream.setupConverters() and register only converters for the types that are allowed in your object | |
664 | 700 | graph.</li> |
665 | 701 | <li>Provide own implementations for ConverterLookup and ConverterRegistry constructing the XStream. Your |
666 | 702 | implementation can then select the appropriate converter at lookup time on its own or prevent the registration of |
667 | 703 | specific converters.</li> |
704 | <li>Since XStream 1.4.7 you have the possibility to <a href="security.html">setup rules</a> for the class types | |
705 | that are allowed to be deserialized.</li> | |
668 | 706 | </ul> |
707 | ||
708 | <!-- ...................................................... --> | |
709 | <h2 id="Security_XXEVulnerability">Is XStream XXE vulnerable?</h2> | |
710 | ||
711 | <p>XStream does not contain an own XML parser, therefore it depends on the parser selected with the | |
712 | <a href="javadoc/com/thoughtworks/xstream/io/HierarchicalStreamDriver.html">HierarchicalStreamDriver</a> | |
713 | 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 | |
715 | entities by default. Status for the different supported XML parsers:</p> | |
716 | ||
717 | <table summary="Comparison of drivers regarding XEE vulnerability"> | |
718 | <tr><th>Driver</th><th>Vulnerable</th><th>Explanation</th></tr> | |
719 | <tr><td>BEAStaxDriver</td><td>yes</td><td>Setting <code>XMLInputFactory.setProperty( | |
720 | XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false)</code> is only respected for general entities, but not | |
721 | for parameter entities.</td></tr> | |
722 | <tr><td>Dom4JDriver</td><td>no</td><td>Driver turns off DOCTYPE processing to suppress handling of external | |
723 | entities with SAX reader in use.</td></tr> | |
724 | <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 | |
726 | entities only for Java 6 or lower, fails for parameterized entities.</td></tr> | |
727 | <tr><td>JDomDriver</td><td>no</td><td>Driver turns off DOCTYPE processing to suppress handling of external | |
728 | entities with SAX reader in use.</td></tr> | |
729 | <tr><td>JDom2Driver</td><td>no</td><td>Driver turns off DOCTYPE processing to suppress handling of external | |
730 | entities with SAX reader in use.</td></tr> | |
731 | <tr><td>KXml2DomDriver</td><td>no</td><td>kXML2 parser does not support entities.</td></tr> | |
732 | <tr><td>KXml2Driver</td><td>no</td><td>kXML2 parser does not support entities.</td></tr> | |
733 | <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> | |
737 | <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 | |
739 | documentation) and a test should be made on the target platform to ensure that the parser respects the setting.</td></tr> | |
740 | <tr><td>WstxDriver</td><td>no</td><td>Driver turns off support for external entities for the Woodstox StAX | |
741 | parser.</td></tr> | |
742 | <tr><td>XomDriver</td><td>yes</td><td>XOM uses an internal list to test for available SAX parsers on the | |
743 | classpath and will explicitly enable external entities, even if the SAXBuilder instance is provided manually.</td></tr> | |
744 | </table> | |
745 | ||
746 | <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> | |
669 | 749 | |
670 | 750 | <!-- ****************************************************** --> |
671 | 751 | <h1 id="Other_Products">Comparison to other products</h1> |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | 2 | Copyright (C) 2005, 2006 Joe Walnes. |
3 | Copyright (C) 2006, 2007, 2013 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2013, 2015 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>XStream is nothing without contributions from the user community. There are many ways to |
19 | 19 | contribute. We are constantly working on the software and documentation, so it's a good |
20 | idea to contact the team. For normal question about usage or possible misbehavior, please contact | |
21 | us on the <a href="list-user.html">user</a> mailing list. To discuss further development of XStream, | |
22 | you may contact us on <a href="list-dev.html">development</a> mailing lists to avoid duplicating effort.</p> | |
20 | idea to contact the team. For question about usage or possible misbehavior, please contact | |
21 | us on the <a href="mailing-lists.html">mailing list</a>. This is also the place to discuss further | |
22 | development of XStream.</p> | |
23 | 23 | |
24 | 24 | <h2 id="help">Help</h2> |
25 | <p>The correct place if you are looking for help is the <a href="list-user.html">user</a> mailing list. You | |
25 | <p>The correct place if you are looking for help is the <a href="mailing-lists.html">mailing list</a>. You | |
26 | 26 | get there a much wider audience from other users and also the developers are reading and answering there |
27 | 27 | your questions.</p> |
28 | 28 | |
38 | 38 | <p>We eat our own dogfood, but we're also happy to feed other people's dogs (if you'll excuse |
39 | 39 | a stretched <span style="text-decoration:line-through">dachshund</span> metaphor!). If you want to |
40 | 40 | request a new feature you can either make a request through the <a href="issues.html">issue tracker</a> |
41 | or by sending a message to the <a href="list-dev.html">development mailing list</a>. The benefit of any | |
41 | or by sending a message to the <a href="mailing-lists.html">mailing list</a>. The benefit of any | |
42 | 42 | new features will be discussed on the mailing list, so its a good idea to sign up so that you can stick your |
43 | 43 | oar in.</p> |
44 | 44 | |
45 | 45 | <h2 id="bug-reports">Bug Reports</h2> |
46 | 46 | <p>You can report bugs through the <a href="issues.html">issue tracker</a> interface or in case you are |
47 | 47 | in doubt whether it is really a bug or just a wrong usage, you may ask first posting to the |
48 | <a href="list-user.html">user mailing list</a>. Additional brownie points are awarded for bug reports that | |
48 | <a href="mailing-lists.html">mailing list</a>. Additional brownie points are awarded for bug reports that | |
49 | 49 | include a failing unit test.</p> |
50 | 50 | |
51 | 51 | <h2 id="patches">Bug Fixes</h2> |
68 | 68 | project on the XStream site.</p> |
69 | 69 | |
70 | 70 | <h2 id="become-committer">Become a Committer</h2> |
71 | <p>We follow the <a href="http://www.codehaus.org/customs/manifesto.html">Codehaus manifesto</a> | |
72 | when it comes to expanding the core team.</p> | |
71 | <p>We follow the former Codehaus manifesto when it comes to expanding the core team.</p> | |
72 | ||
73 | <ol> | |
74 | <li>The Codehaus recognizes that some committers, based upon metrics, longevity and appointed | |
75 | management, have greater say on a project than others.</li> | |
76 | <li>The Codehaus is a place where people are encouraged to get on with code rather than tie | |
77 | their projects up with bureaucracy.</li> | |
78 | <li>The Codehaus encourages projects to strive for quality and for frequent small releases.</li> | |
79 | <li>The Codehaus encourages committers to be respectful friends, meet up with each other as often | |
80 | as possible. Face-to-face is superior to email.</li> | |
81 | <li>The Codehaus stands in favour of diversity (where appropriate) over enforced convergence and | |
82 | homogeneity.</li> | |
83 | <li>The Codehaus places a high bar on entry for committers. Referral is a common means. A new | |
84 | committer is expected to show strong character elements as well as a talent for code. Maturity and | |
85 | wisdom (possibly in advance of years if a youngster) should be demonstrated.</li> | |
86 | <li>New committers to an existing project are expected to ease themselves in with small and deferrent | |
87 | commits to start, and greater free-will may be assumed later.</li> | |
88 | <li>The Codehaus encourages people to be brief in email and to honor internet etiquette. Ten furlongs | |
89 | of text justifying a position is poor form; better would be a (failing) unit test.</li> | |
90 | <li>In case of disagreement, The Despots are right.</li> | |
91 | </ol> | |
73 | 92 | |
74 | 93 | </body> |
75 | 94 | </html> |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | 2 | Copyright (C) 2005, 2006 Joe Walnes. |
3 | Copyright (C) 2006, 2007, 2008, 2011, 2012, 2013, 2014, 2015 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2008, 2011, 2012, 2013, 2014, 2015, 2016 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.8"><b>February 18, 2015</b> XStream 1.4.8 released</h2> | |
75 | <h2 id="1.4.9"><b>March 15, 2016</b> XStream 1.4.9 released</h2> | |
76 | 76 | |
77 | <p>Maintenance release 1.4.8 of XStream with bug fixes and improvements running with Java 8.</p> | |
77 | <p>Maintenance release 1.4.9 of XStream with bug fixes eliminating XXE vulnerability and new benchmark module.</p> | |
78 | 78 | |
79 | <p>XStream supports now serializable lambda types for a Java 9 runtime.</p> | |
79 | <p>Several parsers were vulnerable by processing external entities (XXE vulnerability). This has been turned off as far as possible.</p> | |
80 | 80 | |
81 | <p>View the complete <a href="changes.html">change log</a> and <a href="download.html">download</a>.</p> | |
81 | <p>The home-grown benchmark module has been replaced using an implementation based on JMH.</p> | |
82 | 82 | |
83 | <p>Note, the next major release 1.5 will require Java 6.</p> | |
83 | <p>XStream supports now java.nio.Path with a specialized converter.</p> | |
84 | ||
85 | <p>Note, the next major release 1.5 will require Java 7.</p> | |
84 | 86 | |
85 | 87 | <p>Thanks to this impressive list of <a href="team.html#contributors">contributors</a>.</p> |
86 | 88 |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | Copyright (C) 2007, 2008, 2013 XStream committers. | |
2 | Copyright (C) 2007, 2008, 2013, 2015 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 | </head> |
14 | 14 | <body> |
15 | 15 | |
16 | <p>XStream tracks and manages its issues in <a href="http://www.atlassian.com/software/jira/">JIRA of Atlassian</a>, | |
17 | that is supported by the Codehaus infrastructure and is free for open source development.</p> | |
18 | ||
19 | <h2 id="account">JIRA Account</h2> | |
20 | ||
21 | <p>Before you can report, comment or vote for an issue you need an account for the Codehaus. This account is then also used for | |
22 | Codehaus' JIRA installation. Simply sign up at <a href="http://xircles.codehaus.org">xircles</a> and on top you're able to manage all | |
23 | the mailing list subscriptions at Codehaus inclusive XStream's lists also. This is necessary to reduce spam in the system and as benefit | |
24 | you can be notified if work is done on your reported issues.</p> | |
25 | ||
26 | 16 | <h2 id="policy">Policy</h2> |
27 | 17 | |
28 | 18 | <p>Please, before opening a new issue look through the open or resolved ones, you may already find your problem. Also do not |
29 | use the system to ask questions, for that purpose we have a <a href="list-user.html">user list</a>. We read the list continuously. | |
19 | use the system to ask questions, for that purpose we have a <a href="mailing-lists.html">mailing list</a>. We read the list continuously. | |
30 | 20 | If you are unsure whether the problem is caused by a bug or your usage of XStream, use the user's list first. If we can confirm a bug, |
31 | 21 | you may still open an issue. Also do not report on the list that you have created a new issue, we are already notified by the system.</p> |
32 | 22 | |
35 | 25 | a header with the copyright. It must be a BSD license, simply take the header of any other file in the distribution as template. Otherwise |
36 | 26 | we might not be able to add any code of you.</p> |
37 | 27 | |
38 | <p>Browse XStream in <a href="http://jira.codehaus.org/browse/XSTR">JIRA</a> now.</p> | |
28 | <p>XStream tracks and manages its issues <a href="https://github.com/x-stream/xstream/issues">issues</a> | |
29 | with GitHub's integrated issue management.</p> | |
30 | ||
31 | <h2 id="old-issues">Old Issues</h2> | |
32 | ||
33 | <p>XStream was hosted for more than a decade at Codehaus and used Codehaus' installation of JIRA as issue management. With the help of | |
34 | Paul Hammant's <a href="https://github.com/paul-hammant/JIRA_exporter">export script</a> we can still provide a static version of all the | |
35 | <a href="jira/">former issues</a>.</p> | |
39 | 36 | </body> |
40 | 37 | </html> |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | Copyright (C) 2007, 2008, 2010, 2012, 2013 XStream committers. | |
2 | Copyright (C) 2007, 2008, 2010, 2012, 2013, 2015 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 | |
41 | 41 | <h1 id="jettison">Jettison driver</h1> |
42 | 42 | |
43 | <p>Jettison driver uses <a href="http://jettison.codehaus.org/">Jettison</a> StAX parser to read and write data in JSON | |
43 | <p>Jettison driver uses <a href="https://github.com/jettison-json">Jettison</a> StAX parser to read and write data in JSON | |
44 | 44 | format. It is available in XStream since version 1.2.2 and is implemented in |
45 | 45 | <code>com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver</code> class. To successfully use this driver you need |
46 | to have the Jettison project and <a href="http://stax.codehaus.org/">StAX API</a> in your classpath (see reference for | |
46 | to have the Jettison project and StAX API in your classpath (see reference for | |
47 | 47 | <a href="download.html#optional-deps">optional dependencies</a>).</p> |
48 | 48 | |
49 | 49 | <p>Alternatively you can download JARs manually.</p> |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | 2 | Copyright (C) 2005, 2006 Joe Walnes. |
3 | Copyright (C) 2006, 2007, 2009, 2011 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2009, 2011, 2015 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 | <p>XStream is open source software, made available under a BSD license.</p> |
18 | 18 | |
19 | 19 | <div class="Source Java"><pre>Copyright (c) 2003-2006, Joe Walnes |
20 | Copyright (c) 2006-2009, 2011 XStream Committers | |
20 | Copyright (c) 2006-2015 XStream Committers | |
21 | 21 | All rights reserved. |
22 | 22 | |
23 | 23 | Redistribution and use in source and binary forms, with or without |
0 | <html> | |
1 | <!-- | |
2 | Copyright (C) 2005, 2006 Joe Walnes. | |
3 | Copyright (C) 2006, 2007 XStream committers. | |
4 | All rights reserved. | |
5 | ||
6 | The software in this package is published under the terms of the BSD | |
7 | style license a copy of which has been included with this distribution in | |
8 | the LICENSE.txt file. | |
9 | ||
10 | Created on 29. January 2005 by Joe Walnes | |
11 | --> | |
12 | <head> | |
13 | <title>Developers' Mailing List</title> | |
14 | </head> | |
15 | <body> | |
16 | ||
17 | <p>General discussion and support for anyone who wants to get involved in the development of XStream.</p> | |
18 | ||
19 | <p>Note, if you just have questions about using XStream, you should use the <a href="list-user.html">user's mailing list</a>.</p> | |
20 | ||
21 | <table summary="Links to subscribe and unsubscribe"> | |
22 | <tr> | |
23 | <th>Post</th> | |
24 | <th>(Un-)Subscribe</th> | |
25 | </tr> | |
26 | <tr> | |
27 | <td><a href="mailto:dev@xstream.codehaus.org">dev@xstream.codehaus.org</a></td> | |
28 | <td><a href="http://xircles.codehaus.org/manage_email">Manage Email</a></td> | |
29 | </tr> | |
30 | </table> | |
31 | ||
32 | <p>Due to massive abuse by spammers the subscriptions is centralized for email lists of all projects hosted on Codehaus. | |
33 | After following the link above just register with your email address and you can manage all subscriptions at once.</p> | |
34 | ||
35 | <h2 id="archives">Archives</h2> | |
36 | ||
37 | <iframe src="http://news.gmane.org/gmane.comp.java.xstream.devel"> | |
38 | <p>View <a href="http://news.gmane.org/gmane.comp.java.xstream.devel">archives</a>, provided by Gmane.org</p> | |
39 | </iframe> | |
40 | ||
41 | </body> | |
42 | </html> |
0 | <html> | |
1 | <!-- | |
2 | Copyright (C) 2005, 2006 Joe Walnes. | |
3 | Copyright (C) 2006, 2007 XStream committers. | |
4 | All rights reserved. | |
5 | ||
6 | The software in this package is published under the terms of the BSD | |
7 | style license a copy of which has been included with this distribution in | |
8 | the LICENSE.txt file. | |
9 | ||
10 | Created on 29. January 2005 by Joe Walnes | |
11 | --> | |
12 | <head> | |
13 | <title>Users' Mailing List</title> | |
14 | </head> | |
15 | <body> | |
16 | ||
17 | <p align="left">General discussion and support for anyone using or evaluating XStream.</p> | |
18 | ||
19 | <table summary="Links to subscribe and unsubscribe"> | |
20 | <tr> | |
21 | <th>Post</th> | |
22 | <th>(Un-)Subscribe</th> | |
23 | </tr> | |
24 | <tr> | |
25 | <td><a href="mailto:user@xstream.codehaus.org">user@xstream.codehaus.org</a></td> | |
26 | <td><a href="http://xircles.codehaus.org/manage_email">Manage Email</a></td> | |
27 | </tr> | |
28 | </table> | |
29 | ||
30 | <p>Due to massive abuse by spammers the subscriptions is centralized for email lists of all projects hosted on Codehaus. | |
31 | After following the link above just register with your email address and you can manage all subscriptions at once.</p> | |
32 | ||
33 | <h2 id="archives">Archives</h2> | |
34 | ||
35 | <iframe src="http://news.gmane.org/gmane.comp.java.xstream.user"> | |
36 | <p>View <a href="http://news.gmane.org/gmane.comp.java.xstream.user">archives</a>, provided by Gmane.org</p> | |
37 | </iframe> | |
38 | ||
39 | </body> | |
40 | </html> |
0 | <html> | |
1 | <!-- | |
2 | Copyright (C) 2005, 2006 Joe Walnes. | |
3 | Copyright (C) 2006, 2007, 2015 XStream committers. | |
4 | All rights reserved. | |
5 | ||
6 | The software in this package is published under the terms of the BSD | |
7 | style license a copy of which has been included with this distribution in | |
8 | the LICENSE.txt file. | |
9 | ||
10 | Created on 07. May 2015 by Joerg Schaible, renamed from list-user.html | |
11 | --> | |
12 | <head> | |
13 | <title>Mailing Lists</title> | |
14 | </head> | |
15 | <body> | |
16 | ||
17 | <h2>List and Forum</h2> | |
18 | ||
19 | <p>The mailing lists have been consolidated into one Google Group for | |
20 | <a href="https://groups.google.com/group/xstream-user">users and developers</a> asking questions about XStream's | |
21 | usage, making enhancements requests or proposing improvements for its implementation. Another read-only Google | |
22 | Group is for <a href="https://groups.google.com/group/xstream-notifications">all kind of notifications</a> like | |
23 | announcements, commit or build server status messages.</p> | |
24 | ||
25 | <p>Google Groups provide standard mailing list functionality as well as a user interface in form of a web-based forum.</p> | |
26 | ||
27 | <h2>News</h2> | |
28 | ||
29 | <p><a href="http://www.gmane.org/">Gmane</a> offers a news server interface for ordinary mailing lists. The | |
30 | service collects all mails from the mailing list and offers them in a news group. The same news group was already | |
31 | used for the old user's mailing list of Codehaus.</p> | |
32 | ||
33 | <iframe src="http://news.gmane.org/gmane.comp.java.xstream.user"> | |
34 | <p>View <a href="http://news.gmane.org/gmane.comp.java.xstream.user">archives</a>, provided by Gmane.org</p> | |
35 | </iframe> | |
36 | ||
37 | <h2>Archives</h2> | |
38 | ||
39 | <p>The former mailing lists hosted at Codehaus are gone, but still available in public archives | |
40 | at <a href="http://markmail.org/search/list:org.codehaus.xstream">MarkMail</a>.</p> | |
41 | ||
42 | </body> | |
43 | </html> |
0 | <html> | |
1 | <!-- | |
2 | Copyright (C) 2005, 2006 Joe Walnes. | |
3 | Copyright (C) 2006, 2007 XStream committers. | |
4 | All rights reserved. | |
5 | ||
6 | The software in this package is published under the terms of the BSD | |
7 | style license a copy of which has been included with this distribution in | |
8 | the LICENSE.txt file. | |
9 | ||
10 | Created on 29. January 2005 by Joe Walnes | |
11 | --> | |
12 | <head> | |
13 | <title>Documentation</title> | |
14 | </head> | |
15 | <body> | |
16 | ||
17 | <h2>Essentials</h2> | |
18 | ||
19 | <ul> | |
20 | <li>Uses of XStream</li> | |
21 | <li>Architecture Overview</li> | |
22 | </ul> | |
23 | ||
24 | </body> | |
25 | </html> | |
26 | <!-- | |
27 | X * Two minute tutorial | |
28 | ||
29 | * Essentials | |
30 | + Uses of XStream (when to use, when not to) | |
31 | X + Design overview | |
32 | / + Tweaking output (alias, implicit collections) | |
33 | * Converters | |
34 | + What they do (include context and inheritance questions, lookup, default, implementation guidelines (threads/state)) | |
35 | + Registering a new one | |
36 | + Creating a basic converter | |
37 | + Creating a more complicated converter | |
38 | + Composite converters | |
39 | + The default converter (reflectionprovider, enhanced mode) | |
40 | * IO | |
41 | + Overview | |
42 | + Drivers for convenience | |
43 | + Document based IO: DOM, JDOM, DOM4J, ElectricXML, XOM | |
44 | + Stream based IO: JAXP, TrAX, XPP, StAX, SAX (write only) | |
45 | + Why no SAX reader | |
46 | + XStream and XSLT integration | |
47 | + Non XML | |
48 | * Advanced usage | |
49 | + Thread safety (reusing xstream, shared/isolated objects, dataholder) | |
50 | + ClassLoader | |
51 | + SecurityManagers | |
52 | * Usage hints | |
53 | + Configuration (serialize first) | |
54 | ||
55 | -->⏎ |
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 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 2013, 2014, 2015, 2016 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 | <h2 id="1.4.9"><b>March 15, 2016</b> XStream 1.4.9 released</h2> | |
19 | ||
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> | |
23 | ||
24 | <p>The home-grown benchmark module has been replaced using an implementation based on JMH.</p> | |
25 | ||
26 | <p>XStream supports now java.nio.Path with a specialized converter.</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="GitHub"><b>May 8, 2015</b> XStream hosted at GitHub</h2> | |
33 | ||
34 | <p>Codehaus has been XStream's home for more than a decade. Now is the time for a new home at | |
35 | <a href="http://x-stream.github.io/">GitHub</a>, since Codehaus is shut down within the next few days.</p> | |
36 | ||
37 | <p>The XStream committers want to thank Codehaus for their marvelous service over all those years.</p> | |
38 | ||
39 | <p>The mailing lists are consolidated and are located now at Google Groups:</p> | |
40 | <ul> | |
41 | <li>User's list (<a href="https://groups.google.com/forum/#!forum/xstream-user">xstream-user</a>): For users | |
42 | and developers asking questions about XStream usage, enhancements and improvements for implementation details.</li> | |
43 | <li>Notification list (<a href="https://groups.google.com/forum/#!forum/xstream-notifications">xstream-notifications</a>): | |
44 | All kind of notifications like announcements, commits, and build server status.</li> | |
45 | </ul> | |
46 | ||
18 | 47 | <h2 id="1.4.8"><b>February 18, 2015</b> XStream 1.4.8 released</h2> |
19 | 48 | |
20 | 49 | <p>Maintenance release 1.4.8 of XStream with bug fixes and improvements running with Java 8.</p> |
21 | 50 | |
22 | 51 | <p>XStream supports now serializable lambda types for a Java 8 runtime.</p> |
23 | 52 | |
24 | <p>View the complete <a href="changes.html">change log</a> and <a href="download.html">download</a>.</p> | |
53 | <p>View the complete <a href="changes.html#1.4.8">change log</a> and <a href="download.html">download</a>.</p> | |
25 | 54 | |
26 | 55 | <p>Note, the next major release 1.5 will require Java 6.</p> |
27 | 56 | |
32 | 61 | |
33 | 62 | <p>XStream contains now a security framework to fine-control the unmarshalled types.</p> |
34 | 63 | |
35 | <p>View the complete <a href="changes.html">change log</a> and <a href="download.html">download</a>.</p> | |
64 | <p>View the complete <a href="changes.html#1.4.7">change log</a> and <a href="download.html">download</a>.</p> | |
36 | 65 | |
37 | 66 | <h2 id="1.4.6"><b>December 12, 2013</b> XStream 1.4.6 released</h2> |
38 | 67 |
0 | <html> | |
1 | <!-- | |
2 | Copyright (C) 2009, 2011 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 03. May 2009 by Joerg Schaible | |
10 | --> | |
11 | <head> | |
12 | <title>Parser Benchmarks</title> | |
13 | <style type="text/css"> | |
14 | #content td { text-align: right;} | |
15 | #content dt { font-weight: bold;} | |
16 | </style> | |
17 | </head> | |
18 | ||
19 | <body> | |
20 | <p>Benchmark results are always dependent on a very individual setup. Normally it is not useful to generalize such results | |
21 | for every use case, but it can give you a hint. However, if you're really in the need of maximum performance, you should | |
22 | probably create an own benchmark with your objects or even use a profiler to detect the real hot spots in your application.</p> | |
23 | ||
24 | <h2 id="values">Benchmark Values</h2> | |
25 | ||
26 | <table summary="Benchmark for all XML parsers supported by XStream using different converter types"> | |
27 | <tr> | |
28 | <th>Parser</th> | |
29 | <th>Single Value Converters</th> | |
30 | <th>Standard Converters</th> | |
31 | <th>Reflection Converter</th> | |
32 | <th>Serializable Converter</th> | |
33 | </tr> | |
34 | <tr> | |
35 | <th>W3C DOM</th> | |
36 | <td>1823.0</td> | |
37 | <td>1495.0</td> | |
38 | <td>1437.0</td> | |
39 | <td>1758.0</td> | |
40 | </tr> | |
41 | <tr> | |
42 | <th>JDOM</th> | |
43 | <td>2620.0</td> | |
44 | <td>1796.0</td> | |
45 | <td>1776.0</td> | |
46 | <td>2030.0</td> | |
47 | </tr> | |
48 | <tr> | |
49 | <th>DOM4J</th> | |
50 | <td>1824.0</td> | |
51 | <td>1811.0</td> | |
52 | <td>2636.0</td> | |
53 | <td>2177.0</td> | |
54 | </tr> | |
55 | <tr> | |
56 | <th>XOM</th> | |
57 | <td>571.0</td> | |
58 | <td>716.0</td> | |
59 | <td>995.0</td> | |
60 | <td>958.0</td> | |
61 | </tr> | |
62 | <tr> | |
63 | <th>StAX (BEA)</th> | |
64 | <td>430.0</td> | |
65 | <td>359.0</td> | |
66 | <td>531.0</td> | |
67 | <td>737.0</td> | |
68 | </tr> | |
69 | <tr> | |
70 | <th>StAX (Woodstox)</th> | |
71 | <td>357.0</td> | |
72 | <td>344.0</td> | |
73 | <td>535.0</td> | |
74 | <td>725.0</td> | |
75 | </tr> | |
76 | <tr> | |
77 | <th>StAX (SJSXP)</th> | |
78 | <td>332.0</td> | |
79 | <td>445.0</td> | |
80 | <td>491.0</td> | |
81 | <td>667.0</td> | |
82 | </tr> | |
83 | <tr> | |
84 | <th>XPP (Xpp3)</th> | |
85 | <td>351.0</td> | |
86 | <td>395.0</td> | |
87 | <td>544.0</td> | |
88 | <td>743.0</td> | |
89 | </tr> | |
90 | <tr> | |
91 | <th>XPP (kXML2)</th> | |
92 | <td>299.0</td> | |
93 | <td>353.0</td> | |
94 | <td>517.0</td> | |
95 | <td>761.0</td> | |
96 | </tr> | |
97 | <tr> | |
98 | <th>XppDom (Xpp3)</th> | |
99 | <td>351.0</td> | |
100 | <td>395.0</td> | |
101 | <td>544.0</td> | |
102 | <td>743.0</td> | |
103 | </tr> | |
104 | <tr> | |
105 | <th>XppDom (kXML2)</th> | |
106 | <td>299.0</td> | |
107 | <td>353.0</td> | |
108 | <td>517.0</td> | |
109 | <td>761.0</td> | |
110 | </tr> | |
111 | </table> | |
112 | ||
113 | <h2 id="setup">Setup</h2> | |
114 | ||
115 | <p>The values have been generated running the ParserBenchmark harness of the XStream benchmark module's test code.</p> | |
116 | ||
117 | <dl> | |
118 | <dt>Single Value Converters</dt> | |
119 | <dd>A list with a set of 10 objects of different types (like String, int, File, Locale, Double, ...) that will | |
120 | be all handled by a SingleValueConverter.</dd> | |
121 | <dt>Standard Converters</dt> | |
122 | <dd>A list with a set of 6 objects of different types (like Properties, Color, Class, Method, ...) that will | |
123 | be all handled by a specialized converter processing nested XML elements.</dd> | |
124 | <dt>Reflection Converter</dt> | |
125 | <dd>A list with a set of 6 objects of different types (One, Five of the XStream benchmark package) that will be | |
126 | all handled by the ReflectionConverter.</dd> | |
127 | <dt>Serializable Converter</dt> | |
128 | <dd>A list with a set of 6 objects of different types (SerializableOne, SerializableFive of the XStream | |
129 | benchmark package) that will be all handled by the SerializableConverter.</dd> | |
130 | <dt>JavaBean Converter</dt> | |
131 | <dd>A list with a set of 6 objects of different types (OneBean, FiveBean of the XStream benchmark package) that | |
132 | will be all handled by the JavaBeanConverter. This converter has been registered especially for this two types.</dd> | |
133 | </dl> | |
134 | ||
135 | <h2 id="environment">Environment</h2> | |
136 | ||
137 | <p>The values above's unit is ms measured after 1000 unmarshalling operations with the object graphs described in | |
138 | the setup using XStream 1.4. The benchmark was run on an AMD Athlon with 2.1GHz running a JVM of Sun JDK 1.6.0_13 | |
139 | (32-bit) in Gentoo Linux. Note again, that these values are no replacement for real profiler results and they may | |
140 | vary from run to run for ~100ms due to this machine's background processes on a single CPU. However, it can give | |
141 | you some idea of what you can expect using different parser technologies.</p> | |
142 | </body> | |
143 | </html> | |
144 | ⏎ |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream committers. | |
2 | Copyright (C) 2006, 2007, 2008, 2009, 2011, 2015 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 | <h2 id="bamboo">Atlassian Bamboo</h2> |
23 | 23 | |
24 | 24 | <p><a href="http://www.atlassian.com/software/bamboo/">Bamboo</a> is build server for continuous integration |
25 | and release management. Note, XStream itself uses <a href="http://bamboo.ci.codehaus.org/browse/XSTREAM">Bamboo | |
26 | at Codehaus</a> for continuous integration.</p> | |
25 | and release management. Note, XStream itself used Bamboo at former Codehaus for continuous integration.</p> | |
27 | 26 | |
28 | 27 | <h2 id="confluence">Atlassian Confluence</h2> |
29 | 28 | |
30 | 29 | <p><a href="http://www.atlassian.com/software/confluence/">Confluence</a> is an enterprise wiki that makes it |
31 | 30 | easy for your team to collaborate and share knowledge.</p> |
32 | 31 | |
33 | <h2 id="confluence">Oracle Hudson CI</h2> | |
32 | <h2 id="jenkins">Jenkins CI</h2> | |
34 | 33 | |
35 | <p><a href="http://www.atlassian.com/software/confluence/">Hudson CI</a> is also a build server for continuous | |
36 | integration and release management.</p> | |
34 | <p><a href="https://jenkins-ci.org//">Jenkins CI</a> is also a build server for continuous integration and | |
35 | release management.</p> | |
37 | 36 | |
38 | 37 | <h2 id="muse">Apache Muse</h2> |
39 | 38 |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | 2 | Copyright (C) 2005, 2006 Joe Walnes. |
3 | Copyright (C) 2006, 2007, 2010, 2011 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2010, 2011, 2015 XStream committers. | |
4 | 4 | All rights reserved. |
5 | 5 | |
6 | 6 | The software in this package is published under the terms of the BSD |
19 | 19 | XStream project consists of several modules: |
20 | 20 | <ol> |
21 | 21 | <li>xstream - the core module</li> |
22 | <li>xstream-benchmark - the benchmark tool</li> | |
23 | <li>xstream-distribution - the module contains the documentation and assembles the src and bin distributions</li> | |
22 | <li>xstream-hibernate - the Hibernate support mdule</li> | |
23 | <li>xstream-distribution - the module with the documentation and distribution definition</li> | |
24 | 24 | </ol> |
25 | When you checkout the trunk you'll get all the modules, but you can just add the module you are interested in to the URL, e.g. | |
26 | <div class="Source"><pre>svn co http://svn.codehaus.org/xstream/trunk/[module]</pre></div> | |
27 | to checkout out the single module separately. | |
25 | When you clone the Git repository you'll get all the modules. | |
28 | 26 | |
29 | 27 | <h2 id="browser">Browser</h2> |
30 | 28 | |
31 | <p>You can use the browser to navigate within the sources <a href="http://fisheye.codehaus.org/browse/xstream/trunk/">online</a> | |
32 | with the help of the FishEye installation on Codehaus.</p> | |
29 | <p>You can use the browser to navigate within the sources <a href="https://github.com/x-stream/xstream">online</a>.</p> | |
33 | 30 | |
34 | <h2 id="subversion">Subversion</h2> | |
31 | <h2 id="scm">Source Control Manager</h2> | |
35 | 32 | |
36 | XStream uses Subversion as the SCM. See <a href="http://subversion.apache.org">Subversion website</a> for details and documentation on IDE integration. | |
37 | ||
38 | <h2 id="webdav">WebDav Access</h2> | |
39 | ||
40 | WebDav is an access protocol supported by SVN and being http-based is often allowed by corporate firewalls. | |
41 | ||
42 | <h3 id="webdav-anon">Anonymous Access</h3> | |
43 | ||
44 | <div class="Source"><pre>svn co http://svn.codehaus.org/xstream/trunk</pre></div> | |
45 | ||
46 | <p> | |
47 | You might also use this URL to <a href="http://svn.codehaus.org/xstream/trunk">browse the repository</a> in a simple manner. | |
48 | </p> | |
49 | ||
50 | <h3 id="webdav-auth">Committer Access</h3> | |
51 | ||
52 | <div class="Source"><pre>svn co https://svn.codehaus.org/xstream/trunk</pre></div> | |
53 | ||
54 | <p> | |
55 | This access protocol is available to all, but only developers can commit changes. | |
56 | </p> | |
57 | <p> | |
58 | Developers require a LDAP password for Codehaus username (contact Bob at the Haus to get assigned a password if you don't have one). | |
59 | </p> | |
33 | XStream uses Git as the SCM. See <a href="http://git-scm.com/">Git website</a> for details and documentation on IDE integration. | |
34 | ||
35 | <h2 id="access">Access</h2> | |
36 | ||
37 | Clone the <a href="https://github.com/x-stream/xstream">repository</a> at GitHub. See GitHub documentation about | |
38 | the different possibilities to access the source code. | |
60 | 39 | |
61 | 40 | </body> |
62 | 41 | </html> |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | Copyright (C) 2014 XStream committers. | |
2 | Copyright (C) 2014, 2015 XStream committers. | |
3 | 3 | All rights reserved. |
4 | 4 | |
5 | 5 | The software in this package is published under the terms of the BSD |
201 | 201 | </tr> |
202 | 202 | <tr> |
203 | 203 | <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 PROXIES instance directly.</td> | |
204 | <td>Allow any primitive type and its boxed counterpart (incl void). You may use the PRIMITIVES instance directly.</td> | |
205 | 205 | <td> </td> |
206 | 206 | <td>no</td> |
207 | 207 | </tr> |
238 | 238 | <a href="alias-tutorial.html">Alias Tutorial</a>):</p> |
239 | 239 | <div class="Source Java"><pre>XStream xstream = new XStream(); |
240 | 240 | // clear out existing permissions and set own ones |
241 | xstream.addPermission(NoPermissionType.NONE); | |
241 | xstream.addPermission(NoTypePermission.NONE); | |
242 | 242 | // allow some basics |
243 | 243 | xstream.addPermission(NullPermission.NULL); |
244 | 244 | xstream.addPermission(PrimitiveTypePermission.PRIMITIVES); |
0 | 0 | <html> |
1 | 1 | <!-- |
2 | 2 | Copyright (C) 2005, 2006 Joe Walnes. |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014 XStream committers. | |
3 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2015, 2016 XStream committers. | |
4 | 4 | All rights reserved. |
5 | 5 | |
6 | 6 | The software in this package is published under the terms of the BSD |
118 | 118 | <li>Edison Guo</li> |
119 | 119 | <li>Rico Neubauer</li> |
120 | 120 | <li>David Jorm</li> |
121 | <li>Geoff Groos</li> | |
122 | <li>Aaron Johnson</li> | |
121 | 123 | </ul> |
122 | 124 | |
123 | <p>Please direct all correspondence about XStream to the <a href="list-user.html">users' mailing lists</a> | |
125 | <p>Please direct all correspondence about XStream to the <a href="mailing-lists.html">mailing list</a> | |
124 | 126 | rather than directly to one of the team.</p> |
125 | 127 | |
126 | 128 | </body> |
0 | 0 | <!-- |
1 | 1 | Copyright (C) 2005, 2006 Joe Walnes. |
2 | Copyright (C) 2006, 2007, 2010, 2011, 2014, 2015 XStream committers. | |
2 | Copyright (C) 2006, 2007, 2010, 2011, 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 |
24 | 24 | <page>license.html</page> |
25 | 25 | <page>download.html</page> |
26 | 26 | <page>references.html</page> |
27 | <page>parser-benchmarks.html</page> | |
27 | <page>benchmarks.html</page> | |
28 | 28 | <link title="Code Statistics">https://www.openhub.net/p/xstream</link> |
29 | 29 | </section> |
30 | 30 | <section> |
33 | 33 | <page>converters.html</page> |
34 | 34 | <page>security.html</page> |
35 | 35 | <page>faq.html</page> |
36 | <page>list-user.html</page> | |
36 | <page>mailing-lists.html</page> | |
37 | 37 | <page>issues.html</page> |
38 | 38 | </section> |
39 | 39 | <section> |
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="Benchmark Module">benchmark-javadoc/index.html</link> | |
43 | <link title="JMH Module">benchmark-jmh/index.html</link> | |
44 | 44 | </section> |
45 | 45 | <section> |
46 | 46 | <name>Tutorials</name> |
56 | 56 | <section> |
57 | 57 | <name>Developing XStream</name> |
58 | 58 | <page>how-to-contribute.html</page> |
59 | <page>list-dev.html</page> | |
60 | 59 | <page>team.html</page> |
61 | 60 | <page>repository.html</page> |
62 | <link title="Continuous Integration">http://bamboo.ci.codehaus.org/browse/XSTREAM</link> | |
61 | <link title="Continuous Integration">https://travis-ci.org/x-stream/xstream/branches</link> | |
63 | 62 | </section> |
64 | 63 | </sitemap> |
0 | 0 | <!-- |
1 | 1 | Copyright (C) 2006, 2007, 2008, 2010 XSite committers. |
2 | Copyright (C) 2011 XStream committers. | |
2 | Copyright (C) 2011, 2015 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 | <component-implementation key="org.codehaus.xsite.Skin" class="org.codehaus.xsite.skins.FreemarkerSkin"/> |
23 | 23 | <component-implementation key="org.codehaus.xsite.PageExtractor" class="org.codehaus.xsite.extractors.SiteMeshPageExtractor"/> |
24 | 24 | <component-implementation class="org.codehaus.xsite.extractors.sitemesh.rules.AddFirstChildClassToHeader"/> |
25 | <component-implementation class="com.opensymphony.module.sitemesh.html.rules.RegexReplacementTextFilter"> | |
26 | <parameter><string>JIRA:([A-Z]+)-([0-9]+)</string></parameter> | |
27 | <parameter><string><![CDATA[<a href=\"http://jira.codehaus.org/browse/$1-$2\">$1-$2</a>]]></string></parameter> | |
25 | <component-implementation key="jira-issues" class="com.opensymphony.module.sitemesh.html.rules.RegexReplacementTextFilter"> | |
26 | <parameter><string>JIRA:XSTR-([0-9]+)</string></parameter> | |
27 | <parameter><string><![CDATA[<a href=\"/jira/$1\">XSTR-$1</a>]]></string></parameter> | |
28 | 28 | </component-implementation> |
29 | <component-implementation key="github-issues" class="com.opensymphony.module.sitemesh.html.rules.RegexReplacementTextFilter"> | |
30 | <parameter><string>GHI:[#]([0-9]+)</string></parameter> | |
31 | <parameter><string><![CDATA[<a href=\"https://github.com/x-stream/xstream/issues/$1\">#$1</a>]]></string></parameter> | |
32 | </component-implementation> | |
33 | <component-implementation key="github-pull-requests" class="com.opensymphony.module.sitemesh.html.rules.RegexReplacementTextFilter"> | |
34 | <parameter><string>GHPR:[#]([0-9]+)</string></parameter> | |
35 | <parameter><string><![CDATA[<a href=\"https://github.com/x-stream/xstream/pull/$1\">#$1</a>]]></string></parameter> | |
36 | </component-implementation> | |
29 | 37 | <component-implementation key="email-link-validator" class="org.codehaus.xsite.validators.StartsWithLinkValidator"> |
30 | 38 | <parameter><string>mailto:</string></parameter> |
31 | 39 | </component-implementation> |
47 | 55 | <component-implementation key="javadoc-link-validator" class="org.codehaus.xsite.validators.StartsWithLinkValidator"> |
48 | 56 | <parameter><string>javadoc/</string></parameter> |
49 | 57 | </component-implementation> |
58 | <component-implementation key="jira-link-validator" class="org.codehaus.xsite.validators.StartsWithLinkValidator"> | |
59 | <parameter><string>jira/</string></parameter> | |
60 | </component-implementation> | |
50 | 61 | <component-implementation key="code-coverage-link-validator" class="org.codehaus.xsite.validators.StartsWithLinkValidator"> |
51 | 62 | <parameter><string>code-coverage/</string></parameter> |
52 | 63 | </component-implementation> |
12 | 12 | <parent> |
13 | 13 | <groupId>com.thoughtworks.xstream</groupId> |
14 | 14 | <artifactId>xstream-parent</artifactId> |
15 | <version>1.4.8</version> | |
15 | <version>1.4.9</version> | |
16 | 16 | </parent> |
17 | 17 | <artifactId>xstream-hibernate</artifactId> |
18 | 18 | <packaging>jar</packaging> |
85 | 85 | |
86 | 86 | <build> |
87 | 87 | <plugins> |
88 | <plugin> | |
89 | <groupId>org.apache.maven.plugins</groupId> | |
90 | <artifactId>maven-compiler-plugin</artifactId> | |
91 | </plugin> | |
92 | <plugin> | |
93 | <groupId>org.apache.maven.plugins</groupId> | |
94 | <artifactId>maven-source-plugin</artifactId> | |
95 | </plugin> | |
96 | 88 | <plugin> |
97 | 89 | <groupId>org.apache.maven.plugins</groupId> |
98 | 90 | <artifactId>maven-dependency-plugin</artifactId> |
174 | 166 | <artifactId>junit</artifactId> |
175 | 167 | </dependency> |
176 | 168 | </dependencies> |
169 | ||
170 | <properties> | |
171 | <bundle.export.package>!com.thoughtworks.xstream.hibernate.util,com.thoughtworks.xstream.hibernate.*;-noimport:=true</bundle.export.package> | |
172 | </properties> | |
177 | 173 | </project> |
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 | <!-- | |
2 | Copyright (C) 2015 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. October 2015 by Joerg Schaible | |
10 | --> | |
11 | <modelVersion>4.0.0</modelVersion> | |
12 | <parent> | |
13 | <groupId>com.thoughtworks.xstream</groupId> | |
14 | <artifactId>xstream-parent</artifactId> | |
15 | <version>1.4.9</version> | |
16 | </parent> | |
17 | <artifactId>xstream-jmh</artifactId> | |
18 | <packaging>jar</packaging> | |
19 | <name>XStream JMH Benchmark</name> | |
20 | <description>JMH Benchmark suite of XStream.</description> | |
21 | ||
22 | <profiles> | |
23 | <profile> | |
24 | <id>jdk18-ge</id> | |
25 | <activation> | |
26 | <jdk>[1.8,)</jdk> | |
27 | </activation> | |
28 | <build> | |
29 | <plugins> | |
30 | <plugin> | |
31 | <groupId>org.apache.maven.plugins</groupId> | |
32 | <artifactId>maven-javadoc-plugin</artifactId> | |
33 | </plugin> | |
34 | </plugins> | |
35 | </build> | |
36 | <reporting> | |
37 | <plugins> | |
38 | <plugin> | |
39 | <groupId>org.apache.maven.plugins</groupId> | |
40 | <artifactId>maven-javadoc-plugin</artifactId> | |
41 | <version>${version.plugin.maven.javadoc}</version> | |
42 | <configuration> | |
43 | <additionalparam>${javadoc.xdoclint}</additionalparam> | |
44 | <detectJavaApiLink>false</detectJavaApiLink> | |
45 | <source>${version.java.source}</source> | |
46 | <links> | |
47 | <link>${link.javadoc.javase}</link> | |
48 | </links> | |
49 | </configuration> | |
50 | </plugin> | |
51 | </plugins> | |
52 | </reporting> | |
53 | </profile> | |
54 | </profiles> | |
55 | ||
56 | <build> | |
57 | <plugins> | |
58 | <plugin> | |
59 | <groupId>org.apache.maven.plugins</groupId> | |
60 | <artifactId>maven-source-plugin</artifactId> | |
61 | </plugin> | |
62 | <plugin> | |
63 | <groupId>org.apache.maven.plugins</groupId> | |
64 | <artifactId>maven-surefire-plugin</artifactId> | |
65 | <configuration> | |
66 | <skip>true</skip> | |
67 | </configuration> | |
68 | </plugin> | |
69 | <plugin> | |
70 | <groupId>org.apache.maven.plugins</groupId> | |
71 | <artifactId>maven-assembly-plugin</artifactId> | |
72 | <executions> | |
73 | <execution> | |
74 | <id>app</id> | |
75 | <phase>package</phase> | |
76 | <goals> | |
77 | <goal>attached</goal> | |
78 | </goals> | |
79 | <configuration> | |
80 | <descriptors> | |
81 | <descriptor>${basedir}/src/assembly-app.xml</descriptor> | |
82 | </descriptors> | |
83 | </configuration> | |
84 | </execution> | |
85 | </executions> | |
86 | </plugin> | |
87 | </plugins> | |
88 | </build> | |
89 | ||
90 | <dependencies> | |
91 | <dependency> | |
92 | <groupId>com.thoughtworks.xstream</groupId> | |
93 | <artifactId>xstream</artifactId> | |
94 | </dependency> | |
95 | <dependency> | |
96 | <groupId>org.openjdk.jmh</groupId> | |
97 | <artifactId>jmh-core</artifactId> | |
98 | </dependency> | |
99 | <dependency> | |
100 | <groupId>org.openjdk.jmh</groupId> | |
101 | <artifactId>jmh-generator-annprocess</artifactId> | |
102 | </dependency> | |
103 | <!-- parser --> | |
104 | <dependency> | |
105 | <groupId>xpp3</groupId> | |
106 | <artifactId>xpp3_min</artifactId> | |
107 | <scope>runtime</scope> | |
108 | </dependency> | |
109 | <dependency> | |
110 | <groupId>xmlpull</groupId> | |
111 | <artifactId>xmlpull</artifactId> | |
112 | <scope>runtime</scope> | |
113 | </dependency> | |
114 | <dependency> | |
115 | <groupId>net.sf.kxml</groupId> | |
116 | <artifactId>kxml2-min</artifactId> | |
117 | <scope>runtime</scope> | |
118 | </dependency> | |
119 | <dependency> | |
120 | <groupId>stax</groupId> | |
121 | <artifactId>stax</artifactId> | |
122 | <scope>runtime</scope> | |
123 | </dependency> | |
124 | <dependency> | |
125 | <groupId>org.codehaus.woodstox</groupId> | |
126 | <artifactId>wstx-asl</artifactId> | |
127 | <scope>runtime</scope> | |
128 | </dependency> | |
129 | <dependency> | |
130 | <groupId>dom4j</groupId> | |
131 | <artifactId>dom4j</artifactId> | |
132 | <scope>runtime</scope> | |
133 | </dependency> | |
134 | <dependency> | |
135 | <groupId>org.jdom</groupId> | |
136 | <artifactId>jdom</artifactId> | |
137 | <scope>runtime</scope> | |
138 | </dependency> | |
139 | <dependency> | |
140 | <groupId>org.jdom</groupId> | |
141 | <artifactId>jdom2</artifactId> | |
142 | <scope>runtime</scope> | |
143 | </dependency> | |
144 | <dependency> | |
145 | <groupId>xom</groupId> | |
146 | <artifactId>xom</artifactId> | |
147 | <scope>runtime</scope> | |
148 | </dependency> | |
149 | <dependency> | |
150 | <groupId>org.codehaus.jettison</groupId> | |
151 | <artifactId>jettison</artifactId> | |
152 | <scope>runtime</scope> | |
153 | </dependency> | |
154 | </dependencies> | |
155 | <properties> | |
156 | <version.java.source>1.6</version.java.source> | |
157 | <version.java.target>1.6</version.java.target> | |
158 | </properties> | |
159 | </project> |
0 | @echo off | |
1 | @REM Copyright (C) 2015 XStream Committers. | |
2 | @REM All rights reserved. | |
3 | @REM | |
4 | @REM The software in this package is published under the terms of the BSD | |
5 | @REM style license a copy of which has been included with this distribution in | |
6 | @REM the LICENSE.txt file. | |
7 | @REM | |
8 | @REM Created on 28. October 2015 by Joerg Schaible | |
9 | ||
10 | @REM Run XStream JMH | |
11 | if "%XSTREAM_SCRIPT_ECHO%"=="on" echo on | |
12 | ||
13 | if "%OS%"=="Windows_NT" @setlocal | |
14 | if "%OS%"=="WINNT" @setlocal | |
15 | ||
16 | @REM * Set title | |
17 | @REM *********** | |
18 | title ScalarisDMS | |
19 | ||
20 | @REM * Goto script root dir | |
21 | @REM ********************** | |
22 | cd /d %~dp0\.. | |
23 | ||
24 | @REM * Initialize environment | |
25 | @REM ************************ | |
26 | @REM JAVA_OPTS and APP_OPTS can be set from outside | |
27 | set JAVA_BIN= | |
28 | set APP_CP= | |
29 | ||
30 | @REM * Set Java executable | |
31 | @REM ********************* | |
32 | if not defined JAVA_EXE set JAVA_EXE=java.exe | |
33 | if "%JAVA_BIN%" NEQ "" if exist %JAVA_BIN% goto SetClassPath | |
34 | if defined JAVA_HOME if "%JAVA_HOME%" NEQ "" set JAVA_BIN=%JAVA_HOME%\bin\%JAVA_EXE% | |
35 | if exist %JAVA_BIN% goto SetClassPath | |
36 | if defined JDK_HOME if "%JDK_HOME%" NEQ "" set JAVA_BIN=%JDK_HOME%\jre\bin\%JAVA_EXE% | |
37 | if exist %JAVA_BIN% goto SetClassPath | |
38 | set JAVA_BIN=%JAVA_EXE% | |
39 | ||
40 | :SetClassPath | |
41 | @REM * Set class path | |
42 | @REM **************** | |
43 | for %%i in (lib\*.jar) do call :APP_CP_append %%i | |
44 | call :APP_CP_append "config" | |
45 | ||
46 | @REM * Set options | |
47 | @REM ************* | |
48 | set JAVA_OPTS=%JAVA_OPTS% -Xmx1024m | |
49 | ||
50 | ||
51 | @REM * Main class | |
52 | @REM ************ | |
53 | set MAIN_CLASS=org.openjdk.jmh.Main | |
54 | ||
55 | @REM * Run application | |
56 | @REM ***************** | |
57 | %JAVA_BIN% %JAVA_OPTS% %APP_DEFINES% -cp %APP_CP% %MAIN_CLASS% %APP_OPTS% %* | |
58 | ||
59 | ||
60 | if "%OS%"=="Windows_NT" @endlocal | |
61 | goto :EOF | |
62 | ||
63 | ||
64 | @REM *************** | |
65 | @REM * Sub functions | |
66 | @REM *************** | |
67 | ||
68 | :APP_CP_append | |
69 | set APP_CP=%APP_CP%;%1 | |
70 | goto :EOF |
0 | #!/bin/sh | |
1 | # Copyright (C) 2015 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 28. October 2015 by Joerg Schaible | |
9 | ||
10 | # Run XStream JMH | |
11 | ||
12 | # * Goto script root dir | |
13 | # ********************** | |
14 | cd `dirname $0`/.. | |
15 | ||
16 | # * Initialize environment | |
17 | # ************************ | |
18 | # JAVA_OPTS and APP_OPTS can be set from outside | |
19 | JAVA_BIN= | |
20 | APP_CP= | |
21 | ||
22 | # * Set Java executable | |
23 | # ********************* | |
24 | if [ -z "$JAVA_EXE" ]; then | |
25 | JAVA_EXE=java | |
26 | fi | |
27 | if [ -z "$JAVA_BIN" ] || [ ! -r $JAVA_BIN ]; then | |
28 | JAVA_BIN=$JAVA_HOME/bin/$JAVA_EXE | |
29 | if [ -z "$JAVA_HOME" ] || [ ! -r $JAVA_BIN ]; then | |
30 | JAVA_BIN=$JDK_HOME/jre/bin/$JAVA_EXE | |
31 | if [ -z "$JDK_HOME" ] || [ ! -r $JAVA_BIN ]; then | |
32 | JAVA_BIN=$JAVA_EXE | |
33 | fi | |
34 | fi | |
35 | fi | |
36 | ||
37 | # * Set class path | |
38 | # **************** | |
39 | for i in lib/*.jar; do | |
40 | APP_CP=$APP_CP:$i | |
41 | done | |
42 | ||
43 | # * Set options | |
44 | # ************* | |
45 | JAVA_OPTS="$JAVA_OPTS -Xmx1024m" | |
46 | ||
47 | # * Main class | |
48 | # ************ | |
49 | MAIN_CLASS=org.openjdk.jmh.Main | |
50 | ||
51 | # * Debug | |
52 | # ******* | |
53 | if [ "$XSTREAM_SCRIPT_ECHO" = "on" ]; then | |
54 | echo JAVA_BIN=$JAVA_BIN | |
55 | echo JAVA_OPTS=$JAVA_OPTS | |
56 | echo APP_OPTS=$APP_OPTS | |
57 | echo APP_CP=$APP_CP | |
58 | echo MAIN_CLASS=$MAIN_CLASS | |
59 | fi | |
60 | ||
61 | # * Run application | |
62 | # ***************** | |
63 | $JAVA_BIN $JAVA_OPTS -cp $APP_CP $MAIN_CLASS $APP_OPTS "$@" | |
64 |
0 | <!-- | |
1 | Copyright (C) 2015 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 28. October 2015 by Joerg Schaible | |
9 | --> | |
10 | <assembly> | |
11 | <id>app</id> | |
12 | <formats> | |
13 | <format>zip</format> | |
14 | </formats> | |
15 | <fileSets> | |
16 | <!-- | |
17 | <fileSet> | |
18 | <includes> | |
19 | <include>README*</include> | |
20 | <include>LICENSE*</include> | |
21 | <include>NOTICE*</include> | |
22 | </includes> | |
23 | </fileSet> | |
24 | --> | |
25 | <fileSet> | |
26 | <directory>src/application/bin</directory> | |
27 | <outputDirectory>bin</outputDirectory> | |
28 | <fileMode>0755</fileMode> | |
29 | </fileSet> | |
30 | <fileSet> | |
31 | <directory>src/reference</directory> | |
32 | <outputDirectory>reference</outputDirectory> | |
33 | </fileSet> | |
34 | </fileSets> | |
35 | <dependencySets> | |
36 | <dependencySet> | |
37 | <outputDirectory>lib</outputDirectory> | |
38 | <unpack>false</unpack> | |
39 | <scope>runtime</scope> | |
40 | </dependencySet> | |
41 | </dependencySets> | |
42 | </assembly> |
+282
-0
0 | /* | |
1 | * Copyright (C) 2015 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 20.11.2015 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.benchmark.jmh; | |
11 | ||
12 | import java.math.BigInteger; | |
13 | import java.util.UUID; | |
14 | import java.util.concurrent.TimeUnit; | |
15 | ||
16 | import org.openjdk.jmh.annotations.Benchmark; | |
17 | import org.openjdk.jmh.annotations.BenchmarkMode; | |
18 | import org.openjdk.jmh.annotations.Fork; | |
19 | import org.openjdk.jmh.annotations.Level; | |
20 | import org.openjdk.jmh.annotations.Measurement; | |
21 | import org.openjdk.jmh.annotations.Mode; | |
22 | import org.openjdk.jmh.annotations.OutputTimeUnit; | |
23 | import org.openjdk.jmh.annotations.Scope; | |
24 | import org.openjdk.jmh.annotations.Setup; | |
25 | import org.openjdk.jmh.annotations.State; | |
26 | import org.openjdk.jmh.annotations.Threads; | |
27 | import org.openjdk.jmh.annotations.Warmup; | |
28 | import org.openjdk.jmh.infra.BenchmarkParams; | |
29 | ||
30 | import com.thoughtworks.xstream.XStream; | |
31 | import com.thoughtworks.xstream.converters.ConversionException; | |
32 | import com.thoughtworks.xstream.converters.Converter; | |
33 | import com.thoughtworks.xstream.converters.MarshallingContext; | |
34 | import com.thoughtworks.xstream.converters.UnmarshallingContext; | |
35 | import com.thoughtworks.xstream.converters.javabean.JavaBeanConverter; | |
36 | import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; | |
37 | import com.thoughtworks.xstream.io.HierarchicalStreamReader; | |
38 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; | |
39 | import com.thoughtworks.xstream.io.xml.Xpp3Driver; | |
40 | ||
41 | ||
42 | /** | |
43 | * Benchmark for the different converter types. | |
44 | * | |
45 | * @author Jörg Schaible | |
46 | * @since 1.4.9 | |
47 | */ | |
48 | @BenchmarkMode(Mode.AverageTime) | |
49 | @Fork(value = 1) | |
50 | @Measurement(iterations = 16) | |
51 | @OutputTimeUnit(TimeUnit.NANOSECONDS) | |
52 | @State(Scope.Benchmark) | |
53 | @Threads(4) | |
54 | @Warmup(iterations = 5) | |
55 | public class ConverterTypeBenchmark { | |
56 | ||
57 | private XStream xstream; | |
58 | private Model array[]; | |
59 | private String xml; | |
60 | ||
61 | @SuppressWarnings("javadoc") | |
62 | public static class Model { | |
63 | private char ch; | |
64 | private int i; | |
65 | private String s; | |
66 | private double d; | |
67 | private float f; | |
68 | private BigInteger bi; | |
69 | private UUID uuid; | |
70 | ||
71 | public Model() { | |
72 | ch = 0; | |
73 | i = 0; | |
74 | d = 0.0; | |
75 | f = 0.0f; | |
76 | } | |
77 | ||
78 | public Model(final int i) { | |
79 | ch = (char)(i % 256); | |
80 | this.i = i; | |
81 | s = Integer.toString(i, 2); | |
82 | d = Math.PI * i; | |
83 | f = (float)(Math.E * i); | |
84 | bi = new BigInteger(s, 2); | |
85 | uuid = UUID.randomUUID(); | |
86 | } | |
87 | ||
88 | public char getCh() { | |
89 | return ch; | |
90 | } | |
91 | ||
92 | public void setCh(final char ch) { | |
93 | this.ch = ch; | |
94 | } | |
95 | ||
96 | public int getI() { | |
97 | return i; | |
98 | } | |
99 | ||
100 | public void setI(final int i) { | |
101 | this.i = i; | |
102 | } | |
103 | ||
104 | public String getS() { | |
105 | return s; | |
106 | } | |
107 | ||
108 | public void setS(final String s) { | |
109 | this.s = s; | |
110 | } | |
111 | ||
112 | public Double getD() { | |
113 | return d; | |
114 | } | |
115 | ||
116 | public void setD(final Double d) { | |
117 | this.d = d; | |
118 | } | |
119 | ||
120 | public Float getF() { | |
121 | return f; | |
122 | } | |
123 | ||
124 | public void setF(final Float f) { | |
125 | this.f = f; | |
126 | } | |
127 | ||
128 | public BigInteger getBi() { | |
129 | return bi; | |
130 | } | |
131 | ||
132 | public void setBi(final BigInteger bi) { | |
133 | this.bi = bi; | |
134 | } | |
135 | ||
136 | public UUID getUuid() { | |
137 | return uuid; | |
138 | } | |
139 | ||
140 | public void setUuid(final UUID uuid) { | |
141 | this.uuid = uuid; | |
142 | } | |
143 | } | |
144 | ||
145 | /** | |
146 | * Converter for a Model. | |
147 | * | |
148 | * @since 1.4.9 | |
149 | */ | |
150 | public static final class ModelConverter implements Converter { | |
151 | ||
152 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
153 | return type == Model.class; | |
154 | } | |
155 | ||
156 | public void marshal(final Object source, final HierarchicalStreamWriter writer, | |
157 | final MarshallingContext context) { | |
158 | final Model type = Model.class.cast(source); | |
159 | writeElement(writer, "ch", String.valueOf(type.getCh())); | |
160 | writeElement(writer, "i", String.valueOf(type.getI())); | |
161 | writeElement(writer, "s", type.getS()); | |
162 | writeElement(writer, "d", String.valueOf(type.getD())); | |
163 | writeElement(writer, "f", String.valueOf(type.getF())); | |
164 | writeElement(writer, "bi", type.getBi().toString()); | |
165 | writeElement(writer, "uuid", type.getUuid().toString()); | |
166 | } | |
167 | ||
168 | private void writeElement(final HierarchicalStreamWriter writer, final String name, final String value) { | |
169 | writer.startNode(name); | |
170 | writer.setValue(value); | |
171 | writer.endNode(); | |
172 | } | |
173 | ||
174 | public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { | |
175 | final Model type = new Model(); | |
176 | while (reader.hasMoreChildren()) { | |
177 | reader.moveDown(); | |
178 | final String value = reader.getValue(); | |
179 | final String name = reader.getNodeName(); | |
180 | if (name.equals("ch")) { | |
181 | if (value.length() != 1) { | |
182 | throw new ConversionException("Not a single character"); | |
183 | } | |
184 | type.setCh(value.charAt(0)); | |
185 | } else if (name.equals("i")) { | |
186 | type.setI(Integer.parseInt(value)); | |
187 | } else if (name.equals("s")) { | |
188 | type.setS(value); | |
189 | } else if (name.equals("d")) { | |
190 | type.setD(Double.parseDouble(value)); | |
191 | } else if (name.equals("f")) { | |
192 | type.setF(Float.parseFloat(value)); | |
193 | } else if (name.equals("bi")) { | |
194 | type.setBi(new BigInteger(value)); | |
195 | } else if (name.equals("uuid")) { | |
196 | type.setUuid(UUID.fromString(value)); | |
197 | } else { | |
198 | throw new ConversionException("Unkown element"); | |
199 | } | |
200 | reader.moveUp(); | |
201 | } | |
202 | ||
203 | return type; | |
204 | } | |
205 | ||
206 | } | |
207 | ||
208 | /** | |
209 | * Initialize the XML string to deserialize. | |
210 | * | |
211 | * @since 1.4.9 | |
212 | */ | |
213 | @Setup | |
214 | public void init() { | |
215 | array = new Model[1000]; | |
216 | for (int i = 0; i < array.length; ++i) { | |
217 | array[i] = new Model(i); | |
218 | } | |
219 | } | |
220 | ||
221 | /** | |
222 | * Setup the data to deserialize. | |
223 | * | |
224 | * @param params the parameters of the benchmark | |
225 | * @since 1.4.9 | |
226 | */ | |
227 | @Setup(Level.Trial) | |
228 | public void setUp(final BenchmarkParams params) { | |
229 | xstream = new XStream(new Xpp3Driver()); | |
230 | xstream.allowTypes(new Class[]{Model.class}); | |
231 | final String benchmark = params.getBenchmark(); | |
232 | final String name = benchmark.substring(ConverterTypeBenchmark.class.getName().length() + 1); | |
233 | if (name.equals("reflection")) { | |
234 | xstream.registerConverter(new ReflectionConverter(xstream.getMapper(), xstream.getReflectionProvider(), | |
235 | Model.class)); | |
236 | } else if (name.equals("javaBean")) { | |
237 | xstream.registerConverter(new JavaBeanConverter(xstream.getMapper(), Model.class)); | |
238 | } else if (name.equals("custom")) { | |
239 | xstream.registerConverter(new ModelConverter()); | |
240 | } else { | |
241 | throw new IllegalStateException("Unsupported benchmark type: " + benchmark); | |
242 | } | |
243 | xml = xstream.toXML(array); | |
244 | // System.out.println(xstream.toXML(array[0])); | |
245 | } | |
246 | ||
247 | /** | |
248 | * Use ReflectionConverter. | |
249 | * | |
250 | * @since 1.4.9 | |
251 | */ | |
252 | @Benchmark | |
253 | public void reflection() { | |
254 | run(); | |
255 | } | |
256 | ||
257 | /** | |
258 | * Use JavaBeanConverter. | |
259 | * | |
260 | * @since 1.4.9 | |
261 | */ | |
262 | @Benchmark | |
263 | public void javaBean() { | |
264 | run(); | |
265 | } | |
266 | ||
267 | /** | |
268 | * Use custom converter. | |
269 | * | |
270 | * @since 1.4.9 | |
271 | */ | |
272 | @Benchmark | |
273 | public void custom() { | |
274 | run(); | |
275 | } | |
276 | ||
277 | private void run() { | |
278 | final Object o = xstream.fromXML(xml); | |
279 | assert xstream.toXML(o).equals(xml) : "XML differs"; | |
280 | } | |
281 | } |
+332
-0
0 | /* | |
1 | * Copyright (C) 2015 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 16. December 2015 by Joerg Schaible, renamed from XmlFriendlyBenchmark | |
9 | */ | |
10 | package com.thoughtworks.xstream.benchmark.jmh; | |
11 | ||
12 | import java.util.concurrent.ConcurrentHashMap; | |
13 | import java.util.concurrent.ConcurrentMap; | |
14 | import java.util.concurrent.TimeUnit; | |
15 | ||
16 | import org.openjdk.jmh.annotations.Benchmark; | |
17 | import org.openjdk.jmh.annotations.BenchmarkMode; | |
18 | import org.openjdk.jmh.annotations.Fork; | |
19 | import org.openjdk.jmh.annotations.Level; | |
20 | import org.openjdk.jmh.annotations.Measurement; | |
21 | import org.openjdk.jmh.annotations.Mode; | |
22 | import org.openjdk.jmh.annotations.OutputTimeUnit; | |
23 | import org.openjdk.jmh.annotations.Scope; | |
24 | import org.openjdk.jmh.annotations.Setup; | |
25 | import org.openjdk.jmh.annotations.State; | |
26 | import org.openjdk.jmh.annotations.Threads; | |
27 | import org.openjdk.jmh.annotations.Warmup; | |
28 | import org.openjdk.jmh.infra.BenchmarkParams; | |
29 | ||
30 | import com.thoughtworks.xstream.XStream; | |
31 | import com.thoughtworks.xstream.io.naming.NameCoder; | |
32 | import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder; | |
33 | import com.thoughtworks.xstream.io.xml.Xpp3Driver; | |
34 | ||
35 | ||
36 | /** | |
37 | * Benchmark for different {@link NameCoder} implementations. | |
38 | * | |
39 | * @author Jörg Schaible | |
40 | * @since 1.4.9 | |
41 | */ | |
42 | @BenchmarkMode(Mode.AverageTime) | |
43 | @Fork(value = 1) | |
44 | @Measurement(iterations = 25) | |
45 | @OutputTimeUnit(TimeUnit.NANOSECONDS) | |
46 | @State(Scope.Benchmark) | |
47 | @Threads(4) | |
48 | @Warmup(iterations = 5) | |
49 | public class NameCoderBenchmark { | |
50 | ||
51 | private XStream xstream; | |
52 | private String xml; | |
53 | private _1._2._3._4._5.Unfriendly array[]; | |
54 | ||
55 | /** | |
56 | * No encoding, will create invalid XML for inner class types. | |
57 | * | |
58 | * @since 1.4.9 | |
59 | */ | |
60 | public static final class NoNameCoder implements NameCoder { | |
61 | ||
62 | public String encodeNode(final String name) { | |
63 | return name; | |
64 | } | |
65 | ||
66 | public String encodeAttribute(final String name) { | |
67 | return name; | |
68 | } | |
69 | ||
70 | public String decodeNode(final String nodeName) { | |
71 | return nodeName; | |
72 | } | |
73 | ||
74 | public String decodeAttribute(final String attributeName) { | |
75 | return attributeName; | |
76 | } | |
77 | } | |
78 | ||
79 | /** | |
80 | * Dollar encoding, will create invalid XML for class types in the default package. | |
81 | * | |
82 | * @since 1.4.9 | |
83 | */ | |
84 | public static final class DollarNameCoder implements NameCoder { | |
85 | ||
86 | public String encodeNode(final String name) { | |
87 | return name.replace('$', '\u00b7'); | |
88 | } | |
89 | ||
90 | public String encodeAttribute(final String name) { | |
91 | return name.replace('$', '\u00b7'); | |
92 | } | |
93 | ||
94 | public String decodeNode(final String nodeName) { | |
95 | return nodeName.replace('\u00b7', '$'); | |
96 | } | |
97 | ||
98 | public String decodeAttribute(final String attributeName) { | |
99 | return attributeName.replace('\u00b7', '$'); | |
100 | } | |
101 | } | |
102 | ||
103 | /** | |
104 | * Dollar encoding with an escaped underscore, may create invalid XML for class types defined in other languages | |
105 | * running on the JVM. | |
106 | * | |
107 | * @since 1.4.9 | |
108 | */ | |
109 | public static class EscapedUnderscoreNameCoder implements NameCoder { | |
110 | ||
111 | public String encodeNode(final String name) { | |
112 | final int length = name.length(); | |
113 | final StringBuilder sb = new StringBuilder(length + 20); | |
114 | for (int i = 0; i < length; ++i) { | |
115 | final char ch = name.charAt(i); | |
116 | switch (ch) { | |
117 | case '$': | |
118 | sb.append("_-"); | |
119 | break; | |
120 | case '_': | |
121 | sb.append("__"); | |
122 | break; | |
123 | default: | |
124 | sb.append(ch); | |
125 | } | |
126 | } | |
127 | return sb.toString(); | |
128 | } | |
129 | ||
130 | public String encodeAttribute(final String name) { | |
131 | return encodeNode(name); | |
132 | } | |
133 | ||
134 | public String decodeNode(final String nodeName) { | |
135 | final int length = nodeName.length(); | |
136 | final StringBuilder sb = new StringBuilder(length); | |
137 | for (int i = 0; i < length; ++i) { | |
138 | char ch = nodeName.charAt(i); | |
139 | if (ch == '_') { | |
140 | if (++i == length) { | |
141 | throw new IllegalStateException(); | |
142 | } | |
143 | ch = nodeName.charAt(i); | |
144 | switch (ch) { | |
145 | case '_': | |
146 | sb.append(ch); | |
147 | break; | |
148 | case '-': | |
149 | sb.append('$'); | |
150 | break; | |
151 | default: | |
152 | throw new IllegalStateException(); | |
153 | } | |
154 | } else { | |
155 | sb.append(ch); | |
156 | } | |
157 | } | |
158 | return sb.toString(); | |
159 | } | |
160 | ||
161 | public String decodeAttribute(final String attributeName) { | |
162 | return decodeNode(attributeName); | |
163 | } | |
164 | } | |
165 | ||
166 | /** | |
167 | * Cached dollar encoding with an escaped underscore, may create invalid XML for class types defined in other | |
168 | * languages running on the JVM. | |
169 | * | |
170 | * @since 1.4.9 | |
171 | */ | |
172 | public static class CachedEscapedUnderscoreNameCoder extends EscapedUnderscoreNameCoder { | |
173 | private final ConcurrentMap<String, String> encoderCache = new ConcurrentHashMap<String, String>(); | |
174 | private final ConcurrentMap<String, String> decoderCache = new ConcurrentHashMap<String, String>(); | |
175 | ||
176 | @Override | |
177 | public String encodeNode(final String name) { | |
178 | String encoded = encoderCache.get(name); | |
179 | if (encoded == null) { | |
180 | encoded = super.encodeNode(name); | |
181 | encoderCache.putIfAbsent(name, encoded); | |
182 | decoderCache.putIfAbsent(encoded, name); | |
183 | } | |
184 | return encoded; | |
185 | } | |
186 | ||
187 | @Override | |
188 | public String decodeNode(final String nodeName) { | |
189 | String decoded = decoderCache.get(nodeName); | |
190 | if (decoded == null) { | |
191 | decoded = super.decodeNode(nodeName); | |
192 | decoderCache.putIfAbsent(nodeName, decoded); | |
193 | encoderCache.putIfAbsent(decoded, nodeName); | |
194 | } | |
195 | return decoded; | |
196 | } | |
197 | } | |
198 | ||
199 | private static class _1 { | |
200 | private static class _2 { | |
201 | private static class _3 { | |
202 | private static class _4 { | |
203 | private static class _5 { | |
204 | private static class Unfriendly { | |
205 | @SuppressWarnings("unused") | |
206 | final int __i__i__; | |
207 | @SuppressWarnings("unused") | |
208 | final String x__x__; | |
209 | @SuppressWarnings("unused") | |
210 | final Unfriendly __; | |
211 | ||
212 | public Unfriendly(final int i, final Unfriendly u) { | |
213 | __i__i__ = i; | |
214 | x__x__ = Integer.toHexString(i); | |
215 | __ = u; | |
216 | } | |
217 | } | |
218 | } | |
219 | } | |
220 | } | |
221 | } | |
222 | } | |
223 | ||
224 | /** | |
225 | * Initialize the XML string to deserialize. | |
226 | * | |
227 | * @since 1.4.9 | |
228 | */ | |
229 | @Setup | |
230 | public void init() { | |
231 | array = new _1._2._3._4._5.Unfriendly[250]; | |
232 | for (int i = 0; i < array.length / 10; ++i) { | |
233 | final int idx = i * 10; | |
234 | for (int j = 0; j < 10; ++j) { | |
235 | array[idx] = new _1._2._3._4._5.Unfriendly(idx + 9 - j, array[idx]); | |
236 | if (j < 9) { | |
237 | array[idx + j + 1] = array[idx]; | |
238 | } | |
239 | } | |
240 | } | |
241 | } | |
242 | ||
243 | /** | |
244 | * Setup the data to deserialize. | |
245 | * | |
246 | * @param params the parameters of the benchmark | |
247 | * @since 1.4.9 | |
248 | */ | |
249 | @Setup(Level.Trial) | |
250 | public void setUp(final BenchmarkParams params) { | |
251 | final String benchmark = params.getBenchmark(); | |
252 | final NameCoder nameCoder; | |
253 | final String name = benchmark.substring(NameCoderBenchmark.class.getName().length() + 1); | |
254 | if (name.equals("noCoding")) { | |
255 | nameCoder = new NoNameCoder(); | |
256 | } else if (name.equals("dollarCoding")) { | |
257 | nameCoder = new DollarNameCoder(); | |
258 | } else if (name.equals("escapedUnderscoreCoding")) { | |
259 | nameCoder = new EscapedUnderscoreNameCoder(); | |
260 | } else if (name.equals("cachedEscapedUnderscoreCoding")) { | |
261 | nameCoder = new CachedEscapedUnderscoreNameCoder(); | |
262 | } else if (name.equals("xmlFriendlyCoding")) { | |
263 | nameCoder = new XmlFriendlyNameCoder(); | |
264 | } else { | |
265 | throw new IllegalStateException("Unsupported benchmark type: " + benchmark); | |
266 | } | |
267 | xstream = new XStream(new Xpp3Driver(nameCoder)); | |
268 | xstream.allowTypes(new Class[]{_1._2._3._4._5.Unfriendly.class}); | |
269 | if (nameCoder.getClass() == NoNameCoder.class) { | |
270 | xstream.alias(_1._2._3._4._5.Unfriendly.class.getName().replace('$', '\u00b7'), | |
271 | _1._2._3._4._5.Unfriendly.class); | |
272 | } | |
273 | xml = xstream.toXML(array); | |
274 | // System.out.println(xstream.toXML(array[0])); | |
275 | } | |
276 | ||
277 | /** | |
278 | * No encoding, will produce invalid XML for inner class types. | |
279 | * | |
280 | * @since 1.4.9 | |
281 | */ | |
282 | @Benchmark | |
283 | public void noCoding() { | |
284 | run(); | |
285 | } | |
286 | ||
287 | /** | |
288 | * Dollar encoding, will produce invalid XML for class types in the default package. | |
289 | * | |
290 | * @since 1.4.9 | |
291 | */ | |
292 | @Benchmark | |
293 | public void dollarCoding() { | |
294 | run(); | |
295 | } | |
296 | ||
297 | /** | |
298 | * Escaped underscore encoding, can encode any Java identifier. | |
299 | * | |
300 | * @since 1.4.9 | |
301 | */ | |
302 | @Benchmark | |
303 | public void escapedUnderscoreCoding() { | |
304 | run(); | |
305 | } | |
306 | ||
307 | /** | |
308 | * Escaped underscore encoding with caching, can encode any Java identifier. | |
309 | * | |
310 | * @since 1.4.9 | |
311 | */ | |
312 | @Benchmark | |
313 | public void cachedEscapedUnderscoreCoding() { | |
314 | run(); | |
315 | } | |
316 | ||
317 | /** | |
318 | * XML friendly encoding used by XStream as default, can encode any invalid XML character. | |
319 | * | |
320 | * @since 1.4.9 | |
321 | */ | |
322 | @Benchmark | |
323 | public void xmlFriendlyCoding() { | |
324 | run(); | |
325 | } | |
326 | ||
327 | private void run() { | |
328 | final String x = xstream.toXML(xstream.fromXML(xml)); | |
329 | assert x.equals(xml) : "XML differs"; | |
330 | } | |
331 | } |
0 | /* | |
1 | * Copyright (C) 2015 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 25. October 2015 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.benchmark.jmh; | |
11 | ||
12 | import java.io.ByteArrayInputStream; | |
13 | import java.io.ByteArrayOutputStream; | |
14 | import java.io.Writer; | |
15 | import java.util.ArrayList; | |
16 | import java.util.Arrays; | |
17 | import java.util.List; | |
18 | import java.util.concurrent.TimeUnit; | |
19 | ||
20 | import org.openjdk.jmh.annotations.Benchmark; | |
21 | import org.openjdk.jmh.annotations.BenchmarkMode; | |
22 | import org.openjdk.jmh.annotations.Fork; | |
23 | import org.openjdk.jmh.annotations.Level; | |
24 | import org.openjdk.jmh.annotations.Measurement; | |
25 | import org.openjdk.jmh.annotations.Mode; | |
26 | import org.openjdk.jmh.annotations.OutputTimeUnit; | |
27 | import org.openjdk.jmh.annotations.Param; | |
28 | import org.openjdk.jmh.annotations.Scope; | |
29 | import org.openjdk.jmh.annotations.Setup; | |
30 | import org.openjdk.jmh.annotations.State; | |
31 | import org.openjdk.jmh.annotations.Threads; | |
32 | import org.openjdk.jmh.annotations.Warmup; | |
33 | import org.openjdk.jmh.infra.BenchmarkParams; | |
34 | ||
35 | import com.thoughtworks.xstream.XStream; | |
36 | import com.thoughtworks.xstream.io.HierarchicalStreamDriver; | |
37 | import com.thoughtworks.xstream.io.HierarchicalStreamWriter; | |
38 | import com.thoughtworks.xstream.io.binary.BinaryStreamDriver; | |
39 | import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver; | |
40 | import com.thoughtworks.xstream.io.xml.BEAStaxDriver; | |
41 | import com.thoughtworks.xstream.io.xml.Dom4JDriver; | |
42 | import com.thoughtworks.xstream.io.xml.DomDriver; | |
43 | import com.thoughtworks.xstream.io.xml.JDom2Driver; | |
44 | import com.thoughtworks.xstream.io.xml.JDomDriver; | |
45 | import com.thoughtworks.xstream.io.xml.KXml2Driver; | |
46 | import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; | |
47 | import com.thoughtworks.xstream.io.xml.StandardStaxDriver; | |
48 | import com.thoughtworks.xstream.io.xml.WstxDriver; | |
49 | import com.thoughtworks.xstream.io.xml.XomDriver; | |
50 | import com.thoughtworks.xstream.io.xml.Xpp3Driver; | |
51 | ||
52 | ||
53 | /** | |
54 | * Benchmark for the different {@link HierarchicalStreamDriver} implementations. | |
55 | * | |
56 | * @author Jörg Schaible | |
57 | * @since 1.4.9 | |
58 | */ | |
59 | @BenchmarkMode(Mode.AverageTime) | |
60 | @Fork(value = 1) | |
61 | @Measurement(iterations = 15) | |
62 | @OutputTimeUnit(TimeUnit.NANOSECONDS) | |
63 | @State(Scope.Benchmark) | |
64 | @Threads(1) | |
65 | @Warmup(iterations = 5) | |
66 | public class ParserBenchmark { | |
67 | ||
68 | /** | |
69 | * Driver factory. Enum values used as parameter for the parser benchmark methods. | |
70 | * | |
71 | * @author Jörg Schaible | |
72 | * @since 1.4.9 | |
73 | */ | |
74 | public enum DriverFactory { | |
75 | /** | |
76 | * Factory for the {@link Xpp3Driver}. | |
77 | * | |
78 | * @since 1.4.9 | |
79 | */ | |
80 | Xpp3(new Xpp3Driver()), // | |
81 | /** | |
82 | * Factory for the {@link KXml2Driver}. | |
83 | * | |
84 | * @since 1.4.9 | |
85 | */ | |
86 | kXML2(new KXml2Driver()), // | |
87 | /** | |
88 | * Factory for the {@link StandardStaxDriver}. | |
89 | * | |
90 | * @since 1.4.9 | |
91 | */ | |
92 | JDKStax(new StandardStaxDriver()), // | |
93 | /** | |
94 | * Factory for the {@link WstxDriver}. | |
95 | * | |
96 | * @since 1.4.9 | |
97 | */ | |
98 | Woodstox(new WstxDriver()), // | |
99 | /** | |
100 | * Factory for the {@link BEAStaxDriver}. | |
101 | * | |
102 | * @since 1.4.9 | |
103 | */ | |
104 | BEAStax(new BEAStaxDriver()), // | |
105 | /** | |
106 | * Factory for the {@link DomDriver}. | |
107 | * | |
108 | * @since 1.4.9 | |
109 | */ | |
110 | DOM(new DomDriver()), // | |
111 | /** | |
112 | * Factory for the {@link Dom4JDriver}. | |
113 | * | |
114 | * @since 1.4.9 | |
115 | */ | |
116 | DOM4J(new Dom4JDriver() { // XML writer of DOM4J fails | |
117 | public HierarchicalStreamWriter createWriter(final Writer out) { | |
118 | return new PrettyPrintWriter(out, getNameCoder()); | |
119 | } | |
120 | }), // | |
121 | /** | |
122 | * Factory for the {@link JDomDriver}. | |
123 | * | |
124 | * @since 1.4.9 | |
125 | */ | |
126 | JDom(new JDomDriver()), // | |
127 | /** | |
128 | * Factory for the {@link JDom2Driver}. | |
129 | * | |
130 | * @since 1.4.9 | |
131 | */ | |
132 | JDom2(new JDom2Driver()), // | |
133 | /** | |
134 | * Factory for the {@link XomDriver}. | |
135 | * | |
136 | * @since 1.4.9 | |
137 | */ | |
138 | Xom(new XomDriver()), // | |
139 | /** | |
140 | * Factory for the {@link BinaryStreamDriver}. | |
141 | * | |
142 | * @since 1.4.9 | |
143 | */ | |
144 | Binary(new BinaryStreamDriver()), // | |
145 | /** | |
146 | * Factory for the {@link JettisonMappedXmlDriver}. | |
147 | * | |
148 | * @since 1.4.9 | |
149 | */ | |
150 | Jettison(new JettisonMappedXmlDriver()); | |
151 | ||
152 | private final HierarchicalStreamDriver driver; | |
153 | ||
154 | private DriverFactory(final HierarchicalStreamDriver driver) { | |
155 | this.driver = driver; | |
156 | } | |
157 | ||
158 | /** | |
159 | * Request the driver of the instantiated factory. | |
160 | * | |
161 | * @return the driver | |
162 | * @since 1.4.9 | |
163 | */ | |
164 | public HierarchicalStreamDriver getDriver() { | |
165 | return driver; | |
166 | } | |
167 | } | |
168 | ||
169 | /** | |
170 | * Data factory. Enum values used as data generator and checker for the individual parser benchmark methods. Method | |
171 | * names define the data factory to use for the benchmark. | |
172 | * | |
173 | * @author Jörg Schaible | |
174 | * @since 1.4.9 | |
175 | */ | |
176 | public enum DataFactory { | |
177 | /** | |
178 | * A single element with a text of 100.000 characters. | |
179 | * | |
180 | * @author Jörg Schaible | |
181 | * @since 1.4.9 | |
182 | */ | |
183 | BigText { | |
184 | private int length; | |
185 | private String start; | |
186 | private String end; | |
187 | ||
188 | @Override | |
189 | public void writeData(final HierarchicalStreamWriter writer) { | |
190 | int length = 100000; | |
191 | final StringBuilder builder = new StringBuilder(length); | |
192 | int i = 0; | |
193 | while (length > 0) { | |
194 | final int codePoint = i % Character.MAX_CODE_POINT; | |
195 | if (Character.isLetterOrDigit(codePoint)) { | |
196 | builder.appendCodePoint(codePoint); | |
197 | --length; | |
198 | } | |
199 | ++i; | |
200 | } | |
201 | final String s = builder.toString(); | |
202 | this.length = s.length(); | |
203 | start = s.substring(0, 100); | |
204 | end = s.substring(this.length - 100); | |
205 | ||
206 | writer.startNode("string"); | |
207 | writer.setValue(s); | |
208 | writer.endNode(); | |
209 | } | |
210 | ||
211 | @Override | |
212 | public void checkData(final Object o) { | |
213 | final String s = String.class.cast(o); | |
214 | assert length == s.length() : BigText + " fails length"; | |
215 | assert start.equals(s.substring(0, 100)) : BigText + " fails start"; | |
216 | assert end.equals(s.substring(length - 100)) : BigText + " fails end"; | |
217 | } | |
218 | }, | |
219 | /** | |
220 | * Nested list in list structure, 500 elements deep. | |
221 | * | |
222 | * @author Jörg Schaible | |
223 | * @since 1.4.9 | |
224 | */ | |
225 | NestedElements { | |
226 | private static final int DEPTH = 500; | |
227 | private List<Integer> list; | |
228 | ||
229 | @Override | |
230 | public void writeData(final HierarchicalStreamWriter writer) { | |
231 | for (int i = 0; i < DEPTH; ++i) { | |
232 | writer.startNode("list"); | |
233 | } | |
234 | list = new ArrayList<Integer>(Arrays.asList(42, 7, 3, -17)); | |
235 | for (final Integer i : list) { | |
236 | writer.startNode("int"); | |
237 | writer.setValue(i.toString()); | |
238 | writer.endNode(); | |
239 | } | |
240 | for (int i = 0; i < DEPTH; ++i) { | |
241 | writer.endNode(); | |
242 | } | |
243 | } | |
244 | ||
245 | @Override | |
246 | public void checkData(final Object o) { | |
247 | List<?> list = List.class.cast(o); | |
248 | int depth = DEPTH; | |
249 | while (depth-- > 1) { | |
250 | assert list.size() == 1 : NestedElements + " fails list size"; | |
251 | list = List.class.cast(list.get(0)); | |
252 | } | |
253 | assert this.list.equals(list) : NestedElements + " fails inner list"; | |
254 | } | |
255 | }, | |
256 | /** | |
257 | * An array with 1.000 elements. | |
258 | * | |
259 | * @author Jörg Schaible | |
260 | * @since 1.4.9 | |
261 | */ | |
262 | ManyChildren { | |
263 | private static final int LENGTH = 1000; | |
264 | ||
265 | @Override | |
266 | public void writeData(final HierarchicalStreamWriter writer) { | |
267 | int length = LENGTH; | |
268 | writer.startNode("int-array"); | |
269 | while (length-- > 0) { | |
270 | writer.startNode("int"); | |
271 | writer.setValue(String.valueOf(length)); | |
272 | writer.endNode(); | |
273 | } | |
274 | writer.endNode(); | |
275 | } | |
276 | ||
277 | @Override | |
278 | public void checkData(final Object o) { | |
279 | final int[] array = int[].class.cast(o); | |
280 | assert LENGTH == array.length : ManyChildren + " fails length"; | |
281 | assert LENGTH - 1 == array[0] : ManyChildren + " fails start"; | |
282 | assert 0 == array[LENGTH - 1] : ManyChildren + " fails end"; | |
283 | } | |
284 | }; | |
285 | /** | |
286 | * Write the data of the factory into the writer of the hierarchical stream. | |
287 | * | |
288 | * @param writer the writer of the data | |
289 | * @since 1.4.9 | |
290 | */ | |
291 | public abstract void writeData(HierarchicalStreamWriter writer); | |
292 | ||
293 | /** | |
294 | * Check the deserialized object. | |
295 | * | |
296 | * @param o the object to check | |
297 | * @since 1.4.9 | |
298 | */ | |
299 | public abstract void checkData(Object o); | |
300 | } | |
301 | ||
302 | @Param | |
303 | private DriverFactory driverFactory; | |
304 | private DataFactory dataFactory; | |
305 | private byte[] data; | |
306 | private XStream xstream; | |
307 | private HierarchicalStreamDriver driver; | |
308 | ||
309 | /** | |
310 | * Initialize the XStream instance and instantiate the driver for the benchmark. | |
311 | * | |
312 | * @since 1.4.9 | |
313 | */ | |
314 | @Setup | |
315 | public void init() { | |
316 | xstream = new XStream(); | |
317 | xstream.setMode(XStream.NO_REFERENCES); | |
318 | driver = driverFactory.getDriver(); | |
319 | } | |
320 | ||
321 | /** | |
322 | * Setup the data to deserialize. | |
323 | * | |
324 | * @param params the parameters of the benchmark | |
325 | * @since 1.4.9 | |
326 | */ | |
327 | @Setup(Level.Trial) | |
328 | public void setUp(final BenchmarkParams params) { | |
329 | final String benchmark = params.getBenchmark(); | |
330 | dataFactory = DataFactory.valueOf(benchmark.substring(benchmark.lastIndexOf('.') + 6)); | |
331 | ||
332 | final ByteArrayOutputStream baos = new ByteArrayOutputStream(1024 * 1024); | |
333 | final HierarchicalStreamWriter writer = driver.createWriter(baos); | |
334 | dataFactory.writeData(writer); | |
335 | writer.close(); | |
336 | data = baos.toByteArray(); | |
337 | } | |
338 | ||
339 | /** | |
340 | * Parse an element with a big text as value. | |
341 | * | |
342 | * @since 1.4.9 | |
343 | */ | |
344 | @Benchmark | |
345 | public void parseBigText() { | |
346 | final Object o = xstream.unmarshal(driver.createReader(new ByteArrayInputStream(data))); | |
347 | dataFactory.checkData(o); | |
348 | } | |
349 | ||
350 | /** | |
351 | * Parse a deeply nested structure. | |
352 | * | |
353 | * @since 1.4.9 | |
354 | */ | |
355 | @Benchmark | |
356 | public void parseNestedElements() { | |
357 | final Object o = xstream.unmarshal(driver.createReader(new ByteArrayInputStream(data))); | |
358 | dataFactory.checkData(o); | |
359 | } | |
360 | ||
361 | /** | |
362 | * Parse an element with a lot of simple children. | |
363 | * | |
364 | * @since 1.4.9 | |
365 | */ | |
366 | @Benchmark | |
367 | public void parseManyChildren() { | |
368 | final Object o = xstream.unmarshal(driver.createReader(new ByteArrayInputStream(data))); | |
369 | dataFactory.checkData(o); | |
370 | } | |
371 | } |
+328
-0
0 | /* | |
1 | * Copyright (C) 2015 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.11.2015 by Joerg Schaible | |
9 | */ | |
10 | package com.thoughtworks.xstream.benchmark.jmh; | |
11 | ||
12 | import java.io.StringWriter; | |
13 | import java.util.Collections; | |
14 | import java.util.Map; | |
15 | import java.util.UUID; | |
16 | import java.util.concurrent.ConcurrentHashMap; | |
17 | import java.util.concurrent.ConcurrentMap; | |
18 | import java.util.concurrent.TimeUnit; | |
19 | ||
20 | import org.openjdk.jmh.annotations.Benchmark; | |
21 | import org.openjdk.jmh.annotations.BenchmarkMode; | |
22 | import org.openjdk.jmh.annotations.Fork; | |
23 | import org.openjdk.jmh.annotations.Level; | |
24 | import org.openjdk.jmh.annotations.Measurement; | |
25 | import org.openjdk.jmh.annotations.Mode; | |
26 | import org.openjdk.jmh.annotations.OutputTimeUnit; | |
27 | import org.openjdk.jmh.annotations.Scope; | |
28 | import org.openjdk.jmh.annotations.Setup; | |
29 | import org.openjdk.jmh.annotations.State; | |
30 | import org.openjdk.jmh.annotations.Threads; | |
31 | import org.openjdk.jmh.annotations.Warmup; | |
32 | import org.openjdk.jmh.infra.BenchmarkParams; | |
33 | ||
34 | import com.thoughtworks.xstream.XStream; | |
35 | import com.thoughtworks.xstream.converters.SingleValueConverter; | |
36 | import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; | |
37 | import com.thoughtworks.xstream.core.util.WeakCache; | |
38 | import com.thoughtworks.xstream.io.xml.CompactWriter; | |
39 | import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; | |
40 | import com.thoughtworks.xstream.io.xml.Xpp3Driver; | |
41 | ||
42 | ||
43 | /** | |
44 | * Benchmark for different StringConverter implementations. | |
45 | * | |
46 | * @author Jörg Schaible | |
47 | * @since 1.4.9 | |
48 | */ | |
49 | @BenchmarkMode(Mode.AverageTime) | |
50 | @Fork(value = 1) | |
51 | @Measurement(iterations = 16) | |
52 | @OutputTimeUnit(TimeUnit.NANOSECONDS) | |
53 | @State(Scope.Benchmark) | |
54 | @Threads(4) | |
55 | @Warmup(iterations = 5) | |
56 | public class StringConverterBenchmark { | |
57 | ||
58 | private XStream xstream; | |
59 | private String xml; | |
60 | ||
61 | /** | |
62 | * No memory usage for cache, but any string is a separate instance after deserialization. Memory consumption of the | |
63 | * deserialized array is nearly 3 times compared to a converter that caches and reuses the strings. | |
64 | * | |
65 | * @since 1.4.9 | |
66 | */ | |
67 | public static final class NonCachingStringConverter extends AbstractSingleValueConverter { | |
68 | ||
69 | @Override | |
70 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
71 | return type == String.class; | |
72 | } | |
73 | ||
74 | @Override | |
75 | public Object fromString(final String str) { | |
76 | return str; | |
77 | } | |
78 | } | |
79 | ||
80 | /** | |
81 | * Cache based on String.intern(). Uses PermGenSpace for Java 7 and below. | |
82 | * | |
83 | * @since 1.4.9 | |
84 | */ | |
85 | public static final class InternStringConverter extends AbstractSingleValueConverter { | |
86 | ||
87 | @Override | |
88 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
89 | return type == String.class; | |
90 | } | |
91 | ||
92 | @Override | |
93 | public Object fromString(final String str) { | |
94 | return str.intern(); | |
95 | } | |
96 | } | |
97 | ||
98 | /** | |
99 | * Cache based on a synchronized WeakHashMap with weak keys. Ensures that the deserialized strings vanish when the | |
100 | * deserialized object is GC'ed. | |
101 | * | |
102 | * @since 1.4.9 | |
103 | */ | |
104 | public class SynchronizedWeakCacheStringConverter extends AbstractSingleValueConverter { | |
105 | ||
106 | private final Map<String, String> cache; | |
107 | private final int lengthLimit; | |
108 | ||
109 | private SynchronizedWeakCacheStringConverter(final Map<String, String> map, final int lengthLimit) { | |
110 | cache = map; | |
111 | this.lengthLimit = lengthLimit; | |
112 | } | |
113 | ||
114 | /** | |
115 | * Constructs a SynchronizedWeakCacheStringConverter. | |
116 | * | |
117 | * @param lengthLimit length limit for cached strings | |
118 | * @since 1.4.9 | |
119 | */ | |
120 | @SuppressWarnings("unchecked") | |
121 | public SynchronizedWeakCacheStringConverter(final int lengthLimit) { | |
122 | this(Collections.synchronizedMap(new WeakCache()), lengthLimit); | |
123 | } | |
124 | ||
125 | @Override | |
126 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
127 | return type.equals(String.class); | |
128 | } | |
129 | ||
130 | @Override | |
131 | public Object fromString(final String str) { | |
132 | if (cache != null && str != null && (lengthLimit < 0 || str.length() <= lengthLimit)) { | |
133 | String s = cache.get(str); | |
134 | ||
135 | if (s == null) { | |
136 | // fill cache | |
137 | cache.put(str, str); | |
138 | ||
139 | s = str; | |
140 | } | |
141 | ||
142 | return s; | |
143 | } else { | |
144 | return str; | |
145 | } | |
146 | } | |
147 | } | |
148 | ||
149 | /** | |
150 | * Cache based on a ConcurrentMap. Cache is never flushed. | |
151 | * | |
152 | * @since 1.4.9 | |
153 | */ | |
154 | public class ConcurrentHashMapStringConverter extends AbstractSingleValueConverter { | |
155 | ||
156 | private final ConcurrentMap<String, String> cache; | |
157 | private final int lengthLimit; | |
158 | ||
159 | private ConcurrentHashMapStringConverter(final ConcurrentMap<String, String> map, final int lengthLimit) { | |
160 | cache = map; | |
161 | this.lengthLimit = lengthLimit; | |
162 | } | |
163 | ||
164 | /** | |
165 | * Constructs a ConcurrentHashMapStringConverter. | |
166 | * | |
167 | * @param lengthLimit length limit for cached strings | |
168 | * @since 1.4.9 | |
169 | */ | |
170 | public ConcurrentHashMapStringConverter(final int lengthLimit) { | |
171 | this(new ConcurrentHashMap<String, String>(), lengthLimit); | |
172 | } | |
173 | ||
174 | @Override | |
175 | public boolean canConvert(@SuppressWarnings("rawtypes") final Class type) { | |
176 | return type.equals(String.class); | |
177 | } | |
178 | ||
179 | @Override | |
180 | public Object fromString(final String str) { | |
181 | if (cache != null && str != null && (lengthLimit < 0 || str.length() <= lengthLimit)) { | |
182 | final String s = cache.putIfAbsent(str, str); | |
183 | return s == null ? str : s; | |
184 | } else { | |
185 | return str; | |
186 | } | |
187 | } | |
188 | } | |
189 | ||
190 | /** | |
191 | * Initialize the XML string to deserialize. | |
192 | * | |
193 | * @since 1.4.9 | |
194 | */ | |
195 | @Setup | |
196 | public void init() { | |
197 | final String array[] = new String[300]; | |
198 | for (int i = 0; i < 100;) { | |
199 | array[i] = String.valueOf(++i); | |
200 | } | |
201 | for (int i = 100; i < 200;) { | |
202 | array[i] = "Binary value " + i + ": " + Integer.toString(++i, 2); | |
203 | } | |
204 | for (int i = 200; i < 300;) { | |
205 | array[i++] = UUID.randomUUID().toString().replace('-', ':'); | |
206 | } | |
207 | ||
208 | final StringWriter stringWriter = new StringWriter(); | |
209 | final PrettyPrintWriter writer = new CompactWriter(stringWriter); | |
210 | writer.startNode("string-array"); | |
211 | for (int i = 0; i < 10000; ++i) { | |
212 | writer.startNode("string"); | |
213 | final String s; | |
214 | if ((i & 1) == 1) { | |
215 | s = array[(i >> 1) % 100]; | |
216 | } else if ((i & 2) == 2) { | |
217 | s = array[100 + (i >> 2) % 100]; | |
218 | } else if ((i & 4) == 4) { | |
219 | s = array[200 + (i >> 3) % 100]; | |
220 | } else { | |
221 | s = "Random UUID: " + UUID.randomUUID().toString(); | |
222 | } | |
223 | writer.setValue(s); | |
224 | writer.endNode(); | |
225 | } | |
226 | writer.endNode(); | |
227 | writer.close(); | |
228 | xml = stringWriter.toString(); | |
229 | } | |
230 | ||
231 | /** | |
232 | * Setup the data to deserialize. | |
233 | * | |
234 | * @param params the parameters of the benchmark | |
235 | * @since 1.4.9 | |
236 | */ | |
237 | @Setup(Level.Trial) | |
238 | public void setUp(final BenchmarkParams params) { | |
239 | final String benchmark = params.getBenchmark(); | |
240 | final SingleValueConverter converter; | |
241 | final String name = benchmark.substring(StringConverterBenchmark.class.getName().length() + 1); | |
242 | if ("nonCaching".equals(name)) { | |
243 | converter = new NonCachingStringConverter(); | |
244 | } else if ("intern".equals(name)) { | |
245 | converter = new InternStringConverter(); | |
246 | } else if ("unlimitedSynchronizedWeakCache".equals(name)) { | |
247 | converter = new SynchronizedWeakCacheStringConverter(Integer.MAX_VALUE); | |
248 | } else if ("limitedSynchronizedWeakCache".equals(name)) { | |
249 | converter = new SynchronizedWeakCacheStringConverter(UUID.randomUUID().toString().length() + 2); | |
250 | } else if ("unlimitedConcurrentMap".equals(name)) { | |
251 | converter = new SynchronizedWeakCacheStringConverter(Integer.MAX_VALUE); | |
252 | } else if ("limitedConcurrentMap".equals(name)) { | |
253 | converter = new SynchronizedWeakCacheStringConverter(UUID.randomUUID().toString().length() + 2); | |
254 | } else { | |
255 | throw new IllegalStateException("Unsupported benchmark type: " + benchmark); | |
256 | } | |
257 | xstream = new XStream(new Xpp3Driver()); | |
258 | xstream.registerConverter(converter); | |
259 | } | |
260 | ||
261 | /** | |
262 | * No cache for deserialized strings, each string is an own instance. | |
263 | * | |
264 | * @since 1.4.9 | |
265 | */ | |
266 | @Benchmark | |
267 | public void nonCaching() { | |
268 | run(); | |
269 | } | |
270 | ||
271 | /** | |
272 | * Any string is stored also in the String's internal memory space. | |
273 | * | |
274 | * @since 1.4.9 | |
275 | */ | |
276 | @Benchmark | |
277 | public void intern() { | |
278 | run(); | |
279 | } | |
280 | ||
281 | /** | |
282 | * Any string is cached in a weak entry. | |
283 | * | |
284 | * @since 1.4.9 | |
285 | */ | |
286 | @Benchmark | |
287 | public void unlimitedSynchronizedWeakCache() { | |
288 | run(); | |
289 | } | |
290 | ||
291 | /** | |
292 | * Strings of 38 characters or less are cached in a weak entry. | |
293 | * | |
294 | * @since 1.4.9 | |
295 | */ | |
296 | @Benchmark | |
297 | public void limitedSynchronizedWeakCache() { | |
298 | run(); | |
299 | } | |
300 | ||
301 | /** | |
302 | * Any string is cached in a concurrent map. | |
303 | * | |
304 | * @since 1.4.9 | |
305 | */ | |
306 | @Benchmark | |
307 | public void unlimitedConcurrentMap() { | |
308 | run(); | |
309 | } | |
310 | ||
311 | /** | |
312 | * Strings of 38 characters or less are cached in a concurrent map. | |
313 | * | |
314 | * @since 1.4.9 | |
315 | */ | |
316 | @Benchmark | |
317 | public void limitedConcurrentMap() { | |
318 | run(); | |
319 | } | |
320 | ||
321 | private void run() { | |
322 | final String[] array = (String[])xstream.fromXML(xml); | |
323 | assert array.length == 10000 : "array length is " + array.length; | |
324 | assert array[1].equals("1") : "2nd element was: " + array[1]; | |
325 | assert array[9999].equals("100") : "last element was: " + array[9999]; | |
326 | } | |
327 | } |
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 |
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 |
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 |
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 |