diff --git a/BUILD.txt b/BUILD.txt new file mode 100644 index 0000000..7ccabf6 --- /dev/null +++ b/BUILD.txt @@ -0,0 +1,15 @@ +For Java 5 or higher build with Maven 2.2 or 3 +For Java 1.4 build with Maven 2.0.11 + +Before building: + +To build: + +mvn clean install + +Before deploying: + +copy settings-template.xml to ~/.m2/settings.xml adding your Codehaus DAV username and passwords. + +To deploy (optionally adding sources and javadoc jars): +mvn deploy diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..fa11e38 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,28 @@ +(BSD Style License) + +Copyright (c) 2003-2006, Joe Walnes +Copyright (c) 2006-2011, XStream Committers +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of +conditions and the following disclaimer. Redistributions in binary form must reproduce +the above copyright notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the distribution. + +Neither the name of XStream nor the names of its contributors may be used to endorse +or promote products derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY +WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..0639a48 --- /dev/null +++ b/README.txt @@ -0,0 +1,37 @@ + + *********** +********************** XStream ********************** + *********** + + "Java to XML Serialization, and back again" + + +--[ Binaries ]----------------------------------------------- + +All binary artifacts are in the 'lib' directory. These include the +xstream jars and any other library used at build time, +or optional runtime extras. kXML2 is recommend for use as it will +greatly improve the performance of XStream. + +--[ Documentation ]------------------------------------------ + +Documentation can be found in docs/index.html. This includes: + * Introduction and tutorial + * JavaDoc + * Change log + * Frequently asked questions + +--[ Source ]------------------------------------------------- + +The complete source for XStream is bundled. This includes: + * Main API [src/java] + * Unit tests [src/test] + * Maven build files [pom.xml] + * Dependencies [lib] + +------------------------------------------------------------- + +-XStream Ccommitters + + http://xstream.codehaus.org/ + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..e77fd16 --- /dev/null +++ b/pom.xml @@ -0,0 +1,822 @@ + + + 4.0.0 + + org.codehaus + codehaus-parent + 3 + + + com.thoughtworks.xstream + xstream-parent + pom + 1.4.8 + XStream Parent + + XStream is a serialization library from Java objects to XML and back. + + + 2004 + + XStream + http://xstream.codehaus.org + + + + + jdk19 + + 1.9 + + + 1.6 + 1.6 + + + + jdk18ge + + [1.8,) + + + -Xdoclint:-missing + + + + jdk15-ge + + [1.5,) + + + + + org.apache.felix + maven-bundle-plugin + + + bundle-manifest + process-classes + + manifest + + + + + + + + + + + + jdk15 + + 1.5 + + + 1.8.0.10 + 3.6.6.Final + + + + + jdk14 + + 1.4 + + + 1.3 + 1.3 + http://docs.oracle.com/javase/1.4.2/docs/api/ + + 1.8.0.10 + 3.3.2.GA + 3.6.6.Final + + + + java + + + src/java + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + + ${version.plugin.maven.enforcer} + + + enforce-java-version + + enforce + + + + + ${version.java.enforced} + + + + + + + + + + + xstream-release + + [1.8,1.9) + + + + + org.apache.maven.plugins + maven-gpg-plugin + + + sign-artifacts + verify + + sign + + + + + + + + + + + xstream + xstream-hibernate + xstream-benchmark + xstream-distribution + + + + + BSD style + http://xstream.codehaus.org/license.html + repo + + + + + + + com.thoughtworks.xstream + xstream + 1.4.8 + + + com.thoughtworks.xstream + xstream + 1.4.8 + tests + test-jar + test + + + com.thoughtworks.xstream + xstream + 1.4.8 + javadoc + provided + + + com.thoughtworks.xstream + xstream-hibernate + 1.4.8 + + + com.thoughtworks.xstream + xstream-hibernate + 1.4.8 + javadoc + provided + + + com.thoughtworks.xstream + xstream-benchmark + 1.4.8 + + + com.thoughtworks.xstream + xstream-benchmark + 1.4.8 + javadoc + provided + + + + commons-io + commons-io + ${version.commons.io} + + + + commons-cli + commons-cli + ${version.commons.cli} + + + + commons-lang + commons-lang + ${version.commons.lang} + + + + cglib + cglib-nodep + ${version.cglib.nodep} + + + javassist + javassist + ${version.javaassist} + + + + dom4j + dom4j + ${version.dom4j} + + + xml-apis + xml-apis + + + + + + org.jdom + jdom + ${version.org.jdom} + + + org.jdom + jdom2 + ${version.org.jdom2} + + + + joda-time + joda-time + ${version.joda-time} + + + + com.megginson.sax + xml-writer + ${version.com.megginson.sax.xml-writer} + + + xml-apis + xml-apis + + + + + + stax + stax + ${version.stax} + + + stax + stax-api + ${version.stax.api} + + + + org.codehaus.woodstox + wstx-asl + ${version.org.codehaus.woodstox.asl} + + + + xom + xom + ${version.xom} + + + xerces + xmlParserAPIs + + + xerces + xercesImpl + + + xalan + xalan + + + jaxen + jaxen + + + + + + xpp3 + xpp3_min + ${version.xpp3} + + + net.sf.kxml + kxml2-min + ${version.net.sf.kxml.kxml2} + + + net.sf.kxml + kxml2 + ${version.net.sf.kxml.kxml2} + + + xmlpull + xmlpull + ${version.xmlpull} + + + + oro + oro + ${version.oro} + + + + org.json + json + ${version.org.json} + + + + org.codehaus.jettison + jettison + ${version.org.codehaus.jettison} + + + + xml-apis + xml-apis + ${version.xml-apis} + + + + xerces + xercesImpl + ${version.xerces.impl} + + + + org.hibernate + hibernate-core + ${version.org.hibernate.core} + + + org.hibernate + hibernate-envers + ${version.org.hibernate.envers} + + + cglib + cglib + + + + + org.hsqldb + hsqldb + ${version.hsqldb} + + + org.slf4j + slf4j-api + ${version.org.slf4j} + runtime + + + org.slf4j + slf4j-simple + ${version.org.slf4j} + runtime + + + + + junit + junit + ${version.junit} + test + + + + jmock + jmock + ${version.jmock} + test + + + + + + + ${basedir}/src/java + + + ${basedir}/src/java + + **/*.properties + **/*.xml + + + + ${basedir}/src/test + + + ${basedir}/src/test + + **/*.xml + **/*.xsl + **/*.txt + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + ${version.plugin.maven.antrun} + + + org.apache.maven.plugins + maven-assembly-plugin + ${version.plugin.maven.assembly} + + + org.apache.maven.plugins + maven-clean-plugin + ${version.plugin.maven.clean} + + + org.apache.maven.plugins + maven-compiler-plugin + ${version.plugin.maven.compiler} + + ${version.java.source} + ${version.java.target} + + + + org.apache.maven.plugins + maven-dependency-plugin + ${version.plugin.maven.dependency} + + + org.apache.maven.plugins + maven-deploy-plugin + ${version.plugin.maven.deploy} + + + org.apache.maven.plugins + maven-eclipse-plugin + + true + [artifactId]-1.4.x + + + + org.apache.maven.plugins + maven-enforcer-plugin + ${version.plugin.maven.enforcer} + + + org.apache.maven.plugins + maven-gpg-plugin + ${version.plugin.maven.gpg} + + + org.apache.maven.plugins + maven-install-plugin + ${version.plugin.maven.install} + + + org.apache.maven.plugins + maven-jar-plugin + ${version.plugin.maven.jar} + + + + true + true + + + ${project.info.majorVersion}.${project.info.minorVersion} + ${version.java.source} + ${version.java.target} + Maven ${maven.version} + ${maven.build.timestamp} + ${os.name} + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${version.plugin.maven.javadoc} + + + attach-javadocs + + jar + + + + + false + ${javadoc.xdoclint} + ${version.java.source} + + ${link.javadoc.javase} + + + + true + true + + + ${project.info.majorVersion}.${project.info.minorVersion} + + + + + + org.apache.maven.plugins + maven-release-plugin + ${version.plugin.maven.release} + + deploy + true + + -Pxstream-release + + + + org.apache.maven.plugins + maven-resources-plugin + ${version.plugin.maven.resources} + + + org.apache.maven.plugins + maven-site-plugin + ${version.plugin.maven.site} + + + org.apache.maven.plugins + maven-source-plugin + ${version.plugin.maven.source} + + + attach-sources + package + + jar-no-fork + + + + + + + true + true + + + ${project.info.majorVersion}.${project.info.minorVersion} + 2 + ${project.name} Sources + ${project.artifactId}.sources + ${project.organization.name} Sources + ${project.info.osgiVersion} Sources + ${project.artifactId};version=${project.info.osgiVersion} + ${version.java.source} + ${version.java.target} + Maven ${maven.version} + ${maven.build.timestamp} + ${os.name} + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${version.plugin.maven.surefire} + + once + true + false + + **/*Test.java + **/*TestSuite.java + + + **/Abstract*Test.java + **/*$*.java + + + + java.awt.headless + true + + + + + + org.apache.maven.plugins + maven-surefire-report-plugin + ${version.plugin.maven.surefire} + + + org.codehaus.mojo + build-helper-maven-plugin + ${version.plugin.mojo.build-helper} + + + org.codehaus.mojo + cobertura-maven-plugin + ${version.plugin.mojo.cobertura} + + + + clean + + + + + + org.codehaus.mojo + jxr-maven-plugin + ${version.plugin.mojo.jxr} + + + org.codehaus.xsite + xsite-maven-plugin + ${version.plugin.codehaus.xsite} + + + org.apache.felix + maven-bundle-plugin + ${version.plugin.felix.bundle} + + ${project.build.directory}/OSGi + + <_nouses>true + ${project.artifactId} + ${project.info.majorVersion}.${project.info.minorVersion} + + + + false + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + versions + initialize + + maven-version + parse-version + + + project.info + + + + + + org.apache.maven.plugins + maven-release-plugin + + https://svn.codehaus.org/xstream/tags + + + + + + org.apache.maven.wagon + wagon-webdav + ${version.org.apache.maven.wagon.webdev} + + + + + + + + codehaus.org + Codehaus XStream Site + dav:https://dav.codehaus.org/xstream + + + + + scm:svn:http://svn.codehaus.org/xstream/tags/XSTREAM_1_4_8 + scm:svn:https://svn.codehaus.org/xstream/tags/XSTREAM_1_4_8 + http://fisheye.codehaus.org/browse/xstream/tags/XSTREAM_1_4_8 + + + + 1.5 + 1.5 + [1.4,) + + 1.2.1 + 2.3.7 + 1.1 + 2.1 + 2.2 + 2.1 + 2.1 + 2.3 + 1.4 + 1.4 + 2.2 + 2.2 + 2.10 + 2.1 + 2.2 + 2.0-beta-6 + 2.1.2 + 2.4.3 + 1.5 + 2.0 + 2.0-beta-1 + + 1.0-beta-2 + + 2.2 + 0.2 + 1.1 + 1.4 + 2.4 + 1.6.1 + 2.2.8 + 3.12.1.GA + 1.0.1 + 1.6 + 3.8.1 + 2.3.0 + 1.2 + 3.2.7 + 4.2.5.Final + ${version.org.hibernate.core} + 1.1.3 + 2.0.5 + 20080701 + 1.6.1 + 2.0.8 + 1.2.0 + 1.0.1 + 2.8.1 + 1.3.04 + 1.1.3.1 + 1.1 + 1.1.4c + + http://docs.oracle.com/javase/8/docs/api/ + + + + diff --git a/settings-template.xml b/settings-template.xml new file mode 100644 index 0000000..b67ae92 --- /dev/null +++ b/settings-template.xml @@ -0,0 +1,30 @@ + + + + + + codehaus-nexus-snapshots + your-xircles-id + your-xircles-pwd + + + codehaus-nexus-staging + your-xircles-id + your-xircles-pwd + + + codehaus.org + + + + + diff --git a/svn-autoprops.config b/svn-autoprops.config new file mode 100644 index 0000000..b0fcf67 --- /dev/null +++ b/svn-autoprops.config @@ -0,0 +1,84 @@ +[auto-props] +*.apt = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.c = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.c++ = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.cpp = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.cs = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.css = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.dtd = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.ent = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.fml = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.groovy = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.h = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.h++ = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.hpp = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.html = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.idl = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.include = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.java = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.js = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.jsp = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.ldf = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.ldif = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.mak = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.mdo = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.php = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.rb = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.rtf = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.sql = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.svg = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.t2t = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.vm = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.xhtml = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.xml = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.xsd = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.xsl = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +*.xslt = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision +Makefile = svn:eol-style=native;svn:keywords=Author Date Id HeadURL Revision + +*.launch = svn:eol-style=native +*.MF = svn:eol-style=native +*.properties = svn:eol-style=native +*.script = svn:eol-style=native +*.txt = svn:eol-style=native + +*.dsp = svn:eol-style=CRLF +*.dsw = svn:eol-style=CRLF + +*.iml = svn:eol-style=LF + +*.bat = svn:eol-style=CRLF;svn:executable;svn:keywords=Author Date Id HeadURL Revision +*.cmd = svn:eol-style=CRLF;svn:executable;svn:keywords=Author Date Id HeadURL Revision + +*.ksh = svn:eol-style=LF;svn:executable;svn:keywords=Author Date Id HeadURL Revision +*.sh = svn:eol-style=LF;svn:executable;svn:keywords=Author Date Id HeadURL Revision + +*.pl = svn:eol-style=native;svn:executable;svn:keywords=Author Date Id HeadURL Revision +*.py = svn:eol-style=native;svn:executable;svn:keywords=Author Date Id HeadURL Revision + +*.bmp = svn:mime-type=image/bmp;svn:needs-lock=* +*.gif = svn:mime-type=image/gif;svn:needs-lock=* +*.ico = svn:mime-type=image/x-icon;svn:needs-lock=* +*.jpeg = svn:mime-type=image/jpeg;svn:needs-lock=* +*.jpg = svn:mime-type=image/jpeg;svn:needs-lock=* +*.png = svn:mime-type=image/png;svn:needs-lock=* +*.tif = svn:mime-type=image/tiff;svn:needs-lock=* +*.tiff = svn:mime-type=image/tiff;svn:needs-lock=* + +*.doc = svn:mime-type=application/msword;svn:needs-lock=* +*.jar = svn:mime-type=application/octet-stream;svn:needs-lock=* +*.odc = svn:mime-type=application/vnd.oasis.opendocument.chart;svn:needs-lock=* +*.odf = svn:mime-type=application/vnd.oasis.opendocument.formula;svn:needs-lock=* +*.odg = svn:mime-type=application/vnd.oasis.opendocument.graphics;svn:needs-lock=* +*.odi = svn:mime-type=application/vnd.oasis.opendocument.image;svn:needs-lock=* +*.odp = svn:mime-type=application/vnd.oasis.opendocument.presentation;svn:needs-lock=* +*.ods = svn:mime-type=application/vnd.oasis.opendocument.spreadsheet;svn:needs-lock=* +*.odt = svn:mime-type=application/vnd.oasis.opendocument.text;svn:needs-lock=* +*.pdf = svn:mime-type=application/pdf;svn:needs-lock=* +*.ppt = svn:mime-type=application/vnd.ms-powerpoint;svn:needs-lock=* +*.ser = svn:mime-type=application/octet-stream;svn:needs-lock=* +*.swf = svn:mime-type=application/x-shockwave-flash;svn:needs-lock=* +*.vsd = svn:mime-type=application/x-visio;svn:needs-lock=* +*.xls = svn:mime-type=application/vnd.ms-excel;svn:needs-lock=* +*.zip = svn:mime-type=application/zip;svn:needs-lock=* + diff --git a/xstream/pom.xml b/xstream/pom.xml new file mode 100644 index 0000000..779df61 --- /dev/null +++ b/xstream/pom.xml @@ -0,0 +1,432 @@ + + + 4.0.0 + + com.thoughtworks.xstream + xstream-parent + 1.4.8 + + xstream + jar + XStream Core + + + + dom4j + dom4j + true + + + + org.jdom + jdom + true + + + org.jdom + jdom2 + true + + + + joda-time + joda-time + true + + + + stax + stax + true + + + + org.codehaus.woodstox + wstx-asl + true + + + + stax + stax-api + true + + + + xom + xom + true + + + + xmlpull + xmlpull + + + + net.sf.kxml + kxml2-min + true + + + + net.sf.kxml + kxml2 + true + + + + xpp3 + xpp3_min + + + + cglib + cglib-nodep + true + + + + org.codehaus.jettison + jettison + true + + + + + junit + junit + + + + jmock + jmock + + + + org.json + json + test + + + + com.megginson.sax + xml-writer + test + + + + oro + oro + test + + + + commons-lang + commons-lang + test + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + complete-test-classpath + process-test-resources + + copy + + + target/lib + + + proxytoys + proxytoys + 0.2.1 + + + + + + collect-dependencies + package + + copy-dependencies + + + target/dependencies + runtime + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + **/AbstractAcceptanceTest.* + + + + ${project.name} Test + ${project.name} Test + + + + + + + + + + + + jdk18ge + + [1.8,) + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + -XDignore.symbol.file + + + **/Lambda** + + + **/Lambda** + + + + + compile-jdk18 + + 1.8 + 1.8 + + foo + + + foo + + + + compile + testCompile + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + com.thoughtworks.xstream.core.util + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${version.plugin.maven.javadoc} + + com.thoughtworks.xstream.core.util + ${javadoc.xdoclint} + false + ${version.java.source} + + ${link.javadoc.javase} + + + + + + + + jdk17 + + 1.7 + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + -XDignore.symbol.file + + + **/Lambda** + + + **/Lambda** + + + + + + + + jdk15-16 + + [1.5,1.7) + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + -XDignore.symbol.file + + + **/Lambda** + + + **/Lambda** + **/extended/*17Test* + + + + + + + + jdk15-ge + + [1.5,) + + + + + org.apache.maven.plugins + maven-jar-plugin + + + default-jar + + jar + + + + ${project.build.directory}/OSGi/MANIFEST.MF + + + + + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.felix + maven-bundle-plugin + + + !com.thoughtworks.xstream.core.util,com.thoughtworks.xstream.*;-noimport:=true + + + + + + + + jdk14 + + 1.4 + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + **/Lambda** + **/annotations/* + **/AnnotationMapper* + **/EnumMapper* + **/enums/* + **/basic/StringBuilder* + **/basic/UUID* + **/core/util/Types* + **/extended/*15* + **/io/xml/JDom2* + + + **/Lambda** + **/annotations/* + **/enums/* + **/extended/*17Test* + **/reflection/SunLimitedUnsafeReflectionProviderTest* + **/reflection/PureJavaReflectionProvider15Test* + **/io/xml/JDom2*Test* + **/acceptance/Basic15TypesTest* + **/acceptance/Concurrent15TypesTest* + + + + + + + + xml-apis + xml-apis + + + xerces + xercesImpl + + + + 1.0.1 + + + + + + + + org.apache.maven.plugins + maven-surefire-report-plugin + ${version.plugin.maven.surefire} + + + org.codehaus.mojo + cobertura-maven-plugin + ${version.plugin.mojo.cobertura} + + + + + diff --git a/xstream/src/java/com/thoughtworks/xstream/InitializationException.java b/xstream/src/java/com/thoughtworks/xstream/InitializationException.java new file mode 100644 index 0000000..ffb5c7a --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/InitializationException.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. October 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream; + +/** + * Exception thrown configuring an XStream instance. + * + * @author Joe Walnes + * @author Jörg Schaible + * @since 1.3 + */ +public class InitializationException extends XStream.InitializationException { + public InitializationException(String message, Throwable cause) { + super(message, cause); + } + + public InitializationException(String message) { + super(message); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/MarshallingStrategy.java b/xstream/src/java/com/thoughtworks/xstream/MarshallingStrategy.java new file mode 100644 index 0000000..d8165d2 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/MarshallingStrategy.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2004, 2006 Joe Walnes. + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 16. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream; + +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.converters.DataHolder; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + +public interface MarshallingStrategy { + + Object unmarshal(Object root, HierarchicalStreamReader reader, DataHolder dataHolder, ConverterLookup converterLookup, Mapper mapper); + void marshal(HierarchicalStreamWriter writer, Object obj, ConverterLookup converterLookup, Mapper mapper, DataHolder dataHolder); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/XStream.java b/xstream/src/java/com/thoughtworks/xstream/XStream.java new file mode 100644 index 0000000..40f83d2 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/XStream.java @@ -0,0 +1,2207 @@ +/* + * Copyright (C) 2003, 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.xstream; + +import java.io.EOFException; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.NotActiveException; +import java.io.ObjectInputStream; +import java.io.ObjectInputValidation; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.Vector; +import java.util.regex.Pattern; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.converters.ConverterRegistry; +import com.thoughtworks.xstream.converters.DataHolder; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.SingleValueConverterWrapper; +import com.thoughtworks.xstream.converters.basic.BigDecimalConverter; +import com.thoughtworks.xstream.converters.basic.BigIntegerConverter; +import com.thoughtworks.xstream.converters.basic.BooleanConverter; +import com.thoughtworks.xstream.converters.basic.ByteConverter; +import com.thoughtworks.xstream.converters.basic.CharConverter; +import com.thoughtworks.xstream.converters.basic.DateConverter; +import com.thoughtworks.xstream.converters.basic.DoubleConverter; +import com.thoughtworks.xstream.converters.basic.FloatConverter; +import com.thoughtworks.xstream.converters.basic.IntConverter; +import com.thoughtworks.xstream.converters.basic.LongConverter; +import com.thoughtworks.xstream.converters.basic.NullConverter; +import com.thoughtworks.xstream.converters.basic.ShortConverter; +import com.thoughtworks.xstream.converters.basic.StringBufferConverter; +import com.thoughtworks.xstream.converters.basic.StringConverter; +import com.thoughtworks.xstream.converters.basic.URIConverter; +import com.thoughtworks.xstream.converters.basic.URLConverter; +import com.thoughtworks.xstream.converters.collections.ArrayConverter; +import com.thoughtworks.xstream.converters.collections.BitSetConverter; +import com.thoughtworks.xstream.converters.collections.CharArrayConverter; +import com.thoughtworks.xstream.converters.collections.CollectionConverter; +import com.thoughtworks.xstream.converters.collections.MapConverter; +import com.thoughtworks.xstream.converters.collections.PropertiesConverter; +import com.thoughtworks.xstream.converters.collections.SingletonCollectionConverter; +import com.thoughtworks.xstream.converters.collections.SingletonMapConverter; +import com.thoughtworks.xstream.converters.collections.TreeMapConverter; +import com.thoughtworks.xstream.converters.collections.TreeSetConverter; +import com.thoughtworks.xstream.converters.extended.ColorConverter; +import com.thoughtworks.xstream.converters.extended.DynamicProxyConverter; +import com.thoughtworks.xstream.converters.extended.EncodedByteArrayConverter; +import com.thoughtworks.xstream.converters.extended.FileConverter; +import com.thoughtworks.xstream.converters.extended.FontConverter; +import com.thoughtworks.xstream.converters.extended.GregorianCalendarConverter; +import com.thoughtworks.xstream.converters.extended.JavaClassConverter; +import com.thoughtworks.xstream.converters.extended.JavaFieldConverter; +import com.thoughtworks.xstream.converters.extended.JavaMethodConverter; +import com.thoughtworks.xstream.converters.extended.LocaleConverter; +import com.thoughtworks.xstream.converters.extended.LookAndFeelConverter; +import com.thoughtworks.xstream.converters.extended.SqlDateConverter; +import com.thoughtworks.xstream.converters.extended.SqlTimeConverter; +import com.thoughtworks.xstream.converters.extended.SqlTimestampConverter; +import com.thoughtworks.xstream.converters.extended.TextAttributeConverter; +import com.thoughtworks.xstream.converters.reflection.ExternalizableConverter; +import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; +import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; +import com.thoughtworks.xstream.converters.reflection.SerializableConverter; +import com.thoughtworks.xstream.core.ClassLoaderReference; +import com.thoughtworks.xstream.core.DefaultConverterLookup; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.core.MapBackedDataHolder; +import com.thoughtworks.xstream.core.ReferenceByIdMarshallingStrategy; +import com.thoughtworks.xstream.core.ReferenceByXPathMarshallingStrategy; +import com.thoughtworks.xstream.core.TreeMarshallingStrategy; +import com.thoughtworks.xstream.core.util.CompositeClassLoader; +import com.thoughtworks.xstream.core.util.CustomObjectInputStream; +import com.thoughtworks.xstream.core.util.CustomObjectOutputStream; +import com.thoughtworks.xstream.core.util.SelfStreamingInstanceChecker; +import com.thoughtworks.xstream.io.HierarchicalStreamDriver; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.StatefulWriter; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.mapper.AnnotationConfiguration; +import com.thoughtworks.xstream.mapper.ArrayMapper; +import com.thoughtworks.xstream.mapper.AttributeAliasingMapper; +import com.thoughtworks.xstream.mapper.AttributeMapper; +import com.thoughtworks.xstream.mapper.CachingMapper; +import com.thoughtworks.xstream.mapper.ClassAliasingMapper; +import com.thoughtworks.xstream.mapper.DefaultImplementationsMapper; +import com.thoughtworks.xstream.mapper.DefaultMapper; +import com.thoughtworks.xstream.mapper.DynamicProxyMapper; +import com.thoughtworks.xstream.mapper.FieldAliasingMapper; +import com.thoughtworks.xstream.mapper.ImmutableTypesMapper; +import com.thoughtworks.xstream.mapper.ImplicitCollectionMapper; +import com.thoughtworks.xstream.mapper.LocalConversionMapper; +import com.thoughtworks.xstream.mapper.Mapper; +import com.thoughtworks.xstream.mapper.MapperWrapper; +import com.thoughtworks.xstream.mapper.OuterClassMapper; +import com.thoughtworks.xstream.mapper.PackageAliasingMapper; +import com.thoughtworks.xstream.mapper.SecurityMapper; +import com.thoughtworks.xstream.mapper.SystemAttributeAliasingMapper; +import com.thoughtworks.xstream.mapper.XStream11XmlFriendlyMapper; +import com.thoughtworks.xstream.security.AnyTypePermission; +import com.thoughtworks.xstream.security.ExplicitTypePermission; +import com.thoughtworks.xstream.security.NoPermission; +import com.thoughtworks.xstream.security.NoTypePermission; +import com.thoughtworks.xstream.security.RegExpTypePermission; +import com.thoughtworks.xstream.security.TypeHierarchyPermission; +import com.thoughtworks.xstream.security.TypePermission; +import com.thoughtworks.xstream.security.WildcardTypePermission; + + +/** + * Simple facade to XStream library, a Java-XML serialization tool. + *

+ *


+ * Example
+ * + *
+ * XStream xstream = new XStream();
+ * String xml = xstream.toXML(myObject); // serialize to XML
+ * Object myObject2 = xstream.fromXML(xml); // deserialize from XML
+ * 
+ * + *
+ *
+ * + *

Aliasing classes

+ * + *

+ * To create shorter XML, you can specify aliases for classes using the alias() + * method. For example, you can shorten all occurrences of element + * <com.blah.MyThing> to <my-thing> by registering an + * alias for the class. + *

+ *


+ *
+ * + *
+ * xstream.alias("my-thing", MyThing.class);
+ * 
+ * + *
+ *
+ * + *

Converters

+ * + *

+ * XStream contains a map of {@link com.thoughtworks.xstream.converters.Converter} instances, each + * of which acts as a strategy for converting a particular type of class to XML and back again. Out + * of the box, XStream contains converters for most basic types (String, Date, int, boolean, etc) + * and collections (Map, List, Set, Properties, etc). For other objects reflection is used to + * serialize each field recursively. + *

+ * + *

+ * Extra converters can be registered using the registerConverter() method. Some + * non-standard converters are supplied in the {@link com.thoughtworks.xstream.converters.extended} + * package and you can create your own by implementing the + * {@link com.thoughtworks.xstream.converters.Converter} interface. + *

+ * + *

+ *


+ * Example
+ * + *
+ * xstream.registerConverter(new SqlTimestampConverter());
+ * xstream.registerConverter(new DynamicProxyConverter());
+ * 
+ * + *
+ *
+ *

+ * The converters can be registered with an explicit priority. By default they are registered with + * XStream.PRIORITY_NORMAL. Converters of same priority will be used in the reverse sequence + * they have been registered. The default converter, i.e. the converter which will be used if + * no other registered converter is suitable, can be registered with priority + * XStream.PRIORITY_VERY_LOW. XStream uses by default the + * {@link com.thoughtworks.xstream.converters.reflection.ReflectionConverter} as the fallback + * converter. + *

+ * + *

+ *


+ * Example
+ * + *
+ * xstream.registerConverter(new CustomDefaultConverter(), XStream.PRIORITY_VERY_LOW);
+ * 
+ * + *
+ *
+ * + *

Object graphs

+ * + *

+ * XStream has support for object graphs; a deserialized object graph will keep references intact, + * including circular references. + *

+ * + *

+ * XStream can signify references in XML using either relative/absolute XPath or IDs. The mode can be changed using + * setMode(): + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
xstream.setMode(XStream.XPATH_RELATIVE_REFERENCES);(Default) Uses XPath relative references to signify duplicate references. This produces XML + * with the least clutter.
xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);Uses XPath absolute references to signify duplicate + * references. This produces XML with the least clutter.
xstream.setMode(XStream.SINGLE_NODE_XPATH_RELATIVE_REFERENCES);Uses XPath relative references to signify duplicate references. The XPath expression ensures that + * a single node only is selected always.
xstream.setMode(XStream.SINGLE_NODE_XPATH_ABSOLUTE_REFERENCES);Uses XPath absolute references to signify duplicate references. The XPath expression ensures that + * a single node only is selected always.
xstream.setMode(XStream.ID_REFERENCES);Uses ID references to signify duplicate references. In some scenarios, such as when using + * hand-written XML, this is easier to work with.
xstream.setMode(XStream.NO_REFERENCES);This disables object graph support and treats the object structure like a tree. Duplicate + * references are treated as two separate objects and circular references cause an exception. This + * is slightly faster and uses less memory than the other two modes.
+ *

Thread safety

+ *

+ * The XStream instance is thread-safe. That is, once the XStream instance has been created and + * configured, it may be shared across multiple threads allowing objects to be + * serialized/deserialized concurrently. Note, that this only applies if annotations are not + * auto-detected on-the-fly. + *

+ *

Implicit collections

+ * + *

+ * To avoid the need for special tags for collections, you can define implicit collections using one + * of the addImplicitCollection methods. + *

+ * + * @author Joe Walnes + * @author Jörg Schaible + * @author Mauro Talevi + * @author Guilherme Silveira + */ +public class XStream { + + // CAUTION: The sequence of the fields is intentional for an optimal XML output of a + // self-serialization! + private ReflectionProvider reflectionProvider; + private HierarchicalStreamDriver hierarchicalStreamDriver; + private ClassLoaderReference classLoaderReference; + private MarshallingStrategy marshallingStrategy; + private ConverterLookup converterLookup; + private ConverterRegistry converterRegistry; + private Mapper mapper; + + private PackageAliasingMapper packageAliasingMapper; + private ClassAliasingMapper classAliasingMapper; + private FieldAliasingMapper fieldAliasingMapper; + private AttributeAliasingMapper attributeAliasingMapper; + private SystemAttributeAliasingMapper systemAttributeAliasingMapper; + private AttributeMapper attributeMapper; + private DefaultImplementationsMapper defaultImplementationsMapper; + private ImmutableTypesMapper immutableTypesMapper; + private ImplicitCollectionMapper implicitCollectionMapper; + private LocalConversionMapper localConversionMapper; + private SecurityMapper securityMapper; + private AnnotationConfiguration annotationConfiguration; + + public static final int NO_REFERENCES = 1001; + public static final int ID_REFERENCES = 1002; + public static final int XPATH_RELATIVE_REFERENCES = 1003; + public static final int XPATH_ABSOLUTE_REFERENCES = 1004; + public static final int SINGLE_NODE_XPATH_RELATIVE_REFERENCES = 1005; + public static final int SINGLE_NODE_XPATH_ABSOLUTE_REFERENCES = 1006; + + public static final int PRIORITY_VERY_HIGH = 10000; + public static final int PRIORITY_NORMAL = 0; + public static final int PRIORITY_LOW = -10; + public static final int PRIORITY_VERY_LOW = -20; + + private static final String ANNOTATION_MAPPER_TYPE = "com.thoughtworks.xstream.mapper.AnnotationMapper"; + private static final Pattern IGNORE_ALL = Pattern.compile(".*"); + + /** + * Constructs a default XStream. + *

+ * The instance will use the {@link XppDriver} as default and tries to determine the best + * match for the {@link ReflectionProvider} on its own. + *

+ * + * @throws InitializationException in case of an initialization problem + */ + public XStream() { + this(null, (Mapper)null, new XppDriver()); + } + + /** + * Constructs an XStream with a special {@link ReflectionProvider}. + *

+ * The instance will use the {@link XppDriver} as default. + *

+ * + * @param reflectionProvider the reflection provider to use or null for best + * matching reflection provider + * @throws InitializationException in case of an initialization problem + */ + public XStream(ReflectionProvider reflectionProvider) { + this(reflectionProvider, (Mapper)null, new XppDriver()); + } + + /** + * Constructs an XStream with a special {@link HierarchicalStreamDriver}. + *

+ * The instance will tries to determine the best match for the {@link ReflectionProvider} on + * its own. + *

+ * + * @param hierarchicalStreamDriver the driver instance + * @throws InitializationException in case of an initialization problem + */ + public XStream(HierarchicalStreamDriver hierarchicalStreamDriver) { + this(null, (Mapper)null, hierarchicalStreamDriver); + } + + /** + * Constructs an XStream with a special {@link HierarchicalStreamDriver} and + * {@link ReflectionProvider}. + * + * @param reflectionProvider the reflection provider to use or null for best + * matching Provider + * @param hierarchicalStreamDriver the driver instance + * @throws InitializationException in case of an initialization problem + */ + public XStream( + ReflectionProvider reflectionProvider, HierarchicalStreamDriver hierarchicalStreamDriver) { + this(reflectionProvider, (Mapper)null, hierarchicalStreamDriver); + } + + /** + * Constructs an XStream with a special {@link HierarchicalStreamDriver}, + * {@link ReflectionProvider} and a prepared {@link Mapper} chain. + * + * @param reflectionProvider the reflection provider to use or null for best + * matching Provider + * @param mapper the instance with the {@link Mapper} chain or null for the default + * chain + * @param driver the driver instance + * @throws InitializationException in case of an initialization problem + * @deprecated As of 1.3, use + * {@link #XStream(ReflectionProvider, HierarchicalStreamDriver, ClassLoader, Mapper)} + * instead + */ + public XStream( + ReflectionProvider reflectionProvider, Mapper mapper, HierarchicalStreamDriver driver) { + this(reflectionProvider, driver, new CompositeClassLoader(), mapper); + } + + /** + * Constructs an XStream with a special {@link HierarchicalStreamDriver}, + * {@link ReflectionProvider} and a {@link ClassLoaderReference}. + * + * @param reflectionProvider the reflection provider to use or null for best + * matching Provider + * @param driver the driver instance + * @param classLoaderReference the reference to the {@link ClassLoader} to use + * @throws InitializationException in case of an initialization problem + * @since 1.4.5 + */ + public XStream( + ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver, + ClassLoaderReference classLoaderReference) { + this(reflectionProvider, driver, classLoaderReference, null); + } + + /** + * Constructs an XStream with a special {@link HierarchicalStreamDriver}, + * {@link ReflectionProvider} and the {@link ClassLoader} to use. + * + * @throws InitializationException in case of an initialization problem + * @since 1.3 + * @deprecated As of 1.4.5 use + * {@link #XStream(ReflectionProvider, HierarchicalStreamDriver, ClassLoaderReference)} + */ + public XStream( + ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver, + ClassLoader classLoader) { + this(reflectionProvider, driver, classLoader, null); + } + + /** + * Constructs an XStream with a special {@link HierarchicalStreamDriver}, + * {@link ReflectionProvider}, a prepared {@link Mapper} chain and the {@link ClassLoader} + * to use. + * + * @param reflectionProvider the reflection provider to use or null for best + * matching Provider + * @param driver the driver instance + * @param classLoader the {@link ClassLoader} to use + * @param mapper the instance with the {@link Mapper} chain or null for the default + * chain + * @throws InitializationException in case of an initialization problem + * @since 1.3 + * @deprecated As of 1.4.5 use + * {@link #XStream(ReflectionProvider, HierarchicalStreamDriver, ClassLoaderReference, Mapper)} + */ + public XStream( + ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver, + ClassLoader classLoader, Mapper mapper) { + this( + reflectionProvider, driver, new ClassLoaderReference(classLoader), mapper, new DefaultConverterLookup()); + } + + /** + * Constructs an XStream with a special {@link HierarchicalStreamDriver}, + * {@link ReflectionProvider}, a prepared {@link Mapper} chain and the + * {@link ClassLoaderReference}. + *

+ * The {@link ClassLoaderReference} should also be used for the {@link Mapper} chain. + *

+ * + * @param reflectionProvider the reflection provider to use or null for best + * matching Provider + * @param driver the driver instance + * @param classLoaderReference the reference to the {@link ClassLoader} to use + * @param mapper the instance with the {@link Mapper} chain or null for the default + * chain + * @throws InitializationException in case of an initialization problem + * @since 1.4.5 + */ + public XStream( + ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver, + ClassLoaderReference classLoaderReference, Mapper mapper) { + this( + reflectionProvider, driver, classLoaderReference, mapper, new DefaultConverterLookup()); + } + + private XStream( + ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver, ClassLoaderReference classLoader, + Mapper mapper, final DefaultConverterLookup defaultConverterLookup) { + this(reflectionProvider, driver, classLoader, mapper, new ConverterLookup() { + public Converter lookupConverterForType(Class type) { + return defaultConverterLookup.lookupConverterForType(type); + } + }, new ConverterRegistry() { + public void registerConverter(Converter converter, int priority) { + defaultConverterLookup.registerConverter(converter, priority); + } + }); + } + + /** + * Constructs an XStream with a special {@link HierarchicalStreamDriver}, + * {@link ReflectionProvider}, a prepared {@link Mapper} chain, the + * {@link ClassLoaderReference} and an own {@link ConverterLookup} and + * {@link ConverterRegistry}. + * + * @param reflectionProvider the reflection provider to use or null for best + * matching Provider + * @param driver the driver instance + * @param classLoader the {@link ClassLoader} to use + * @param mapper the instance with the {@link Mapper} chain or null for the default + * chain + * @param converterLookup the instance that is used to lookup the converters + * @param converterRegistry an instance to manage the converter instances + * @throws InitializationException in case of an initialization problem + * @since 1.3 + * @deprecated As of 1.4.5 use + * {@link #XStream(ReflectionProvider, HierarchicalStreamDriver, ClassLoaderReference, Mapper, ConverterLookup, ConverterRegistry)} + */ + public XStream( + ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver, + ClassLoader classLoader, Mapper mapper, ConverterLookup converterLookup, + ConverterRegistry converterRegistry) { + this(reflectionProvider, driver, new ClassLoaderReference(classLoader), mapper, converterLookup, converterRegistry); + } + + /** + * Constructs an XStream with a special {@link HierarchicalStreamDriver}, + * {@link ReflectionProvider}, a prepared {@link Mapper} chain, the + * {@link ClassLoaderReference} and an own {@link ConverterLookup} and + * {@link ConverterRegistry}. + *

+ * The ClassLoaderReference should also be used for the Mapper chain. The ConverterLookup + * should access the ConverterRegistry if you intent to register {@link Converter} instances + * with XStream facade or you are using annotations. + *

+ * + * @param reflectionProvider the reflection provider to use or null for best + * matching Provider + * @param driver the driver instance + * @param classLoaderReference the reference to the {@link ClassLoader} to use + * @param mapper the instance with the {@link Mapper} chain or null for the default + * chain + * @param converterLookup the instance that is used to lookup the converters + * @param converterRegistry an instance to manage the converter instances or null + * to prevent any further registry (including annotations) + * @throws InitializationException in case of an initialization problem + * @since 1.4.5 + */ + public XStream( + ReflectionProvider reflectionProvider, HierarchicalStreamDriver driver, + ClassLoaderReference classLoaderReference, Mapper mapper, ConverterLookup converterLookup, + ConverterRegistry converterRegistry) { + if (reflectionProvider == null) { + reflectionProvider = JVM.newReflectionProvider(); + } + this.reflectionProvider = reflectionProvider; + this.hierarchicalStreamDriver = driver; + this.classLoaderReference = classLoaderReference; + this.converterLookup = converterLookup; + this.converterRegistry = converterRegistry; + this.mapper = mapper == null ? buildMapper() : mapper; + + setupMappers(); + setupSecurity(); + setupAliases(); + setupDefaultImplementations(); + setupConverters(); + setupImmutableTypes(); + setMode(XPATH_RELATIVE_REFERENCES); + } + + private Mapper buildMapper() { + Mapper mapper = new DefaultMapper(classLoaderReference); + if (useXStream11XmlFriendlyMapper()) { + mapper = new XStream11XmlFriendlyMapper(mapper); + } + mapper = new DynamicProxyMapper(mapper); + mapper = new PackageAliasingMapper(mapper); + mapper = new ClassAliasingMapper(mapper); + mapper = new FieldAliasingMapper(mapper); + mapper = new AttributeAliasingMapper(mapper); + mapper = new SystemAttributeAliasingMapper(mapper); + mapper = new ImplicitCollectionMapper(mapper); + mapper = new OuterClassMapper(mapper); + mapper = new ArrayMapper(mapper); + mapper = new DefaultImplementationsMapper(mapper); + mapper = new AttributeMapper(mapper, converterLookup, reflectionProvider); + if (JVM.is15()) { + mapper = buildMapperDynamically( + "com.thoughtworks.xstream.mapper.EnumMapper", new Class[]{Mapper.class}, + new Object[]{mapper}); + } + mapper = new LocalConversionMapper(mapper); + mapper = new ImmutableTypesMapper(mapper); + if (JVM.is18()) { + mapper = buildMapperDynamically("com.thoughtworks.xstream.mapper.LambdaMapper", new Class[]{Mapper.class}, + new Object[]{mapper}); + } + mapper = new SecurityMapper(mapper); + if (JVM.is15()) { + mapper = buildMapperDynamically(ANNOTATION_MAPPER_TYPE, new Class[]{ + Mapper.class, ConverterRegistry.class, ConverterLookup.class, + ClassLoaderReference.class, ReflectionProvider.class}, new Object[]{ + mapper, converterRegistry, converterLookup, classLoaderReference, + reflectionProvider}); + } + mapper = wrapMapper((MapperWrapper)mapper); + mapper = new CachingMapper(mapper); + return mapper; + } + + private Mapper buildMapperDynamically(String className, Class[] constructorParamTypes, + Object[] constructorParamValues) { + try { + Class type = Class.forName(className, false, classLoaderReference.getReference()); + Constructor constructor = type.getConstructor(constructorParamTypes); + return (Mapper)constructor.newInstance(constructorParamValues); + } catch (Exception e) { + throw new com.thoughtworks.xstream.InitializationException( + "Could not instantiate mapper : " + className, e); + } catch (LinkageError e) { + throw new com.thoughtworks.xstream.InitializationException( + "Could not instantiate mapper : " + className, e); + } + } + + protected MapperWrapper wrapMapper(MapperWrapper next) { + return next; + } + + /** + * @deprecated As of 1.4.8 + */ + protected boolean useXStream11XmlFriendlyMapper() { + return false; + } + + private void setupMappers() { + packageAliasingMapper = (PackageAliasingMapper)this.mapper + .lookupMapperOfType(PackageAliasingMapper.class); + classAliasingMapper = (ClassAliasingMapper)this.mapper + .lookupMapperOfType(ClassAliasingMapper.class); + fieldAliasingMapper = (FieldAliasingMapper)this.mapper + .lookupMapperOfType(FieldAliasingMapper.class); + attributeMapper = (AttributeMapper)this.mapper + .lookupMapperOfType(AttributeMapper.class); + attributeAliasingMapper = (AttributeAliasingMapper)this.mapper + .lookupMapperOfType(AttributeAliasingMapper.class); + systemAttributeAliasingMapper = (SystemAttributeAliasingMapper)this.mapper + .lookupMapperOfType(SystemAttributeAliasingMapper.class); + implicitCollectionMapper = (ImplicitCollectionMapper)this.mapper + .lookupMapperOfType(ImplicitCollectionMapper.class); + defaultImplementationsMapper = (DefaultImplementationsMapper)this.mapper + .lookupMapperOfType(DefaultImplementationsMapper.class); + immutableTypesMapper = (ImmutableTypesMapper)this.mapper + .lookupMapperOfType(ImmutableTypesMapper.class); + localConversionMapper = (LocalConversionMapper)this.mapper + .lookupMapperOfType(LocalConversionMapper.class); + securityMapper = (SecurityMapper)this.mapper + .lookupMapperOfType(SecurityMapper.class); + annotationConfiguration = (AnnotationConfiguration)this.mapper + .lookupMapperOfType(AnnotationConfiguration.class); + } + + protected void setupSecurity() { + if (securityMapper == null) { + return; + } + + addPermission(AnyTypePermission.ANY); + } + + protected void setupAliases() { + if (classAliasingMapper == null) { + return; + } + + alias("null", Mapper.Null.class); + alias("int", Integer.class); + alias("float", Float.class); + alias("double", Double.class); + alias("long", Long.class); + alias("short", Short.class); + alias("char", Character.class); + alias("byte", Byte.class); + alias("boolean", Boolean.class); + alias("number", Number.class); + alias("object", Object.class); + alias("big-int", BigInteger.class); + alias("big-decimal", BigDecimal.class); + + alias("string-buffer", StringBuffer.class); + alias("string", String.class); + alias("java-class", Class.class); + alias("method", Method.class); + alias("constructor", Constructor.class); + alias("field", Field.class); + alias("date", Date.class); + alias("uri", URI.class); + alias("url", URL.class); + alias("bit-set", BitSet.class); + + alias("map", Map.class); + alias("entry", Map.Entry.class); + alias("properties", Properties.class); + alias("list", List.class); + alias("set", Set.class); + alias("sorted-set", SortedSet.class); + + alias("linked-list", LinkedList.class); + alias("vector", Vector.class); + alias("tree-map", TreeMap.class); + alias("tree-set", TreeSet.class); + alias("hashtable", Hashtable.class); + + alias("empty-list", Collections.EMPTY_LIST.getClass()); + alias("empty-map", Collections.EMPTY_MAP.getClass()); + alias("empty-set", Collections.EMPTY_SET.getClass()); + alias("singleton-list", Collections.singletonList(this).getClass()); + alias("singleton-map", Collections.singletonMap(this, null).getClass()); + alias("singleton-set", Collections.singleton(this).getClass()); + + if (JVM.isAWTAvailable()) { + // Instantiating these two classes starts the AWT system, which is undesirable. + // Calling loadClass ensures a reference to the class is found but they are not + // instantiated. + alias("awt-color", JVM.loadClassForName("java.awt.Color", false)); + alias("awt-font", JVM.loadClassForName("java.awt.Font", false)); + alias("awt-text-attribute", JVM.loadClassForName("java.awt.font.TextAttribute")); + } + + if (JVM.isSQLAvailable()) { + alias("sql-timestamp", JVM.loadClassForName("java.sql.Timestamp")); + alias("sql-time", JVM.loadClassForName("java.sql.Time")); + alias("sql-date", JVM.loadClassForName("java.sql.Date")); + } + + alias("file", File.class); + alias("locale", Locale.class); + alias("gregorian-calendar", Calendar.class); + + if (JVM.is14()) { + aliasDynamically("auth-subject", "javax.security.auth.Subject"); + alias("linked-hash-map", JVM.loadClassForName("java.util.LinkedHashMap")); + alias("linked-hash-set", JVM.loadClassForName("java.util.LinkedHashSet")); + alias("trace", JVM.loadClassForName("java.lang.StackTraceElement")); + alias("currency", JVM.loadClassForName("java.util.Currency")); + aliasType("charset", JVM.loadClassForName("java.nio.charset.Charset")); + } + + if (JVM.is15()) { + aliasDynamically("duration", "javax.xml.datatype.Duration"); + alias("concurrent-hash-map", JVM.loadClassForName("java.util.concurrent.ConcurrentHashMap")); + alias("enum-set", JVM.loadClassForName("java.util.EnumSet")); + alias("enum-map", JVM.loadClassForName("java.util.EnumMap")); + alias("string-builder", JVM.loadClassForName("java.lang.StringBuilder")); + alias("uuid", JVM.loadClassForName("java.util.UUID")); + } + if (JVM.loadClassForName("java.lang.invoke.SerializedLambda") != null) { + aliasDynamically("serialized-lambda", "java.lang.invoke.SerializedLambda"); + } + } + + private void aliasDynamically(String alias, String className) { + Class type = JVM.loadClassForName(className); + if (type != null) { + alias(alias, type); + } + } + + protected void setupDefaultImplementations() { + if (defaultImplementationsMapper == null) { + return; + } + addDefaultImplementation(HashMap.class, Map.class); + addDefaultImplementation(ArrayList.class, List.class); + addDefaultImplementation(HashSet.class, Set.class); + addDefaultImplementation(TreeSet.class, SortedSet.class); + addDefaultImplementation(GregorianCalendar.class, Calendar.class); + } + + protected void setupConverters() { + registerConverter( + new ReflectionConverter(mapper, reflectionProvider), PRIORITY_VERY_LOW); + + registerConverter( + new SerializableConverter(mapper, reflectionProvider, classLoaderReference), PRIORITY_LOW); + registerConverter(new ExternalizableConverter(mapper, classLoaderReference), PRIORITY_LOW); + + registerConverter(new NullConverter(), PRIORITY_VERY_HIGH); + registerConverter(new IntConverter(), PRIORITY_NORMAL); + registerConverter(new FloatConverter(), PRIORITY_NORMAL); + registerConverter(new DoubleConverter(), PRIORITY_NORMAL); + registerConverter(new LongConverter(), PRIORITY_NORMAL); + registerConverter(new ShortConverter(), PRIORITY_NORMAL); + registerConverter((Converter)new CharConverter(), PRIORITY_NORMAL); + registerConverter(new BooleanConverter(), PRIORITY_NORMAL); + registerConverter(new ByteConverter(), PRIORITY_NORMAL); + + registerConverter(new StringConverter(), PRIORITY_NORMAL); + registerConverter(new StringBufferConverter(), PRIORITY_NORMAL); + registerConverter(new DateConverter(), PRIORITY_NORMAL); + registerConverter(new BitSetConverter(), PRIORITY_NORMAL); + registerConverter(new URIConverter(), PRIORITY_NORMAL); + registerConverter(new URLConverter(), PRIORITY_NORMAL); + registerConverter(new BigIntegerConverter(), PRIORITY_NORMAL); + registerConverter(new BigDecimalConverter(), PRIORITY_NORMAL); + + registerConverter(new ArrayConverter(mapper), PRIORITY_NORMAL); + registerConverter(new CharArrayConverter(), PRIORITY_NORMAL); + registerConverter(new CollectionConverter(mapper), PRIORITY_NORMAL); + registerConverter(new MapConverter(mapper), PRIORITY_NORMAL); + registerConverter(new TreeMapConverter(mapper), PRIORITY_NORMAL); + registerConverter(new TreeSetConverter(mapper), PRIORITY_NORMAL); + registerConverter(new SingletonCollectionConverter(mapper), PRIORITY_NORMAL); + registerConverter(new SingletonMapConverter(mapper), PRIORITY_NORMAL); + registerConverter(new PropertiesConverter(), PRIORITY_NORMAL); + registerConverter((Converter)new EncodedByteArrayConverter(), PRIORITY_NORMAL); + + registerConverter(new FileConverter(), PRIORITY_NORMAL); + if (JVM.isSQLAvailable()) { + registerConverter(new SqlTimestampConverter(), PRIORITY_NORMAL); + registerConverter(new SqlTimeConverter(), PRIORITY_NORMAL); + registerConverter(new SqlDateConverter(), PRIORITY_NORMAL); + } + registerConverter( + new DynamicProxyConverter(mapper, classLoaderReference), PRIORITY_NORMAL); + registerConverter(new JavaClassConverter(classLoaderReference), PRIORITY_NORMAL); + registerConverter(new JavaMethodConverter(classLoaderReference), PRIORITY_NORMAL); + registerConverter(new JavaFieldConverter(classLoaderReference), PRIORITY_NORMAL); + if (JVM.isAWTAvailable()) { + registerConverter(new FontConverter(mapper), PRIORITY_NORMAL); + registerConverter(new ColorConverter(), PRIORITY_NORMAL); + registerConverter(new TextAttributeConverter(), PRIORITY_NORMAL); + } + if (JVM.isSwingAvailable()) { + registerConverter( + new LookAndFeelConverter(mapper, reflectionProvider), PRIORITY_NORMAL); + } + registerConverter(new LocaleConverter(), PRIORITY_NORMAL); + registerConverter(new GregorianCalendarConverter(), PRIORITY_NORMAL); + + if (JVM.is14()) { + // late bound converters - allows XStream to be compiled on earlier JDKs + registerConverterDynamically( + "com.thoughtworks.xstream.converters.extended.SubjectConverter", + PRIORITY_NORMAL, new Class[]{Mapper.class}, new Object[]{mapper}); + registerConverterDynamically( + "com.thoughtworks.xstream.converters.extended.ThrowableConverter", + PRIORITY_NORMAL, new Class[]{ConverterLookup.class}, + new Object[]{converterLookup}); + registerConverterDynamically( + "com.thoughtworks.xstream.converters.extended.StackTraceElementConverter", + PRIORITY_NORMAL, null, null); + registerConverterDynamically( + "com.thoughtworks.xstream.converters.extended.CurrencyConverter", + PRIORITY_NORMAL, null, null); + registerConverterDynamically( + "com.thoughtworks.xstream.converters.extended.RegexPatternConverter", + PRIORITY_NORMAL, null, null); + registerConverterDynamically( + "com.thoughtworks.xstream.converters.extended.CharsetConverter", + PRIORITY_NORMAL, null, null); + } + + if (JVM.is15()) { + // late bound converters - allows XStream to be compiled on earlier JDKs + if (JVM.loadClassForName("javax.xml.datatype.Duration") != null) { + registerConverterDynamically( + "com.thoughtworks.xstream.converters.extended.DurationConverter", + PRIORITY_NORMAL, null, null); + } + registerConverterDynamically( + "com.thoughtworks.xstream.converters.enums.EnumConverter", PRIORITY_NORMAL, + null, null); + registerConverterDynamically( + "com.thoughtworks.xstream.converters.enums.EnumSetConverter", PRIORITY_NORMAL, + new Class[]{Mapper.class}, new Object[]{mapper}); + registerConverterDynamically( + "com.thoughtworks.xstream.converters.enums.EnumMapConverter", PRIORITY_NORMAL, + new Class[]{Mapper.class}, new Object[]{mapper}); + registerConverterDynamically( + "com.thoughtworks.xstream.converters.basic.StringBuilderConverter", + PRIORITY_NORMAL, null, null); + registerConverterDynamically( + "com.thoughtworks.xstream.converters.basic.UUIDConverter", PRIORITY_NORMAL, + null, null); + } + if (JVM.is18()) { + registerConverterDynamically("com.thoughtworks.xstream.converters.reflection.LambdaConverter", + PRIORITY_NORMAL, new Class[]{Mapper.class, ReflectionProvider.class, ClassLoaderReference.class}, + new Object[]{mapper, reflectionProvider, classLoaderReference}); + } + + registerConverter( + new SelfStreamingInstanceChecker(converterLookup, this), PRIORITY_NORMAL); + } + + private void registerConverterDynamically(String className, int priority, + Class[] constructorParamTypes, Object[] constructorParamValues) { + try { + Class type = Class.forName(className, false, classLoaderReference.getReference()); + Constructor constructor = type.getConstructor(constructorParamTypes); + Object instance = constructor.newInstance(constructorParamValues); + if (instance instanceof Converter) { + registerConverter((Converter)instance, priority); + } else if (instance instanceof SingleValueConverter) { + registerConverter((SingleValueConverter)instance, priority); + } + } catch (Exception e) { + throw new com.thoughtworks.xstream.InitializationException( + "Could not instantiate converter : " + className, e); + } catch (LinkageError e) { + throw new com.thoughtworks.xstream.InitializationException( + "Could not instantiate converter : " + className, e); + } + } + + protected void setupImmutableTypes() { + if (immutableTypesMapper == null) { + return; + } + + // primitives are always immutable + addImmutableType(boolean.class); + addImmutableType(Boolean.class); + addImmutableType(byte.class); + addImmutableType(Byte.class); + addImmutableType(char.class); + addImmutableType(Character.class); + addImmutableType(double.class); + addImmutableType(Double.class); + addImmutableType(float.class); + addImmutableType(Float.class); + addImmutableType(int.class); + addImmutableType(Integer.class); + addImmutableType(long.class); + addImmutableType(Long.class); + addImmutableType(short.class); + addImmutableType(Short.class); + + // additional types + addImmutableType(Mapper.Null.class); + addImmutableType(BigDecimal.class); + addImmutableType(BigInteger.class); + addImmutableType(String.class); + addImmutableType(URI.class); + addImmutableType(URL.class); + addImmutableType(File.class); + addImmutableType(Class.class); + + addImmutableType(Collections.EMPTY_LIST.getClass()); + addImmutableType(Collections.EMPTY_SET.getClass()); + addImmutableType(Collections.EMPTY_MAP.getClass()); + + if (JVM.isAWTAvailable()) { + addImmutableTypeDynamically("java.awt.font.TextAttribute"); + } + + if (JVM.is14()) { + // late bound types - allows XStream to be compiled on earlier JDKs + addImmutableTypeDynamically("java.nio.charset.Charset"); + addImmutableTypeDynamically("java.util.Currency"); + } + } + + private void addImmutableTypeDynamically(String className) { + Class type = JVM.loadClassForName(className); + if (type != null) { + addImmutableType(type); + } + } + + public void setMarshallingStrategy(MarshallingStrategy marshallingStrategy) { + this.marshallingStrategy = marshallingStrategy; + } + + /** + * Serialize an object to a pretty-printed XML String. + * + * @throws XStreamException if the object cannot be serialized + */ + public String toXML(Object obj) { + Writer writer = new StringWriter(); + toXML(obj, writer); + return writer.toString(); + } + + /** + * Serialize an object to the given Writer as pretty-printed XML. The Writer will be flushed + * afterwards and in case of an exception. + * + * @throws XStreamException if the object cannot be serialized + */ + public void toXML(Object obj, Writer out) { + HierarchicalStreamWriter writer = hierarchicalStreamDriver.createWriter(out); + try { + marshal(obj, writer); + } finally { + writer.flush(); + } + } + + /** + * Serialize an object to the given OutputStream as pretty-printed XML. The OutputStream + * will be flushed afterwards and in case of an exception. + * + * @throws XStreamException if the object cannot be serialized + */ + public void toXML(Object obj, OutputStream out) { + HierarchicalStreamWriter writer = hierarchicalStreamDriver.createWriter(out); + try { + marshal(obj, writer); + } finally { + writer.flush(); + } + } + + /** + * Serialize and object to a hierarchical data structure (such as XML). + * + * @throws XStreamException if the object cannot be serialized + */ + public void marshal(Object obj, HierarchicalStreamWriter writer) { + marshal(obj, writer, null); + } + + /** + * Serialize and object to a hierarchical data structure (such as XML). + * + * @param dataHolder Extra data you can use to pass to your converters. Use this as you + * want. If not present, XStream shall create one lazily as needed. + * @throws XStreamException if the object cannot be serialized + */ + public void marshal(Object obj, HierarchicalStreamWriter writer, DataHolder dataHolder) { + marshallingStrategy.marshal(writer, obj, converterLookup, mapper, dataHolder); + } + + /** + * Deserialize an object from an XML String. + * + * @throws XStreamException if the object cannot be deserialized + */ + public Object fromXML(String xml) { + return fromXML(new StringReader(xml)); + } + + /** + * Deserialize an object from an XML Reader. + * + * @throws XStreamException if the object cannot be deserialized + */ + public Object fromXML(Reader reader) { + return unmarshal(hierarchicalStreamDriver.createReader(reader), null); + } + + /** + * Deserialize an object from an XML InputStream. + * + * @throws XStreamException if the object cannot be deserialized + */ + public Object fromXML(InputStream input) { + return unmarshal(hierarchicalStreamDriver.createReader(input), null); + } + + /** + * Deserialize an object from a URL. + * + * Depending on the parser implementation, some might take the file path as SystemId to + * resolve additional references. + * + * @throws XStreamException if the object cannot be deserialized + * @since 1.4 + */ + public Object fromXML(URL url) { + return fromXML(url, null); + } + + /** + * Deserialize an object from a file. + * + * Depending on the parser implementation, some might take the file path as SystemId to + * resolve additional references. + * + * @throws XStreamException if the object cannot be deserialized + * @since 1.4 + */ + public Object fromXML(File file) { + return fromXML(file, null); + } + + /** + * Deserialize an object from an XML String, populating the fields of the given root object + * instead of instantiating a new one. Note, that this is a special use case! With the + * ReflectionConverter XStream will write directly into the raw memory area of the existing + * object. Use with care! + * + * @throws XStreamException if the object cannot be deserialized + */ + public Object fromXML(String xml, Object root) { + return fromXML(new StringReader(xml), root); + } + + /** + * Deserialize an object from an XML Reader, populating the fields of the given root object + * instead of instantiating a new one. Note, that this is a special use case! With the + * ReflectionConverter XStream will write directly into the raw memory area of the existing + * object. Use with care! + * + * @throws XStreamException if the object cannot be deserialized + */ + public Object fromXML(Reader xml, Object root) { + return unmarshal(hierarchicalStreamDriver.createReader(xml), root); + } + + /** + * Deserialize an object from a URL, populating the fields of the given root + * object instead of instantiating a new one. Note, that this is a special use case! With + * the ReflectionConverter XStream will write directly into the raw memory area of the + * existing object. Use with care! + * + * Depending on the parser implementation, some might take the file path as SystemId to + * resolve additional references. + * + * @throws XStreamException if the object cannot be deserialized + * @since 1.4 + */ + public Object fromXML(URL url, Object root) { + return unmarshal(hierarchicalStreamDriver.createReader(url), root); + } + + /** + * Deserialize an object from a file, populating the fields of the given root + * object instead of instantiating a new one. Note, that this is a special use case! With + * the ReflectionConverter XStream will write directly into the raw memory area of the + * existing object. Use with care! + * + * Depending on the parser implementation, some might take the file path as SystemId to + * resolve additional references. + * + * @throws XStreamException if the object cannot be deserialized + * @since 1.4 + */ + public Object fromXML(File file, Object root) { + HierarchicalStreamReader reader = hierarchicalStreamDriver.createReader(file); + try { + return unmarshal(reader, root); + } finally { + reader.close(); + } + } + + /** + * Deserialize an object from an XML InputStream, populating the fields of the given root + * object instead of instantiating a new one. Note, that this is a special use case! With + * the ReflectionConverter XStream will write directly into the raw memory area of the + * existing object. Use with care! + * + * @throws XStreamException if the object cannot be deserialized + */ + public Object fromXML(InputStream input, Object root) { + return unmarshal(hierarchicalStreamDriver.createReader(input), root); + } + + /** + * Deserialize an object from a hierarchical data structure (such as XML). + * + * @throws XStreamException if the object cannot be deserialized + */ + public Object unmarshal(HierarchicalStreamReader reader) { + return unmarshal(reader, null, null); + } + + /** + * Deserialize an object from a hierarchical data structure (such as XML), populating the + * fields of the given root object instead of instantiating a new one. Note, that this is a + * special use case! With the ReflectionConverter XStream will write directly into the raw + * memory area of the existing object. Use with care! + * + * @throws XStreamException if the object cannot be deserialized + */ + public Object unmarshal(HierarchicalStreamReader reader, Object root) { + return unmarshal(reader, root, null); + } + + /** + * Deserialize an object from a hierarchical data structure (such as XML). + * + * @param root If present, the passed in object will have its fields populated, as opposed + * to XStream creating a new instance. Note, that this is a special use case! + * With the ReflectionConverter XStream will write directly into the raw memory + * area of the existing object. Use with care! + * @param dataHolder Extra data you can use to pass to your converters. Use this as you + * want. If not present, XStream shall create one lazily as needed. + * @throws XStreamException if the object cannot be deserialized + */ + public Object unmarshal(HierarchicalStreamReader reader, Object root, DataHolder dataHolder) { + try { + return marshallingStrategy.unmarshal( + root, reader, dataHolder, converterLookup, mapper); + + } catch (ConversionException e) { + Package pkg = getClass().getPackage(); + String version = pkg != null ? pkg.getImplementationVersion() : null; + e.add("version", version != null ? version : "not available"); + throw e; + } + } + + /** + * Alias a Class to a shorter name to be used in XML elements. + * + * @param name Short name + * @param type Type to be aliased + * @throws InitializationException if no {@link ClassAliasingMapper} is available + */ + public void alias(String name, Class type) { + if (classAliasingMapper == null) { + throw new com.thoughtworks.xstream.InitializationException("No " + + ClassAliasingMapper.class.getName() + + " available"); + } + classAliasingMapper.addClassAlias(name, type); + } + + /** + * Alias a type to a shorter name to be used in XML elements. Any class that is assignable + * to this type will be aliased to the same name. + * + * @param name Short name + * @param type Type to be aliased + * @since 1.2 + * @throws InitializationException if no {@link ClassAliasingMapper} is available + */ + public void aliasType(String name, Class type) { + if (classAliasingMapper == null) { + throw new com.thoughtworks.xstream.InitializationException("No " + + ClassAliasingMapper.class.getName() + + " available"); + } + classAliasingMapper.addTypeAlias(name, type); + } + + /** + * Alias a Class to a shorter name to be used in XML elements. + * + * @param name Short name + * @param type Type to be aliased + * @param defaultImplementation Default implementation of type to use if no other specified. + * @throws InitializationException if no {@link DefaultImplementationsMapper} or no + * {@link ClassAliasingMapper} is available + */ + public void alias(String name, Class type, Class defaultImplementation) { + alias(name, type); + addDefaultImplementation(defaultImplementation, type); + } + + /** + * Alias a package to a shorter name to be used in XML elements. + * + * @param name Short name + * @param pkgName package to be aliased + * @throws InitializationException if no {@link DefaultImplementationsMapper} or no + * {@link PackageAliasingMapper} is available + * @since 1.3.1 + */ + public void aliasPackage(String name, String pkgName) { + if (packageAliasingMapper == null) { + throw new com.thoughtworks.xstream.InitializationException("No " + + PackageAliasingMapper.class.getName() + + " available"); + } + packageAliasingMapper.addPackageAlias(name, pkgName); + } + + /** + * Create an alias for a field name. + * + * @param alias the alias itself + * @param definedIn the type that declares the field + * @param fieldName the name of the field + * @throws InitializationException if no {@link FieldAliasingMapper} is available + */ + public void aliasField(String alias, Class definedIn, String fieldName) { + if (fieldAliasingMapper == null) { + throw new com.thoughtworks.xstream.InitializationException("No " + + FieldAliasingMapper.class.getName() + + " available"); + } + fieldAliasingMapper.addFieldAlias(alias, definedIn, fieldName); + } + + /** + * Create an alias for an attribute + * + * @param alias the alias itself + * @param attributeName the name of the attribute + * @throws InitializationException if no {@link AttributeAliasingMapper} is available + */ + public void aliasAttribute(String alias, String attributeName) { + if (attributeAliasingMapper == null) { + throw new com.thoughtworks.xstream.InitializationException("No " + + AttributeAliasingMapper.class.getName() + + " available"); + } + attributeAliasingMapper.addAliasFor(attributeName, alias); + } + + /** + * Create an alias for a system attribute. XStream will not write a system attribute if its + * alias is set to null. However, this is not reversible, i.e. deserialization + * of the result is likely to fail afterwards and will not produce an object equal to the + * originally written one. + * + * @param alias the alias itself (may be null) + * @param systemAttributeName the name of the system attribute + * @throws InitializationException if no {@link SystemAttributeAliasingMapper} is available + * @since 1.3.1 + */ + public void aliasSystemAttribute(String alias, String systemAttributeName) { + if (systemAttributeAliasingMapper == null) { + throw new com.thoughtworks.xstream.InitializationException("No " + + SystemAttributeAliasingMapper.class.getName() + + " available"); + } + systemAttributeAliasingMapper.addAliasFor(systemAttributeName, alias); + } + + /** + * Create an alias for an attribute. + * + * @param definedIn the type where the attribute is defined + * @param attributeName the name of the attribute + * @param alias the alias itself + * @throws InitializationException if no {@link AttributeAliasingMapper} is available + * @since 1.2.2 + */ + public void aliasAttribute(Class definedIn, String attributeName, String alias) { + aliasField(alias, definedIn, attributeName); + useAttributeFor(definedIn, attributeName); + } + + /** + * Use an attribute for a field or a specific type. + * + * @param fieldName the name of the field + * @param type the Class of the type to be rendered as XML attribute + * @throws InitializationException if no {@link AttributeMapper} is available + * @since 1.2 + */ + public void useAttributeFor(String fieldName, Class type) { + if (attributeMapper == null) { + throw new com.thoughtworks.xstream.InitializationException("No " + + AttributeMapper.class.getName() + + " available"); + } + attributeMapper.addAttributeFor(fieldName, type); + } + + /** + * Use an attribute for a field declared in a specific type. + * + * @param fieldName the name of the field + * @param definedIn the Class containing such field + * @throws InitializationException if no {@link AttributeMapper} is available + * @since 1.2.2 + */ + public void useAttributeFor(Class definedIn, String fieldName) { + if (attributeMapper == null) { + throw new com.thoughtworks.xstream.InitializationException("No " + + AttributeMapper.class.getName() + + " available"); + } + attributeMapper.addAttributeFor(definedIn, fieldName); + } + + /** + * Use an attribute for an arbitrary type. + * + * @param type the Class of the type to be rendered as XML attribute + * @throws InitializationException if no {@link AttributeMapper} is available + * @since 1.2 + */ + public void useAttributeFor(Class type) { + if (attributeMapper == null) { + throw new com.thoughtworks.xstream.InitializationException("No " + + AttributeMapper.class.getName() + + " available"); + } + attributeMapper.addAttributeFor(type); + } + + /** + * Associate a default implementation of a class with an object. Whenever XStream encounters + * an instance of this type, it will use the default implementation instead. For example, + * java.util.ArrayList is the default implementation of java.util.List. + * + * @param defaultImplementation + * @param ofType + * @throws InitializationException if no {@link DefaultImplementationsMapper} is available + */ + public void addDefaultImplementation(Class defaultImplementation, Class ofType) { + if (defaultImplementationsMapper == null) { + throw new com.thoughtworks.xstream.InitializationException("No " + + DefaultImplementationsMapper.class.getName() + + " available"); + } + defaultImplementationsMapper.addDefaultImplementation(defaultImplementation, ofType); + } + + /** + * Add immutable types. The value of the instances of these types will always be written + * into the stream even if they appear multiple times. + * + * @throws InitializationException if no {@link ImmutableTypesMapper} is available + */ + public void addImmutableType(Class type) { + if (immutableTypesMapper == null) { + throw new com.thoughtworks.xstream.InitializationException("No " + + ImmutableTypesMapper.class.getName() + + " available"); + } + immutableTypesMapper.addImmutableType(type); + } + + public void registerConverter(Converter converter) { + registerConverter(converter, PRIORITY_NORMAL); + } + + public void registerConverter(Converter converter, int priority) { + if (converterRegistry != null) { + converterRegistry.registerConverter(converter, priority); + } + } + + public void registerConverter(SingleValueConverter converter) { + registerConverter(converter, PRIORITY_NORMAL); + } + + public void registerConverter(SingleValueConverter converter, int priority) { + if (converterRegistry != null) { + converterRegistry.registerConverter( + new SingleValueConverterWrapper(converter), priority); + } + } + + /** + * Register a local {@link Converter} for a field. + * + * @param definedIn the class type the field is defined in + * @param fieldName the field name + * @param converter the converter to use + * @since 1.3 + */ + public void registerLocalConverter(Class definedIn, String fieldName, Converter converter) { + if (localConversionMapper == null) { + throw new com.thoughtworks.xstream.InitializationException("No " + + LocalConversionMapper.class.getName() + + " available"); + } + localConversionMapper.registerLocalConverter(definedIn, fieldName, converter); + } + + /** + * Register a local {@link SingleValueConverter} for a field. + * + * @param definedIn the class type the field is defined in + * @param fieldName the field name + * @param converter the converter to use + * @since 1.3 + */ + public void registerLocalConverter(Class definedIn, String fieldName, + SingleValueConverter converter) { + registerLocalConverter( + definedIn, fieldName, (Converter)new SingleValueConverterWrapper(converter)); + } + + /** + * Retrieve the {@link Mapper}. This is by default a chain of {@link MapperWrapper + * MapperWrappers}. + * + * @return the mapper + * @since 1.2 + */ + public Mapper getMapper() { + return mapper; + } + + /** + * Retrieve the {@link ReflectionProvider} in use. + * + * @return the mapper + * @since 1.2.1 + */ + public ReflectionProvider getReflectionProvider() { + return reflectionProvider; + } + + public ConverterLookup getConverterLookup() { + return converterLookup; + } + + /** + * Change mode for dealing with duplicate references. Valid values are + * XPATH_ABSOLUTE_REFERENCES, XPATH_RELATIVE_REFERENCES, + * XStream.ID_REFERENCES and XStream.NO_REFERENCES. + * + * @throws IllegalArgumentException if the mode is not one of the declared types + * @see #XPATH_ABSOLUTE_REFERENCES + * @see #XPATH_RELATIVE_REFERENCES + * @see #ID_REFERENCES + * @see #NO_REFERENCES + */ + public void setMode(int mode) { + switch (mode) { + case NO_REFERENCES: + setMarshallingStrategy(new TreeMarshallingStrategy()); + break; + case ID_REFERENCES: + setMarshallingStrategy(new ReferenceByIdMarshallingStrategy()); + break; + case XPATH_RELATIVE_REFERENCES: + setMarshallingStrategy(new ReferenceByXPathMarshallingStrategy( + ReferenceByXPathMarshallingStrategy.RELATIVE)); + break; + case XPATH_ABSOLUTE_REFERENCES: + setMarshallingStrategy(new ReferenceByXPathMarshallingStrategy( + ReferenceByXPathMarshallingStrategy.ABSOLUTE)); + break; + case SINGLE_NODE_XPATH_RELATIVE_REFERENCES: + setMarshallingStrategy(new ReferenceByXPathMarshallingStrategy( + ReferenceByXPathMarshallingStrategy.RELATIVE + | ReferenceByXPathMarshallingStrategy.SINGLE_NODE)); + break; + case SINGLE_NODE_XPATH_ABSOLUTE_REFERENCES: + setMarshallingStrategy(new ReferenceByXPathMarshallingStrategy( + ReferenceByXPathMarshallingStrategy.ABSOLUTE + | ReferenceByXPathMarshallingStrategy.SINGLE_NODE)); + break; + default: + throw new IllegalArgumentException("Unknown mode : " + mode); + } + } + + /** + * Adds a default implicit collection which is used for any unmapped XML tag. + * + * @param ownerType class owning the implicit collection + * @param fieldName name of the field in the ownerType. This field must be a concrete + * collection type or matching the default implementation type of the collection + * type. + */ + public void addImplicitCollection(Class ownerType, String fieldName) { + addImplicitCollection(ownerType, fieldName, null, null); + } + + /** + * Adds implicit collection which is used for all items of the given itemType. + * + * @param ownerType class owning the implicit collection + * @param fieldName name of the field in the ownerType. This field must be a concrete + * collection type or matching the default implementation type of the collection + * type. + * @param itemType type of the items to be part of this collection + * @throws InitializationException if no {@link ImplicitCollectionMapper} is available + */ + public void addImplicitCollection(Class ownerType, String fieldName, Class itemType) { + addImplicitCollection(ownerType, fieldName, null, itemType); + } + + /** + * Adds implicit collection which is used for all items of the given element name defined by + * itemFieldName. + * + * @param ownerType class owning the implicit collection + * @param fieldName name of the field in the ownerType. This field must be a concrete + * collection type or matching the default implementation type of the collection + * type. + * @param itemFieldName element name of the implicit collection + * @param itemType item type to be aliases be the itemFieldName + * @throws InitializationException if no {@link ImplicitCollectionMapper} is available + */ + public void addImplicitCollection(Class ownerType, String fieldName, String itemFieldName, + Class itemType) { + addImplicitMap(ownerType, fieldName, itemFieldName, itemType, null); + } + + /** + * Adds an implicit array. + * + * @param ownerType class owning the implicit array + * @param fieldName name of the array field + * @since 1.4 + */ + public void addImplicitArray(Class ownerType, String fieldName) { + addImplicitCollection(ownerType, fieldName); + } + + /** + * Adds an implicit array which is used for all items of the given itemType when the array + * type matches. + * + * @param ownerType class owning the implicit array + * @param fieldName name of the array field in the ownerType + * @param itemType type of the items to be part of this array + * @throws InitializationException if no {@link ImplicitCollectionMapper} is available or the + * array type does not match the itemType + * @since 1.4 + */ + public void addImplicitArray(Class ownerType, String fieldName, Class itemType) { + addImplicitCollection(ownerType, fieldName, itemType); + } + + /** + * Adds an implicit array which is used for all items of the given element name defined by + * itemName. + * + * @param ownerType class owning the implicit array + * @param fieldName name of the array field in the ownerType + * @param itemName alias name of the items + * @throws InitializationException if no {@link ImplicitCollectionMapper} is available + * @since 1.4 + */ + public void addImplicitArray(Class ownerType, String fieldName, String itemName) { + addImplicitCollection(ownerType, fieldName, itemName, null); + } + + /** + * Adds an implicit map. + * + * @param ownerType class owning the implicit map + * @param fieldName name of the field in the ownerType. This field must be a concrete + * map type or matching the default implementation type of the map + * type. + * @param itemType type of the items to be part of this map as value + * @param keyFieldName the name of the field of the itemType that is used for the key in the map + * @since 1.4 + */ + public void addImplicitMap(Class ownerType, String fieldName, Class itemType, String keyFieldName) { + addImplicitMap(ownerType, fieldName, null, itemType, keyFieldName); + } + + /** + * Adds an implicit map. + * + * @param ownerType class owning the implicit map + * @param fieldName name of the field in the ownerType. This field must be a concrete + * map type or matching the default implementation type of the map + * type. + * @param itemName alias name of the items + * @param itemType type of the items to be part of this map as value + * @param keyFieldName the name of the field of the itemType that is used for the key in the map + * @since 1.4 + */ + public void addImplicitMap(Class ownerType, String fieldName, String itemName, + Class itemType, String keyFieldName) { + if (implicitCollectionMapper == null) { + throw new com.thoughtworks.xstream.InitializationException("No " + + ImplicitCollectionMapper.class.getName() + + " available"); + } + implicitCollectionMapper.add(ownerType, fieldName, itemName, itemType, keyFieldName); + } + + /** + * Create a DataHolder that can be used to pass data to the converters. The DataHolder is + * provided with a call to {@link #marshal(Object, HierarchicalStreamWriter, DataHolder)} or + * {@link #unmarshal(HierarchicalStreamReader, Object, DataHolder)}. + * + * @return a new {@link DataHolder} + */ + public DataHolder newDataHolder() { + return new MapBackedDataHolder(); + } + + /** + * Creates an ObjectOutputStream that serializes a stream of objects to the writer using + * XStream. + *

+ * To change the name of the root element (from <object-stream>), use + * {@link #createObjectOutputStream(java.io.Writer, String)}. + *

+ * + * @see #createObjectOutputStream(com.thoughtworks.xstream.io.HierarchicalStreamWriter, + * String) + * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader) + * @since 1.0.3 + */ + public ObjectOutputStream createObjectOutputStream(Writer writer) throws IOException { + return createObjectOutputStream( + hierarchicalStreamDriver.createWriter(writer), "object-stream"); + } + + /** + * Creates an ObjectOutputStream that serializes a stream of objects to the writer using + * XStream. + *

+ * To change the name of the root element (from <object-stream>), use + * {@link #createObjectOutputStream(java.io.Writer, String)}. + *

+ * + * @see #createObjectOutputStream(com.thoughtworks.xstream.io.HierarchicalStreamWriter, + * String) + * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader) + * @since 1.0.3 + */ + public ObjectOutputStream createObjectOutputStream(HierarchicalStreamWriter writer) + throws IOException { + return createObjectOutputStream(writer, "object-stream"); + } + + /** + * Creates an ObjectOutputStream that serializes a stream of objects to the writer using + * XStream. + * + * @see #createObjectOutputStream(com.thoughtworks.xstream.io.HierarchicalStreamWriter, + * String) + * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader) + * @since 1.0.3 + */ + public ObjectOutputStream createObjectOutputStream(Writer writer, String rootNodeName) + throws IOException { + return createObjectOutputStream( + hierarchicalStreamDriver.createWriter(writer), rootNodeName); + } + + /** + * Creates an ObjectOutputStream that serializes a stream of objects to the OutputStream + * using XStream. + *

+ * To change the name of the root element (from <object-stream>), use + * {@link #createObjectOutputStream(java.io.Writer, String)}. + *

+ * + * @see #createObjectOutputStream(com.thoughtworks.xstream.io.HierarchicalStreamWriter, + * String) + * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader) + * @since 1.3 + */ + public ObjectOutputStream createObjectOutputStream(OutputStream out) throws IOException { + return createObjectOutputStream( + hierarchicalStreamDriver.createWriter(out), "object-stream"); + } + + /** + * Creates an ObjectOutputStream that serializes a stream of objects to the OutputStream + * using XStream. + * + * @see #createObjectOutputStream(com.thoughtworks.xstream.io.HierarchicalStreamWriter, + * String) + * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader) + * @since 1.3 + */ + public ObjectOutputStream createObjectOutputStream(OutputStream out, String rootNodeName) + throws IOException { + return createObjectOutputStream( + hierarchicalStreamDriver.createWriter(out), rootNodeName); + } + + /** + * Creates an ObjectOutputStream that serializes a stream of objects to the writer using + * XStream. + *

+ * Because an ObjectOutputStream can contain multiple items and XML only allows a single + * root node, the stream must be written inside an enclosing node. + *

+ *

+ * It is necessary to call ObjectOutputStream.close() when done, otherwise the stream will + * be incomplete. + *

+ *

Example

+ * + *
+     *  ObjectOutputStream out = xstream.createObjectOutputStream(aWriter, "things");
+     *   out.writeInt(123);
+     *   out.writeObject("Hello");
+     *   out.writeObject(someObject)
+     *   out.close();
+     * 
+ * + * @param writer The writer to serialize the objects to. + * @param rootNodeName The name of the root node enclosing the stream of objects. + * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader) + * @since 1.0.3 + */ + public ObjectOutputStream createObjectOutputStream(final HierarchicalStreamWriter writer, + String rootNodeName) throws IOException { + final StatefulWriter statefulWriter = new StatefulWriter(writer); + statefulWriter.startNode(rootNodeName, null); + return new CustomObjectOutputStream(new CustomObjectOutputStream.StreamCallback() { + public void writeToStream(Object object) { + marshal(object, statefulWriter); + } + + public void writeFieldsToStream(Map fields) throws NotActiveException { + throw new NotActiveException("not in call to writeObject"); + } + + public void defaultWriteObject() throws NotActiveException { + throw new NotActiveException("not in call to writeObject"); + } + + public void flush() { + statefulWriter.flush(); + } + + public void close() { + if (statefulWriter.state() != StatefulWriter.STATE_CLOSED) { + statefulWriter.endNode(); + statefulWriter.close(); + } + } + }); + } + + /** + * Creates an ObjectInputStream that deserializes a stream of objects from a reader using + * XStream. + * + * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader) + * @see #createObjectOutputStream(com.thoughtworks.xstream.io.HierarchicalStreamWriter, + * String) + * @since 1.0.3 + */ + public ObjectInputStream createObjectInputStream(Reader xmlReader) throws IOException { + return createObjectInputStream(hierarchicalStreamDriver.createReader(xmlReader)); + } + + /** + * Creates an ObjectInputStream that deserializes a stream of objects from an InputStream + * using XStream. + * + * @see #createObjectInputStream(com.thoughtworks.xstream.io.HierarchicalStreamReader) + * @see #createObjectOutputStream(com.thoughtworks.xstream.io.HierarchicalStreamWriter, + * String) + * @since 1.3 + */ + public ObjectInputStream createObjectInputStream(InputStream in) throws IOException { + return createObjectInputStream(hierarchicalStreamDriver.createReader(in)); + } + + /** + * Creates an ObjectInputStream that deserializes a stream of objects from a reader using + * XStream.

Example

+ * + *
+     * ObjectInputStream in = xstream.createObjectOutputStream(aReader);
+     * int a = out.readInt();
+     * Object b = out.readObject();
+     * Object c = out.readObject();
+     * 
+ * + * @see #createObjectOutputStream(com.thoughtworks.xstream.io.HierarchicalStreamWriter, + * String) + * @since 1.0.3 + */ + public ObjectInputStream createObjectInputStream(final HierarchicalStreamReader reader) + throws IOException { + return new CustomObjectInputStream(new CustomObjectInputStream.StreamCallback() { + public Object readFromStream() throws EOFException { + if (!reader.hasMoreChildren()) { + throw new EOFException(); + } + reader.moveDown(); + Object result = unmarshal(reader); + reader.moveUp(); + return result; + } + + public Map readFieldsFromStream() throws IOException { + throw new NotActiveException("not in call to readObject"); + } + + public void defaultReadObject() throws NotActiveException { + throw new NotActiveException("not in call to readObject"); + } + + public void registerValidation(ObjectInputValidation validation, int priority) + throws NotActiveException { + throw new NotActiveException("stream inactive"); + } + + public void close() { + reader.close(); + } + }, classLoaderReference); + } + + /** + * Change the ClassLoader XStream uses to load classes. Creating an XStream instance it will + * register for all kind of classes and types of the current JDK, but not for any 3rd party + * type. To ensure that all other types are loaded with your class loader, you should call + * this method as early as possible - or consider to provide the class loader directly in + * the constructor. + * + * @since 1.1.1 + */ + public void setClassLoader(ClassLoader classLoader) { + classLoaderReference.setReference(classLoader); + } + + /** + * Retrieve the ClassLoader XStream uses to load classes. + * + * @since 1.1.1 + */ + public ClassLoader getClassLoader() { + return classLoaderReference.getReference(); + } + + /** + * Retrieve the reference to this instance' ClassLoader. Use this reference for other + * XStream components (like converters) to ensure that they will use a changed ClassLoader + * instance automatically. + * + * @return the reference + * @since 1.4.5 + */ + public ClassLoaderReference getClassLoaderReference() { + return classLoaderReference; + } + + /** + * Prevents a field from being serialized. To omit a field you must always provide the + * declaring type and not necessarily the type that is converted. + * + * @since 1.1.3 + * @throws InitializationException if no {@link FieldAliasingMapper} is available + */ + public void omitField(Class definedIn, String fieldName) { + if (fieldAliasingMapper == null) { + throw new com.thoughtworks.xstream.InitializationException("No " + + FieldAliasingMapper.class.getName() + + " available"); + } + fieldAliasingMapper.omitField(definedIn, fieldName); + } + + /** + * Ignore all unknown elements. + * + * @since 1.4.5 + */ + public void ignoreUnknownElements() { + ignoreUnknownElements(IGNORE_ALL); + } + + /** + * Add pattern for unknown element names to ignore. + * + * @param pattern the name pattern as regular expression + * @since 1.4.5 + */ + public void ignoreUnknownElements(String pattern) { + ignoreUnknownElements(Pattern.compile(pattern)); + } + + /** + * Add pattern for unknown element names to ignore. + * + * @param pattern the name pattern as regular expression + * @since 1.4.5 + */ + public void ignoreUnknownElements(final Pattern pattern) { + if (fieldAliasingMapper == null) { + throw new com.thoughtworks.xstream.InitializationException("No " + + FieldAliasingMapper.class.getName() + + " available"); + } + fieldAliasingMapper.addFieldsToIgnore(pattern); + } + + /** + * Process the annotations of the given types and configure the XStream. + * + * @param types the types with XStream annotations + * @since 1.3 + */ + public void processAnnotations(final Class[] types) { + if (annotationConfiguration == null) { + throw new com.thoughtworks.xstream.InitializationException("No " + + ANNOTATION_MAPPER_TYPE + + " available"); + } + annotationConfiguration.processAnnotations(types); + } + + /** + * Process the annotations of the given type and configure the XStream. A call of this + * method will automatically turn the auto-detection mode for annotations off. + * + * @param type the type with XStream annotations + * @since 1.3 + */ + public void processAnnotations(final Class type) { + processAnnotations(new Class[]{type}); + } + + /** + * Set the auto-detection mode of the AnnotationMapper. Note that auto-detection implies + * that the XStream is configured while it is processing the XML steams. This is a potential + * concurrency problem. Also is it technically not possible to detect all class aliases at + * deserialization. You have been warned! + * + * @param mode true if annotations are auto-detected + * @since 1.3 + */ + public void autodetectAnnotations(boolean mode) { + if (annotationConfiguration != null) { + annotationConfiguration.autodetectAnnotations(mode); + } + } + + /** + * Add a new security permission. + * + *

+ * Permissions are evaluated in the added sequence. An instance of {@link NoTypePermission} or + * {@link AnyTypePermission} will implicitly wipe any existing permission. + *

+ * + * @param permission the permission to add + * @since 1.4.7 + */ + public void addPermission(TypePermission permission) { + if (securityMapper != null) { + securityMapper.addPermission(permission); + } + } + + /** + * Add security permission for explicit types by name. + * + * @param names the type names to allow + * @since 1.4.7 + */ + public void allowTypes(String[] names) { + addPermission(new ExplicitTypePermission(names)); + } + + /** + * Add security permission for explicit types. + * + * @param types the types to allow + * @since 1.4.7 + */ + public void allowTypes(Class[] types) { + addPermission(new ExplicitTypePermission(types)); + } + + /** + * Add security permission for a type hierarchy. + * + * @param type the base type to allow + * @since 1.4.7 + */ + public void allowTypeHierarchy(Class type) { + addPermission(new TypeHierarchyPermission(type)); + } + + /** + * Add security permission for types matching one of the specified regular expressions. + * + * @param regexps the regular expressions to allow type names + * @since 1.4.7 + */ + public void allowTypesByRegExp(String[] regexps) { + addPermission(new RegExpTypePermission(regexps)); + } + + /** + * Add security permission for types matching one of the specified regular expressions. + * + * @param regexps the regular expressions to allow type names + * @since 1.4.7 + */ + public void allowTypesByRegExp(Pattern[] regexps) { + addPermission(new RegExpTypePermission(regexps)); + } + + /** + * Add security permission for types matching one of the specified wildcard patterns. + *

+ * Supported are patterns with path expressions using dot as separator: + *

+ * + * + * @param patterns the patterns to allow type names + * @since 1.4.7 + */ + public void allowTypesByWildcard(String[] patterns) { + addPermission(new WildcardTypePermission(patterns)); + } + + /** + * Add security permission denying another one. + * + * @param permission the permission to deny + * @since 1.4.7 + */ + public void denyPermission(TypePermission permission) { + addPermission(new NoPermission(permission)); + } + + /** + * Add security permission forbidding explicit types by name. + * + * @param names the type names to forbid + * @since 1.4.7 + */ + public void denyTypes(String[] names) { + denyPermission(new ExplicitTypePermission(names)); + } + + /** + * Add security permission forbidding explicit types. + * + * @param types the types to forbid + * @since 1.4.7 + */ + public void denyTypes(Class[] types) { + denyPermission(new ExplicitTypePermission(types)); + } + + /** + * Add security permission forbidding a type hierarchy. + * + * @param type the base type to forbid + * @since 1.4.7 + */ + public void denyTypeHierarchy(Class type) { + denyPermission(new TypeHierarchyPermission(type)); + } + + /** + * Add security permission forbidding types matching one of the specified regular expressions. + * + * @param regexps the regular expressions to forbid type names + * @since 1.4.7 + */ + public void denyTypesByRegExp(String[] regexps) { + denyPermission(new RegExpTypePermission(regexps)); + } + + /** + * Add security permission forbidding types matching one of the specified regular expressions. + * + * @param regexps the regular expressions to forbid type names + * @since 1.4.7 + */ + public void denyTypesByRegExp(Pattern[] regexps) { + denyPermission(new RegExpTypePermission(regexps)); + } + + /** + * Add security permission forbidding types matching one of the specified wildcard patterns. + *

+ * Supported are patterns with path expressions using dot as separator: + *

+ * + * + * @param patterns the patterns to forbid names + * @since 1.4.7 + */ + public void denyTypesByWildcard(String[] patterns) { + denyPermission(new WildcardTypePermission(patterns)); + } + + /** + * @deprecated As of 1.3, use {@link com.thoughtworks.xstream.InitializationException} + * instead + */ + public static class InitializationException extends XStreamException { + /** + * @deprecated As of 1.3, use + * {@link com.thoughtworks.xstream.InitializationException#InitializationException(String, Throwable)} + * instead + */ + public InitializationException(String message, Throwable cause) { + super(message, cause); + } + + /** + * @deprecated As of 1.3, use + * {@link com.thoughtworks.xstream.InitializationException#InitializationException(String)} + * instead + */ + public InitializationException(String message) { + super(message); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/XStreamException.java b/xstream/src/java/com/thoughtworks/xstream/XStreamException.java new file mode 100644 index 0000000..002a605 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/XStreamException.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. October 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream; + +import com.thoughtworks.xstream.core.BaseException; + + +/** + * Base exception for all thrown exceptions with XStream. JDK 1.3 friendly cause handling. + * + * @author Joe Walnes + * @author Jörg Schaible + * @since 1.3 + */ +public class XStreamException extends BaseException { + + private Throwable cause; + + /** + * Default constructor. + * + * @since 1.3 + */ + protected XStreamException() { + this("", null); + } + + /** + * Constructs an XStreamException with a message. + * + * @param message + * @since 1.3 + */ + public XStreamException(String message) { + this(message, null); + } + + /** + * Constructs an XStreamException as wrapper for a different causing {@link Throwable}. + * + * @param cause + * @since 1.3 + */ + public XStreamException(Throwable cause) { + this("", cause); + } + + /** + * Constructs an XStreamException with a message as wrapper for a different causing + * {@link Throwable}. + * + * @param message + * @param cause + * @since 1.3 + */ + public XStreamException(String message, Throwable cause) { + super(message + (cause == null ? "" : " : " + cause.getMessage())); + this.cause = cause; + } + + public Throwable getCause() { + return cause; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/XStreamer.java b/xstream/src/java/com/thoughtworks/xstream/XStreamer.java new file mode 100644 index 0000000..6d40890 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/XStreamer.java @@ -0,0 +1,301 @@ +/* + * Copyright (C) 2006, 2007, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. April 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamException; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; + +import javax.xml.datatype.DatatypeFactory; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.converters.ConverterMatcher; +import com.thoughtworks.xstream.converters.ConverterRegistry; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.converters.javabean.JavaBeanProvider; +import com.thoughtworks.xstream.converters.reflection.FieldKeySorter; +import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.io.HierarchicalStreamDriver; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.naming.NameCoder; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.mapper.Mapper; +import com.thoughtworks.xstream.security.AnyTypePermission; +import com.thoughtworks.xstream.security.TypeHierarchyPermission; +import com.thoughtworks.xstream.security.TypePermission; +import com.thoughtworks.xstream.security.WildcardTypePermission; + +/** + * Self-contained XStream generator. The class is a utility to write XML streams that contain + * additionally the XStream that was used to serialize the object graph. Such a stream can + * be unmarshalled using this embedded XStream instance, that kept any settings. + * + * @author Jörg Schaible + * @since 1.2 + */ +public class XStreamer { + + private final static TypePermission[] PERMISSIONS = { + new TypeHierarchyPermission(ConverterMatcher.class), + new TypeHierarchyPermission(Mapper.class), + new TypeHierarchyPermission(XStream.class), + new TypeHierarchyPermission(ReflectionProvider.class), + new TypeHierarchyPermission(JavaBeanProvider.class), + new TypeHierarchyPermission(FieldKeySorter.class), + new TypeHierarchyPermission(ConverterLookup.class), + new TypeHierarchyPermission(ConverterRegistry.class), + new TypeHierarchyPermission(HierarchicalStreamDriver.class), + new TypeHierarchyPermission(MarshallingStrategy.class), + new TypeHierarchyPermission(MarshallingContext.class), + new TypeHierarchyPermission(UnmarshallingContext.class), + new TypeHierarchyPermission(NameCoder.class), + new TypeHierarchyPermission(TypePermission.class), + new WildcardTypePermission(new String[]{JVM.class.getPackage().getName()+".**"}), + new TypeHierarchyPermission(DatatypeFactory.class) // required by DurationConverter + }; + + /** + * Serialize an object including the XStream to a pretty-printed XML String. + * + * @throws ObjectStreamException if the XML contains non-serializable elements + * @throws com.thoughtworks.xstream.XStreamException if the object cannot be serialized + * @since 1.2 + * @see #toXML(XStream, Object, Writer) + */ + public String toXML(final XStream xstream, final Object obj) throws ObjectStreamException { + final Writer writer = new StringWriter(); + try { + toXML(xstream, obj, writer); + } catch (final ObjectStreamException e) { + throw e; + } catch (final IOException e) { + throw new ConversionException("Unexpected IO error from a StringWriter", e); + } + return writer.toString(); + } + + /** + * Serialize an object including the XStream to the given Writer as pretty-printed XML. + *

+ * Warning: XStream will serialize itself into this XML stream. To read such an XML code, you + * should use {@link XStreamer#fromXML(Reader)} or one of the other overloaded + * methods. Since a lot of internals are written into the stream, you cannot expect to use such + * an XML to work with another XStream version or with XStream running on different JDKs and/or + * versions. We have currently no JDK 1.3 support, nor will the PureReflectionConverter work + * with a JDK less than 1.5. + *

+ * + * @throws IOException if an error occurs reading from the Writer. + * @throws com.thoughtworks.xstream.XStreamException if the object cannot be serialized + * @since 1.2 + */ + public void toXML(final XStream xstream, final Object obj, final Writer out) + throws IOException { + final XStream outer = new XStream(); + final ObjectOutputStream oos = outer.createObjectOutputStream(out); + try { + oos.writeObject(xstream); + oos.flush(); + xstream.toXML(obj, out); + } finally { + oos.close(); + } + } + + /** + * Deserialize a self-contained XStream with object from a String. The method will use + * internally an XppDriver to load the contained XStream instance with default permissions. + * + * @param xml the XML data + * @throws ClassNotFoundException if a class in the XML stream cannot be found + * @throws ObjectStreamException if the XML contains non-deserializable elements + * @throws com.thoughtworks.xstream.XStreamException if the object cannot be deserialized + * @since 1.2 + * @see #toXML(XStream, Object, Writer) + */ + public Object fromXML(final String xml) throws ClassNotFoundException, ObjectStreamException { + try { + return fromXML(new StringReader(xml)); + } catch (final ObjectStreamException e) { + throw e; + } catch (final IOException e) { + throw new ConversionException("Unexpected IO error from a StringReader", e); + } + } + + /** + * Deserialize a self-contained XStream with object from a String. The method will use + * internally an XppDriver to load the contained XStream instance. + * + * @param xml the XML data + * @param permissions the permissions to use (ensure that they include the defaults) + * @throws ClassNotFoundException if a class in the XML stream cannot be found + * @throws ObjectStreamException if the XML contains non-deserializable elements + * @throws com.thoughtworks.xstream.XStreamException if the object cannot be deserialized + * @since 1.4.7 + * @see #toXML(XStream, Object, Writer) + */ + public Object fromXML(final String xml, final TypePermission[] permissions) throws ClassNotFoundException, ObjectStreamException { + try { + return fromXML(new StringReader(xml), permissions); + } catch (final ObjectStreamException e) { + throw e; + } catch (final IOException e) { + throw new ConversionException("Unexpected IO error from a StringReader", e); + } + } + + /** + * Deserialize a self-contained XStream with object from a String. + * + * @param driver the implementation to use + * @param xml the XML data + * @throws ClassNotFoundException if a class in the XML stream cannot be found + * @throws ObjectStreamException if the XML contains non-deserializable elements + * @throws com.thoughtworks.xstream.XStreamException if the object cannot be deserialized + * @since 1.2 + * @see #toXML(XStream, Object, Writer) + */ + public Object fromXML(final HierarchicalStreamDriver driver, final String xml) + throws ClassNotFoundException, ObjectStreamException { + try { + return fromXML(driver, new StringReader(xml)); + } catch (final ObjectStreamException e) { + throw e; + } catch (final IOException e) { + throw new ConversionException("Unexpected IO error from a StringReader", e); + } + } + + /** + * Deserialize a self-contained XStream with object from a String. + * + * @param driver the implementation to use + * @param xml the XML data + * @param permissions the permissions to use (ensure that they include the defaults) + * @throws ClassNotFoundException if a class in the XML stream cannot be found + * @throws ObjectStreamException if the XML contains non-deserializable elements + * @throws com.thoughtworks.xstream.XStreamException if the object cannot be deserialized + * @since 1.4.7 + * @see #toXML(XStream, Object, Writer) + */ + public Object fromXML(final HierarchicalStreamDriver driver, final String xml, final TypePermission[] permissions) + throws ClassNotFoundException, ObjectStreamException { + try { + return fromXML(driver, new StringReader(xml), permissions); + } catch (final ObjectStreamException e) { + throw e; + } catch (final IOException e) { + throw new ConversionException("Unexpected IO error from a StringReader", e); + } + } + + /** + * Deserialize a self-contained XStream with object from an XML Reader. The method will use + * internally an XppDriver to load the contained XStream instance with default permissions. + * + * @param xml the {@link Reader} providing the XML data + * @throws IOException if an error occurs reading from the Reader. + * @throws ClassNotFoundException if a class in the XML stream cannot be found + * @throws com.thoughtworks.xstream.XStreamException if the object cannot be deserialized + * @since 1.2 + * @see #toXML(XStream, Object, Writer) + */ + public Object fromXML(final Reader xml) + throws IOException, ClassNotFoundException { + return fromXML(new XppDriver(), xml); + } + + /** + * Deserialize a self-contained XStream with object from an XML Reader. The method will use + * internally an XppDriver to load the contained XStream instance. + * + * @param xml the {@link Reader} providing the XML data + * @param permissions the permissions to use (ensure that they include the defaults) + * @throws IOException if an error occurs reading from the Reader. + * @throws ClassNotFoundException if a class in the XML stream cannot be found + * @throws com.thoughtworks.xstream.XStreamException if the object cannot be deserialized + * @since 1.4.7 + * @see #toXML(XStream, Object, Writer) + */ + public Object fromXML(final Reader xml, final TypePermission[] permissions) + throws IOException, ClassNotFoundException { + return fromXML(new XppDriver(), xml, permissions); + } + + /** + * Deserialize a self-contained XStream with object from an XML Reader. + * + * @param driver the implementation to use + * @param xml the {@link Reader} providing the XML data + * @throws IOException if an error occurs reading from the Reader. + * @throws ClassNotFoundException if a class in the XML stream cannot be found + * @throws com.thoughtworks.xstream.XStreamException if the object cannot be deserialized + * @since 1.2 + */ + public Object fromXML(final HierarchicalStreamDriver driver, final Reader xml) + throws IOException, ClassNotFoundException { + return fromXML(driver, xml, new TypePermission[]{AnyTypePermission.ANY}); + } + + /** + * Deserialize a self-contained XStream with object from an XML Reader. + * + * @param driver the implementation to use + * @param xml the {@link Reader} providing the XML data + * @param permissions the permissions to use (ensure that they include the defaults) + * @throws IOException if an error occurs reading from the Reader. + * @throws ClassNotFoundException if a class in the XML stream cannot be found + * @throws com.thoughtworks.xstream.XStreamException if the object cannot be deserialized + * @since 1.4.7 + */ + public Object fromXML(final HierarchicalStreamDriver driver, final Reader xml, final TypePermission[] permissions) + throws IOException, ClassNotFoundException { + final XStream outer = new XStream(driver); + for(int i = 0; i < permissions.length; ++i) { + outer.addPermission(permissions[i]); + } + final HierarchicalStreamReader reader = driver.createReader(xml); + final ObjectInputStream configIn = outer.createObjectInputStream(reader); + try { + final XStream configured = (XStream)configIn.readObject(); + final ObjectInputStream in = configured.createObjectInputStream(reader); + try { + return in.readObject(); + } finally { + in.close(); + } + } finally { + configIn.close(); + } + } + + /** + * Retrieve the default permissions to unmarshal an XStream instance. + *

+ * The returned list will only cover permissions for XStream's own types. If your custom converters or mappers keep + * references to other types, you will have to add permission for those types on your own. + *

+ * + * @since 1.4.7 + */ + public static TypePermission[] getDefaultPermissions() { + return (TypePermission[])PERMISSIONS.clone(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/annotations/AnnotationProvider.java b/xstream/src/java/com/thoughtworks/xstream/annotations/AnnotationProvider.java new file mode 100644 index 0000000..0da315b --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/annotations/AnnotationProvider.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 02. March 2006 by Mauro Talevi + */ +package com.thoughtworks.xstream.annotations; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; + + +/** + * An utility class to provide annotations from different sources + * + * @author Guilherme Silveira + * @deprecated As of 1.3 + */ +@Deprecated +public class AnnotationProvider { + + /** + * Returns a field annotation based on an annotation type + * + * @param field the annotation Field + * @param annotationClass the annotation Class + * @return The Annotation type + * @deprecated As of 1.3 + */ + @Deprecated + public T getAnnotation(Field field, Class annotationClass) { + return field.getAnnotation(annotationClass); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/annotations/AnnotationReflectionConverter.java b/xstream/src/java/com/thoughtworks/xstream/annotations/AnnotationReflectionConverter.java new file mode 100644 index 0000000..88cd5a9 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/annotations/AnnotationReflectionConverter.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 02. March 2006 by Mauro Talevi + */ +package com.thoughtworks.xstream.annotations; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.ConverterMatcher; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.SingleValueConverterWrapper; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; +import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; +import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; +import com.thoughtworks.xstream.mapper.Mapper; + + +/** + * ReflectionConverter which uses an AnnotationProvider to marshall and unmarshall fields based + * on the annotated converters. + * + * @author Guilherme Silveira + * @author Mauro Talevi + * @deprecated As of 1.3, build into {@link ReflectionConverter} + */ +@Deprecated +public class AnnotationReflectionConverter extends ReflectionConverter { + + private final AnnotationProvider annotationProvider; + + private final Map, Converter> cachedConverters; + + @Deprecated + public AnnotationReflectionConverter( + Mapper mapper, ReflectionProvider reflectionProvider, + AnnotationProvider annotationProvider) { + super(mapper, reflectionProvider); + this.annotationProvider = annotationProvider; + this.cachedConverters = new HashMap, Converter>(); + } + + protected void marshallField(final MarshallingContext context, Object newObj, Field field) { + XStreamConverter annotation = annotationProvider.getAnnotation( + field, XStreamConverter.class); + if (annotation != null) { + Class type = annotation.value(); + ensureCache(type); + context.convertAnother(newObj, cachedConverters.get(type)); + } else { + context.convertAnother(newObj); + } + } + + private void ensureCache(Class type) { + if (!this.cachedConverters.containsKey(type)) { + cachedConverters.put(type, newInstance(type)); + } + } + + protected Object unmarshallField( + final UnmarshallingContext context, final Object result, + Class type, Field field) { + XStreamConverter annotation = annotationProvider.getAnnotation( + field, XStreamConverter.class); + if (annotation != null) { + Class converterType = (Class)annotation.value(); + ensureCache(converterType); + return context.convertAnother(result, type, cachedConverters.get(converterType)); + } else { + return context.convertAnother(result, type); + } + } + + /** + * Instantiates a converter using its default constructor. + * + * @param type the converter type to instantiate + * @return the new instance + */ + private Converter newInstance(Class type) { + Converter converter; + // TODO: We need a separate exception for runtime initialization. + try { + if (SingleValueConverter.class.isAssignableFrom(type)) { + final SingleValueConverter svc = (SingleValueConverter)type.getConstructor().newInstance(); + converter = new SingleValueConverterWrapper(svc); + } else { + converter = (Converter)type.getConstructor().newInstance(); + } + } catch (InvocationTargetException e) { + throw new ObjectAccessException("Cannot construct " + type.getName(), e + .getCause()); + } catch (InstantiationException e) { + throw new ObjectAccessException("Cannot construct " + type.getName(), e); + } catch (IllegalAccessException e) { + throw new ObjectAccessException("Cannot construct " + type.getName(), e); + } catch (NoSuchMethodException e) { + throw new ObjectAccessException("Cannot construct " + type.getName(), e); + } + return converter; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/annotations/Annotations.java b/xstream/src/java/com/thoughtworks/xstream/annotations/Annotations.java new file mode 100644 index 0000000..1e48132 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/annotations/Annotations.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 11. August 2005 by Mauro Talevi + */ +package com.thoughtworks.xstream.annotations; + +import com.thoughtworks.xstream.XStream; + + +/** + * Contains utility methods that enable to configure an XStream instance with class and field + * aliases, based on a class decorated with annotations defined in this package. + * + * @author Emil Kirschner + * @author Chung-Onn Cheong + * @author Guilherme Silveira + * @author Jörg Schaible + * @deprecated As of 1.3, use {@link XStream#processAnnotations(Class[])} + */ +@Deprecated +public class Annotations { + /** + * This class is not instantiable + */ + private Annotations() { + } + + /** + * Configures aliases on the specified XStream object based on annotations that decorate the + * specified class. It will recursively invoke itself. If a field is parameterized, a + * recursive call for each of its parameters type will be made. + * + * @param topLevelClasses the class for which the XStream object is configured. This class + * is expected to be decorated with annotations defined in this package. + * @param xstream the XStream object that will be configured + * @deprecated As of 1.3, use {@link XStream#processAnnotations(Class[])} + */ + @Deprecated + public static synchronized void configureAliases(XStream xstream, + Class ... topLevelClasses) { + xstream.processAnnotations(topLevelClasses); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamAlias.java b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamAlias.java new file mode 100644 index 0000000..88d3c4c --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamAlias.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 11. August 2005 by Mauro Talevi + */ +package com.thoughtworks.xstream.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation used to define an XStream class or field alias. + * + * @author Emil Kirschner + * @author Chung-Onn Cheong + * @see com.thoughtworks.xstream.XStream#alias(String, Class) + * @see com.thoughtworks.xstream.XStream#alias(String, Class, Class) + * @see com.thoughtworks.xstream.XStream#addDefaultImplementation(Class, Class) + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.FIELD}) +public @interface XStreamAlias { + /** + * The name of the class or field alias. + */ + public String value(); + /** + * A possible default implementation if the annotated type is an interface. + */ + public Class impl() default Void.class; //Use Void to denote as Null +} diff --git a/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamAliasType.java b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamAliasType.java new file mode 100644 index 0000000..2019e47 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamAliasType.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2013 XStream Committers. + * All rights reserved. + * + * Created on 12.07.2013 by Joerg Schaible + */ +package com.thoughtworks.xstream.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + * Annotation used to define an XStream type alias. + * + * @author Jörg Schaible + * @since 1.4.5 + * @see com.thoughtworks.xstream.XStream#aliasType(String, Class) + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface XStreamAliasType { + /** + * The name of the type alias. + */ + public String value(); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamAsAttribute.java b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamAsAttribute.java new file mode 100644 index 0000000..a39e7ab --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamAsAttribute.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. December 2006 by Guilherme Silveira + */ +package com.thoughtworks.xstream.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Defines that a field should be serialized as an attribute. + * + * @author Guilherme Silveira + * @since 1.2.2 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +@Documented +public @interface XStreamAsAttribute { +} diff --git a/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamContainedType.java b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamContainedType.java new file mode 100644 index 0000000..6f2bc9e --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamContainedType.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 11. August 2005 by Mauro Talevi + */ +package com.thoughtworks.xstream.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation used to notify Annotations.configureAliases that it should recursively invoke itself for + * all parameterized types of this field. + * + * @author Emil Kirschner + * @author Chung-Onn Cheong + * @deprecated As of 1.3, recursive behaviour is now always used and the annotation is therefore superfluous + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +@Deprecated +public @interface XStreamContainedType { + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamConverter.java b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamConverter.java new file mode 100644 index 0000000..c0ef961 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamConverter.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 16. September 2005 by Mauro Talevi + */ +package com.thoughtworks.xstream.annotations; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.ConverterMatcher; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + * Annotation to declare a converter. The annotation supports additionally the injection of + * various constructor arguments provided by XStream: + *
    + *
  • {@link com.thoughtworks.xstream.mapper.Mapper}: The current mapper chain of the XStream + * instance.
  • + *
  • {@link com.thoughtworks.xstream.core.ClassLoaderReference}: The reference to the class + * loader used by the XStream instance to deserialize the objects.
  • + *
  • {@link com.thoughtworks.xstream.converters.reflection.ReflectionProvider}: The reflection + * provider used by the reflection based converters of the current XStream instance.
  • + *
  • {@link com.thoughtworks.xstream.converters.ConverterLookup}: The lookup for converters + * handling a special type.
  • + *
  • All elements provided with the individual arrays of this annotation. The provided values + * follow the declaration sequence if a constructor requires multiple arguments of the same + * type.
  • + *
  • {@link Class}: The type of the element where the annotation is declared. Note, that this + * argument is not supported when using + * {@link com.thoughtworks.xstream.annotations.XStreamConverters} or {@link #useImplicitType()} + * == false.
  • + *
  • {@link com.thoughtworks.xstream.core.JVM}: Utility e.g. to load classes.
  • + *
  • {@link ClassLoader} (deprecated since 1.4.5): The class loader used by the XStream + * instance to deserialize the objects. Use ClassLoaderReference as argument
  • + *
+ *

+ * The algorithm will try the converter's constructor with the most arguments first. + *

+ *

+ * Note, the annotation matches a {@link ConverterMatcher}. + * {@link com.thoughtworks.xstream.converters.Converter} as well as + * {@link com.thoughtworks.xstream.converters.SingleValueConverter} extend this interface. The + * {@link com.thoughtworks.xstream.mapper.AnnotationMapper} can only handle these two + * known types. + *

+ * + * @author Chung-Onn Cheong + * @author Jörg Schaible + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.FIELD}) +@Documented +public @interface XStreamConverter { + Class value(); + + int priority() default XStream.PRIORITY_NORMAL; + + /** + * Flag to provide the current type as implicit first Class argument to a converter's + * constructor. + * + * @return true if the current type is provided + * @since 1.4.5 + */ + boolean useImplicitType() default true; + + /** + * Provide class types as arguments for the converter's constructor arguments. + *

+ * Note, that XStream itself provides the current class type as first Class argument to a + * constructor, if the annotation is added directly to a class type (and not as part of a + * parameter declaration of a {@link XStreamConverters} annotation). The current type has + * precedence over any type provided with this method. This behavior can be overridden + * setting {@link #useImplicitType()} to false. + * + * @return the types + * @since 1.4.2 + */ + Class[] types() default {}; + + String[] strings() default {}; + + byte[] bytes() default {}; + + char[] chars() default {}; + + short[] shorts() default {}; + + int[] ints() default {}; + + long[] longs() default {}; + + float[] floats() default {}; + + double[] doubles() default {}; + + boolean[] booleans() default {}; +} diff --git a/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamConverters.java b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamConverters.java new file mode 100644 index 0000000..a515b70 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamConverters.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 16. September 2005 by Mauro Talevi + */ +package com.thoughtworks.xstream.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * + * @author Chung-Onn Cheong + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface XStreamConverters { + XStreamConverter[] value(); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamImplicit.java b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamImplicit.java new file mode 100644 index 0000000..e589add --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamImplicit.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. December 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * An annotation for marking a field as an implicit collection or array. + * + * @author Lucio Benfante + * @author Jörg Schaible + * @since 1.2.2 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface XStreamImplicit { + /** + * Element name of the implicit collection. + */ + String itemFieldName() default ""; + /** + * Field name of map entries that are used as key for the element in the implicit map. + * @since 1.4 + */ + String keyFieldName() default ""; +} diff --git a/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamImplicitCollection.java b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamImplicitCollection.java new file mode 100644 index 0000000..b54f45f --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamImplicitCollection.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 16. September 2005 by Mauro Talevi + */ +package com.thoughtworks.xstream.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * + * @author Chung-Onn Cheong + * @deprecated As of 1.3, use @XStreamImplicit at field level + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface XStreamImplicitCollection { + String value(); //fieldName + String item() default ""; //itemfieldName +} diff --git a/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamInclude.java b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamInclude.java new file mode 100644 index 0000000..44e9fe4 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamInclude.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. November 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation to force automated processing of further classes. + * + * @author Steven Sparling + * @since 1.3.1 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface XStreamInclude +{ + public Class[] value(); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamOmitField.java b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamOmitField.java new file mode 100644 index 0000000..9e3ab20 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/annotations/XStreamOmitField.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. May 2005 by Guilherme Silveira + */ +package com.thoughtworks.xstream.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +/** + * Declares a field to be omitted. The result is the same as invoking the method + * omitField in a XStream instance. + * + * @author Chung-Onn Cheong + * @author Guilherme Silveira + * @since 1.2.2 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @ interface XStreamOmitField { +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/ConversionException.java b/xstream/src/java/com/thoughtworks/xstream/converters/ConversionException.java new file mode 100644 index 0000000..cd920be --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/ConversionException.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2003, 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters; + +import com.thoughtworks.xstream.XStreamException; +import com.thoughtworks.xstream.core.util.OrderRetainingMap; + +import java.util.Iterator; +import java.util.Map; + +/** + * Thrown by {@link Converter} implementations when they cannot convert an object + * to/from textual data. + * + * When this exception is thrown it can be passed around to things that accept an + * {@link ErrorWriter}, allowing them to add diagnostics to the stack trace. + * + * @author Joe Walnes + * @author Jörg Schaible + * + * @see ErrorWriter + */ +public class ConversionException extends XStreamException implements ErrorWriter { + + private static final String SEPARATOR = "\n-------------------------------"; + private Map stuff = new OrderRetainingMap(); + + public ConversionException(String msg, Throwable cause) { + super(msg, cause); + if (msg != null) { + add("message", msg); + } + if (cause != null) { + add("cause-exception", cause.getClass().getName()); + add("cause-message", cause instanceof ConversionException ? ((ConversionException)cause).getShortMessage() : cause.getMessage()); + } + } + + public ConversionException(String msg) { + super(msg); + } + + public ConversionException(Throwable cause) { + this(cause.getMessage(), cause); + } + + public String get(String errorKey) { + return (String) stuff.get(errorKey); + } + + public void add(String name, String information) { + String key = name; + int i = 0; + while (stuff.containsKey(key)) { + String value = (String)stuff.get(key); + if (information.equals(value)) + return; + key = name + "[" + ++i +"]"; + } + stuff.put(key, information); + } + + public void set(String name, String information) { + String key = name; + int i = 0; + stuff.put(key, information); // keep order + while (stuff.containsKey(key)) { + if (i != 0) { + stuff.remove(key); + } + key = name + "[" + ++i +"]"; + } + } + + public Iterator keys() { + return stuff.keySet().iterator(); + } + + public String getMessage() { + StringBuffer result = new StringBuffer(); + if (super.getMessage() != null) { + result.append(super.getMessage()); + } + if (!result.toString().endsWith(SEPARATOR)) { + result.append("\n---- Debugging information ----"); + } + for (Iterator iterator = keys(); iterator.hasNext();) { + String k = (String) iterator.next(); + String v = get(k); + result.append('\n').append(k); + result.append(" ".substring(Math.min(20, k.length()))); + result.append(": ").append(v); + } + result.append(SEPARATOR); + return result.toString(); + } + + public String getShortMessage() { + return super.getMessage(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/Converter.java b/xstream/src/java/com/thoughtworks/xstream/converters/Converter.java new file mode 100644 index 0000000..3d20ca9 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/Converter.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2003, 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + +/** + * Converter implementations are responsible marshalling Java objects + * to/from textual data. + * + *

If an exception occurs during processing, a {@link ConversionException} + * should be thrown.

+ * + *

If working with the high level {@link com.thoughtworks.xstream.XStream} facade, + * you can register new converters using the XStream.registerConverter() method.

+ * + *

If working with the lower level API, the + * {@link com.thoughtworks.xstream.converters.ConverterLookup} implementation is + * responsible for looking up the appropriate converter.

+ * + *

Converters for object that can store all information in a single value + * should implement {@link com.thoughtworks.xstream.converters.SingleValueConverter}. + * {@link com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter} + * provides a starting point.

+ * + *

{@link com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter} + * provides a starting point for objects that hold a collection of other objects + * (such as Lists and Maps).

+ * + * @author Joe Walnes + * @see com.thoughtworks.xstream.XStream + * @see com.thoughtworks.xstream.converters.ConverterLookup + * @see com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter + * @see com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter + */ +public interface Converter extends ConverterMatcher { + + /** + * Convert an object to textual data. + * + * @param source The object to be marshalled. + * @param writer A stream to write to. + * @param context A context that allows nested objects to be processed by XStream. + */ + void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context); + + /** + * Convert textual data back into an object. + * + * @param reader The stream to read the text from. + * @param context + * @return The resulting object. + */ + Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context); + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/ConverterLookup.java b/xstream/src/java/com/thoughtworks/xstream/converters/ConverterLookup.java new file mode 100644 index 0000000..818702c --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/ConverterLookup.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2003, 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters; + +/** + * Responsible for looking up the correct Converter implementation for a specific type. + * + * @author Joe Walnes + * @see Converter + */ +public interface ConverterLookup { + + /** + * Lookup a converter for a specific type. + *

+ * This type may be any Class, including primitive and array types. It may also be null, signifying + * the value to be converted is a null type. + *

+ */ + Converter lookupConverterForType(Class type); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/ConverterMatcher.java b/xstream/src/java/com/thoughtworks/xstream/converters/ConverterMatcher.java new file mode 100644 index 0000000..4400727 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/ConverterMatcher.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. February 2006 by Mauro Talevi + */ +package com.thoughtworks.xstream.converters; + +/** + * ConverterMatcher allows to match converters to classes by + * determining if a given type can be converted by the converter instance. + * ConverterMatcher is the base interface of any converter. + * + * @author Joe Walnes + * @author Jörg Schaible + * @author Mauro Talevi + * @see com.thoughtworks.xstream.converters.Converter + * @see com.thoughtworks.xstream.converters.SingleValueConverter + * @since 1.2 + */ +public interface ConverterMatcher { + + /** + * Determines whether the converter can marshall a particular type. + * @param type the Class representing the object type to be converted + */ + boolean canConvert(Class type); + +} \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/ConverterRegistry.java b/xstream/src/java/com/thoughtworks/xstream/converters/ConverterRegistry.java new file mode 100644 index 0000000..d3ec037 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/ConverterRegistry.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. January 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters; + +/** + * An interface for the converter management. + * + * @author Jörg Schaible + * @since 1.3 + */ +public interface ConverterRegistry { + + void registerConverter(Converter converter, int priority); + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/DataHolder.java b/xstream/src/java/com/thoughtworks/xstream/converters/DataHolder.java new file mode 100644 index 0000000..05d45bf --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/DataHolder.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 16. August 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters; + +import java.util.Iterator; + +/** + * Holds generic data, to be used as seen fit by the user. + * + * @author Joe Walnes + */ +public interface DataHolder { + + Object get(Object key); + void put(Object key, Object value); + Iterator keys(); + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/ErrorReporter.java b/xstream/src/java/com/thoughtworks/xstream/converters/ErrorReporter.java new file mode 100644 index 0000000..83fa22f --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/ErrorReporter.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15.02.2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters; + +/** + * To aid debugging, some components expose themselves as ErrorReporter + * indicating that they can add information in case of an error.. + * + * @author Joerg Schaible + * + * @since 1.4 + */ +public interface ErrorReporter { + /** + * Append context information to an {@link ErrorWriter}. + * + * @param errorWriter the error writer + * @since 1.4 + */ + void appendErrors(ErrorWriter errorWriter); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/ErrorWriter.java b/xstream/src/java/com/thoughtworks/xstream/converters/ErrorWriter.java new file mode 100644 index 0000000..27e0d61 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/ErrorWriter.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 08. May 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters; + +import java.util.Iterator; + +/** + * To aid debugging, some components are passed an ErrorWriter + * when things go wrong, allowing them to add information + * to the error message that may be helpful to diagnose problems. + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public interface ErrorWriter { + + /** + * Add some information to the error message. The information will be added even + * if the identifier is already in use. + * + * @param name something to identify the type of information (e.g. 'XPath'). + * @param information detail of the message (e.g. '/blah/moo[3]' + */ + void add(String name, String information); + + /** + * Set some information to the error message. If the identifier is already in use, the + * new information will replace the old one. + * + * @param name something to identify the type of information (e.g. 'XPath'). + * @param information detail of the message (e.g. '/blah/moo[3]' + * @since 1.4 + */ + void set(String name, String information); + + /** + * Retrieve information of the error message. + * + * @param errorKey the key of the message + * @return the value + * @since 1.3 + */ + String get(String errorKey); + + /** + * Retrieve an iterator over all keys of the error message. + * + * @return an Iterator + * @since 1.3 + */ + Iterator keys(); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/MarshallingContext.java b/xstream/src/java/com/thoughtworks/xstream/converters/MarshallingContext.java new file mode 100644 index 0000000..bdca456 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/MarshallingContext.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters; + +public interface MarshallingContext extends DataHolder { + + /** + * Converts another object searching for the default converter + * @param nextItem the next item to convert + */ + void convertAnother(Object nextItem); + + /** + * Converts another object using the specified converter + * @param nextItem the next item to convert + * @param converter the Converter to use + * @since 1.2 + */ + void convertAnother(Object nextItem, Converter converter); + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/SingleValueConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/SingleValueConverter.java new file mode 100644 index 0000000..6884bf0 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/SingleValueConverter.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. February 2006 by Mauro Talevi + */ +package com.thoughtworks.xstream.converters; + +/** + * SingleValueConverter implementations are marshallable to/from a single value String representation. + * + *

{@link com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter} + * provides a starting point for objects that can store all information in a single value String.

+ * + * @author Joe Walnes + * @author Jörg Schaible + * @author Mauro Talevi + * @see com.thoughtworks.xstream.converters.Converter + * @see com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter + * @since 1.2 + */ +public interface SingleValueConverter extends ConverterMatcher { + + /** + * Marshals an Object into a single value representation. + * @param obj the Object to be converted + * @return a String with the single value of the Object or null + */ + public String toString(Object obj); + + /** + * Unmarshals an Object from its single value representation. + * @param str the String with the single value of the Object + * @return the Object + */ + public Object fromString(String str); + +} \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/SingleValueConverterWrapper.java b/xstream/src/java/com/thoughtworks/xstream/converters/SingleValueConverterWrapper.java new file mode 100644 index 0000000..795448d --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/SingleValueConverterWrapper.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2006, 2007, 2011, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 20. February 2006 by Mauro Talevi + */ +package com.thoughtworks.xstream.converters; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + +/** + * Wrapper to convert a {@link com.thoughtworks.xstream.converters.SingleValueConverter} into a + * {@link com.thoughtworks.xstream.converters.Converter}. + * + * @author Jörg Schaible + * @see com.thoughtworks.xstream.converters.Converter + * @see com.thoughtworks.xstream.converters.SingleValueConverter + */ +public class SingleValueConverterWrapper implements Converter, SingleValueConverter, ErrorReporter { + + private final SingleValueConverter wrapped; + + public SingleValueConverterWrapper(SingleValueConverter wrapped) { + this.wrapped = wrapped; + } + + public boolean canConvert(Class type) { + return wrapped.canConvert(type); + } + + public String toString(Object obj) { + return wrapped.toString(obj); + } + + public Object fromString(String str) { + return wrapped.fromString(str); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + writer.setValue(toString(source)); + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + return fromString(reader.getValue()); + } + + public void appendErrors(ErrorWriter errorWriter) { + errorWriter.add("wrapped-converter", wrapped == null ? "(null)" : wrapped.getClass().getName()); + if (wrapped instanceof ErrorReporter) { + ((ErrorReporter)wrapped).appendErrors(errorWriter); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/UnmarshallingContext.java b/xstream/src/java/com/thoughtworks/xstream/converters/UnmarshallingContext.java new file mode 100644 index 0000000..dff988e --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/UnmarshallingContext.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters; + +public interface UnmarshallingContext extends DataHolder { + + Object convertAnother(Object current, Class type); + + /** + * @since 1.2 + */ + Object convertAnother(Object current, Class type, Converter converter); + + Object currentObject(); + + Class getRequiredType(); + + void addCompletionCallback(Runnable work, int priority); + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/AbstractSingleValueConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/AbstractSingleValueConverter.java new file mode 100644 index 0000000..467412d --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/AbstractSingleValueConverter.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. February 2006 by Mauro Talevi + */ +package com.thoughtworks.xstream.converters.basic; + +import com.thoughtworks.xstream.converters.SingleValueConverter; + +/** + * Base abstract implementation of {@link com.thoughtworks.xstream.converters.SingleValueConverter}. + * + *

Subclasses should implement methods canConvert(Class) and fromString(String) for the conversion.

+ * + * @author Joe Walnes + * @author Jörg Schaible + * @author Mauro Talevi + * @see com.thoughtworks.xstream.converters.SingleValueConverter + */ +public abstract class AbstractSingleValueConverter implements SingleValueConverter { + + public abstract boolean canConvert(Class type); + + public String toString(Object obj) { + return obj == null ? null : obj.toString(); + } + + public abstract Object fromString(String str); + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/BigDecimalConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/BigDecimalConverter.java new file mode 100644 index 0000000..57a2014 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/BigDecimalConverter.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. May 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.basic; + +import java.math.BigDecimal; + +/** + * Converts a java.math.BigDecimal to a String, retaining + * its precision. + * + * @author Joe Walnes + */ +public class BigDecimalConverter extends AbstractSingleValueConverter { + + public boolean canConvert(Class type) { + return type.equals(BigDecimal.class); + } + + public Object fromString(String str) { + return new BigDecimal(str); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/BigIntegerConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/BigIntegerConverter.java new file mode 100644 index 0000000..e3113ed --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/BigIntegerConverter.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. May 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.basic; + +import java.math.BigInteger; + +/** + * Converts a java.math.BigInteger to a String. + * + * @author Joe Walnes + */ +public class BigIntegerConverter extends AbstractSingleValueConverter { + + public boolean canConvert(Class type) { + return type.equals(BigInteger.class); + } + + public Object fromString(String str) { + return new BigInteger(str); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/BooleanConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/BooleanConverter.java new file mode 100644 index 0000000..7afb03b --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/BooleanConverter.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2003, 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.basic; + + +/** + * Converts a boolean primitive or java.lang.Boolean wrapper to + * a String. + * + * @author Joe Walnes + * @author David Blevins + */ +public class BooleanConverter extends AbstractSingleValueConverter { + + public static final BooleanConverter TRUE_FALSE = new BooleanConverter("true", "false", false); + + public static final BooleanConverter YES_NO = new BooleanConverter("yes", "no", false); + + public static final BooleanConverter BINARY = new BooleanConverter("1", "0", true); + + private final String positive; + private final String negative; + private final boolean caseSensitive; + + public BooleanConverter(final String positive, final String negative, final boolean caseSensitive) { + this.positive = positive; + this.negative = negative; + this.caseSensitive = caseSensitive; + } + + public BooleanConverter() { + this("true", "false", false); + } + + /** + * @deprecated As of 1.4.8 use {@link #canConvert(Class)} + */ + public boolean shouldConvert(final Class type, final Object value) { + return true; + } + + public boolean canConvert(final Class type) { + return type.equals(boolean.class) || type.equals(Boolean.class); + } + + public Object fromString(final String str) { + if (caseSensitive) { + return positive.equals(str) ? Boolean.TRUE : Boolean.FALSE; + } else { + return positive.equalsIgnoreCase(str) ? Boolean.TRUE : Boolean.FALSE; + } + } + + public String toString(final Object obj) { + final Boolean value = (Boolean) obj; + return obj == null ? null : value.booleanValue() ? positive : negative; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/ByteConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/ByteConverter.java new file mode 100644 index 0000000..46b168a --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/ByteConverter.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2003, 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.basic; + +/** + * Converts a byte primitive or java.lang.Byte wrapper to + * a String. + * + * @author Joe Walnes + */ +public class ByteConverter extends AbstractSingleValueConverter { + + public boolean canConvert(Class type) { + return type.equals(byte.class) || type.equals(Byte.class); + } + + public Object fromString(String str) { + int value = Integer.decode(str).intValue(); + if(value < Byte.MIN_VALUE || value > 0xFF) { + throw new NumberFormatException("For input string: \"" + str + '"'); + } + return new Byte((byte)value); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/CharConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/CharConverter.java new file mode 100644 index 0000000..4f93310 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/CharConverter.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2003, 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.basic; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + +/** + * Converts a char primitive or java.lang.Character wrapper to + * a String. If char is \0 the representing String is empty. + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class CharConverter implements Converter, SingleValueConverter { + + public boolean canConvert(Class type) { + return type.equals(char.class) || type.equals(Character.class); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + writer.setValue(toString(source)); + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + String nullAttribute = reader.getAttribute("null"); + if (nullAttribute != null && nullAttribute.equals("true")) { + return new Character('\0'); + } else { + return fromString(reader.getValue()); + } + } + + public Object fromString(String str) { + if (str.length() == 0) { + return new Character('\0'); + } else { + return new Character(str.charAt(0)); + } + } + + public String toString(Object obj) { + char ch = ((Character)obj).charValue(); + return ch == '\0' ? "" : obj.toString(); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/DateConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/DateConverter.java new file mode 100644 index 0000000..ad111ed --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/DateConverter.java @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2003, 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 2013, 2014, 2015 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.basic; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.ErrorReporter; +import com.thoughtworks.xstream.converters.ErrorWriter; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.core.util.ThreadSafeSimpleDateFormat; + + +/** + * Converts a {@link Date} to a string as a date format, retaining precision down to milliseconds. + *

+ * The formatted string is by default in UTC and English locale. You can provide a different {@link Locale} and + * {@link TimeZone} that are used for serialization or null to use always the current TimeZone. Note, that + * the default format uses 3-letter time zones that can be ambiguous and may cause wrong results at deserialization and + * is localized since Java 6. + *

+ *

+ * Using a Java 7 runtime or higher, the converter supports the datetime + * format defined by W3C (a subset of ISO 8601) at deserialization. Only the formats that also contain the time + * information. + *

+ *

+ * Dates in a different era are using a special default pattern that contains the era itself. + *

+ * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class DateConverter extends AbstractSingleValueConverter implements ErrorReporter { + + private static final String[] DEFAULT_ACCEPTABLE_FORMATS; + private static final String DEFAULT_PATTERN; + private static final String DEFAULT_ERA_PATTERN; + private static final TimeZone UTC; + private static final long ERA_START; + static { + UTC = TimeZone.getTimeZone("UTC"); + + final String defaultPattern = "yyyy-MM-dd HH:mm:ss.S z"; + final String defaultEraPattern = "yyyy-MM-dd G HH:mm:ss.S z"; + final List acceptablePatterns = new ArrayList(); + final boolean utcSupported = JVM.canParseUTCDateFormat(); + DEFAULT_PATTERN = utcSupported ? defaultPattern : "yyyy-MM-dd HH:mm:ss.S 'UTC'"; + DEFAULT_ERA_PATTERN = utcSupported ? defaultEraPattern : "yyyy-MM-dd G HH:mm:ss.S 'UTC'"; + acceptablePatterns.add("yyyy-MM-dd HH:mm:ss.S z"); + if (!utcSupported) { + acceptablePatterns.add(defaultPattern); + } + acceptablePatterns.add("yyyy-MM-dd HH:mm:ss.S a"); + // JDK 1.3 needs both versions + acceptablePatterns.add("yyyy-MM-dd HH:mm:ssz"); + acceptablePatterns.add("yyyy-MM-dd HH:mm:ss z"); + if (!utcSupported) { + acceptablePatterns.add("yyyy-MM-dd HH:mm:ss 'UTC'"); + } + if (JVM.canParseISO8601TimeZoneInDateFormat()) { + acceptablePatterns.add("yyyy-MM-dd'T'HH:mm:ss.SX"); + acceptablePatterns.add("yyyy-MM-dd'T'HH:mm:ssX"); + acceptablePatterns.add("yyyy-MM-dd'T'HH:mmX"); + } + // backwards compatibility + acceptablePatterns.add("yyyy-MM-dd HH:mm:ssa"); + DEFAULT_ACCEPTABLE_FORMATS = (String[]) acceptablePatterns.toArray(new String[acceptablePatterns.size()]); + + final Calendar cal = Calendar.getInstance(); + cal.setTimeZone(UTC); + cal.clear(); + cal.set(1, Calendar.JANUARY, 1); + ERA_START = cal.getTime().getTime(); // calendar.getTimeInMillis() not available under JDK 1.3 + } + private final ThreadSafeSimpleDateFormat defaultFormat; + private final ThreadSafeSimpleDateFormat defaultEraFormat; + private final ThreadSafeSimpleDateFormat[] acceptableFormats; + + /** + * Construct a DateConverter with standard formats and lenient set off. + */ + public DateConverter() { + this(false); + } + + /** + * Construct a DateConverter with standard formats, lenient set off and uses a given + * TimeZone for serialization. + * + * @param timeZone the TimeZone used to serialize the Date + * @since 1.4 + */ + public DateConverter(final TimeZone timeZone) { + this(DEFAULT_PATTERN, DEFAULT_ACCEPTABLE_FORMATS, timeZone); + } + + /** + * Construct a DateConverter with standard formats and using UTC. + * + * @param lenient the lenient setting of {@link SimpleDateFormat#setLenient(boolean)} + * @since 1.3 + */ + public DateConverter(final boolean lenient) { + this(DEFAULT_PATTERN, DEFAULT_ACCEPTABLE_FORMATS, lenient); + } + + /** + * Construct a DateConverter with lenient set off using UTC. + * + * @param defaultFormat the default format + * @param acceptableFormats fallback formats + */ + public DateConverter(final String defaultFormat, final String[] acceptableFormats) { + this(defaultFormat, acceptableFormats, false); + } + + /** + * Construct a DateConverter with a given TimeZone and lenient set off. + * + * @param defaultFormat the default format + * @param acceptableFormats fallback formats + * @since 1.4 + */ + public DateConverter(final String defaultFormat, final String[] acceptableFormats, final TimeZone timeZone) { + this(defaultFormat, acceptableFormats, timeZone, false); + } + + /** + * Construct a DateConverter. + * + * @param defaultFormat the default format + * @param acceptableFormats fallback formats + * @param lenient the lenient setting of {@link SimpleDateFormat#setLenient(boolean)} + * @since 1.3 + */ + public DateConverter(final String defaultFormat, final String[] acceptableFormats, final boolean lenient) { + this(defaultFormat, acceptableFormats, UTC, lenient); + } + + /** + * Construct a DateConverter. + * + * @param defaultFormat the default format + * @param acceptableFormats fallback formats + * @param timeZone the TimeZone used to serialize the Date + * @param lenient the lenient setting of {@link SimpleDateFormat#setLenient(boolean)} + * @since 1.4 + */ + public DateConverter( + final String defaultFormat, final String[] acceptableFormats, final TimeZone timeZone, final boolean lenient) { + this(DEFAULT_ERA_PATTERN, defaultFormat, acceptableFormats, Locale.ENGLISH, timeZone, lenient); + } + + /** + * Construct a DateConverter. + * + * @param defaultEraFormat the default format for dates in a different era (may be + * null to drop era support) + * @param defaultFormat the default format + * @param acceptableFormats fallback formats + * @param locale locale to use for the format + * @param timeZone the TimeZone used to serialize the Date + * @param lenient the lenient setting of {@link SimpleDateFormat#setLenient(boolean)} + * @since 1.4.4 + */ + public DateConverter( + final String defaultEraFormat, final String defaultFormat, final String[] acceptableFormats, + final Locale locale, final TimeZone timeZone, final boolean lenient) { + if (defaultEraFormat != null) { + this.defaultEraFormat = new ThreadSafeSimpleDateFormat( + defaultEraFormat, timeZone, locale, 4, 20, lenient); + } else { + this.defaultEraFormat = null; + } + this.defaultFormat = new ThreadSafeSimpleDateFormat( + defaultFormat, timeZone, locale, 4, 20, lenient); + this.acceptableFormats = acceptableFormats != null + ? new ThreadSafeSimpleDateFormat[acceptableFormats.length] + : new ThreadSafeSimpleDateFormat[0]; + for (int i = 0; i < this.acceptableFormats.length; i++ ) { + this.acceptableFormats[i] = new ThreadSafeSimpleDateFormat( + acceptableFormats[i], timeZone, locale, 1, 20, lenient); + } + } + + public boolean canConvert(Class type) { + return type.equals(Date.class); + } + + public Object fromString(String str) { + if (defaultEraFormat != null) { + try { + return defaultEraFormat.parse(str); + } catch (ParseException e) { + // try next ... + } + } + if (defaultEraFormat != defaultFormat) { + try { + return defaultFormat.parse(str); + } catch (ParseException e) { + // try next ... + } + } + for (int i = 0; i < acceptableFormats.length; i++ ) { + try { + return acceptableFormats[i].parse(str); + } catch (ParseException e3) { + // no worries, let's try the next format. + } + } + // no dateFormats left to try + throw new ConversionException("Cannot parse date " + str); + } + + public String toString(Object obj) { + final Date date = (Date)obj; + if (date.getTime() < ERA_START && defaultEraFormat != null) { + return defaultEraFormat.format(date); + } else { + return defaultFormat.format(date); + } + } + + public void appendErrors(ErrorWriter errorWriter) { + errorWriter.add("Default date pattern", defaultFormat.toString()); + if (defaultEraFormat != null) { + errorWriter.add("Default era date pattern", defaultEraFormat.toString()); + } + for (int i = 0; i < acceptableFormats.length; i++ ) { + errorWriter.add("Alternative date pattern", acceptableFormats[i].toString()); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/DoubleConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/DoubleConverter.java new file mode 100644 index 0000000..1c5b6e3 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/DoubleConverter.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2003, 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.basic; + +/** + * Converts a double primitive or java.lang.Double wrapper to + * a String. + * + * @author Joe Walnes + */ +public class DoubleConverter extends AbstractSingleValueConverter { + + public boolean canConvert(Class type) { + return type.equals(double.class) || type.equals(Double.class); + } + + public Object fromString(String str) { + return Double.valueOf(str); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/FloatConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/FloatConverter.java new file mode 100644 index 0000000..66a486f --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/FloatConverter.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2003, 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.basic; + +/** + * Converts a float primitive or java.lang.Float wrapper to + * a String. + * + * @author Joe Walnes + */ +public class FloatConverter extends AbstractSingleValueConverter { + + public boolean canConvert(Class type) { + return type.equals(float.class) || type.equals(Float.class); + } + + public Object fromString(String str) { + return Float.valueOf(str); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/IntConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/IntConverter.java new file mode 100644 index 0000000..cc28fcd --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/IntConverter.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2003, 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.basic; + +/** + * Converts an int primitive or java.lang.Integer wrapper to + * a String. + * + * @author Joe Walnes + */ +public class IntConverter extends AbstractSingleValueConverter { + + public boolean canConvert(Class type) { + return type.equals(int.class) || type.equals(Integer.class); + } + + public Object fromString(String str) { + long value = Long.decode(str).longValue(); + if(value < Integer.MIN_VALUE || value > 0xFFFFFFFFl) { + throw new NumberFormatException("For input string: \"" + str + '"'); + } + return new Integer((int)value); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/LongConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/LongConverter.java new file mode 100644 index 0000000..88771f1 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/LongConverter.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2003, 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.basic; + +/** + * Converts a long primitive or java.lang.Long wrapper to a String. + * + * @author Joe Walnes + */ +public class LongConverter extends AbstractSingleValueConverter { + + public boolean canConvert(Class type) { + return type.equals(long.class) || type.equals(Long.class); + } + + public Object fromString(String str) { + int len = str.length(); + if (len == 0) { + throw new NumberFormatException("For input string: \"\""); + } + if (len < 17) { + return Long.decode(str); + } + char c0 = str.charAt(0); + if (c0 != '0' && c0 != '#') { + return Long.decode(str); + } + char c1 = str.charAt(1); + final long high; + final long low; + if (c0 == '#' && len == 17) { + high = Long.parseLong(str.substring(1, 9), 16) << 32; + low = Long.parseLong(str.substring(9, 17), 16); + } else if ((c1 == 'x' || c1 == 'X') && len == 18) { + high = Long.parseLong(str.substring(2, 10), 16) << 32; + low = Long.parseLong(str.substring(10, 18), 16); + } else if (len == 23 && c1 == '1') { + high = Long.parseLong(str.substring(1, 12), 8) << 33; + low = Long.parseLong(str.substring(12, 23), 8); + } else { + return Long.decode(str); + } + final long num = high | low; + return new Long(num); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/NullConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/NullConverter.java new file mode 100644 index 0000000..7b2fe53 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/NullConverter.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2003, 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2012 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. October 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.basic; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; +import com.thoughtworks.xstream.mapper.Mapper; + +/** + * Special converter to signify nulls at the root level. + * + * @author Joe Walnes + */ +public class NullConverter implements Converter { + + public boolean canConvert(Class type) { + return type == null || Mapper.Null.class.isAssignableFrom(type); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + ExtendedHierarchicalStreamWriterHelper.startNode(writer, "null", Mapper.Null.class); + writer.endNode(); + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + return null; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/ShortConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/ShortConverter.java new file mode 100644 index 0000000..df9c851 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/ShortConverter.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2003, 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.basic; + +/** + * Converts a short primitive or java.lang.Short wrapper to + * a String. + * + * @author Joe Walnes + */ +public class ShortConverter extends AbstractSingleValueConverter { + + public boolean canConvert(Class type) { + return type.equals(short.class) || type.equals(Short.class); + } + + public Object fromString(String str) { + int value = Integer.decode(str).intValue(); + if(value < Short.MIN_VALUE || value > 0xFFFF) { + throw new NumberFormatException("For input string: \"" + str + '"'); + } + return new Short((short)value); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringBufferConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringBufferConverter.java new file mode 100644 index 0000000..4bdaaab --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringBufferConverter.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2003, 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. September 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.basic; + +/** + * Converts the contents of a StringBuffer to XML. + * + * @author Joe Walnes + */ +public class StringBufferConverter extends AbstractSingleValueConverter { + + public Object fromString(String str) { + return new StringBuffer(str); + } + + public boolean canConvert(Class type) { + return type.equals(StringBuffer.class); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringBuilderConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringBuilderConverter.java new file mode 100644 index 0000000..d1557af --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringBuilderConverter.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. January 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.basic; + +/** + * Converts the contents of a StringBuilder to XML. + * + * @author Jörg Schaible + */ +public class StringBuilderConverter extends AbstractSingleValueConverter { + + public Object fromString(String str) { + return new StringBuilder(str); + } + + public boolean canConvert(Class type) { + return type.equals(StringBuilder.class); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringConverter.java new file mode 100644 index 0000000..7ee0437 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/StringConverter.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2003, 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.basic; + +import java.util.Collections; +import java.util.Map; + +import com.thoughtworks.xstream.core.util.WeakCache; + + +/** + * Converts a String to a String ;). + *

+ * Well ok, it doesn't actually do any conversion. The converter uses by default a map + * with weak references to reuse instances of strings that do not exceed a length limit. This + * limit is by default 38 characters to cache typical strings containing UUIDs. Only shorter + * strings are typically repeated more often in XML values. + *

+ * + * @author Joe Walnes + * @author Rene Schwietzke + * @author Jörg Schaible + */ +public class StringConverter extends AbstractSingleValueConverter { + + private static final int LENGTH_LIMIT = 38; + + /** + * A Map to store strings as long as needed to map similar strings onto the same instance + * and conserve memory. The map can be set from the outside during construction, so it can + * be a LRU map or a weak map, synchronised or not. + */ + private final Map cache; + private final int lengthLimit; + + /** + * Construct a StringConverter using a map-based cache for strings not exceeding the length limit. + * + * @param map the map to use for the instances to reuse (may be null to not cache at all) + * @param lengthLimit maximum string length of a cached string, -1 to cache all, 0 to turn off the cache + * @since 1.4.2 + */ + public StringConverter(final Map map, int lengthLimit) { + cache = map; + this.lengthLimit = lengthLimit; + } + + /** + * Construct a StringConverter using a map-based cache for strings not exceeding 38 characters. + * + * @param map the map to use for the instances to reuse (may be null to not cache at all) + */ + public StringConverter(final Map map) { + this(map, LENGTH_LIMIT); + } + + /** + * Construct a StringConverter using a cache with weak references for strings not exceeding the length limit. + * + * @param lengthLimit maximum string length of a cached string, -1 to cache all, 0 to turn off the cache + * @since 1.4.2 + */ + public StringConverter(int lengthLimit) { + this(Collections.synchronizedMap(new WeakCache()), lengthLimit); + } + + /** + * Construct a StringConverter using a cache with weak references for strings not exceeding 38 characters. + */ + public StringConverter() { + this(LENGTH_LIMIT); + } + + public boolean canConvert(final Class type) { + return type.equals(String.class); + } + + public Object fromString(final String str) { + if (cache != null && str != null && (lengthLimit < 0 || str.length() <= lengthLimit)) { + String s = (String)cache.get(str); + + if (s == null) { + // fill cache + cache.put(str, str); + + s = str; + } + + return s; + } else { + return str; + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/URIConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/URIConverter.java new file mode 100644 index 0000000..0661efd --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/URIConverter.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2010 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 3. August 2010 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.basic; + +import java.net.URI; +import java.net.URISyntaxException; + +import com.thoughtworks.xstream.converters.ConversionException; + + +/** + * Converts a java.net.URI to a string. + * + * @author Carlos Roman + */ +public class URIConverter extends AbstractSingleValueConverter { + + public boolean canConvert(Class type) { + return type.equals(URI.class); + } + + public Object fromString(String str) { + try { + return new URI(str); + } catch (URISyntaxException e) { + throw new ConversionException(e); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/URLConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/URLConverter.java new file mode 100644 index 0000000..8aee562 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/URLConverter.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 25. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.basic; + +import com.thoughtworks.xstream.converters.ConversionException; + +import java.net.MalformedURLException; +import java.net.URL; + +/** + * Converts a java.net.URL to a string. + * + * @author J. Matthew Pryor + */ +public class URLConverter extends AbstractSingleValueConverter { + + public boolean canConvert(Class type) { + return type.equals(URL.class); + } + + public Object fromString(String str) { + try { + return new URL(str); + } catch (MalformedURLException e) { + throw new ConversionException(e); + } + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/UUIDConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/basic/UUIDConverter.java new file mode 100644 index 0000000..a1d69d8 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/UUIDConverter.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. January 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.basic; + +import com.thoughtworks.xstream.converters.ConversionException; + +import java.util.UUID; + + +/** + * Converts a java.util.UUID to a string. + * + * @author Jörg Schaible + */ +public class UUIDConverter extends AbstractSingleValueConverter { + + public boolean canConvert(Class type) { + return type.equals(UUID.class); + } + + public Object fromString(String str) { + try { + return UUID.fromString(str); + } catch(IllegalArgumentException e) { + throw new ConversionException("Cannot create UUID instance", e); + } + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/basic/package.html b/xstream/src/java/com/thoughtworks/xstream/converters/basic/package.html new file mode 100644 index 0000000..6440f47 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/basic/package.html @@ -0,0 +1,22 @@ + + +

Converters for common basic types in Java. These include +primitives (int, boolean, etc), wrapper objects (Integer, Boolean, etc), +String, StringBuffer, java.util.Date, null, java.net.URL, +java.math.BigInteger and java.math.BigDecimal.

+ +

These converters are enabled by default.

+ +

All of the basic converters will convert the item +into a single String, with no nested elements.

+ \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/AbstractCollectionConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/AbstractCollectionConverter.java new file mode 100644 index 0000000..0909417 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/AbstractCollectionConverter.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2003, 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.collections; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.core.util.HierarchicalStreams; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; +import com.thoughtworks.xstream.mapper.Mapper; + +/** + * Base helper class for converters that need to handle + * collections of items (arrays, Lists, Maps, etc). + * + *

Typically, subclasses of this will converter the outer + * structure of the collection, loop through the contents and + * call readItem() or writeItem() for each item.

+ * + * @author Joe Walnes + */ +public abstract class AbstractCollectionConverter implements Converter { + + private final Mapper mapper; + + public abstract boolean canConvert(Class type); + + public AbstractCollectionConverter(Mapper mapper) { + this.mapper = mapper; + } + + protected Mapper mapper() { + return mapper; + } + + public abstract void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context); + + public abstract Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context); + + + + protected void writeItem(Object item, MarshallingContext context, HierarchicalStreamWriter writer) { + // PUBLISHED API METHOD! If changing signature, ensure backwards compatibility. + if (item == null) { + // todo: this is duplicated in TreeMarshaller.start() + String name = mapper().serializedClass(null); + ExtendedHierarchicalStreamWriterHelper.startNode(writer, name, Mapper.Null.class); + writer.endNode(); + } else { + String name = mapper().serializedClass(item.getClass()); + ExtendedHierarchicalStreamWriterHelper.startNode(writer, name, item.getClass()); + context.convertAnother(item); + writer.endNode(); + } + } + + protected Object readItem(HierarchicalStreamReader reader, UnmarshallingContext context, Object current) { + Class type = HierarchicalStreams.readClassType(reader, mapper()); + return context.convertAnother(current, type); + } + + protected Object createCollection(Class type) { + Class defaultType = mapper().defaultImplementationOf(type); + try { + return defaultType.newInstance(); + } catch (InstantiationException e) { + throw new ConversionException("Cannot instantiate " + defaultType.getName(), e); + } catch (IllegalAccessException e) { + throw new ConversionException("Cannot instantiate " + defaultType.getName(), e); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/ArrayConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/ArrayConverter.java new file mode 100644 index 0000000..25da0ce --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/ArrayConverter.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2003, 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. October 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.collections; + +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Converts an array of objects or primitives to XML, using + * a nested child element for each item. + * + * @author Joe Walnes + */ +public class ArrayConverter extends AbstractCollectionConverter { + + public ArrayConverter(Mapper mapper) { + super(mapper); + } + + public boolean canConvert(Class type) { + return type.isArray(); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + int length = Array.getLength(source); + for (int i = 0; i < length; i++) { + Object item = Array.get(source, i); + writeItem(item, context, writer); + } + + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + // read the items from xml into a list + List items = new ArrayList(); + while (reader.hasMoreChildren()) { + reader.moveDown(); + Object item = readItem(reader, context, null); // TODO: arg, what should replace null? + items.add(item); + reader.moveUp(); + } + // now convertAnother the list into an array + // (this has to be done as a separate list as the array size is not + // known until all items have been read) + Object array = Array.newInstance(context.getRequiredType().getComponentType(), items.size()); + int i = 0; + for (Iterator iterator = items.iterator(); iterator.hasNext();) { + Array.set(array, i++, iterator.next()); + } + return array; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/BitSetConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/BitSetConverter.java new file mode 100644 index 0000000..627ba8c --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/BitSetConverter.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.collections; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + +import java.util.BitSet; +import java.util.StringTokenizer; + +/** + * Converts a java.util.BitSet to XML, as a compact + * comma delimited list of ones and zeros. + * + * @author Joe Walnes + */ +public class BitSetConverter implements Converter { + + public boolean canConvert(Class type) { + return type.equals(BitSet.class); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + BitSet bitSet = (BitSet) source; + StringBuffer buffer = new StringBuffer(); + boolean seenFirst = false; + for (int i = 0; i < bitSet.length(); i++) { + if (bitSet.get(i)) { + if (seenFirst) { + buffer.append(','); + } else { + seenFirst = true; + } + buffer.append(i); + } + } + writer.setValue(buffer.toString()); + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + BitSet result = new BitSet(); + StringTokenizer tokenizer = new StringTokenizer(reader.getValue(), ",", false); + while (tokenizer.hasMoreTokens()) { + int index = Integer.parseInt(tokenizer.nextToken()); + result.set(index); + } + return result; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/CharArrayConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/CharArrayConverter.java new file mode 100644 index 0000000..62e8332 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/CharArrayConverter.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.collections; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + +/** + * Converts a char[] to XML, storing the contents as a single + * String. + * + * @author Joe Walnes + */ +public class CharArrayConverter implements Converter { + + public boolean canConvert(Class type) { + return type.isArray() && type.getComponentType().equals(char.class); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + char[] chars = (char[]) source; + writer.setValue(new String(chars)); + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + return reader.getValue().toCharArray(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/CollectionConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/CollectionConverter.java new file mode 100644 index 0000000..4c7e90d --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/CollectionConverter.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2003, 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2010, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. October 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.collections; + +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Vector; + +/** + * Converts most common Collections (Lists and Sets) to XML, specifying a nested + * element for each item. + * + *

Supports java.util.ArrayList, java.util.HashSet, + * java.util.LinkedList, java.util.Vector and java.util.LinkedHashSet.

+ * + * @author Joe Walnes + */ +public class CollectionConverter extends AbstractCollectionConverter { + + private final Class type; + + public CollectionConverter(Mapper mapper) { + this(mapper, null); + } + + /** + * Construct a CollectionConverter for a special Collection type. + * @param mapper the mapper + * @param type the Collection type to handle + * @since 1.4.5 + */ + public CollectionConverter(Mapper mapper, Class type) { + super(mapper); + this.type = type; + if (type != null && !Collection.class.isAssignableFrom(type)) { + throw new IllegalArgumentException(type + " not of type " + Collection.class); + } + } + + public boolean canConvert(Class type) { + if (this.type != null) { + return type.equals(this.type); + } + return type.equals(ArrayList.class) + || type.equals(HashSet.class) + || type.equals(LinkedList.class) + || type.equals(Vector.class) + || (JVM.is14() && type.getName().equals("java.util.LinkedHashSet")); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + Collection collection = (Collection) source; + for (Iterator iterator = collection.iterator(); iterator.hasNext();) { + Object item = iterator.next(); + writeItem(item, context, writer); + } + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + Collection collection = (Collection) createCollection(context.getRequiredType()); + populateCollection(reader, context, collection); + return collection; + } + + protected void populateCollection(HierarchicalStreamReader reader, UnmarshallingContext context, Collection collection) { + populateCollection(reader, context, collection, collection); + } + + protected void populateCollection(HierarchicalStreamReader reader, UnmarshallingContext context, Collection collection, Collection target) { + while (reader.hasMoreChildren()) { + reader.moveDown(); + addCurrentElementToCollection(reader, context, collection, target); + reader.moveUp(); + } + } + + protected void addCurrentElementToCollection(HierarchicalStreamReader reader, UnmarshallingContext context, + Collection collection, Collection target) { + Object item = readItem(reader, context, collection); + target.add(item); + } + + protected Object createCollection(Class type) { + return super.createCollection(this.type != null ? this.type : type); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/MapConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/MapConverter.java new file mode 100644 index 0000000..dccaca7 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/MapConverter.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2003, 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2012, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.collections; + +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; + +/** + * Converts a java.util.Map to XML, specifying an 'entry' + * element with 'key' and 'value' children. + *

Note: 'key' and 'value' is not the name of the generated tag. The + * children are serialized as normal elements and the implementation expects + * them in the order 'key'/'value'.

+ *

Supports java.util.HashMap, java.util.Hashtable, + * java.util.LinkedHashMap and java.util.concurrent.ConcurrentHashMap.

+ * + * @author Joe Walnes + */ +public class MapConverter extends AbstractCollectionConverter { + + private final Class type; + + public MapConverter(Mapper mapper) { + this(mapper, null); + } + + /** + * Construct a MapConverter for a special Map type. + * @param mapper the mapper + * @param type the type to handle + * @since 1.4.5 + */ + public MapConverter(Mapper mapper, Class type) { + super(mapper); + this.type = type; + if (type != null && !Map.class.isAssignableFrom(type)) { + throw new IllegalArgumentException(type + " not of type " + Map.class); + } + } + + public boolean canConvert(Class type) { + if (this.type != null) { + return type.equals(this.type); + } + return type.equals(HashMap.class) + || type.equals(Hashtable.class) + || type.getName().equals("java.util.LinkedHashMap") + || type.getName().equals("java.util.concurrent.ConcurrentHashMap") + || type.getName().equals("sun.font.AttributeMap") // Used by java.awt.Font in JDK 6 + ; + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + Map map = (Map) source; + String entryName = mapper().serializedClass(Map.Entry.class); + for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = (Map.Entry) iterator.next(); + ExtendedHierarchicalStreamWriterHelper.startNode(writer, entryName, entry.getClass()); + + writeItem(entry.getKey(), context, writer); + writeItem(entry.getValue(), context, writer); + + writer.endNode(); + } + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + Map map = (Map) createCollection(context.getRequiredType()); + populateMap(reader, context, map); + return map; + } + + protected void populateMap(HierarchicalStreamReader reader, UnmarshallingContext context, Map map) { + populateMap(reader, context, map, map); + } + + protected void populateMap(HierarchicalStreamReader reader, UnmarshallingContext context, Map map, Map target) { + while (reader.hasMoreChildren()) { + reader.moveDown(); + putCurrentEntryIntoMap(reader, context, map, target); + reader.moveUp(); + } + } + + protected void putCurrentEntryIntoMap(HierarchicalStreamReader reader, UnmarshallingContext context, + Map map, Map target) { + reader.moveDown(); + Object key = readItem(reader, context, map); + reader.moveUp(); + + reader.moveDown(); + Object value = readItem(reader, context, map); + reader.moveUp(); + + target.put(key, value); + } + + protected Object createCollection(Class type) { + return super.createCollection(this.type != null ? this.type : type); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/PropertiesConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/PropertiesConverter.java new file mode 100644 index 0000000..0f3c8b4 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/PropertiesConverter.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 23. February 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.collections; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.core.util.Fields; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + +import java.lang.reflect.Field; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; +import java.util.TreeMap; + + +/** + * Special converter for java.util.Properties that stores properties in a more compact form than + * java.util.Map. + *

+ * Because all entries of a Properties instance are Strings, a single element is used for each + * property with two attributes; one for key and one for value. + *

+ *

+ * Additionally, default properties are also serialized, if they are present or if a + * SecurityManager is set, and it has permissions for SecurityManager.checkPackageAccess, + * SecurityManager.checkMemberAccess(this, EnumSet.MEMBER) and + * ReflectPermission("suppressAccessChecks"). + *

+ * + * @author Joe Walnes + * @author Kevin Ring + */ +public class PropertiesConverter implements Converter { + + private final static Field defaultsField = Fields.locate(Properties.class, Properties.class, false); + private final boolean sort; + + public PropertiesConverter() { + this(false); + } + + public PropertiesConverter(boolean sort) { + this.sort = sort; + } + + public boolean canConvert(Class type) { + return Properties.class == type; + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + final Properties properties = (Properties) source; + Map map = sort ? (Map)new TreeMap(properties) : (Map)properties; + for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = (Map.Entry) iterator.next(); + writer.startNode("property"); + writer.addAttribute("name", entry.getKey().toString()); + writer.addAttribute("value", entry.getValue().toString()); + writer.endNode(); + } + if (defaultsField != null) { + Properties defaults = (Properties)Fields.read(defaultsField, properties); + if (defaults != null) { + writer.startNode("defaults"); + marshal(defaults, writer, context); + writer.endNode(); + } + } + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + Properties properties = new Properties(); + Properties defaults = null; + while (reader.hasMoreChildren()) { + reader.moveDown(); + if (reader.getNodeName().equals("defaults")) { + defaults = (Properties) unmarshal(reader, context); + } else { + String name = reader.getAttribute("name"); + String value = reader.getAttribute("value"); + properties.setProperty(name, value); + } + reader.moveUp(); + } + if (defaults == null) { + return properties; + } else { + Properties propertiesWithDefaults = new Properties(defaults); + propertiesWithDefaults.putAll(properties); + return propertiesWithDefaults; + } + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/SingletonCollectionConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/SingletonCollectionConverter.java new file mode 100644 index 0000000..c56bc90 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/SingletonCollectionConverter.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 11. October 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.collections; + +import java.util.Collections; + +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.mapper.Mapper; + + +/** + * Converts singleton collections (list and set) to XML, specifying a nested element for the + * item. + *

+ * Supports Collections.singleton(Object) and Collections.singletonList(Object). + *

+ * + * @author Jörg Schaible + * @since 1.4.2 + */ +public class SingletonCollectionConverter extends CollectionConverter { + + private static final Class LIST = Collections.singletonList(Boolean.TRUE).getClass(); + private static final Class SET = Collections.singleton(Boolean.TRUE).getClass(); + + /** + * Construct a SingletonCollectionConverter. + * + * @param mapper the mapper + * @since 1.4.2 + */ + public SingletonCollectionConverter(Mapper mapper) { + super(mapper); + } + + public boolean canConvert(Class type) { + return LIST == type || SET == type; + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + reader.moveDown(); + Object item = readItem(reader, context, null); + reader.moveUp(); + return context.getRequiredType() == LIST + ? (Object)Collections.singletonList(item) + : (Object)Collections.singleton(item); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/SingletonMapConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/SingletonMapConverter.java new file mode 100644 index 0000000..5656374 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/SingletonMapConverter.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 11. October 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.collections; + +import java.util.Collections; + +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.mapper.Mapper; + +/** + * Converts a singleton map to XML, specifying an 'entry' + * element with 'key' and 'value' children. + *

Note: 'key' and 'value' is not the name of the generated tag. The + * children are serialized as normal elements and the implementation expects + * them in the order 'key'/'value'.

+ *

Supports Collections.singletonMap.

+ * + * @author Jörg Schaible + * @since 1.4.2 + */ +public class SingletonMapConverter extends MapConverter { + + private static final Class MAP = Collections.singletonMap(Boolean.TRUE, null).getClass(); + + /** + * Construct a SingletonMapConverter. + * @param mapper + * @since 1.4.2 + */ + public SingletonMapConverter(Mapper mapper) { + super(mapper); + } + + public boolean canConvert(Class type) { + return MAP == type; + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + reader.moveDown(); + reader.moveDown(); + Object key = readItem(reader, context, null); + reader.moveUp(); + + reader.moveDown(); + Object value = readItem(reader, context, null); + reader.moveUp(); + reader.moveUp(); + + return Collections.singletonMap(key, value); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeMapConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeMapConverter.java new file mode 100644 index 0000000..a79f4f5 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeMapConverter.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2010, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 08. May 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.collections; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.core.util.Fields; +import com.thoughtworks.xstream.core.util.HierarchicalStreams; +import com.thoughtworks.xstream.core.util.PresortedMap; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.lang.reflect.Field; +import java.util.Comparator; +import java.util.SortedMap; +import java.util.TreeMap; + +/** + * Converts a java.util.TreeMap to XML, and serializes + * the associated java.util.Comparator. The converter + * assumes that the entries in the XML are already sorted + * according the comparator. + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class TreeMapConverter extends MapConverter { + + private static final class NullComparator extends Mapper.Null implements Comparator { + public int compare(Object o1, Object o2) { + Comparable c1 = (Comparable)o1; + Comparable c2 = (Comparable)o2; + return c1.compareTo(o2); + } + } + + private final static Comparator NULL_MARKER = new NullComparator(); + private final static Field comparatorField = Fields.locate(TreeMap.class, Comparator.class, false); + + public TreeMapConverter(Mapper mapper) { + super(mapper, TreeMap.class); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + SortedMap sortedMap = (SortedMap) source; + marshalComparator(sortedMap.comparator(), writer, context); + super.marshal(source, writer, context); + } + + protected void marshalComparator(Comparator comparator, HierarchicalStreamWriter writer, + MarshallingContext context) { + if (comparator != null) { + writer.startNode("comparator"); + writer.addAttribute(mapper().aliasForSystemAttribute("class"), + mapper().serializedClass(comparator.getClass())); + context.convertAnother(comparator); + writer.endNode(); + } + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + TreeMap result = comparatorField != null ? new TreeMap() : null; + final Comparator comparator = unmarshalComparator(reader, context, result); + if (result == null) { + result = comparator == null ? new TreeMap() : new TreeMap(comparator); + } + populateTreeMap(reader, context, result, comparator); + return result; + } + + protected Comparator unmarshalComparator(HierarchicalStreamReader reader, + UnmarshallingContext context, TreeMap result) { + final Comparator comparator; + if (reader.hasMoreChildren()) { + reader.moveDown(); + if (reader.getNodeName().equals("comparator")) { + Class comparatorClass = HierarchicalStreams.readClassType(reader, mapper()); + comparator = (Comparator) context.convertAnother(result, comparatorClass); + } else if (reader.getNodeName().equals("no-comparator")) { // pre 1.4 format + comparator = null; + } else { + // we are already within the first entry + return NULL_MARKER; + } + reader.moveUp(); + } else { + comparator = null; + } + return comparator; + } + + protected void populateTreeMap(HierarchicalStreamReader reader, UnmarshallingContext context, + TreeMap result, Comparator comparator) { + boolean inFirstElement = comparator == NULL_MARKER; + if (inFirstElement) { + comparator = null; + } + SortedMap sortedMap = new PresortedMap(comparator != null && JVM.hasOptimizedTreeMapPutAll() ? comparator : null); + if (inFirstElement) { + // we are already within the first entry + putCurrentEntryIntoMap(reader, context, result, sortedMap); + reader.moveUp(); + } + populateMap(reader, context, result, sortedMap); + try { + if (JVM.hasOptimizedTreeMapPutAll()) { + if (comparator != null && comparatorField != null) { + comparatorField.set(result, comparator); + } + result.putAll(sortedMap); // internal optimization will not call comparator + } else if (comparatorField != null) { + comparatorField.set(result, sortedMap.comparator()); + result.putAll(sortedMap); // "sort" by index + comparatorField.set(result, comparator); + } else { + result.putAll(sortedMap); // will use comparator for already sorted map + } + } catch (final IllegalAccessException e) { + throw new ConversionException("Cannot set comparator of TreeMap", e); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java new file mode 100644 index 0000000..7e9e630 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2010, 2011, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 08. May 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.collections; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.core.util.Fields; +import com.thoughtworks.xstream.core.util.PresortedSet; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.lang.reflect.Field; +import java.util.AbstractList; +import java.util.Comparator; +import java.util.Map; +import java.util.SortedMap; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.TreeSet; + +/** + * Converts a java.util.TreeSet to XML, and serializes + * the associated java.util.Comparator. The converter + * assumes that the elements in the XML are already sorted + * according the comparator. + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class TreeSetConverter extends CollectionConverter { + private transient TreeMapConverter treeMapConverter; + private final static Field sortedMapField; + private final static Object constantValue; + static { + Object value = null; + sortedMapField = JVM.hasOptimizedTreeSetAddAll() ? Fields.locate(TreeSet.class, SortedMap.class, false) : null; + if (sortedMapField != null) { + TreeSet set = new TreeSet(); + set.add("1"); + set.add("2"); + + Map backingMap = null; + try { + backingMap = (Map)sortedMapField.get(set); + } catch (final IllegalAccessException e) { + // give up; + } + if (backingMap != null) { + Object[] values = backingMap.values().toArray(); + if (values[0] == values[1]) { + value = values[0]; + } + } + } else { + Field valueField = Fields.locate(TreeSet.class, Object.class, true); + if (valueField != null) { + try { + value = valueField.get(null); + } catch (final IllegalAccessException e) { + // give up; + } + } + } + constantValue = value; + } + + public TreeSetConverter(Mapper mapper) { + super(mapper, TreeSet.class); + readResolve(); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + SortedSet sortedSet = (SortedSet) source; + treeMapConverter.marshalComparator(sortedSet.comparator(), writer, context); + super.marshal(source, writer, context); + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + TreeSet result = null; + final TreeMap treeMap; + Comparator unmarshalledComparator = treeMapConverter.unmarshalComparator(reader, context, null); + boolean inFirstElement = unmarshalledComparator instanceof Mapper.Null; + Comparator comparator = inFirstElement ? null : unmarshalledComparator; + if (sortedMapField != null) { + TreeSet possibleResult = comparator == null ? new TreeSet() : new TreeSet(comparator); + Object backingMap = null; + try { + backingMap = sortedMapField.get(possibleResult); + } catch (IllegalAccessException e) { + throw new ConversionException("Cannot get backing map of TreeSet", e); + } + if (backingMap instanceof TreeMap) { + treeMap = (TreeMap)backingMap; + result = possibleResult; + } else { + treeMap = null; + } + } else { + treeMap = null; + } + if (treeMap == null) { + final PresortedSet set = new PresortedSet(comparator); + result = comparator == null ? new TreeSet() : new TreeSet(comparator); + if (inFirstElement) { + // we are already within the first element + addCurrentElementToCollection(reader, context, result, set); + reader.moveUp(); + } + populateCollection(reader, context, result, set); + if (set.size() > 0) { + result.addAll(set); // comparator will not be called if internally optimized + } + } else { + treeMapConverter.populateTreeMap(reader, context, treeMap, unmarshalledComparator); + } + return result; + } + + private Object readResolve() { + treeMapConverter = new TreeMapConverter(mapper()) { + + protected void populateMap(HierarchicalStreamReader reader, + UnmarshallingContext context, Map map, final Map target) { + populateCollection(reader, context, new AbstractList() { + public boolean add(Object object) { + return target.put(object, constantValue != null ? constantValue : object) != null; + } + + public Object get(int location) { + return null; + } + + public int size() { + return target.size(); + } + }); + } + + protected void putCurrentEntryIntoMap(HierarchicalStreamReader reader, UnmarshallingContext context, + Map map, Map target) { + Object key = readItem(reader, context, map); + target.put(key, key); + } + }; + return this; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/collections/package.html b/xstream/src/java/com/thoughtworks/xstream/converters/collections/package.html new file mode 100644 index 0000000..9d59acd --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/collections/package.html @@ -0,0 +1,17 @@ + + +

Converters for collection objects that write their items as +nested elements, such as arrays, Lists, Sets and Maps.

+ +

All the converters in this package are enabled by default.

+ diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumConverter.java new file mode 100644 index 0000000..4b4a2ba --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumConverter.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 18. March 2005 by Joe Walnes + */ + +// ***** READ THIS ***** +// This class will only compile with JDK 1.5.0 or above as it test Java enums. +// If you are using an earlier version of Java, just don't try to build this class. XStream should work fine without it. + +package com.thoughtworks.xstream.converters.enums; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; + +/** + * Converter for JDK 1.5 enums. Combined with EnumMapper this also deals with polymorphic enums. + * + * @author Eric Snell + * @author Bryan Coleman + */ +public class EnumConverter implements Converter { + + public boolean canConvert(Class type) { + return type.isEnum() || Enum.class.isAssignableFrom(type); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + writer.setValue(((Enum) source).name()); + } + + @SuppressWarnings("unchecked") + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + Class type = context.getRequiredType(); + if (type.getSuperclass() != Enum.class) { + type = type.getSuperclass(); // polymorphic enums + } + String name = reader.getValue(); + try { + return Enum.valueOf(type, name); + } catch (IllegalArgumentException e) { + // failed to find it, do a case insensitive match + for (Enum c : (Enum[])type.getEnumConstants()) + if (c.name().equalsIgnoreCase(name)) + return c; + // all else failed + throw e; + } + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumMapConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumMapConverter.java new file mode 100644 index 0000000..aaed8a3 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumMapConverter.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. April 2005 by Joe Walnes + */ + +// ***** READ THIS ***** +// This class will only compile with JDK 1.5.0 or above as it test Java enums. +// If you are using an earlier version of Java, just don't try to build this class. XStream should work fine without it. + +package com.thoughtworks.xstream.converters.enums; + +import com.thoughtworks.xstream.converters.collections.MapConverter; +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.mapper.Mapper; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.core.util.Fields; + +import java.util.EnumMap; +import java.lang.reflect.Field; + +/** + * Serializes an Java 5 EnumMap, including the type of Enum it's for. If a SecurityManager is set, the converter will only work with permissions + * for SecurityManager.checkPackageAccess, SecurityManager.checkMemberAccess(this, EnumSet.MEMBER) + * and ReflectPermission("suppressAccessChecks"). + * + * @author Joe Walnes + */ +public class EnumMapConverter extends MapConverter { + + private final static Field typeField = Fields.locate(EnumMap.class, Class.class, false); + + public EnumMapConverter(Mapper mapper) { + super(mapper); + } + + public boolean canConvert(Class type) { + return typeField != null && type == EnumMap.class; + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + Class type = (Class) Fields.read(typeField, source); + String attributeName = mapper().aliasForSystemAttribute("enum-type"); + if (attributeName != null) { + writer.addAttribute(attributeName, mapper().serializedClass(type)); + } + super.marshal(source, writer, context); + } + + @SuppressWarnings("unchecked") + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + String attributeName = mapper().aliasForSystemAttribute("enum-type"); + if (attributeName == null) { + throw new ConversionException("No EnumType specified for EnumMap"); + } + Class type = mapper().realClass(reader.getAttribute(attributeName)); + EnumMap map = new EnumMap(type); + populateMap(reader, context, map); + return map; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumSetConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumSetConverter.java new file mode 100644 index 0000000..2d39908 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumSetConverter.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. April 2005 by Joe Walnes + */ + +// ***** READ THIS ***** +// This class will only compile with JDK 1.5.0 or above as it test Java enums. +// If you are using an earlier version of Java, just don't try to build this class. XStream should work fine without it. + +package com.thoughtworks.xstream.converters.enums; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; +import com.thoughtworks.xstream.core.util.Fields; + +import java.lang.reflect.Field; +import java.util.EnumSet; +import java.util.Iterator; + +/** + * Serializes a Java 5 EnumSet. If a SecurityManager is set, the converter will only work with permissions + * for SecurityManager.checkPackageAccess, SecurityManager.checkMemberAccess(this, EnumSet.MEMBER) + * and ReflectPermission("suppressAccessChecks"). + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class EnumSetConverter implements Converter { + + private final static Field typeField = Fields.locate(EnumSet.class, Class.class, false); + private final Mapper mapper; + + public EnumSetConverter(Mapper mapper) { + this.mapper = mapper; + } + + public boolean canConvert(Class type) { + return typeField != null && EnumSet.class.isAssignableFrom(type); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + EnumSet set = (EnumSet) source; + Class enumTypeForSet = (Class) Fields.read(typeField, set); + String attributeName = mapper.aliasForSystemAttribute("enum-type"); + if (attributeName != null) { + writer.addAttribute(attributeName, mapper.serializedClass(enumTypeForSet)); + } + writer.setValue(joinEnumValues(set)); + } + + private String joinEnumValues(EnumSet set) { + boolean seenFirst = false; + StringBuffer result = new StringBuffer(); + for (Iterator iterator = set.iterator(); iterator.hasNext();) { + Enum value = (Enum) iterator.next(); + if (seenFirst) { + result.append(','); + } else { + seenFirst = true; + } + result.append(value.name()); + } + return result.toString(); + } + + @SuppressWarnings("unchecked") + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + String attributeName = mapper.aliasForSystemAttribute("enum-type"); + if (attributeName == null) { + throw new ConversionException("No EnumType specified for EnumSet"); + } + Class enumTypeForSet = mapper.realClass(reader.getAttribute(attributeName)); + EnumSet set = EnumSet.noneOf(enumTypeForSet); + String[] enumValues = reader.getValue().split(","); + for (int i = 0; i < enumValues.length; i++) { + String enumValue = enumValues[i]; + if(enumValue.length() > 0) { + set.add(Enum.valueOf(enumTypeForSet, enumValue)); + } + } + return set; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumSingleValueConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumSingleValueConverter.java new file mode 100644 index 0000000..eb668a2 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumSingleValueConverter.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2008, 2009, 2010, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 12. February 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.enums; + +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; + + +/** + * A single value converter for a special enum type. Converter is internally automatically + * instantiated for enum types. + * + * @author Jörg Schaible + * @since 1.3 + */ +public class EnumSingleValueConverter extends AbstractSingleValueConverter { + + private final Class enumType; + + public EnumSingleValueConverter(Class type) { + if (!Enum.class.isAssignableFrom(type) && type != Enum.class) { + throw new IllegalArgumentException("Converter can only handle defined enums"); + } + enumType = type; + } + + @Override + public boolean canConvert(Class type) { + return enumType.isAssignableFrom(type); + } + + @Override + public String toString(Object obj) { + return Enum.class.cast(obj).name(); + } + + @Override + public Object fromString(String str) { + @SuppressWarnings("unchecked") + Enum result = Enum.valueOf(enumType, str); + return result; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumToStringConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumToStringConverter.java new file mode 100644 index 0000000..90fea84 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/enums/EnumToStringConverter.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 14. March 2013 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.enums; + +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; + + +/** + * A single value converter for a special enum type using its string representation. + * + * @author Jörg Schaible + * @since 1.4.5 + */ +public class EnumToStringConverter> extends AbstractSingleValueConverter { + + private final Class enumType; + private final Map strings; + private final EnumMap values; + + public EnumToStringConverter(Class type) { + this(type, extractStringMap(type), null); + } + + public EnumToStringConverter(Class type, Map strings) { + this(type, strings, buildValueMap(type, strings)); + } + + private EnumToStringConverter( + Class type, Map strings, EnumMap values) { + enumType = type; + this.strings = strings; + this.values = values; + } + + private static > Map extractStringMap(Class type) { + checkType(type); + EnumSet values = EnumSet.allOf(type); + Map strings = new HashMap(values.size()); + for (T value : values) { + if (strings.put(value.toString(), value) != null) { + throw new IllegalArgumentException("Enum type " + + type.getName() + + " does not have unique string representations for its values"); + } + } + return strings; + } + + private static void checkType(Class type) { + if (!Enum.class.isAssignableFrom(type) && type != Enum.class) { + throw new IllegalArgumentException("Converter can only handle enum types"); + } + } + + private static > EnumMap buildValueMap(Class type, + Map strings) { + EnumMap values = new EnumMap(type); + for (Map.Entry entry : strings.entrySet()) { + values.put(entry.getValue(), entry.getKey()); + } + return values; + } + + @Override + public boolean canConvert(Class type) { + return enumType.isAssignableFrom(type); + } + + @Override + public String toString(Object obj) { + Enum value = Enum.class.cast(obj); + return values == null ? value.toString() : values.get(value); + } + + @Override + public Object fromString(String str) { + if (str == null) { + return null; + } + T result = strings.get(str); + if (result == null) { + throw new ConversionException("Invalid string representation for enum type " + + enumType.getName() + + ": <" + + str + + ">"); + } + return result; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/CharsetConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/CharsetConverter.java new file mode 100644 index 0000000..ca90bd1 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/CharsetConverter.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. April 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; + +import java.nio.charset.Charset; + +/** + * Converts a java.nio.charset.Carset to a string. + * + * @author Jörg Schaible + * @since 1.2 + */ +public class CharsetConverter extends AbstractSingleValueConverter { + + public boolean canConvert(Class type) { + return Charset.class.isAssignableFrom(type); + } + + public String toString(Object obj) { + return obj == null ? null : ((Charset)obj).name(); + } + + + public Object fromString(String str) { + return Charset.forName(str); + } +} \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ColorConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ColorConverter.java new file mode 100644 index 0000000..f7de926 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ColorConverter.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2003, 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. October 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + +import java.awt.Color; +import java.util.HashMap; +import java.util.Map; + +/** + * Converts a java.awt.Color to XML, using four nested elements: + * red, green, blue, alpha. + * + * @author Joe Walnes + */ +public class ColorConverter implements Converter { + + public boolean canConvert(Class type) { + // String comparison is used here because Color.class loads the class which in turns instantiates AWT, + // which is nasty if you don't want it. + return type.getName().equals("java.awt.Color"); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + Color color = (Color) source; + write("red", color.getRed(), writer); + write("green", color.getGreen(), writer); + write("blue", color.getBlue(), writer); + write("alpha", color.getAlpha(), writer); + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + Map elements = new HashMap(); + while (reader.hasMoreChildren()) { + reader.moveDown(); + elements.put(reader.getNodeName(), Integer.valueOf(reader.getValue())); + reader.moveUp(); + } + return new Color(((Integer) elements.get("red")).intValue(), + ((Integer) elements.get("green")).intValue(), + ((Integer) elements.get("blue")).intValue(), + ((Integer) elements.get("alpha")).intValue()); + } + + private void write(String fieldName, int value, HierarchicalStreamWriter writer) { + ExtendedHierarchicalStreamWriterHelper.startNode(writer, fieldName, int.class); + writer.setValue(String.valueOf(value)); + writer.endNode(); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/CurrencyConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/CurrencyConverter.java new file mode 100644 index 0000000..1609f49 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/CurrencyConverter.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. July 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import java.util.Currency; + +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; + +/** + * Converts a java.util.Currency to String. Despite the name of this class, it has nothing to do with converting + * currencies between exchange rates! It makes sense in the context of XStream. + * + * @author Jose A. Illescas + * @author Joe Walnes + */ +public class CurrencyConverter extends AbstractSingleValueConverter { + + public boolean canConvert(Class type) { + return type.equals(Currency.class); + } + + public Object fromString(String str) { + return Currency.getInstance(str); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/DurationConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/DurationConverter.java new file mode 100644 index 0000000..e7f906d --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/DurationConverter.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2007, 2008, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 21.09.2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.Duration; + + +/** + * A Converter for the XML Schema datatype duration and the Java type + * {@link Duration}. The implementation uses a {@link DatatypeFactory} to create Duration + * objects. If no factory is provided and the instantiation of the internal factory fails with a + * {@link DatatypeConfigurationException}, the converter will not claim the responsibility for + * Duration objects. + * + * @author John Kristian + * @author Jörg Schaible + * @since 1.3 + */ +public class DurationConverter extends AbstractSingleValueConverter { + private final DatatypeFactory factory; + + public DurationConverter() { + this(new Object() { + DatatypeFactory getFactory() { + try { + return DatatypeFactory.newInstance(); + } catch (final DatatypeConfigurationException e) { + return null; + } + } + }.getFactory()); + } + + public DurationConverter(DatatypeFactory factory) { + this.factory = factory; + } + + public boolean canConvert(Class c) { + return factory != null && Duration.class.isAssignableFrom(c); + } + + public Object fromString(String s) { + return factory.newDuration(s); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/DynamicProxyConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/DynamicProxyConverter.java new file mode 100644 index 0000000..9700c9a --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/DynamicProxyConverter.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2010, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 25. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.core.ClassLoaderReference; +import com.thoughtworks.xstream.core.util.Fields; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.DynamicProxyMapper; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.List; + +/** + * Converts a dynamic proxy to XML, storing the implemented + * interfaces and handler. + * + * @author Joe Walnes + */ +public class DynamicProxyConverter implements Converter { + + private ClassLoaderReference classLoaderReference; + private Mapper mapper; + private static final Field HANDLER = Fields.locate(Proxy.class, InvocationHandler.class, false); + private static final InvocationHandler DUMMY = new InvocationHandler() { + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + return null; + } + }; + + /** + * @deprecated As of 1.4.5 use {@link #DynamicProxyConverter(Mapper, ClassLoaderReference)} + */ + public DynamicProxyConverter(Mapper mapper) { + this(mapper, DynamicProxyConverter.class.getClassLoader()); + } + + /** + * Construct a DynamicProxyConverter. + * @param mapper the Mapper chain + * @param classLoaderReference the reference to the {@link ClassLoader} of the XStream instance + * @since 1.4.5 + */ + public DynamicProxyConverter(Mapper mapper, ClassLoaderReference classLoaderReference) { + this.classLoaderReference = classLoaderReference; + this.mapper = mapper; + } + + /** + * @deprecated As of 1.4.5 use {@link #DynamicProxyConverter(Mapper, ClassLoaderReference)} + */ + public DynamicProxyConverter(Mapper mapper, ClassLoader classLoader) { + this(mapper,new ClassLoaderReference(classLoader)); + } + + public boolean canConvert(Class type) { + return type.equals(DynamicProxyMapper.DynamicProxy.class) || Proxy.isProxyClass(type); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + InvocationHandler invocationHandler = Proxy.getInvocationHandler(source); + addInterfacesToXml(source, writer); + writer.startNode("handler"); + String attributeName = mapper.aliasForSystemAttribute("class"); + if (attributeName != null) { + writer.addAttribute(attributeName, mapper.serializedClass(invocationHandler.getClass())); + } + context.convertAnother(invocationHandler); + writer.endNode(); + } + + private void addInterfacesToXml(Object source, HierarchicalStreamWriter writer) { + Class[] interfaces = source.getClass().getInterfaces(); + for (int i = 0; i < interfaces.length; i++) { + Class currentInterface = interfaces[i]; + writer.startNode("interface"); + writer.setValue(mapper.serializedClass(currentInterface)); + writer.endNode(); + } + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + List interfaces = new ArrayList(); + InvocationHandler handler = null; + Class handlerType = null; + while (reader.hasMoreChildren()) { + reader.moveDown(); + String elementName = reader.getNodeName(); + if (elementName.equals("interface")) { + interfaces.add(mapper.realClass(reader.getValue())); + } else if (elementName.equals("handler")) { + String attributeName = mapper.aliasForSystemAttribute("class"); + if (attributeName != null) { + handlerType = mapper.realClass(reader.getAttribute(attributeName)); + break; + } + } + reader.moveUp(); + } + if (handlerType == null) { + throw new ConversionException("No InvocationHandler specified for dynamic proxy"); + } + Class[] interfacesAsArray = new Class[interfaces.size()]; + interfaces.toArray(interfacesAsArray); + Object proxy = null; + if (HANDLER != null) { // we will not be able to resolve references to the proxy + proxy = Proxy.newProxyInstance(classLoaderReference.getReference(), interfacesAsArray, DUMMY); + } + handler = (InvocationHandler) context.convertAnother(proxy, handlerType); + reader.moveUp(); + if (HANDLER != null) { + Fields.write(HANDLER, proxy, handler); + } else { + proxy = Proxy.newProxyInstance(classLoaderReference.getReference(), interfacesAsArray, handler); + } + return proxy; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/EncodedByteArrayConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/EncodedByteArrayConverter.java new file mode 100644 index 0000000..6eb815d --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/EncodedByteArrayConverter.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2010 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.converters.basic.ByteConverter; +import com.thoughtworks.xstream.core.util.Base64Encoder; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Converts a byte array to a single Base64 encoding string. + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class EncodedByteArrayConverter implements Converter, SingleValueConverter { + + private static final Base64Encoder base64 = new Base64Encoder(); + private static final ByteConverter byteConverter = new ByteConverter(); + + public boolean canConvert(Class type) { + return type.isArray() && type.getComponentType().equals(byte.class); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + writer.setValue(toString(source)); + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + String data = reader.getValue(); // needs to be called before hasMoreChildren. + if (!reader.hasMoreChildren()) { + return fromString(data); + } else { + // backwards compatibility ... try to unmarshal byte arrays that haven't been encoded + return unmarshalIndividualByteElements(reader, context); + } + } + + private Object unmarshalIndividualByteElements(HierarchicalStreamReader reader, UnmarshallingContext context) { + List bytes = new ArrayList(); // have to create a temporary list because don't know the size of the array + boolean firstIteration = true; + while (firstIteration || reader.hasMoreChildren()) { // hangover from previous hasMoreChildren + reader.moveDown(); + bytes.add(byteConverter.fromString(reader.getValue())); + reader.moveUp(); + firstIteration = false; + } + // copy into real array + byte[] result = new byte[bytes.size()]; + int i = 0; + for (Iterator iterator = bytes.iterator(); iterator.hasNext();) { + Byte b = (Byte) iterator.next(); + result[i] = b.byteValue(); + i++; + } + return result; + } + + public String toString(Object obj) { + return base64.encode((byte[]) obj); + } + + public Object fromString(String str) { + return base64.decode(str); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/FileConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/FileConverter.java new file mode 100644 index 0000000..6003465 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/FileConverter.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. January 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; + +import java.io.File; + +/** + * This converter will take care of storing and retrieving File with either + * an absolute path OR a relative path depending on how they were created. + * + * @author Joe Walnes + */ +public class FileConverter extends AbstractSingleValueConverter { + + public boolean canConvert(Class type) { + return type.equals(File.class); + } + + public Object fromString(String str) { + return new File(str); + } + + public String toString(Object obj) { + return ((File) obj).getPath(); + } + +} \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/FontConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/FontConverter.java new file mode 100644 index 0000000..c1703d8 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/FontConverter.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 08. July 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + +import javax.swing.plaf.FontUIResource; + +import java.awt.Font; +import java.awt.font.TextAttribute; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +public class FontConverter implements Converter { + + private final SingleValueConverter textAttributeConverter; + private final Mapper mapper; + + /** + * Constructs a FontConverter. + * @deprecated As of 1.4.5 + */ + public FontConverter() { + this(null); + } + + /** + * Constructs a FontConverter. + * @param mapper + * @since 1.4.5 + */ + public FontConverter(Mapper mapper) { + this.mapper = mapper; + if (mapper == null) { + textAttributeConverter = null; + } else { + textAttributeConverter = new TextAttributeConverter(); + } + } + + public boolean canConvert(Class type) { + // String comparison is used here because Font.class loads the class which in turns instantiates AWT, + // which is nasty if you don't want it. + return type.getName().equals("java.awt.Font") || type.getName().equals("javax.swing.plaf.FontUIResource"); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, + MarshallingContext context) { + Font font = (Font)source; + Map attributes = font.getAttributes(); + if (mapper != null) { + String classAlias = mapper.aliasForSystemAttribute("class"); + for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) { + Map.Entry entry = (Map.Entry)iter.next(); + String name = textAttributeConverter.toString(entry.getKey()); + Object value = entry.getValue(); + Class type = value != null ? value.getClass() : Mapper.Null.class; + ExtendedHierarchicalStreamWriterHelper.startNode(writer, name, type); + writer.addAttribute(classAlias, mapper.serializedClass(type)); + if (value != null) { + context.convertAnother(value); + } + writer.endNode(); + } + } else { + writer.startNode("attributes"); // + context.convertAnother(attributes); + writer.endNode(); // + } + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + final Map attributes; + if (reader.hasMoreChildren()) { + reader.moveDown(); + if (!reader.getNodeName().equals("attributes")) { + String classAlias = mapper.aliasForSystemAttribute("class"); + attributes = new HashMap(); + do { + if (!attributes.isEmpty()) { + reader.moveDown(); + } + Class type = mapper.realClass(reader.getAttribute(classAlias)); + TextAttribute attribute = (TextAttribute)textAttributeConverter.fromString(reader.getNodeName()); + Object value = type == Mapper.Null.class ? null : context.convertAnother(null, type); + attributes.put(attribute, value); + reader.moveUp(); + } while(reader.hasMoreChildren()); + } else { + // in + attributes = (Map)context.convertAnother(null, Map.class); + reader.moveUp(); // out of + } + } else { + attributes = Collections.EMPTY_MAP; + } + if (!JVM.is16()) { + for (Iterator iter = attributes.values().iterator(); iter.hasNext(); ) { + if (iter.next() == null) { + iter.remove(); + } + } + } + Font font = Font.getFont(attributes); + if (context.getRequiredType() == FontUIResource.class) { + return new FontUIResource(font); + } else { + return font; + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/GregorianCalendarConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/GregorianCalendarConverter.java new file mode 100644 index 0000000..f8ed612 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/GregorianCalendarConverter.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. July 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +/** + * Converts a java.util.GregorianCalendar to XML. Note that although it currently only contains one field, it nests + * it inside a child element, to allow for other fields to be stored in the future. + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class GregorianCalendarConverter implements Converter { + + public boolean canConvert(Class type) { + return type.equals(GregorianCalendar.class); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + GregorianCalendar calendar = (GregorianCalendar) source; + ExtendedHierarchicalStreamWriterHelper.startNode(writer, "time", long.class); + long timeInMillis = calendar.getTime().getTime(); // calendar.getTimeInMillis() not available under JDK 1.3 + writer.setValue(String.valueOf(timeInMillis)); + writer.endNode(); + ExtendedHierarchicalStreamWriterHelper.startNode(writer, "timezone", String.class); + writer.setValue(calendar.getTimeZone().getID()); + writer.endNode(); + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + reader.moveDown(); + long timeInMillis = Long.parseLong(reader.getValue()); + reader.moveUp(); + final String timeZone; + if (reader.hasMoreChildren()) { + reader.moveDown(); + timeZone = reader.getValue(); + reader.moveUp(); + } else { // backward compatibility to XStream 1.1.2 and below + timeZone = TimeZone.getDefault().getID(); + } + + GregorianCalendar result = new GregorianCalendar(); + result.setTimeZone(TimeZone.getTimeZone(timeZone)); + result.setTime(new Date(timeInMillis)); // calendar.setTimeInMillis() not available under JDK 1.3 + + return result; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601DateConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601DateConverter.java new file mode 100644 index 0000000..67d03e2 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601DateConverter.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. November 2004 by Mauro Talevi + */ +package com.thoughtworks.xstream.converters.extended; + +import java.util.Calendar; +import java.util.Date; + + +/** + * A DateConverter conforming to the ISO8601 standard. + * http://www.iso.ch/iso/en/CatalogueDetailPage.CatalogueDetail?CSNUMBER=26780 + * + * @author Mauro Talevi + * @author Jörg Schaible + */ +public class ISO8601DateConverter extends ISO8601GregorianCalendarConverter { + + public boolean canConvert(Class type) { + return type.equals(Date.class); + } + + public Object fromString(String str) { + return ((Calendar)super.fromString(str)).getTime(); + } + + public String toString(Object obj) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime((Date)obj); + return super.toString(calendar); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverter.java new file mode 100644 index 0000000..1d0da42 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverter.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2011, 2013, 2014, 2015 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. October 2005 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; + +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.TimeZone; + + +/** + * A GregorianCalendarConverter conforming to the ISO8601 standard. The converter will always + * serialize the calendar value in UTC and deserialize it to a value in the current default time + * zone. + * + * @author Mauro Talevi + * @author Jörg Schaible + * @see ISO 8601 + * @since 1.1.3 + */ +public class ISO8601GregorianCalendarConverter extends AbstractSingleValueConverter { + private static final DateTimeFormatter[] formattersUTC = new DateTimeFormatter[]{ + ISODateTimeFormat.dateTime(), + ISODateTimeFormat.dateTimeNoMillis(), + ISODateTimeFormat.basicDateTime(), + ISODateTimeFormat.basicOrdinalDateTime(), + ISODateTimeFormat.basicOrdinalDateTimeNoMillis(), + ISODateTimeFormat.basicTime(), + ISODateTimeFormat.basicTimeNoMillis(), + ISODateTimeFormat.basicTTime(), + ISODateTimeFormat.basicTTimeNoMillis(), + ISODateTimeFormat.basicWeekDateTime(), + ISODateTimeFormat.basicWeekDateTimeNoMillis(), + ISODateTimeFormat.ordinalDateTime(), + ISODateTimeFormat.ordinalDateTimeNoMillis(), + ISODateTimeFormat.time(), + ISODateTimeFormat.timeNoMillis(), + ISODateTimeFormat.tTime(), + ISODateTimeFormat.tTimeNoMillis(), + ISODateTimeFormat.weekDateTime(), + ISODateTimeFormat.weekDateTimeNoMillis() + }; + private static final DateTimeFormatter[] formattersNoUTC = new DateTimeFormatter[]{ + ISODateTimeFormat.basicDate(), + ISODateTimeFormat.basicOrdinalDate(), + ISODateTimeFormat.basicWeekDate(), + ISODateTimeFormat.date(), + ISODateTimeFormat.dateHour(), + ISODateTimeFormat.dateHourMinute(), + ISODateTimeFormat.dateHourMinuteSecond(), + ISODateTimeFormat.dateHourMinuteSecondFraction(), + ISODateTimeFormat.dateHourMinuteSecondMillis(), + ISODateTimeFormat.hour(), + ISODateTimeFormat.hourMinute(), + ISODateTimeFormat.hourMinuteSecond(), + ISODateTimeFormat.hourMinuteSecondFraction(), + ISODateTimeFormat.hourMinuteSecondMillis(), + ISODateTimeFormat.ordinalDate(), + ISODateTimeFormat.weekDate(), + ISODateTimeFormat.year(), + ISODateTimeFormat.yearMonth(), + ISODateTimeFormat.yearMonthDay(), + ISODateTimeFormat.weekyear(), + ISODateTimeFormat.weekyearWeek(), + ISODateTimeFormat.weekyearWeekDay() + }; + + public boolean canConvert(Class type) { + return type.equals(GregorianCalendar.class); + } + + public Object fromString(String str) { + for (int i = 0; i < formattersUTC.length; i++ ) { + DateTimeFormatter formatter = formattersUTC[i]; + try { + DateTime dt = formatter.parseDateTime(str); + Calendar calendar = dt.toGregorianCalendar(); + calendar.setTimeZone(TimeZone.getDefault()); + return calendar; + } catch (IllegalArgumentException e) { + // try with next formatter + } + } + final DateTimeZone dateTimeZone = DateTimeZone.forTimeZone(TimeZone.getDefault()); + for (int i = 0; i < formattersNoUTC.length; i++ ) { + try { + final DateTimeFormatter formatter = formattersNoUTC[i].withZone(dateTimeZone); + final DateTime dt = formatter.parseDateTime(str); + final Calendar calendar = dt.toGregorianCalendar(); + calendar.setTimeZone(TimeZone.getDefault()); + return calendar; + } catch (IllegalArgumentException e) { + // try with next formatter + } + } + throw new ConversionException("Cannot parse date " + str); + } + + public String toString(Object obj) { + DateTime dt = new DateTime(obj); + return dt.toString(formattersUTC[0]); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601SqlTimestampConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601SqlTimestampConverter.java new file mode 100644 index 0000000..fbecf39 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ISO8601SqlTimestampConverter.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. October 2005 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.extended; + +import java.sql.Timestamp; +import java.util.Date; + + +/** + * A SqlTimestampConverter conforming to the ISO8601 standard. + * http://www.iso.ch/iso/en/CatalogueDetailPage.CatalogueDetail?CSNUMBER=26780 + * + * @author Jörg Schaible + * @since 1.1.3 + */ +public class ISO8601SqlTimestampConverter extends ISO8601DateConverter { + + private final static String PADDING = "000000000"; + + public boolean canConvert(Class type) { + return type.equals(Timestamp.class); + } + + public Object fromString(String str) { + final int idxFraction = str.lastIndexOf('.'); + int nanos = 0; + if (idxFraction > 0) { + int idx; + for (idx = idxFraction + 1; Character.isDigit(str.charAt(idx)); ++idx) + ; + nanos = Integer.parseInt(str.substring(idxFraction + 1, idx)); + str = str.substring(0, idxFraction) + str.substring(idx); + } + final Date date = (Date)super.fromString(str); + final Timestamp timestamp = new Timestamp(date.getTime()); + timestamp.setNanos(nanos); + return timestamp; + } + + public String toString(Object obj) { + final Timestamp timestamp = (Timestamp)obj; + String str = super.toString(new Date((timestamp.getTime() / 1000) * 1000)); + final String nanos = String.valueOf(timestamp.getNanos()); + final int idxFraction = str.lastIndexOf('.'); + str = str.substring(0, idxFraction + 1) + + PADDING.substring(nanos.length()) + + nanos + + str.substring(idxFraction + 4); + return str; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaClassConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaClassConverter.java new file mode 100644 index 0000000..ed77196 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaClassConverter.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. April 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; +import com.thoughtworks.xstream.core.ClassLoaderReference; +import com.thoughtworks.xstream.mapper.CannotResolveClassException; +import com.thoughtworks.xstream.mapper.DefaultMapper; +import com.thoughtworks.xstream.mapper.Mapper; + +/** + * Converts a java.lang.Class to XML. + * + * @author Aslak Hellesøy + * @author Joe Walnes + * @author Matthew Sandoz + * @author Jörg Schaible + */ +public class JavaClassConverter extends AbstractSingleValueConverter { + + private Mapper mapper; + + /** + * Construct a JavaClassConverter. + * @param classLoaderReference the reference to the {@link ClassLoader} of the XStream instance + * @since 1.4.5 + */ + public JavaClassConverter(ClassLoaderReference classLoaderReference) { + this(new DefaultMapper(classLoaderReference)); + } + + /** + * @deprecated As of 1.4.5 use {@link #JavaClassConverter(ClassLoaderReference)} + */ + public JavaClassConverter(ClassLoader classLoader) { + this(new ClassLoaderReference(classLoader)); + } + + /** + * Construct a JavaClassConverter that uses a provided mapper. Depending on the mapper + * chain it will not only be used to load classes, but also to support type aliases. + * @param mapper to use + * @since 1.4.5 + */ + protected JavaClassConverter(Mapper mapper) { + this.mapper = mapper; + } + + public boolean canConvert(Class clazz) { + return Class.class.equals(clazz); // :) + } + + public String toString(Object obj) { + return mapper.serializedClass(((Class) obj)); + } + + public Object fromString(String str) { + try { + return mapper.realClass(str); + } catch (CannotResolveClassException e) { + throw new ConversionException("Cannot load java class " + str, e.getCause()); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaFieldConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaFieldConverter.java new file mode 100644 index 0000000..793a872 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaFieldConverter.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2009, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 17. April 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.core.ClassLoaderReference; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.DefaultMapper; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.lang.reflect.Field; + +/** + * Converts a java.lang.reflect.Field to XML. + * + * @author Jörg Schaible + */ +public class JavaFieldConverter implements Converter { + + private final SingleValueConverter javaClassConverter; + private final Mapper mapper; + + /** + * Construct a JavaFieldConverter. + * @param classLoaderReference the reference to the {@link ClassLoader} of the XStream instance + * @since 1.4.5 + */ + public JavaFieldConverter(ClassLoaderReference classLoaderReference) { + this(new JavaClassConverter(classLoaderReference), new DefaultMapper(classLoaderReference)); + } + + /** + * @deprecated As of 1.4.5 use {@link #JavaFieldConverter(ClassLoaderReference)} + */ + public JavaFieldConverter(ClassLoader classLoader) { + this(new ClassLoaderReference(classLoader)); + } + + /** + * Construct a JavaFieldConverter. Depending on the mapper chain the converter will also respect aliases. + * @param javaClassConverter the converter to use + * @param mapper to use + * @since 1.4.5 + */ + protected JavaFieldConverter(SingleValueConverter javaClassConverter, Mapper mapper) { + this.javaClassConverter = javaClassConverter; + this.mapper = mapper; + } + + public boolean canConvert(Class type) { + return type.equals(Field.class); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + Field field = (Field) source; + Class type = field.getDeclaringClass(); + + writer.startNode("name"); + writer.setValue(mapper.serializedMember(type, field.getName())); + writer.endNode(); + + writer.startNode("clazz"); + writer.setValue(javaClassConverter.toString(type)); + writer.endNode(); + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + String methodName = null; + String declaringClassName = null; + + while((methodName == null || declaringClassName == null) && reader.hasMoreChildren()) { + reader.moveDown(); + + if (reader.getNodeName().equals("name")) { + methodName = reader.getValue(); + } else if (reader.getNodeName().equals("clazz")) { + declaringClassName = reader.getValue(); + } + reader.moveUp(); + } + + Class declaringClass = (Class)javaClassConverter.fromString(declaringClassName); + try { + return declaringClass.getDeclaredField(mapper.realMember(declaringClass, methodName)); + } catch (NoSuchFieldException e) { + throw new ConversionException(e); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaMethodConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaMethodConverter.java new file mode 100644 index 0000000..b91d2e9 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/JavaMethodConverter.java @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. April 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.core.ClassLoaderReference; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +/** + * Converts a java.lang.reflect.Method to XML. + * + * @author Aslak Hellesøy + * @author Jörg Schaible + */ +public class JavaMethodConverter implements Converter { + + private final SingleValueConverter javaClassConverter; + + /** + * Construct a JavaMethodConverter. + * @param classLoaderReference the reference to the {@link ClassLoader} of the XStream instance + * @since 1.4.5 + */ + public JavaMethodConverter(ClassLoaderReference classLoaderReference) { + this(new JavaClassConverter(classLoaderReference)); + } + + /** + * @deprecated As of 1.4.5 use {@link #JavaMethodConverter(ClassLoaderReference)} + */ + public JavaMethodConverter(ClassLoader classLoader) { + this(new ClassLoaderReference(classLoader)); + } + + /** + * Construct a JavaMethodConverter. + * @param javaClassConverter the converter to use + * @since 1.4.5 + */ + protected JavaMethodConverter(SingleValueConverter javaClassConverter) { + this.javaClassConverter = javaClassConverter; + } + + public boolean canConvert(Class type) { + return type.equals(Method.class) || type.equals(Constructor.class); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + if (source instanceof Method) { + Method method = (Method) source; + String declaringClassName = javaClassConverter.toString(method.getDeclaringClass()); + marshalMethod(writer, declaringClassName, method.getName(), method.getParameterTypes()); + } else { + Constructor method = (Constructor) source; + String declaringClassName = javaClassConverter.toString(method.getDeclaringClass()); + marshalMethod(writer, declaringClassName, null, method.getParameterTypes()); + } + } + + private void marshalMethod(HierarchicalStreamWriter writer, String declaringClassName, String methodName, Class[] parameterTypes) { + + writer.startNode("class"); + writer.setValue(declaringClassName); + writer.endNode(); + + if (methodName != null) { + // it's a method and not a ctor + writer.startNode("name"); + writer.setValue(methodName); + writer.endNode(); + } + + writer.startNode("parameter-types"); + for (int i = 0; i < parameterTypes.length; i++) { + writer.startNode("class"); + writer.setValue(javaClassConverter.toString(parameterTypes[i])); + writer.endNode(); + } + writer.endNode(); + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + try { + boolean isMethodNotConstructor = context.getRequiredType().equals(Method.class); + + reader.moveDown(); + String declaringClassName = reader.getValue(); + Class declaringClass = (Class)javaClassConverter.fromString(declaringClassName); + reader.moveUp(); + + String methodName = null; + if (isMethodNotConstructor) { + reader.moveDown(); + methodName = reader.getValue(); + reader.moveUp(); + } + + reader.moveDown(); + List parameterTypeList = new ArrayList(); + while (reader.hasMoreChildren()) { + reader.moveDown(); + String parameterTypeName = reader.getValue(); + parameterTypeList.add(javaClassConverter.fromString(parameterTypeName)); + reader.moveUp(); + } + Class[] parameterTypes = (Class[]) parameterTypeList.toArray(new Class[parameterTypeList.size()]); + reader.moveUp(); + + if (isMethodNotConstructor) { + return declaringClass.getDeclaredMethod(methodName, parameterTypes); + } else { + return declaringClass.getDeclaredConstructor(parameterTypes); + } + } catch (NoSuchMethodException e) { + throw new ConversionException(e); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/LocaleConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/LocaleConverter.java new file mode 100644 index 0000000..bcd9f83 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/LocaleConverter.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. Julyl 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; + +import java.util.Locale; + +/** + * Converts a java.util.Locale to a string. + * + * @author Jose A. Illescas + * @author Joe Walnes + */ +public class LocaleConverter extends AbstractSingleValueConverter { + + public boolean canConvert(Class type) { + return type.equals(Locale.class); + } + + public Object fromString(String str) { + int[] underscorePositions = underscorePositions(str); + String language, country, variant; + if (underscorePositions[0] == -1) { // "language" + language = str; + country = ""; + variant = ""; + } else if (underscorePositions[1] == -1) { // "language_country" + language = str.substring(0, underscorePositions[0]); + country = str.substring(underscorePositions[0] + 1); + variant = ""; + } else { // "language_country_variant" + language = str.substring(0, underscorePositions[0]); + country = str.substring(underscorePositions[0] + 1, underscorePositions[1]); + variant = str.substring(underscorePositions[1] + 1); + } + return new Locale(language, country, variant); + } + + private int[] underscorePositions(String in) { + int[] result = new int[2]; + for (int i = 0; i < result.length; i++) { + int last = i == 0 ? 0 : result[i - 1]; + result[i] = in.indexOf('_', last + 1); + } + return result; + } + +} \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/LookAndFeelConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/LookAndFeelConverter.java new file mode 100644 index 0000000..2315a33 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/LookAndFeelConverter.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2007, 2008, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 08.12.2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; +import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; +import com.thoughtworks.xstream.mapper.Mapper; + +import javax.swing.LookAndFeel; + +import java.io.NotSerializableException; + + +/** + * A converter for Swing LookAndFeel implementations. The JDK's implementations are serializable + * for historical reasons but will throw a {@link NotSerializableException} in their writeObject + * method. Therefore XStream will use an implementation based on the ReflectionConverter. + * + * @author Jörg Schaible + * @since 1.3 + */ +public class LookAndFeelConverter extends ReflectionConverter { + + /** + * Constructs a LookAndFeelConverter. + * + * @param mapper the mapper + * @param reflectionProvider the reflection provider + * @since 1.3 + */ + public LookAndFeelConverter(Mapper mapper, ReflectionProvider reflectionProvider) { + super(mapper, reflectionProvider); + } + + public boolean canConvert(Class type) { + return LookAndFeel.class.isAssignableFrom(type) && canAccess(type); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedArrayConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedArrayConverter.java new file mode 100644 index 0000000..3312330 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedArrayConverter.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. December 2013 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.extended; + +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.List; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.core.util.HierarchicalStreams; +import com.thoughtworks.xstream.core.util.Primitives; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + +/** + * An array converter that uses predefined names for its items. + *

+ * To be used as local converter. + *

+ * + * @author Jörg Schaible + * @since 1.4.6 + */ +public class NamedArrayConverter implements Converter { + + private final Class arrayType; + private final String itemName; + private final Mapper mapper; + + /** + * Construct a NamedArrayConverter. + * @param arrayType + * @param mapper + * @param itemName + * @since 1.4.6 + */ + public NamedArrayConverter(final Class arrayType, final Mapper mapper, final String itemName) { + if (!arrayType.isArray()) { + throw new IllegalArgumentException(arrayType.getName() + " is not an array"); + } + this.arrayType = arrayType; + this.mapper = mapper; + this.itemName = itemName; + } + + public boolean canConvert(final Class type) { + return type == arrayType; + } + + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final int length = Array.getLength(source); + for (int i = 0; i < length; ++i) { + final Object item = Array.get(source, i); + final Class itemType = item == null + ? Mapper.Null.class + : arrayType.getComponentType().isPrimitive() + ? Primitives.unbox(item.getClass()) + : item.getClass(); + ExtendedHierarchicalStreamWriterHelper.startNode(writer, itemName, itemType); + if (!itemType.equals(arrayType.getComponentType())) { + final String attributeName = mapper.aliasForSystemAttribute("class"); + if (attributeName != null) { + writer.addAttribute(attributeName, mapper.serializedClass(itemType)); + } + } + if (item != null) { + context.convertAnother(item); + } + writer.endNode(); + } + } + + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + final List list = new ArrayList(); + while (reader.hasMoreChildren()) { + reader.moveDown(); + final Object item; + final String className = HierarchicalStreams.readClassAttribute(reader, mapper); + final Class itemType = className == null ? arrayType.getComponentType() : mapper.realClass(className); + if (Mapper.Null.class.equals(itemType)) { + item = null; + } else { + item = context.convertAnother(null, itemType); + } + list.add(item); + reader.moveUp(); + } + final Object array = Array.newInstance(arrayType.getComponentType(), list.size()); + for (int i = 0; i < list.size(); ++i) { + Array.set(array, i, list.get(i)); + } + return array; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedCollectionConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedCollectionConverter.java new file mode 100644 index 0000000..3e5b798 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedCollectionConverter.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 19. September 2013 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.converters.collections.CollectionConverter; +import com.thoughtworks.xstream.core.util.HierarchicalStreams; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + + +/** + * A collection converter that uses predefined names for its items. + *

+ * To be used as local converter. Note, suppress the usage of the implicit type argument, if + * registered with annotation. + *

+ * + * @author Jörg Schaible + * @since 1.4.5 + */ +public class NamedCollectionConverter extends CollectionConverter { + + private final String name; + private final Class type; + + /** + * Constructs a NamedCollectionConverter. + * + * @param mapper the mapper + * @param itemName the name of the items + * @param itemType the base type of the items + * @since 1.4.5 + */ + public NamedCollectionConverter(Mapper mapper, String itemName, Class itemType) { + this(null, mapper, itemName, itemType); + } + + /** + * Constructs a NamedCollectionConverter handling an explicit Collection type. + * + * @param type the Collection type to handle + * @param mapper the mapper + * @param itemName the name of the items + * @param itemType the base type of the items + * @since 1.4.5 + */ + public NamedCollectionConverter(Class type, Mapper mapper, String itemName, Class itemType) { + super(mapper, type); + this.name = itemName; + this.type = itemType; + } + + protected void writeItem(Object item, MarshallingContext context, HierarchicalStreamWriter writer) { + Class itemType = item == null ? Mapper.Null.class : item.getClass(); + ExtendedHierarchicalStreamWriterHelper.startNode(writer, name, itemType); + if (!itemType.equals(type)) { + String attributeName = mapper().aliasForSystemAttribute("class"); + if (attributeName != null) { + writer.addAttribute(attributeName, mapper().serializedClass(itemType)); + } + } + if (item != null) { + context.convertAnother(item); + } + writer.endNode(); + } + + protected Object readItem(HierarchicalStreamReader reader, UnmarshallingContext context, Object current) { + String className = HierarchicalStreams.readClassAttribute(reader, mapper()); + Class itemType = className == null ? type : mapper().realClass(className); + if (Mapper.Null.class.equals(itemType)) { + return null; + } else { + return context.convertAnother(current, itemType); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedMapConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedMapConverter.java new file mode 100644 index 0000000..24f6e0e --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/NamedMapConverter.java @@ -0,0 +1,391 @@ +/* + * Copyright (C) 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 20. September 2013 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.extended; + +import java.util.Iterator; +import java.util.Map; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.converters.collections.MapConverter; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.core.util.HierarchicalStreams; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + + +/** + * A map converter that uses predefined names for its elements. + *

+ * To be used as local converter. Note, suppress the usage of the implicit type argument, if + * registered with annotation. Depending on the constructor arguments it is possible to support + * various formats: + *

+ *
    + *
  • new NamedMapConverter(xstream.getMapper(), "entry", "key", String.class, "value", + * Integer.class); + * + *
    + * <map>
    + *   <entry>
    + *     <key>keyValue</key>
    + *     <value>0</value>
    + *   </entry>
    + * </map>
    + * 
    + * + *
  • + *
  • new NamedMapConverter(xstream.getMapper(), null, "key", String.class, "value", + * Integer.class); + * + *
    + * <map>
    + *   <key>keyValue</key>
    + *   <value>0</value>
    + * </map>
    + * 
    + * + *
  • + *
  • new NamedMapConverter(xstream.getMapper(), "entry", "key", String.class, "value", + * Integer.class, true, true, xstream.getConverterLookup()); + * + *
    + * <map>
    + *   <entry> key="keyValue" value="0"/>
    + * </map>
    + * 
    + * + *
  • + *
  • new NamedMapConverter(xstream.getMapper(), "entry", "key", String.class, "value", + * Integer.class, true, false, xstream.getConverterLookup()); + * + *
    + * <map>
    + *   <entry key="keyValue">
    + *     <value>0</value>
    + *   </entry>
    + * </map>
    + * 
    + * + *
  • + *
  • new NamedMapConverter(xstream.getMapper(), "entry", "key", String.class, "value", + * Integer.class, false, true, xstream.getConverterLookup()); + * + *
    + * <map>
    + *   <entry value="0">
    + *     <key>keyValue</key>
    + *   </entry>
    + * </map>
    + * 
    + * + *
  • + *
  • new NamedMapConverter(xstream.getMapper(), "entry", "key", String.class, null, + * Integer.class, true, false, xstream.getConverterLookup()); + * + *
    + * <map>
    + *   <entry key="keyValue">0</entry>
    + * </map>
    + * 
    + * + *
  • + *
+ * + * @author Jörg Schaible + * @since 1.4.5 + */ +public class NamedMapConverter extends MapConverter { + + private final String entryName; + private final String keyName; + private final Class keyType; + private final String valueName; + private final Class valueType; + private final boolean keyAsAttribute; + private final boolean valueAsAttribute; + private final ConverterLookup lookup; + private final Mapper enumMapper; + + /** + * Constructs a NamedMapConverter. + * + * @param mapper the mapper + * @param entryName the name of the entry elements + * @param keyName the name of the key elements + * @param keyType the base type of key elements + * @param valueName the name of the value elements + * @param valueType the base type of value elements + * @since 1.4.5 + */ + public NamedMapConverter( + Mapper mapper, String entryName, String keyName, Class keyType, String valueName, + Class valueType) { + this(mapper, entryName, keyName, keyType, valueName, valueType, false, false, null); + } + + /** + * Constructs a NamedMapConverter handling an explicit Map type. + * + * @param type the Map type this instance will handle + * @param mapper the mapper + * @param entryName the name of the entry elements + * @param keyName the name of the key elements + * @param keyType the base type of key elements + * @param valueName the name of the value elements + * @param valueType the base type of value elements + * @since 1.4.5 + */ + public NamedMapConverter( + Class type, Mapper mapper, String entryName, String keyName, Class keyType, + String valueName, Class valueType) { + this( + type, mapper, entryName, keyName, keyType, valueName, valueType, false, false, null); + } + + /** + * Constructs a NamedMapConverter with attribute support. + * + * @param mapper the mapper + * @param entryName the name of the entry elements + * @param keyName the name of the key elements + * @param keyType the base type of key elements + * @param valueName the name of the value elements + * @param valueType the base type of value elements + * @param keyAsAttribute flag to write key as attribute of entry element + * @param valueAsAttribute flag to write value as attribute of entry element + * @param lookup used to lookup SingleValueConverter for attributes + * @since 1.4.5 + */ + public NamedMapConverter( + Mapper mapper, String entryName, String keyName, Class keyType, String valueName, + Class valueType, boolean keyAsAttribute, boolean valueAsAttribute, + ConverterLookup lookup) { + this( + null, mapper, entryName, keyName, keyType, valueName, valueType, keyAsAttribute, + valueAsAttribute, lookup); + } + + /** + * Constructs a NamedMapConverter with attribute support handling an explicit Map type. + * + * @param type the Map type this instance will handle + * @param mapper the mapper + * @param entryName the name of the entry elements + * @param keyName the name of the key elements + * @param keyType the base type of key elements + * @param valueName the name of the value elements + * @param valueType the base type of value elements + * @param keyAsAttribute flag to write key as attribute of entry element + * @param valueAsAttribute flag to write value as attribute of entry element + * @param lookup used to lookup SingleValueConverter for attributes + * @since 1.4.5 + */ + public NamedMapConverter( + Class type, Mapper mapper, String entryName, String keyName, Class keyType, + String valueName, Class valueType, boolean keyAsAttribute, boolean valueAsAttribute, + ConverterLookup lookup) { + super(mapper, type); + this.entryName = entryName != null && entryName.length() == 0 ? null : entryName; + this.keyName = keyName != null && keyName.length() == 0 ? null : keyName; + this.keyType = keyType; + this.valueName = valueName != null && valueName.length() == 0 ? null : valueName; + this.valueType = valueType; + this.keyAsAttribute = keyAsAttribute; + this.valueAsAttribute = valueAsAttribute; + this.lookup = lookup; + enumMapper = JVM.is15() ? UseAttributeForEnumMapper.createEnumMapper(mapper) : null; + + if (keyType == null || valueType == null) { + throw new IllegalArgumentException("Class types of key and value are mandatory"); + } + if (entryName == null) { + if (keyAsAttribute || valueAsAttribute) { + throw new IllegalArgumentException( + "Cannot write attributes to map entry, if map entry must be omitted"); + } + if (valueName == null) { + throw new IllegalArgumentException( + "Cannot write value as text of entry, if entry must be omitted"); + } + } + if (keyName == null) { + throw new IllegalArgumentException("Cannot write key without name"); + } + if (valueName == null) { + if (valueAsAttribute) { + throw new IllegalArgumentException( + "Cannot write value as attribute without name"); + } else if (!keyAsAttribute) { + throw new IllegalArgumentException( + "Cannot write value as text of entry, if key is also child element"); + } + } + if (keyAsAttribute && valueAsAttribute && keyName.equals(valueName)) { + throw new IllegalArgumentException( + "Cannot write key and value with same attribute name"); + } + } + + public void marshal(Object source, HierarchicalStreamWriter writer, + MarshallingContext context) { + Map map = (Map)source; + SingleValueConverter keyConverter = null; + SingleValueConverter valueConverter = null; + if (keyAsAttribute) { + keyConverter = getSingleValueConverter(keyType); + } + if (valueAsAttribute || valueName == null) { + valueConverter = getSingleValueConverter(valueType); + } + for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = (Map.Entry)iterator.next(); + Object key = entry.getKey(); + Object value = entry.getValue(); + if (entryName != null) { + ExtendedHierarchicalStreamWriterHelper.startNode( + writer, entryName, entry.getClass()); + if (keyConverter != null && key != null) { + writer.addAttribute(keyName, keyConverter.toString(key)); + } + if (valueName != null && valueConverter != null && value != null) { + writer.addAttribute(valueName, valueConverter.toString(value)); + } + } + + if (keyConverter == null) { + writeItem(keyName, keyType, key, context, writer); + } + if (valueConverter == null) { + writeItem(valueName, valueType, value, context, writer); + } else if (valueName == null) { + writer.setValue(valueConverter.toString(value)); + } + + if (entryName != null) { + writer.endNode(); + } + } + } + + protected void populateMap(HierarchicalStreamReader reader, UnmarshallingContext context, + Map map, Map target) { + SingleValueConverter keyConverter = null; + SingleValueConverter valueConverter = null; + if (keyAsAttribute) { + keyConverter = getSingleValueConverter(keyType); + } + if (valueAsAttribute || valueName == null) { + valueConverter = getSingleValueConverter(valueType); + } + + while (reader.hasMoreChildren()) { + Object key = null; + Object value = null; + + if (entryName != null) { + reader.moveDown(); + + if (keyConverter != null) { + String attribute = reader.getAttribute(keyName); + if (attribute != null) { + key = keyConverter.fromString(attribute); + } + } + + if (valueAsAttribute && valueConverter != null) { + String attribute = reader.getAttribute(valueName); + if (attribute != null) { + value = valueConverter.fromString(attribute); + } + } + } + + if (keyConverter == null) { + reader.moveDown(); + if (valueConverter == null + && !keyName.equals(valueName) + && reader.getNodeName().equals(valueName)) { + value = readItem(valueType, reader, context, map); + } else { + key = readItem(keyType, reader, context, map); + } + reader.moveUp(); + } + + if (valueConverter == null) { + reader.moveDown(); + if (keyConverter == null && key == null && value != null) { + key = readItem(keyType, reader, context, map); + } else { + value = readItem(valueType, reader, context, map); + } + reader.moveUp(); + } else if (!valueAsAttribute) { + value = reader.getValue(); + } + + target.put(key, value); + + if (entryName != null) { + reader.moveUp(); + } + } + } + + private SingleValueConverter getSingleValueConverter(Class type) { + SingleValueConverter conv = UseAttributeForEnumMapper.isEnum(type) ? enumMapper + .getConverterFromItemType(null, type, null) : mapper().getConverterFromItemType( + null, type, null); + if (conv == null) { + Converter converter = lookup.lookupConverterForType(type); + if (converter instanceof SingleValueConverter) { + conv = (SingleValueConverter)converter; + } else { + throw new ConversionException("No SingleValueConverter for key available"); + } + } + return conv; + } + + protected void writeItem(String name, Class type, Object item, MarshallingContext context, + HierarchicalStreamWriter writer) { + Class itemType = item == null ? Mapper.Null.class : item.getClass(); + ExtendedHierarchicalStreamWriterHelper.startNode(writer, name, itemType); + if (!itemType.equals(type)) { + String attributeName = mapper().aliasForSystemAttribute("class"); + if (attributeName != null) { + writer.addAttribute(attributeName, mapper().serializedClass(itemType)); + } + } + if (item != null) { + context.convertAnother(item); + } + writer.endNode(); + } + + protected Object readItem(Class type, HierarchicalStreamReader reader, + UnmarshallingContext context, Object current) { + String className = HierarchicalStreams.readClassAttribute(reader, mapper()); + Class itemType = className == null ? type : mapper().realClass(className); + if (Mapper.Null.class.equals(itemType)) { + return null; + } else { + return context.convertAnother(current, itemType); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/PropertyEditorCapableConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/PropertyEditorCapableConverter.java new file mode 100644 index 0000000..8c5a111 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/PropertyEditorCapableConverter.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 20.09.2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.core.util.ThreadSafePropertyEditor; + +import java.beans.PropertyEditor; + + +/** + * A SingleValueConverter that can utilize a {@link PropertyEditor} implementation used for a + * specific type. The converter ensures that the editors can be used concurrently. + * + * @author Jukka Lindström + * @author Jörg Schaible + * @since 1.3 + */ +public class PropertyEditorCapableConverter implements SingleValueConverter { + + private final ThreadSafePropertyEditor editor; + private final Class type; + + public PropertyEditorCapableConverter(final Class propertyEditorType, final Class type) { + this.type = type; + editor = new ThreadSafePropertyEditor(propertyEditorType, 2, 5); + } + + public boolean canConvert(final Class type) { + return this.type == type; + } + + public Object fromString(final String str) { + return editor.setAsText(str); + } + + public String toString(final Object obj) { + return editor.getAsText(obj); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/RegexPatternConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/RegexPatternConverter.java new file mode 100644 index 0000000..3bed0f6 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/RegexPatternConverter.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 31. July 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + +import java.util.regex.Pattern; + +/** + * Ensures java.util.regex.Pattern is compiled upon deserialization. + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class RegexPatternConverter implements Converter { + + /** + * @since 1.4.5 + */ + public RegexPatternConverter() { + } + + /** + * @deprecated As of 1.4.5, use {@link #RegexPatternConverter()} instead + */ + public RegexPatternConverter(Converter defaultConverter) { + } + + public boolean canConvert(final Class type) { + return type.equals(Pattern.class); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + Pattern pattern = (Pattern)source; + writer.startNode("pattern"); + writer.setValue(pattern.pattern()); + writer.endNode(); + writer.startNode("flags"); + writer.setValue(String.valueOf(pattern.flags())); + writer.endNode(); + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + reader.moveDown(); + String pattern = reader.getValue(); + reader.moveUp(); + reader.moveDown(); + int flags = Integer.parseInt(reader.getValue()); + reader.moveUp(); + return Pattern.compile(pattern, flags); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlDateConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlDateConverter.java new file mode 100644 index 0000000..f5d8e7f --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlDateConverter.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. July 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import java.sql.Date; + +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; + +/** + * Converts a java.sql.Date to text. + * + * @author Jose A. Illescas + */ +public class SqlDateConverter extends AbstractSingleValueConverter { + + public boolean canConvert(Class type) { + return type.equals(Date.class); + } + + public Object fromString(String str) { + return Date.valueOf(str); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlTimeConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlTimeConverter.java new file mode 100644 index 0000000..3315f23 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlTimeConverter.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. July 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; + +import java.sql.Time; + +/** + * Converts a java.sql.Time to text. Warning: Any granularity smaller than seconds is lost. + * + * @author Jose A. Illescas + */ +public class SqlTimeConverter extends AbstractSingleValueConverter { + + public boolean canConvert(Class type) { + return type.equals(Time.class); + } + + public Object fromString(String str) { + return Time.valueOf(str); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlTimestampConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlTimestampConverter.java new file mode 100644 index 0000000..d5f9c45 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/SqlTimestampConverter.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2003, 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2012, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. October 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; +import com.thoughtworks.xstream.core.util.ThreadSafeSimpleDateFormat; + +import java.sql.Timestamp; +import java.text.ParseException; +import java.util.TimeZone; + + +/** + * Converts a java.sql.Timestamp to text. + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class SqlTimestampConverter extends AbstractSingleValueConverter { + + private final ThreadSafeSimpleDateFormat format = new ThreadSafeSimpleDateFormat( + "yyyy-MM-dd HH:mm:ss", TimeZone.getTimeZone("UTC"), 0, 5, false); + + public boolean canConvert(Class type) { + return type.equals(Timestamp.class); + } + + public String toString(Object obj) { + Timestamp timestamp = (Timestamp)obj; + StringBuffer buffer = new StringBuffer(format.format(timestamp)).append('.'); + if (timestamp.getNanos() == 0) { + buffer.append('0'); + } else { + String nanos = String.valueOf(timestamp.getNanos() + 1000000000); + int last = 10; + while (last > 2 && nanos.charAt(last-1) == '0') + --last; + buffer.append(nanos.subSequence(1, last)); + } + return buffer.toString(); + } + + public Object fromString(String str) { + int idx = str.lastIndexOf('.'); + if (idx < 0 || str.length() - idx < 2 || str.length() - idx > 10) { + throw new ConversionException( + "Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]"); + } + try { + Timestamp timestamp = new Timestamp(format.parse(str.substring(0, idx)).getTime()); + StringBuffer buffer = new StringBuffer(str.substring(idx + 1)); + while(buffer.length() != 9) { + buffer.append('0'); + } + timestamp.setNanos(Integer.parseInt(buffer.toString())); + return timestamp; + } catch (NumberFormatException e) { + throw new ConversionException( + "Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]", e); + } catch (ParseException e) { + throw new ConversionException( + "Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]", e); + } + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/StackTraceElementConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/StackTraceElementConverter.java new file mode 100644 index 0000000..c56b9e3 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/StackTraceElementConverter.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. May 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; +import com.thoughtworks.xstream.core.JVM; + +/** + * Converter for StackTraceElement (the lines of a stack trace) - JDK 1.4+ only. + * + * @author B. K. Oxley (binkley) + * @author Joe Walnes + */ +public class StackTraceElementConverter extends AbstractSingleValueConverter { + + // Regular expression to parse a line of a stack trace. Returns 4 groups. + // + // Example: com.blah.MyClass.doStuff(MyClass.java:123) + // |-------1------| |--2--| |----3-----| |4| + // (Note group 4 is optional is optional and only present if a colon char exists.) + + private static final Pattern PATTERN = Pattern.compile("^(.+)\\.([^\\(]+)\\(([^:]*)(:(\\d+))?\\)$"); + private static final StackTraceElementFactory FACTORY; + static { + StackTraceElementFactory factory = null; + if (JVM.is15()) { + Class factoryType = JVM.loadClassForName( + "com.thoughtworks.xstream.converters.extended.StackTraceElementFactory15", + false); + try { + factory = (StackTraceElementFactory)factoryType.newInstance(); + } catch (Exception e) { + // N/A + } catch (LinkageError e) { + // N/A + } + } + if (factory == null) { + factory = new StackTraceElementFactory(); + } + try { + factory.unknownSourceElement("a", "b"); + } catch (Exception e) { + factory = null; + } catch (NoClassDefFoundError e) { // GAE + factory = null; + } + FACTORY = factory; + } + + public boolean canConvert(Class type) { + return StackTraceElement.class.equals(type) && FACTORY != null; + } + + public String toString(Object obj) { + String s = super.toString(obj); + // JRockit adds ":???" for invalid line number + return s.replaceFirst(":\\?\\?\\?", ""); + } + + public Object fromString(String str) { + Matcher matcher = PATTERN.matcher(str); + if (matcher.matches()) { + String declaringClass = matcher.group(1); + String methodName = matcher.group(2); + String fileName = matcher.group(3); + if (fileName.equals("Unknown Source")) { + return FACTORY.unknownSourceElement(declaringClass, methodName); + } else if (fileName.equals("Native Method")) { + return FACTORY.nativeMethodElement(declaringClass, methodName); + } else { + if (matcher.group(4) != null) { + int lineNumber = Integer.parseInt(matcher.group(5)); + return FACTORY.element(declaringClass, methodName, fileName, lineNumber); + } else { + return FACTORY.element(declaringClass, methodName, fileName); + } + } + } else { + throw new ConversionException("Could not parse StackTraceElement : " + str); + } + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/StackTraceElementFactory.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/StackTraceElementFactory.java new file mode 100644 index 0000000..7154c8a --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/StackTraceElementFactory.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. May 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.ConversionException; + +import java.lang.reflect.Field; + +/** + * Factory for creating StackTraceElements. + * Factory for creating StackTraceElements. + * + * @author B. K. Oxley (binkley) + * @author Joe Walnes + * @deprecated As of 1.4.8, it is an internal helper class + */ +public class StackTraceElementFactory { + + public StackTraceElement nativeMethodElement(String declaringClass, String methodName) { + return create(declaringClass, methodName, "Native Method", -2); + } + + public StackTraceElement unknownSourceElement(String declaringClass, String methodName) { + return create(declaringClass, methodName, "Unknown Source", -1); + } + + public StackTraceElement element(String declaringClass, String methodName, String fileName) { + return create(declaringClass, methodName, fileName, -1); + } + + public StackTraceElement element(String declaringClass, String methodName, String fileName, int lineNumber) { + return create(declaringClass, methodName, fileName, lineNumber); + } + + protected StackTraceElement create(String declaringClass, String methodName, String fileName, int lineNumber) { + StackTraceElement result = new Throwable().getStackTrace()[0]; + setField(result, "declaringClass", declaringClass); + setField(result, "methodName", methodName); + setField(result, "fileName", fileName); + setField(result, "lineNumber", new Integer(lineNumber)); + return result; + } + + private void setField(StackTraceElement element, String fieldName, Object value) { + try { + final Field field = StackTraceElement.class.getDeclaredField(fieldName); + field.setAccessible(true); + field.set(element, value); + } catch (Exception e) { + throw new ConversionException(e); + } + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/StackTraceElementFactory15.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/StackTraceElementFactory15.java new file mode 100644 index 0000000..f34024c --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/StackTraceElementFactory15.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. December 2013 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.extended; + +/** + * @author Jörg Schaible + * + * @since 1.4.6 + */ +class StackTraceElementFactory15 extends StackTraceElementFactory { + + @Override + protected StackTraceElement create(final String declaringClass, final String methodName, + final String fileName, final int lineNumber) { + return new StackTraceElement(declaringClass, methodName, fileName, lineNumber); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/SubjectConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/SubjectConverter.java new file mode 100644 index 0000000..bbb5890 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/SubjectConverter.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 12. January 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + +import javax.security.auth.Subject; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * Converts a {@link Subject} instance. Note, that this Converter does only convert the contained Principals as + * it is done by JDK serialization, but not any credentials. For other behaviour you can derive your own converter, + * overload the appropriate methods and register it in the {@link com.thoughtworks.xstream.XStream}. + * + * @author Jörg Schaible + * @since 1.1.3 + */ +public class SubjectConverter extends AbstractCollectionConverter { + + public SubjectConverter(Mapper mapper) { + super(mapper); + } + + public boolean canConvert(Class type) { + return type.equals(Subject.class); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + Subject subject = (Subject) source; + marshalPrincipals(subject.getPrincipals(), writer, context); + marshalPublicCredentials(subject.getPublicCredentials(), writer, context); + marshalPrivateCredentials(subject.getPrivateCredentials(), writer, context); + marshalReadOnly(subject.isReadOnly(), writer); + } + + protected void marshalPrincipals(Set principals, HierarchicalStreamWriter writer, MarshallingContext context) { + writer.startNode("principals"); + for (final Iterator iter = principals.iterator(); iter.hasNext();) { + final Object principal = iter.next(); // pre jdk 1.4 a Principal was also in javax.security + writeItem(principal, context, writer); + } + writer.endNode(); + }; + + protected void marshalPublicCredentials(Set pubCredentials, HierarchicalStreamWriter writer, MarshallingContext context) { + }; + + protected void marshalPrivateCredentials(Set privCredentials, HierarchicalStreamWriter writer, MarshallingContext context) { + }; + + protected void marshalReadOnly(boolean readOnly, HierarchicalStreamWriter writer) { + writer.startNode("readOnly"); + writer.setValue(String.valueOf(readOnly)); + writer.endNode(); + }; + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + Set principals = unmarshalPrincipals(reader, context); + Set publicCredentials = unmarshalPublicCredentials(reader, context); + Set privateCredentials = unmarshalPrivateCredentials(reader, context); + boolean readOnly = unmarshalReadOnly(reader); + return new Subject(readOnly, principals, publicCredentials, privateCredentials); + } + + protected Set unmarshalPrincipals(HierarchicalStreamReader reader, UnmarshallingContext context) { + return populateSet(reader, context); + }; + + protected Set unmarshalPublicCredentials(HierarchicalStreamReader reader, UnmarshallingContext context) { + return Collections.EMPTY_SET; + }; + + protected Set unmarshalPrivateCredentials(HierarchicalStreamReader reader, UnmarshallingContext context) { + return Collections.EMPTY_SET; + }; + + protected boolean unmarshalReadOnly(HierarchicalStreamReader reader) { + reader.moveDown(); + boolean readOnly = Boolean.getBoolean(reader.getValue()); + reader.moveUp(); + return readOnly; + }; + + protected Set populateSet(HierarchicalStreamReader reader, UnmarshallingContext context) { + Set set = new HashSet(); + reader.moveDown(); + while (reader.hasMoreChildren()) { + reader.moveDown(); + Object elementl = readItem(reader, context, set); + reader.moveUp(); + set.add(elementl); + } + reader.moveUp(); + return set; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/TextAttributeConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/TextAttributeConverter.java new file mode 100644 index 0000000..0c5fdb5 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/TextAttributeConverter.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 25. March 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.reflection.AbstractAttributedCharacterIteratorAttributeConverter; + +import java.awt.font.TextAttribute; + + +/** + * A converter for {@link TextAttribute} constants. + * + * @author Jörg Schaible + * @since 1.2 + */ +public class TextAttributeConverter extends + AbstractAttributedCharacterIteratorAttributeConverter { + + /** + * Constructs a TextAttributeConverter. + * + * @since 1.2.2 + */ + public TextAttributeConverter() { + super(TextAttribute.class); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ThrowableConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ThrowableConverter.java new file mode 100644 index 0000000..a0c8d3b --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ThrowableConverter.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. May 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + +/** + * Converter for Throwable (and Exception) that retains stack trace. + * + * @author B. K. Oxley (binkley) + * @author Joe Walnes + * @author Jörg Schaible + */ +public class ThrowableConverter implements Converter { + + private Converter defaultConverter; + private final ConverterLookup lookup; + + /** + * @deprecated As of 1.4.5 use {@link #ThrowableConverter(ConverterLookup)} + */ + public ThrowableConverter(Converter defaultConverter) { + this.defaultConverter = defaultConverter; + lookup = null; + } + + /** + * @since 1.4.5 + */ + public ThrowableConverter(ConverterLookup lookup) { + this.lookup = lookup; + } + + public boolean canConvert(final Class type) { + return Throwable.class.isAssignableFrom(type); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + Throwable throwable = (Throwable) source; + if (throwable.getCause() == null) { + try { + throwable.initCause(null); + } catch (IllegalStateException e) { + // ignore, initCause failed, cause was already set + } + } + throwable.getStackTrace(); // Force stackTrace field to be lazy loaded by special JVM native witchcraft (outside our control). + getConverter().marshal(throwable, writer, context); + } + + private Converter getConverter() { + return defaultConverter != null ? defaultConverter : lookup.lookupConverterForType(Object.class); + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + return getConverter().unmarshal(reader, context); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverter.java new file mode 100644 index 0000000..df5f483 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverter.java @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. July 2011 by Joerg Schaible + */ + +package com.thoughtworks.xstream.converters.extended; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.converters.ConverterMatcher; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.DuplicateFieldException; +import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.core.util.FastField; +import com.thoughtworks.xstream.core.util.HierarchicalStreams; +import com.thoughtworks.xstream.core.util.Primitives; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + + +/** + * Converter that supports the definition of one field member that will be written as value and + * all other field members are written as attributes. The converter requires that all the field + * types (expect the one with the value) are handled by a {@link SingleValueConverter}. The + * value field is defined using the name of the type that declares the field and the field name + * itself. Therefore it is possible to define an inherited field as value. It is also possible + * to provide no value field at all, so that all fields are written as attributes. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class ToAttributedValueConverter implements Converter { + private static final String STRUCTURE_MARKER = ""; + private final Class type; + private final Mapper mapper; + private final Mapper enumMapper; + private final ReflectionProvider reflectionProvider; + private final ConverterLookup lookup; + private final Field valueField; + + /** + * Creates a new ToAttributedValueConverter instance. + * + * @param type the type that is handled by this converter instance + * @param mapper the mapper in use + * @param reflectionProvider the reflection provider in use + * @param lookup the converter lookup in use + * @param valueFieldName the field defining the tag's value (may be null) + */ + public ToAttributedValueConverter( + final Class type, final Mapper mapper, final ReflectionProvider reflectionProvider, + final ConverterLookup lookup, final String valueFieldName) { + this(type, mapper, reflectionProvider, lookup, valueFieldName, null); + } + + /** + * Creates a new ToAttributedValueConverter instance. + * + * @param type the type that is handled by this converter instance + * @param mapper the mapper in use + * @param reflectionProvider the reflection provider in use + * @param lookup the converter lookup in use + * @param valueFieldName the field defining the tag's value (may be null) + * @param valueDefinedIn the type defining the field + */ + public ToAttributedValueConverter( + final Class type, final Mapper mapper, final ReflectionProvider reflectionProvider, + final ConverterLookup lookup, final String valueFieldName, Class valueDefinedIn) { + this.type = type; + this.mapper = mapper; + this.reflectionProvider = reflectionProvider; + this.lookup = lookup; + + if (valueFieldName == null) { + valueField = null; + } else { + Field field = null; + try { + field = (valueDefinedIn != null ? valueDefinedIn : type) + .getDeclaredField(valueFieldName); + if (!field.isAccessible()) { + field.setAccessible(true); + } + } catch (NoSuchFieldException e) { + throw new IllegalArgumentException(e.getMessage() + ": " + valueFieldName); + } + this.valueField = field; + } + enumMapper = JVM.is15() ? UseAttributeForEnumMapper.createEnumMapper(mapper) : null; + } + + public boolean canConvert(final Class type) { + return this.type == type; + } + + public void marshal(final Object source, final HierarchicalStreamWriter writer, + final MarshallingContext context) { + final Class sourceType = source.getClass(); + final Map defaultFieldDefinition = new HashMap(); + final String[] tagValue = new String[1]; + final Object[] realValue = new Object[1]; + final Class[] fieldType = new Class[1]; + final Class[] definingType = new Class[1]; + reflectionProvider.visitSerializableFields(source, new ReflectionProvider.Visitor() { + public void visit(final String fieldName, final Class type, final Class definedIn, + final Object value) { + if (!mapper.shouldSerializeMember(definedIn, fieldName)) { + return; + } + + final FastField field = new FastField(definedIn, fieldName); + final String alias = mapper.serializedMember(definedIn, fieldName); + if (!defaultFieldDefinition.containsKey(alias)) { + final Class lookupType = sourceType; + defaultFieldDefinition.put( + alias, reflectionProvider.getField(lookupType, fieldName)); + } else if (!fieldIsEqual(field)) { + final ConversionException exception = new ConversionException( + "Cannot write attribute twice for object"); + exception.add("alias", alias); + exception.add("type", sourceType.getName()); + throw exception; + } + + ConverterMatcher converter = UseAttributeForEnumMapper.isEnum(type) + ? (ConverterMatcher)enumMapper.getConverterFromItemType(null, type, null) + : (ConverterMatcher)mapper.getLocalConverter(definedIn, fieldName); + if (converter == null) { + converter = lookup.lookupConverterForType(type); + } + + if (value != null) { + boolean isValueField = valueField != null && fieldIsEqual(field); + if (isValueField) { + definingType[0] = definedIn; + fieldType[0] = type; + realValue[0] = value; + tagValue[0] = STRUCTURE_MARKER; + } + if (converter instanceof SingleValueConverter) { + final String str = ((SingleValueConverter)converter).toString(value); + + if (isValueField) { + tagValue[0] = str; + } else { + if (str != null) { + writer.addAttribute(alias, str); + } + } + } else { + if (!isValueField) { + final ConversionException exception = new ConversionException( + "Cannot write element as attribute"); + exception.add("alias", alias); + exception.add("type", sourceType.getName()); + throw exception; + } + } + } + } + }); + + if (tagValue[0] != null) { + final Class actualType = realValue[0].getClass(); + final Class defaultType = mapper.defaultImplementationOf(fieldType[0]); + if (!actualType.equals(defaultType)) { + final String serializedClassName = mapper.serializedClass(actualType); + if (!serializedClassName.equals(mapper.serializedClass(defaultType))) { + final String attributeName = mapper.aliasForSystemAttribute("class"); + if (attributeName != null) { + writer.addAttribute(attributeName, serializedClassName); + } + } + } + + if (tagValue[0] == STRUCTURE_MARKER) { + context.convertAnother(realValue[0]); + } else { + writer.setValue(tagValue[0]); + } + } + } + + public Object unmarshal(final HierarchicalStreamReader reader, + final UnmarshallingContext context) { + final Object result = reflectionProvider.newInstance(context.getRequiredType()); + final Class resultType = result.getClass(); + + final Set seenFields = new HashSet(); + final Iterator it = reader.getAttributeNames(); + + final Set systemAttributes = new HashSet(); + systemAttributes.add(mapper.aliasForSystemAttribute("class")); + + // Process attributes before recursing into child elements. + while (it.hasNext()) { + final String attrName = (String)it.next(); + if (systemAttributes.contains(attrName)) { + continue; + } + + final String fieldName = mapper.realMember(resultType, attrName); + final Field field = reflectionProvider.getFieldOrNull(resultType, fieldName); + if (field != null) { + if (Modifier.isTransient(field.getModifiers())) { + continue; + } + + Class type = field.getType(); + final Class declaringClass = field.getDeclaringClass(); + ConverterMatcher converter = UseAttributeForEnumMapper.isEnum(type) + ? (ConverterMatcher)enumMapper.getConverterFromItemType(null, type, null) + : (ConverterMatcher)mapper.getLocalConverter(declaringClass, fieldName); + if (converter == null) { + converter = lookup.lookupConverterForType(type); + } + + if (!(converter instanceof SingleValueConverter)) { + final ConversionException exception = new ConversionException( + "Cannot read field as a single value for object"); + exception.add("field", fieldName); + exception.add("type", resultType.getName()); + throw exception; + } + + if (converter != null) { + final Object value = ((SingleValueConverter)converter).fromString(reader + .getAttribute(attrName)); + if (type.isPrimitive()) { + type = Primitives.box(type); + } + + if (value != null && !type.isAssignableFrom(value.getClass())) { + final ConversionException exception = new ConversionException( + "Cannot assign object to type"); + exception.add("object type", value.getClass().getName()); + exception.add("target type", type.getName()); + throw exception; + } + + reflectionProvider.writeField(result, fieldName, value, declaringClass); + if (!seenFields.add(new FastField(declaringClass, fieldName))) { + throw new DuplicateFieldException(fieldName + + " [" + + declaringClass.getName() + + "]"); + } + } + } + } + + if (valueField != null) { + final Class classDefiningField = valueField.getDeclaringClass(); + final String fieldName = valueField.getName(); + final Field field = fieldName == null ? null : reflectionProvider.getField( + classDefiningField, fieldName); + if (fieldName == null || field == null) { + final ConversionException exception = new ConversionException( + "Cannot assign value to field of type"); + exception.add("element", reader.getNodeName()); + exception.add("field", fieldName); + exception.add("target type", context.getRequiredType().getName()); + throw exception; + } + + Class type; + final String classAttribute = HierarchicalStreams + .readClassAttribute(reader, mapper); + if (classAttribute != null) { + type = mapper.realClass(classAttribute); + } else { + type = mapper.defaultImplementationOf(reflectionProvider.getFieldType( + result, fieldName, classDefiningField)); + } + + final Object value = context.convertAnother( + result, type, + mapper.getLocalConverter(field.getDeclaringClass(), field.getName())); + + final Class definedType = reflectionProvider.getFieldType( + result, fieldName, classDefiningField); + if (!definedType.isPrimitive()) { + type = definedType; + } + + if (value != null && !type.isAssignableFrom(value.getClass())) { + final ConversionException exception = new ConversionException( + "Cannot assign object to type"); + exception.add("object type", value.getClass().getName()); + exception.add("target type", type.getName()); + throw exception; + } + + reflectionProvider.writeField(result, fieldName, value, classDefiningField); + if (!seenFields.add(new FastField(classDefiningField, fieldName))) { + throw new DuplicateFieldException(fieldName + + " [" + + classDefiningField.getName() + + "]"); + } + } + return result; + } + + private boolean fieldIsEqual(FastField field) { + return valueField.getName().equals(field.getName()) + && valueField.getDeclaringClass().getName().equals(field.getDeclaringClass()); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToStringConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToStringConverter.java new file mode 100644 index 0000000..852f264 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/ToStringConverter.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. July 2006 by Mauro Talevi + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +/** + * Convenient converter for classes with natural string representation. + * + * Converter for classes that adopt the following convention: + * - a constructor that takes a single string parameter + * - a toString() that is overloaded to issue a string that is meaningful + * + * @author Paul Hammant + */ +public class ToStringConverter extends AbstractSingleValueConverter { + private final Class clazz; + private final Constructor ctor; + + public ToStringConverter(Class clazz) throws NoSuchMethodException { + this.clazz = clazz; + ctor = clazz.getConstructor(new Class[] {String.class}); + } + public boolean canConvert(Class type) { + return type.equals(clazz); + } + public String toString(Object obj) { + return obj == null ? null : obj.toString(); + } + + public Object fromString(String str) { + try { + return ctor.newInstance(new Object[] {str}); + } catch (InstantiationException e) { + throw new ConversionException("Unable to instantiate single String param constructor", e); + } catch (IllegalAccessException e) { + throw new ConversionException("Unable to access single String param constructor", e); + } catch (InvocationTargetException e) { + throw new ConversionException("Unable to target single String param constructor", e.getTargetException()); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/UseAttributeForEnumMapper.java b/xstream/src/java/com/thoughtworks/xstream/converters/extended/UseAttributeForEnumMapper.java new file mode 100644 index 0000000..2b2e22d --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/UseAttributeForEnumMapper.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 25. September 2013 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.core.util.DependencyInjectionFactory; +import com.thoughtworks.xstream.mapper.AttributeMapper; +import com.thoughtworks.xstream.mapper.DefaultMapper; +import com.thoughtworks.xstream.mapper.Mapper; + +class UseAttributeForEnumMapper extends AttributeMapper { + + public UseAttributeForEnumMapper(Mapper wrapped) { + super(wrapped, null, null); + } + + /** + * @deprecated only used for Java 1.4 support + */ + public static boolean isEnum(Class type) { + while(type != null && type != Object.class) { + if (type.getName().equals("java.lang.Enum")) { + return true; + } + type = type.getSuperclass(); + } + return false; + } + + public boolean shouldLookForSingleValueConverter(String fieldName, Class type, + Class definedIn) { + return isEnum(type); + } + + public SingleValueConverter getConverterFromItemType(String fieldName, Class type, + Class definedIn) { + return null; + } + + public SingleValueConverter getConverterFromAttribute(Class definedIn, + String attribute, Class type) { + return null; + } + + static Mapper createEnumMapper(final Mapper mapper) { + try { + Class enumMapperClass = Class.forName( + "com.thoughtworks.xstream.mapper.EnumMapper", true, + Mapper.class.getClassLoader()); + return (Mapper)DependencyInjectionFactory.newInstance( + enumMapperClass, + new Object[]{new UseAttributeForEnumMapper(mapper + .lookupMapperOfType(DefaultMapper.class))}); + } catch (Exception e) { + return null; + } + } +} \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/extended/package.html b/xstream/src/java/com/thoughtworks/xstream/converters/extended/package.html new file mode 100644 index 0000000..10e58df --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/extended/package.html @@ -0,0 +1,14 @@ + + +

Extra converters that may not be enabled in XStream by default.

+ diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/javabean/BeanProperty.java b/xstream/src/java/com/thoughtworks/xstream/converters/javabean/BeanProperty.java new file mode 100644 index 0000000..5a8c445 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/javabean/BeanProperty.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 12. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.javabean; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.UndeclaredThrowableException; + +/** + * Provide access to a bean property. + * + * @author Andrea Aime + * @deprecated As of 1.3.1, no longer in use + */ +public class BeanProperty { + + /** the target class */ + private Class memberClass; + + /** the property name */ + private String propertyName; + + /** the property type */ + private Class type; + + /** the getter */ + protected Method getter; + + /** the setter */ + private Method setter; + + private static final Object[] EMPTY_ARGS = new Object[0]; + + /** + * Creates a new {@link BeanProperty}that gets the specified property from + * the specified class. + */ + public BeanProperty(Class memberClass, String propertyName, Class propertyType) { + this.memberClass = memberClass; + this.propertyName = propertyName; + this.type = propertyType; + } + + /** + * Gets the base class that this getter accesses. + */ + public Class getBeanClass() { + return memberClass; + } + + /** + * Returns the property type + */ + public Class getType() { + return type; + } + + /** + * Gets the name of the property that this getter extracts. + */ + public String getName() { + return propertyName; + } + + /** + * Gets whether this property can get get. + */ + public boolean isReadable() { + return (getter != null); + } + + /** + * Gets whether this property can be set. + */ + public boolean isWritable() { + return (setter != null); + } + + /** + * Gets the value of this property for the specified Object. + * @throws IllegalAccessException + * @throws IllegalArgumentException + */ + public Object get(Object member) throws IllegalArgumentException, IllegalAccessException { + if (!isReadable()) + throw new IllegalStateException("Property " + propertyName + " of " + memberClass + + " not readable"); + + try { + return getter.invoke(member, EMPTY_ARGS); + } catch (InvocationTargetException e) { + throw new UndeclaredThrowableException(e.getTargetException()); + } + } + + /** + * Sets the value of this property for the specified Object. + * @throws IllegalAccessException + * @throws IllegalArgumentException + */ + public Object set(Object member, Object newValue) throws IllegalArgumentException, IllegalAccessException { + if (!isWritable()) + throw new IllegalStateException("Property " + propertyName + " of " + memberClass + + " not writable"); + + try { + return setter.invoke(member, new Object[] { newValue }); + } catch (InvocationTargetException e) { + throw new UndeclaredThrowableException(e.getTargetException()); + } + } + + /** + * @param method + */ + public void setGetterMethod(Method method) { + this.getter = method; + + } + + /** + * @param method + */ + public void setSetterMethod(Method method) { + this.setter = method; + } +} \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/javabean/BeanProvider.java b/xstream/src/java/com/thoughtworks/xstream/converters/javabean/BeanProvider.java new file mode 100644 index 0000000..82fd9c1 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/javabean/BeanProvider.java @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 12. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.javabean; + +import java.beans.PropertyDescriptor; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; + + +public class BeanProvider implements JavaBeanProvider { + + /** + * @deprecated As of 1.4.6 + */ + protected static final Object[] NO_PARAMS = new Object[0]; + protected PropertyDictionary propertyDictionary; + + /** + * Construct a BeanProvider that will process the bean properties in their natural order. + */ + public BeanProvider() { + this(new PropertyDictionary(new NativePropertySorter())); + } + + /** + * Construct a BeanProvider with a comparator to sort the bean properties by name in the + * dictionary. + * + * @param propertyNameComparator the comparator + */ + public BeanProvider(final Comparator propertyNameComparator) { + this(new PropertyDictionary(new ComparingPropertySorter(propertyNameComparator))); + } + + /** + * Construct a BeanProvider with a provided property dictionary. + * + * @param propertyDictionary the property dictionary to use + * @since 1.4 + */ + public BeanProvider(final PropertyDictionary propertyDictionary) { + this.propertyDictionary = propertyDictionary; + } + + public Object newInstance(Class type) { + try { + return type.newInstance(); + } catch (InstantiationException e) { + throw new ObjectAccessException("Cannot construct " + type.getName(), e); + } catch (IllegalAccessException e) { + throw new ObjectAccessException("Cannot construct " + type.getName(), e); + } catch (SecurityException e) { + throw new ObjectAccessException("Cannot construct " + type.getName(), e); + } catch (ExceptionInInitializerError e) { + throw new ObjectAccessException("Cannot construct " + type.getName(), e); + } + } + + public void visitSerializableProperties(Object object, JavaBeanProvider.Visitor visitor) { + PropertyDescriptor[] propertyDescriptors = getSerializableProperties(object); + for (int i = 0; i < propertyDescriptors.length; i++ ) { + PropertyDescriptor property = propertyDescriptors[i]; + try { + Method readMethod = property.getReadMethod(); + String name = property.getName(); + Class definedIn = readMethod.getDeclaringClass(); + if (visitor.shouldVisit(name, definedIn)) { + Object value = readMethod.invoke(object, new Object[0]); + visitor.visit(name, property.getPropertyType(), definedIn, value); + } + } catch (IllegalArgumentException e) { + throw new ObjectAccessException("Could not get property " + + object.getClass() + + "." + + property.getName(), e); + } catch (IllegalAccessException e) { + throw new ObjectAccessException("Could not get property " + + object.getClass() + + "." + + property.getName(), e); + } catch (InvocationTargetException e) { + throw new ObjectAccessException("Could not get property " + + object.getClass() + + "." + + property.getName(), e); + } + } + } + + public void writeProperty(Object object, String propertyName, Object value) { + PropertyDescriptor property = getProperty(propertyName, object.getClass()); + try { + property.getWriteMethod().invoke(object, new Object[]{value}); + } catch (IllegalArgumentException e) { + throw new ObjectAccessException("Could not set property " + + object.getClass() + + "." + + property.getName(), e); + } catch (IllegalAccessException e) { + throw new ObjectAccessException("Could not set property " + + object.getClass() + + "." + + property.getName(), e); + } catch (InvocationTargetException e) { + throw new ObjectAccessException("Could not set property " + + object.getClass() + + "." + + property.getName(), e); + } + } + + public Class getPropertyType(Object object, String name) { + return getProperty(name, object.getClass()).getPropertyType(); + } + + public boolean propertyDefinedInClass(String name, Class type) { + return getProperty(name, type) != null; + } + + /** + * Returns true if the Bean provider can instantiate the specified class + */ + public boolean canInstantiate(Class type) { + try { + return newInstance(type) != null; + } catch (ObjectAccessException e) { + return false; + } + } + + /** + * Returns the default constructor, or null if none is found + * + * @param type + * @deprecated As of 1.4.6 use {@link #newInstance(Class)} or {@link #canInstantiate(Class)} directly. + */ + protected Constructor getDefaultConstrutor(Class type) { + + Constructor[] constructors = type.getConstructors(); + for (int i = 0; i < constructors.length; i++ ) { + Constructor c = constructors[i]; + if (c.getParameterTypes().length == 0 && Modifier.isPublic(c.getModifiers())) + return c; + } + return null; + } + + protected PropertyDescriptor[] getSerializableProperties(Object object) { + List result = new ArrayList(); + for (final Iterator iter = propertyDictionary.propertiesFor(object.getClass()); iter.hasNext();) { + final PropertyDescriptor descriptor = (PropertyDescriptor)iter.next(); + if (canStreamProperty(descriptor)) { + result.add(descriptor); + } + } + return (PropertyDescriptor[])result.toArray(new PropertyDescriptor[result.size()]); + } + + protected boolean canStreamProperty(PropertyDescriptor descriptor) { + return descriptor.getReadMethod() != null && descriptor.getWriteMethod() != null; + } + + public boolean propertyWriteable(String name, Class type) { + PropertyDescriptor property = getProperty(name, type); + return property.getWriteMethod() != null; + } + + protected PropertyDescriptor getProperty(String name, Class type) { + return (PropertyDescriptor)propertyDictionary.propertyDescriptor(type, name); + } + + /** + * @deprecated As of 1.4 use {@link JavaBeanProvider.Visitor} + */ + public interface Visitor extends JavaBeanProvider.Visitor { + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/javabean/ComparingPropertySorter.java b/xstream/src/java/com/thoughtworks/xstream/converters/javabean/ComparingPropertySorter.java new file mode 100644 index 0000000..a66d238 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/javabean/ComparingPropertySorter.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 16. July 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.javabean; + +import java.util.Comparator; +import java.util.Map; +import java.util.TreeMap; + +/** + * A sorter that uses a comparator to determine the order of the bean properties. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class ComparingPropertySorter implements PropertySorter { + + private final Comparator comparator; + + public ComparingPropertySorter(final Comparator propertyNameComparator) { + this.comparator = propertyNameComparator; + } + + public Map sort(final Class type, final Map nameMap) { + TreeMap map = new TreeMap(comparator); + map.putAll(nameMap); + return map; + } + +} \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/javabean/JavaBeanConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/javabean/JavaBeanConverter.java new file mode 100644 index 0000000..9109597 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/javabean/JavaBeanConverter.java @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 12. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.javabean; + +import java.util.HashSet; +import java.util.Set; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.converters.reflection.MissingFieldException; +import com.thoughtworks.xstream.core.util.FastField; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; +import com.thoughtworks.xstream.mapper.Mapper; + +/** + * Can convert any bean with a public default constructor. The {@link BeanProvider} used as + * default is based on {@link java.beans.BeanInfo}. Indexed properties are currently not supported. + */ +public class JavaBeanConverter implements Converter { + + /* + * TODO: + * - support indexed properties + * - support attributes (XSTR-620) + * - support local converters (XSTR-601) + * Problem: Mappers take definitions based on reflection, they don't know about bean info + */ + protected final Mapper mapper; + protected final JavaBeanProvider beanProvider; + private final Class type; + + /** + * @deprecated As of 1.3, no necessity for field anymore. + */ + private String classAttributeIdentifier; + + public JavaBeanConverter(Mapper mapper) { + this(mapper, (Class)null); + } + + public JavaBeanConverter(Mapper mapper, Class type) { + this(mapper, new BeanProvider(), type); + } + + public JavaBeanConverter(Mapper mapper, JavaBeanProvider beanProvider) { + this(mapper,beanProvider, null); + } + + public JavaBeanConverter(Mapper mapper, JavaBeanProvider beanProvider, Class type) { + this.mapper = mapper; + this.beanProvider = beanProvider; + this.type = type; + } + + /** + * @deprecated As of 1.3, use {@link #JavaBeanConverter(Mapper)} and {@link com.thoughtworks.xstream.XStream#aliasAttribute(String, String)} + */ + public JavaBeanConverter(Mapper mapper, String classAttributeIdentifier) { + this(mapper, new BeanProvider()); + this.classAttributeIdentifier = classAttributeIdentifier; + } + + /** + * Checks if the bean provider can instantiate this type. + * If you need less strict checks, subclass JavaBeanConverter + */ + public boolean canConvert(Class type) { + return (this.type == null || this.type == type) && beanProvider.canInstantiate(type); + } + + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final String classAttributeName = classAttributeIdentifier != null ? classAttributeIdentifier : mapper.aliasForSystemAttribute("class"); + beanProvider.visitSerializableProperties(source, new JavaBeanProvider.Visitor() { + public boolean shouldVisit(String name, Class definedIn) { + return mapper.shouldSerializeMember(definedIn, name); + } + + public void visit(String propertyName, Class fieldType, Class definedIn, Object newObj) { + if (newObj != null) { + writeField(propertyName, fieldType, newObj, definedIn); + } + } + + private void writeField(String propertyName, Class fieldType, Object newObj, Class definedIn) { + Class actualType = newObj.getClass(); + Class defaultType = mapper.defaultImplementationOf(fieldType); + String serializedMember = mapper.serializedMember(source.getClass(), propertyName); + ExtendedHierarchicalStreamWriterHelper.startNode(writer, serializedMember, actualType); + if (!actualType.equals(defaultType) && classAttributeName != null) { + writer.addAttribute(classAttributeName, mapper.serializedClass(actualType)); + } + context.convertAnother(newObj); + + writer.endNode(); + } + }); + } + + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + final Object result = instantiateNewInstance(context); + final Set seenProperties = new HashSet() { + public boolean add(Object e) { + if (!super.add(e)) { + throw new DuplicatePropertyException(((FastField)e).getName()); + } + return true; + } + }; + + Class resultType = result.getClass(); + while (reader.hasMoreChildren()) { + reader.moveDown(); + + String propertyName = mapper.realMember(resultType, reader.getNodeName()); + + if (mapper.shouldSerializeMember(resultType, propertyName)) { + boolean propertyExistsInClass = beanProvider.propertyDefinedInClass(propertyName, resultType); + + if (propertyExistsInClass) { + Class type = determineType(reader, result, propertyName); + Object value = context.convertAnother(result, type); + beanProvider.writeProperty(result, propertyName, value); + seenProperties.add(new FastField(resultType, propertyName)); + } else { + throw new MissingFieldException(resultType.getName(), propertyName); + } + } + reader.moveUp(); + } + + return result; + } + + private Object instantiateNewInstance(UnmarshallingContext context) { + Object result = context.currentObject(); + if (result == null) { + result = beanProvider.newInstance(context.getRequiredType()); + } + return result; + } + + private Class determineType(HierarchicalStreamReader reader, Object result, String fieldName) { + final String classAttributeName = classAttributeIdentifier != null ? classAttributeIdentifier : mapper.aliasForSystemAttribute("class"); + String classAttribute = classAttributeName == null ? null : reader.getAttribute(classAttributeName); + if (classAttribute != null) { + return mapper.realClass(classAttribute); + } else { + return mapper.defaultImplementationOf(beanProvider.getPropertyType(result, fieldName)); + } + } + + /** + * @deprecated As of 1.3 + */ + public static class DuplicateFieldException extends ConversionException { + public DuplicateFieldException(String msg) { + super(msg); + } + } + + /** + * Exception to indicate double processing of a property to avoid silent clobbering. + * + * @author Jörg Schaible + * @since 1.4.2 + */ + public static class DuplicatePropertyException extends ConversionException { + public DuplicatePropertyException(String msg) { + super("Duplicate property " + msg); + add("property", msg); + } + } +} \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/javabean/JavaBeanProvider.java b/xstream/src/java/com/thoughtworks/xstream/converters/javabean/JavaBeanProvider.java new file mode 100644 index 0000000..fb63b50 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/javabean/JavaBeanProvider.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. July 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.javabean; + + +/** + * @author Jörg Schaible + * + * @since 1.4 + */ +public interface JavaBeanProvider { + + Object newInstance(Class type); + + void visitSerializableProperties(Object object, Visitor visitor); + + void writeProperty(Object object, String propertyName, Object value); + + Class getPropertyType(Object object, String name); + + boolean propertyDefinedInClass(String name, Class type); + + /** + * Returns true if the Bean provider can instantiate the specified class + */ + boolean canInstantiate(Class type); + + public interface Visitor { + boolean shouldVisit(String name, Class definedIn); + void visit(String name, Class type, Class definedIn, Object value); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/javabean/NativePropertySorter.java b/xstream/src/java/com/thoughtworks/xstream/converters/javabean/NativePropertySorter.java new file mode 100644 index 0000000..fea1143 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/javabean/NativePropertySorter.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 16. July 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.javabean; + +import java.util.Map; + + +/** + * A sorter that keeps the natural order of the bean properties as they are returned by the + * JavaBean introspection. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class NativePropertySorter implements PropertySorter { + + public Map sort(final Class type, final Map nameMap) { + return nameMap; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/javabean/PropertyDictionary.java b/xstream/src/java/com/thoughtworks/xstream/converters/javabean/PropertyDictionary.java new file mode 100644 index 0000000..c5c6b19 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/javabean/PropertyDictionary.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 12. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.javabean; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import com.thoughtworks.xstream.converters.reflection.MissingFieldException; +import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; +import com.thoughtworks.xstream.core.Caching; +import com.thoughtworks.xstream.core.util.OrderRetainingMap; + + +/** + * Builds the properties maps for each bean and caches them. + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class PropertyDictionary implements Caching { + private transient Map propertyNameCache = Collections.synchronizedMap(new HashMap()); + private final PropertySorter sorter; + + public PropertyDictionary() { + this(new NativePropertySorter()); + } + + public PropertyDictionary(PropertySorter sorter) { + this.sorter = sorter; + } + + /** + * @deprecated As of 1.3.1, use {@link #propertiesFor(Class)} instead + */ + public Iterator serializablePropertiesFor(Class type) { + Collection beanProperties = new ArrayList(); + Collection descriptors = buildMap(type).values(); + for (Iterator iter = descriptors.iterator(); iter.hasNext();) { + PropertyDescriptor descriptor = (PropertyDescriptor)iter.next(); + if (descriptor.getReadMethod() != null && descriptor.getWriteMethod() != null) { + beanProperties.add(new BeanProperty(type, descriptor.getName(), descriptor + .getPropertyType())); + } + } + return beanProperties.iterator(); + } + + /** + * Locates a serializable property. + * + * @param cls + * @param name + * @deprecated As of 1.3.1, use {@link #propertyDescriptor(Class, String)} instead + */ + public BeanProperty property(Class cls, String name) { + BeanProperty beanProperty = null; + PropertyDescriptor descriptor = (PropertyDescriptor)buildMap(cls).get(name); + if (descriptor == null) { + throw new MissingFieldException(cls.getName(), name); + } + if (descriptor.getReadMethod() != null && descriptor.getWriteMethod() != null) { + beanProperty = new BeanProperty( + cls, descriptor.getName(), descriptor.getPropertyType()); + } + return beanProperty; + } + + public Iterator propertiesFor(Class type) { + return buildMap(type).values().iterator(); + } + + /** + * Locates a property descriptor. + * + * @param type + * @param name + */ + public PropertyDescriptor propertyDescriptor(Class type, String name) { + PropertyDescriptor descriptor = (PropertyDescriptor)buildMap(type).get(name); + if (descriptor == null) { + throw new MissingFieldException(type.getName(), name); + } + return descriptor; + } + + private Map buildMap(Class type) { + Map nameMap = (Map)propertyNameCache.get(type); + if (nameMap == null) { + BeanInfo beanInfo; + try { + beanInfo = Introspector.getBeanInfo(type, Object.class); + } catch (IntrospectionException e) { + throw new ObjectAccessException( + "Cannot get BeanInfo of type " + type.getName(), e); + } + nameMap = new OrderRetainingMap(); + PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); + for (int i = 0; i < propertyDescriptors.length; i++ ) { + PropertyDescriptor descriptor = propertyDescriptors[i]; + nameMap.put(descriptor.getName(), descriptor); + } + nameMap = sorter.sort(type, nameMap); + propertyNameCache.put(type, nameMap); + } + return nameMap; + } + + public void flushCache() { + propertyNameCache.clear(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/javabean/PropertySorter.java b/xstream/src/java/com/thoughtworks/xstream/converters/javabean/PropertySorter.java new file mode 100644 index 0000000..29819bb --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/javabean/PropertySorter.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 16. July 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.javabean; + +import java.beans.PropertyDescriptor; +import java.util.Map; + +/** + * An interface capable of sorting Java bean properties. Implement this interface if you + * want to customize the order in which XStream serializes the properties of a bean. + * + * @author Jörg Schaible + * @since 1.4 + */ +public interface PropertySorter { + + /** + * Sort the properties of a bean type. The method will be called with the class type + * that contains all the properties and a Map that retains the order in which the + * elements have been added. The sequence in which elements are returned by an iterator + * defines the processing order of the properties. An implementation may create a + * different Map with similar semantic, add all elements of the original map and return + * the new one. + * + * @param type the bean class that contains all the properties + * @param nameMap the map to sort, key is the property name, value the + * {@link PropertyDescriptor} + * @return the sorted nameMap + * @since 1.4 + */ + Map sort(Class type, Map nameMap); + +} \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractAttributedCharacterIteratorAttributeConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractAttributedCharacterIteratorAttributeConverter.java new file mode 100644 index 0000000..ac65fab --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractAttributedCharacterIteratorAttributeConverter.java @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. February 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.reflection; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; +import com.thoughtworks.xstream.core.util.Fields; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.text.AttributedCharacterIterator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + + +/** + * An abstract converter implementation for constants of + * {@link java.text.AttributedCharacterIterator.Attribute} and derived types. + * + * @author Jörg Schaible + * @since 1.2.2 + */ +public class AbstractAttributedCharacterIteratorAttributeConverter extends + AbstractSingleValueConverter { + + private static final Map instanceMaps = new HashMap(); + private static final Method getName; + static { + Method method = null; + try { + method = AttributedCharacterIterator.Attribute.class.getDeclaredMethod( + "getName", (Class[])null); + if (!method.isAccessible()) { + method.setAccessible(true); + } + } catch (SecurityException e) { + // ignore for now + } catch (NoSuchMethodException e) { + // ignore for now + } + getName = method; + } + + private final Class type; + private transient Map attributeMap; + + public AbstractAttributedCharacterIteratorAttributeConverter(final Class type) { + super(); + if (!AttributedCharacterIterator.Attribute.class.isAssignableFrom(type)) { + throw new IllegalArgumentException(type.getName() + + " is not a " + AttributedCharacterIterator.Attribute.class.getName()); + } + this.type = type; + readResolve(); + } + + public boolean canConvert(final Class type) { + return type == this.type && !attributeMap.isEmpty(); + } + + public String toString(final Object source) { + return getName((AttributedCharacterIterator.Attribute)source); + } + + private String getName(AttributedCharacterIterator.Attribute attribute) { + Exception ex = null; + if (getName != null) { + try { + return (String)getName.invoke(attribute, (Object[])null); + } catch (IllegalAccessException e) { + ex = e; + } catch (InvocationTargetException e) { + ex = e; + } + } + String s = attribute.toString(); + String className = attribute.getClass().getName(); + if (s.startsWith(className)) { + return s.substring(className.length()+1, s.length()-1); + } + throw new ConversionException("Cannot find name of attribute of type " + className, ex); + } + + public Object fromString(final String str) { + if (attributeMap.containsKey(str)) { + return attributeMap.get(str); + } + throw new ConversionException("Cannot find attribute of type " + type.getName() + " with name " + str); + } + + private Object readResolve() { + attributeMap = (Map)instanceMaps.get(type.getName()); + if (attributeMap == null) { + attributeMap = new HashMap(); + Field instanceMap = Fields.locate(type, Map.class, true); + if (instanceMap != null) { + try { + Map map = (Map)Fields.read(instanceMap, null); + if (map != null) { + boolean valid = true; + for (Iterator iter = map.entrySet().iterator(); valid && iter.hasNext(); ) { + Map.Entry entry = (Map.Entry)iter.next(); + valid = entry.getKey().getClass() == String.class && entry.getValue().getClass() == type; + } + if (valid) { + attributeMap.putAll(map); + } + } + } catch (ObjectAccessException e) { + } + } + if (attributeMap.isEmpty()) { + try { + Field[] fields = type.getDeclaredFields(); + for(int i = 0; i < fields.length; ++i) { + if(fields[i].getType() == type == Modifier.isStatic(fields[i].getModifiers())) { + AttributedCharacterIterator.Attribute attribute = + (AttributedCharacterIterator.Attribute)Fields.read(fields[i], null); + attributeMap.put(toString(attribute), attribute); + } + } + } catch (SecurityException e) { + attributeMap.clear(); + } catch (ObjectAccessException e) { + attributeMap.clear(); + } catch (NoClassDefFoundError e) { + attributeMap.clear(); + } + } + instanceMaps.put(type.getName(), attributeMap); + } + return this; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java new file mode 100644 index 0000000..ffde863 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java @@ -0,0 +1,683 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 02. March 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.reflection; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.core.Caching; +import com.thoughtworks.xstream.core.ReferencingMarshallingContext; +import com.thoughtworks.xstream.core.util.ArrayIterator; +import com.thoughtworks.xstream.core.util.FastField; +import com.thoughtworks.xstream.core.util.HierarchicalStreams; +import com.thoughtworks.xstream.core.util.Primitives; +import com.thoughtworks.xstream.core.util.SerializationMembers; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.CannotResolveClassException; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.AbstractList; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + + +public abstract class AbstractReflectionConverter implements Converter, Caching { + + protected final ReflectionProvider reflectionProvider; + protected final Mapper mapper; + /** + * @deprecated As of 1.4.8, use {@link #serializationMembers}. + */ + protected transient SerializationMethodInvoker serializationMethodInvoker; + protected transient SerializationMembers serializationMembers; + private transient ReflectionProvider pureJavaReflectionProvider; + + public AbstractReflectionConverter(Mapper mapper, ReflectionProvider reflectionProvider) { + this.mapper = mapper; + this.reflectionProvider = reflectionProvider; + serializationMethodInvoker = new SerializationMethodInvoker(); + serializationMembers = serializationMethodInvoker.serializationMembers; + } + + protected boolean canAccess(Class type) { + try { + reflectionProvider.getFieldOrNull(type, "%"); + return true; + } catch (NoClassDefFoundError e) { + // restricted type in GAE + } + return false; + } + + public void marshal(Object original, final HierarchicalStreamWriter writer, + final MarshallingContext context) { + final Object source = serializationMembers.callWriteReplace(original); + + if (source != original && context instanceof ReferencingMarshallingContext) { + ((ReferencingMarshallingContext)context).replace(original, source); + } + if (source.getClass() != original.getClass()) { + String attributeName = mapper.aliasForSystemAttribute("resolves-to"); + if (attributeName != null) { + writer.addAttribute(attributeName, mapper.serializedClass(source.getClass())); + } + context.convertAnother(source); + } else { + doMarshal(source, writer, context); + } + } + + protected void doMarshal(final Object source, final HierarchicalStreamWriter writer, + final MarshallingContext context) { + final List fields = new ArrayList(); + final Map defaultFieldDefinition = new HashMap(); + + // Attributes might be preferred to child elements ... + reflectionProvider.visitSerializableFields(source, new ReflectionProvider.Visitor() { + final Set writtenAttributes = new HashSet(); + + public void visit(String fieldName, Class type, Class definedIn, Object value) { + if (!mapper.shouldSerializeMember(definedIn, fieldName)) { + return; + } + if (!defaultFieldDefinition.containsKey(fieldName)) { + Class lookupType = source.getClass(); + // See XSTR-457 and OmitFieldsTest + if (definedIn != source.getClass() + && !mapper.shouldSerializeMember(lookupType, fieldName)) { + lookupType = definedIn; + } + defaultFieldDefinition.put( + fieldName, reflectionProvider.getField(lookupType, fieldName)); + } + + SingleValueConverter converter = mapper.getConverterFromItemType( + fieldName, type, definedIn); + if (converter != null) { + final String attribute = mapper.aliasForAttribute(mapper.serializedMember( + definedIn, fieldName)); + if (value != null) { + if (writtenAttributes.contains(fieldName)) { // TODO: use attribute + throw new ConversionException("Cannot write field with name '" + + fieldName + + "' twice as attribute for object of type " + + source.getClass().getName()); + } + final String str = converter.toString(value); + if (str != null) { + writer.addAttribute(attribute, str); + } + } + writtenAttributes.add(fieldName); // TODO: use attribute + } else { + fields.add(new FieldInfo(fieldName, type, definedIn, value)); + } + } + }); + + new Object() { + { + for (Iterator fieldIter = fields.iterator(); fieldIter.hasNext();) { + FieldInfo info = (FieldInfo)fieldIter.next(); + if (info.value != null) { + Mapper.ImplicitCollectionMapping mapping = mapper + .getImplicitCollectionDefForFieldName( + source.getClass(), info.fieldName); + if (mapping != null) { + if (context instanceof ReferencingMarshallingContext) { + if (info.value != Collections.EMPTY_LIST + && info.value != Collections.EMPTY_SET + && info.value != Collections.EMPTY_MAP) { + ReferencingMarshallingContext refContext = (ReferencingMarshallingContext)context; + refContext.registerImplicit(info.value); + } + } + final boolean isCollection = info.value instanceof Collection; + final boolean isMap = info.value instanceof Map; + final boolean isEntry = isMap && mapping.getKeyFieldName() == null; + final boolean isArray = info.value.getClass().isArray(); + for (Iterator iter = isArray + ? new ArrayIterator(info.value) + : isCollection ? ((Collection)info.value).iterator() : isEntry + ? ((Map)info.value).entrySet().iterator() + : ((Map)info.value).values().iterator(); iter.hasNext();) { + Object obj = iter.next(); + final String itemName; + final Class itemType; + if (obj == null) { + itemType = Object.class; + itemName = mapper.serializedClass(null); + } else if (isEntry) { + final String entryName = mapping.getItemFieldName() != null + ? mapping.getItemFieldName() + : mapper.serializedClass(Map.Entry.class); + Map.Entry entry = (Map.Entry)obj; + ExtendedHierarchicalStreamWriterHelper.startNode( + writer, entryName, entry.getClass()); + writeItem(entry.getKey(), context, writer); + writeItem(entry.getValue(), context, writer); + writer.endNode(); + continue; + } else if (mapping.getItemFieldName() != null) { + itemType = mapping.getItemType(); + itemName = mapping.getItemFieldName(); + } else { + itemType = obj.getClass(); + itemName = mapper.serializedClass(itemType); + } + writeField( + info.fieldName, itemName, itemType, info.definedIn, obj); + } + } else { + writeField( + info.fieldName, null, info.type, info.definedIn, info.value); + } + } + } + + } + + void writeField(String fieldName, String aliasName, Class fieldType, + Class definedIn, Object newObj) { + Class actualType = newObj != null ? newObj.getClass() : fieldType; + ExtendedHierarchicalStreamWriterHelper.startNode(writer, aliasName != null + ? aliasName + : mapper.serializedMember(source.getClass(), fieldName), actualType); + + if (newObj != null) { + Class defaultType = mapper.defaultImplementationOf(fieldType); + if (!actualType.equals(defaultType)) { + String serializedClassName = mapper.serializedClass(actualType); + if (!serializedClassName.equals(mapper.serializedClass(defaultType))) { + String attributeName = mapper.aliasForSystemAttribute("class"); + if (attributeName != null) { + writer.addAttribute(attributeName, serializedClassName); + } + } + } + + final Field defaultField = (Field)defaultFieldDefinition.get(fieldName); + if (defaultField.getDeclaringClass() != definedIn) { + String attributeName = mapper.aliasForSystemAttribute("defined-in"); + if (attributeName != null) { + writer.addAttribute( + attributeName, mapper.serializedClass(definedIn)); + } + } + + Field field = reflectionProvider.getField(definedIn, fieldName); + marshallField(context, newObj, field); + } + writer.endNode(); + } + + void writeItem(Object item, MarshallingContext context, + HierarchicalStreamWriter writer) { + if (item == null) { + String name = mapper.serializedClass(null); + ExtendedHierarchicalStreamWriterHelper.startNode( + writer, name, Mapper.Null.class); + writer.endNode(); + } else { + String name = mapper.serializedClass(item.getClass()); + ExtendedHierarchicalStreamWriterHelper.startNode( + writer, name, item.getClass()); + context.convertAnother(item); + writer.endNode(); + } + } + }; + } + + protected void marshallField(final MarshallingContext context, Object newObj, Field field) { + context.convertAnother( + newObj, mapper.getLocalConverter(field.getDeclaringClass(), field.getName())); + } + + public Object unmarshal(final HierarchicalStreamReader reader, + final UnmarshallingContext context) { + Object result = instantiateNewInstance(reader, context); + result = doUnmarshal(result, reader, context); + return serializationMembers.callReadResolve(result); + } + + public Object doUnmarshal(final Object result, final HierarchicalStreamReader reader, + final UnmarshallingContext context) { + final Class resultType = result.getClass(); + final Set seenFields = new HashSet() { + public boolean add(Object e) { + if (!super.add(e)) { + throw new DuplicateFieldException(((FastField)e).getName()); + } + return true; + } + }; + + // process attributes before recursing into child elements. + Iterator it = reader.getAttributeNames(); + while (it.hasNext()) { + String attrAlias = (String)it.next(); + // TODO: realMember should return FastField + String attrName = mapper + .realMember(resultType, mapper.attributeForAlias(attrAlias)); + Field field = reflectionProvider.getFieldOrNull(resultType, attrName); + if (field != null && shouldUnmarshalField(field)) { + Class classDefiningField = field.getDeclaringClass(); + if (!mapper.shouldSerializeMember(classDefiningField, attrName)) { + continue; + } + + // we need a converter that produces a string representation only + SingleValueConverter converter = mapper.getConverterFromAttribute( + classDefiningField, attrName, field.getType()); + Class type = field.getType(); + if (converter != null) { + Object value = converter.fromString(reader.getAttribute(attrAlias)); + if (type.isPrimitive()) { + type = Primitives.box(type); + } + if (value != null && !type.isAssignableFrom(value.getClass())) { + throw new ConversionException("Cannot convert type " + + value.getClass().getName() + + " to type " + + type.getName()); + } + seenFields.add(new FastField(classDefiningField, attrName)); + reflectionProvider.writeField(result, attrName, value, classDefiningField); + } + } + } + + Map implicitCollectionsForCurrentObject = null; + while (reader.hasMoreChildren()) { + reader.moveDown(); + + String originalNodeName = reader.getNodeName(); + Class explicitDeclaringClass = readDeclaringClass(reader); + Class fieldDeclaringClass = explicitDeclaringClass == null + ? resultType + : explicitDeclaringClass; + String fieldName = mapper.realMember(fieldDeclaringClass, originalNodeName); + Mapper.ImplicitCollectionMapping implicitCollectionMapping = mapper + .getImplicitCollectionDefForFieldName(fieldDeclaringClass, fieldName); + final Object value; + String implicitFieldName = null; + Field field = null; + Class type = null; + if (implicitCollectionMapping == null) { + // no item of an implicit collection for this name ... do we have a field? + field = reflectionProvider.getFieldOrNull(fieldDeclaringClass, fieldName); + if (field == null) { + // it is not a field ... do we have a field alias? + Class itemType = mapper.getItemTypeForItemFieldName(resultType, fieldName); + if (itemType != null) { + String classAttribute = HierarchicalStreams.readClassAttribute( + reader, mapper); + if (classAttribute != null) { + type = mapper.realClass(classAttribute); + } else { + type = itemType; + } + } else { + // it is not an alias ... do we have an element of an implicit + // collection based on type only? + try { + type = mapper.realClass(originalNodeName); + implicitFieldName = mapper.getFieldNameForItemTypeAndName( + context.getRequiredType(), type, originalNodeName); + } catch (CannotResolveClassException e) { + // type stays null ... + } + if (type == null || (type != null && implicitFieldName == null)) { + // either not a type or element is a type alias, but does not + // belong to an implicit field + handleUnknownField( + explicitDeclaringClass, fieldName, resultType, originalNodeName); + + // element is unknown in declaring class, ignore it now + type = null; + } + } + if (type == null) { + // no type, no value + value = null; + } else { + if (Map.Entry.class.equals(type)) { + // it is an element of an implicit map with two elements now for + // key and value + reader.moveDown(); + final Object key = context.convertAnother( + result, HierarchicalStreams.readClassType(reader, mapper)); + reader.moveUp(); + reader.moveDown(); + final Object v = context.convertAnother( + result, HierarchicalStreams.readClassType(reader, mapper)); + reader.moveUp(); + value = Collections.singletonMap(key, v) + .entrySet().iterator().next(); + } else { + // recurse info hierarchy + value = context.convertAnother(result, type); + } + } + } else { + boolean fieldAlreadyChecked = false; + + // we have a field, but do we have to address a hidden one? + if (explicitDeclaringClass == null) { + while (field != null + && !(fieldAlreadyChecked = shouldUnmarshalField(field) + && mapper.shouldSerializeMember( + field.getDeclaringClass(), fieldName))) { + field = reflectionProvider.getFieldOrNull(field + .getDeclaringClass() + .getSuperclass(), fieldName); + } + } + if (field != null + && (fieldAlreadyChecked || (shouldUnmarshalField(field) && mapper + .shouldSerializeMember(field.getDeclaringClass(), fieldName)))) { + + String classAttribute = HierarchicalStreams.readClassAttribute( + reader, mapper); + if (classAttribute != null) { + type = mapper.realClass(classAttribute); + } else { + type = mapper.defaultImplementationOf(field.getType()); + } + // TODO the reflection provider should already return the proper field + value = unmarshallField(context, result, type, field); + Class definedType = field.getType(); + if (!definedType.isPrimitive()) { + type = definedType; + } + } else { + value = null; + } + } + } else { + // we have an implicit collection with defined names + implicitFieldName = implicitCollectionMapping.getFieldName(); + type = implicitCollectionMapping.getItemType(); + if (type == null) { + String classAttribute = HierarchicalStreams.readClassAttribute( + reader, mapper); + type = mapper.realClass(classAttribute != null + ? classAttribute + : originalNodeName); + } + value = context.convertAnother(result, type); + } + + if (value != null && !type.isAssignableFrom(value.getClass())) { + throw new ConversionException("Cannot convert type " + + value.getClass().getName() + + " to type " + + type.getName()); + } + + if (field != null) { + reflectionProvider.writeField(result, fieldName, value, field.getDeclaringClass()); + seenFields.add(new FastField(field.getDeclaringClass(), fieldName)); + } else if (type != null) { + if (implicitFieldName == null) { + // look for implicit field + implicitFieldName = mapper.getFieldNameForItemTypeAndName( + context.getRequiredType(), + value != null ? value.getClass() : Mapper.Null.class, + originalNodeName); + } + if (implicitCollectionsForCurrentObject == null) { + implicitCollectionsForCurrentObject = new HashMap(); + } + writeValueToImplicitCollection( + value, implicitCollectionsForCurrentObject, result, implicitFieldName); + } + + reader.moveUp(); + } + + if (implicitCollectionsForCurrentObject != null) { + for (Iterator iter = implicitCollectionsForCurrentObject.entrySet().iterator(); iter + .hasNext();) { + Map.Entry entry = (Map.Entry)iter.next(); + Object value = entry.getValue(); + if (value instanceof ArraysList) { + Object array = ((ArraysList)value).toPhysicalArray(); + reflectionProvider.writeField(result, (String)entry.getKey(), array, null); + } + } + } + + return result; + } + + protected Object unmarshallField(final UnmarshallingContext context, final Object result, + Class type, Field field) { + return context.convertAnother( + result, type, mapper.getLocalConverter(field.getDeclaringClass(), field.getName())); + } + + protected boolean shouldUnmarshalTransientFields() { + return false; + } + + protected boolean shouldUnmarshalField(Field field) { + return !(Modifier.isTransient(field.getModifiers()) && !shouldUnmarshalTransientFields()); + } + + private void handleUnknownField(Class classDefiningField, String fieldName, + Class resultType, String originalNodeName) { + if (classDefiningField == null) { + for (Class cls = resultType; cls != null; cls = cls.getSuperclass()) { + if (!mapper.shouldSerializeMember(cls, originalNodeName)) { + return; + } + } + } + throw new UnknownFieldException(resultType.getName(), fieldName); + } + + private void writeValueToImplicitCollection(Object value, Map implicitCollections, Object result, String implicitFieldName) { + Collection collection = (Collection)implicitCollections.get(implicitFieldName); + if (collection == null) { + Class physicalFieldType = reflectionProvider.getFieldType( + result, implicitFieldName, null); + if (physicalFieldType.isArray()) { + collection = new ArraysList(physicalFieldType); + } else { + Class fieldType = mapper.defaultImplementationOf(physicalFieldType); + if (!(Collection.class.isAssignableFrom(fieldType) || Map.class + .isAssignableFrom(fieldType))) { + throw new ObjectAccessException( + "Field " + + implicitFieldName + + " of " + + result.getClass().getName() + + " is configured for an implicit Collection or Map, but field is of type " + + fieldType.getName()); + } + if (pureJavaReflectionProvider == null) { + pureJavaReflectionProvider = new PureJavaReflectionProvider(); + } + Object instance = pureJavaReflectionProvider.newInstance(fieldType); + if (instance instanceof Collection) { + collection = (Collection)instance; + } else { + Mapper.ImplicitCollectionMapping implicitCollectionMapping = mapper + .getImplicitCollectionDefForFieldName(result.getClass(), implicitFieldName); + collection = new MappingList( + (Map)instance, implicitCollectionMapping.getKeyFieldName()); + } + reflectionProvider.writeField(result, implicitFieldName, instance, null); + } + implicitCollections.put(implicitFieldName, collection); + } + collection.add(value); + } + + private Class readDeclaringClass(HierarchicalStreamReader reader) { + String attributeName = mapper.aliasForSystemAttribute("defined-in"); + String definedIn = attributeName == null ? null : reader.getAttribute(attributeName); + return definedIn == null ? null : mapper.realClass(definedIn); + } + + protected Object instantiateNewInstance(HierarchicalStreamReader reader, + UnmarshallingContext context) { + String attributeName = mapper.aliasForSystemAttribute("resolves-to"); + String readResolveValue = attributeName == null ? null : reader + .getAttribute(attributeName); + Object currentObject = context.currentObject(); + if (currentObject != null) { + return currentObject; + } else if (readResolveValue != null) { + return reflectionProvider.newInstance(mapper.realClass(readResolveValue)); + } else { + return reflectionProvider.newInstance(context.getRequiredType()); + } + } + + public void flushCache() { + serializationMethodInvoker.flushCache(); + } + + protected Object readResolve() { + serializationMethodInvoker = new SerializationMethodInvoker(); + serializationMembers = serializationMethodInvoker.serializationMembers; + return this; + } + + public static class DuplicateFieldException extends ConversionException { + public DuplicateFieldException(String msg) { + super("Duplicate field " + msg); + add("field", msg); + } + } + + public static class UnknownFieldException extends ConversionException { + public UnknownFieldException(String type, String field) { + super("No such field " + type + "." + field); + add("field", field); + } + } + + private static class FieldInfo { + final String fieldName; + final Class type; + final Class definedIn; + final Object value; + + FieldInfo(String fieldName, Class type, Class definedIn, Object value) { + this.fieldName = fieldName; + this.type = type; + this.definedIn = definedIn; + this.value = value; + } + } + + private static class ArraysList extends ArrayList { + final Class physicalFieldType; + + ArraysList(Class physicalFieldType) { + this.physicalFieldType = physicalFieldType; + } + + Object toPhysicalArray() { + Object[] objects = toArray(); + Object array = Array.newInstance( + physicalFieldType.getComponentType(), objects.length); + if (physicalFieldType.getComponentType().isPrimitive()) { + for (int i = 0; i < objects.length; ++i) { + Array.set(array, i, Array.get(objects, i)); + } + } else { + System.arraycopy(objects, 0, array, 0, objects.length); + } + return array; + } + } + + private class MappingList extends AbstractList { + + private final Map map; + private final String keyFieldName; + private final Map fieldCache = new HashMap(); + + public MappingList(Map map, String keyFieldName) { + this.map = map; + this.keyFieldName = keyFieldName; + } + + public boolean add(Object object) { + if (object == null) { + boolean containsNull = !map.containsKey(null); + map.put(null, null); + return containsNull; + } + Class itemType = object.getClass(); + + if (keyFieldName != null) { + Field field = (Field)fieldCache.get(itemType); + if (field == null) { + field = reflectionProvider.getField(itemType, keyFieldName); + fieldCache.put(itemType, field); + } + if (field != null) { + try { + Object key = field.get(object); + return map.put(key, object) == null; + } catch (IllegalArgumentException e) { + throw new ObjectAccessException("Could not get field " + + field.getClass() + + "." + + field.getName(), e); + } catch (IllegalAccessException e) { + throw new ObjectAccessException("Could not get field " + + field.getClass() + + "." + + field.getName(), e); + } + } + } else if (object instanceof Map.Entry) { + final Map.Entry entry = (Map.Entry)object; + return map.put(entry.getKey(), entry.getValue()) == null; + } + + throw new ConversionException("Element of type " + + object.getClass().getName() + + " is not defined as entry for map of type " + + map.getClass().getName()); + } + + public Object get(int index) { + throw new UnsupportedOperationException(); + } + + public int size() { + return map.size(); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/CGLIBEnhancedConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/CGLIBEnhancedConverter.java new file mode 100644 index 0000000..6ba08cc --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/CGLIBEnhancedConverter.java @@ -0,0 +1,498 @@ +/* + * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2013, 2014, 2015 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. April 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.reflection; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.core.ClassLoaderReference; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.CGLIBMapper; +import com.thoughtworks.xstream.mapper.Mapper; + +import net.sf.cglib.proxy.Callback; +import net.sf.cglib.proxy.CallbackFilter; +import net.sf.cglib.proxy.Enhancer; +import net.sf.cglib.proxy.Factory; +import net.sf.cglib.proxy.MethodInterceptor; +import net.sf.cglib.proxy.NoOp; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + + +/** + * Converts a proxy created by the CGLIB {@link Enhancer}. Such a proxy is recreated while + * deserializing the proxy. The converter does only work, if
+ *
    + *
  • the DefaultNamingPolicy is used for the proxy's name
  • + *
  • the proxy uses a factory or only one Callback is registered
  • + *
  • a possible super class has at least a protected default constructor
  • + *
+ * Note, that the this converter relies on the CGLIBMapper. + * + * @author Jörg Schaible + * @since 1.2 + */ +public class CGLIBEnhancedConverter extends SerializableConverter { + private static String DEFAULT_NAMING_MARKER = "$$EnhancerByCGLIB$$"; + private static String CALLBACK_MARKER = "CGLIB$CALLBACK_"; + private transient Map fieldCache; + + /** + * Construct a CGLIBEnhancedConverter. + * @param mapper the mapper chain instance + * @param reflectionProvider the reflection provider + * @param classLoaderReference the reference to the {@link ClassLoader} of the XStream instance + * @since 1.4.5 + */ + public CGLIBEnhancedConverter(Mapper mapper, ReflectionProvider reflectionProvider, ClassLoaderReference classLoaderReference) { + super(mapper, new CGLIBFilteringReflectionProvider(reflectionProvider), classLoaderReference); + this.fieldCache = new HashMap(); + } + + /** + * @deprecated As of 1.4.5 use {@link #CGLIBEnhancedConverter(Mapper, ReflectionProvider, ClassLoaderReference)} + */ + public CGLIBEnhancedConverter(Mapper mapper, ReflectionProvider reflectionProvider, ClassLoader classLoader) { + super(mapper, new CGLIBFilteringReflectionProvider(reflectionProvider), classLoader); + this.fieldCache = new HashMap(); + } + + /** + * @deprecated As of 1.4 use {@link #CGLIBEnhancedConverter(Mapper, ReflectionProvider, ClassLoaderReference)} + */ + public CGLIBEnhancedConverter(Mapper mapper, ReflectionProvider reflectionProvider) { + this(mapper, new CGLIBFilteringReflectionProvider(reflectionProvider), CGLIBEnhancedConverter.class.getClassLoader()); + } + + public boolean canConvert(Class type) { + return (Enhancer.isEnhanced(type) && type.getName().indexOf(DEFAULT_NAMING_MARKER) > 0) + || type == CGLIBMapper.Marker.class; + } + + public void marshal(Object source, HierarchicalStreamWriter writer, + MarshallingContext context) { + Class type = source.getClass(); + boolean hasFactory = Factory.class.isAssignableFrom(type); + ExtendedHierarchicalStreamWriterHelper.startNode(writer, "type", type); + context.convertAnother(type.getSuperclass()); + writer.endNode(); + writer.startNode("interfaces"); + Class[] interfaces = type.getInterfaces(); + for (int i = 0; i < interfaces.length; i++ ) { + if (interfaces[i] == Factory.class) { + continue; + } + ExtendedHierarchicalStreamWriterHelper.startNode(writer, mapper + .serializedClass(interfaces[i].getClass()), interfaces[i].getClass()); + context.convertAnother(interfaces[i]); + writer.endNode(); + } + writer.endNode(); + writer.startNode("hasFactory"); + writer.setValue(String.valueOf(hasFactory)); + writer.endNode(); + Map callbackIndexMap = null; + Callback[] callbacks = hasFactory + ? ((Factory)source).getCallbacks() + : getCallbacks(source); + if (callbacks.length > 1) { + if (hasFactory) { + callbackIndexMap = createCallbackIndexMap((Factory)source); + } else { + ConversionException exception = new ConversionException( + "Cannot handle CGLIB enhanced proxies without factory that have multiple callbacks"); + exception.add("proxy superclass", type.getSuperclass().getName()); + exception.add("number of callbacks", String.valueOf(callbacks.length)); + throw exception; + } + writer.startNode("callbacks"); + writer.startNode("mapping"); + context.convertAnother(callbackIndexMap); + writer.endNode(); + } + boolean hasInterceptor = false; + for (int i = 0; i < callbacks.length; i++ ) { + final Callback callback = callbacks[i]; + if (callback == null) { + String name = mapper.serializedClass(null); + writer.startNode(name); + writer.endNode(); + } else { + hasInterceptor = hasInterceptor + || MethodInterceptor.class.isAssignableFrom(callback.getClass()); + ExtendedHierarchicalStreamWriterHelper.startNode(writer, mapper + .serializedClass(callback.getClass()), callback.getClass()); + context.convertAnother(callback); + writer.endNode(); + } + } + if (callbacks.length > 1) { + writer.endNode(); + } + try { + final Field field = type.getDeclaredField("serialVersionUID"); + if (!field.isAccessible()) { + field.setAccessible(true); + } + long serialVersionUID = field.getLong(null); + ExtendedHierarchicalStreamWriterHelper.startNode( + writer, "serialVersionUID", String.class); + writer.setValue(String.valueOf(serialVersionUID)); + writer.endNode(); + } catch (NoSuchFieldException e) { + // OK, ignore + } catch (IllegalAccessException e) { + throw new ObjectAccessException("Access to serialVersionUID of " + + type.getName() + + " not allowed", e); + } + if (hasInterceptor) { + writer.startNode("instance"); + super.doMarshalConditionally(source, writer, context); + writer.endNode(); + } + } + + private Callback[] getCallbacks(Object source) { + Class type = source.getClass(); + List fields = (List)fieldCache.get(type.getName()); + if (fields == null) { + fields = new ArrayList(); + fieldCache.put(type.getName(), fields); + for (int i = 0; true; ++i) { + try { + Field field = type.getDeclaredField(CALLBACK_MARKER + i); + if (!field.isAccessible()) { + field.setAccessible(true); + } + fields.add(field); + } catch (NoSuchFieldException e) { + break; + } + } + } + List list = new ArrayList(); + for (int i = 0; i < fields.size(); ++i) { + try { + Field field = (Field)fields.get(i); + Object callback = field.get(source); + list.add(callback); + } catch (IllegalAccessException e) { + throw new ObjectAccessException("Access to " + + type.getName() + + "." + + CALLBACK_MARKER + + i + + " not allowed", e); + } + } + return (Callback[])list.toArray(new Callback[list.size()]); + } + + private Map createCallbackIndexMap(Factory source) { + Callback[] originalCallbacks = source.getCallbacks(); + Callback[] reverseEngineeringCallbacks = new Callback[originalCallbacks.length]; + Map callbackIndexMap = new HashMap(); + int idxNoOp = -1; + for (int i = 0; i < originalCallbacks.length; i++ ) { + Callback callback = originalCallbacks[i]; + if (callback == null) { + reverseEngineeringCallbacks[i] = null; + } else if (NoOp.class.isAssignableFrom(callback.getClass())) { + reverseEngineeringCallbacks[i] = NoOp.INSTANCE; + idxNoOp = i; + } else { + reverseEngineeringCallbacks[i] = createReverseEngineeredCallbackOfProperType( + callback, i, callbackIndexMap); + } + } + + try { + source.setCallbacks(reverseEngineeringCallbacks); + final Set interfaces = new HashSet(); + final Set methods = new HashSet(); + Class type = source.getClass(); + do { + methods.addAll(Arrays.asList(type.getDeclaredMethods())); + methods.addAll(Arrays.asList(type.getMethods())); + Class[] implementedInterfaces = type.getInterfaces(); + interfaces.addAll(Arrays.asList(implementedInterfaces)); + type = type.getSuperclass(); + } while (type != null); + for (final Iterator iterator = interfaces.iterator(); iterator.hasNext();) { + type = (Class)iterator.next(); + methods.addAll(Arrays.asList(type.getDeclaredMethods())); + } + for (final Iterator iter = methods.iterator(); iter.hasNext();) { + final Method method = (Method)iter.next(); + if (!method.isAccessible()) { + method.setAccessible(true); + } + if (Factory.class.isAssignableFrom(method.getDeclaringClass()) + || (method.getModifiers() & (Modifier.FINAL | Modifier.STATIC)) > 0) { + iter.remove(); + continue; + } + Class[] parameterTypes = method.getParameterTypes(); + Method calledMethod = method; + try { + if ((method.getModifiers() & Modifier.ABSTRACT) > 0) { + calledMethod = source.getClass().getMethod( + method.getName(), method.getParameterTypes()); + } + callbackIndexMap.put(null, method); + calledMethod.invoke(source, parameterTypes == null + ? (Object[])null + : createNullArguments(parameterTypes)); + } catch (IllegalAccessException e) { + throw new ObjectAccessException("Access to " + + calledMethod + + " not allowed", e); + } catch (InvocationTargetException e) { + // OK, ignore + } catch (NoSuchMethodException e) { + ConversionException exception = new ConversionException( + "CGLIB enhanced proxies wit abstract nethod that has not been implemented"); + exception.add("proxy superclass", type.getSuperclass().getName()); + exception.add("method", method.toString()); + throw exception; + } + if (callbackIndexMap.containsKey(method)) { + iter.remove(); + } + } + if (idxNoOp >= 0) { + Integer idx = new Integer(idxNoOp); + for (final Iterator iter = methods.iterator(); iter.hasNext();) { + callbackIndexMap.put(iter.next(), idx); + } + } + } finally { + source.setCallbacks(originalCallbacks); + } + + callbackIndexMap.remove(null); + return callbackIndexMap; + } + + private Object[] createNullArguments(Class[] parameterTypes) { + Object[] arguments = new Object[parameterTypes.length]; + for (int i = 0; i < arguments.length; i++ ) { + Class type = parameterTypes[i]; + if (type.isPrimitive()) { + if (type == byte.class) { + arguments[i] = new Byte((byte)0); + } else if (type == short.class) { + arguments[i] = new Short((short)0); + } else if (type == int.class) { + arguments[i] = new Integer(0); + } else if (type == long.class) { + arguments[i] = new Long(0); + } else if (type == float.class) { + arguments[i] = new Float(0); + } else if (type == double.class) { + arguments[i] = new Double(0); + } else if (type == char.class) { + arguments[i] = new Character('\0'); + } else { + arguments[i] = Boolean.FALSE; + } + } + } + return arguments; + } + + private Callback createReverseEngineeredCallbackOfProperType(Callback callback, int index, + Map callbackIndexMap) { + Class iface = null; + Class[] interfaces = callback.getClass().getInterfaces(); + for (int i = 0; i < interfaces.length; i++ ) { + if (Callback.class.isAssignableFrom(interfaces[i])) { + iface = interfaces[i]; + if (iface == Callback.class) { + ConversionException exception = new ConversionException( + "Cannot handle CGLIB callback"); + exception.add("CGLIB callback type", callback.getClass().getName()); + throw exception; + } + interfaces = iface.getInterfaces(); + if (Arrays.asList(interfaces).contains(Callback.class)) { + break; + } + i = -1; + } + } + return (Callback)Proxy.newProxyInstance( + iface.getClassLoader(), new Class[]{iface}, + new ReverseEngineeringInvocationHandler(index, callbackIndexMap)); + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + final Enhancer enhancer = new Enhancer(); + reader.moveDown(); + enhancer.setSuperclass((Class)context.convertAnother(null, Class.class)); + reader.moveUp(); + reader.moveDown(); + List interfaces = new ArrayList(); + while (reader.hasMoreChildren()) { + reader.moveDown(); + interfaces + .add(context.convertAnother(null, mapper.realClass(reader.getNodeName()))); + reader.moveUp(); + } + enhancer.setInterfaces((Class[])interfaces.toArray(new Class[interfaces.size()])); + reader.moveUp(); + reader.moveDown(); + boolean useFactory = Boolean.valueOf(reader.getValue()).booleanValue(); + enhancer.setUseFactory(useFactory); + reader.moveUp(); + + List callbacksToEnhance = new ArrayList(); + List callbacks = new ArrayList(); + Map callbackIndexMap = null; + reader.moveDown(); + if ("callbacks".equals(reader.getNodeName())) { + reader.moveDown(); + callbackIndexMap = (Map)context.convertAnother(null, HashMap.class); + reader.moveUp(); + while (reader.hasMoreChildren()) { + reader.moveDown(); + readCallback(reader, context, callbacksToEnhance, callbacks); + reader.moveUp(); + } + } else { + readCallback(reader, context, callbacksToEnhance, callbacks); + } + enhancer.setCallbacks((Callback[])callbacksToEnhance + .toArray(new Callback[callbacksToEnhance.size()])); + if (callbackIndexMap != null) { + enhancer.setCallbackFilter(new ReverseEngineeredCallbackFilter(callbackIndexMap)); + } + reader.moveUp(); + Object result = null; + while (reader.hasMoreChildren()) { + reader.moveDown(); + if (reader.getNodeName().equals("serialVersionUID")) { + enhancer.setSerialVersionUID(Long.valueOf(reader.getValue())); + } else if (reader.getNodeName().equals("instance")) { + result = create(enhancer, callbacks, useFactory); + super.doUnmarshalConditionally(result, reader, context); + } + reader.moveUp(); + } + if (result == null) { + result = create(enhancer, callbacks, useFactory); + } + return serializationMembers.callReadResolve(result); + } + + private void readCallback(HierarchicalStreamReader reader, UnmarshallingContext context, + List callbacksToEnhance, List callbacks) { + Callback callback = (Callback)context.convertAnother(null, mapper.realClass(reader + .getNodeName())); + callbacks.add(callback); + if (callback == null) { + callbacksToEnhance.add(NoOp.INSTANCE); + } else { + callbacksToEnhance.add(callback); + } + } + + private Object create(final Enhancer enhancer, List callbacks, boolean useFactory) { + Object result = enhancer.create(); + if (useFactory) { + ((Factory)result).setCallbacks((Callback[])callbacks.toArray(new Callback[callbacks + .size()])); + } + return result; + } + + protected List hierarchyFor(Class type) { + List typeHierarchy = super.hierarchyFor(type); + // drop the CGLIB proxy + typeHierarchy.remove(typeHierarchy.size() - 1); + return typeHierarchy; + } + + protected Object readResolve() { + super.readResolve(); + fieldCache = new HashMap(); + return this; + } + + private static class CGLIBFilteringReflectionProvider extends ReflectionProviderWrapper { + + public CGLIBFilteringReflectionProvider(final ReflectionProvider reflectionProvider) { + super(reflectionProvider); + } + + public void visitSerializableFields(final Object object, final Visitor visitor) { + wrapped.visitSerializableFields(object, new Visitor() { + public void visit(String name, Class type, Class definedIn, Object value) { + if (!name.startsWith("CGLIB$")) { + visitor.visit(name, type, definedIn, value); + } + } + }); + } + } + + private static final class ReverseEngineeringInvocationHandler implements InvocationHandler { + private final Integer index; + private final Map indexMap; + + public ReverseEngineeringInvocationHandler(int index, Map indexMap) { + this.indexMap = indexMap; + this.index = new Integer(index); + } + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + indexMap.put(indexMap.get(null), index); + return null; + } + } + + private static class ReverseEngineeredCallbackFilter implements CallbackFilter { + + private final Map callbackIndexMap; + + public ReverseEngineeredCallbackFilter(Map callbackIndexMap) { + this.callbackIndexMap = callbackIndexMap; + } + + public int accept(Method method) { + if (!callbackIndexMap.containsKey(method)) { + ConversionException exception = new ConversionException( + "CGLIB callback not detected in reverse engineering"); + exception.add("CGLIB callback", method.toString()); + throw exception; + } + return ((Integer)callbackIndexMap.get(method)).intValue(); + } + + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ExternalizableConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ExternalizableConverter.java new file mode 100644 index 0000000..cd8a585 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ExternalizableConverter.java @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2013, 2014, 2015 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. August 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.reflection; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.core.ClassLoaderReference; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.core.ReferencingMarshallingContext; +import com.thoughtworks.xstream.core.util.CustomObjectInputStream; +import com.thoughtworks.xstream.core.util.CustomObjectOutputStream; +import com.thoughtworks.xstream.core.util.HierarchicalStreams; +import com.thoughtworks.xstream.core.util.SerializationMembers; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.NotActiveException; +import java.io.ObjectInputValidation; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.Map; + +/** + * Converts any object that implements the java.io.Externalizable interface, allowing compatibility with native Java + * serialization. + * + * @author Joe Walnes + */ +public class ExternalizableConverter implements Converter { + + private Mapper mapper; + private final ClassLoaderReference classLoaderReference; + private transient SerializationMembers serializationMembers; + + /** + * Construct an ExternalizableConverter. + * + * @param mapper the Mapper chain + * @param classLoaderReference the reference to XStream's {@link ClassLoader} instance + * @since 1.4.5 + */ + public ExternalizableConverter(Mapper mapper, ClassLoaderReference classLoaderReference) { + this.mapper = mapper; + this.classLoaderReference = classLoaderReference; + serializationMembers = new SerializationMembers(); + } + + /** + * @deprecated As of 1.4.5 use {@link #ExternalizableConverter(Mapper, ClassLoaderReference)} + */ + public ExternalizableConverter(Mapper mapper, ClassLoader classLoader) { + this(mapper, new ClassLoaderReference(classLoader)); + } + + /** + * @deprecated As of 1.4 use {@link #ExternalizableConverter(Mapper, ClassLoader)} + */ + public ExternalizableConverter(Mapper mapper) { + this(mapper, ExternalizableConverter.class.getClassLoader()); + } + + public boolean canConvert(Class type) { + return JVM.canCreateDerivedObjectOutputStream() && Externalizable.class.isAssignableFrom(type); + } + + public void marshal(final Object original, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final Object source = serializationMembers.callWriteReplace(original); + if (source != original && context instanceof ReferencingMarshallingContext) { + ((ReferencingMarshallingContext)context).replace(original, source); + } + if (source.getClass() != original.getClass()) { + final String attributeName = mapper.aliasForSystemAttribute("resolves-to"); + if (attributeName != null) { + writer.addAttribute(attributeName, mapper.serializedClass(source.getClass())); + } + context.convertAnother(source); + } else { + try { + Externalizable externalizable = (Externalizable)source; + CustomObjectOutputStream.StreamCallback callback = new CustomObjectOutputStream.StreamCallback() { + public void writeToStream(final Object object) { + if (object == null) { + writer.startNode("null"); + writer.endNode(); + } else { + ExtendedHierarchicalStreamWriterHelper.startNode(writer, mapper.serializedClass(object.getClass()), object.getClass()); + context.convertAnother(object); + writer.endNode(); + } + } + + public void writeFieldsToStream(final Map fields) { + throw new UnsupportedOperationException(); + } + + public void defaultWriteObject() { + throw new UnsupportedOperationException(); + } + + public void flush() { + writer.flush(); + } + + public void close() { + throw new UnsupportedOperationException("Objects are not allowed to call ObjectOutput.close() from writeExternal()"); + } + }; + final CustomObjectOutputStream objectOutput = CustomObjectOutputStream.getInstance(context, callback); + externalizable.writeExternal(objectOutput); + objectOutput.popCallback(); + } catch (IOException e) { + throw new ConversionException("Cannot serialize " + source.getClass().getName() + " using Externalization", e); + } + } + } + + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + final Class type = context.getRequiredType(); + final Constructor defaultConstructor; + try { + defaultConstructor = type.getDeclaredConstructor((Class[]) null); + if (!defaultConstructor.isAccessible()) { + defaultConstructor.setAccessible(true); + } + final Externalizable externalizable = (Externalizable) defaultConstructor.newInstance((Object[]) null); + CustomObjectInputStream.StreamCallback callback = new CustomObjectInputStream.StreamCallback() { + public Object readFromStream() { + reader.moveDown(); + Class type = HierarchicalStreams.readClassType(reader, mapper); + Object streamItem = context.convertAnother(externalizable, type); + reader.moveUp(); + return streamItem; + } + + public Map readFieldsFromStream() { + throw new UnsupportedOperationException(); + } + + public void defaultReadObject() { + throw new UnsupportedOperationException(); + } + + public void registerValidation(ObjectInputValidation validation, int priority) throws NotActiveException { + throw new NotActiveException("stream inactive"); + } + + public void close() { + throw new UnsupportedOperationException("Objects are not allowed to call ObjectInput.close() from readExternal()"); + } + }; + CustomObjectInputStream objectInput = CustomObjectInputStream.getInstance(context, callback, classLoaderReference); + externalizable.readExternal(objectInput); + objectInput.popCallback(); + return serializationMembers.callReadResolve(externalizable); + } catch (NoSuchMethodException e) { + throw new ConversionException("Cannot construct " + type.getClass() + ", missing default constructor", e); + } catch (InvocationTargetException e) { + throw new ConversionException("Cannot construct " + type.getClass(), e); + } catch (InstantiationException e) { + throw new ConversionException("Cannot construct " + type.getClass(), e); + } catch (IllegalAccessException e) { + throw new ConversionException("Cannot construct " + type.getClass(), e); + } catch (IOException e) { + throw new ConversionException("Cannot externalize " + type.getClass(), e); + } catch (ClassNotFoundException e) { + throw new ConversionException("Cannot externalize " + type.getClass(), e); + } + } + + private Object readResolve() { + serializationMembers = new SerializationMembers(); + return this; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/FieldDictionary.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/FieldDictionary.java new file mode 100644 index 0000000..a450e8f --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/FieldDictionary.java @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 14. May 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.reflection; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.thoughtworks.xstream.core.Caching; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.core.util.OrderRetainingMap; + + +/** + * A field dictionary instance caches information about classes fields. + * + * @author Joe Walnes + * @author Jörg Schaible + * @author Guilherme Silveira + */ +public class FieldDictionary implements Caching { + + private transient Map keyedByFieldNameCache; + private transient Map keyedByFieldKeyCache; + private final FieldKeySorter sorter; + + public FieldDictionary() { + this(new ImmutableFieldKeySorter()); + } + + public FieldDictionary(FieldKeySorter sorter) { + this.sorter = sorter; + init(); + } + + private void init() { + keyedByFieldNameCache = new HashMap(); + keyedByFieldKeyCache = new HashMap(); + keyedByFieldNameCache.put(Object.class, Collections.EMPTY_MAP); + keyedByFieldKeyCache.put(Object.class, Collections.EMPTY_MAP); + } + + /** + * Returns an iterator for all fields for some class + * + * @param cls the class you are interested on + * @return an iterator for its fields + * @deprecated As of 1.3, use {@link #fieldsFor(Class)} instead + */ + public Iterator serializableFieldsFor(Class cls) { + return fieldsFor(cls); + } + + /** + * Returns an iterator for all fields for some class + * + * @param cls the class you are interested on + * @return an iterator for its fields + */ + public Iterator fieldsFor(final Class cls) { + return buildMap(cls, true).values().iterator(); + } + + /** + * Returns an specific field of some class. If definedIn is null, it searches for the field + * named 'name' inside the class cls. If definedIn is different than null, tries to find the + * specified field name in the specified class cls which should be defined in class + * definedIn (either equals cls or a one of it's superclasses) + * + * @param cls the class where the field is to be searched + * @param name the field name + * @param definedIn the superclass (or the class itself) of cls where the field was defined + * @return the field itself + * @throws ObjectAccessException if no field can be found + */ + public Field field(Class cls, String name, Class definedIn) { + Field field = fieldOrNull(cls, name, definedIn); + if (field == null) { + throw new MissingFieldException(cls.getName(), name); + } else { + return field; + } + } + + /** + * Returns an specific field of some class. If definedIn is null, it searches for the field + * named 'name' inside the class cls. If definedIn is different than null, tries to find the + * specified field name in the specified class cls which should be defined in class + * definedIn (either equals cls or a one of it's superclasses) + * + * @param cls the class where the field is to be searched + * @param name the field name + * @param definedIn the superclass (or the class itself) of cls where the field was defined + * @return the field itself or null + * @since 1.4 + */ + public Field fieldOrNull(Class cls, String name, Class definedIn) { + Map fields = buildMap(cls, definedIn != null); + Field field = (Field)fields.get(definedIn != null + ? (Object)new FieldKey(name, definedIn, -1) + : (Object)name); + return field; + } + + private Map buildMap(final Class type, boolean tupleKeyed) { + Class cls = type; + synchronized (this) { + if (!keyedByFieldNameCache.containsKey(type)) { + final List superClasses = new ArrayList(); + while (!Object.class.equals(cls) && cls != null) { + superClasses.add(0, cls); + cls = cls.getSuperclass(); + } + Map lastKeyedByFieldName = Collections.EMPTY_MAP; + Map lastKeyedByFieldKey = Collections.EMPTY_MAP; + for (final Iterator iter = superClasses.iterator(); iter.hasNext();) { + cls = (Class)iter.next(); + if (!keyedByFieldNameCache.containsKey(cls)) { + final Map keyedByFieldName = new HashMap(lastKeyedByFieldName); + final Map keyedByFieldKey = new OrderRetainingMap(lastKeyedByFieldKey); + Field[] fields = cls.getDeclaredFields(); + if (JVM.reverseFieldDefinition()) { + for (int i = fields.length >> 1; i-- > 0;) { + final int idx = fields.length - i - 1; + final Field field = fields[i]; + fields[i] = fields[idx]; + fields[idx] = field; + } + } + for (int i = 0; i < fields.length; i++ ) { + Field field = fields[i]; + if (!field.isAccessible()) { + field.setAccessible(true); + } + FieldKey fieldKey = new FieldKey( + field.getName(), field.getDeclaringClass(), i); + Field existent = (Field)keyedByFieldName.get(field.getName()); + if (existent == null + // do overwrite statics + || ((existent.getModifiers() & Modifier.STATIC) != 0) + // overwrite non-statics with non-statics only + || (existent != null && ((field.getModifiers() & Modifier.STATIC) == 0))) { + keyedByFieldName.put(field.getName(), field); + } + keyedByFieldKey.put(fieldKey, field); + } + final Map sortedFieldKeys = sorter.sort(cls, keyedByFieldKey); + keyedByFieldNameCache.put(cls, keyedByFieldName); + keyedByFieldKeyCache.put(cls, sortedFieldKeys); + lastKeyedByFieldName = keyedByFieldName; + lastKeyedByFieldKey = sortedFieldKeys; + } else { + lastKeyedByFieldName = (Map)keyedByFieldNameCache.get(cls); + lastKeyedByFieldKey = (Map)keyedByFieldKeyCache.get(cls); + } + } + return tupleKeyed ? lastKeyedByFieldKey : lastKeyedByFieldName; + } + } + return (Map)(tupleKeyed + ? keyedByFieldKeyCache.get(type) + : keyedByFieldNameCache.get(type)); + } + + public synchronized void flushCache() { + Set objectTypeSet = Collections.singleton(Object.class); + keyedByFieldNameCache.keySet().retainAll(objectTypeSet); + keyedByFieldKeyCache.keySet().retainAll(objectTypeSet); + if (sorter instanceof Caching) { + ((Caching)sorter).flushCache(); + } + } + + protected Object readResolve() { + init(); + return this; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/FieldKey.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/FieldKey.java new file mode 100644 index 0000000..8e5a6d7 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/FieldKey.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 10. April 2007 by Guilherme Silveira + */ +package com.thoughtworks.xstream.converters.reflection; + +/** + * A field key. + * + * @author Guilherme Silveira + * @author Jörg Schaible + */ +public class FieldKey { + final private String fieldName; + final private Class declaringClass; + final private int depth; + final private int order; + + public FieldKey(String fieldName, Class declaringClass, int order) { + if (fieldName == null || declaringClass == null) { + throw new IllegalArgumentException("fieldName or declaringClass is null"); + } + this.fieldName = fieldName; + this.declaringClass = declaringClass; + this.order = order; + Class c = declaringClass; + int i = 0; + while (c.getSuperclass() != null) { + i++; + c = c.getSuperclass(); + } + depth = i; + } + + public String getFieldName() { + return this.fieldName; + } + + public Class getDeclaringClass() { + return this.declaringClass; + } + + public int getDepth() { + return this.depth; + } + + public int getOrder() { + return this.order; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof FieldKey)) return false; + + final FieldKey fieldKey = (FieldKey)o; + + if (!declaringClass.equals(fieldKey.declaringClass)) + return false; + if (!fieldName.equals(fieldKey.fieldName)) + return false; + + return true; + } + + public int hashCode() { + int result; + result = fieldName.hashCode(); + result = 29 * result +declaringClass.hashCode(); + return result; + } + + public String toString() { + return "FieldKey{" + + "order=" + + order + + ", writer=" + + depth + + ", declaringClass=" + + declaringClass + + ", fieldName='" + + fieldName + + "'" + + "}"; + } + +} \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/FieldKeySorter.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/FieldKeySorter.java new file mode 100644 index 0000000..774a088 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/FieldKeySorter.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 10. April 2007 by Guilherme Silveira + */ +package com.thoughtworks.xstream.converters.reflection; + +import java.util.Map; + + +/** + * An interface capable of sorting fields. Implement this interface if you want to customize the + * field order in which XStream serializes objects. + * + * @author Guilherme Silveira + * @since 1.2.2 + */ +public interface FieldKeySorter { + + /** + * Sort the fields of a type. The method will be called with the class type that contains + * all the fields and a Map that retains the order in which the elements have been added. + * The sequence in which elements are returned by an iterator defines the processing order + * of the fields. An implementation may create a different Map with similar semantic, add + * all elements of the original map and return the new one. + * + * @param type the class that contains all the fields + * @param keyedByFieldKey a Map containing a {@link FieldKey} as key element and a + * {@link java.lang.reflect.Field} as value. + * @return a Map with all the entries of the original Map + * @since 1.2.2 + */ + Map sort(Class type, Map keyedByFieldKey); + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ImmutableFieldKeySorter.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ImmutableFieldKeySorter.java new file mode 100644 index 0000000..db7b48e --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ImmutableFieldKeySorter.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 10. April 2007 by Guilherme Silveira + */ +package com.thoughtworks.xstream.converters.reflection; + +import java.util.Map; + +/** + * Does not change the order of the fields. + * + * @author Guilherme Silveira + * @since 1.2.2 + */ +public class ImmutableFieldKeySorter implements FieldKeySorter { + + public Map sort(Class type, Map keyedByFieldKey) { + return keyedByFieldKey; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/LambdaConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/LambdaConverter.java new file mode 100644 index 0000000..8f2f7ff --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/LambdaConverter.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2015 XStream Committer. + * All rights reserved. + * + * Created on 17. January 2015 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.reflection; + +import java.io.Serializable; + +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.core.ClassLoaderReference; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.core.util.Types; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + + +/** + * Converts a lambda type. + * + * The implementation maps any non-serializable lambda instance to {@code null}. + * + * @author Jörg Schaible + * @since 1.4.8 + */ +public class LambdaConverter extends SerializableConverter { + + /** + * Constructs a LambdaConverter. + * + * @param mapper + * @param reflectionProvider + * @param classLoaderReference + * @since 1.4.8 + */ + public LambdaConverter( + final Mapper mapper, final ReflectionProvider reflectionProvider, + final ClassLoaderReference classLoaderReference) { + super(mapper, reflectionProvider, classLoaderReference); + } + + @Override + public boolean canConvert(final Class type) { + return Types.isLambdaType(type) + && (JVM.canCreateDerivedObjectOutputStream() || !Serializable.class.isAssignableFrom(type)); + } + + @Override + public void marshal(final Object original, final HierarchicalStreamWriter writer, final MarshallingContext context) { + if (original instanceof Serializable) { + super.marshal(original, writer, context); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/MissingFieldException.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/MissingFieldException.java new file mode 100644 index 0000000..102fa92 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/MissingFieldException.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. October 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.reflection; + +/** + * Indicates a missing field or property creating an object. + * + * @author Nikita Levyankov + * @author Joerg Schaible + * @since 1.4.2 + */ +public class MissingFieldException extends ObjectAccessException { + + private final String fieldName; + private final String className; + + /** + * Construct a MissingFieldException. + * @param className the name of the class missing the field + * @param fieldName the name of the missed field + * @since 1.4.2 + */ + public MissingFieldException(final String className, final String fieldName) { + super("No field '" + fieldName + "' found in class '" + className + "'"); + this.className = className; + this.fieldName = fieldName; + } + + /** + * Retrieve the name of the missing field. + * @return the field name + * @since 1.4.2 + */ + public String getFieldName() { + return fieldName; + } + + /** + * Retrieve the name of the class with the missing field. + * @return the class name + * @since 1.4.2 + */ + protected String getClassName() { + return className; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/NativeFieldKeySorter.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/NativeFieldKeySorter.java new file mode 100644 index 0000000..4220a3b --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/NativeFieldKeySorter.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 17.05.2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.reflection; + +import java.util.Comparator; +import java.util.Map; +import java.util.TreeMap; + + +/** + * Sort the fields in their natural order. Fields are returned in their declaration order, + * fields of base classes first. + * + * @author Jörg Schaible + * @since 1.2.2 + */ +public class NativeFieldKeySorter implements FieldKeySorter { + + public Map sort(final Class type, final Map keyedByFieldKey) { + final Map map = new TreeMap(new Comparator() { + + public int compare(final Object o1, final Object o2) { + final FieldKey fieldKey1 = (FieldKey)o1; + final FieldKey fieldKey2 = (FieldKey)o2; + int i = fieldKey1.getDepth() - fieldKey2.getDepth(); + if (i == 0) { + i = fieldKey1.getOrder() - fieldKey2.getOrder(); + } + return i; + } + }); + map.putAll(keyedByFieldKey); + return map; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ObjectAccessException.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ObjectAccessException.java new file mode 100644 index 0000000..c3ac302 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ObjectAccessException.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.reflection; + +import com.thoughtworks.xstream.XStreamException; + +public class ObjectAccessException extends XStreamException { + public ObjectAccessException(String message) { + super(message); + } + + public ObjectAccessException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/PureJavaReflectionProvider.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/PureJavaReflectionProvider.java new file mode 100644 index 0000000..8158e37 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/PureJavaReflectionProvider.java @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.reflection; + +import com.thoughtworks.xstream.core.JVM; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectStreamClass; +import java.io.ObjectStreamConstants; +import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.util.Iterator; +import java.util.Map; +import java.util.WeakHashMap; + +/** + * Pure Java ObjectFactory that instantiates objects using standard Java reflection, however the types of objects + * that can be constructed are limited. + *

+ * Can newInstance: classes with public visibility, outer classes, static inner classes, classes with default constructors + * and any class that implements java.io.Serializable. + *

+ *

+ * Cannot newInstance: classes without public visibility, non-static inner classes, classes without default constructors. + * Note that any code in the constructor of a class will be executed when the ObjectFactory instantiates the object. + *

+ * @author Joe Walnes + */ +public class PureJavaReflectionProvider implements ReflectionProvider { + + private transient Map serializedDataCache; + protected FieldDictionary fieldDictionary; + + public PureJavaReflectionProvider() { + this(new FieldDictionary(new ImmutableFieldKeySorter())); + } + + public PureJavaReflectionProvider(FieldDictionary fieldDictionary) { + this.fieldDictionary = fieldDictionary; + init(); + } + + public Object newInstance(Class type) { + try { + Constructor[] constructors = type.getDeclaredConstructors(); + for (int i = 0; i < constructors.length; i++) { + final Constructor constructor = constructors[i]; + if (constructor.getParameterTypes().length == 0) { + if (!constructor.isAccessible()) { + constructor.setAccessible(true); + } + return constructor.newInstance(new Object[0]); + } + } + if (Serializable.class.isAssignableFrom(type)) { + return instantiateUsingSerialization(type); + } else { + throw new ObjectAccessException("Cannot construct " + type.getName() + + " as it does not have a no-args constructor"); + } + } catch (InstantiationException e) { + throw new ObjectAccessException("Cannot construct " + type.getName(), e); + } catch (IllegalAccessException e) { + throw new ObjectAccessException("Cannot construct " + type.getName(), e); + } catch (InvocationTargetException e) { + if (e.getTargetException() instanceof RuntimeException) { + throw (RuntimeException)e.getTargetException(); + } else if (e.getTargetException() instanceof Error) { + throw (Error)e.getTargetException(); + } else { + throw new ObjectAccessException("Constructor for " + type.getName() + " threw an exception", e.getTargetException()); + } + } + } + + private Object instantiateUsingSerialization(final Class type) { + try { + synchronized (serializedDataCache) { + byte[] data = (byte[]) serializedDataCache.get(type); + if (data == null) { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + DataOutputStream stream = new DataOutputStream(bytes); + stream.writeShort(ObjectStreamConstants.STREAM_MAGIC); + stream.writeShort(ObjectStreamConstants.STREAM_VERSION); + stream.writeByte(ObjectStreamConstants.TC_OBJECT); + stream.writeByte(ObjectStreamConstants.TC_CLASSDESC); + stream.writeUTF(type.getName()); + stream.writeLong(ObjectStreamClass.lookup(type).getSerialVersionUID()); + stream.writeByte(2); // classDescFlags (2 = Serializable) + stream.writeShort(0); // field count + stream.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA); + stream.writeByte(ObjectStreamConstants.TC_NULL); + data = bytes.toByteArray(); + serializedDataCache.put(type, data); + } + + ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(data)) { + protected Class resolveClass(ObjectStreamClass desc) + throws IOException, ClassNotFoundException { + return Class.forName(desc.getName(), false, type.getClassLoader()); + } + }; + return in.readObject(); + } + } catch (IOException e) { + throw new ObjectAccessException("Cannot create " + type.getName() + " by JDK serialization", e); + } catch (ClassNotFoundException e) { + throw new ObjectAccessException("Cannot find class " + e.getMessage(), e); + } + } + + public void visitSerializableFields(Object object, ReflectionProvider.Visitor visitor) { + for (Iterator iterator = fieldDictionary.fieldsFor(object.getClass()); iterator.hasNext();) { + Field field = (Field) iterator.next(); + if (!fieldModifiersSupported(field)) { + continue; + } + validateFieldAccess(field); + try { + Object value = field.get(object); + visitor.visit(field.getName(), field.getType(), field.getDeclaringClass(), value); + } catch (IllegalArgumentException e) { + throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); + } catch (IllegalAccessException e) { + throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); + } + } + } + + public void writeField(Object object, String fieldName, Object value, Class definedIn) { + Field field = fieldDictionary.field(object.getClass(), fieldName, definedIn); + validateFieldAccess(field); + try { + field.set(object, value); + } catch (IllegalArgumentException e) { + throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), e); + } catch (IllegalAccessException e) { + throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), e); + } + } + + public Class getFieldType(Object object, String fieldName, Class definedIn) { + return fieldDictionary.field(object.getClass(), fieldName, definedIn).getType(); + } + + /** + * @deprecated As of 1.4.5, use {@link #getFieldOrNull(Class, String)} instead + */ + public boolean fieldDefinedInClass(String fieldName, Class type) { + Field field = fieldDictionary.fieldOrNull(type, fieldName, null); + return field != null && fieldModifiersSupported(field); + } + + protected boolean fieldModifiersSupported(Field field) { + int modifiers = field.getModifiers(); + return !(Modifier.isStatic(modifiers) || Modifier.isTransient(modifiers)); + } + + protected void validateFieldAccess(Field field) { + if (Modifier.isFinal(field.getModifiers())) { + if (JVM.is15()) { + if (!field.isAccessible()) { + field.setAccessible(true); + } + } else { + throw new ObjectAccessException("Invalid final field " + + field.getDeclaringClass().getName() + "." + field.getName()); + } + } + } + + public Field getField(Class definedIn, String fieldName) { + return fieldDictionary.field(definedIn, fieldName, null); + } + + public Field getFieldOrNull(Class definedIn, String fieldName) { + return fieldDictionary.fieldOrNull(definedIn, fieldName, null); + } + + public void setFieldDictionary(FieldDictionary dictionary) { + this.fieldDictionary = dictionary; + } + + private Object readResolve() { + init(); + return this; + } + + protected void init() { + serializedDataCache = new WeakHashMap(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ReflectionConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ReflectionConverter.java new file mode 100644 index 0000000..aa7c3eb --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ReflectionConverter.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.reflection; + +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.mapper.Mapper; + +public class ReflectionConverter extends AbstractReflectionConverter { + + // Might be missing in Android + private final static Class eventHandlerType = JVM.loadClassForName("java.beans.EventHandler"); + private Class type; + + public ReflectionConverter(Mapper mapper, ReflectionProvider reflectionProvider) { + super(mapper, reflectionProvider); + } + + /** + * Construct a ReflectionConverter for an explicit type. + * + * @param mapper the mapper in use + * @param reflectionProvider the reflection provider in use + * @param type the explicit type to handle + * @since 1.4.7 + */ + public ReflectionConverter(Mapper mapper, ReflectionProvider reflectionProvider, Class type) { + this(mapper, reflectionProvider); + this.type = type; + } + + public boolean canConvert(Class type) { + return ((this.type != null && this.type == type) || (this.type == null && type != null && type != eventHandlerType)) + && canAccess(type); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ReflectionProvider.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ReflectionProvider.java new file mode 100644 index 0000000..286d9db --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ReflectionProvider.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2004, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.reflection; + +import java.lang.reflect.Field; + + +/** + * Provides core reflection services. + * + * @author Joe Walnes + */ +public interface ReflectionProvider { + + /** + * Creates a new instance of the specified type. It is in the responsibility of the + * implementation how such an instance is created. + * + * @param type the type to instantiate + * @return a new instance of this type + */ + Object newInstance(Class type); + + void visitSerializableFields(Object object, Visitor visitor); + + void writeField(Object object, String fieldName, Object value, Class definedIn); + + Class getFieldType(Object object, String fieldName, Class definedIn); + + /** + * @deprecated As of 1.4.5, use {@link #getFieldOrNull(Class, String)} instead + */ + boolean fieldDefinedInClass(String fieldName, Class type); + + /** + * A visitor interface for serializable fields defined in a class. + */ + interface Visitor { + + /** + * Callback for each visit + * + * @param name field name + * @param type field type + * @param definedIn where the field was defined + * @param value field value + */ + void visit(String name, Class type, Class definedIn, Object value); + } + + /** + * Returns a field defined in some class. + * + * @param definedIn class where the field was defined + * @param fieldName field name + * @return the field itself + * @throws ObjectAccessException if field does not exist + */ + Field getField(Class definedIn, String fieldName); + + /** + * Returns a field defined in some class. + * + * @param definedIn class where the field was defined + * @param fieldName field name + * @return the field itself or null + * @since 1.4.5 + */ + Field getFieldOrNull(Class definedIn, String fieldName); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ReflectionProviderWrapper.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ReflectionProviderWrapper.java new file mode 100644 index 0000000..e97da5a --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/ReflectionProviderWrapper.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. April 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.reflection; + +import java.lang.reflect.Field; + +/** + * A wrapper implementation for the ReflectionProvider. + * + * @author Jörg Schaible + * @since 1.2 + */ +public class ReflectionProviderWrapper implements ReflectionProvider { + + final protected ReflectionProvider wrapped; + + public ReflectionProviderWrapper(ReflectionProvider wrapper) { + this.wrapped = wrapper; + } + + /** + * @deprecated As of 1.4.5, use {@link #getFieldOrNull(Class, String)} instead + */ + public boolean fieldDefinedInClass(String fieldName, Class type) { + return this.wrapped.fieldDefinedInClass(fieldName, type); + } + + public Field getField(Class definedIn, String fieldName) { + return this.wrapped.getField(definedIn, fieldName); + } + + public Field getFieldOrNull(Class definedIn, String fieldName) { + return this.wrapped.getFieldOrNull(definedIn, fieldName); + } + + public Class getFieldType(Object object, String fieldName, Class definedIn) { + return this.wrapped.getFieldType(object, fieldName, definedIn); + } + + public Object newInstance(Class type) { + return this.wrapped.newInstance(type); + } + + public void visitSerializableFields(Object object, Visitor visitor) { + this.wrapped.visitSerializableFields(object, visitor); + } + + public void writeField(Object object, String fieldName, Object value, Class definedIn) { + this.wrapped.writeField(object, fieldName, value, definedIn); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SelfStreamingInstanceChecker.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SelfStreamingInstanceChecker.java new file mode 100644 index 0000000..6a45fe7 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SelfStreamingInstanceChecker.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. April 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.reflection; + +import com.thoughtworks.xstream.converters.Converter; + +/** + * A special converter that prevents self-serialization. The serializing XStream instance + * adds a converter of this type to prevent self-serialization and will throw an + * exception instead. + * + * @author Jörg Schaible + * @since 1.2 + * @deprecated As of 1.4.5 use {@link com.thoughtworks.xstream.core.util.SelfStreamingInstanceChecker} + */ +public class SelfStreamingInstanceChecker extends com.thoughtworks.xstream.core.util.SelfStreamingInstanceChecker { + + public SelfStreamingInstanceChecker(Converter defaultConverter, Object xstream) { + super(defaultConverter, xstream); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializableConverter.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializableConverter.java new file mode 100644 index 0000000..2825980 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializableConverter.java @@ -0,0 +1,499 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2012, 2013, 2014, 2015 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 21. December 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.reflection; + +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputValidation; +import java.io.ObjectStreamClass; +import java.io.ObjectStreamField; +import java.io.Serializable; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.core.ClassLoaderReference; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.core.util.CustomObjectInputStream; +import com.thoughtworks.xstream.core.util.CustomObjectOutputStream; +import com.thoughtworks.xstream.core.util.HierarchicalStreams; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + +/** + * Emulates the mechanism used by standard Java Serialization for classes that implement java.io.Serializable AND + * implement or inherit a custom readObject()/writeObject() method. + * + *

Supported features of serialization

+ *
    + *
  • readObject(), writeObject()
  • + *
  • class inheritance
  • + *
  • readResolve(), writeReplace()
  • + *
  • getFields(), putFields(), writeFields(), readFields()
  • + *
  • ObjectStreamField[] serialPersistentFields
  • + *
  • ObjectInputValidation
  • + *
+ * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class SerializableConverter extends AbstractReflectionConverter { + + private static final String ELEMENT_NULL = "null"; + private static final String ELEMENT_DEFAULT = "default"; + private static final String ELEMENT_UNSERIALIZABLE_PARENTS = "unserializable-parents"; + private static final String ATTRIBUTE_CLASS = "class"; + private static final String ATTRIBUTE_SERIALIZATION = "serialization"; + private static final String ATTRIBUTE_VALUE_CUSTOM = "custom"; + private static final String ELEMENT_FIELDS = "fields"; + private static final String ELEMENT_FIELD = "field"; + private static final String ATTRIBUTE_NAME = "name"; + + private final ClassLoaderReference classLoaderReference; + + /** + * Construct a SerializableConverter. + * + * @param mapper the mapper chain instance + * @param reflectionProvider the reflection provider + * @param classLoaderReference the reference to the {@link ClassLoader} of the XStream instance + * @since 1.4.5 + */ + public SerializableConverter(Mapper mapper, ReflectionProvider reflectionProvider, ClassLoaderReference classLoaderReference) { + super(mapper, new UnserializableParentsReflectionProvider(reflectionProvider)); + this.classLoaderReference = classLoaderReference; + } + + /** + * @deprecated As of 1.4.5 use {@link #SerializableConverter(Mapper, ReflectionProvider, ClassLoaderReference)} + */ + public SerializableConverter(Mapper mapper, ReflectionProvider reflectionProvider, ClassLoader classLoader) { + this(mapper, reflectionProvider, new ClassLoaderReference(classLoader)); + } + + /** + * @deprecated As of 1.4 use {@link #SerializableConverter(Mapper, ReflectionProvider, ClassLoaderReference)} + */ + public SerializableConverter(Mapper mapper, ReflectionProvider reflectionProvider) { + this(mapper, new UnserializableParentsReflectionProvider(reflectionProvider), new ClassLoaderReference(null)); + } + + public boolean canConvert(Class type) { + return JVM.canCreateDerivedObjectOutputStream() && isSerializable(type); + } + + private boolean isSerializable(Class type) { + if (type != null + && Serializable.class.isAssignableFrom(type) + && !type.isInterface() + && (serializationMembers.supportsReadObject(type, true) || serializationMembers.supportsWriteObject(type, + true))) { + for (Iterator iter = hierarchyFor(type).iterator(); iter.hasNext();) { + if (!Serializable.class.isAssignableFrom((Class)iter.next())) { + return canAccess(type); + } + } + return true; + } + return false; + } + + public void doMarshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + String attributeName = mapper.aliasForSystemAttribute(ATTRIBUTE_SERIALIZATION); + if (attributeName != null) { + writer.addAttribute(attributeName, ATTRIBUTE_VALUE_CUSTOM); + } + + // this is an array as it's a non final value that's accessed from an anonymous inner class. + final Class[] currentType = new Class[1]; + final boolean[] writtenClassWrapper = {false}; + + CustomObjectOutputStream.StreamCallback callback = new CustomObjectOutputStream.StreamCallback() { + + public void writeToStream(Object object) { + if (object == null) { + writer.startNode(ELEMENT_NULL); + writer.endNode(); + } else { + ExtendedHierarchicalStreamWriterHelper.startNode(writer, mapper.serializedClass(object.getClass()), object.getClass()); + context.convertAnother(object); + writer.endNode(); + } + } + + public void writeFieldsToStream(Map fields) { + ObjectStreamClass objectStreamClass = ObjectStreamClass.lookup(currentType[0]); + + writer.startNode(ELEMENT_DEFAULT); + for (Iterator iterator = fields.keySet().iterator(); iterator.hasNext();) { + String name = (String) iterator.next(); + if (!mapper.shouldSerializeMember(currentType[0], name)) { + continue; + } + ObjectStreamField field = objectStreamClass.getField(name); + Object value = fields.get(name); + if (field == null) { + throw new ObjectAccessException("Class " + value.getClass().getName() + + " may not write a field named '" + name + "'"); + } + if (value != null) { + ExtendedHierarchicalStreamWriterHelper.startNode( + writer, mapper.serializedMember(source.getClass(), name), + value.getClass()); + if (field.getType() != value.getClass() && !field.getType().isPrimitive()) { + String attributeName = mapper.aliasForSystemAttribute(ATTRIBUTE_CLASS); + if (attributeName != null) { + writer.addAttribute(attributeName, mapper.serializedClass(value.getClass())); + } + } + context.convertAnother(value); + writer.endNode(); + } + } + writer.endNode(); + } + + public void defaultWriteObject() { + boolean writtenDefaultFields = false; + + ObjectStreamClass objectStreamClass = ObjectStreamClass.lookup(currentType[0]); + + if (objectStreamClass == null) { + return; + } + + ObjectStreamField[] fields = objectStreamClass.getFields(); + for (int i = 0; i < fields.length; i++) { + ObjectStreamField field = fields[i]; + Object value = readField(field, currentType[0], source); + if (value != null) { + if (!writtenClassWrapper[0]) { + writer.startNode(mapper.serializedClass(currentType[0])); + writtenClassWrapper[0] = true; + } + if (!writtenDefaultFields) { + writer.startNode(ELEMENT_DEFAULT); + writtenDefaultFields = true; + } + if (!mapper.shouldSerializeMember(currentType[0], field.getName())) { + continue; + } + + Class actualType = value.getClass(); + ExtendedHierarchicalStreamWriterHelper.startNode( + writer, mapper.serializedMember(source.getClass(), field.getName()), actualType); + Class defaultType = mapper.defaultImplementationOf(field.getType()); + if (!actualType.equals(defaultType)) { + String attributeName = mapper.aliasForSystemAttribute(ATTRIBUTE_CLASS); + if (attributeName != null) { + writer.addAttribute(attributeName, mapper.serializedClass(actualType)); + } + } + + context.convertAnother(value); + + writer.endNode(); + } + } + if (writtenClassWrapper[0] && !writtenDefaultFields) { + writer.startNode(ELEMENT_DEFAULT); + writer.endNode(); + } else if (writtenDefaultFields) { + writer.endNode(); + } + } + + public void flush() { + writer.flush(); + } + + public void close() { + throw new UnsupportedOperationException("Objects are not allowed to call ObjectOutputStream.close() from writeObject()"); + } + }; + + try { + boolean mustHandleUnserializableParent = false; + Iterator classHieararchy = hierarchyFor(source.getClass()).iterator(); + while (classHieararchy.hasNext()) { + currentType[0] = (Class) classHieararchy.next(); + if (!Serializable.class.isAssignableFrom(currentType[0])) { + mustHandleUnserializableParent = true; + continue; + } else { + if (mustHandleUnserializableParent) { + marshalUnserializableParent(writer, context, source); + mustHandleUnserializableParent = false; + } + if (serializationMembers.supportsWriteObject(currentType[0], false)) { + writtenClassWrapper[0] = true; + writer.startNode(mapper.serializedClass(currentType[0])); + if (currentType[0] != mapper.defaultImplementationOf(currentType[0])) { + String classAttributeName = mapper.aliasForSystemAttribute(ATTRIBUTE_CLASS); + if (classAttributeName != null) { + writer.addAttribute(classAttributeName, currentType[0].getName()); + } + } + CustomObjectOutputStream objectOutputStream = CustomObjectOutputStream.getInstance(context, callback); + serializationMembers.callWriteObject(currentType[0], source, objectOutputStream); + objectOutputStream.popCallback(); + writer.endNode(); + } else if (serializationMembers.supportsReadObject(currentType[0], false)) { + // Special case for objects that have readObject(), but not writeObject(). + // The class wrapper is always written, whether or not this class in the hierarchy has + // serializable fields. This guarantees that readObject() will be called upon deserialization. + writtenClassWrapper[0] = true; + writer.startNode(mapper.serializedClass(currentType[0])); + if (currentType[0] != mapper.defaultImplementationOf(currentType[0])) { + String classAttributeName = mapper.aliasForSystemAttribute(ATTRIBUTE_CLASS); + if (classAttributeName != null) { + writer.addAttribute(classAttributeName, currentType[0].getName()); + } + } + callback.defaultWriteObject(); + writer.endNode(); + } else { + writtenClassWrapper[0] = false; + callback.defaultWriteObject(); + if (writtenClassWrapper[0]) { + writer.endNode(); + } + } + } + } + } catch (IOException e) { + throw new ObjectAccessException("Could not call defaultWriteObject()", e); + } + } + + protected void marshalUnserializableParent(final HierarchicalStreamWriter writer, final MarshallingContext context, final Object replacedSource) { + writer.startNode(ELEMENT_UNSERIALIZABLE_PARENTS); + super.doMarshal(replacedSource, writer, context); + writer.endNode(); + } + + private Object readField(ObjectStreamField field, Class type, Object instance) { + try { + Field javaField = type.getDeclaredField(field.getName()); + if (!javaField.isAccessible()) { + javaField.setAccessible(true); + } + return javaField.get(instance); + } catch (IllegalArgumentException e) { + throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); + } catch (IllegalAccessException e) { + throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); + } catch (NoSuchFieldException e) { + throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); + } catch (SecurityException e) { + throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); + } + } + + protected List hierarchyFor(Class type) { + List result = new ArrayList(); + while(type != Object.class && type != null) { + result.add(type); + type = type.getSuperclass(); + } + + // In Java Object Serialization, the classes are deserialized starting from parent class and moving down. + Collections.reverse(result); + + return result; + } + + public Object doUnmarshal(final Object result, final HierarchicalStreamReader reader, final UnmarshallingContext context) { + // this is an array as it's a non final value that's accessed from an anonymous inner class. + final Class[] currentType = new Class[1]; + + String attributeName = mapper.aliasForSystemAttribute(ATTRIBUTE_SERIALIZATION); + if (attributeName != null && !ATTRIBUTE_VALUE_CUSTOM.equals(reader.getAttribute(attributeName))) { + throw new ConversionException("Cannot deserialize object with new readObject()/writeObject() methods"); + } + + CustomObjectInputStream.StreamCallback callback = new CustomObjectInputStream.StreamCallback() { + public Object readFromStream() { + reader.moveDown(); + Class type = HierarchicalStreams.readClassType(reader, mapper); + Object value = context.convertAnother(result, type); + reader.moveUp(); + return value; + } + + public Map readFieldsFromStream() { + final Map fields = new HashMap(); + reader.moveDown(); + if (reader.getNodeName().equals(ELEMENT_FIELDS)) { + // Maintain compatibility with XStream 1.1.0 + while (reader.hasMoreChildren()) { + reader.moveDown(); + if (!reader.getNodeName().equals(ELEMENT_FIELD)) { + throw new ConversionException("Expected <" + ELEMENT_FIELD + "/> element inside <" + ELEMENT_FIELD + "/>"); + } + String name = reader.getAttribute(ATTRIBUTE_NAME); + Class type = mapper.realClass(reader.getAttribute(ATTRIBUTE_CLASS)); + Object value = context.convertAnother(result, type); + fields.put(name, value); + reader.moveUp(); + } + } else if (reader.getNodeName().equals(ELEMENT_DEFAULT)) { + // New format introduced in XStream 1.1.1 + ObjectStreamClass objectStreamClass = ObjectStreamClass.lookup(currentType[0]); + while (reader.hasMoreChildren()) { + reader.moveDown(); + String name = mapper.realMember(currentType[0], reader.getNodeName()); + if (mapper.shouldSerializeMember(currentType[0], name)) { + String classAttribute = HierarchicalStreams.readClassAttribute(reader, mapper); + Class type; + if (classAttribute != null) { + type = mapper.realClass(classAttribute); + } else { + ObjectStreamField field = objectStreamClass.getField(name); + if (field == null) { + throw new MissingFieldException(currentType[0].getName(), name); + } + type = field.getType(); + } + Object value = context.convertAnother(result, type); + fields.put(name, value); + } + reader.moveUp(); + } + } else { + throw new ConversionException("Expected <" + ELEMENT_FIELDS + "/> or <" + + ELEMENT_DEFAULT + "/> element when calling ObjectInputStream.readFields()"); + } + reader.moveUp(); + return fields; + } + + public void defaultReadObject() { + if (serializationMembers.getSerializablePersistentFields(currentType[0]) != null) { + readFieldsFromStream(); + return; + } + if (!reader.hasMoreChildren()) { + return; + } + reader.moveDown(); + if (!reader.getNodeName().equals(ELEMENT_DEFAULT)) { + throw new ConversionException("Expected <" + ELEMENT_DEFAULT + "/> element in readObject() stream"); + } + while (reader.hasMoreChildren()) { + reader.moveDown(); + + String fieldName = mapper.realMember(currentType[0], reader.getNodeName()); + if (mapper.shouldSerializeMember(currentType[0], fieldName)) { + String classAttribute = HierarchicalStreams.readClassAttribute(reader, mapper); + final Class type; + if (classAttribute != null) { + type = mapper.realClass(classAttribute); + } else { + type = mapper.defaultImplementationOf(reflectionProvider.getFieldType(result, fieldName, currentType[0])); + } + + Object value = context.convertAnother(result, type); + reflectionProvider.writeField(result, fieldName, value, currentType[0]); + } + + reader.moveUp(); + } + reader.moveUp(); + } + + public void registerValidation(final ObjectInputValidation validation, int priority) { + context.addCompletionCallback(new Runnable() { + public void run() { + try { + validation.validateObject(); + } catch (InvalidObjectException e) { + throw new ObjectAccessException("Cannot validate object : " + e.getMessage(), e); + } + } + }, priority); + } + + public void close() { + throw new UnsupportedOperationException("Objects are not allowed to call ObjectInputStream.close() from readObject()"); + } + }; + + while (reader.hasMoreChildren()) { + reader.moveDown(); + String nodeName = reader.getNodeName(); + if (nodeName.equals(ELEMENT_UNSERIALIZABLE_PARENTS)) { + super.doUnmarshal(result, reader, context); + } else { + String classAttribute = HierarchicalStreams.readClassAttribute(reader, mapper); + if (classAttribute == null) { + currentType[0] = mapper.defaultImplementationOf(mapper.realClass(nodeName)); + } else { + currentType[0] = mapper.realClass(classAttribute); + } + if (serializationMembers.supportsReadObject(currentType[0], false)) { + CustomObjectInputStream objectInputStream = + CustomObjectInputStream.getInstance(context, callback, classLoaderReference); + serializationMembers.callReadObject(currentType[0], result, objectInputStream); + objectInputStream.popCallback(); + } else { + try { + callback.defaultReadObject(); + } catch (IOException e) { + throw new ObjectAccessException("Could not call defaultWriteObject()", e); + } + } + } + reader.moveUp(); + } + + return result; + } + + protected void doMarshalConditionally(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + if(isSerializable(source.getClass())) { + doMarshal(source, writer, context); + } else { + super.doMarshal(source, writer, context); + } + } + + protected Object doUnmarshalConditionally(final Object result, final HierarchicalStreamReader reader, final UnmarshallingContext context) { + return isSerializable(result.getClass()) ? doUnmarshal(result, reader, context) : super.doUnmarshal(result, reader, context); + } + + private static class UnserializableParentsReflectionProvider extends ReflectionProviderWrapper { + + public UnserializableParentsReflectionProvider(final ReflectionProvider reflectionProvider) { + super(reflectionProvider); + } + + public void visitSerializableFields(final Object object, final Visitor visitor) { + wrapped.visitSerializableFields(object, new Visitor() { + public void visit(String name, Class type, Class definedIn, Object value) { + if (!Serializable.class.isAssignableFrom(definedIn)) { + visitor.visit(name, type, definedIn, value); + } + } + }); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializationMethodInvoker.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializationMethodInvoker.java new file mode 100644 index 0000000..e8b3193 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SerializationMethodInvoker.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2014, 2015 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 23. August 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.reflection; + +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +import com.thoughtworks.xstream.core.Caching; +import com.thoughtworks.xstream.core.util.SerializationMembers; + +/** + * Convenience wrapper to invoke special serialization methods on objects (and perform + * reflection caching). + * + * @author Joe Walnes + * @author Jörg Schaible + * @deprecated As of 1.4.8, moved into internal util package. + */ +public class SerializationMethodInvoker implements Caching { + + SerializationMembers serializationMembers = new SerializationMembers(); + + /** + * Resolves an object as native serialization does by calling readResolve(), if available. + * + * @deprecated As of 1.4.8, moved into internal util package. + */ + public Object callReadResolve(Object result) { + return serializationMembers.callReadResolve(result); + } + + /** + * @deprecated As of 1.4.8, moved into internal util package. + */ + public Object callWriteReplace(Object object) { + return serializationMembers.callWriteReplace(object); + } + + /** + * @deprecated As of 1.4.8, moved into internal util package. + */ + public boolean supportsReadObject(Class type, boolean includeBaseClasses) { + return serializationMembers.supportsReadObject(type, includeBaseClasses); + } + + /** + * @deprecated As of 1.4.8, moved into internal util package. + */ + public void callReadObject(Class type, Object object, ObjectInputStream stream) { + serializationMembers.callReadObject(type, object, stream); + } + + /** + * @deprecated As of 1.4.8, moved into internal util package. + */ + public boolean supportsWriteObject(Class type, boolean includeBaseClasses) { + return serializationMembers.supportsWriteObject(type, includeBaseClasses); + } + + /** + * @deprecated As of 1.4.8, moved into internal util package. + */ + public void callWriteObject(Class type, Object instance, ObjectOutputStream stream) { + serializationMembers.callWriteObject(type, instance, stream); + } + + /** + * @deprecated As of 1.4.8, moved into internal util package. + */ + public void flushCache() { + serializationMembers.flushCache(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SortableFieldKeySorter.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SortableFieldKeySorter.java new file mode 100644 index 0000000..f6bee5e --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SortableFieldKeySorter.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 10. April 2007 by Guilherme Silveira + */ +package com.thoughtworks.xstream.converters.reflection; + +import com.thoughtworks.xstream.core.Caching; +import com.thoughtworks.xstream.core.util.OrderRetainingMap; +import com.thoughtworks.xstream.io.StreamException; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; + + +/** + * The default implementation for sorting fields. Invoke registerFieldOrder in order to set the + * field order for an specific type. + * + * @author Guilherme Silveira + * @since 1.2.2 + */ +public class SortableFieldKeySorter implements FieldKeySorter, Caching { + + private final Map map = new HashMap(); + + public Map sort(Class type, Map keyedByFieldKey) { + if (map.containsKey(type)) { + Map result = new OrderRetainingMap(); + FieldKey[] fieldKeys = (FieldKey[])keyedByFieldKey.keySet().toArray( + new FieldKey[keyedByFieldKey.size()]); + Arrays.sort(fieldKeys, (Comparator)map.get(type)); + for (int i = 0; i < fieldKeys.length; i++ ) { + result.put(fieldKeys[i], keyedByFieldKey.get(fieldKeys[i])); + } + return result; + } else { + return keyedByFieldKey; + } + } + + /** + * Registers the field order to use for a specific type. This will not affect any of the + * type's super or sub classes. If you skip a field which will be serialized, XStream will + * thrown an StreamException during the serialization process. + * + * @param type the type + * @param fields the field order + */ + public void registerFieldOrder(Class type, String[] fields) { + map.put(type, new FieldComparator(fields)); + } + + private class FieldComparator implements Comparator { + + private final String[] fieldOrder; + + public FieldComparator(String[] fields) { + this.fieldOrder = fields; + } + + public int compare(String first, String second) { + int firstPosition = -1, secondPosition = -1; + for (int i = 0; i < fieldOrder.length; i++ ) { + if (fieldOrder[i].equals(first)) { + firstPosition = i; + } + if (fieldOrder[i].equals(second)) { + secondPosition = i; + } + } + if (firstPosition == -1 || secondPosition == -1) { + // field not defined!!! + throw new StreamException( + "You have not given XStream a list of all fields to be serialized."); + } + return firstPosition - secondPosition; + } + + public int compare(Object firstObject, Object secondObject) { + FieldKey first = (FieldKey)firstObject, second = (FieldKey)secondObject; + return compare(first.getFieldName(), second.getFieldName()); + } + + } + + public void flushCache() { + map.clear(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/Sun14ReflectionProvider.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/Sun14ReflectionProvider.java new file mode 100644 index 0000000..3c1be88 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/Sun14ReflectionProvider.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2011, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.reflection; + +/** + * Instantiates a new object on the Sun JVM by bypassing the constructor (meaning code in the constructor will never be + * executed and parameters do not have to be known). This is the same method used by the internals of standard Java + * serialization, but relies on internal Sun code that may not be present on all JVMs. + * + * @author Joe Walnes + * @author Brian Slesinsky + * @deprecated As of 1.4.7 use {@link SunUnsafeReflectionProvider} + */ +public class Sun14ReflectionProvider extends SunUnsafeReflectionProvider { + /** + * @deprecated As of 1.4.7 use {@link SunUnsafeReflectionProvider#SunUnsafeReflectionProvider()} + */ + public Sun14ReflectionProvider() { + super(); + } + + /** + * @deprecated As of 1.4.7 use {@link SunUnsafeReflectionProvider#SunUnsafeReflectionProvider(FieldDictionary)} + */ + public Sun14ReflectionProvider(FieldDictionary dic) { + super(dic); + } + + private Object readResolve() { + init(); + return this; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProvider.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProvider.java new file mode 100644 index 0000000..4faef33 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProvider.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2011, 2013, 2014 XStream Committers. + * All rights reserved. + * + * Created on 08. January 2014 by Joerg Schaible, factored out from SunUnsafeReflectionProvider + */ +package com.thoughtworks.xstream.converters.reflection; + +import java.lang.reflect.Field; + +import sun.misc.Unsafe; + + +/** + * Instantiates a new object bypassing the constructor using undocumented internal JDK features. + *

+ * The code in the constructor will never be executed and parameters do not have to be known. This is the same method + * used by the internals of standard Java serialization, but relies on internal code (sun.misc.Unsafe) that may not be + * present on all JVMs. + *

+ *

+ * The implementation will use standard Java functionality to write any fields. This requires Java 5 as minimum runtime + * and is used as fallback on platforms that do not provide the complete implementation level for the internals (like + * Dalvik). + *

+ * + * @author Jörg Schaible + * @author Joe Walnes + * @author Brian Slesinsky + * @since 1.4.7 + */ +public class SunLimitedUnsafeReflectionProvider extends PureJavaReflectionProvider { + + protected static final Unsafe unsafe; + protected static final Exception exception; + static { + Unsafe u = null; + Exception ex = null; + try { + Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); + unsafeField.setAccessible(true); + u = (Unsafe)unsafeField.get(null); + } catch (SecurityException e) { + ex = e; + } catch (NoSuchFieldException e) { + ex = e; + } catch (IllegalArgumentException e) { + ex = e; + } catch (IllegalAccessException e) { + ex = e; + } + exception = ex; + unsafe = u; + } + + /** + * @since 1.4.7 + */ + public SunLimitedUnsafeReflectionProvider() { + super(); + } + + /** + * @since 1.4.7 + */ + public SunLimitedUnsafeReflectionProvider(FieldDictionary fieldDictionary) { + super(fieldDictionary); + } + + public Object newInstance(Class type) { + if (exception != null) { + throw new ObjectAccessException("Cannot construct " + type.getName(), exception); + } + try { + return unsafe.allocateInstance(type); + } catch (SecurityException e) { + throw new ObjectAccessException("Cannot construct " + type.getName(), e); + } catch (InstantiationException e) { + throw new ObjectAccessException("Cannot construct " + type.getName(), e); + } catch (IllegalArgumentException e) { + throw new ObjectAccessException("Cannot construct " + type.getName(), e); + } + } + + protected void validateFieldAccess(Field field) { + // (overriden) don't mind final fields. + } + + private Object readResolve() { + init(); + return this; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunUnsafeReflectionProvider.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunUnsafeReflectionProvider.java new file mode 100644 index 0000000..c97c0c8 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/SunUnsafeReflectionProvider.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2011, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 08. January 2014 by Joerg Schaible, renamed from Sun14ReflectionProvider + */ +package com.thoughtworks.xstream.converters.reflection; + +import java.lang.reflect.Field; +import java.util.Map; +import java.util.WeakHashMap; + + +/** + * Instantiates a new object bypassing the constructor using undocumented internal JDK features. + *

+ * The code in the constructor will never be executed and parameters do not have to be known. This is the same method + * used by the internals of standard Java serialization, but relies on internal code (sun.misc.Unsafe) that may not be + * present on all JVMs. + *

+ *

+ * The implementation will use the same internals to write into fields. This is a lot faster and was additionally the + * only possibility to set final fields prior to Java 5. + *

+ * + * @author Joe Walnes + * @author Brian Slesinsky + * @author Jörg Schaible + * @since 1.4.7 + */ +public class SunUnsafeReflectionProvider extends SunLimitedUnsafeReflectionProvider { + + // references to the Field key are kept in the FieldDictionary + private transient Map fieldOffsetCache; + + /** + * @since 1.4.7 + */ + public SunUnsafeReflectionProvider() { + super(); + } + + /** + * @since 1.4.7 + */ + public SunUnsafeReflectionProvider(FieldDictionary dic) { + super(dic); + } + + public void writeField(Object object, String fieldName, Object value, Class definedIn) { + write(fieldDictionary.field(object.getClass(), fieldName, definedIn), object, value); + } + + private void write(Field field, Object object, Object value) { + if (exception != null) { + throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), + exception); + } + try { + long offset = getFieldOffset(field); + Class type = field.getType(); + if (type.isPrimitive()) { + if (type.equals(Integer.TYPE)) { + unsafe.putInt(object, offset, ((Integer)value).intValue()); + } else if (type.equals(Long.TYPE)) { + unsafe.putLong(object, offset, ((Long)value).longValue()); + } else if (type.equals(Short.TYPE)) { + unsafe.putShort(object, offset, ((Short)value).shortValue()); + } else if (type.equals(Character.TYPE)) { + unsafe.putChar(object, offset, ((Character)value).charValue()); + } else if (type.equals(Byte.TYPE)) { + unsafe.putByte(object, offset, ((Byte)value).byteValue()); + } else if (type.equals(Float.TYPE)) { + unsafe.putFloat(object, offset, ((Float)value).floatValue()); + } else if (type.equals(Double.TYPE)) { + unsafe.putDouble(object, offset, ((Double)value).doubleValue()); + } else if (type.equals(Boolean.TYPE)) { + unsafe.putBoolean(object, offset, ((Boolean)value).booleanValue()); + } else { + throw new ObjectAccessException("Could not set field " + + object.getClass() + + "." + + field.getName() + + ": Unknown type " + + type); + } + } else { + unsafe.putObject(object, offset, value); + } + + } catch (IllegalArgumentException e) { + throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), e); + } + } + + private synchronized long getFieldOffset(Field f) { + Long l = (Long)fieldOffsetCache.get(f); + if (l == null) { + l = new Long(unsafe.objectFieldOffset(f)); + fieldOffsetCache.put(f, l); + } + + return l.longValue(); + } + + private Object readResolve() { + init(); + return this; + } + + protected void init() { + super.init(); + fieldOffsetCache = new WeakHashMap(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/converters/reflection/XStream12FieldKeySorter.java b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/XStream12FieldKeySorter.java new file mode 100644 index 0000000..121d9e0 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/converters/reflection/XStream12FieldKeySorter.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2007, 2008, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 19.09.2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.reflection; + +import java.util.Comparator; +import java.util.Map; +import java.util.TreeMap; + + +/** + * Sort the fields in the order of XStream 1.2.x. Fields are returned in their declaration order, + * fields of base classes last. + * + * @author Jörg Schaible + * @since 1.3 + */ +public class XStream12FieldKeySorter implements FieldKeySorter { + + public Map sort(final Class type, final Map keyedByFieldKey) { + final Map map = new TreeMap(new Comparator() { + + public int compare(final Object o1, final Object o2) { + final FieldKey fieldKey1 = (FieldKey)o1; + final FieldKey fieldKey2 = (FieldKey)o2; + int i = fieldKey2.getDepth() - fieldKey1.getDepth(); + if (i == 0) { + i = fieldKey1.getOrder() - fieldKey2.getOrder(); + } + return i; + } + }); + map.putAll(keyedByFieldKey); + keyedByFieldKey.clear(); + keyedByFieldKey.putAll(map); + return keyedByFieldKey; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/AbstractReferenceMarshaller.java b/xstream/src/java/com/thoughtworks/xstream/core/AbstractReferenceMarshaller.java new file mode 100644 index 0000000..cbd9417 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/AbstractReferenceMarshaller.java @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. March 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.core.util.ObjectIdDictionary; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.path.Path; +import com.thoughtworks.xstream.io.path.PathTracker; +import com.thoughtworks.xstream.io.path.PathTrackingWriter; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.util.Iterator; + +/** + * Abstract base class for a TreeMarshaller, that can build references. + * + * @author Joe Walnes + * @author Jörg Schaible + * @author Mauro Talevi + * @since 1.2 + */ +public abstract class AbstractReferenceMarshaller extends TreeMarshaller implements MarshallingContext { + + private ObjectIdDictionary references = new ObjectIdDictionary(); + private ObjectIdDictionary implicitElements = new ObjectIdDictionary(); + private PathTracker pathTracker = new PathTracker(); + private Path lastPath; + + public AbstractReferenceMarshaller(HierarchicalStreamWriter writer, + ConverterLookup converterLookup, + Mapper mapper) { + super(writer, converterLookup, mapper); + this.writer = new PathTrackingWriter(writer, pathTracker); + } + + public void convert(Object item, Converter converter) { + if (getMapper().isImmutableValueType(item.getClass())) { + // strings, ints, dates, etc... don't bother using references. + converter.marshal(item, writer, this); + } else { + final Path currentPath = pathTracker.getPath(); + Id existingReference = (Id)references.lookupId(item); + if (existingReference != null && existingReference.getPath() != currentPath) { + String attributeName = getMapper().aliasForSystemAttribute("reference"); + if (attributeName != null) { + writer.addAttribute(attributeName, createReference(currentPath, existingReference.getItem())); + } + } else { + final Object newReferenceKey = existingReference == null + ? createReferenceKey(currentPath, item) + : existingReference.getItem(); + if (lastPath == null || !currentPath.isAncestor(lastPath)) { + fireValidReference(newReferenceKey); + lastPath = currentPath; + references.associateId(item, new Id(newReferenceKey, currentPath)); + } + converter.marshal(item, writer, new ReferencingMarshallingContext() { + + public void put(Object key, Object value) { + AbstractReferenceMarshaller.this.put(key, value); + } + + public Iterator keys() { + return AbstractReferenceMarshaller.this.keys(); + } + + public Object get(Object key) { + return AbstractReferenceMarshaller.this.get(key); + } + + public void convertAnother(Object nextItem, Converter converter) { + AbstractReferenceMarshaller.this.convertAnother(nextItem, converter); + } + + public void convertAnother(Object nextItem) { + AbstractReferenceMarshaller.this.convertAnother(nextItem); + } + + public void replace(Object original, Object replacement) { + references.associateId(replacement, new Id(newReferenceKey, currentPath)); + } + + public Object lookupReference(Object item) { + Id id = (Id)references.lookupId(item); + return id.getItem(); + } + + /** + * @deprecated As of 1.4.2 + */ + public Path currentPath() { + return pathTracker.getPath(); + } + + public void registerImplicit(Object item) { + if (implicitElements.containsId(item)) { + throw new ReferencedImplicitElementException(item, currentPath); + } + implicitElements.associateId(item, newReferenceKey); + } + }); + } + } + } + + protected abstract String createReference(Path currentPath, Object existingReferenceKey); + protected abstract Object createReferenceKey(Path currentPath, Object item); + protected abstract void fireValidReference(Object referenceKey); + + private static class Id { + private Object item; + private Path path; + public Id(Object item, Path path) { + this.item = item; + this.path = path; + } + protected Object getItem() { + return this.item; + } + protected Path getPath() { + return this.path; + } + } + + public static class ReferencedImplicitElementException extends ConversionException { + public ReferencedImplicitElementException(final Object item, final Path path) { + super("Cannot reference implicit element"); + add("implicit-element", item.toString()); + add("referencing-element", path.toString()); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/AbstractReferenceUnmarshaller.java b/xstream/src/java/com/thoughtworks/xstream/core/AbstractReferenceUnmarshaller.java new file mode 100644 index 0000000..d8218fd --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/AbstractReferenceUnmarshaller.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2006, 2007, 2008, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. March 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.core; + +import java.util.HashMap; +import java.util.Map; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.core.util.FastStack; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.mapper.Mapper; + +/** + * Abstract base class for a TreeUnmarshaller, that resolves references. + * + * @author Joe Walnes + * @author Jörg Schaible + * @author Mauro Talevi + * @since 1.2 + */ +public abstract class AbstractReferenceUnmarshaller extends TreeUnmarshaller { + + private static final Object NULL = new Object(); + private Map values = new HashMap(); + private FastStack parentStack = new FastStack(16); + + public AbstractReferenceUnmarshaller(Object root, HierarchicalStreamReader reader, + ConverterLookup converterLookup, Mapper mapper) { + super(root, reader, converterLookup, mapper); + } + + protected Object convert(Object parent, Class type, Converter converter) { + if (parentStack.size() > 0) { // handles circular references + Object parentReferenceKey = parentStack.peek(); + if (parentReferenceKey != null) { + if (!values.containsKey(parentReferenceKey)) { // see AbstractCircularReferenceTest.testWeirdCircularReference() + values.put(parentReferenceKey, parent); + } + } + } + final Object result; + String attributeName = getMapper().aliasForSystemAttribute("reference"); + String reference = attributeName == null ? null : reader.getAttribute(attributeName); + if (reference != null) { + Object cache = values.get(getReferenceKey(reference)); + if (cache == null) { + final ConversionException ex = new ConversionException("Invalid reference"); + ex.add("reference", reference); + throw ex; + } + result = cache == NULL ? null : cache; + } else { + Object currentReferenceKey = getCurrentReferenceKey(); + parentStack.push(currentReferenceKey); + result = super.convert(parent, type, converter); + if (currentReferenceKey != null) { + values.put(currentReferenceKey, result == null ? NULL : result); + } + parentStack.popSilently(); + } + return result; + } + + protected abstract Object getReferenceKey(String reference); + protected abstract Object getCurrentReferenceKey(); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/AbstractTreeMarshallingStrategy.java b/xstream/src/java/com/thoughtworks/xstream/core/AbstractTreeMarshallingStrategy.java new file mode 100644 index 0000000..46d09c3 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/AbstractTreeMarshallingStrategy.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26.09.2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.xstream.MarshallingStrategy; +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.converters.DataHolder; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + + +/** + * Basic functionality of a tree based marshalling strategy. + * + * @author Joe Walnes + * @author Jörg Schaible + * @since 1.3 + */ +public abstract class AbstractTreeMarshallingStrategy implements MarshallingStrategy { + + public Object unmarshal(Object root, HierarchicalStreamReader reader, DataHolder dataHolder, ConverterLookup converterLookup, Mapper mapper) { + TreeUnmarshaller context = createUnmarshallingContext(root, reader, converterLookup, mapper); + return context.start(dataHolder); + } + + public void marshal(HierarchicalStreamWriter writer, Object obj, ConverterLookup converterLookup, Mapper mapper, DataHolder dataHolder) { + TreeMarshaller context = createMarshallingContext(writer, converterLookup, mapper); + context.start(obj, dataHolder); + } + + protected abstract TreeUnmarshaller createUnmarshallingContext(Object root, + HierarchicalStreamReader reader, ConverterLookup converterLookup, Mapper mapper); + + protected abstract TreeMarshaller createMarshallingContext( + HierarchicalStreamWriter writer, ConverterLookup converterLookup, Mapper mapper); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/BaseException.java b/xstream/src/java/com/thoughtworks/xstream/core/BaseException.java new file mode 100644 index 0000000..a1bdb51 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/BaseException.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 14. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.xstream.XStreamException; + +/** + * JDK1.3 friendly exception that retains cause. + * @deprecated As of 1.3, use {@link XStreamException} instead + */ +public abstract class BaseException extends RuntimeException { + + protected BaseException(String message) { + super(message); + } + + public abstract Throwable getCause(); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/Caching.java b/xstream/src/java/com/thoughtworks/xstream/core/Caching.java new file mode 100644 index 0000000..ef329da --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/Caching.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 19. July 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.core; + +/** + * Marker interface for caching implementations. + * + * @author Jörg Schaible + * @since 1.4 + */ +public interface Caching { + void flushCache(); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/ClassLoaderReference.java b/xstream/src/java/com/thoughtworks/xstream/core/ClassLoaderReference.java new file mode 100644 index 0000000..d6701ec --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/ClassLoaderReference.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. June 2013 by Joerg Schaible + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.xstream.core.util.CompositeClassLoader; + +/** + * Reference to a ClassLoader, allowing a single instance to be passed around the codebase that + * can later have its destination changed. + * + * @author Jörg Schaible + * @since 1.4.5 + */ +public final class ClassLoaderReference { + + private transient ClassLoader reference; + + public ClassLoaderReference(ClassLoader reference) { + setReference(reference); + } + + public ClassLoader getReference() { + return reference; + } + + public void setReference(ClassLoader reference) { + this.reference = reference instanceof com.thoughtworks.xstream.core.util.ClassLoaderReference + ? ((com.thoughtworks.xstream.core.util.ClassLoaderReference)reference) + .getReference() : reference; + } + + private Object readResolve() { + this.reference = new CompositeClassLoader(); + return this; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/DefaultConverterLookup.java b/xstream/src/java/com/thoughtworks/xstream/core/DefaultConverterLookup.java new file mode 100644 index 0000000..b4b955f --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/DefaultConverterLookup.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.converters.ConverterRegistry; +import com.thoughtworks.xstream.core.util.PrioritizedList; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.WeakHashMap; + +/** + * The default implementation of converters lookup. + * + * @author Joe Walnes + * @author Jörg Schaible + * @author Guilherme Silveira + */ +public class DefaultConverterLookup implements ConverterLookup, ConverterRegistry, Caching { + + private final PrioritizedList converters = new PrioritizedList(); + private transient Map typeToConverterMap; + + public DefaultConverterLookup() { + readResolve(); + } + + /** + * @deprecated As of 1.3, use {@link #DefaultConverterLookup()} + */ + public DefaultConverterLookup(Mapper mapper) { + } + + public Converter lookupConverterForType(Class type) { + Converter cachedConverter = (Converter) typeToConverterMap.get(type); + if (cachedConverter != null) { + return cachedConverter; + } + Iterator iterator = converters.iterator(); + while (iterator.hasNext()) { + Converter converter = (Converter) iterator.next(); + if (converter.canConvert(type)) { + typeToConverterMap.put(type, converter); + return converter; + } + } + throw new ConversionException("No converter specified for " + type); + } + + public void registerConverter(Converter converter, int priority) { + converters.add(converter, priority); + for (Iterator iter = typeToConverterMap.keySet().iterator(); iter.hasNext();) { + Class type = (Class) iter.next(); + if (converter.canConvert(type)) { + iter.remove(); + } + } + } + + public void flushCache() { + typeToConverterMap.clear(); + Iterator iterator = converters.iterator(); + while (iterator.hasNext()) { + Converter converter = (Converter) iterator.next(); + if (converter instanceof Caching) { + ((Caching)converter).flushCache(); + } + } + } + + private Object readResolve() { + typeToConverterMap = Collections.synchronizedMap(new WeakHashMap()); + return this; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/JVM.java b/xstream/src/java/com/thoughtworks/xstream/core/JVM.java new file mode 100644 index 0000000..056a4fc --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/JVM.java @@ -0,0 +1,540 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2012, 2013, 2014, 2015 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 09. May 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.xstream.converters.reflection.FieldDictionary; +import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; +import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; +import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; +import com.thoughtworks.xstream.core.util.CustomObjectOutputStream; +import com.thoughtworks.xstream.core.util.DependencyInjectionFactory; +import com.thoughtworks.xstream.core.util.PresortedMap; +import com.thoughtworks.xstream.core.util.PresortedSet; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.text.AttributedString; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Comparator; +import java.util.SortedMap; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.TreeSet; + +public class JVM implements Caching { + + private ReflectionProvider reflectionProvider; + + private static final boolean isAWTAvailable; + private static final boolean isSwingAvailable; + private static final boolean isSQLAvailable; + private static final boolean canAllocateWithUnsafe; + private static final boolean canWriteWithUnsafe; + private static final boolean optimizedTreeSetAddAll; + private static final boolean optimizedTreeMapPutAll; + private static final boolean canParseUTCDateFormat; + private static final boolean canParseISO8601TimeZoneInDateFormat; + private static final boolean canCreateDerivedObjectOutputStream; + + private static final String vendor = System.getProperty("java.vm.vendor"); + private static final float majorJavaVersion = getMajorJavaVersion(); + private static final float DEFAULT_JAVA_VERSION = 1.4f; + private static final boolean reverseFieldOrder = false; + private static final Class reflectionProviderType; + + static class Test { + private Object o; + private char c; + private byte b; + private short s; + private int i; + private long l; + private float f; + private double d; + private boolean bool; + Test() { + throw new UnsupportedOperationException(); + } + } + + static { + boolean test = true; + Object unsafe = null; + try { + Class unsafeClass = Class.forName("sun.misc.Unsafe"); + Field unsafeField = unsafeClass.getDeclaredField("theUnsafe"); + unsafeField.setAccessible(true); + unsafe = unsafeField.get(null); + Method allocateInstance = unsafeClass.getDeclaredMethod("allocateInstance", new Class[]{Class.class}); + allocateInstance.setAccessible(true); + test = allocateInstance.invoke(unsafe, new Object[]{Test.class}) != null; + } catch (Exception e) { + test = false; + } catch (Error e) { + test = false; + } + canAllocateWithUnsafe = test; + test = false; + Class type = PureJavaReflectionProvider.class; + if (canUseSunUnsafeReflectionProvider()) { + Class cls = loadClassForName("com.thoughtworks.xstream.converters.reflection.SunUnsafeReflectionProvider"); + if (cls != null) { + try { + ReflectionProvider provider = (ReflectionProvider)DependencyInjectionFactory.newInstance(cls, null); + Test t = (Test)provider.newInstance(Test.class); + try { + provider.writeField(t, "o", "object", Test.class); + provider.writeField(t, "c", new Character('c'), Test.class); + provider.writeField(t, "b", new Byte((byte)1), Test.class); + provider.writeField(t, "s", new Short((short)1), Test.class); + provider.writeField(t, "i", new Integer(1), Test.class); + provider.writeField(t, "l", new Long(1), Test.class); + provider.writeField(t, "f", new Float(1), Test.class); + provider.writeField(t, "d", new Double(1), Test.class); + provider.writeField(t, "bool", Boolean.TRUE, Test.class); + test = true; + } catch(IncompatibleClassChangeError e) { + cls = null; + } catch (ObjectAccessException e) { + cls = null; + } + if (cls == null) { + cls = loadClassForName("com.thoughtworks.xstream.converters.reflection.SunLimitedUnsafeReflectionProvider"); + } + type = cls; + } catch (ObjectAccessException e) { + } + } + } + reflectionProviderType = type; + canWriteWithUnsafe = test; + Comparator comparator = new Comparator() { + public int compare(Object o1, Object o2) { + throw new RuntimeException(); + } + }; + SortedMap map = new PresortedMap(comparator); + map.put("one", null); + map.put("two", null); + try { + new TreeMap(comparator).putAll(map); + test = true; + } catch (RuntimeException e) { + test = false; + } + optimizedTreeMapPutAll = test; + SortedSet set = new PresortedSet(comparator); + set.addAll(map.keySet()); + try { + new TreeSet(comparator).addAll(set); + test = true; + } catch (RuntimeException e) { + test = false; + } + optimizedTreeSetAddAll = test; + try { + new SimpleDateFormat("z").parse("UTC"); + test = true; + } catch (ParseException e) { + test = false; + } + canParseUTCDateFormat = test; + try { + new SimpleDateFormat("X").parse("Z"); + test = true; + } catch (final ParseException e) { + test = false; + } catch (final IllegalArgumentException e) { + test = false; + } + canParseISO8601TimeZoneInDateFormat = test; + try { + test = new CustomObjectOutputStream(null) != null; + } catch (RuntimeException e) { + test = false; + } catch (IOException e) { + test = false; + } + canCreateDerivedObjectOutputStream = test; + + isAWTAvailable = loadClassForName("java.awt.Color", false) != null; + isSwingAvailable = loadClassForName("javax.swing.LookAndFeel", false) != null; + isSQLAvailable = loadClassForName("java.sql.Date") != null; + } + + /** + * @deprecated As of 1.4.5 use the static methods of JVM. + */ + public JVM() { + } + + /** + * Parses the java version system property to determine the major java version, + * i.e. 1.x + * + * @return A float of the form 1.x + */ + private static final float getMajorJavaVersion() { + try { + return isAndroid() ? 1.5f : Float.parseFloat(System.getProperty("java.specification.version")); + } catch ( NumberFormatException e ){ + // Some JVMs may not conform to the x.y.z java.version format + return DEFAULT_JAVA_VERSION; + } + } + + /** + * @deprecated As of 1.4.4, minimal JDK version is 1.4 already + */ + public static boolean is14() { + return majorJavaVersion >= 1.4f; + } + + /** + * @deprecated As of 1.4.4, minimal JDK version will be 1.6 for next major release + */ + public static boolean is15() { + return majorJavaVersion >= 1.5f; + } + + /** + * @deprecated As of 1.4.4, minimal JDK version will be 1.6 for next major release + */ + public static boolean is16() { + return majorJavaVersion >= 1.6f; + } + + /** + * @since 1.4 + */ + public static boolean is17() { + return majorJavaVersion >= 1.7f; + } + + /** + * @since 1.4 + */ + public static boolean is18() { + return majorJavaVersion >= 1.8f; + } + + /** + * @since 1.4.8 + */ + public static boolean is19() { + return majorJavaVersion >= 1.9f; + } + + private static boolean isIBM() { + return vendor.indexOf("IBM") != -1; + } + + /** + * @since 1.4 + */ + private static boolean isAndroid() { + return vendor.indexOf("Android") != -1; + } + + /** + * Load a XStream class for the given name. + * + *

This method is not meant to use loading arbitrary classes. It is used by XStream bootstrap + * until it is able to use the user provided or the default {@link ClassLoader}.

+ * + * @since 1.4.5 + */ + public static Class loadClassForName(String name) { + return loadClassForName(name, true); + } + + /** + * @deprecated As of 1.4.5 use {@link #loadClassForName(String)} + */ + public Class loadClass(String name) { + return loadClassForName(name, true); + } + + /** + * Load a XStream class for the given name. + * + *

This method is not meant to use loading arbitrary classes. It is used by XStream bootstrap + * until it is able to use the user provided or the default {@link ClassLoader}.

+ * + * @since 1.4.5 + */ + public static Class loadClassForName(String name, boolean initialize) { + try { + Class clazz = Class.forName(name, initialize, JVM.class.getClassLoader()); + return clazz; + } catch (LinkageError e) { + return null; + } catch (ClassNotFoundException e) { + return null; + } + } + + /** + * @since 1.4.4 + * @deprecated As of 1.4.5 use {@link #loadClassForName(String, boolean)} + */ + public Class loadClass(String name, boolean initialize) { + return loadClassForName(name, initialize); + } + + /** + * Create the best matching ReflectionProvider. + * + * @return a new instance + * @since 1.4.5 + */ + public static ReflectionProvider newReflectionProvider() { + return (ReflectionProvider)DependencyInjectionFactory.newInstance(reflectionProviderType, null); + } + + /** + * Create the best matching ReflectionProvider. + * + * @param dictionary the FieldDictionary to use by the ReflectionProvider + * @return a new instance + * @since 1.4.5 + */ + public static ReflectionProvider newReflectionProvider(FieldDictionary dictionary) { + return (ReflectionProvider)DependencyInjectionFactory.newInstance(reflectionProviderType, new Object[]{ dictionary }); + } + + /** + * Get the XMLInputFactory implementation used normally by the current Java runtime as + * standard. + *

+ * In contrast to XMLInputFactory.newFactory() this method will ignore any implementations + * provided with the system property javax.xml.stream.XMLInputFactory, + * implementations configured in lib/stax.properties or registered with the Service + * API. + *

+ * + * @return the XMLInputFactory implementation or null + * @throws ClassNotFoundException if the standard class cannot be found + * @since 1.4.5 + */ + public static Class getStaxInputFactory() throws ClassNotFoundException { + if (is16()) { + if (isIBM()) { + return Class.forName("com.ibm.xml.xlxp.api.stax.XMLInputFactoryImpl"); + } else { + return Class.forName("com.sun.xml.internal.stream.XMLInputFactoryImpl"); + } + } + return null; + } + + /** + * Get the XMLOutputFactory implementation used normally by the current Java runtime as + * standard. + *

+ * In contrast to XMLOutputFactory.newFactory() this method will ignore any implementations + * provided with the system property javax.xml.stream.XMLOutputFactory, + * implementations configured in lib/stax.properties or registered with the Service + * API. + *

+ * + * @return the XMLOutputFactory implementation or null + * @throws ClassNotFoundException if the standard class cannot be found + * @since 1.4.5 + */ + public static Class getStaxOutputFactory() throws ClassNotFoundException { + if (is16()) { + if (isIBM()) { + return Class.forName("com.ibm.xml.xlxp.api.stax.XMLOutputFactoryImpl"); + } else { + return Class.forName("com.sun.xml.internal.stream.XMLOutputFactoryImpl"); + } + } + return null; + } + + /** + * @deprecated As of 1.4.5 use {@link #newReflectionProvider()} + */ + public synchronized ReflectionProvider bestReflectionProvider() { + if (reflectionProvider == null) { + reflectionProvider = newReflectionProvider(); + } + return reflectionProvider; + } + + private static boolean canUseSunUnsafeReflectionProvider() { + return canAllocateWithUnsafe && is14(); + } + + private static boolean canUseSunLimitedUnsafeReflectionProvider() { + return canWriteWithUnsafe; + } + + /** + * @deprecated As of 1.4.5 + */ + public static boolean reverseFieldDefinition() { + return reverseFieldOrder; + } + + /** + * Checks if AWT is available. + * @since 1.4.5 + */ + public static boolean isAWTAvailable() { + return isAWTAvailable; + } + + /** + * Checks if the jvm supports awt. + * @deprecated As of 1.4.5 use {@link #isAWTAvailable()} + */ + public boolean supportsAWT() { + return this.isAWTAvailable; + } + + /** + * Checks if Swing is available. + * @since 1.4.5 + */ + public static boolean isSwingAvailable() { + return isSwingAvailable; + } + + /** + * Checks if the jvm supports swing. + * @deprecated As of 1.4.5 use {@link #isSwingAvailable()} + */ + public boolean supportsSwing() { + return this.isSwingAvailable; + } + + /** + * Checks if SQL is available. + * @since 1.4.5 + */ + public static boolean isSQLAvailable() { + return isSQLAvailable; + } + + /** + * Checks if the jvm supports sql. + * @deprecated As of 1.4.5 use {@link #isSQLAvailable()} + */ + public boolean supportsSQL() { + return this.isSQLAvailable; + } + + /** + * Checks if TreeSet.addAll is optimized for SortedSet argument. + * + * @since 1.4 + */ + public static boolean hasOptimizedTreeSetAddAll() { + return optimizedTreeSetAddAll; + } + + /** + * Checks if TreeMap.putAll is optimized for SortedMap argument. + * + * @since 1.4 + */ + public static boolean hasOptimizedTreeMapPutAll() { + return optimizedTreeMapPutAll; + } + + public static boolean canParseUTCDateFormat() { + return canParseUTCDateFormat; + } + + /** + * @since 1.4.8 + */ + public static boolean canParseISO8601TimeZoneInDateFormat() { + return canParseISO8601TimeZoneInDateFormat; + } + + /** + * @since 1.4.6 + */ + public static boolean canCreateDerivedObjectOutputStream() { + return canCreateDerivedObjectOutputStream; + } + + /** + * @deprecated As of 1.4.5 no functionality + */ + public void flushCache() { + } + + public static void main(String[] args) { + boolean reverseJDK = false; + Field[] fields = AttributedString.class.getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + if (fields[i].getName().equals("text")) { + reverseJDK = i > 3; + break; + } + } + + boolean reverseLocal = false; + fields = Test.class.getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + if (fields[i].getName().equals("o")) { + reverseLocal = i > 3; + break; + } + } + + String staxInputFactory = null; + try { + staxInputFactory = getStaxInputFactory().getName(); + } catch (ClassNotFoundException e) { + staxInputFactory = e.getMessage(); + } catch (NullPointerException e) { + } + + String staxOutputFactory = null; + try { + staxOutputFactory = getStaxOutputFactory().getName(); + } catch (ClassNotFoundException e) { + staxOutputFactory = e.getMessage(); + } catch (NullPointerException e) { + } + + System.out.println("XStream JVM diagnostics"); + System.out.println("java.specification.version: " + System.getProperty("java.specification.version")); + System.out.println("java.specification.vendor: " + System.getProperty("java.specification.vendor")); + System.out.println("java.specification.name: " + System.getProperty("java.specification.name")); + System.out.println("java.vm.vendor: " + vendor); + System.out.println("java.vendor: " + System.getProperty("java.vendor")); + System.out.println("java.vm.name: " + System.getProperty("java.vm.name")); + System.out.println("Version: " + majorJavaVersion); + System.out.println("XStream support for enhanced Mode: " + canUseSunUnsafeReflectionProvider()); + System.out.println("XStream support for reduced Mode: " + canUseSunLimitedUnsafeReflectionProvider()); + System.out.println("Supports AWT: " + isAWTAvailable()); + System.out.println("Supports Swing: " + isSwingAvailable()); + System.out.println("Supports SQL: " + isSQLAvailable()); + System.out.println("Java Beans EventHandler present: " + (loadClassForName("java.beans.EventHandler") != null)); + System.out.println("Standard StAX XMLInputFactory: " + staxInputFactory); + System.out.println("Standard StAX XMLOutputFactory: " + staxOutputFactory); + System.out.println("Optimized TreeSet.addAll: " + hasOptimizedTreeSetAddAll()); + System.out.println("Optimized TreeMap.putAll: " + hasOptimizedTreeMapPutAll()); + System.out.println("Can parse UTC date format: " + canParseUTCDateFormat()); + System.out.println("Can create derive ObjectOutputStream: " + canCreateDerivedObjectOutputStream()); + System.out.println("Reverse field order detected for JDK: " + reverseJDK); + System.out.println("Reverse field order detected (only if JVM class itself has been compiled): " + reverseLocal); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/MapBackedDataHolder.java b/xstream/src/java/com/thoughtworks/xstream/core/MapBackedDataHolder.java new file mode 100644 index 0000000..09f02f1 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/MapBackedDataHolder.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. October 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.xstream.converters.DataHolder; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +public class MapBackedDataHolder implements DataHolder { + private final Map map; + + public MapBackedDataHolder() { + this(new HashMap()); + } + + public MapBackedDataHolder(Map map) { + this.map = map; + } + + public Object get(Object key) { + return map.get(key); + } + + public void put(Object key, Object value) { + map.put(key, value); + } + + public Iterator keys() { + return Collections.unmodifiableCollection(map.keySet()).iterator(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/ReferenceByIdMarshaller.java b/xstream/src/java/com/thoughtworks/xstream/core/ReferenceByIdMarshaller.java new file mode 100644 index 0000000..05802b1 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/ReferenceByIdMarshaller.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.path.Path; +import com.thoughtworks.xstream.mapper.Mapper; + +public class ReferenceByIdMarshaller extends AbstractReferenceMarshaller { + + private final IDGenerator idGenerator; + + public static interface IDGenerator { + String next(Object item); + } + + public ReferenceByIdMarshaller(HierarchicalStreamWriter writer, + ConverterLookup converterLookup, + Mapper mapper, + IDGenerator idGenerator) { + super(writer, converterLookup, mapper); + this.idGenerator = idGenerator; + } + + public ReferenceByIdMarshaller(HierarchicalStreamWriter writer, + ConverterLookup converterLookup, + Mapper mapper) { + this(writer, converterLookup, mapper, new SequenceGenerator(1)); + } + + protected String createReference(Path currentPath, Object existingReferenceKey) { + return existingReferenceKey.toString(); + } + + protected Object createReferenceKey(Path currentPath, Object item) { + return idGenerator.next(item); + } + + protected void fireValidReference(Object referenceKey) { + String attributeName = getMapper().aliasForSystemAttribute("id"); + if (attributeName != null) { + writer.addAttribute(attributeName, referenceKey.toString()); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/ReferenceByIdMarshallingStrategy.java b/xstream/src/java/com/thoughtworks/xstream/core/ReferenceByIdMarshallingStrategy.java new file mode 100644 index 0000000..fc7e0dd --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/ReferenceByIdMarshallingStrategy.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 16. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + +public class ReferenceByIdMarshallingStrategy extends AbstractTreeMarshallingStrategy { + + protected TreeUnmarshaller createUnmarshallingContext(Object root, + HierarchicalStreamReader reader, ConverterLookup converterLookup, Mapper mapper) { + return new ReferenceByIdUnmarshaller(root, reader, converterLookup, mapper); + } + + protected TreeMarshaller createMarshallingContext( + HierarchicalStreamWriter writer, ConverterLookup converterLookup, Mapper mapper) { + return new ReferenceByIdMarshaller(writer, converterLookup, mapper); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/ReferenceByIdUnmarshaller.java b/xstream/src/java/com/thoughtworks/xstream/core/ReferenceByIdUnmarshaller.java new file mode 100644 index 0000000..aa53323 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/ReferenceByIdUnmarshaller.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.mapper.Mapper; + +public class ReferenceByIdUnmarshaller extends AbstractReferenceUnmarshaller { + + public ReferenceByIdUnmarshaller(Object root, HierarchicalStreamReader reader, + ConverterLookup converterLookup, Mapper mapper) { + super(root, reader, converterLookup, mapper); + } + + protected Object getReferenceKey(String reference) { + return reference; + } + + protected Object getCurrentReferenceKey() { + String attributeName = getMapper().aliasForSystemAttribute("id"); + return attributeName == null ? null : reader.getAttribute(attributeName); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/ReferenceByXPathMarshaller.java b/xstream/src/java/com/thoughtworks/xstream/core/ReferenceByXPathMarshaller.java new file mode 100644 index 0000000..954d4df --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/ReferenceByXPathMarshaller.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2004, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. April 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.path.Path; +import com.thoughtworks.xstream.mapper.Mapper; + +public class ReferenceByXPathMarshaller extends AbstractReferenceMarshaller { + + private final int mode; + + public ReferenceByXPathMarshaller(HierarchicalStreamWriter writer, ConverterLookup converterLookup, Mapper mapper, int mode) { + super(writer, converterLookup, mapper); + this.mode = mode; + } + + protected String createReference(Path currentPath, Object existingReferenceKey) { + Path existingPath = (Path)existingReferenceKey; + Path referencePath = (mode & ReferenceByXPathMarshallingStrategy.ABSOLUTE) > 0 ? existingPath : currentPath.relativeTo(existingPath); + return (mode & ReferenceByXPathMarshallingStrategy.SINGLE_NODE) > 0 ? referencePath.explicit() : referencePath.toString(); + } + + protected Object createReferenceKey(Path currentPath, Object item) { + return currentPath; + } + + protected void fireValidReference(Object referenceKey) { + // nothing to do + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/ReferenceByXPathMarshallingStrategy.java b/xstream/src/java/com/thoughtworks/xstream/core/ReferenceByXPathMarshallingStrategy.java new file mode 100644 index 0000000..75bb705 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/ReferenceByXPathMarshallingStrategy.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. April 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + +public class ReferenceByXPathMarshallingStrategy extends AbstractTreeMarshallingStrategy { + + public static int RELATIVE = 0; + public static int ABSOLUTE = 1; + public static int SINGLE_NODE = 2; + private final int mode; + + public ReferenceByXPathMarshallingStrategy(int mode) { + this.mode = mode; + } + + protected TreeUnmarshaller createUnmarshallingContext(Object root, + HierarchicalStreamReader reader, ConverterLookup converterLookup, Mapper mapper) { + return new ReferenceByXPathUnmarshaller(root, reader, converterLookup, mapper); + } + + protected TreeMarshaller createMarshallingContext( + HierarchicalStreamWriter writer, ConverterLookup converterLookup, Mapper mapper) { + return new ReferenceByXPathMarshaller(writer, converterLookup, mapper, mode); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/ReferenceByXPathUnmarshaller.java b/xstream/src/java/com/thoughtworks/xstream/core/ReferenceByXPathUnmarshaller.java new file mode 100644 index 0000000..8e9731b --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/ReferenceByXPathUnmarshaller.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. April 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.io.AbstractReader; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.path.Path; +import com.thoughtworks.xstream.io.path.PathTracker; +import com.thoughtworks.xstream.io.path.PathTrackingReader; +import com.thoughtworks.xstream.mapper.Mapper; + +public class ReferenceByXPathUnmarshaller extends AbstractReferenceUnmarshaller { + + private PathTracker pathTracker = new PathTracker(); + protected boolean isNameEncoding; + + public ReferenceByXPathUnmarshaller(Object root, HierarchicalStreamReader reader, + ConverterLookup converterLookup, Mapper mapper) { + super(root, reader, converterLookup, mapper); + this.reader = new PathTrackingReader(reader, pathTracker); + isNameEncoding = reader.underlyingReader() instanceof AbstractReader; + } + + protected Object getReferenceKey(String reference) { + final Path path = new Path(isNameEncoding ? ((AbstractReader)reader.underlyingReader()).decodeNode(reference) : reference); + // We have absolute references, if path starts with '/' + return reference.charAt(0) != '/' ? pathTracker.getPath().apply(path) : path; + } + + protected Object getCurrentReferenceKey() { + return pathTracker.getPath(); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/ReferencingMarshallingContext.java b/xstream/src/java/com/thoughtworks/xstream/core/ReferencingMarshallingContext.java new file mode 100644 index 0000000..44fd349 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/ReferencingMarshallingContext.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. May 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.io.path.Path; + +/** + * A {@link MarshallingContext} that manages references. + * + * @author Jörg Schaible + * @since 1.4 + */ +public interface ReferencingMarshallingContext extends MarshallingContext { + + /** + * Retrieve the current path. + * + * @return the current path + * @since 1.4 + * @deprecated As of 1.4.2 + */ + Path currentPath(); + + /** + * Request the reference key for the given item + * + * @param item the item to lookup + * @return the reference key or null + * @since 1.4 + */ + Object lookupReference(Object item); + + /** + * Replace the currently marshalled item. + * + *

Use this method only, if you know exactly what you do! It is a special solution for + * Serializable types that make usage of the writeReplace method where the replacing object itself is referenced.

+ * + * @param original the original item to convert + * @param replacement the replacement item that is converted instead + * @since 1.4 + */ + void replace(Object original, Object replacement); + + /** + * Register an implicit element. This is typically some kind of collection. Note, that this object may not be + * referenced anywhere else in the object stream. + * + * @param item the object that is implicit + * @since 1.4 + */ + void registerImplicit(Object item); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/SequenceGenerator.java b/xstream/src/java/com/thoughtworks/xstream/core/SequenceGenerator.java new file mode 100644 index 0000000..690b5f5 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/SequenceGenerator.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 16. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core; + +public class SequenceGenerator implements ReferenceByIdMarshaller.IDGenerator { + + private int counter; + + public SequenceGenerator(int startsAt) { + this.counter = startsAt; + } + + public String next(Object item) { + return String.valueOf(counter++); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/TreeMarshaller.java b/xstream/src/java/com/thoughtworks/xstream/core/TreeMarshaller.java new file mode 100644 index 0000000..771f195 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/TreeMarshaller.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.converters.DataHolder; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.core.util.ObjectIdDictionary; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.util.Iterator; + + +public class TreeMarshaller implements MarshallingContext { + + protected HierarchicalStreamWriter writer; + protected ConverterLookup converterLookup; + private Mapper mapper; + private ObjectIdDictionary parentObjects = new ObjectIdDictionary(); + private DataHolder dataHolder; + + public TreeMarshaller( + HierarchicalStreamWriter writer, ConverterLookup converterLookup, Mapper mapper) { + this.writer = writer; + this.converterLookup = converterLookup; + this.mapper = mapper; + } + + public void convertAnother(Object item) { + convertAnother(item, null); + } + + public void convertAnother(Object item, Converter converter) { + if (converter == null) { + converter = converterLookup.lookupConverterForType(item.getClass()); + } else { + if (!converter.canConvert(item.getClass())) { + ConversionException e = new ConversionException( + "Explicit selected converter cannot handle item"); + e.add("item-type", item.getClass().getName()); + e.add("converter-type", converter.getClass().getName()); + throw e; + } + } + convert(item, converter); + } + + protected void convert(Object item, Converter converter) { + if (parentObjects.containsId(item)) { + ConversionException e = new CircularReferenceException( + "Recursive reference to parent object"); + e.add("item-type", item.getClass().getName()); + e.add("converter-type", converter.getClass().getName()); + throw e; + } + parentObjects.associateId(item, ""); + converter.marshal(item, writer, this); + parentObjects.removeId(item); + } + + public void start(Object item, DataHolder dataHolder) { + this.dataHolder = dataHolder; + if (item == null) { + writer.startNode(mapper.serializedClass(null)); + writer.endNode(); + } else { + ExtendedHierarchicalStreamWriterHelper.startNode(writer, mapper + .serializedClass(item.getClass()), item.getClass()); + convertAnother(item); + writer.endNode(); + } + } + + public Object get(Object key) { + lazilyCreateDataHolder(); + return dataHolder.get(key); + } + + public void put(Object key, Object value) { + lazilyCreateDataHolder(); + dataHolder.put(key, value); + } + + public Iterator keys() { + lazilyCreateDataHolder(); + return dataHolder.keys(); + } + + private void lazilyCreateDataHolder() { + if (dataHolder == null) { + dataHolder = new MapBackedDataHolder(); + } + } + + protected Mapper getMapper() { + return this.mapper; + } + + public static class CircularReferenceException extends ConversionException { + + public CircularReferenceException(String msg) { + super(msg); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/TreeMarshallingStrategy.java b/xstream/src/java/com/thoughtworks/xstream/core/TreeMarshallingStrategy.java new file mode 100644 index 0000000..8e1635b --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/TreeMarshallingStrategy.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 16. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + +public class TreeMarshallingStrategy extends AbstractTreeMarshallingStrategy { + + protected TreeUnmarshaller createUnmarshallingContext(Object root, + HierarchicalStreamReader reader, ConverterLookup converterLookup, Mapper mapper) { + return new TreeUnmarshaller(root, reader, converterLookup, mapper); + } + + protected TreeMarshaller createMarshallingContext( + HierarchicalStreamWriter writer, ConverterLookup converterLookup, Mapper mapper) { + return new TreeMarshaller(writer, converterLookup, mapper); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/TreeUnmarshaller.java b/xstream/src/java/com/thoughtworks/xstream/core/TreeUnmarshaller.java new file mode 100644 index 0000000..e40b105 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/TreeUnmarshaller.java @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core; + +import java.util.Iterator; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.converters.DataHolder; +import com.thoughtworks.xstream.converters.ErrorReporter; +import com.thoughtworks.xstream.converters.ErrorWriter; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.core.util.FastStack; +import com.thoughtworks.xstream.core.util.HierarchicalStreams; +import com.thoughtworks.xstream.core.util.PrioritizedList; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.mapper.Mapper; + + +public class TreeUnmarshaller implements UnmarshallingContext { + + private Object root; + protected HierarchicalStreamReader reader; + private ConverterLookup converterLookup; + private Mapper mapper; + private FastStack types = new FastStack(16); + private DataHolder dataHolder; + private final PrioritizedList validationList = new PrioritizedList(); + + public TreeUnmarshaller( + Object root, HierarchicalStreamReader reader, ConverterLookup converterLookup, + Mapper mapper) { + this.root = root; + this.reader = reader; + this.converterLookup = converterLookup; + this.mapper = mapper; + } + + public Object convertAnother(Object parent, Class type) { + return convertAnother(parent, type, null); + } + + public Object convertAnother(Object parent, Class type, Converter converter) { + type = mapper.defaultImplementationOf(type); + if (converter == null) { + converter = converterLookup.lookupConverterForType(type); + } else { + if (!converter.canConvert(type)) { + ConversionException e = new ConversionException( + "Explicit selected converter cannot handle type"); + e.add("item-type", type.getName()); + e.add("converter-type", converter.getClass().getName()); + throw e; + } + } + return convert(parent, type, converter); + } + + protected Object convert(Object parent, Class type, Converter converter) { + try { + types.push(type); + Object result = converter.unmarshal(reader, this); + types.popSilently(); + return result; + } catch (ConversionException conversionException) { + addInformationTo(conversionException, type, converter, parent); + throw conversionException; + } catch (RuntimeException e) { + ConversionException conversionException = new ConversionException(e); + addInformationTo(conversionException, type, converter, parent); + throw conversionException; + } + } + + private void addInformationTo(ErrorWriter errorWriter, Class type, Converter converter, Object parent) { + errorWriter.add("class", type.getName()); + errorWriter.add("required-type", getRequiredType().getName()); + errorWriter.add("converter-type", converter.getClass().getName()); + if (converter instanceof ErrorReporter) { + ((ErrorReporter)converter).appendErrors(errorWriter); + } + if (parent instanceof ErrorReporter) { + ((ErrorReporter)parent).appendErrors(errorWriter); + } + reader.appendErrors(errorWriter); + } + + public void addCompletionCallback(Runnable work, int priority) { + validationList.add(work, priority); + } + + public Object currentObject() { + return types.size() == 1 ? root : null; + } + + public Class getRequiredType() { + return (Class)types.peek(); + } + + public Object get(Object key) { + lazilyCreateDataHolder(); + return dataHolder.get(key); + } + + public void put(Object key, Object value) { + lazilyCreateDataHolder(); + dataHolder.put(key, value); + } + + public Iterator keys() { + lazilyCreateDataHolder(); + return dataHolder.keys(); + } + + private void lazilyCreateDataHolder() { + if (dataHolder == null) { + dataHolder = new MapBackedDataHolder(); + } + } + + public Object start(DataHolder dataHolder) { + this.dataHolder = dataHolder; + Class type = HierarchicalStreams.readClassType(reader, mapper); + Object result = convertAnother(null, type); + Iterator validations = validationList.iterator(); + while (validations.hasNext()) { + Runnable runnable = (Runnable)validations.next(); + runnable.run(); + } + return result; + } + + protected Mapper getMapper() { + return this.mapper; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/ArrayIterator.java b/xstream/src/java/com/thoughtworks/xstream/core/util/ArrayIterator.java new file mode 100644 index 0000000..782756d --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/ArrayIterator.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29.07.2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +import java.lang.reflect.Array; +import java.util.Iterator; + +/** + * @author Jörg Schaible + * + * @since 1.4 + */ +public class ArrayIterator implements Iterator { + private final Object array; + private int idx; + private int length; + public ArrayIterator(Object array) { + this.array = array; + length = Array.getLength(array); + } + + public boolean hasNext() { + return idx < length; + } + + public Object next() { + return Array.get(array, idx++); + } + + public void remove() { + throw new UnsupportedOperationException("Remove from array"); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/Base64Encoder.java b/xstream/src/java/com/thoughtworks/xstream/core/util/Base64Encoder.java new file mode 100644 index 0000000..f28d991 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/Base64Encoder.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. August 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; + +/** + * Encodes binary data to plain text as Base64. + * + *

Despite there being a gazillion other Base64 implementations out there, this has been written as part of XStream as + * it forms a core part but is too trivial to warrant an extra dependency.

+ * + *

This meets the standard as described in RFC 1521, section 5.2 , allowing + * other Base64 tools to manipulate the data.

+ * + * @author Joe Walnes + */ +public class Base64Encoder { + + // Here's how encoding works: + // + // 1) Incoming bytes are broken up into groups of 3 (each byte having 8 bits). + // + // 2) The combined 24 bits (3 * 8) are split into 4 groups of 6 bits. + // + // input |------||------||------| (3 values each with 8 bits) + // 101010101010101010101010 + // output |----||----||----||----| (4 values each with 6 bits) + // + // 3) Each of these 4 groups of 6 bits are converted back to a number, which will fall in the range of 0 - 63. + // + // 4) Each of these 4 numbers are converted to an alphanumeric char in a specified mapping table, to create + // a 4 character string. + // + // 5) This is repeated for all groups of three bytes. + // + // 6) Special padding is done at the end of the stream using the '=' char. + + private static final char[] SIXTY_FOUR_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); + private static final int[] REVERSE_MAPPING = new int[123]; + + static { + for (int i = 0; i < SIXTY_FOUR_CHARS.length; i++) REVERSE_MAPPING[SIXTY_FOUR_CHARS[i]] = i + 1; + } + + public String encode(byte[] input) { + StringBuffer result = new StringBuffer(); + int outputCharCount = 0; + for (int i = 0; i < input.length; i += 3) { + int remaining = Math.min(3, input.length - i); + int oneBigNumber = (input[i] & 0xff) << 16 | (remaining <= 1 ? 0 : input[i + 1] & 0xff) << 8 | (remaining <= 2 ? 0 : input[i + 2] & 0xff); + for (int j = 0; j < 4; j++) result.append(remaining + 1 > j ? SIXTY_FOUR_CHARS[0x3f & oneBigNumber >> 6 * (3 - j)] : '='); + if ((outputCharCount += 4) % 76 == 0) result.append('\n'); + } + return result.toString(); + } + + public byte[] decode(String input) { + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + StringReader in = new StringReader(input); + for (int i = 0; i < input.length(); i += 4) { + int a[] = {mapCharToInt(in), mapCharToInt(in), mapCharToInt(in), mapCharToInt(in)}; + int oneBigNumber = (a[0] & 0x3f) << 18 | (a[1] & 0x3f) << 12 | (a[2] & 0x3f) << 6 | (a[3] & 0x3f); + for (int j = 0; j < 3; j++) if (a[j + 1] >= 0) out.write(0xff & oneBigNumber >> 8 * (2 - j)); + } + return out.toByteArray(); + } catch (IOException e) { + throw new Error(e + ": " + e.getMessage()); + } + } + + private int mapCharToInt(Reader input) throws IOException { + int c; + while ((c = input.read()) != -1) { + int result = REVERSE_MAPPING[c]; + if (result != 0) return result -1; + if (c == '=') return -1; + } + return -1; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/ClassLoaderReference.java b/xstream/src/java/com/thoughtworks/xstream/core/util/ClassLoaderReference.java new file mode 100644 index 0000000..d79a5b9 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/ClassLoaderReference.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.core.util; + +/** + * ClassLoader that refers to another ClassLoader, allowing a single instance to be passed around the codebase that + * can later have its destination changed. + * + * @author Joe Walnes + * @author Jörg Schaible + * @since 1.1.1 + * @deprecated As of 1.4.5 use {@link com.thoughtworks.xstream.core.ClassLoaderReference} instead + */ +public class ClassLoaderReference extends ClassLoader { + + private transient ClassLoader reference; + + /** + * @deprecated As of 1.4.5 use + * {@link com.thoughtworks.xstream.core.ClassLoaderReference#ClassLoaderReference(ClassLoader)} + * instead + */ + public ClassLoaderReference(ClassLoader reference) { + this.reference = reference; + } + + /** + * @deprecated As of 1.4.5 use + * {@link com.thoughtworks.xstream.core.ClassLoaderReference#getReference()} + * .loadClass(String) instead + */ + public Class loadClass(String name) throws ClassNotFoundException { + return reference.loadClass(name); + } + + /** + * @deprecated As of 1.4.5 use + * {@link com.thoughtworks.xstream.core.ClassLoaderReference#getReference()} + * instead + */ + public ClassLoader getReference() { + return reference; + } + + /** + * @deprecated As of 1.4.5 use + * {@link com.thoughtworks.xstream.core.ClassLoaderReference#setReference(ClassLoader)} + * instead + */ + public void setReference(ClassLoader reference) { + this.reference = reference; + } + + private Object writeReplace() { + return new Replacement(); + } + + static class Replacement { + + private Object readResolve() { + return new ClassLoaderReference(new CompositeClassLoader()); + } + + }; +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/Cloneables.java b/xstream/src/java/com/thoughtworks/xstream/core/util/Cloneables.java new file mode 100644 index 0000000..5079097 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/Cloneables.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2009, 2010, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. August 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +import java.lang.reflect.Array; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; + +/** + * Utility functions for {@link Cloneable} objects. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class Cloneables { + + public static Object clone(Object o) { + if (o instanceof Cloneable) { + if (o.getClass().isArray()) { + final Class componentType = o.getClass().getComponentType(); + if (!componentType.isPrimitive()) { + return ((Object[])o).clone(); + } else { + int length = Array.getLength(o); + final Object clone = Array.newInstance(componentType, length); + while (length-- > 0) { + Array.set(clone, length, Array.get(o, length)); + } + + return clone; + } + } else { + try { + Method clone = o.getClass().getMethod("clone", (Class[])null); + return clone.invoke(o, (Object[])null); + } catch (NoSuchMethodException e) { + throw new ObjectAccessException("Cloneable type has no clone method", e); + } catch (IllegalAccessException e) { + throw new ObjectAccessException("Cannot clone Cloneable type", e); + } catch (InvocationTargetException e) { + throw new ObjectAccessException("Exception cloning Cloneable type", e.getCause()); + } + } + } + return null; + } + + public static Object cloneIfPossible(Object o) { + Object clone = clone(o); + return clone == null ? o : clone; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/CompositeClassLoader.java b/xstream/src/java/com/thoughtworks/xstream/core/util/CompositeClassLoader.java new file mode 100644 index 0000000..bdfc626 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/CompositeClassLoader.java @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 16. November 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core.util; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import com.thoughtworks.xstream.core.JVM; + +/** + * ClassLoader that is composed of other classloaders. Each loader will be used to try to load the particular class, until + * one of them succeeds. Note: The loaders will always be called in the REVERSE order they were added in. + * + *

The Composite class loader also has registered the classloader that loaded xstream.jar + * and (if available) the thread's context classloader.

+ * + *

Example

+ *
CompositeClassLoader loader = new CompositeClassLoader();
+ * loader.add(MyClass.class.getClassLoader());
+ * loader.add(new AnotherClassLoader());
+ *  
+ * loader.loadClass("com.blah.ChickenPlucker");
+ * 
+ * + *

The above code will attempt to load a class from the following classloaders (in order):

+ * + *
    + *
  • AnotherClassLoader (and all its parents)
  • + *
  • The classloader for MyClas (and all its parents)
  • + *
  • The thread's context classloader (and all its parents)
  • + *
  • The classloader for XStream (and all its parents)
  • + *
+ * + *

The added classloaders are kept with weak references to allow an application container to reload classes.

+ * + * @author Joe Walnes + * @author Jörg Schaible + * @since 1.0.3 + */ +public class CompositeClassLoader extends ClassLoader { + static { + if (JVM.is17()) { + // see http://www.cs.duke.edu/csed/java/jdk1.7/technotes/guides/lang/cl-mt.html + try { + Method m = ClassLoader.class.getDeclaredMethod("registerAsParallelCapable", (Class[])null); + if (!m.isAccessible()) { + m.setAccessible(true); + } + m.invoke(null, (Object[])null); + } catch (Exception e) { + // ignore errors, JVM will synchronize class for Java 7 or higher + } + } + } + + private final ReferenceQueue queue = new ReferenceQueue(); + private final List classLoaders = new ArrayList(); + + public CompositeClassLoader() { + addInternal(Object.class.getClassLoader()); // bootstrap loader. + addInternal(getClass().getClassLoader()); // whichever classloader loaded this jar. + } + + /** + * Add a loader to the n + * @param classLoader + */ + public synchronized void add(ClassLoader classLoader) { + cleanup(); + if (classLoader != null) { + addInternal(classLoader); + } + } + + private void addInternal(ClassLoader classLoader) { + WeakReference refClassLoader = null; + for (Iterator iterator = classLoaders.iterator(); iterator.hasNext();) { + WeakReference ref = (WeakReference) iterator.next(); + ClassLoader cl = (ClassLoader)ref.get(); + if (cl == null) { + iterator.remove(); + } else if (cl == classLoader) { + iterator.remove(); + refClassLoader = ref; + } + } + classLoaders.add(0, refClassLoader != null ? refClassLoader : new WeakReference(classLoader, queue)); + } + + public Class loadClass(String name) throws ClassNotFoundException { + List copy = new ArrayList(classLoaders.size()) { + + public boolean addAll(Collection c) { + boolean result = false; + for(Iterator iter = c.iterator(); iter.hasNext(); ) { + result |= add(iter.next()); + } + return result; + } + + public boolean add(Object ref) { + Object classLoader = ((WeakReference)ref).get(); + if (classLoader != null) { + return super.add(classLoader); + } + return false; + } + + }; + synchronized(this) { + cleanup(); + copy.addAll(classLoaders); + } + + ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + for (Iterator iterator = copy.iterator(); iterator.hasNext();) { + ClassLoader classLoader = (ClassLoader) iterator.next(); + if (classLoader == contextClassLoader) { + contextClassLoader = null; + } + try { + return classLoader.loadClass(name); + } catch (ClassNotFoundException notFound) { + // ok.. try another one + } + } + + // One last try - the context class loader associated with the current thread. Often used in j2ee servers. + // Note: The contextClassLoader cannot be added to the classLoaders list up front as the thread that constructs + // XStream is potentially different to thread that uses it. + if (contextClassLoader != null) { + return contextClassLoader.loadClass(name); + } else { + throw new ClassNotFoundException(name); + } + } + + private void cleanup() { + WeakReference ref; + while ((ref = (WeakReference)queue.poll()) != null) + { + classLoaders.remove(ref); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/CustomObjectInputStream.java b/xstream/src/java/com/thoughtworks/xstream/core/util/CustomObjectInputStream.java new file mode 100644 index 0000000..5b47e5e --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/CustomObjectInputStream.java @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2010, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 23. August 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core.util; + +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.NotActiveException; +import java.io.ObjectInputStream; +import java.io.ObjectInputValidation; +import java.io.ObjectStreamClass; +import java.io.StreamCorruptedException; +import java.util.Map; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.DataHolder; +import com.thoughtworks.xstream.core.ClassLoaderReference; + +public class CustomObjectInputStream extends ObjectInputStream { + + private FastStack callbacks = new FastStack(1); + private final ClassLoaderReference classLoaderReference; + + private static final String DATA_HOLDER_KEY = CustomObjectInputStream.class.getName(); + + public static interface StreamCallback { + Object readFromStream() throws IOException; + Map readFieldsFromStream() throws IOException; + void defaultReadObject() throws IOException; + void registerValidation(ObjectInputValidation validation, int priority) throws NotActiveException, InvalidObjectException; + void close() throws IOException; + } + + /** + * @deprecated As of 1.4 use {@link #getInstance(DataHolder, StreamCallback, ClassLoader)} + */ + public static CustomObjectInputStream getInstance(DataHolder whereFrom, CustomObjectInputStream.StreamCallback callback) { + return getInstance(whereFrom, callback, (ClassLoader)null); + } + + /** + * @deprecated As of 1.4.5 use {@link #getInstance(DataHolder, StreamCallback, ClassLoaderReference)} + */ + public static synchronized CustomObjectInputStream getInstance(DataHolder whereFrom, CustomObjectInputStream.StreamCallback callback, ClassLoader classLoader) { + return getInstance(whereFrom, callback, new ClassLoaderReference(classLoader)); + } + + public static synchronized CustomObjectInputStream getInstance(DataHolder whereFrom, CustomObjectInputStream.StreamCallback callback, ClassLoaderReference classLoaderReference) { + try { + CustomObjectInputStream result = (CustomObjectInputStream) whereFrom.get(DATA_HOLDER_KEY); + if (result == null) { + result = new CustomObjectInputStream(callback, classLoaderReference); + whereFrom.put(DATA_HOLDER_KEY, result); + } else { + result.pushCallback(callback); + } + return result; + } catch (IOException e) { + throw new ConversionException("Cannot create CustomObjectStream", e); + } + } + + /** + * Warning, this object is expensive to create (due to functionality inherited from superclass). + * Use the static fetch() method instead, wherever possible. + * + * @see #getInstance(DataHolder, StreamCallback, ClassLoaderReference) + */ + public CustomObjectInputStream(StreamCallback callback, ClassLoaderReference classLoaderReference) throws IOException, SecurityException { + super(); + this.callbacks.push(callback); + this.classLoaderReference = classLoaderReference; + } + + /** + * @deprecated As of 1.4.5 use {@link #CustomObjectInputStream(StreamCallback, ClassLoaderReference)} + */ + public CustomObjectInputStream(StreamCallback callback, ClassLoader classLoader) throws IOException, SecurityException { + this(callback, new ClassLoaderReference(classLoader)); + } + + /** + * Allows the CustomObjectInputStream (which is expensive to create) to be reused. + */ + public void pushCallback(StreamCallback callback) { + this.callbacks.push(callback); + } + + public StreamCallback popCallback(){ + return (StreamCallback) this.callbacks.pop(); + } + + public StreamCallback peekCallback(){ + return (StreamCallback) this.callbacks.peek(); + } + + protected Class resolveClass(ObjectStreamClass desc) + throws IOException, ClassNotFoundException { + ClassLoader classLoader = classLoaderReference.getReference(); + if (classLoader == null) { + return super.resolveClass(desc); + } else { + return Class.forName(desc.getName(), false, classLoader); + } + } + + public void defaultReadObject() throws IOException { + peekCallback().defaultReadObject(); + } + + protected Object readObjectOverride() throws IOException { + return peekCallback().readFromStream(); + } + + public Object readUnshared() throws IOException, ClassNotFoundException { + return readObject(); + } + + public boolean readBoolean() throws IOException { + return ((Boolean)peekCallback().readFromStream()).booleanValue(); + } + + public byte readByte() throws IOException { + return ((Byte)peekCallback().readFromStream()).byteValue(); + } + + public int readUnsignedByte() throws IOException { + int b = ((Byte)peekCallback().readFromStream()).byteValue(); + if (b < 0) { + b += Byte.MAX_VALUE; + } + return b; + } + + public int readInt() throws IOException { + return ((Integer)peekCallback().readFromStream()).intValue(); + } + + public char readChar() throws IOException { + return ((Character)peekCallback().readFromStream()).charValue(); + } + + public float readFloat() throws IOException { + return ((Float)peekCallback().readFromStream()).floatValue(); + } + + public double readDouble() throws IOException { + return ((Double)peekCallback().readFromStream()).doubleValue(); + } + + public long readLong() throws IOException { + return ((Long)peekCallback().readFromStream()).longValue(); + } + + public short readShort() throws IOException { + return ((Short)peekCallback().readFromStream()).shortValue(); + } + + public int readUnsignedShort() throws IOException { + int b = ((Short)peekCallback().readFromStream()).shortValue(); + if (b < 0) { + b += Short.MAX_VALUE; + } + return b; + } + + public String readUTF() throws IOException { + return (String)peekCallback().readFromStream(); + } + + public void readFully(byte[] buf) throws IOException { + readFully(buf, 0, buf.length); + } + + public void readFully(byte[] buf, int off, int len) throws IOException { + byte[] b = (byte[])peekCallback().readFromStream(); + System.arraycopy(b, 0, buf, off, len); + } + + public int read() throws IOException { + return readUnsignedByte(); + } + + public int read(byte[] buf, int off, int len) throws IOException { + byte[] b = (byte[])peekCallback().readFromStream(); + if (b.length != len) { + throw new StreamCorruptedException("Expected " + len + " bytes from stream, got " + b.length); + } + System.arraycopy(b, 0, buf, off, len); + return len; + } + + public int read(byte b[]) throws IOException { + return read(b, 0, b.length); + } + + public GetField readFields() throws IOException { + return new CustomGetField(peekCallback().readFieldsFromStream()); + } + + private class CustomGetField extends GetField { + + private Map fields; + + public CustomGetField(Map fields) { + this.fields = fields; + } + + public ObjectStreamClass getObjectStreamClass() { + throw new UnsupportedOperationException(); + } + + private Object get(String name) { + return fields.get(name); + } + + public boolean defaulted(String name) { + return !fields.containsKey(name); + } + + public byte get(String name, byte val) { + return defaulted(name) ? val : ((Byte)get(name)).byteValue(); + } + + public char get(String name, char val) { + return defaulted(name) ? val : ((Character)get(name)).charValue(); + } + + public double get(String name, double val) { + return defaulted(name) ? val : ((Double)get(name)).doubleValue(); + } + + public float get(String name, float val) { + return defaulted(name) ? val : ((Float)get(name)).floatValue(); + } + + public int get(String name, int val) { + return defaulted(name) ? val : ((Integer)get(name)).intValue(); + } + + public long get(String name, long val) { + return defaulted(name) ? val : ((Long)get(name)).longValue(); + } + + public short get(String name, short val) { + return defaulted(name) ? val : ((Short)get(name)).shortValue(); + } + + public boolean get(String name, boolean val) { + return defaulted(name) ? val : ((Boolean)get(name)).booleanValue(); + } + + public Object get(String name, Object val) { + return defaulted(name) ? val : get(name); + } + + } + + public void registerValidation(ObjectInputValidation validation, int priority) throws NotActiveException, InvalidObjectException { + peekCallback().registerValidation(validation, priority); + } + + public void close() throws IOException { + peekCallback().close(); + } + + /****** Unsupported methods ******/ + + public int available() { + throw new UnsupportedOperationException(); + } + + public String readLine() { + throw new UnsupportedOperationException(); + } + + public int skipBytes(int len) { + throw new UnsupportedOperationException(); + } + + public long skip(long n) { + throw new UnsupportedOperationException(); + } + + public void mark(int readlimit) { + throw new UnsupportedOperationException(); + } + + public void reset() { + throw new UnsupportedOperationException(); + } + + public boolean markSupported() { + return false; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/CustomObjectOutputStream.java b/xstream/src/java/com/thoughtworks/xstream/core/util/CustomObjectOutputStream.java new file mode 100644 index 0000000..09a2cdf --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/CustomObjectOutputStream.java @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 23. August 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core.util; + +import java.io.IOException; +import java.io.ObjectOutput; +import java.io.ObjectOutputStream; +import java.util.Map; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.DataHolder; + +public class CustomObjectOutputStream extends ObjectOutputStream { + + private FastStack callbacks = new FastStack(1); + private FastStack customFields = new FastStack(1); + + private static final String DATA_HOLDER_KEY = CustomObjectOutputStream.class.getName(); + + public static synchronized CustomObjectOutputStream getInstance(DataHolder whereFrom, StreamCallback callback) { + try { + CustomObjectOutputStream result = (CustomObjectOutputStream) whereFrom.get(DATA_HOLDER_KEY); + if (result == null) { + result = new CustomObjectOutputStream(callback); + whereFrom.put(DATA_HOLDER_KEY, result); + } else { + result.pushCallback(callback); + } + return result; + } catch (IOException e) { + throw new ConversionException("Cannot create CustomObjectStream", e); + } + } + + public static interface StreamCallback { + void writeToStream(Object object) throws IOException; + void writeFieldsToStream(Map fields) throws IOException; + void defaultWriteObject() throws IOException; + void flush() throws IOException; + void close() throws IOException; + } + + /** + * Warning, this object is expensive to create (due to functionality inherited from superclass). + * Use the static fetch() method instead, wherever possible. + * + * @see #getInstance(com.thoughtworks.xstream.converters.DataHolder, com.thoughtworks.xstream.core.util.CustomObjectOutputStream.StreamCallback) + */ + public CustomObjectOutputStream(StreamCallback callback) throws IOException, SecurityException { + this.callbacks.push(callback); + } + + /** + * Allows the CustomObjectOutputStream (which is expensive to create) to be reused. + */ + public void pushCallback(StreamCallback callback) { + this.callbacks.push(callback); + } + + public StreamCallback popCallback(){ + return (StreamCallback) this.callbacks.pop(); + } + + public StreamCallback peekCallback(){ + return (StreamCallback) this.callbacks.peek(); + } + + /*** Methods to delegate to callback ***/ + + public void defaultWriteObject() throws IOException { + peekCallback().defaultWriteObject(); + } + + protected void writeObjectOverride(Object obj) throws IOException { + peekCallback().writeToStream(obj); + } + + public void writeBoolean(boolean val) throws IOException { + peekCallback().writeToStream(val ? Boolean.TRUE : Boolean.FALSE); // JDK 1.3 friendly + } + + public void writeByte(int val) throws IOException { + peekCallback().writeToStream(new Byte((byte) val)); + } + + public void writeInt(int val) throws IOException { + peekCallback().writeToStream(new Integer(val)); + } + + public void writeChar(int val) throws IOException { + peekCallback().writeToStream(new Character((char)val)); + } + + public void writeDouble(double val) throws IOException { + peekCallback().writeToStream(new Double(val)); + } + + public void writeFloat(float val) throws IOException { + peekCallback().writeToStream(new Float(val)); + } + + public void writeLong(long val) throws IOException { + peekCallback().writeToStream(new Long(val)); + } + + public void writeShort(int val) throws IOException { + peekCallback().writeToStream(new Short((short) val)); + } + + public void write(byte[] buf) throws IOException { + peekCallback().writeToStream(buf); + } + + public void writeChars(String str) throws IOException { + peekCallback().writeToStream(str.toCharArray()); + } + + public void writeUTF(String str) throws IOException { + peekCallback().writeToStream(str); + } + + public void write(int val) throws IOException { + peekCallback().writeToStream(new Byte((byte) val)); + } + + public void write(byte[] buf, int off, int len) throws IOException { + byte[] b = new byte[len]; + System.arraycopy(buf, off, b, 0, len); + peekCallback().writeToStream(b); + } + + public void flush() throws IOException { + peekCallback().flush(); + } + + public void close() throws IOException { + peekCallback().close(); + } + + public PutField putFields() { + CustomPutField result = new CustomPutField(); + customFields.push(result); + return result; + } + + public void writeFields() throws IOException { + CustomPutField customPutField = (CustomPutField) customFields.pop(); + peekCallback().writeFieldsToStream(customPutField.asMap()); + } + + private class CustomPutField extends PutField { + + private final Map fields = new OrderRetainingMap(); + + public Map asMap() { + return fields; + } + + public void write(ObjectOutput out) throws IOException { + peekCallback().writeToStream(asMap()); + } + + public void put(String name, Object val) { + fields.put(name, val); + } + + public void put(String name, byte val) { + put(name, new Byte(val)); + } + + public void put(String name, char val) { + put(name, new Character(val)); + } + + public void put(String name, double val) { + put(name, new Double(val)); + } + + public void put(String name, float val) { + put(name, new Float(val)); + } + + public void put(String name, int val) { + put(name, new Integer(val)); + } + + public void put(String name, long val) { + put(name, new Long(val)); + } + + public void put(String name, short val) { + put(name, new Short(val)); + } + + public void put(String name, boolean val) { + put(name, val ? Boolean.TRUE : Boolean.FALSE); // JDK 1.3 friendly + } + + } + + /****** Unsupported methods ******/ + + public void reset() { + throw new UnsupportedOperationException(); + } + + public void useProtocolVersion(int version) { + throw new UnsupportedOperationException(); + } + + public void writeBytes(String str) { + throw new UnsupportedOperationException(); + } + + public void writeUnshared(Object obj) { + throw new UnsupportedOperationException(); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/DependencyInjectionFactory.java b/xstream/src/java/com/thoughtworks/xstream/core/util/DependencyInjectionFactory.java new file mode 100644 index 0000000..b7cb672 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/DependencyInjectionFactory.java @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2007, 2009, 2010, 2011, 2012, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. March 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.Comparator; +import java.util.List; + +import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; + + +/** + * A dependency injection factory. + * + * @author Jörg Schaible + * @since 1.2.2 + */ +public class DependencyInjectionFactory { + + /** + * Create an instance with dependency injection. The given dependencies are used to match the parameters of the + * constructors of the type. Constructors with most parameters are examined first. A parameter type sequence + * matching the sequence of the dependencies' types match first. Otherwise all the types of the dependencies must + * match one of the the parameters although no dependency is used twice. Use a {@link TypedNull} instance to inject + * null as parameter. + * + * @param type the type to create an instance of + * @param dependencies the possible dependencies + * @return the instantiated object + * @throws ObjectAccessException if no instance can be generated + * @throws IllegalArgumentException if more than 63 dependencies have been provided + * @since 1.2.2 + */ + public static Object newInstance(final Class type, final Object[] dependencies) { + return newInstance(type, dependencies, null); + } + + /** + * Create an instance with dependency injection. The given dependencies are used to match the parameters of the + * constructors of the type. Constructors with most parameters are examined first. A parameter type sequence + * matching the sequence of the dependencies' types match first. Otherwise all the types of the dependencies must + * match one of the the parameters although no dependency is used twice. Use a {@link TypedNull} instance to inject + * null as parameter. + * + * @param type the type to create an instance of + * @param dependencies the possible dependencies + * @param usedDependencies bit mask set by the method for all used dependencies (may be null) + * @return the instantiated object + * @throws ObjectAccessException if no instance can be generated + * @throws IllegalArgumentException if more than 63 dependencies have been provided + * @since 1.4 + */ + public static Object newInstance(final Class type, final Object[] dependencies, final BitSet usedDependencies) { + if (dependencies != null && dependencies.length > 63) { + throw new IllegalArgumentException("More than 63 arguments are not supported"); + } + Constructor bestMatchingCtor = null; + final ArrayList matchingDependencies = new ArrayList(); + List possibleMatchingDependencies = null; + long usedDeps = 0; + long possibleUsedDeps = 0; + + if (dependencies != null && dependencies.length > 0) { + // sort available ctors according their arity + final Constructor[] ctors = type.getConstructors(); + if (ctors.length > 1) { + Arrays.sort(ctors, new Comparator() { + public int compare(final Object o1, final Object o2) { + return ((Constructor)o2).getParameterTypes().length + - ((Constructor)o1).getParameterTypes().length; + } + }); + } + + final TypedValue[] typedDependencies = new TypedValue[dependencies.length]; + for (int i = 0; i < dependencies.length; i++ ) { + Object dependency = dependencies[i]; + Class depType = dependency.getClass(); + if (depType.isPrimitive()) { + depType = Primitives.box(depType); + } else if (depType == TypedNull.class) { + depType = ((TypedNull)dependency).getType(); + dependency = null; + } + + typedDependencies[i] = new TypedValue(depType, dependency); + } + + Constructor possibleCtor = null; + int arity = Integer.MAX_VALUE; + for (int i = 0; bestMatchingCtor == null && i < ctors.length; i++ ) { + final Constructor constructor = ctors[i]; + final Class[] parameterTypes = constructor.getParameterTypes(); + if (parameterTypes.length > dependencies.length) { + continue; + } else if (parameterTypes.length == 0) { + if (possibleCtor == null) { + bestMatchingCtor = constructor; + } + break; + } + if (arity > parameterTypes.length) { + if (possibleCtor != null) { + continue; + } + arity = parameterTypes.length; + } + + for (int j = 0; j < parameterTypes.length; j++ ) { + if (parameterTypes[j].isPrimitive()) { + parameterTypes[j] = Primitives.box(parameterTypes[j]); + } + } + + // first approach: test the ctor params against the dependencies in the sequence + // of the parameter declaration + matchingDependencies.clear(); + usedDeps = 0; + for (int j = 0, k = 0; j < parameterTypes.length + && parameterTypes.length + k - j <= typedDependencies.length; k++ ) { + if (parameterTypes[j].isAssignableFrom(typedDependencies[k].type)) { + matchingDependencies.add(typedDependencies[k].value); + usedDeps |= 1L << k; + if ( ++j == parameterTypes.length) { + bestMatchingCtor = constructor; + break; + } + } + } + + if (bestMatchingCtor == null) { + boolean possible = true; // assumption + + // try to match all dependencies in the sequence of the parameter + // declaration + final TypedValue[] deps = new TypedValue[typedDependencies.length]; + System.arraycopy(typedDependencies, 0, deps, 0, deps.length); + matchingDependencies.clear(); + usedDeps = 0; + for (int j = 0; j < parameterTypes.length; j++ ) { + int assignable = -1; + for (int k = 0; k < deps.length; k++ ) { + if (deps[k] == null) { + continue; + } + if (deps[k].type == parameterTypes[j]) { + assignable = k; + // optimal match + break; + } else if (parameterTypes[j].isAssignableFrom(deps[k].type)) { + // use most specific type + if (assignable < 0 + || (deps[assignable].type != deps[k].type && deps[assignable].type + .isAssignableFrom(deps[k].type))) { + assignable = k; + } + } + } + + if (assignable >= 0) { + matchingDependencies.add(deps[assignable].value); + usedDeps |= 1L << assignable; + deps[assignable] = null; // do not match same dep twice + } else { + possible = false; + break; + } + } + + if (possible) { + // the smaller the value, the smaller the indices in the deps array + if (possibleCtor != null && usedDeps >= possibleUsedDeps) { + continue; + } + possibleCtor = constructor; + possibleMatchingDependencies = (List)matchingDependencies.clone(); + possibleUsedDeps = usedDeps; + } + } + } + + if (bestMatchingCtor == null) { + if (possibleCtor == null) { + usedDeps = 0; + throw new ObjectAccessException("Cannot construct " + + type.getName() + + ", none of the dependencies match any constructor's parameters"); + } else { + bestMatchingCtor = possibleCtor; + matchingDependencies.clear(); + matchingDependencies.addAll(possibleMatchingDependencies); + usedDeps = possibleUsedDeps; + } + } + } + + try { + final Object instance; + if (bestMatchingCtor == null) { + instance = type.newInstance(); + } else { + instance = bestMatchingCtor.newInstance(matchingDependencies.toArray()); + } + if (usedDependencies != null) { + usedDependencies.clear(); + int i = 0; + for(long l = 1; l < usedDeps; l <<= 1, ++i) { + if ((usedDeps & l) > 0) { + usedDependencies.set(i); + } + } + } + return instance; + } catch (final InstantiationException e) { + throw new ObjectAccessException("Cannot construct " + type.getName(), e); + } catch (final IllegalAccessException e) { + throw new ObjectAccessException("Cannot construct " + type.getName(), e); + } catch (final InvocationTargetException e) { + throw new ObjectAccessException("Cannot construct " + type.getName(), e); + } catch (final SecurityException e) { + throw new ObjectAccessException("Cannot construct " + type.getName(), e); + } catch (final ExceptionInInitializerError e) { + throw new ObjectAccessException("Cannot construct " + type.getName(), e); + } + } + + private static class TypedValue { + final Class type; + final Object value; + + public TypedValue(final Class type, final Object value) { + super(); + this.type = type; + this.value = value; + } + + public String toString() + { + return type.getName() + ":" + value; + } + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/FastField.java b/xstream/src/java/com/thoughtworks/xstream/core/util/FastField.java new file mode 100644 index 0000000..3e4363f --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/FastField.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2008, 2010 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. October 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +public final class FastField { + private final String name; + private final String declaringClass; + + public FastField(String definedIn, String name) { + this.name = name; + this.declaringClass = definedIn; + } + + public FastField(Class definedIn, String name) { + this(definedIn == null ? null : definedIn.getName(), name); + } + + public String getName() { + return this.name; + } + + public String getDeclaringClass() { + return this.declaringClass; + } + + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (obj instanceof FastField) { + final FastField field = (FastField)obj; + if ((declaringClass == null && field.declaringClass != null) + || (declaringClass != null && field.declaringClass == null)) { + return false; + } + return name.equals(field.getName()) + && (declaringClass == null || declaringClass.equals(field.getDeclaringClass())); + } + return false; + } + + public int hashCode() { + return name.hashCode() ^ (declaringClass == null ? 0 : declaringClass.hashCode()); + } + + public String toString() { + return (declaringClass == null ? "" : declaringClass + ".") + name; + } +} \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/FastStack.java b/xstream/src/java/com/thoughtworks/xstream/core/util/FastStack.java new file mode 100644 index 0000000..92f6068 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/FastStack.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 02. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core.util; + +/** + * An array-based stack implementation. + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public final class FastStack { + + private Object[] stack; + private int pointer; + + public FastStack(int initialCapacity) { + stack = new Object[initialCapacity]; + } + + public Object push(Object value) { + if (pointer + 1 >= stack.length) { + resizeStack(stack.length * 2); + } + stack[pointer++] = value; + return value; + } + + public void popSilently() { + stack[--pointer] = null; + } + + public Object pop() { + final Object result = stack[--pointer]; + stack[pointer] = null; + return result; + } + + public Object peek() { + return pointer == 0 ? null : stack[pointer - 1]; + } + + public Object replace(Object value) { + final Object result = stack[pointer - 1]; + stack[pointer - 1] = value; + return result; + } + + public void replaceSilently(Object value) { + stack[pointer - 1] = value; + } + + public int size() { + return pointer; + } + + public boolean hasStuff() { + return pointer > 0; + } + + public Object get(int i) { + return stack[i]; + } + + private void resizeStack(int newCapacity) { + Object[] newStack = new Object[newCapacity]; + System.arraycopy(stack, 0, newStack, 0, Math.min(pointer, newCapacity)); + stack = newStack; + } + + public String toString() { + StringBuffer result = new StringBuffer("["); + for (int i = 0; i < pointer; i++) { + if (i > 0) { + result.append(", "); + } + result.append(stack[i]); + } + result.append(']'); + return result.toString(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/Fields.java b/xstream/src/java/com/thoughtworks/xstream/core/util/Fields.java new file mode 100644 index 0000000..368353a --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/Fields.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. April 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core.util; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; + +/** + * Slightly nicer way to find, get and set fields in classes. Wraps standard java.lang.reflect.Field calls but wraps + * wraps exception in XStreamExceptions. + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class Fields { + public static Field locate(Class definedIn, Class fieldType, boolean isStatic) { + Field field = null; + try { + Field[] fields = definedIn.getDeclaredFields(); + for(int i = 0; i < fields.length; ++i) { + if (Modifier.isStatic(fields[i].getModifiers()) == isStatic) { + if (fieldType.isAssignableFrom(fields[i].getType())) { + field = fields[i]; + } + } + } + if (field != null && !field.isAccessible()) { + field.setAccessible(true); + } + } catch (SecurityException e) { + // active SecurityManager + } catch (NoClassDefFoundError e) { + // restricted type in GAE + } + return field; + } + + public static Field find(Class type, String name) { + try { + Field result = type.getDeclaredField(name); + if (!result.isAccessible()) { + result.setAccessible(true); + } + return result; + } catch (NoSuchFieldException e) { + throw new IllegalArgumentException("Could not access " + type.getName() + "." + name + " field: " + e.getMessage()); + } catch (NoClassDefFoundError e) { + throw new ObjectAccessException("Could not access " + type.getName() + "." + name + " field: " + e.getMessage()); + } + } + + public static void write(Field field, Object instance, Object value) { + try { + field.set(instance, value); + } catch (IllegalAccessException e) { + throw new ObjectAccessException("Could not write " + field.getType().getName() + "." + field.getName() + " field", e); + } catch (NoClassDefFoundError e) { + throw new ObjectAccessException("Could not write " + field.getType().getName() + "." + field.getName() + " field", e); + } + } + + public static Object read(Field field, Object instance) { + try { + return field.get(instance); + } catch (IllegalAccessException e) { + throw new ObjectAccessException("Could not read " + field.getType().getName() + "." + field.getName() + " field", e); + } catch (NoClassDefFoundError e) { + throw new ObjectAccessException("Could not read " + field.getType().getName() + "." + field.getName() + " field", e); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/HierarchicalStreams.java b/xstream/src/java/com/thoughtworks/xstream/core/util/HierarchicalStreams.java new file mode 100644 index 0000000..85ae1ed --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/HierarchicalStreams.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 09. October 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + +/** + * Helper methods for {@link HierarchicalStreamReader} and {@link HierarchicalStreamWriter}. + * + * @author Jörg Schaible + * @since 1.3.1 + */ +public class HierarchicalStreams { + + public static Class readClassType(HierarchicalStreamReader reader, Mapper mapper) { + String classAttribute = readClassAttribute(reader, mapper); + Class type; + if (classAttribute == null) { + type = mapper.realClass(reader.getNodeName()); + } else { + type = mapper.realClass(classAttribute); + } + return type; + } + + public static String readClassAttribute(HierarchicalStreamReader reader, Mapper mapper) { + String attributeName = mapper.aliasForSystemAttribute("resolves-to"); + String classAttribute = attributeName == null ? null : reader.getAttribute(attributeName); + if (classAttribute == null) { + attributeName = mapper.aliasForSystemAttribute("class"); + if (attributeName != null) { + classAttribute = reader.getAttribute(attributeName); + } + } + return classAttribute; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/ObjectIdDictionary.java b/xstream/src/java/com/thoughtworks/xstream/core/util/ObjectIdDictionary.java new file mode 100644 index 0000000..4c42d4d --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/ObjectIdDictionary.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2010 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 09. May 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core.util; + +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.HashMap; +import java.util.Map; + + +/** + * Store IDs against given object references. + *

+ * Behaves similar to java.util.IdentityHashMap, but in JDK1.3 as well. Additionally the + * implementation keeps track of orphaned IDs by using a WeakReference to store the reference + * object. + *

+ */ +public class ObjectIdDictionary { + + private final Map map = new HashMap(); + private final ReferenceQueue queue = new ReferenceQueue(); + + private static interface Wrapper { + int hashCode(); + boolean equals(Object obj); + String toString(); + Object get(); + } + + private static class IdWrapper implements Wrapper { + + private final Object obj; + private final int hashCode; + + public IdWrapper(Object obj) { + hashCode = System.identityHashCode(obj); + this.obj = obj; + } + + public int hashCode() { + return hashCode; + } + + public boolean equals(Object other) { + return obj == ((Wrapper)other).get(); + } + + public String toString() { + return obj.toString(); + } + + public Object get() { + return obj; + } + } + + private class WeakIdWrapper extends WeakReference implements Wrapper { + + private final int hashCode; + + public WeakIdWrapper(Object obj) { + super(obj, queue); + hashCode = System.identityHashCode(obj); + } + + public int hashCode() { + return hashCode; + } + + public boolean equals(Object other) { + return get() == ((Wrapper)other).get(); + } + + public String toString() { + Object obj = get(); + return obj == null ? "(null)" : obj.toString(); + } + } + + public void associateId(Object obj, Object id) { + map.put(new WeakIdWrapper(obj), id); + cleanup(); + } + + public Object lookupId(Object obj) { + Object id = map.get(new IdWrapper(obj)); + return id; + } + + public boolean containsId(Object item) { + boolean b = map.containsKey(new IdWrapper(item)); + return b; + } + + public void removeId(Object item) { + map.remove(new IdWrapper(item)); + cleanup(); + } + + public int size() { + cleanup(); + return map.size(); + } + + private void cleanup() { + WeakIdWrapper wrapper; + while ((wrapper = (WeakIdWrapper)queue.poll()) != null) + { + map.remove(wrapper); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/OrderRetainingMap.java b/xstream/src/java/com/thoughtworks/xstream/core/util/OrderRetainingMap.java new file mode 100644 index 0000000..f62062f --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/OrderRetainingMap.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. February 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.core.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + + +/** + * @deprecated As of 1.4.8 use {@link java.util.LinkedHashMap} + */ +public class OrderRetainingMap extends HashMap { + + private ArraySet keyOrder = new ArraySet(); + private List valueOrder = new ArrayList(); + + public OrderRetainingMap() { + super(); + } + + public OrderRetainingMap(Map m) { + super(); + putAll(m); + } + + public void putAll(Map m) { + for(Iterator iter = m.entrySet().iterator(); iter.hasNext(); ) { + Map.Entry entry = (Map.Entry)iter.next(); + put(entry.getKey(), entry.getValue()); + } + } + + public Object put(Object key, Object value) { + int idx = keyOrder.lastIndexOf(key); + if (idx < 0) { + keyOrder.add(key); + valueOrder.add(value); + } else { + valueOrder.set(idx, value); + } + return super.put(key, value); + } + + public Object remove(Object key) { + int idx = keyOrder.lastIndexOf(key); + if (idx != 0) { + keyOrder.remove(idx); + valueOrder.remove(idx); + } + return super.remove(key); + } + + public void clear() { + keyOrder.clear(); + valueOrder.clear(); + super.clear(); + } + + public Collection values() { + return Collections.unmodifiableList(valueOrder); + } + + public Set keySet() { + return Collections.unmodifiableSet(keyOrder); + } + + public Set entrySet() { + Map.Entry[] entries = new Map.Entry[size()]; + for (Iterator iter = super.entrySet().iterator(); iter.hasNext();) { + Map.Entry entry = (Map.Entry)iter.next(); + entries[keyOrder.indexOf(entry.getKey())] = entry; + } + Set set = new ArraySet(); + set.addAll(Arrays.asList(entries)); + return Collections.unmodifiableSet(set); + } + + private static class ArraySet extends ArrayList implements Set { + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/Pool.java b/xstream/src/java/com/thoughtworks/xstream/core/util/Pool.java new file mode 100644 index 0000000..1829377 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/Pool.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 10. May 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +/** + * A simple pool implementation. + * + * @author Jörg Schaible + * @author Joe Walnes + */ +public class Pool { + + public interface Factory { + public Object newInstance(); + } + + private final int initialPoolSize; + private final int maxPoolSize; + private final Factory factory; + private transient Object[] pool; + private transient int nextAvailable; + private transient Object mutex = new Object(); + + public Pool(int initialPoolSize, int maxPoolSize, Factory factory) { + this.initialPoolSize = initialPoolSize; + this.maxPoolSize = maxPoolSize; + this.factory = factory; + } + + public Object fetchFromPool() { + Object result; + synchronized (mutex) { + if (pool == null) { + pool = new Object[maxPoolSize]; + for (nextAvailable = initialPoolSize; nextAvailable > 0; ) { + putInPool(factory.newInstance()); + } + } + while (nextAvailable == maxPoolSize) { + try { + mutex.wait(); + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted whilst waiting " + + "for a free item in the pool : " + e.getMessage()); + } + } + result = pool[nextAvailable++]; + if (result == null) { + result = factory.newInstance(); + putInPool(result); + ++nextAvailable; + } + } + return result; + } + + protected void putInPool(Object object) { + synchronized (mutex) { + pool[--nextAvailable] = object; + mutex.notify(); + } + } + + private Object readResolve() { + mutex = new Object(); + return this; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/PresortedMap.java b/xstream/src/java/com/thoughtworks/xstream/core/util/PresortedMap.java new file mode 100644 index 0000000..13b3800 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/PresortedMap.java @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2006, 2007, 2010 XStream Committers. + * All rights reserved. + * + * Created on 12.10.2010 by Joerg Schaible, extracted from TreeMapConverter. + */ +package com.thoughtworks.xstream.core.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; + +/** + * @author Jörg Schaible + */ +public class PresortedMap implements SortedMap { + + private static class ArraySet extends ArrayList implements Set { + } + + private final PresortedMap.ArraySet set; + private final Comparator comparator; + + public PresortedMap() { + this(null, new ArraySet()); + } + + public PresortedMap(Comparator comparator) { + this(comparator, new ArraySet()); + } + + private PresortedMap(Comparator comparator, PresortedMap.ArraySet set) { + this.comparator = comparator != null ? comparator : new ArraySetComparator(set); + this.set = set; + } + + public Comparator comparator() { + return comparator; + } + + public Set entrySet() { + return set; + } + + public Object firstKey() { + throw new UnsupportedOperationException(); + } + + public SortedMap headMap(Object toKey) { + throw new UnsupportedOperationException(); + } + + public Set keySet() { + Set keySet = new ArraySet(); + for (final Iterator iterator = set.iterator(); iterator.hasNext();) { + final Entry entry = (Entry)iterator.next(); + keySet.add(entry.getKey()); + } + return keySet; + } + + public Object lastKey() { + throw new UnsupportedOperationException(); + } + + public SortedMap subMap(Object fromKey, Object toKey) { + throw new UnsupportedOperationException(); + } + + public SortedMap tailMap(Object fromKey) { + throw new UnsupportedOperationException(); + } + + public Collection values() { + Set values = new ArraySet(); + for (final Iterator iterator = set.iterator(); iterator.hasNext();) { + final Entry entry = (Entry)iterator.next(); + values.add(entry.getValue()); + } + return values; + } + + public void clear() { + throw new UnsupportedOperationException(); + } + + public boolean containsKey(Object key) { + return false; + } + + public boolean containsValue(Object value) { + throw new UnsupportedOperationException(); + } + + public Object get(Object key) { + throw new UnsupportedOperationException(); + } + + public boolean isEmpty() { + return set.isEmpty(); + } + + public Object put(final Object key, final Object value) { + set.add(new Entry(){ + + public Object getKey() { + return key; + } + + public Object getValue() { + return value; + } + + public Object setValue(Object value) { + throw new UnsupportedOperationException(); + }}); + return null; + } + + public void putAll(Map m) { + for (final Iterator iter = m.entrySet().iterator(); iter.hasNext();) { + set.add(iter.next()); + } + } + + public Object remove(Object key) { + throw new UnsupportedOperationException(); + } + + public int size() { + return set.size(); + } + + private static class ArraySetComparator implements Comparator { + + private final ArrayList list; + private Map.Entry[] array; + + ArraySetComparator(ArrayList list) { + this.list = list; + } + + public int compare(Object object1, Object object2) { + if (array == null || list.size() != array.length) { + Map.Entry[] a = new Map.Entry[list.size()]; + if (array != null) { + System.arraycopy(array, 0, a, 0, array.length); + } + for (int i = array == null ? 0 : array.length; i < list.size(); ++i) { + a[i] = (Map.Entry)list.get(i); + } + array = a; + } + int idx1 = Integer.MAX_VALUE, idx2 = Integer.MAX_VALUE; + for(int i = 0; i < array.length && !(idx1 < Integer.MAX_VALUE && idx2 < Integer.MAX_VALUE); ++i) { + if (idx1 == Integer.MAX_VALUE && object1 == array[i].getKey()) { + idx1 = i; + } + if (idx2 == Integer.MAX_VALUE && object2 == array[i].getKey()) { + idx2 = i; + } + } + return idx1 - idx2; + } + } +} \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/PresortedSet.java b/xstream/src/java/com/thoughtworks/xstream/core/util/PresortedSet.java new file mode 100644 index 0000000..bc252d3 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/PresortedSet.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2006, 2007, 2010 XStream Committers. + * All rights reserved. + * + * Created on 12.10.2010 by Joerg Schaible, extracted from TreeSetConverter. + */ +package com.thoughtworks.xstream.core.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.SortedSet; + +/** + * @author Jörg Schaible + */ +public class PresortedSet implements SortedSet { + private final List list = new ArrayList(); + private final Comparator comparator; + + public PresortedSet() { + this(null); + } + + public PresortedSet(Comparator comparator) { + this(comparator, null); + } + + public PresortedSet(Comparator comparator, Collection c) { + this.comparator = comparator; + if (c != null) { + addAll(c); + } + } + + public boolean add(Object e) { + return this.list.add(e); + } + + public boolean addAll(Collection c) { + return this.list.addAll(c); + } + + public void clear() { + this.list.clear(); + } + + public boolean contains(Object o) { + return this.list.contains(o); + } + + public boolean containsAll(Collection c) { + return this.list.containsAll(c); + } + + public boolean equals(Object o) { + return this.list.equals(o); + } + + public int hashCode() { + return this.list.hashCode(); + } + + public boolean isEmpty() { + return this.list.isEmpty(); + } + + public Iterator iterator() { + return this.list.iterator(); + } + + public boolean remove(Object o) { + return this.list.remove(o); + } + + public boolean removeAll(Collection c) { + return this.list.removeAll(c); + } + + public boolean retainAll(Collection c) { + return this.list.retainAll(c); + } + + public int size() { + return this.list.size(); + } + + public List subList(int fromIndex, int toIndex) { + return this.list.subList(fromIndex, toIndex); + } + + public Object[] toArray() { + return this.list.toArray(); + } + + public Object[] toArray(Object[] a) { + return this.list.toArray(a); + } + + public Comparator comparator() { + return comparator; + } + + public Object first() { + return list.isEmpty() ? null : list.get(0); + } + + public SortedSet headSet(Object toElement) { + throw new UnsupportedOperationException(); + } + + public Object last() { + return list.isEmpty() ? null : list.get(list.size() - 1); + } + + public SortedSet subSet(Object fromElement, Object toElement) { + throw new UnsupportedOperationException(); + } + + public SortedSet tailSet(Object fromElement) { + throw new UnsupportedOperationException(); + } +} \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/Primitives.java b/xstream/src/java/com/thoughtworks/xstream/core/util/Primitives.java new file mode 100644 index 0000000..7a95282 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/Primitives.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 11. October 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +import java.util.HashMap; +import java.util.Map; + +/** + * Utility class for primitives. + * + * @author Jörg Schaible + * @since 1.2.1 + */ +public final class Primitives { + private final static Map BOX = new HashMap(); + private final static Map UNBOX = new HashMap(); + private final static Map NAMED_PRIMITIVE = new HashMap(); + private final static Map REPRESENTING_CHAR = new HashMap(); + + static { + final Class[][] boxing = new Class[][]{ + { Byte.TYPE, Byte.class}, + { Character.TYPE, Character.class}, + { Short.TYPE, Short.class}, + { Integer.TYPE, Integer.class}, + { Long.TYPE, Long.class}, + { Float.TYPE, Float.class}, + { Double.TYPE, Double.class}, + { Boolean.TYPE, Boolean.class}, + { Void.TYPE, Void.class}, + }; + final Character[] representingChars = { + new Character('B'), + new Character('C'), + new Character('S'), + new Character('I'), + new Character('J'), + new Character('F'), + new Character('D'), + new Character('Z'), + null + }; + for (int i = 0; i < boxing.length; i++) { + final Class primitiveType = boxing[i][0]; + final Class boxedType = boxing[i][1]; + BOX.put(primitiveType, boxedType); + UNBOX.put(boxedType, primitiveType); + NAMED_PRIMITIVE.put(primitiveType.getName(), primitiveType); + REPRESENTING_CHAR.put(primitiveType, representingChars[i]); + } + } + + /** + * Get the boxed type for a primitive. + * + * @param type the primitive type + * @return the boxed type or null + */ + static public Class box(final Class type) { + return (Class)BOX.get(type); + } + + /** + * Get the primitive type for a boxed one. + * + * @param type the boxed type + * @return the primitive type or null + */ + static public Class unbox(final Class type) { + return (Class)UNBOX.get(type); + } + + /** + * Check for a boxed type. + * + * @param type the type to check + * @return true if the type is boxed + * @since 1.4 + */ + static public boolean isBoxed(final Class type) { + return UNBOX.containsKey(type); + } + + /** + * Get the primitive type by name. + * + * @param name the name of the type + * @return the Java type or null + * @since 1.4 + */ + static public Class primitiveType(final String name) { + return (Class)NAMED_PRIMITIVE.get(name); + } + + /** + * Get the representing character of a primitive type. + * + * @param type the primitive type + * @return the representing character or 0 + * @since 1.4 + */ + static public char representingChar(final Class type) { + Character ch = (Character)REPRESENTING_CHAR.get(type); + return ch == null ? 0 : ch.charValue(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/PrioritizedList.java b/xstream/src/java/com/thoughtworks/xstream/core/util/PrioritizedList.java new file mode 100644 index 0000000..f6546b7 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/PrioritizedList.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. February 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.core.util; + +import java.util.Iterator; +import java.util.Set; +import java.util.TreeSet; + + +/** + * List that allows items to be added with a priority that will affect the order in which they are later iterated over. + * Objects with a high priority will appear before objects with a low priority in the list. If two objects of the same + * priority are added to the list, the most recently added one will be iterated over first. Implementation uses a + * TreeSet, which has a guaranteed add time of O(log(n)). + * + * @author Joe Walnes + * @author Guilherme Silveira + */ +public class PrioritizedList { + + private final Set set = new TreeSet(); + + private int lowestPriority = Integer.MAX_VALUE; + + private int lastId = 0; + + public void add(Object item, int priority) { + if (this.lowestPriority > priority) { + this.lowestPriority = priority; + } + this.set.add(new PrioritizedItem(item, priority, ++lastId)); + } + + public Iterator iterator() { + return new PrioritizedItemIterator(this.set.iterator()); + } + + private static class PrioritizedItem implements Comparable { + + final Object value; + final int priority; + final int id; + + public PrioritizedItem(Object value, int priority, int id) { + this.value = value; + this.priority = priority; + this.id = id; + } + + public int compareTo(Object o) { + PrioritizedItem other = (PrioritizedItem)o; + if (this.priority != other.priority) { + return (other.priority - this.priority); + } + return (other.id - this.id); + } + + public boolean equals(Object obj) { + return this.id == ((PrioritizedItem)obj).id; + } + + } + + private static class PrioritizedItemIterator implements Iterator { + + private Iterator iterator; + + public PrioritizedItemIterator(Iterator iterator) { + this.iterator = iterator; + } + + public void remove() { + // call iterator.remove()? + throw new UnsupportedOperationException(); + } + + public boolean hasNext() { + return iterator.hasNext(); + } + + public Object next() { + return ((PrioritizedItem)iterator.next()).value; + } + + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/QuickWriter.java b/xstream/src/java/com/thoughtworks/xstream/core/util/QuickWriter.java new file mode 100644 index 0000000..019ed36 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/QuickWriter.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core.util; + +import com.thoughtworks.xstream.io.StreamException; + +import java.io.IOException; +import java.io.Writer; + +public class QuickWriter { + + private final Writer writer; + private char[] buffer; + private int pointer; + + public QuickWriter(Writer writer) { + this(writer, 1024); + } + + public QuickWriter(Writer writer, int bufferSize) { + this.writer = writer; + buffer = new char[bufferSize]; + } + + public void write(String str) { + int len = str.length(); + if (pointer + len >= buffer.length) { + flush(); + if (len > buffer.length) { + raw(str.toCharArray()); + return; + } + } + str.getChars(0, len, buffer, pointer); + pointer += len; + } + + public void write(char c) { + if (pointer + 1 >= buffer.length) { + flush(); + if (buffer.length == 0) { + raw(c); + return; + } + } + buffer[pointer++] = c; + } + + public void write(char[] c) { + int len = c.length; + if (pointer + len >= buffer.length) { + flush(); + if (len > buffer.length) { + raw(c); + return; + } + } + System.arraycopy(c, 0, buffer, pointer, len); + pointer += len; + } + + public void flush() { + try { + writer.write(buffer, 0, pointer); + pointer = 0; + writer.flush(); + } catch (IOException e) { + throw new StreamException(e); + } + } + + public void close() { + try { + writer.write(buffer, 0, pointer); + pointer = 0; + writer.close(); + } catch (IOException e) { + throw new StreamException(e); + } + } + + private void raw(char[] c) { + try { + writer.write(c); + writer.flush(); + } catch (IOException e) { + throw new StreamException(e); + } + } + + private void raw(char c) { + try { + writer.write(c); + writer.flush(); + } catch (IOException e) { + throw new StreamException(e); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/SelfStreamingInstanceChecker.java b/xstream/src/java/com/thoughtworks/xstream/core/util/SelfStreamingInstanceChecker.java new file mode 100644 index 0000000..d4ee0f5 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/SelfStreamingInstanceChecker.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. March 2013 by Joerg Schaible, moved from package + * com.thoughtworks.xstream.converters.reflection. + */ +package com.thoughtworks.xstream.core.util; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + +/** + * A special converter that prevents self-serialization. The serializing XStream instance + * adds a converter of this type to prevent self-serialization and will throw an + * exception instead. + * + * @author Jörg Schaible + * @since 1.2 + */ +public class SelfStreamingInstanceChecker implements Converter { + + private final Object self; + private Converter defaultConverter; + private final ConverterLookup lookup; + + /** + * @since 1.4.5 + */ + public SelfStreamingInstanceChecker(ConverterLookup lookup, Object xstream) { + this.lookup = lookup; + this.self = xstream; + } + + /** + * @deprecated As of 1.4.5 use {@link #SelfStreamingInstanceChecker(ConverterLookup, Object)} + */ + public SelfStreamingInstanceChecker(Converter defaultConverter, Object xstream) { + this.defaultConverter = defaultConverter; + this.self = xstream; + lookup = null; + } + + public boolean canConvert(Class type) { + return type == self.getClass(); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + if (source == self) { + throw new ConversionException("Cannot marshal the XStream instance in action"); + } + getConverter().marshal(source, writer, context); + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + return getConverter().unmarshal(reader, context); + } + + private Converter getConverter() { + return defaultConverter != null ? defaultConverter : lookup.lookupConverterForType(Object.class); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/SerializationMembers.java b/xstream/src/java/com/thoughtworks/xstream/core/util/SerializationMembers.java new file mode 100644 index 0000000..505df5d --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/SerializationMembers.java @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2014, 2015 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 12. February 2015 by Joerg Schaible, copied from c.t.x.converters.reflection.SerializationMemberInvoker. + */ +package com.thoughtworks.xstream.core.util; + +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamField; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; +import com.thoughtworks.xstream.core.Caching; + + +/** + * Convenience wrapper to invoke special serialization methods on objects (and perform reflection caching). + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class SerializationMembers implements Caching { + + private static final Method NO_METHOD = (new Object() { + private void noMethod() { + } + }).getClass().getDeclaredMethods()[0]; + private static final Object[] EMPTY_ARGS = new Object[0]; + private static final Class[] EMPTY_CLASSES = new Class[0]; + private static final Map NO_FIELDS = Collections.EMPTY_MAP; + private static final int PERSISTENT_FIELDS_MODIFIER = Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL; + private static final FastField[] OBJECT_TYPE_FIELDS = { + new FastField(Object.class, "readResolve"), + new FastField(Object.class, "writeReplace"), + new FastField(Object.class, "readObject"), + new FastField(Object.class, "writeObject") + }; + private Map declaredCache = Collections.synchronizedMap(new HashMap()); + private Map resRepCache = Collections.synchronizedMap(new HashMap()); + private final Map fieldCache = Collections.synchronizedMap(new HashMap()); + { + for(int i = 0; i < OBJECT_TYPE_FIELDS.length; ++i) { + declaredCache.put(OBJECT_TYPE_FIELDS[i], NO_METHOD); + } + for(int i = 0; i < 2; ++i) { + resRepCache.put(OBJECT_TYPE_FIELDS[i], NO_METHOD); + } + } + + /** + * Resolves an object as native serialization does by calling readResolve(), if available. + */ + public Object callReadResolve(final Object result) { + if (result == null) { + return null; + } else { + final Class resultType = result.getClass(); + final Method readResolveMethod = getRRMethod(resultType, "readResolve"); + if (readResolveMethod != null) { + try { + return readResolveMethod.invoke(result, EMPTY_ARGS); + } catch (IllegalAccessException e) { + throw new ObjectAccessException("Could not call " + + resultType.getName() + + ".readResolve()", e); + } catch (InvocationTargetException e) { + throw new ObjectAccessException("Could not call " + + resultType.getName() + + ".readResolve()", e.getTargetException()); + } + } else { + return result; + } + } + } + + public Object callWriteReplace(final Object object) { + if (object == null) { + return null; + } else { + final Class objectType = object.getClass(); + final Method writeReplaceMethod = getRRMethod(objectType, "writeReplace"); + if (writeReplaceMethod != null) { + try { + return writeReplaceMethod.invoke(object, EMPTY_ARGS); + } catch (IllegalAccessException e) { + throw new ObjectAccessException("Could not call " + + objectType.getName() + + ".writeReplace()", e); + } catch (InvocationTargetException e) { + throw new ObjectAccessException("Could not call " + + objectType.getName() + + ".writeReplace()", e.getTargetException()); + } + } else { + return object; + } + } + } + + public boolean supportsReadObject(final Class type, final boolean includeBaseClasses) { + return getMethod( + type, "readObject", new Class[]{ObjectInputStream.class}, includeBaseClasses) != null; + } + + public void callReadObject(final Class type, final Object object, final ObjectInputStream stream) { + try { + Method readObjectMethod = getMethod( + type, "readObject", new Class[]{ObjectInputStream.class}, false); + readObjectMethod.invoke(object, new Object[]{stream}); + } catch (IllegalAccessException e) { + throw new ConversionException("Could not call " + + object.getClass().getName() + + ".readObject()", e); + } catch (InvocationTargetException e) { + throw new ConversionException("Could not call " + + object.getClass().getName() + + ".readObject()", e.getTargetException()); + } + } + + public boolean supportsWriteObject(final Class type, final boolean includeBaseClasses) { + return getMethod( + type, "writeObject", new Class[]{ObjectOutputStream.class}, includeBaseClasses) != null; + } + + public void callWriteObject(final Class type, final Object instance, final ObjectOutputStream stream) { + try { + Method readObjectMethod = getMethod( + type, "writeObject", new Class[]{ObjectOutputStream.class}, false); + readObjectMethod.invoke(instance, new Object[]{stream}); + } catch (IllegalAccessException e) { + throw new ConversionException("Could not call " + + instance.getClass().getName() + + ".writeObject()", e); + } catch (InvocationTargetException e) { + throw new ConversionException("Could not call " + + instance.getClass().getName() + + ".writeObject()", e.getTargetException()); + } + } + + private Method getMethod(Class type, String name, Class[] parameterTypes, + boolean includeBaseclasses) { + Method method = getMethod(type, name, parameterTypes); + return method == NO_METHOD + || (!includeBaseclasses && !method.getDeclaringClass().equals(type)) + ? null + : method; + } + + private Method getMethod(Class type, String name, Class[] parameterTypes) { + if (type == null) { + return null; + } + FastField method = new FastField(type, name); + Method result = (Method)declaredCache.get(method); + if (result == null) { + try { + result = type.getDeclaredMethod(name, parameterTypes); + if (!result.isAccessible()) { + result.setAccessible(true); + } + } catch (NoSuchMethodException e) { + result = getMethod(type.getSuperclass(), name, parameterTypes); + } + declaredCache.put(method, result); + } + return result; + } + + private Method getRRMethod(final Class type, final String name) { + final FastField method = new FastField(type, name); + Method result = (Method)resRepCache.get(method); + if (result == null) { + result = getMethod(type, name, EMPTY_CLASSES, true); + if (result != null && result.getDeclaringClass() != type) { + if ((result.getModifiers() & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0) { + if ((result.getModifiers() & Modifier.PRIVATE) > 0 + || type.getPackage() != result.getDeclaringClass().getPackage()) { + result = NO_METHOD; + } + } + } else if (result == null) { + result = NO_METHOD; + } + resRepCache.put(method, result); + } + return result == NO_METHOD ? null : result; + } + + public Map getSerializablePersistentFields(final Class type) { + if (type == null) { + return null; + } + Map result = (Map)fieldCache.get(type.getName()); + if (result == null) { + try { + final Field field = type.getDeclaredField("serialPersistentFields"); + if ((field.getModifiers() & PERSISTENT_FIELDS_MODIFIER) == PERSISTENT_FIELDS_MODIFIER) { + field.setAccessible(true); + final ObjectStreamField[] fields = (ObjectStreamField[])field.get(null); + if (fields != null) { + result = new HashMap(); + for (int i = 0; i < fields.length; ++i) { + result.put(fields[i].getName(), fields[i]); + } + } + } + } catch (final NoSuchFieldException e) { + } catch (final IllegalAccessException e) { + throw new ObjectAccessException("Cannot get " + type.getName() + ".serialPersistentFields.", e); + } catch (final ClassCastException e) { + throw new ObjectAccessException("Cannot get " + type.getName() + ".serialPersistentFields.", e); + } + if (result == null) { + result = NO_FIELDS; + } + fieldCache.put(type.getName(), result); + } + return result == NO_FIELDS ? null : result; + } + + public void flushCache() { + declaredCache.keySet().retainAll(Arrays.asList(OBJECT_TYPE_FIELDS)); + resRepCache.keySet().retainAll(Arrays.asList(OBJECT_TYPE_FIELDS)); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/ThreadSafePropertyEditor.java b/xstream/src/java/com/thoughtworks/xstream/core/util/ThreadSafePropertyEditor.java new file mode 100644 index 0000000..34c9953 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/ThreadSafePropertyEditor.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 20. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; + +import java.beans.PropertyEditor; + + +/** + * Wrapper around {@link PropertyEditor} that can be called by multiple threads concurrently. + *

+ * A PropertyEditor is not thread safe. To make best use of resources, the PropertyEditor + * provides a dynamically sizing pool of instances, each of which will only be called by a + * single thread at a time. + *

+ *

+ * The pool has a maximum capacity, to limit overhead. If all instances in the pool are in use + * and another is required, it shall block until one becomes available. + *

+ * + * @author Jörg Schaible + * @since 1.3 + */ +public class ThreadSafePropertyEditor { + + private final Class editorType; + private final Pool pool; + + public ThreadSafePropertyEditor(Class type, int initialPoolSize, int maxPoolSize) { + if (!PropertyEditor.class.isAssignableFrom(type)) { + throw new IllegalArgumentException(type.getName() + + " is not a " + + PropertyEditor.class.getName()); + } + editorType = type; + pool = new Pool(initialPoolSize, maxPoolSize, new Pool.Factory() { + public Object newInstance() { + try { + return editorType.newInstance(); + } catch (InstantiationException e) { + throw new ObjectAccessException("Could not call default constructor of " + + editorType.getName(), e); + } catch (IllegalAccessException e) { + throw new ObjectAccessException("Could not call default constructor of " + + editorType.getName(), e); + } + } + + }); + } + + public String getAsText(Object object) { + PropertyEditor editor = fetchFromPool(); + try { + editor.setValue(object); + return editor.getAsText(); + } finally { + pool.putInPool(editor); + } + } + + public Object setAsText(String str) { + PropertyEditor editor = fetchFromPool(); + try { + editor.setAsText(str); + return editor.getValue(); + } finally { + pool.putInPool(editor); + } + } + + private PropertyEditor fetchFromPool() { + PropertyEditor editor = (PropertyEditor)pool.fetchFromPool(); + return editor; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/ThreadSafeSimpleDateFormat.java b/xstream/src/java/com/thoughtworks/xstream/core/util/ThreadSafeSimpleDateFormat.java new file mode 100644 index 0000000..dfd15a8 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/ThreadSafeSimpleDateFormat.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011, 2012 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. May 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core.util; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +/** + * Wrapper around java.text.SimpleDateFormat that can + * be called by multiple threads concurrently. + *

SimpleDateFormat has a high overhead in creating + * and is not thread safe. To make best use of resources, + * the ThreadSafeSimpleDateFormat provides a dynamically + * sizing pool of instances, each of which will only + * be called by a single thread at a time.

+ *

The pool has a maximum capacity, to limit overhead. + * If all instances in the pool are in use and another is + * required, it shall block until one becomes available.

+ * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class ThreadSafeSimpleDateFormat { + + private final String formatString; + private final Pool pool; + private final TimeZone timeZone; + + public ThreadSafeSimpleDateFormat( + String format, TimeZone timeZone, int initialPoolSize, int maxPoolSize, + final boolean lenient) { + this(format, timeZone, Locale.ENGLISH, initialPoolSize, maxPoolSize, lenient); + } + + public ThreadSafeSimpleDateFormat( + String format, TimeZone timeZone, final Locale locale, int initialPoolSize, + int maxPoolSize, final boolean lenient) { + formatString = format; + this.timeZone = timeZone; + pool = new Pool(initialPoolSize, maxPoolSize, new Pool.Factory() { + public Object newInstance() { + SimpleDateFormat dateFormat = new SimpleDateFormat(formatString, locale); + dateFormat.setLenient(lenient); + return dateFormat; + } + + }); + } + + public String format(Date date) { + DateFormat format = fetchFromPool(); + try { + return format.format(date); + } finally { + pool.putInPool(format); + } + } + + public Date parse(String date) throws ParseException { + DateFormat format = fetchFromPool(); + try { + return format.parse(date); + } finally { + pool.putInPool(format); + } + } + + private DateFormat fetchFromPool() { + DateFormat format = (DateFormat)pool.fetchFromPool(); + TimeZone tz = timeZone != null ? timeZone : TimeZone.getDefault(); + if (!tz.equals(format.getTimeZone())) { + format.setTimeZone(tz); + } + return format; + } + + public String toString() { + return formatString; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/TypedNull.java b/xstream/src/java/com/thoughtworks/xstream/core/util/TypedNull.java new file mode 100644 index 0000000..a6458f8 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/TypedNull.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. March 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +/** + * A placeholder for a null value of a specific type. + * + * @author Jörg Schaible + * @since 1.2.2 + */ +public class TypedNull +{ + private final Class type; + + public TypedNull(Class type) + { + super(); + this.type = type; + } + + public Class getType() + { + return this.type; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/Types.java b/xstream/src/java/com/thoughtworks/xstream/core/util/Types.java new file mode 100644 index 0000000..5168be7 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/Types.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2015 XStream Committers. + * All rights reserved. + * + * Created on 17. January 2015 by Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +import java.util.regex.Pattern; + + +/** + * Helper methods for class types. + * + * @author Jörg Schaible + * @since 1.4.8 + */ +public class Types { + private static final Pattern lambdaPattern = Pattern.compile(".*\\$\\$Lambda\\$[0-9]+/.*"); + + public static final boolean isLambdaType(final Class type) { + return type != null && type.isSynthetic() && lambdaPattern.matcher(type.getSimpleName()).matches(); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/WeakCache.java b/xstream/src/java/com/thoughtworks/xstream/core/util/WeakCache.java new file mode 100644 index 0000000..c13d29e --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/WeakCache.java @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2011, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 12. July 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.WeakHashMap; + + +/** + * A HashMap implementation with weak references values and by default for the key. When the + * value is garbage collected, the key will also vanish from the map. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class WeakCache extends AbstractMap { + + private final Map map; + + /** + * Construct a WeakCache with weak keys. + * + *

Note, that the internally used WeakHashMap is not thread-safe.

+ * + * @param map the map to use + * @since 1.4 + */ + public WeakCache() { + this(new WeakHashMap()); + } + + /** + * Construct a WeakCache. + * + * @param map the map to use + * @since 1.4 + */ + public WeakCache(Map map) { + this.map = map; + } + + public Object get(Object key) { + Reference reference = (Reference)map.get(key); + return reference != null ? reference.get() : null; + } + + public Object put(Object key, Object value) { + Reference ref = (Reference)map.put(key, createReference(value)); + return ref == null ? null : ref.get(); + } + + public Object remove(Object key) { + Reference ref = (Reference)map.remove(key); + return ref == null ? null : ref.get(); + } + + protected Reference createReference(Object value) { + return new WeakReference(value); + } + + public boolean containsValue(final Object value) { + Boolean result = (Boolean)iterate(new Visitor() { + + public Object visit(Object element) { + return element.equals(value) ? Boolean.TRUE : null; + } + + }, 0); + return result == Boolean.TRUE; + } + + public int size() { + if (map.size() == 0) { + return 0; + } + final int i[] = new int[1]; + i[0] = 0; + iterate(new Visitor() { + + public Object visit(Object element) { + ++i[0]; + return null; + } + + }, 0); + return i[0]; + } + + public Collection values() { + final Collection collection = new ArrayList(); + if (map.size() != 0) { + iterate(new Visitor() { + + public Object visit(Object element) { + collection.add(element); + return null; + } + + }, 0); + } + return collection; + } + + public Set entrySet() { + final Set set = new HashSet(); + if (map.size() != 0) { + iterate(new Visitor() { + + public Object visit(Object element) { + final Map.Entry entry = (Map.Entry)element; + set.add(new Map.Entry() { + + public Object getKey() { + return entry.getKey(); + } + + public Object getValue() { + return ((Reference)entry.getValue()).get(); + } + + public Object setValue(Object value) { + Reference reference = (Reference)entry.setValue(createReference(value)); + return reference != null ? reference.get() : null; + } + + }); + return null; + } + + }, 2); + } + return set; + } + + private Object iterate(Visitor visitor, int type) { + Object result = null; + for (Iterator iter = map.entrySet().iterator(); result == null && iter.hasNext();) { + Map.Entry entry = (Map.Entry)iter.next(); + Reference reference = (Reference)entry.getValue(); + Object element = reference.get(); + if (element == null) { + iter.remove(); + continue; + } + switch (type) { + case 0: + result = visitor.visit(element); + break; + case 1: + result = visitor.visit(entry.getKey()); + break; + case 2: + result = visitor.visit(entry); + break; + } + + } + return result; + } + + private interface Visitor { + Object visit(Object element); + } + + public boolean containsKey(Object key) { + return map.containsKey(key); + } + + public void clear() { + map.clear(); + } + + public Set keySet() { + return map.keySet(); + } + + public boolean equals(Object o) { + return map.equals(o); + } + + public int hashCode() { + return map.hashCode(); + } + + public String toString() { + return map.toString(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/core/util/XmlHeaderAwareReader.java b/xstream/src/java/com/thoughtworks/xstream/core/util/XmlHeaderAwareReader.java new file mode 100644 index 0000000..b0364fc --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/core/util/XmlHeaderAwareReader.java @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2007, 2008, 2010 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. September 2007 by Joerg Schaible. + */ + +package com.thoughtworks.xstream.core.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PushbackInputStream; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.Map; + + +/** + * A {@link Reader} that evaluates the XML header. It selects its encoding based on the encoding read with the XML + * header of the provided {@link InputStream}. The default encoding is UTF-8 and the version is 1.0 if the + * stream does not contain an XML header or the attributes are not set within the header. + * + * @author Jörg Schaible + * @since 1.3 + */ +public final class XmlHeaderAwareReader extends Reader { + + private final InputStreamReader reader; + private final double version; + + private static final String KEY_ENCODING = "encoding"; + private static final String KEY_VERSION = "version"; + + private static final String XML_TOKEN = "?xml"; + + private static final int STATE_BOM = 0; + private static final int STATE_START = 1; + private static final int STATE_AWAIT_XML_HEADER = 2; + private static final int STATE_ATTR_NAME = 3; + private static final int STATE_ATTR_VALUE = 4; + + /** + * Constructs an XmlHeaderAwareReader. + * + * @param in the {@link InputStream} + * @throws UnsupportedEncodingException if the encoding is not supported + * @throws IOException occurred while reading the XML header + * @since 1.3 + */ + public XmlHeaderAwareReader(final InputStream in) throws UnsupportedEncodingException, IOException { + final PushbackInputStream[] pin = new PushbackInputStream[]{in instanceof PushbackInputStream + ? (PushbackInputStream)in + : new PushbackInputStream(in, 64)}; + final Map header = getHeader(pin); + version = Double.parseDouble((String)header.get(KEY_VERSION)); + reader = new InputStreamReader(pin[0], (String)header.get(KEY_ENCODING)); + } + + private Map getHeader(final PushbackInputStream[] in) throws IOException { + final Map header = new HashMap(); + header.put(KEY_ENCODING, "utf-8"); + header.put(KEY_VERSION, "1.0"); + + int state = STATE_BOM; + final ByteArrayOutputStream out = new ByteArrayOutputStream(64); + int i = 0; + char ch = 0; + char valueEnd = 0; + final StringBuffer name = new StringBuffer(); + final StringBuffer value = new StringBuffer(); + boolean escape = false; + while (i != -1 && (i = in[0].read()) != -1) { + out.write(i); + ch = (char)i; + switch (state) { + case STATE_BOM: + if ((ch == 0xEF && out.size() == 1) + || (ch == 0xBB && out.size() == 2) + || (ch == 0xBF && out.size() == 3)) { + if (ch == 0xBF) { + out.reset(); + state = STATE_START; + } + break; + } else if (out.size() > 1) { + i = -1; + break; + } else { + state = STATE_START; + } + // fall through + case STATE_START: + if (!Character.isWhitespace(ch)) { + if (ch == '<') { + state = STATE_AWAIT_XML_HEADER; + } else { + i = -1; + } + } + break; + case STATE_AWAIT_XML_HEADER: + if (!Character.isWhitespace(ch)) { + name.append(Character.toLowerCase(ch)); + if (!XML_TOKEN.startsWith(name.substring(0))) { + i = -1; + } + } else { + if (name.toString().equals(XML_TOKEN)) { + state = STATE_ATTR_NAME; + name.setLength(0); + } else { + i = -1; + } + } + break; + case STATE_ATTR_NAME: + if (!Character.isWhitespace(ch)) { + if (ch == '=') { + state = STATE_ATTR_VALUE; + } else { + ch = Character.toLowerCase(ch); + if (Character.isLetter(ch)) { + name.append(ch); + } else { + i = -1; + } + } + } else if (name.length() > 0) { + i = -1; + } + break; + case STATE_ATTR_VALUE: + if (valueEnd == 0) { + if (ch == '"' || ch == '\'') { + valueEnd = ch; + } else { + i = -1; + } + } else { + if (ch == '\\' && !escape) { + escape = true; + break; + } + if (ch == valueEnd && !escape) { + valueEnd = 0; + state = STATE_ATTR_NAME; + header.put(name.toString(), value.toString()); + name.setLength(0); + value.setLength(0); + } else { + escape = false; + if (ch != '\n') { + value.append(ch); + } else { + i = -1; + } + } + } + break; + } + } + + byte[] pushbackData = out.toByteArray(); + for (i = pushbackData.length; i-- > 0;) { + final byte b = pushbackData[i]; + try { + in[0].unread(b); + } catch (IOException ex) { + in[0] = new PushbackInputStream(in[0], ++i); + } + } + return header; + } + + /** + * @see InputStreamReader#getEncoding() + * @since 1.3 + */ + public String getEncoding() { + return reader.getEncoding(); + } + + /** + * @see InputStreamReader#getEncoding() + * @since 1.3 + */ + public double getVersion() { + return version; + } + + /** + * @see java.io.Reader#mark(int) + */ + public void mark(final int readAheadLimit) throws IOException { + reader.mark(readAheadLimit); + } + + /** + * @see java.io.Reader#markSupported() + */ + public boolean markSupported() { + return reader.markSupported(); + } + + /** + * @see java.io.Reader#read() + */ + public int read() throws IOException { + return reader.read(); + } + + /** + * @see java.io.Reader#read(char[], int, int) + */ + public int read(final char[] cbuf, final int offset, final int length) throws IOException { + return reader.read(cbuf, offset, length); + } + + /** + * @see java.io.Reader#read(char[]) + */ + public int read(final char[] cbuf) throws IOException { + return reader.read(cbuf); + } + +// TODO: This is JDK 1.5 +// public int read(final CharBuffer target) throws IOException { +// return reader.read(target); +// } + + /** + * @see java.io.Reader#ready() + */ + public boolean ready() throws IOException { + return reader.ready(); + } + + /** + * @see java.io.Reader#reset() + */ + public void reset() throws IOException { + reader.reset(); + } + + /** + * @see java.io.Reader#skip(long) + */ + public long skip(final long n) throws IOException { + return reader.skip(n); + } + + /** + * @see java.io.Reader#close() + */ + public void close() throws IOException { + reader.close(); + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(final Object obj) { + return reader.equals(obj); + } + + /** + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return reader.hashCode(); + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + return reader.toString(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/AbstractDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/AbstractDriver.java new file mode 100644 index 0000000..85d29ac --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/AbstractDriver.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. August 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import com.thoughtworks.xstream.io.naming.NameCoder; +import com.thoughtworks.xstream.io.naming.NoNameCoder; + + +/** + * Abstract base class for all HierarchicalStreamDriver implementations. Implementations of + * {@link HierarchicalStreamDriver} should rather be derived from this class then implementing + * the interface directly. + * + * @author Jörg Schaible + * @since 1.4 + */ +public abstract class AbstractDriver implements HierarchicalStreamDriver { + + private NameCoder replacer; + + /** + * Creates an AbstractDriver with a NameCoder that does nothing. + */ + public AbstractDriver() { + this(new NoNameCoder()); + } + + /** + * Creates an AbstractDriver with a provided {@link NameCoder}. + * + * @param nameCoder the name coder for the target format + */ + public AbstractDriver(NameCoder nameCoder) { + this.replacer = nameCoder; + } + + protected NameCoder getNameCoder() { + return replacer; + } + + /** + * {@inheritDoc} + */ + public HierarchicalStreamReader createReader(URL in) { + InputStream stream = null; + try { + stream = in.openStream(); + } catch (IOException e) { + throw new StreamException(e); + } + return createReader(stream); + } + + /** + * {@inheritDoc} + */ + public HierarchicalStreamReader createReader(File in) { + try { + return createReader(new FileInputStream(in)); + } catch (FileNotFoundException e) { + throw new StreamException(e); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/AbstractReader.java b/xstream/src/java/com/thoughtworks/xstream/io/AbstractReader.java new file mode 100644 index 0000000..ad5e041 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/AbstractReader.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 16. August 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io; + +import com.thoughtworks.xstream.core.util.Cloneables; +import com.thoughtworks.xstream.io.naming.NameCoder; +import com.thoughtworks.xstream.io.naming.NoNameCoder; + + +/** + * Abstract base class for all HierarchicalStreamReader implementations. Implementations of + * {@link HierarchicalStreamReader} should rather be derived from this class then implementing + * the interface directly. + * + * @author Jörg Schaible + * @since 1.4 + */ +public abstract class AbstractReader implements ExtendedHierarchicalStreamReader { + + private NameCoder nameCoder; + + /** + * Creates an AbstractReader with a NameCoder that does nothing. + * + * @since 1.4 + */ + protected AbstractReader() { + this(new NoNameCoder()); + } + + /** + * Creates an AbstractReader with a provided {@link NameCoder}. + * + * @param nameCoder the name coder used to read names from the incoming format + * @since 1.4 + */ + protected AbstractReader(NameCoder nameCoder) { + this.nameCoder = (NameCoder)Cloneables.cloneIfPossible(nameCoder); + } + + /** + * {@inheritDoc} + */ + public HierarchicalStreamReader underlyingReader() { + return this; + } + + /** + * Decode a node name from the target format. + * + * @param name the name in the target format + * @return the original name + * @since 1.4 + */ + public String decodeNode(String name) { + return nameCoder.decodeNode(name); + } + + /** + * Decode an attribute name from the target format. + * + * @param name the name in the target format + * @return the original name + * @since 1.4 + */ + public String decodeAttribute(String name) { + return nameCoder.decodeAttribute(name); + } + + /** + * Encode the node name again into the name of the target format. Internally used. + * + * @param name the original name + * @return the name in the target format + * @since 1.4 + */ + protected String encodeNode(String name) { + return nameCoder.encodeNode(name); + } + + /** + * Encode the attribute name again into the name of the target format. Internally used. + * + * @param name the original name + * @return the name in the target format + * @since 1.4 + */ + protected String encodeAttribute(String name) { + return nameCoder.encodeAttribute(name); + } + + public String peekNextChild() { + throw new UnsupportedOperationException("peekNextChild"); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/AbstractWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/AbstractWriter.java new file mode 100644 index 0000000..165cfa0 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/AbstractWriter.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 17. August 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io; + +import com.thoughtworks.xstream.core.util.Cloneables; +import com.thoughtworks.xstream.io.naming.NameCoder; +import com.thoughtworks.xstream.io.naming.NoNameCoder; + + +/** + * Abstract base class for all HierarchicalStreamWriter implementations. Implementations of + * {@link HierarchicalStreamWriter} should rather be derived from this class then implementing + * the interface directly. + * + * @author Jörg Schaible + * @since 1.4 + */ +public abstract class AbstractWriter implements ExtendedHierarchicalStreamWriter { + + private NameCoder nameCoder; + + /** + * Creates an AbstractWriter with a NameCoder that does nothing. + * + * @since 1.4 + */ + protected AbstractWriter() { + this(new NoNameCoder()); + } + + /** + * Creates an AbstractWriter with a provided {@link NameCoder}. + * + * @param nameCoder the name coder used to write names in the target format + * @since 1.4 + */ + protected AbstractWriter(NameCoder nameCoder) { + this.nameCoder = (NameCoder)Cloneables.cloneIfPossible(nameCoder); + } + + /** + * {@inheritDoc} + */ + public void startNode(String name, Class clazz) { + startNode(name); + } + + /** + * {@inheritDoc} + */ + public HierarchicalStreamWriter underlyingWriter() { + return this; + } + + /** + * Encode the node name into the name of the target format. + * + * @param name the original name + * @return the name in the target format + * @since 1.4 + */ + public String encodeNode(String name) { + return nameCoder.encodeNode(name); + } + + /** + * Encode the attribute name into the name of the target format. + * + * @param name the original name + * @return the name in the target format + * @since 1.4 + */ + public String encodeAttribute(String name) { + return nameCoder.encodeAttribute(name); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/AttributeNameIterator.java b/xstream/src/java/com/thoughtworks/xstream/io/AttributeNameIterator.java new file mode 100644 index 0000000..e71e3fb --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/AttributeNameIterator.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.io; + +import java.util.Iterator; + +/** + * Provide an iterator over the attribute names of the current node of a reader. + * + * @author Joe Walnes + * @deprecated As of 1.4.8, it is an internal helper class only + */ +public class AttributeNameIterator implements Iterator { + + private int current; + private final int count; + private final HierarchicalStreamReader reader; + + public AttributeNameIterator(HierarchicalStreamReader reader) { + this.reader = reader; + count = reader.getAttributeCount(); + } + + public boolean hasNext() { + return current < count; + } + + public Object next() { + return reader.getAttributeName(current++); + } + + public void remove() { + throw new UnsupportedOperationException(); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamReader.java b/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamReader.java new file mode 100644 index 0000000..27059fb --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamReader.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. October 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.io; + +/** + * @author Jörg Schaible + * @since 1.4.2 + */ +public interface ExtendedHierarchicalStreamReader extends HierarchicalStreamReader { + + /** + * Peek the name of the next child. In situation where {@link #hasMoreChildren()} returns + * true, peek the tag name of the child. + * + * @since 1.4.2 + */ + String peekNextChild(); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamWriter.java new file mode 100644 index 0000000..1091da1 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamWriter.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. June 2006 by Mauro Talevi + */ +package com.thoughtworks.xstream.io; + +/** + * @author Paul Hammant + */ +public interface ExtendedHierarchicalStreamWriter extends HierarchicalStreamWriter { + + void startNode(String name, Class clazz); + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamWriterHelper.java b/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamWriterHelper.java new file mode 100644 index 0000000..ac06624 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamWriterHelper.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. June 2006 by Mauro Talevi + */ +package com.thoughtworks.xstream.io; + +public class ExtendedHierarchicalStreamWriterHelper { + public static void startNode(HierarchicalStreamWriter writer, String name, Class clazz) { + if (writer instanceof ExtendedHierarchicalStreamWriter) { + ((ExtendedHierarchicalStreamWriter) writer).startNode(name, clazz); + } else { + writer.startNode(name); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/HierarchicalStreamDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/HierarchicalStreamDriver.java new file mode 100644 index 0000000..bc5c686 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/HierarchicalStreamDriver.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io; + +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.net.URL; + +/** + * Provides implementation of stream parsers and writers to XStream. + * + * @author Joe Walnes + * @author James Strachan + */ +public interface HierarchicalStreamDriver { + + /** + * Create the HierarchicalStreamReader with the stream parser reading from the IO reader. + * + * @param in the {@link Reader} with the data to parse + * @return the HierarchicalStreamReader + */ + HierarchicalStreamReader createReader(Reader in); + + /** + * Create the HierarchicalStreamReader with the stream parser reading from the input stream. + * + * @param in the {@link InputStream} with the data to parse + * @since 1.1.3 + */ + HierarchicalStreamReader createReader(InputStream in); + + /** + * Create the HierarchicalStreamReader with the stream parser reading from a URL. + * + * Depending on the parser implementation, some might take the URL as SystemId to resolve + * additional references. + * + * @param in the {@link URL} defining the location with the data to parse + * @return the HierarchicalStreamReader + * @since 1.4 + */ + HierarchicalStreamReader createReader(URL in); + + /** + * Create the HierarchicalStreamReader with the stream parser reading from a File. + * + * Depending on the parser implementation, some might take the file path as SystemId to + * resolve additional references. + * + * @param in the {@link URL} defining the location with the data to parse + * @return the HierarchicalStreamReader + * @since 1.4 + */ + HierarchicalStreamReader createReader(File in); + + /** + * Create the HierarchicalStreamWriter with the formatted writer. + * + * @param out the {@link Writer} to receive the formatted data + * @return the HierarchicalStreamWriter + */ + HierarchicalStreamWriter createWriter(Writer out); + /** + * Create the HierarchicalStreamWriter with the formatted writer. + * + * @param out the {@link OutputStream} to receive the formatted data + * @return the HierarchicalStreamWriter + * @since 1.1.3 + */ + HierarchicalStreamWriter createWriter(OutputStream out); + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/HierarchicalStreamReader.java b/xstream/src/java/com/thoughtworks/xstream/io/HierarchicalStreamReader.java new file mode 100644 index 0000000..8ee85c7 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/HierarchicalStreamReader.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io; + +import com.thoughtworks.xstream.converters.ErrorReporter; +import com.thoughtworks.xstream.converters.ErrorWriter; + +import java.util.Iterator; + +/** + * @author Joe Walnes + */ +public interface HierarchicalStreamReader extends ErrorReporter { + + /** + * Does the node have any more children remaining that have not yet been read? + */ + boolean hasMoreChildren(); + + /** + * Select the current child as current node. + * A call to this function must be balanced with a call to {@link #moveUp()}. + */ + void moveDown(); + + /** + * Select the parent node as current node. + */ + void moveUp(); + + /** + * Get the name of the current node. + */ + String getNodeName(); + + /** + * Get the value (text content) of the current node. + */ + String getValue(); + + /** + * Get the value of an attribute of the current node. + */ + String getAttribute(String name); + + /** + * Get the value of an attribute of the current node, by index. + */ + String getAttribute(int index); + + /** + * Number of attributes in current node. + */ + int getAttributeCount(); + + /** + * Name of attribute in current node. + */ + String getAttributeName(int index); + + /** + * Names of attributes (as Strings). + */ + Iterator getAttributeNames(); + + /** + * If any errors are detected, allow the reader to add any additional information that can aid debugging + * (such as line numbers, XPath expressions, etc). + */ + void appendErrors(ErrorWriter errorWriter); + + /** + * Close the reader, if necessary. + */ + void close(); + + /** + * Return the underlying HierarchicalStreamReader implementation. + * + *

If a Converter needs to access methods of a specific HierarchicalStreamReader implementation that are not + * defined in the HierarchicalStreamReader interface, it should call this method before casting. This is because + * the reader passed to the Converter is often wrapped/decorated by another implementation to provide additional + * functionality (such as XPath tracking).

+ * + *

For example:

+ *
MySpecificReader mySpecificReader = (MySpecificReader)reader; // INCORRECT!
+     * mySpecificReader.doSomethingSpecific();
+ + *
MySpecificReader mySpecificReader = (MySpecificReader)reader.underlyingReader();  // CORRECT!
+     * mySpecificReader.doSomethingSpecific();
+ * + *

Implementations of HierarchicalStreamReader should return 'this', unless they are a decorator, in which case + * they should delegate to whatever they are wrapping.

+ */ + HierarchicalStreamReader underlyingReader(); + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/HierarchicalStreamWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/HierarchicalStreamWriter.java new file mode 100644 index 0000000..4449928 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/HierarchicalStreamWriter.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io; + +/** + * @author Joe Walnes + */ +public interface HierarchicalStreamWriter { + + void startNode(String name); + + void addAttribute(String name, String value); + + /** + * Write the value (text content) of the current node. + */ + void setValue(String text); + + void endNode(); + + /** + * Flush the writer, if necessary. + */ + void flush(); + + /** + * Close the writer, if necessary. + */ + void close(); + + /** + * Return the underlying HierarchicalStreamWriter implementation. + * + *

If a Converter needs to access methods of a specific HierarchicalStreamWriter implementation that are not + * defined in the HierarchicalStreamWriter interface, it should call this method before casting. This is because + * the writer passed to the Converter is often wrapped/decorated by another implementation to provide additional + * functionality (such as XPath tracking).

+ * + *

For example:

+ *
MySpecificWriter mySpecificWriter = (MySpecificWriter)writer; // INCORRECT!
+     * mySpecificWriter.doSomethingSpecific();
+ + *
MySpecificWriter mySpecificWriter = (MySpecificWriter)writer.underlyingWriter();  // CORRECT!
+     * mySpecificWriter.doSomethingSpecific();
+ * + *

Implementations of HierarchicalStreamWriter should return 'this', unless they are a decorator, in which case + * they should delegate to whatever they are wrapping.

+ */ + HierarchicalStreamWriter underlyingWriter(); + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/ReaderWrapper.java b/xstream/src/java/com/thoughtworks/xstream/io/ReaderWrapper.java new file mode 100644 index 0000000..38cbbf6 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/ReaderWrapper.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 10. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.io; + +import com.thoughtworks.xstream.converters.ErrorWriter; + +import java.util.Iterator; + +/** + * Base class to make it easy to create wrappers (decorators) for HierarchicalStreamReader. + * + * @author Joe Walnes + */ +public abstract class ReaderWrapper implements ExtendedHierarchicalStreamReader { + + protected HierarchicalStreamReader wrapped; + + protected ReaderWrapper(HierarchicalStreamReader reader) { + this.wrapped = reader; + } + + public boolean hasMoreChildren() { + return wrapped.hasMoreChildren(); + } + + public void moveDown() { + wrapped.moveDown(); + } + + public void moveUp() { + wrapped.moveUp(); + } + + public String getNodeName() { + return wrapped.getNodeName(); + } + + public String getValue() { + return wrapped.getValue(); + } + + public String getAttribute(String name) { + return wrapped.getAttribute(name); + } + + public String getAttribute(int index) { + return wrapped.getAttribute(index); + } + + public int getAttributeCount() { + return wrapped.getAttributeCount(); + } + + public String getAttributeName(int index) { + return wrapped.getAttributeName(index); + } + + public Iterator getAttributeNames() { + return wrapped.getAttributeNames(); + } + + public void appendErrors(ErrorWriter errorWriter) { + wrapped.appendErrors(errorWriter); + } + + public void close() { + wrapped.close(); + } + + public String peekNextChild() { + if (! (wrapped instanceof ExtendedHierarchicalStreamReader)) { + throw new UnsupportedOperationException("peekNextChild"); + } + return ((ExtendedHierarchicalStreamReader)wrapped).peekNextChild(); + } + + public HierarchicalStreamReader underlyingReader() { + return wrapped.underlyingReader(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/StatefulWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/StatefulWriter.java new file mode 100644 index 0000000..23e0cab --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/StatefulWriter.java @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. March 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.io; + +import com.thoughtworks.xstream.core.util.FastStack; + +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; + + +/** + * An wrapper for all {@link HierarchicalStreamWriter} implementations, that keeps the state. + * Writing in a wrong state will throw a {@link StreamException}, that wraps either an + * {@link IOException} (writing to a closed writer) or an {@link IllegalStateException}. The + * implementation will also track unbalanced nodes or multiple attributes with the same name. + * + * @author Jörg Schaible + * @since 1.2 + */ +public class StatefulWriter extends WriterWrapper { + + /** + * STATE_OPEN is the initial value of the writer. + * + * @since 1.2 + */ + public static int STATE_OPEN = 0; + /** + * STATE_NODE_START is the state of a new node has been started. + * + * @since 1.2 + */ + public static int STATE_NODE_START = 1; + /** + * STATE_VALUE is the state if the value of a node has been written. + * + * @since 1.2 + */ + public static int STATE_VALUE = 2; + /** + * STATE_NODE_END is the state if a node has ended + * + * @since 1.2 + */ + public static int STATE_NODE_END = 3; + /** + * STATE_CLOSED is the state if the writer has been closed. + * + * @since 1.2 + */ + public static int STATE_CLOSED = 4; + + private transient int state = STATE_OPEN; + private transient int balance; + private transient FastStack attributes; + + /** + * Constructs a StatefulWriter. + * + * @param wrapped the wrapped writer + * @since 1.2 + */ + public StatefulWriter(final HierarchicalStreamWriter wrapped) { + super(wrapped); + attributes = new FastStack(16); + } + + public void startNode(final String name) { + startNodeCommon(); + super.startNode(name); + } + + public void startNode(final String name, final Class clazz) { + startNodeCommon(); + super.startNode(name, clazz); + } + + private void startNodeCommon() { + checkClosed(); + if (state == STATE_VALUE) { + // legal XML, but not in XStream ... ? + throw new StreamException(new IllegalStateException("Opening node after writing text")); + } + state = STATE_NODE_START; + ++balance; + attributes.push(new HashSet()); + } + + public void addAttribute(String name, String value) { + checkClosed(); + if (state != STATE_NODE_START) { + throw new StreamException(new IllegalStateException("Writing attribute '" + + name + + "' without an opened node")); + } + Set currentAttributes = (Set)attributes.peek(); + if (currentAttributes.contains(name)) { + throw new StreamException(new IllegalStateException("Writing attribute '" + + name + + "' twice")); + } + currentAttributes.add(name); + super.addAttribute(name, value); + } + + public void setValue(String text) { + checkClosed(); + if (state != STATE_NODE_START) { + // STATE_NODE_END is legal XML, but not in XStream ... ? + throw new StreamException(new IllegalStateException( + "Writing text without an opened node")); + } + state = STATE_VALUE; + super.setValue(text); + } + + public void endNode() { + checkClosed(); + if (balance-- == 0) { + throw new StreamException(new IllegalStateException("Unbalanced node")); + } + attributes.popSilently(); + state = STATE_NODE_END; + super.endNode(); + } + + public void flush() { + checkClosed(); + super.flush(); + } + + public void close() { + if (state != STATE_NODE_END && state != STATE_OPEN) { + // calling close in a finally block should not throw again + // throw new StreamException(new IllegalStateException("Closing with unbalanced tag")); + } + state = STATE_CLOSED; + super.close(); + } + + private void checkClosed() { + if (state == STATE_CLOSED) { + throw new StreamException(new IOException("Writing on a closed stream")); + } + } + + /** + * Retrieve the state of the writer. + * + * @return one of the states + * @see #STATE_OPEN + * @see #STATE_NODE_START + * @see #STATE_VALUE + * @see #STATE_NODE_END + * @see #STATE_CLOSED + * @since 1.2 + */ + public int state() { + return state; + } + + private Object readResolve() { + attributes = new FastStack(16); + return this; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/StreamException.java b/xstream/src/java/com/thoughtworks/xstream/io/StreamException.java new file mode 100644 index 0000000..4be7844 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/StreamException.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2004, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io; + +import com.thoughtworks.xstream.XStreamException; + +public class StreamException extends XStreamException { + public StreamException(Throwable e) { + super(e); + } + + public StreamException(String message) { + super(message); + } + + /** + * @since 1.4 + */ + public StreamException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/WriterWrapper.java b/xstream/src/java/com/thoughtworks/xstream/io/WriterWrapper.java new file mode 100644 index 0000000..54d0007 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/WriterWrapper.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 10. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.io; + +/** + * Base class to make it easy to create wrappers (decorators) for HierarchicalStreamWriter. + * + * @author Joe Walnes + */ +public abstract class WriterWrapper implements ExtendedHierarchicalStreamWriter { + + protected HierarchicalStreamWriter wrapped; + + protected WriterWrapper(HierarchicalStreamWriter wrapped) { + this.wrapped = wrapped; + } + + public void startNode(String name) { + wrapped.startNode(name); + } + + public void startNode(String name, Class clazz) { + + ((ExtendedHierarchicalStreamWriter) wrapped).startNode(name, clazz); + } + + public void endNode() { + wrapped.endNode(); + } + + public void addAttribute(String key, String value) { + wrapped.addAttribute(key, value); + } + + public void setValue(String text) { + wrapped.setValue(text); + } + + public void flush() { + wrapped.flush(); + } + + public void close() { + wrapped.close(); + } + + public HierarchicalStreamWriter underlyingWriter() { + return wrapped.underlyingWriter(); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/binary/BinaryStreamDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/binary/BinaryStreamDriver.java new file mode 100644 index 0000000..ca7e6fb --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/binary/BinaryStreamDriver.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 14. October 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.binary; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; + +import com.thoughtworks.xstream.io.AbstractDriver; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + + +/** + * HierarchicalStreamDriver for binary input and output. The driver uses an optimized binary + * format to store an object graph. The format is not as compact as Java serialization, but a + * lot more than typical text-based formats like XML. However, due to its nature it cannot use a + * {@link Reader} for input or a {@link Writer} for output. + * + * @author Jörg Schaible + * @since 1.4.2 + */ +public class BinaryStreamDriver extends AbstractDriver { + + /** + * @throws UnsupportedOperationException if called + */ + public HierarchicalStreamReader createReader(Reader in) { + throw new UnsupportedOperationException( + "The BinaryDriver cannot use character-oriented input streams."); + } + + public HierarchicalStreamReader createReader(InputStream in) { + return new BinaryStreamReader(in); + } + + /** + * @throws UnsupportedOperationException if called + */ + public HierarchicalStreamWriter createWriter(Writer out) { + throw new UnsupportedOperationException( + "The BinaryDriver cannot use character-oriented output streams."); + } + + public HierarchicalStreamWriter createWriter(OutputStream out) { + return new BinaryStreamWriter(out); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/binary/BinaryStreamReader.java b/xstream/src/java/com/thoughtworks/xstream/io/binary/BinaryStreamReader.java new file mode 100644 index 0000000..2839651 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/binary/BinaryStreamReader.java @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. June 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.io.binary; + +import com.thoughtworks.xstream.converters.ErrorWriter; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.StreamException; + +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * A HierarchicalStreamReader that reads from a binary stream created by + * {@link BinaryStreamWriter}. + * + * @author Joe Walnes + * @see BinaryStreamReader + * @since 1.2 + */ +public class BinaryStreamReader implements ExtendedHierarchicalStreamReader { + + private final DataInputStream in; + private final ReaderDepthState depthState = new ReaderDepthState(); + private final IdRegistry idRegistry = new IdRegistry(); + + private Token pushback; + private final Token.Formatter tokenFormatter = new Token.Formatter(); + + public BinaryStreamReader(InputStream inputStream) { + in = new DataInputStream(inputStream); + moveDown(); + } + + public boolean hasMoreChildren() { + return depthState.hasMoreChildren(); + } + + public String getNodeName() { + return depthState.getName(); + } + + public String getValue() { + return depthState.getValue(); + } + + public String getAttribute(String name) { + return depthState.getAttribute(name); + } + + public String getAttribute(int index) { + return depthState.getAttribute(index); + } + + public int getAttributeCount() { + return depthState.getAttributeCount(); + } + + public String getAttributeName(int index) { + return depthState.getAttributeName(index); + } + + public Iterator getAttributeNames() { + return depthState.getAttributeNames(); + } + + public void moveDown() { + depthState.push(); + Token firstToken = readToken(); + switch (firstToken.getType()) { + case Token.TYPE_START_NODE: + depthState.setName(idRegistry.get(firstToken.getId())); + break; + default: + throw new StreamException("Expected StartNode"); + } + while (true) { + Token nextToken = readToken(); + switch (nextToken.getType()) { + case Token.TYPE_ATTRIBUTE: + depthState.addAttribute(idRegistry.get(nextToken.getId()), nextToken.getValue()); + break; + case Token.TYPE_VALUE: + depthState.setValue(nextToken.getValue()); + break; + case Token.TYPE_END_NODE: + depthState.setHasMoreChildren(false); + pushBack(nextToken); + return; + case Token.TYPE_START_NODE: + depthState.setHasMoreChildren(true); + pushBack(nextToken); + return; + default: + throw new StreamException("Unexpected token " + nextToken); + } + } + } + + public void moveUp() { + depthState.pop(); + // We're done with this depth. Skip over all tokens until we get to the end. + int depth = 0; + slurp: + while (true) { + Token nextToken = readToken(); + switch(nextToken.getType()) { + case Token.TYPE_END_NODE: + if (depth == 0) { + break slurp; + } else { + depth--; + } + break; + case Token.TYPE_START_NODE: + depth++; + break; + default: + // Ignore other tokens + } + } + // Peek ahead to determine if there are any more kids at this level. + Token nextToken = readToken(); + switch(nextToken.getType()) { + case Token.TYPE_END_NODE: + depthState.setHasMoreChildren(false); + break; + case Token.TYPE_START_NODE: + depthState.setHasMoreChildren(true); + break; + default: + throw new StreamException("Unexpected token " + nextToken); + } + pushBack(nextToken); + } + + private Token readToken() { + if (pushback == null) { + try { + Token token = tokenFormatter.read(in); + switch (token.getType()) { + case Token.TYPE_MAP_ID_TO_VALUE: + idRegistry.put(token.getId(), token.getValue()); + return readToken(); // Next one please. + default: + return token; + } + } catch (IOException e) { + throw new StreamException(e); + } + } else { + Token result = pushback; + pushback = null; + return result; + } + } + + public void pushBack(Token token) { + if (pushback == null) { + pushback = token; + } else { + // If this happens, I've messed up :( -joe. + throw new Error("Cannot push more than one token back"); + } + } + + public void close() { + try { + in.close(); + } catch (IOException e) { + throw new StreamException(e); + } + } + + public String peekNextChild() { + if (depthState.hasMoreChildren()) { + return idRegistry.get(pushback.getId()); + } + return null; + } + + public HierarchicalStreamReader underlyingReader() { + return this; + } + + public void appendErrors(ErrorWriter errorWriter) { + // TODO: When things go bad, it would be good to know where! + } + + private static class IdRegistry { + + private Map map = new HashMap(); + + public void put(long id, String value) { + map.put(new Long(id), value); + } + + public String get(long id) { + String result = (String) map.get(new Long(id)); + if (result == null) { + throw new StreamException("Unknown ID : " + id); + } else { + return result; + } + } + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/binary/BinaryStreamWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/binary/BinaryStreamWriter.java new file mode 100644 index 0000000..e7f88a0 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/binary/BinaryStreamWriter.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. June 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.io.binary; + +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriter; + +import java.io.DataOutputStream; +import java.io.OutputStream; +import java.io.IOException; +import java.util.Map; +import java.util.HashMap; + +/** + * @since 1.2 + */ +public class BinaryStreamWriter implements ExtendedHierarchicalStreamWriter { + + private final IdRegistry idRegistry = new IdRegistry(); + private final DataOutputStream out; + private final Token.Formatter tokenFormatter = new Token.Formatter(); + + public BinaryStreamWriter(OutputStream outputStream) { + out = new DataOutputStream(outputStream); + } + + public void startNode(String name) { + write(new Token.StartNode(idRegistry.getId(name))); + } + + public void startNode(String name, Class clazz) { + startNode(name); + } + + public void addAttribute(String name, String value) { + write(new Token.Attribute(idRegistry.getId(name), value)); + } + + public void setValue(String text) { + write(new Token.Value(text)); + } + + public void endNode() { + write(new Token.EndNode()); + } + + public void flush() { + try { + out.flush(); + } catch (IOException e) { + throw new StreamException(e); + } + } + + public void close() { + try { + out.close(); + } catch (IOException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamWriter underlyingWriter() { + return this; + } + + private void write(Token token) { + try { + tokenFormatter.write(out, token); + } catch (IOException e) { + throw new StreamException(e); + } + } + + private class IdRegistry { + + private long nextId = 0; + private Map ids = new HashMap(); + + public long getId(String value) { + Long id = (Long) ids.get(value); + if (id == null) { + id = new Long(++nextId); + ids.put(value, id); + write(new Token.MapIdToValue(id.longValue(), value)); + } + return id.longValue(); + } + + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/binary/ReaderDepthState.java b/xstream/src/java/com/thoughtworks/xstream/io/binary/ReaderDepthState.java new file mode 100644 index 0000000..6a27ce8 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/binary/ReaderDepthState.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. June 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.io.binary; + +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Collections; + +/** + * Maintains the state of a pull reader at various states in the document depth. + * + * Used by the {@link BinaryStreamReader} + * + * @author Joe Walnes + * @since 1.2 + */ +class ReaderDepthState { + + private static final String EMPTY_STRING = ""; + + private static class State { + String name; + String value; + List attributes; + boolean hasMoreChildren; + State parent; + } + + private static class Attribute { + String name; + String value; + } + + private State current; + + public void push() { + State newState = new State(); + newState.parent = current; + current = newState; + } + + public void pop() { + current = current.parent; + } + + public String getName() { + return current.name; + } + + public void setName(String name) { + current.name = name; + } + + public String getValue() { + return current.value == null ? EMPTY_STRING : current.value; + } + + public void setValue(String value) { + current.value = value; + } + + public boolean hasMoreChildren() { + return current.hasMoreChildren; + } + + public void setHasMoreChildren(boolean hasMoreChildren) { + current.hasMoreChildren = hasMoreChildren; + } + + public void addAttribute(String name, String value) { + Attribute attribute = new Attribute(); + attribute.name = name; + attribute.value = value; + if (current.attributes == null) { + current.attributes = new ArrayList(); + } + current.attributes.add(attribute); + } + + public String getAttribute(String name) { + if (current.attributes == null) { + return null; + } else { + // For short maps, it's faster to iterate then do a hashlookup. + for (Iterator iterator = current.attributes.iterator(); iterator.hasNext();) { + Attribute attribute = (Attribute) iterator.next(); + if (attribute.name.equals(name)) { + return attribute.value; + } + } + return null; + } + } + + public String getAttribute(int index) { + if (current.attributes == null) { + return null; + } else { + Attribute attribute = (Attribute) current.attributes.get(index); + return attribute.value; + } + } + + public String getAttributeName(int index) { + if (current.attributes == null) { + return null; + } else { + Attribute attribute = (Attribute) current.attributes.get(index); + return attribute.name; + } + } + + public int getAttributeCount() { + return current.attributes == null ? 0 : current.attributes.size(); + } + + public Iterator getAttributeNames() { + if (current.attributes == null) { + return Collections.EMPTY_SET.iterator(); + } else { + final Iterator attributeIterator = current.attributes.iterator(); + return new Iterator() { + public boolean hasNext() { + return attributeIterator.hasNext(); + } + + public Object next() { + Attribute attribute = (Attribute) attributeIterator.next(); + return attribute.name; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/binary/Token.java b/xstream/src/java/com/thoughtworks/xstream/io/binary/Token.java new file mode 100644 index 0000000..0dfef39 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/binary/Token.java @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. June 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.io.binary; + +import com.thoughtworks.xstream.io.StreamException; + +import java.io.DataOutput; +import java.io.IOException; +import java.io.DataInput; + +/** + * Represents the Tokens stored in the binary stream used by + * {@link BinaryStreamReader} and {@link BinaryStreamWriter}. + *

+ * A token consists of a type and (depending on this type) + * it may additionally have an ID (positive long number) + * and/or a value (String).

+ *

+ * The first byte of the token represents how many subsequent + * bytes are used by the ID.

+ * + * @author Joe Walnes + * @see BinaryStreamReader + * @see BinaryStreamWriter + * @since 1.2 + */ +public abstract class Token { + + private static final byte TYPE_MASK = 0x7; + public static final byte TYPE_VERSION = 0x1; + public static final byte TYPE_MAP_ID_TO_VALUE = 0x2; + public static final byte TYPE_START_NODE = 0x3; + public static final byte TYPE_END_NODE = 0x4; + public static final byte TYPE_ATTRIBUTE = 0x5; + public static final byte TYPE_VALUE = 0x6; + + private static final byte ID_MASK = 0x38; + private static final byte ID_ONE_BYTE = 0x08; + private static final byte ID_TWO_BYTES = 0x10; + private static final byte ID_FOUR_BYTES = 0x18; + private static final byte ID_EIGHT_BYTES = 0x20; + + private static final String ID_SPLITTED = "\u0000\u2021\u0000"; + private static final int MAX_UTF8_LENGTH = 0xffff; + + private final byte type; + + protected long id = -1; + protected String value; + + public Token(byte type) { + this.type = type; + } + + public byte getType() { + return type; + } + + public long getId() { + return id; + } + + public String getValue() { + return value; + } + + public String toString() { + return getClass().getName() + " [id=" + id + ", value='" + value + "']"; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final Token token = (Token) o; + + if (id != token.id) return false; + if (type != token.type) return false; + return !(value != null ? !value.equals(token.value) : token.value != null); + } + + public int hashCode() { + int result; + result = type; + result = 29 * result + (int) (id ^ (id >>> 32)); + result = 29 * result + (value != null ? value.hashCode() : 0); + return result; + } + + public abstract void writeTo(DataOutput out, byte idType) throws IOException; + + public abstract void readFrom(DataInput in, byte idType) throws IOException; + + protected void writeId(DataOutput out, long id, byte idType) throws IOException { + if (id < 0) { + throw new IOException("id must not be negative " + id); + } + switch (idType) { + case ID_ONE_BYTE: + out.writeByte((byte) id + Byte.MIN_VALUE); + break; + case ID_TWO_BYTES: + out.writeShort((short) id + Short.MIN_VALUE); + break; + case ID_FOUR_BYTES: + out.writeInt((int) id + Integer.MIN_VALUE); + break; + case ID_EIGHT_BYTES: + out.writeLong(id + Long.MIN_VALUE); + break; + default: + throw new Error("Unknown idType " + idType); + } + } + + protected void writeString(DataOutput out, String string) throws IOException { + final byte[] bytes = (string.length() > MAX_UTF8_LENGTH / 4) ? string.getBytes("utf-8") : new byte[0]; + int length = bytes.length; + if (length <= MAX_UTF8_LENGTH) { + out.writeUTF(string); + } else { + out.writeUTF(ID_SPLITTED); + out.writeInt(bytes.length); + out.write(bytes); + } + } + + protected long readId(DataInput in, byte idType) throws IOException { + switch (idType) { + case ID_ONE_BYTE: + return in.readByte() - Byte.MIN_VALUE; + case ID_TWO_BYTES: + return in.readShort() - Short.MIN_VALUE; + case ID_FOUR_BYTES: + return in.readInt() - Integer.MIN_VALUE; + case ID_EIGHT_BYTES: + return in.readLong() - Long.MIN_VALUE; + default: + throw new Error("Unknown idType " + idType); + } + } + + protected String readString(DataInput in) throws IOException { + final String string = in.readUTF(); + if (!ID_SPLITTED.equals(string)) { + return string; + } + final int size = in.readInt(); + final byte[] bytes = new byte[size]; + in.readFully(bytes); + return new String(bytes, "utf-8"); + } + + public static class Formatter { + + public void write(DataOutput out, Token token) throws IOException { + long id = token.getId(); + byte idType; + if (id <= Byte.MAX_VALUE - Byte.MIN_VALUE) { + idType = ID_ONE_BYTE; + } else if (id <= Short.MAX_VALUE - Short.MIN_VALUE) { + idType = ID_TWO_BYTES; + } else if (id <= (long) Integer.MAX_VALUE - (long) Integer.MIN_VALUE) { // cast to long to prevent overflow + idType = ID_FOUR_BYTES; + } else { + idType = ID_EIGHT_BYTES; + } + out.write(token.getType() + idType); + token.writeTo(out, idType); + } + + public Token read(DataInput in) throws IOException { + byte nextByte = in.readByte(); + byte type = (byte) (nextByte & TYPE_MASK); + byte idType = (byte) (nextByte & ID_MASK); + Token token = contructToken(type); + token.readFrom(in, idType); + return token; + } + + private Token contructToken(byte type) { + switch (type) { + case Token.TYPE_START_NODE: + return new StartNode(); + case Token.TYPE_MAP_ID_TO_VALUE: + return new MapIdToValue(); + case Token.TYPE_ATTRIBUTE: + return new Attribute(); + case Token.TYPE_END_NODE: + return new EndNode(); + case Token.TYPE_VALUE: + return new Value(); + default: + throw new StreamException("Unknown token type"); + } + } + } + + public static class MapIdToValue extends Token { + + public MapIdToValue(long id, String value) { + super(TYPE_MAP_ID_TO_VALUE); + this.id = id; + this.value = value; + } + + public MapIdToValue() { + super(TYPE_MAP_ID_TO_VALUE); + } + + public void writeTo(DataOutput out, byte idType) throws IOException { + writeId(out, id, idType); + writeString(out, value); + } + + public void readFrom(DataInput in, byte idType) throws IOException { + id = readId(in, idType); + value = readString(in); + } + + } + + public static class StartNode extends Token { + + public StartNode(long id) { + super(TYPE_START_NODE); + this.id = id; + } + + public StartNode() { + super(TYPE_START_NODE); + } + + public void writeTo(DataOutput out, byte idType) throws IOException { + writeId(out, id, idType); + } + + public void readFrom(DataInput in, byte idType) throws IOException { + id = readId(in, idType); + } + + } + + public static class EndNode extends Token { + + public EndNode() { + super(TYPE_END_NODE); + } + + public void writeTo(DataOutput out, byte idType) { + } + + public void readFrom(DataInput in, byte idType) { + } + + } + + public static class Attribute extends Token { + + public Attribute(long id, String value) { + super(TYPE_ATTRIBUTE); + this.id = id; + this.value = value; + } + + public Attribute() { + super(TYPE_ATTRIBUTE); + } + + public void writeTo(DataOutput out, byte idType) throws IOException { + writeId(out, id, idType); + writeString(out, value); + } + + public void readFrom(DataInput in, byte idType) throws IOException { + this.id = readId(in, idType); + this.value = readString(in); + } + + } + + public static class Value extends Token { + + public Value(String value) { + super(TYPE_VALUE); + this.value = value; + } + + public Value() { + super(TYPE_VALUE); + } + + public void writeTo(DataOutput out, byte idType) throws IOException { + writeString(out, value); + } + + public void readFrom(DataInput in, byte idType) throws IOException { + value = readString(in); + } + + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/copy/HierarchicalStreamCopier.java b/xstream/src/java/com/thoughtworks/xstream/io/copy/HierarchicalStreamCopier.java new file mode 100644 index 0000000..3bb9f15 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/copy/HierarchicalStreamCopier.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. June 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.io.copy; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + +/** + * Tool for copying the contents of one HierarichalStreamReader to a HierarichalStreamWriter. + *

+ * This is useful for transforming the output of one format to another (e.g. binary to XML) + * without needing to know details about the classes and avoiding the overhead of serialization.

+ * + *

Example

+ *
+ * HierarchicalStreamReader reader = new BinaryStreamReader(someBinaryInput);
+ * HierarchicalStreamWriter writer = new PrettyPrintWriter(someXmlOutput);
+ * HierarchicalStreamCopier copier = new HierarchicalStreamCopier();
+ * copier.copy(reader, writer);
+ * 
+ * + * @author Joe Walnes + * @since 1.2 + */ +public class HierarchicalStreamCopier { + public void copy(HierarchicalStreamReader source, HierarchicalStreamWriter destination) { + destination.startNode(source.getNodeName()); + int attributeCount = source.getAttributeCount(); + for (int i = 0; i < attributeCount; i++) { + destination.addAttribute(source.getAttributeName(i), source.getAttribute(i)); + } + String value = source.getValue(); + if (value != null && value.length() > 0) { + destination.setValue(value); + } + while (source.hasMoreChildren()) { + source.moveDown(); + copy(source, destination); + source.moveUp(); + } + destination.endNode(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/json/AbstractJsonWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/json/AbstractJsonWriter.java new file mode 100644 index 0000000..ce5bb1e --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/json/AbstractJsonWriter.java @@ -0,0 +1,661 @@ +/* + * Copyright (C) 2009, 2010, 2011, 2012, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 20. August 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.json; + +import java.io.Externalizable; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.core.util.FastStack; +import com.thoughtworks.xstream.io.AbstractWriter; +import com.thoughtworks.xstream.io.naming.NameCoder; +import com.thoughtworks.xstream.io.naming.NoNameCoder; +import com.thoughtworks.xstream.mapper.Mapper; + + +/** + * An abstract implementation of a writer that calls abstract methods to build JSON structures. + * Note, that XStream's implicit collection feature is only compatible with the syntax in + * {@link #EXPLICIT_MODE}. + * + * @author Jörg Schaible + * @since 1.4 + */ +public abstract class AbstractJsonWriter extends AbstractWriter { + /** + * DROP_ROOT_MODE drops the JSON root node. + *

+ * The root node is the first level of the JSON object i.e.

+ * + *
+     * { "person": {
+     *     "name": "Joe"
+     * }}
+     * 
+ * + *

will be written without root simply as

+ * + *
+     * {
+     *     "name": "Joe"
+     * }
+     * 
+ * + *

+ * Without a root node, the top level element might now also be an array. However, it is + * possible to generate invalid JSON unless {@link #STRICT_MODE} is also set.

+ * + * @since 1.3.1 + */ + public static final int DROP_ROOT_MODE = 1; + /** + * STRICT_MODE prevents invalid JSON for single value objects when dropping the root. + *

+ * The mode is only useful in combination with the {@link #DROP_ROOT_MODE}. An object with a + * single value as first node i.e.

+ * + *
+     * { "name": "Joe" }
+     * 
+ * + *

is simply written as

+ * + *
+     * "Joe"
+     * 
+ * + *

+ * However, this is no longer valid JSON. Therefore you can activate {@link #STRICT_MODE} + * and a {@link ConversionException} is thrown instead.

+ * + * @since 1.3.1 + */ + public static final int STRICT_MODE = 2; + /** + * EXPLICIT_MODE assures that all data has its explicit equivalent in the resulting JSON. + *

+ * XStream is normally using attributes in XML that have no real equivalent in JSON. + * Additionally it is essential in XML that the individual child elements of a tag keep + * order and may have the same tag name. XStream's model relies on both characteristics. + * However, properties of a JSON object do not have a defined order, but their names have to + * be unique. Only a JSON array defines the order of its elements. + *

+ *

+ * Therefore XStream uses in explicit mode a JSON format that supports the original + * requirements at the expense of the simplicity of the JSON objects and arrays. Each Java + * object will be represented by a JSON object with a single property representing the name + * of the object and an array as value that contains two more arrays. The first one contains + * a JSON object with all attributes, the second one the value of the Java object which can + * be null, a string or integer value or again a new JSON object representing a Java object. + * Here an example of an string array with one member, where the array and the string has an + * additional attribute 'id':

+ * + *
+     * {"string-array":[[{"id":"1"}],[{"string":[[{"id":"2"}],["Joe"]]}]]}
+     * 
+ * + *

+ * This format can be used to always deserialize into Java again. + *

+ *

+ * This mode cannot combined with {@link #STRICT_MODE} or {@link #DROP_ROOT_MODE}. + *

+ * + * @since 1.4 + */ + public static final int EXPLICIT_MODE = 4; + /** + * IEEE_754_MODE keeps precision of 64-bit integer values. + *

+ * In JavaScript every number is expressed as 64-bit double value with a precision of 53 + * bits following IEEE 754. Therefore it is not possible to represent the complete value + * range of 64-bit integer values. Any integer value > 253 + * (9007199254740992) or < -253 (-9007199254740992) will therefore be + * written as string value. + *

+ *

+ * CAUTION: A client must be aware that the element may contain a number or a string value. + *

+ * + * @since 1.4.5 + * @see ECMA Specification: The Number Type + */ + public static final int IEEE_754_MODE = 8; + + public static class Type { + public static Type NULL = new Type(); + public static Type STRING = new Type(); + public static Type NUMBER = new Type(); + public static Type BOOLEAN = new Type(); + } + + private static class StackElement { + final Class type; + int status; + public StackElement(Class type, int status) { + this.type = type; + this.status = status; + } + } + + private static class IllegalWriterStateException extends IllegalStateException { + public IllegalWriterStateException(int from, int to, String element) { + super("Cannot turn from state " + getState(from) + " into state " + getState(to) + + (element == null ? "" : " for property " + element)); + } + private static String getState(int state) { + switch (state) { + case STATE_ROOT: return "ROOT"; + case STATE_END_OBJECT: return "END_OBJECT"; + case STATE_START_OBJECT: return "START_OBJECT"; + case STATE_START_ATTRIBUTES: return "START_ATTRIBUTES"; + case STATE_NEXT_ATTRIBUTE: return "NEXT_ATTRIBUTE"; + case STATE_END_ATTRIBUTES: return "END_ATTRIBUTES"; + case STATE_START_ELEMENTS: return "START_ELEMENTS"; + case STATE_NEXT_ELEMENT: return "NEXT_ELEMENT"; + case STATE_END_ELEMENTS: return "END_ELEMENTS"; + case STATE_SET_VALUE: return "SET_VALUE"; + default: throw new IllegalArgumentException("Unknown state provided: " + state + + ", cannot create message for IllegalWriterStateException"); + } + } + } + + private static final int STATE_ROOT = 1 << 0; + private static final int STATE_END_OBJECT = 1 << 1; + private static final int STATE_START_OBJECT = 1 << 2; + private static final int STATE_START_ATTRIBUTES = 1 << 3; + private static final int STATE_NEXT_ATTRIBUTE = 1 << 4; + private static final int STATE_END_ATTRIBUTES = 1 << 5; + private static final int STATE_START_ELEMENTS = 1 << 6; + private static final int STATE_NEXT_ELEMENT = 1 << 7; + private static final int STATE_END_ELEMENTS = 1 << 8; + private static final int STATE_SET_VALUE = 1 << 9; + + private static final Set NUMBER_TYPES = new HashSet(Arrays.asList(new Class[]{ + byte.class, Byte.class, short.class, Short.class, int.class, Integer.class, long.class, + Long.class, float.class, Float.class, double.class, Double.class, BigInteger.class, + BigDecimal.class})); + private int mode; + private FastStack stack = new FastStack(16); + private int expectedStates; + + /** + * Construct a JSON writer. + * + * @since 1.4 + */ + public AbstractJsonWriter() { + this(new NoNameCoder()); + } + + /** + * Construct a JSON writer with a special mode. + * + * @param mode a bit mask of the mode constants + * @since 1.4 + */ + public AbstractJsonWriter(int mode) { + this(mode, new NoNameCoder()); + } + + /** + * Construct a JSON writer with a special name coder. + * + * @param nameCoder the name coder to use + * @since 1.4 + */ + public AbstractJsonWriter(NameCoder nameCoder) { + this(0, nameCoder); + } + + /** + * Construct a JSON writer with a special mode and name coder. + * + * @param mode a bit mask of the mode constants + * @param nameCoder the name coder to use + * @since 1.4 + */ + public AbstractJsonWriter(int mode, NameCoder nameCoder) { + super(nameCoder); + this.mode = (mode & EXPLICIT_MODE) > 0 ? EXPLICIT_MODE : mode; + stack.push(new StackElement(null, STATE_ROOT)); + expectedStates = STATE_START_OBJECT; + } + + public void startNode(String name, Class clazz) { + if (name == null) { + throw new NullPointerException("name"); + } + stack.push(new StackElement(clazz, ((StackElement)stack.peek()).status)); + handleCheckedStateTransition(STATE_START_OBJECT, name, null); + expectedStates = STATE_SET_VALUE | STATE_NEXT_ATTRIBUTE | STATE_START_OBJECT | STATE_NEXT_ELEMENT | STATE_ROOT; + } + + public void startNode(String name) { + startNode(name, null); + } + + public void addAttribute(String name, String value) { + handleCheckedStateTransition(STATE_NEXT_ATTRIBUTE, name, value); + expectedStates = STATE_SET_VALUE | STATE_NEXT_ATTRIBUTE | STATE_START_OBJECT | STATE_NEXT_ELEMENT | STATE_ROOT; + } + + public void setValue(String text) { + Class type = ((StackElement)stack.peek()).type; + if ((type == Character.class || type == Character.TYPE) && "".equals(text)) { + text = "\u0000"; + } + handleCheckedStateTransition(STATE_SET_VALUE, null, text); + expectedStates = STATE_NEXT_ELEMENT | STATE_ROOT; + } + + public void endNode() { + int size = stack.size(); + int nextState = size > 2 ? STATE_NEXT_ELEMENT : STATE_ROOT; + handleCheckedStateTransition(nextState, null, null); + stack.pop(); + ((StackElement)stack.peek()).status = nextState; + expectedStates = STATE_START_OBJECT; + if (size > 2) { + expectedStates |= STATE_NEXT_ELEMENT | STATE_ROOT; + } + } + + private void handleCheckedStateTransition(final int requiredState, final String elementToAdd, final String valueToAdd) + { + final StackElement stackElement = (StackElement)stack.peek(); + if ((expectedStates & requiredState) == 0) { + throw new IllegalWriterStateException(stackElement.status, requiredState, elementToAdd); + } + int currentState = handleStateTransition(stackElement.status, requiredState, elementToAdd, valueToAdd); + stackElement.status = currentState; + } + + private int handleStateTransition(int currentState, final int requiredState, final String elementToAdd, final String valueToAdd) + { + int size = stack.size(); + Class currentType = ((StackElement)stack.peek()).type; + boolean isArray = size > 1 && isArray(currentType); + boolean isArrayElement = size > 1 && isArray(((StackElement)stack.get(size-2)).type); + switch(currentState) { + case STATE_ROOT: + if (requiredState == STATE_START_OBJECT) { + currentState = handleStateTransition(STATE_START_ELEMENTS, STATE_START_OBJECT, elementToAdd, null); + return requiredState; + } + throw new IllegalWriterStateException(currentState, requiredState, elementToAdd); + + case STATE_END_OBJECT: + switch(requiredState) { + case STATE_START_OBJECT: + currentState = handleStateTransition(currentState, STATE_NEXT_ELEMENT, null, null); + currentState = handleStateTransition(currentState, STATE_START_OBJECT, elementToAdd, null); + return requiredState; + case STATE_NEXT_ELEMENT: + nextElement(); + return requiredState; + case STATE_ROOT: + if (((mode & DROP_ROOT_MODE) == 0 || size > 2) && (mode & EXPLICIT_MODE) == 0) { + endObject(); + } + return requiredState; + default: + throw new IllegalWriterStateException(currentState, requiredState, elementToAdd); + } + + case STATE_START_OBJECT: + switch(requiredState) { + case STATE_SET_VALUE: + case STATE_START_OBJECT: + case STATE_ROOT: + case STATE_NEXT_ELEMENT: + if (!isArrayElement || (mode & EXPLICIT_MODE) != 0) { + currentState = handleStateTransition(currentState, STATE_START_ATTRIBUTES, null, null); + currentState = handleStateTransition(currentState, STATE_END_ATTRIBUTES, null, null); + } + currentState = STATE_START_ELEMENTS; + + switch(requiredState) { + case STATE_SET_VALUE: + currentState = handleStateTransition(currentState, STATE_SET_VALUE, null, valueToAdd); + break; + case STATE_START_OBJECT: + currentState = handleStateTransition(currentState, STATE_START_OBJECT, elementToAdd, null); + break; + case STATE_ROOT: + case STATE_NEXT_ELEMENT: + currentState = handleStateTransition(currentState, STATE_SET_VALUE, null, null); + currentState = handleStateTransition(currentState, requiredState, null, null); + break; + } + return requiredState; + case STATE_START_ATTRIBUTES: + if ((mode & EXPLICIT_MODE) != 0) { + startArray(); + } + return requiredState; + case STATE_NEXT_ATTRIBUTE: + if ((mode & EXPLICIT_MODE) != 0 || !isArray) { + currentState = handleStateTransition(currentState, STATE_START_ATTRIBUTES, null, null); + currentState = handleStateTransition(currentState, STATE_NEXT_ATTRIBUTE, elementToAdd, valueToAdd); + return requiredState; + } else { + return STATE_START_OBJECT; + } + default: + throw new IllegalWriterStateException(currentState, requiredState, elementToAdd); + } + + case STATE_NEXT_ELEMENT: + switch(requiredState) { + case STATE_START_OBJECT: + nextElement(); + if (!isArrayElement && (mode & EXPLICIT_MODE) == 0) { + addLabel(encodeNode(elementToAdd)); + if ((mode & EXPLICIT_MODE) == 0 && isArray) { + startArray(); + } + return requiredState; + } + break; + case STATE_ROOT: + currentState = handleStateTransition(currentState, STATE_END_OBJECT, null, null); + currentState = handleStateTransition(currentState, STATE_ROOT, null, null); + return requiredState; + case STATE_NEXT_ELEMENT: + case STATE_END_OBJECT: + currentState = handleStateTransition(currentState, STATE_END_ELEMENTS, null, null); + currentState = handleStateTransition(currentState, STATE_END_OBJECT, null, null); + if ((mode & EXPLICIT_MODE) == 0 && !isArray) { + endObject(); + } + return requiredState; + case STATE_END_ELEMENTS: + if ((mode & EXPLICIT_MODE) == 0 && isArray) { + endArray(); + } + return requiredState; + default: + throw new IllegalWriterStateException(currentState, requiredState, elementToAdd); + } + // fall through + case STATE_START_ELEMENTS: + switch(requiredState) { + case STATE_START_OBJECT: + if ((mode & DROP_ROOT_MODE) == 0 || size > 2) { + if (!isArrayElement || (mode & EXPLICIT_MODE) != 0) { + if (!"".equals(valueToAdd)) { + startObject(); + } + addLabel(encodeNode(elementToAdd)); + } + if ((mode & EXPLICIT_MODE) != 0) { + startArray(); + } + } + if ((mode & EXPLICIT_MODE) == 0) { + if (isArray) { + startArray(); + } + } + return requiredState; + case STATE_SET_VALUE: + if ((mode & STRICT_MODE) != 0 && size == 2) { + throw new ConversionException("Single value cannot be root element"); + } + if (valueToAdd == null) { + if (currentType == Mapper.Null.class) { + addValue("null", Type.NULL); + } else if ((mode & EXPLICIT_MODE) == 0 && !isArray) { + startObject(); + endObject(); + } + } else { + if (((mode & IEEE_754_MODE) != 0) + && (currentType == long.class || currentType == Long.class)) { + long longValue = Long.parseLong(valueToAdd); + // JavaScript supports a maximum of 2^53 + if (longValue > 9007199254740992L || longValue < -9007199254740992L) { + addValue(valueToAdd, Type.STRING); + } else { + addValue(valueToAdd, getType(currentType)); + } + } else { + addValue(valueToAdd, getType(currentType)); + } + } + return requiredState; + case STATE_END_ELEMENTS: + case STATE_NEXT_ELEMENT: + if ((mode & EXPLICIT_MODE) == 0) { + if (isArray) { + endArray(); + } else { + endObject(); + } + } + return requiredState; + default: + throw new IllegalWriterStateException(currentState, requiredState, elementToAdd); + } + + case STATE_END_ELEMENTS: + switch(requiredState) { + case STATE_END_OBJECT: + if ((mode & EXPLICIT_MODE) != 0) { + endArray(); + endArray(); + endObject(); + } + return requiredState; + default: + throw new IllegalWriterStateException(currentState, requiredState, elementToAdd); + } + + case STATE_START_ATTRIBUTES: + switch(requiredState) { + case STATE_NEXT_ATTRIBUTE: + if (elementToAdd != null) { + String name = ((mode & EXPLICIT_MODE) == 0 ? "@" : "" ) + elementToAdd; + startObject(); + addLabel(encodeAttribute(name)); + addValue(valueToAdd, Type.STRING); + } + return requiredState; + } + // fall through + case STATE_NEXT_ATTRIBUTE: + switch(requiredState) { + case STATE_END_ATTRIBUTES: + if ((mode & EXPLICIT_MODE) != 0) { + if (currentState == STATE_NEXT_ATTRIBUTE) { + endObject(); + } + endArray(); + nextElement(); + startArray(); + } + return requiredState; + case STATE_NEXT_ATTRIBUTE: + if (!isArray || (mode & EXPLICIT_MODE) != 0) { + nextElement(); + String name = ((mode & EXPLICIT_MODE) == 0 ? "@" : "" ) + elementToAdd; + addLabel(encodeAttribute(name)); + addValue(valueToAdd, Type.STRING); + } + return requiredState; + case STATE_SET_VALUE: + case STATE_START_OBJECT: + currentState = handleStateTransition(currentState, STATE_END_ATTRIBUTES, null, null); + currentState = handleStateTransition(currentState, STATE_START_ELEMENTS, null, null); + switch (requiredState) { + case STATE_SET_VALUE: + if ((mode & EXPLICIT_MODE) == 0) { + addLabel(encodeNode("$")); + } + currentState = handleStateTransition(currentState, STATE_SET_VALUE, null, valueToAdd); + if ((mode & EXPLICIT_MODE) == 0) { + endObject(); + } + break; + case STATE_START_OBJECT: + currentState = handleStateTransition(currentState, STATE_START_OBJECT, elementToAdd, (mode & EXPLICIT_MODE) == 0 ? "" : null); + break; + case STATE_END_OBJECT: + currentState = handleStateTransition(currentState, STATE_SET_VALUE, null, null); + currentState = handleStateTransition(currentState, STATE_END_OBJECT, null, null); + break; + } + return requiredState; + case STATE_NEXT_ELEMENT: + currentState = handleStateTransition(currentState, STATE_END_ATTRIBUTES, null, null); + currentState = handleStateTransition(currentState, STATE_END_OBJECT, null, null); + return requiredState; + case STATE_ROOT: + currentState = handleStateTransition(currentState, STATE_END_ATTRIBUTES, null, null); + currentState = handleStateTransition(currentState, STATE_END_OBJECT, null, null); + currentState = handleStateTransition(currentState, STATE_ROOT, null, null); + return requiredState; + default: + throw new IllegalWriterStateException(currentState, requiredState, elementToAdd); + } + + case STATE_END_ATTRIBUTES: + switch(requiredState) { + case STATE_START_ELEMENTS: + if ((mode & EXPLICIT_MODE) == 0) { + nextElement(); + } + break; + case STATE_END_OBJECT: + currentState = handleStateTransition(STATE_START_ELEMENTS, STATE_END_ELEMENTS, null, null); + currentState = handleStateTransition(currentState, STATE_END_OBJECT, null, null); + break; + default: + throw new IllegalWriterStateException(currentState, requiredState, elementToAdd); + } + return requiredState; + + case STATE_SET_VALUE: + switch(requiredState) { + case STATE_END_ELEMENTS: + if ((mode & EXPLICIT_MODE) == 0 && isArray) { + endArray(); + } + return requiredState; + case STATE_NEXT_ELEMENT: + currentState = handleStateTransition(currentState, STATE_END_ELEMENTS, null, null); + currentState = handleStateTransition(currentState, STATE_END_OBJECT, null, null); + return requiredState; + case STATE_ROOT: + currentState = handleStateTransition(currentState, STATE_END_ELEMENTS, null, null); + currentState = handleStateTransition(currentState, STATE_END_OBJECT, null, null); + currentState = handleStateTransition(currentState, STATE_ROOT, null, null); + return requiredState; + default: + throw new IllegalWriterStateException(currentState, requiredState, elementToAdd); + } + } + + throw new IllegalWriterStateException(currentState, requiredState, elementToAdd); + } + + /** + * Method to return the appropriate JSON type for a Java type. + * + * @param clazz the type + * @return One of the {@link Type} instances + * @since 1.4.4 + */ + protected Type getType(Class clazz) { + return clazz == Mapper.Null.class + ? Type.NULL + : (clazz == Boolean.class || clazz == Boolean.TYPE) + ? Type.BOOLEAN + : NUMBER_TYPES.contains(clazz) + ? Type.NUMBER + : Type.STRING; + } + + /** + * Method to declare various Java types to be handles as JSON array. + * + * @param clazz the type + * @return true if handles as array + * @since 1.4 + */ + protected boolean isArray(Class clazz) { + return clazz != null && (clazz.isArray() + || Collection.class.isAssignableFrom(clazz) + || Externalizable.class.isAssignableFrom(clazz) + || Map.class.isAssignableFrom(clazz) + || Map.Entry.class.isAssignableFrom(clazz)); + } + + /** + * Start a JSON object. + * + * @since 1.4 + */ + protected abstract void startObject(); + + /** + * Add a label to a JSON object. + * + * @param name the label's name + * @since 1.4 + */ + protected abstract void addLabel(String name); + + /** + * Add a value to a JSON object's label or to an array. + * + * @param value the value itself + * @param type the JSON type + * @since 1.4 + */ + protected abstract void addValue(String value, Type type); + + /** + * Start a JSON array. + * + * @since 1.4 + */ + protected abstract void startArray(); + + /** + * Prepare a JSON object or array for another element. + * + * @since 1.4 + */ + protected abstract void nextElement(); + + /** + * End the JSON array. + * + * @since 1.4 + */ + protected abstract void endArray(); + + /** + * End the JSON object. + * + * @since 1.4 + */ + protected abstract void endObject(); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/json/JettisonMappedXmlDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/json/JettisonMappedXmlDriver.java new file mode 100644 index 0000000..272ca11 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/json/JettisonMappedXmlDriver.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2007, 2008, 2009, 2010, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. March 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.json; + +import com.thoughtworks.xstream.io.AbstractDriver; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.xml.QNameMap; +import com.thoughtworks.xstream.io.xml.StaxReader; +import com.thoughtworks.xstream.io.xml.StaxWriter; + +import org.codehaus.jettison.mapped.Configuration; +import org.codehaus.jettison.mapped.MappedNamespaceConvention; +import org.codehaus.jettison.mapped.MappedXMLInputFactory; +import org.codehaus.jettison.mapped.MappedXMLOutputFactory; + +import javax.xml.stream.XMLStreamException; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.net.URL; + + +/** + * Simple XStream driver wrapping Jettison's Mapped reader and writer. Serializes object from + * and to JSON. + * + * @author Dejan Bosanac + */ +public class JettisonMappedXmlDriver extends AbstractDriver { + + protected final MappedXMLOutputFactory mof; + protected final MappedXMLInputFactory mif; + protected final MappedNamespaceConvention convention; + protected final boolean useSerializeAsArray; + + /** + * Construct a JettisonMappedXmlDriver. + */ + public JettisonMappedXmlDriver() { + this(new Configuration()); + } + + /** + * Construct a JettisonMappedXmlDriver with configuration. + * @param config the Jettison configuration + */ + public JettisonMappedXmlDriver(final Configuration config) { + this(config, true); + } + + /** + * Construct a JettisonMappedXmlDriver with configuration. This constructor has been added + * by special request of Jettison users to support JSON generated by older Jettison + * versions. if the driver is setup to ignore the XStream hints for JSON arrays, there is + * neither support from XStream's side nor are there any tests to ensure this mode. + * + * @param config the Jettison configuration + * @param useSerializeAsArray flag to use XStream's hints for collections and arrays + * @since 1.4 + */ + public JettisonMappedXmlDriver(final Configuration config, final boolean useSerializeAsArray) { + mof = new MappedXMLOutputFactory(config); + mif = new MappedXMLInputFactory(config); + convention = new MappedNamespaceConvention(config); + this.useSerializeAsArray = useSerializeAsArray; + } + + public HierarchicalStreamReader createReader(final Reader reader) { + try { + return new StaxReader(new QNameMap(), mif.createXMLStreamReader(reader), getNameCoder()); + } catch (final XMLStreamException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamReader createReader(final InputStream input) { + try { + return new StaxReader(new QNameMap(), mif.createXMLStreamReader(input), getNameCoder()); + } catch (final XMLStreamException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamReader createReader(URL in) { + InputStream instream = null; + try { + instream = in.openStream(); + return new StaxReader(new QNameMap(), mif.createXMLStreamReader( + in.toExternalForm(), instream), getNameCoder()); + } catch (final XMLStreamException e) { + throw new StreamException(e); + } catch (IOException e) { + throw new StreamException(e); + } finally { + if (instream != null) { + try { + instream.close(); + } catch (IOException e) { + // ignore + } + } + } + } + + public HierarchicalStreamReader createReader(File in) { + InputStream instream = null; + try { + instream = new FileInputStream(in); + return new StaxReader(new QNameMap(), mif.createXMLStreamReader(in + .toURI() + .toASCIIString(), instream), getNameCoder()); + } catch (final XMLStreamException e) { + throw new StreamException(e); + } catch (IOException e) { + throw new StreamException(e); + } finally { + if (instream != null) { + try { + instream.close(); + } catch (IOException e) { + // ignore + } + } + } + } + + public HierarchicalStreamWriter createWriter(final Writer writer) { + try { + if (useSerializeAsArray) { + return new JettisonStaxWriter(new QNameMap(), mof.createXMLStreamWriter(writer), getNameCoder(), convention); + } else { + return new StaxWriter(new QNameMap(), mof.createXMLStreamWriter(writer), getNameCoder()); + } + } catch (final XMLStreamException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamWriter createWriter(final OutputStream output) { + try { + if (useSerializeAsArray) { + return new JettisonStaxWriter(new QNameMap(), mof.createXMLStreamWriter(output), getNameCoder(), convention); + } else { + return new StaxWriter(new QNameMap(), mof.createXMLStreamWriter(output), getNameCoder()); + } + } catch (final XMLStreamException e) { + throw new StreamException(e); + } + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/json/JettisonStaxWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/json/JettisonStaxWriter.java new file mode 100644 index 0000000..bc2117e --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/json/JettisonStaxWriter.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 17.04.2008 by Joerg Schaible. + */ +package com.thoughtworks.xstream.io.json; + +import com.thoughtworks.xstream.io.naming.NameCoder; +import com.thoughtworks.xstream.io.xml.QNameMap; +import com.thoughtworks.xstream.io.xml.StaxWriter; +import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer; + +import org.codehaus.jettison.AbstractXMLStreamWriter; +import org.codehaus.jettison.mapped.MappedNamespaceConvention; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; + +import java.util.Collection; +import java.util.Map; + + +/** + * A specialized {@link StaxWriter} that makes usage of internal functionality of Jettison. + * + * @author Jörg Schaible + * @since 1.3.1 + */ +public class JettisonStaxWriter extends StaxWriter { + + private final MappedNamespaceConvention convention; + + /** + * @since 1.4 + */ + public JettisonStaxWriter( + QNameMap qnameMap, XMLStreamWriter out, boolean writeEnclosingDocument, + boolean namespaceRepairingMode, NameCoder nameCoder, + MappedNamespaceConvention convention) throws XMLStreamException { + super(qnameMap, out, writeEnclosingDocument, namespaceRepairingMode, nameCoder); + this.convention = convention; + } + + /** + * @deprecated As of 1.4 use + * {@link JettisonStaxWriter#JettisonStaxWriter(QNameMap, XMLStreamWriter, boolean, boolean, NameCoder, MappedNamespaceConvention)} + * instead + */ + public JettisonStaxWriter( + QNameMap qnameMap, XMLStreamWriter out, boolean writeEnclosingDocument, + boolean namespaceRepairingMode, XmlFriendlyReplacer replacer, + MappedNamespaceConvention convention) throws XMLStreamException { + this(qnameMap, out, writeEnclosingDocument, namespaceRepairingMode, (NameCoder) replacer, convention); + } + + public JettisonStaxWriter( + QNameMap qnameMap, XMLStreamWriter out, boolean writeEnclosingDocument, + boolean namespaceRepairingMode, MappedNamespaceConvention convention) + throws XMLStreamException { + super(qnameMap, out, writeEnclosingDocument, namespaceRepairingMode); + this.convention = convention; + } + + public JettisonStaxWriter( + QNameMap qnameMap, XMLStreamWriter out, MappedNamespaceConvention convention) + throws XMLStreamException { + super(qnameMap, out); + this.convention = convention; + } + + /** + * @since 1.4 + */ + public JettisonStaxWriter( + QNameMap qnameMap, XMLStreamWriter out, NameCoder nameCoder, MappedNamespaceConvention convention) + throws XMLStreamException { + super(qnameMap, out, nameCoder); + this.convention = convention; + } + + public void startNode(String name, Class clazz) { + XMLStreamWriter out = getXMLStreamWriter(); + if (clazz != null && out instanceof AbstractXMLStreamWriter) { + if (Collection.class.isAssignableFrom(clazz) + || Map.class.isAssignableFrom(clazz) + || clazz.isArray()) { + QName qname = getQNameMap().getQName(encodeNode(name)); + String prefix = qname.getPrefix(); + String uri = qname.getNamespaceURI(); + String key = convention.createKey(prefix, uri, qname.getLocalPart()); + if (!((AbstractXMLStreamWriter)out).getSerializedAsArrays().contains(key)) { + // Typo is in the API of Jettison ... + ((AbstractXMLStreamWriter)out).seriliazeAsArray(key); + } + } + } + startNode(name); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/json/JsonHierarchicalStreamDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/json/JsonHierarchicalStreamDriver.java new file mode 100644 index 0000000..c0e607f --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/json/JsonHierarchicalStreamDriver.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. June 2006 by Mauro Talevi + */ +package com.thoughtworks.xstream.io.json; + +import com.thoughtworks.xstream.io.AbstractDriver; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.naming.NameCoder; + +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.io.Writer; +import java.net.URL; + +/** + * A driver for JSON that writes optimized JSON format, but is not able to deserialize the result. + * + * @author Paul Hammant + * @since 1.2 + */ +public class JsonHierarchicalStreamDriver extends AbstractDriver { + + /** + * Construct a JsonHierarchicalStreamDriver. + */ + public JsonHierarchicalStreamDriver() { + super(); + } + + /** + * Construct a JsonHierarchicalStreamDriver with name coding. + * + * @param nameCoder the coder to encode and decode the JSON labels. + * @since 1.4.2 + */ + public JsonHierarchicalStreamDriver(NameCoder nameCoder) { + super(nameCoder); + } + + public HierarchicalStreamReader createReader(Reader in) { + throw new UnsupportedOperationException("The JsonHierarchicalStreamDriver can only write JSON"); + } + + public HierarchicalStreamReader createReader(InputStream in) { + throw new UnsupportedOperationException("The JsonHierarchicalStreamDriver can only write JSON"); + } + + public HierarchicalStreamReader createReader(URL in) { + throw new UnsupportedOperationException("The JsonHierarchicalStreamDriver can only write JSON"); + } + + public HierarchicalStreamReader createReader(File in) { + throw new UnsupportedOperationException("The JsonHierarchicalStreamDriver can only write JSON"); + } + + /** + * Create a HierarchicalStreamWriter that writes JSON. + */ + public HierarchicalStreamWriter createWriter(Writer out) { + return new JsonWriter(out); + } + + public HierarchicalStreamWriter createWriter(OutputStream out) { + try { + // JSON spec requires UTF-8 + return createWriter(new OutputStreamWriter(out, "UTF-8")); + } catch (UnsupportedEncodingException e) { + throw new StreamException(e); + } + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/json/JsonHierarchicalStreamWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/json/JsonHierarchicalStreamWriter.java new file mode 100644 index 0000000..4511a67 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/json/JsonHierarchicalStreamWriter.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. June 2006 by Mauro Talevi + */ +package com.thoughtworks.xstream.io.json; + +import java.io.Writer; + + +/** + * A simple writer that outputs JSON in a pretty-printed indented stream. Arrays, Lists and Sets + * rely on you NOT using XStream.addImplicitCollection(..) + * + * @author Paul Hammant + * @author Jörg Schaible + * @since 1.2 + * @deprecated As of 1.3.1, use JsonWriter instead + */ +public class JsonHierarchicalStreamWriter extends JsonWriter { + + /** + * @deprecated As of 1.3.1, use JsonWriter instead + */ + public JsonHierarchicalStreamWriter(Writer writer, char[] lineIndenter, String newLine) { + super(writer, lineIndenter, newLine); + } + + /** + * @deprecated As of 1.3.1, use JsonWriter instead + */ + public JsonHierarchicalStreamWriter(Writer writer, char[] lineIndenter) { + this(writer, lineIndenter, "\n"); + } + + /** + * @deprecated As of 1.3.1, use JsonWriter instead + */ + public JsonHierarchicalStreamWriter(Writer writer, String lineIndenter, String newLine) { + this(writer, lineIndenter.toCharArray(), newLine); + } + + /** + * @deprecated As of 1.3.1, use JsonWriter instead + */ + public JsonHierarchicalStreamWriter(Writer writer, String lineIndenter) { + this(writer, lineIndenter.toCharArray()); + } + + /** + * @deprecated As of 1.3.1, use JsonWriter instead + */ + public JsonHierarchicalStreamWriter(Writer writer) { + this(writer, new char[]{' ', ' '}); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/json/JsonWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/json/JsonWriter.java new file mode 100644 index 0000000..b81b81b --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/json/JsonWriter.java @@ -0,0 +1,406 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 28. November 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.json; + +import java.io.Writer; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.core.util.QuickWriter; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.naming.NameCoder; +import com.thoughtworks.xstream.io.naming.NoNameCoder; + + +/** + * A simple writer that outputs JSON in a pretty-printed indented stream. Arrays, Lists and Sets + * rely on you NOT using XStream.addImplicitCollection(..). + * + * @author Paul Hammant + * @author Jörg Schaible + * @since 1.3.1 + */ +public class JsonWriter extends AbstractJsonWriter { + + protected final QuickWriter writer; + protected final Format format; + private int depth; + private boolean newLineProposed; + + /** + * @deprecated As of 1.4 use {@link JsonWriter#JsonWriter(Writer, Format) instead} + */ + public JsonWriter(Writer writer, char[] lineIndenter, String newLine) { + this(writer, 0, new Format( + lineIndenter, newLine.toCharArray(), Format.SPACE_AFTER_LABEL + | Format.COMPACT_EMPTY_ELEMENT)); + } + + /** + * @deprecated As of 1.4 use {@link JsonWriter#JsonWriter(Writer, Format) instead} + */ + public JsonWriter(Writer writer, char[] lineIndenter) { + this(writer, 0, new Format(lineIndenter, new char[]{'\n'}, Format.SPACE_AFTER_LABEL + | Format.COMPACT_EMPTY_ELEMENT)); + } + + /** + * @deprecated As of 1.4 use {@link JsonWriter#JsonWriter(Writer, Format) instead} + */ + public JsonWriter(Writer writer, String lineIndenter, String newLine) { + this(writer, 0, new Format( + lineIndenter.toCharArray(), newLine.toCharArray(), Format.SPACE_AFTER_LABEL + | Format.COMPACT_EMPTY_ELEMENT)); + } + + /** + * @deprecated As of 1.4 use {@link JsonWriter#JsonWriter(Writer, Format) instead} + */ + public JsonWriter(Writer writer, String lineIndenter) { + this(writer, 0, new Format( + lineIndenter.toCharArray(), new char[]{'\n'}, Format.SPACE_AFTER_LABEL + | Format.COMPACT_EMPTY_ELEMENT)); + } + + public JsonWriter(Writer writer) { + this(writer, 0, new Format( + new char[]{' ', ' '}, new char[]{'\n'}, Format.SPACE_AFTER_LABEL + | Format.COMPACT_EMPTY_ELEMENT)); + } + + /** + * @since 1.3.1 + * @deprecated As of 1.4 use {@link JsonWriter#JsonWriter(Writer, int, Format) instead} + */ + public JsonWriter(Writer writer, char[] lineIndenter, String newLine, int mode) { + this(writer, mode, new Format( + lineIndenter, newLine.toCharArray(), Format.SPACE_AFTER_LABEL + | Format.COMPACT_EMPTY_ELEMENT)); + } + + /** + * Create a JsonWriter where the writer mode can be chosen. + * + * @param writer the {@link Writer} where the JSON is written to + * @param mode the JsonWriter mode + * @since 1.3.1 + * @see #JsonWriter(Writer, int, Format) + */ + public JsonWriter(Writer writer, int mode) { + this(writer, mode, new Format()); + } + + /** + * Create a JsonWriter where the format is provided. + * + * @param writer the {@link Writer} where the JSON is written to + * @param format the JSON format definition + * @since 1.4 + * @see #JsonWriter(Writer, int, Format) + */ + public JsonWriter(Writer writer, Format format) { + this(writer, 0, format); + } + + /** + * Create a JsonWriter where the writer mode can be chosen and the format definition is + * provided. + *

+ * Following constants can be used as bit mask for the mode: + *

+ *
    + *
  • {@link #DROP_ROOT_MODE}: drop the root node
  • + *
  • {@link #STRICT_MODE}: do not throw {@link ConversionException}, if writer should + * generate invalid JSON
  • + *
  • {@link #EXPLICIT_MODE}: ensure that all available data is explicitly written even if + * addition objects must be added
  • + *
+ * + * @param writer the {@link Writer} where the JSON is written to + * @param mode the JsonWriter mode + * @param format the JSON format definition + * @since 1.4 + */ + public JsonWriter(Writer writer, int mode, Format format) { + this(writer, mode, format, 1024); + } + + /** + * Create a JsonWriter. + * + * @param writer the {@link Writer} where the JSON is written to + * @param mode the JsonWriter mode + * @param format the JSON format definition + * @param bufferSize the buffer size of the internally used QuickWriter + * @see JsonWriter#JsonWriter(Writer, int, Format) + * @since 1.4 + */ + public JsonWriter(Writer writer, int mode, Format format, int bufferSize) { + super(mode, format.getNameCoder()); + this.writer = new QuickWriter(writer, bufferSize); + this.format = format; + depth = (mode & DROP_ROOT_MODE) == 0 ? -1 : 0; + } + + public void flush() { + writer.flush(); + } + + public void close() { + writer.close(); + } + + public HierarchicalStreamWriter underlyingWriter() { + return this; + } + + /** + * {@inheritDoc} + */ + protected void startObject() { + if (newLineProposed) { + writeNewLine(); + } + writer.write('{'); + startNewLine(); + } + + /** + * {@inheritDoc} + */ + protected void addLabel(String name) { + if (newLineProposed) { + writeNewLine(); + } + writer.write('"'); + writeText(name); + writer.write("\":"); + if ((format.mode() & Format.SPACE_AFTER_LABEL) != 0) { + writer.write(' '); + } + } + + /** + * {@inheritDoc} + */ + protected void addValue(String value, Type type) { + if (newLineProposed) { + writeNewLine(); + } + if (type == Type.STRING) { + writer.write('"'); + } + writeText(value); + if (type == Type.STRING) { + writer.write('"'); + } + } + + /** + * {@inheritDoc} + */ + protected void startArray() { + if (newLineProposed) { + writeNewLine(); + } + writer.write("["); + startNewLine(); + } + + /** + * {@inheritDoc} + */ + protected void nextElement() { + writer.write(","); + writeNewLine(); + } + + /** + * {@inheritDoc} + */ + protected void endArray() { + endNewLine(); + writer.write("]"); + } + + /** + * {@inheritDoc} + */ + protected void endObject() { + endNewLine(); + writer.write("}"); + } + + private void startNewLine() { + if ( ++depth > 0) { + newLineProposed = true; + } + } + + private void endNewLine() { + if (depth-- > 0) { + if (((format.mode() & Format.COMPACT_EMPTY_ELEMENT) != 0) && newLineProposed) { + newLineProposed = false; + } else { + writeNewLine(); + } + } + } + + private void writeNewLine() { + int depth = this.depth; + writer.write(format.getNewLine()); + while (depth-- > 0) { + writer.write(format.getLineIndenter()); + } + newLineProposed = false; + } + + private void writeText(String text) { + int length = text.length(); + for (int i = 0; i < length; i++ ) { + char c = text.charAt(i); + switch (c) { + case '"': + this.writer.write("\\\""); + break; + case '\\': + this.writer.write("\\\\"); + break; + // turn this off - it is no CTRL char anyway + // case '/': + // this.writer.write("\\/"); + // break; + case '\b': + this.writer.write("\\b"); + break; + case '\f': + this.writer.write("\\f"); + break; + case '\n': + this.writer.write("\\n"); + break; + case '\r': + this.writer.write("\\r"); + break; + case '\t': + this.writer.write("\\t"); + break; + default: + if (c > 0x1f) { + this.writer.write(c); + } else { + this.writer.write("\\u"); + String hex = "000" + Integer.toHexString(c); + this.writer.write(hex.substring(hex.length() - 4)); + } + } + } + } + + /** + * Format definition for JSON. + * + * @author Jörg Schaible + * @since 1.4 + */ + public static class Format { + + public static int SPACE_AFTER_LABEL = 1; + public static int COMPACT_EMPTY_ELEMENT = 2; + + private char[] lineIndenter; + private char[] newLine; + private final int mode; + private final NameCoder nameCoder; + + /** + * Create a new default Formatter. The formatter uses two spaces, normal line feed + * character, adds a space after the label and will try to compact the output. + * + * @since 1.4.2 + */ + public Format() { + this(new char[]{' ', ' '}, new char[]{'\n'}, Format.SPACE_AFTER_LABEL + | Format.COMPACT_EMPTY_ELEMENT); + } + + + /** + * Create a new Formatter. + * + * @param lineIndenter the characters used for indenting the line + * @param newLine the characters used to create a new line + * @param mode the flags for the format modes + * @since 1.4 + */ + public Format(char[] lineIndenter, char[] newLine, int mode) { + this(lineIndenter, newLine, mode, new NoNameCoder()); + } + + /** + * Create a new Formatter. + * + * @param lineIndenter the characters used for indenting the line + * @param newLine the characters used to create a new line + * @param mode the flags for the format modes + * @param nameCoder the name encoder and decoder + * @since 1.4.2 + */ + public Format(char[] lineIndenter, char[] newLine, int mode, NameCoder nameCoder) { + this.lineIndenter = lineIndenter; + this.newLine = newLine; + this.mode = mode; + this.nameCoder = nameCoder; + } + + /** + * Retrieve the lineIndenter. + * + * @return the lineIndenter + * @since 1.4 + */ + public char[] getLineIndenter() { + return this.lineIndenter; + } + + /** + * Retrieve the newLine. + * + * @return the newLine + * @since 1.4 + */ + public char[] getNewLine() { + return this.newLine; + } + + /** + * Retrieve the mode flags of the formatter. + * + * @return the mode + * @since 1.4 + */ + public int mode() { + return this.mode; + } + + + /** + * Retrieve the NameCoder. + * + * @return the name coder + * @since 1.4.2 + */ + public NameCoder getNameCoder() { + return nameCoder; + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/naming/NameCoder.java b/xstream/src/java/com/thoughtworks/xstream/io/naming/NameCoder.java new file mode 100644 index 0000000..c383bb0 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/naming/NameCoder.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 14. August 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.naming; + +/** + * Coder between names in the object graph and names of a target format. + *

+ * The names form the object graph are typically names generated from Java identifiers (Java + * types or field members), but some names may also contain a minus sign. However, the original + * name might have already been aliased, so a wider range of characters can occur. + *

+ *

+ * The target names should satisfy the syntax of the target format. Transforming Java objects to + * XML this affects names that contain or even start with a dollar sign. Such names violate the + * XML specification. + *

+ *

+ * By default all names from the object graph are used as node names in the target format. + * Meta-data that is necessary to unmarshal the object again is typically written as attribute. + * Since such attributes might be represented differently in the target format, the NameCoder + * distinguishes between the names used for meta-data elements and the ones for the object data. + * The names in the target format might even have to follow a different syntax. Remember, that + * XStream can be easily configured to write also object data as attributes. + *

+ *

+ * Note that the instance of a NameCoder should be either thread-safe or implement {@link Cloneable}. + *

+ * + * @author Jörg Schaible + * @since 1.4 + */ +public interface NameCoder { + /** + * Encode an object name for a node in the target format. + * + * @param name the name of the object data + * @return the node name in the target format + * @since 1.4 + */ + String encodeNode(String name); + + /** + * Encode a meta-data name for an attribute in the target format. + * + * @param name the name of the meta-data + * @return the attribute name in the target format + * @since 1.4 + */ + String encodeAttribute(String name); + + /** + * Decode a node name to an object name. + * + * @param nodeName the name of the node + * @return the name of the object + * @since 1.4 + */ + String decodeNode(String nodeName); + + /** + * Decode an attribute name to an object name. + * + * @param attributeName the name of the attribute + * @return the name of the meta-data + * @since 1.4 + */ + String decodeAttribute(String attributeName); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/naming/NameCoderWrapper.java b/xstream/src/java/com/thoughtworks/xstream/io/naming/NameCoderWrapper.java new file mode 100644 index 0000000..d18f3e8 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/naming/NameCoderWrapper.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. August 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.naming; + +/** + * A wrapper for another NameCoder. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class NameCoderWrapper implements NameCoder { + + private final NameCoder wrapped; + + /** + * Construct a new wrapper for a NameCoder. + * + * @param inner the wrapped NameCoder + * @since 1.4 + */ + public NameCoderWrapper(NameCoder inner) { + this.wrapped = inner; + } + + /** + * {@inheritDoc} + */ + public String decodeAttribute(String attributeName) { + return wrapped.decodeAttribute(attributeName); + } + + /** + * {@inheritDoc} + */ + public String decodeNode(String nodeName) { + return wrapped.decodeNode(nodeName); + } + + /** + * {@inheritDoc} + */ + public String encodeAttribute(String name) { + return wrapped.encodeAttribute(name); + } + + /** + * {@inheritDoc} + */ + public String encodeNode(String name) { + return wrapped.encodeNode(name); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/naming/NoNameCoder.java b/xstream/src/java/com/thoughtworks/xstream/io/naming/NoNameCoder.java new file mode 100644 index 0000000..d240f27 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/naming/NoNameCoder.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. August 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.naming; + +/** + * A NameCoder that does nothing. + *

+ * The usage of this implementation implies that the names used for the objects can also be used + * in the target format without any change. This applies also for XML if the object graph + * contains no object that is an instance of an inner class type or is in the default package. + *

+ * + * @author Jörg Schaiblea + * @since 1.4 + */ +public class NoNameCoder implements NameCoder { + + /** + * {@inheritDoc} + */ + public String decodeAttribute(String attributeName) { + return attributeName; + } + + /** + * {@inheritDoc} + */ + public String decodeNode(String nodeName) { + return nodeName; + } + + /** + * {@inheritDoc} + */ + public String encodeAttribute(String name) { + return name; + } + + /** + * {@inheritDoc} + */ + public String encodeNode(String name) { + return name; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/naming/StaticNameCoder.java b/xstream/src/java/com/thoughtworks/xstream/io/naming/StaticNameCoder.java new file mode 100644 index 0000000..8531d4a --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/naming/StaticNameCoder.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. August 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.naming; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + + +/** + * A NameCoder that encodes and decodes names based on a map. + *

+ * The provided map should contain a mapping between the name of the Java type or field to the + * proper element in the target format. If a name cannot be found in the map, it is assumed not + * to be mapped at all. Note that the values of the map should be unique also, otherwise the + * decoding will produce wrong results. + *

+ * + * @author Jörg Schaible + * @since 1.4 + */ +public class StaticNameCoder implements NameCoder { + + private final Map java2Node; + private final Map java2Attribute; + + private transient Map node2Java; + private transient Map attribute2Java; + + /** + * Construct a StaticNameCoder. + * + * @param java2Node mapping of Java names to nodes + * @param java2Attribute mapping of Java names to attributes + * @since 1.4 + */ + public StaticNameCoder(Map java2Node, Map java2Attribute) { + this.java2Node = new HashMap(java2Node); + if (java2Node == java2Attribute || java2Attribute == null) { + this.java2Attribute = this.java2Node; + } else { + this.java2Attribute = new HashMap(java2Attribute); + } + readResolve(); + } + + /** + * {@inheritDoc} + */ + public String decodeAttribute(String attributeName) { + String name = (String)attribute2Java.get(attributeName); + return name == null ? attributeName : name; + } + + /** + * {@inheritDoc} + */ + public String decodeNode(String nodeName) { + String name = (String)node2Java.get(nodeName); + return name == null ? nodeName : name; + } + + /** + * {@inheritDoc} + */ + public String encodeAttribute(String name) { + String friendlyName = (String)java2Attribute.get(name); + return friendlyName == null ? name : friendlyName; + } + + /** + * {@inheritDoc} + */ + public String encodeNode(String name) { + String friendlyName = (String)java2Node.get(name); + return friendlyName == null ? name : friendlyName; + } + + private Object readResolve() { + node2Java = invertMap(java2Node); + if (java2Node == java2Attribute) { + attribute2Java = node2Java; + } else { + attribute2Java = invertMap(java2Attribute); + } + return this; + } + + private Map invertMap(Map map) { + Map inverseMap = new HashMap(map.size()); + for (final Iterator iter = map.entrySet().iterator(); iter.hasNext();) { + final Map.Entry entry = (Map.Entry)iter.next(); + inverseMap.put((String)entry.getValue(), (String)entry.getKey()); + } + return inverseMap; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/path/Path.java b/xstream/src/java/com/thoughtworks/xstream/io/path/Path.java new file mode 100644 index 0000000..b743939 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/path/Path.java @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 02. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.path; + +import com.thoughtworks.xstream.core.util.FastStack; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a path to a single node in the tree. + * + *

Two absolute paths can also be compared to calculate the relative path between them. + * A relative path can be applied to an absolute path to calculate another absolute path.

+ * + *

Note that the paths are normally XPath compliant, so can be read by other XPath engines. + * However, {@link #toString()} will select a node list while {@link #explicit()} will always select + * an individual node. If the return type of the XPath evaluation is a node, the result will be the same, + * because XPath will then use the first element of the list. The following are examples of path + * expressions that the Path object supports:

+ * + *

Note that the implementation does not take care if the paths are XPath compliant, it simply + * manages the values between the path separator. However, it normalizes the path if a path element + * ends with a selector for the first element (i.e. "[1]"). Those will be handled transparent i.e. two Paths + * are treated equal if one was created with path elements containing this selector and the other one + * without.

+ * + *

The following are examples of path expressions that the Path object supports:

+ *
    + *
  • /
  • + *
  • /some/node
  • + *
  • /a/b/c/b/a
  • + *
  • /a/b[1]/c[1]/b[1]/a[1]
  • + *
  • /some[3]/node[2]/a
  • + *
  • ../../../another[3]/node
  • + *
+ * + *

Example

+ * + *
+ * Path a = new Path("/html/body/div[1]/table[2]/tr[3]/td/div");
+ * Path b = new Path("/html/body/div/table[2]/tr[6]/td/form");
+ *
+ * Path relativePath = a.relativeTo(b); // produces: "../../../tr[6]/td/form"
+ * Path c = a.apply(relativePath); // same as Path b.
+ * 
+ * + * @see PathTracker + * + * @author Joe Walnes + */ +public class Path { + + private final String[] chunks; + private transient String pathAsString; + private transient String pathExplicit; + private static final Path DOT = new Path(new String[] {"."}); + + public Path(String pathAsString) { + // String.split() too slow. StringTokenizer too crappy. + List result = new ArrayList(); + int currentIndex = 0; + int nextSeparator; + this.pathAsString = pathAsString; + while ((nextSeparator = pathAsString.indexOf('/', currentIndex)) != -1) { + // normalize explicit paths + result.add(normalize(pathAsString, currentIndex, nextSeparator)); + currentIndex = nextSeparator + 1; + } + result.add(normalize(pathAsString,currentIndex,pathAsString.length())); + String[] arr = new String[result.size()]; + result.toArray(arr); + chunks = arr; + } + + private String normalize(String s, int start, int end) { + if (end - start > 3 + && s.charAt(end-3) == '[' + && s.charAt(end-2) == '1' + && s.charAt(end-1) == ']') { + this.pathAsString = null; + return s.substring(start, end-3); + } else { + return s.substring(start, end); + } + + } + + public Path(String[] chunks) { + this.chunks = chunks; + } + + public String toString() { + if (pathAsString == null) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < chunks.length; i++) { + if (i > 0) buffer.append('/'); + buffer.append(chunks[i]); + } + pathAsString = buffer.toString(); + } + return pathAsString; + } + + public String explicit() { + if (pathExplicit == null) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < chunks.length; i++) { + if (i > 0) buffer.append('/'); + String chunk = chunks[i]; + buffer.append(chunk); + int length = chunk.length(); + if (length > 0) { + char c = chunk.charAt(length-1); + if (c != ']' && c != '.') { + buffer.append("[1]"); + } + } + } + pathExplicit = buffer.toString(); + } + return pathExplicit; + } + + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Path)) return false; + + final Path other = (Path) o; + if (chunks.length != other.chunks.length) return false; + for (int i = 0; i < chunks.length; i++) { + if (!chunks[i].equals(other.chunks[i])) return false; + } + + return true; + } + + public int hashCode() { + int result = 543645643; + for (int i = 0; i < chunks.length; i++) { + result = 29 * result + chunks[i].hashCode(); + } + return result; + } + + public Path relativeTo(Path that) { + int depthOfPathDivergence = depthOfPathDivergence(chunks, that.chunks); + String[] result = new String[chunks.length + that.chunks.length - 2 * depthOfPathDivergence]; + int count = 0; + + for (int i = depthOfPathDivergence; i < chunks.length; i++) { + result[count++] = ".."; + } + for (int j = depthOfPathDivergence; j < that.chunks.length; j++) { + result[count++] = that.chunks[j]; + } + + if (count == 0) { + return DOT; + } else { + return new Path(result); + } + } + + private int depthOfPathDivergence(String[] path1, String[] path2) { + int minLength = Math.min(path1.length, path2.length); + for (int i = 0; i < minLength; i++) { + if (!path1[i].equals(path2[i])) { + return i; + } + } + return minLength; + } + + public Path apply(Path relativePath) { + FastStack absoluteStack = new FastStack(16); + + for (int i = 0; i < chunks.length; i++) { + absoluteStack.push(chunks[i]); + } + + for (int i = 0; i < relativePath.chunks.length; i++) { + String relativeChunk = relativePath.chunks[i]; + if (relativeChunk.equals("..")) { + absoluteStack.pop(); + } else if (!relativeChunk.equals(".")) { + absoluteStack.push(relativeChunk); + } + } + + String[] result = new String[absoluteStack.size()]; + for (int i = 0; i < result.length; i++) { + result[i] = (String) absoluteStack.get(i); + } + + return new Path(result); + } + + public boolean isAncestor(Path child) { + if (child == null || child.chunks.length < chunks.length) { + return false; + } + for (int i = 0; i < chunks.length; i++) { + if (!chunks[i].equals(child.chunks[i])) { + return false; + } + } + return true; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/path/PathTracker.java b/xstream/src/java/com/thoughtworks/xstream/io/path/PathTracker.java new file mode 100644 index 0000000..76b25cd --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/path/PathTracker.java @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.path; + +import java.util.HashMap; +import java.util.Map; + +/** + * Maintains the current {@link Path} as a stream is moved through. + * + *

Can be linked to a {@link com.thoughtworks.xstream.io.HierarchicalStreamWriter} or + * {@link com.thoughtworks.xstream.io.HierarchicalStreamReader} by wrapping them with a + * {@link PathTrackingWriter} or {@link PathTrackingReader}.

+ * + *

Example

+ * + *
+ * PathTracker tracker = new PathTracker();
+ * tracker.pushElement("table");
+ * tracker.pushElement("tr");
+ * tracker.pushElement("td");
+ * tracker.pushElement("form");
+ * tracker.popElement("form");
+ * tracker.popElement("td");
+ * tracker.pushElement("td");
+ * tracker.pushElement("div");
+ *
+ * Path path = tracker.getPath(); // returns "/table/tr/td[2]/div"
+ * 
+ * + * @see Path + * @see PathTrackingReader + * @see PathTrackingWriter + * + * @author Joe Walnes + */ +public class PathTracker { + + private int pointer; + private int capacity; + private String[] pathStack; + private Map[] indexMapStack; + + private Path currentPath; + + public PathTracker() { + this(16); + } + + /** + * @param initialCapacity Size of the initial stack of nodes (one level per depth in the tree). Note that this is + * only for optimizations - the stack will resize itself if it exceeds its capacity. If in doubt, + * use the other constructor. + */ + public PathTracker(int initialCapacity) { + this.capacity = Math.max(1, initialCapacity); + pathStack = new String[capacity]; + indexMapStack = new Map[capacity]; + } + + /** + * Notify the tracker that the stream has moved into a new element. + * + * @param name Name of the element + */ + public void pushElement(String name) { + if (pointer + 1 >= capacity) { + resizeStacks(capacity * 2); + } + pathStack[pointer] = name; + Map indexMap = indexMapStack[pointer]; + if (indexMap == null) { + indexMap = new HashMap(); + indexMapStack[pointer] = indexMap; + } + if (indexMap.containsKey(name)) { + indexMap.put(name, new Integer(((Integer) indexMap.get(name)).intValue() + 1)); + } else { + indexMap.put(name, new Integer(1)); + } + pointer++; + currentPath = null; + } + + /** + * Notify the tracker that the stream has moved out of an element. + */ + public void popElement() { + indexMapStack[pointer] = null; + pathStack[pointer] = null; + currentPath = null; + pointer--; + } + + /** + * Get the last path element from the stack. + * + * @return the name of the path element + * @since 1.4.2 + */ + public String peekElement() { + return peekElement(0); + } + + /** + * Get a path element from the stack. + * + * @param i path index + * @return the name of the path element + * @since 1.4.2 + * @throws ArrayIndexOutOfBoundsException if the index is >= 0 or <= -depth() + */ + public String peekElement(int i) { + if (i < -pointer || i > 0) { + throw new ArrayIndexOutOfBoundsException(i); + } + int idx = pointer + i - 1; + final String name; + Integer integer = ((Integer) indexMapStack[idx].get(pathStack[idx])); + int index = integer.intValue(); + if (index > 1) { + StringBuffer chunk = new StringBuffer(pathStack[idx].length() + 6); + chunk.append(pathStack[idx]).append('[').append(index).append(']'); + name = chunk.toString(); + } else { + name = pathStack[idx]; + } + return name; + } + + /** + * Get the depth of the stack. + * + * @return the stack depth + * @since 1.4.2 + */ + public int depth() { + return pointer; + } + + private void resizeStacks(int newCapacity) { + String[] newPathStack = new String[newCapacity]; + Map[] newIndexMapStack = new Map[newCapacity]; + int min = Math.min(capacity, newCapacity); + System.arraycopy(pathStack, 0, newPathStack, 0, min); + System.arraycopy(indexMapStack, 0, newIndexMapStack, 0, min); + pathStack = newPathStack; + indexMapStack = newIndexMapStack; + capacity = newCapacity; + } + + /** + * Current Path in stream. + */ + public Path getPath() { + if (currentPath == null) { + String[] chunks = new String[pointer + 1]; + chunks[0] = ""; + for (int i = -pointer; ++i <= 0; ) { + final String name = peekElement(i); + chunks[i + pointer] = name; + } + currentPath = new Path(chunks); + } + return currentPath; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/path/PathTrackingReader.java b/xstream/src/java/com/thoughtworks/xstream/io/path/PathTrackingReader.java new file mode 100644 index 0000000..b990a0e --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/path/PathTrackingReader.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. April 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.path; + +import com.thoughtworks.xstream.converters.ErrorWriter; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.ReaderWrapper; + +/** + * Wrapper for HierarchicalStreamReader that tracks the path (a subset of XPath) of the current node that is being read. + * + * @see PathTracker + * @see Path + * + * @author Joe Walnes + */ +public class PathTrackingReader extends ReaderWrapper { + + private final PathTracker pathTracker; + + public PathTrackingReader(HierarchicalStreamReader reader, PathTracker pathTracker) { + super(reader); + this.pathTracker = pathTracker; + pathTracker.pushElement(getNodeName()); + } + + public void moveDown() { + super.moveDown(); + pathTracker.pushElement(getNodeName()); + } + + public void moveUp() { + super.moveUp(); + pathTracker.popElement(); + } + + public void appendErrors(ErrorWriter errorWriter) { + errorWriter.add("path", pathTracker.getPath().toString()); + super.appendErrors(errorWriter); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/path/PathTrackingWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/path/PathTrackingWriter.java new file mode 100644 index 0000000..2c3a716 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/path/PathTrackingWriter.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.path; + +import com.thoughtworks.xstream.io.AbstractWriter; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.WriterWrapper; + +/** + * Wrapper for HierarchicalStreamWriter that tracks the path (a subset of XPath) of the current node that is being written. + * + * @see PathTracker + * @see Path + * + * @author Joe Walnes + */ +public class PathTrackingWriter extends WriterWrapper { + + private final PathTracker pathTracker; + private final boolean isNameEncoding; + + public PathTrackingWriter(HierarchicalStreamWriter writer, PathTracker pathTracker) { + super(writer); + this.isNameEncoding = writer.underlyingWriter() instanceof AbstractWriter; + this.pathTracker = pathTracker; + } + + public void startNode(String name) { + pathTracker.pushElement(isNameEncoding ? ((AbstractWriter)wrapped.underlyingWriter()).encodeNode(name) : name); + super.startNode(name); + } + + public void startNode(String name, Class clazz) { + pathTracker.pushElement(isNameEncoding ? ((AbstractWriter)wrapped.underlyingWriter()).encodeNode(name) : name); + super.startNode(name, clazz); + } + + public void endNode() { + super.endNode(); + pathTracker.popElement(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/path/package.html b/xstream/src/java/com/thoughtworks/xstream/io/path/package.html new file mode 100644 index 0000000..86d4a4b --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/path/package.html @@ -0,0 +1,43 @@ + + + + + +

Library for tracking paths of nodes in documents using a subset of XPath. This subset of XPath is just enough + for XStream to be able to use XPath expressions to represent references across the object graph, while still remaining + very quick.

+ +

The Path class represents a path to a single node in the tree. + Two absolute paths can also be compared to calculate the relative path between them. + A relative path can be applied to an absolute path to calculate another absolute path.

+ +

A PathTracker can be linked to a + HierarchicalStreamWriter or + HierarchicalStreamReader and expose the path of wherever the node + is currently positioned. This is done by wrapping the HierarchicalStreamWriter/HierarchicalStreamReader instances + with a PathTrackingWriter or PathTrackingReader.

+ +

Note that the paths produced are XPath compliant, so can be read by other XPath engines. The following are examples of path + expressions that the Path object supports:

+ +
    +
  • /
  • +
  • /some/node
  • +
  • /a/b/c/b/a
  • +
  • /some[3]/node[2]/a
  • +
  • ../../../another[3]/node
  • +
+ + + + diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractDocumentReader.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractDocumentReader.java new file mode 100644 index 0000000..4cb562f --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractDocumentReader.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import java.util.Iterator; + +import com.thoughtworks.xstream.converters.ErrorWriter; +import com.thoughtworks.xstream.core.util.FastStack; +import com.thoughtworks.xstream.io.AttributeNameIterator; +import com.thoughtworks.xstream.io.naming.NameCoder; + +public abstract class AbstractDocumentReader extends AbstractXmlReader implements DocumentReader { + + private FastStack pointers = new FastStack(16); + private Object current; + + protected AbstractDocumentReader(Object rootElement) { + this(rootElement, new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + protected AbstractDocumentReader(Object rootElement, NameCoder nameCoder) { + super(nameCoder); + this.current = rootElement; + pointers.push(new Pointer()); + reassignCurrentElement(current); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link AbstractDocumentReader#AbstractDocumentReader(Object, NameCoder)} instead. + */ + protected AbstractDocumentReader(Object rootElement, XmlFriendlyReplacer replacer) { + this(rootElement, (NameCoder)replacer); + } + + protected abstract void reassignCurrentElement(Object current); + protected abstract Object getParent(); + protected abstract Object getChild(int index); + protected abstract int getChildCount(); + + private static class Pointer { + public int v; + } + + public boolean hasMoreChildren() { + Pointer pointer = (Pointer) pointers.peek(); + + if (pointer.v < getChildCount()) { + return true; + } else { + return false; + } + } + + public void moveUp() { + current = getParent(); + pointers.popSilently(); + reassignCurrentElement(current); + } + + public void moveDown() { + Pointer pointer = (Pointer) pointers.peek(); + pointers.push(new Pointer()); + + current = getChild(pointer.v); + + pointer.v++; + reassignCurrentElement(current); + } + + public Iterator getAttributeNames() { + return new AttributeNameIterator(this); + } + + public void appendErrors(ErrorWriter errorWriter) { + } + + public Object getCurrent() { + return this.current; + } + + public void close() { + // don't need to do anything + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractDocumentWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractDocumentWriter.java new file mode 100644 index 0000000..f13f56a --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractDocumentWriter.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 18. October 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.core.util.FastStack; +import com.thoughtworks.xstream.io.naming.NameCoder; + +import java.util.ArrayList; +import java.util.List; + + +/** + * A generic {@link com.thoughtworks.xstream.io.HierarchicalStreamWriter} for DOM writer + * implementations. The implementation manages a list of top level DOM nodes. Every time the + * last node is closed on the node stack, the next started node is added to the list. This list + * can be retrieved using the {@link DocumentWriter#getTopLevelNodes()} method. + * + * @author Laurent Bihanic + * @author Jörg Schaible + * @since 1.2.1 + */ +public abstract class AbstractDocumentWriter extends AbstractXmlWriter implements + DocumentWriter { + + private final List result = new ArrayList(); + private final FastStack nodeStack = new FastStack(16); + + /** + * Constructs an AbstractDocumentWriter. + * + * @param container the top level container for the nodes to create (may be + * null) + * @param nameCoder the object that creates XML-friendly names + * @since 1.4 + */ + public AbstractDocumentWriter(final Object container, final NameCoder nameCoder) { + super(nameCoder); + if (container != null) { + nodeStack.push(container); + result.add(container); + } + } + + /** + * Constructs an AbstractDocumentWriter. + * + * @param container the top level container for the nodes to create (may be + * null) + * @param replacer the object that creates XML-friendly names + * @since 1.2.1 + * @deprecated As of 1.4 use + * {@link AbstractDocumentWriter#AbstractDocumentWriter(Object, NameCoder)} + * instead. + */ + public AbstractDocumentWriter(final Object container, final XmlFriendlyReplacer replacer) { + this(container, (NameCoder)replacer); + } + + public final void startNode(final String name) { + final Object node = createNode(name); + nodeStack.push(node); + } + + /** + * Create a node. The provided node name is not yet XML friendly. If {@link #getCurrent()} + * returns null the node is a top level node. + * + * @param name the node name + * @return the new node + * @since 1.2.1 + */ + protected abstract Object createNode(String name); + + public final void endNode() { + endNodeInternally(); + final Object node = nodeStack.pop(); + if (nodeStack.size() == 0) { + result.add(node); + } + } + + /** + * Called when a node ends. Hook for derived implementations. + * + * @since 1.2.1 + */ + public void endNodeInternally() { + } + + /** + * @since 1.2.1 + */ + protected final Object getCurrent() { + return nodeStack.peek(); + } + + public List getTopLevelNodes() { + return result; + } + + public void flush() { + // don't need to do anything + } + + public void close() { + // don't need to do anything + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractPullReader.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractPullReader.java new file mode 100644 index 0000000..be2d247 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractPullReader.java @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2010, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import java.util.Iterator; + +import com.thoughtworks.xstream.core.util.FastStack; +import com.thoughtworks.xstream.io.AttributeNameIterator; +import com.thoughtworks.xstream.io.naming.NameCoder; + +/** + * Base class that contains common functionality across HierarchicalStreamReader implementations + * that need to read from a pull parser. + * + * @author Joe Walnes + * @author James Strachan + */ +public abstract class AbstractPullReader extends AbstractXmlReader { + + protected static final int START_NODE = 1; + protected static final int END_NODE = 2; + protected static final int TEXT = 3; + protected static final int COMMENT = 4; + protected static final int OTHER = 0; + + private final FastStack elementStack = new FastStack(16); + private final FastStack pool = new FastStack(16); + + private final FastStack lookahead = new FastStack(4); + private final FastStack lookback = new FastStack(4); + private boolean marked; + + private static class Event { + int type; + String value; + } + + /** + * @since 1.4 + */ + protected AbstractPullReader(NameCoder nameCoder) { + super(nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link AbstractPullReader#AbstractPullReader(NameCoder)} instead + */ + protected AbstractPullReader(XmlFriendlyReplacer replacer) { + this((NameCoder)replacer); + } + + + /** + * Pull the next event from the stream. + * + *

This MUST return {@link #START_NODE}, {@link #END_NODE}, {@link #TEXT}, {@link #COMMENT}, + * {@link #OTHER} or throw {@link com.thoughtworks.xstream.io.StreamException}.

+ * + *

The underlying pull parser will most likely return its own event types. These must be + * mapped to the appropriate events.

+ */ + protected abstract int pullNextEvent(); + + /** + * Pull the name of the current element from the stream. + */ + protected abstract String pullElementName(); + + /** + * Pull the contents of the current text node from the stream. + */ + protected abstract String pullText(); + + public boolean hasMoreChildren() { + mark(); + while (true) { + switch (readEvent().type) { + case START_NODE: + reset(); + return true; + case END_NODE: + reset(); + return false; + default: + continue; + } + } + } + + public void moveDown() { + int currentDepth = elementStack.size(); + while (elementStack.size() <= currentDepth) { + move(); + if (elementStack.size() < currentDepth) { + throw new RuntimeException(); // sanity check + } + } + } + + public void moveUp() { + int currentDepth = elementStack.size(); + while (elementStack.size() >= currentDepth) { + move(); + } + } + + private void move() { + final Event event = readEvent(); + pool.push(event); + switch (event.type) { + case START_NODE: + elementStack.push(pullElementName()); + break; + case END_NODE: + elementStack.pop(); + break; + } + } + + private Event readEvent() { + if (marked) { + if (lookback.hasStuff()) { + return (Event) lookahead.push(lookback.pop()); + } else { + return (Event) lookahead.push(readRealEvent()); + } + } else { + if (lookback.hasStuff()) { + return (Event) lookback.pop(); + } else { + return readRealEvent(); + } + } + } + + private Event readRealEvent() { + Event event = pool.hasStuff() ? (Event)pool.pop() : new Event(); + event.type = pullNextEvent(); + if (event.type == TEXT) { + event.value = pullText(); + } else if (event.type == START_NODE) { + event.value = pullElementName(); + } else { + event.value = null; + } + return event; + } + + public void mark() { + marked = true; + } + + public void reset() { + while(lookahead.hasStuff()) { + lookback.push(lookahead.pop()); + } + marked = false; + } + + public String getValue() { + // we should collapse together any text which + // contains comments + + // lets only use a string buffer when we get 2 strings + // to avoid copying strings + String last = null; + StringBuffer buffer = null; + + mark(); + Event event = readEvent(); + while (true) { + if (event.type == TEXT) { + String text = event.value; + if (text != null && text.length() > 0) { + if (last == null) { + last = text; + } else { + if (buffer == null) { + buffer = new StringBuffer(last); + } + buffer.append(text); + } + } + } else if (event.type != COMMENT) { + break; + } + event = readEvent(); + } + reset(); + if (buffer != null) { + return buffer.toString(); + } else { + return (last == null) ? "" : last; + } + } + + public Iterator getAttributeNames() { + return new AttributeNameIterator(this); + } + + public String getNodeName() { + return unescapeXmlName((String) elementStack.peek()); + } + + public String peekNextChild() { + mark(); + while (true) { + Event ev = readEvent(); + switch (ev.type) { + case START_NODE: + reset(); + return ev.value; + case END_NODE: + reset(); + return null; + default: + continue; + } + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractXmlDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractXmlDriver.java new file mode 100644 index 0000000..8aa15be --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractXmlDriver.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 28. May 2005 by Mauro Talevi + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.AbstractDriver; +import com.thoughtworks.xstream.io.naming.NameCoder; + + +/** + * Base class for HierarchicalStreamDrivers to use xml-based HierarchicalStreamReader and + * HierarchicalStreamWriter. + * + * @author Mauro Talevi + * @author Jörg Schaible + * @since 1.2 + * @deprecated As of 1.4 + */ +public abstract class AbstractXmlDriver extends AbstractDriver { + + /** + * Creates a AbstractXmlFriendlyDriver with default XmlFriendlyReplacer + * + * @deprecated As of 1.4 + */ + public AbstractXmlDriver() { + this(new XmlFriendlyNameCoder()); + } + + /** + * Creates a AbstractXmlFriendlyDriver with default XmlFriendlyReplacer + * @since 1.4 + */ + public AbstractXmlDriver(NameCoder nameCoder) { + super(nameCoder); + } + + /** + * Creates a AbstractXmlFriendlyDriver with custom XmlFriendlyReplacer + * + * @param replacer the XmlFriendlyReplacer + * @deprecated As of 1.4 + */ + public AbstractXmlDriver(XmlFriendlyReplacer replacer) { + this((NameCoder)replacer); + } + + /** + * @deprecated As of 1.4 + */ + protected XmlFriendlyReplacer xmlFriendlyReplacer() { + NameCoder nameCoder = getNameCoder(); + return nameCoder instanceof XmlFriendlyReplacer ? (XmlFriendlyReplacer)nameCoder : null; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractXmlReader.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractXmlReader.java new file mode 100644 index 0000000..40a6c7c --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractXmlReader.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. June 2006 by Mauro Talevi + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.AbstractReader; +import com.thoughtworks.xstream.io.naming.NameCoder; + + +/** + * Abstract base implementation of HierarchicalStreamReader that provides common functionality + * to all XML-based readers. + * + * @author Mauro Talevi + * @author Jörg Schaible + * @since 1.2 + * @deprecated As of 1.4, use {@link AbstractReader} instead. + */ +public abstract class AbstractXmlReader extends AbstractReader /* implements XmlFriendlyReader */ { + + protected AbstractXmlReader() { + this(new XmlFriendlyNameCoder()); + } + + /** + * @deprecated As of 1.4, use {@link AbstractReader} instead. + */ + protected AbstractXmlReader(XmlFriendlyReplacer replacer) { + this((NameCoder)replacer); + } + + protected AbstractXmlReader(NameCoder nameCoder) { + super(nameCoder); + } + + /** + * Unescapes XML-friendly name (node or attribute) + * + * @param name the escaped XML-friendly name + * @return An unescaped name with original characters + * @deprecated As of 1.4, use {@link #decodeNode(String)} or {@link #decodeAttribute(String)} instead. + */ + public String unescapeXmlName(String name) { + return decodeNode(name); + } + + /** + * Escapes XML-unfriendly name (node or attribute) + * + * @param name the unescaped XML-unfriendly name + * @return An escaped name with original characters + * @deprecated As of 1.4, use {@link AbstractReader} instead. + */ + protected String escapeXmlName(String name) { + return encodeNode(name); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractXmlWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractXmlWriter.java new file mode 100644 index 0000000..054ea2e --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractXmlWriter.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. June 2006 by Mauro Talevi + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.AbstractWriter; +import com.thoughtworks.xstream.io.naming.NameCoder; + +/** + * Abstract base implementation of HierarchicalStreamWriter that provides common functionality + * to all XML-based writers. + * + * @author Mauro Talevi + * @author Jörg Schaible + * @since 1.2 + * @deprecated As of 1.4 use {@link AbstractWriter} instead + */ +public abstract class AbstractXmlWriter extends AbstractWriter implements XmlFriendlyWriter { + + protected AbstractXmlWriter(){ + this(new XmlFriendlyNameCoder()); + } + + /** + * @deprecated As of 1.4 + */ + protected AbstractXmlWriter(XmlFriendlyReplacer replacer) { + this((NameCoder)replacer); + } + + protected AbstractXmlWriter(NameCoder nameCoder) { + super(nameCoder); + } + + /** + * Escapes XML name (node or attribute) to be XML-friendly + * + * @param name the unescaped XML name + * @return An escaped name with original characters replaced + * @deprecated As of 1.4 use {@link #encodeNode(String)} or {@link #encodeAttribute(String)} instead + */ + public String escapeXmlName(String name) { + return super.encodeNode(name); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractXppDomDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractXppDomDriver.java new file mode 100644 index 0000000..ef58dba --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractXppDomDriver.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. May 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.core.util.XmlHeaderAwareReader; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.naming.NameCoder; +import com.thoughtworks.xstream.io.xml.xppdom.XppDom; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.io.Writer; + +/** + * An abstract base class for a driver using an XPP DOM implementation. + * + * @author Joe Walnes + * @author Jörg Schaible + * @since 1.4 + */ +public abstract class AbstractXppDomDriver extends AbstractXmlDriver { + + /** + * Construct an AbstractXppDomDriver. + * + * @param nameCoder the replacer for XML friendly names + * @since 1.4 + */ + public AbstractXppDomDriver(NameCoder nameCoder) { + super(nameCoder); + } + + /** + * {@inheritDoc} + */ + public HierarchicalStreamReader createReader(Reader in) { + try { + XmlPullParser parser = createParser(); + parser.setInput(in); + return new XppDomReader(XppDom.build(parser), getNameCoder()); + } catch (XmlPullParserException e) { + throw new StreamException(e); + } catch (IOException e) { + throw new StreamException(e); + } + } + + /** + * {@inheritDoc} + */ + public HierarchicalStreamReader createReader(InputStream in) { + try { + return createReader(new XmlHeaderAwareReader(in)); + } catch (UnsupportedEncodingException e) { + throw new StreamException(e); + } catch (IOException e) { + throw new StreamException(e); + } + } + + /** + * {@inheritDoc} + */ + public HierarchicalStreamWriter createWriter(Writer out) { + return new PrettyPrintWriter(out, getNameCoder()); + } + + /** + * {@inheritDoc} + */ + public HierarchicalStreamWriter createWriter(OutputStream out) { + return createWriter(new OutputStreamWriter(out)); + } + + /** + * Create the parser of the XPP implementation. + + * @throws XmlPullParserException if the parser cannot be created + * @since 1.4 + */ + protected abstract XmlPullParser createParser() throws XmlPullParserException; +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractXppDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractXppDriver.java new file mode 100644 index 0000000..efcd59a --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/AbstractXppDriver.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. April 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.core.util.XmlHeaderAwareReader; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.naming.NameCoder; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.io.Writer; + +/** + * An abstract base class for a driver using an XPP implementation. + * + * @author Joe Walnes + * @author Jörg Schaible + * @since 1.4 + */ +public abstract class AbstractXppDriver extends AbstractXmlDriver { + + /** + * Construct an AbstractXppDriver. + * + * @param nameCoder the replacer for XML friendly tag and attribute names + * @since 1.4 + */ + public AbstractXppDriver(NameCoder nameCoder) { + super(nameCoder); + } + + /** + * {@inheritDoc} + */ + public HierarchicalStreamReader createReader(Reader in) { + try { + return new XppReader(in, createParser(), getNameCoder()); + } catch (XmlPullParserException e) { + throw new StreamException("Cannot create XmlPullParser"); + } + } + + /** + * {@inheritDoc} + */ + public HierarchicalStreamReader createReader(InputStream in) { + try { + return createReader(new XmlHeaderAwareReader(in)); + } catch (UnsupportedEncodingException e) { + throw new StreamException(e); + } catch (IOException e) { + throw new StreamException(e); + } + } + + /** + * {@inheritDoc} + */ + public HierarchicalStreamWriter createWriter(Writer out) { + return new PrettyPrintWriter(out, getNameCoder()); + } + + /** + * {@inheritDoc} + */ + public HierarchicalStreamWriter createWriter(OutputStream out) { + return createWriter(new OutputStreamWriter(out)); + } + + /** + * Create the parser of the XPP implementation. + + * @throws XmlPullParserException if the parser cannot be created + * @since 1.4 + */ + protected abstract XmlPullParser createParser() throws XmlPullParserException; +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/BEAStaxDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/BEAStaxDriver.java new file mode 100644 index 0000000..3c67699 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/BEAStaxDriver.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. April 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.bea.xml.stream.MXParserFactory; +import com.bea.xml.stream.XMLOutputFactoryBase; +import com.thoughtworks.xstream.io.naming.NameCoder; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; + +/** + * A driver using the BEA StAX implementation. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class BEAStaxDriver extends StaxDriver { + + public BEAStaxDriver() { + super(); + } + + /** + * @deprecated As of 1.4.6 use {@link #BEAStaxDriver(QNameMap, NameCoder)} + */ + public BEAStaxDriver(QNameMap qnameMap, XmlFriendlyNameCoder nameCoder) { + super(qnameMap, nameCoder); + } + + /** + * @since 1.4.6 + */ + public BEAStaxDriver(QNameMap qnameMap, NameCoder nameCoder) { + super(qnameMap, nameCoder); + } + + public BEAStaxDriver(QNameMap qnameMap) { + super(qnameMap); + } + + /** + * @deprecated As of 1.4.6 use {@link #BEAStaxDriver(NameCoder)} + */ + public BEAStaxDriver(XmlFriendlyNameCoder nameCoder) { + super(nameCoder); + } + + /** + * @since 1.4.6 + */ + public BEAStaxDriver(NameCoder nameCoder) { + super(nameCoder); + } + + protected XMLInputFactory createInputFactory() { + return new MXParserFactory(); + } + + protected XMLOutputFactory createOutputFactory() { + return new XMLOutputFactoryBase(); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/CompactWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/CompactWriter.java new file mode 100644 index 0000000..18a9695 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/CompactWriter.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.naming.NameCoder; + +import java.io.Writer; + +public class CompactWriter extends PrettyPrintWriter { + + public CompactWriter(Writer writer) { + super(writer); + } + + /** + * @since 1.3 + */ + public CompactWriter(Writer writer, int mode) { + super(writer, mode); + } + + /** + * @since 1.4 + */ + public CompactWriter(Writer writer, NameCoder nameCoder) { + super(writer, nameCoder); + } + + /** + * @since 1.4 + */ + public CompactWriter(Writer writer, int mode, NameCoder nameCoder) { + super(writer, mode, nameCoder); + } + + /** + * @deprecated As of 1.4 use {@link CompactWriter#CompactWriter(Writer, NameCoder)} instead. + */ + public CompactWriter(Writer writer, XmlFriendlyReplacer replacer) { + super(writer, replacer); + } + + /** + * @since 1.3 + * @deprecated As of 1.4 use {@link CompactWriter#CompactWriter(Writer, int, NameCoder)} instead. + */ + public CompactWriter(Writer writer, int mode, XmlFriendlyReplacer replacer) { + super(writer, mode, replacer); + } + + protected void endOfLine() { + // override parent: don't write anything at end of line + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/DocumentReader.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/DocumentReader.java new file mode 100644 index 0000000..1747205 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/DocumentReader.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 18. October 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; + + +/** + * A generic interface for all {@link HierarchicalStreamReader} implementations reading a DOM. + * + * @author Jörg Schaible + * @since 1.2.1 + */ +public interface DocumentReader extends HierarchicalStreamReader { + + /** + * Retrieve the current processed node of the DOM. + * + * @return the current node + * @since 1.2.1 + */ + public Object getCurrent(); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/DocumentWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/DocumentWriter.java new file mode 100644 index 0000000..7435cfb --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/DocumentWriter.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 18. October 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import java.util.List; + +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + + +/** + * A generic interface for all {@link HierarchicalStreamWriter} implementations generating a + * DOM. + * + * @author Jörg Schaible + * @since 1.2.1 + */ +public interface DocumentWriter extends HierarchicalStreamWriter { + + /** + * Retrieve a {@link List} with the top elements. In the standard use case this list will + * only contain a single element. Additional elements can only occur, if + * {@link HierarchicalStreamWriter#startNode(String)} of the implementing + * {@link HierarchicalStreamWriter} was called multiple times with an empty node stack. Such + * a situation occurs calling + * {@link com.thoughtworks.xstream.XStream#marshal(Object, HierarchicalStreamWriter)} + * multiple times directly. + * + * @return a {@link List} with top nodes + * @since 1.2.1 + */ + List getTopLevelNodes(); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JDriver.java new file mode 100644 index 0000000..bce7cff --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JDriver.java @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import java.io.File; +import java.io.FilterWriter; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.Writer; +import java.net.URL; + +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.DocumentFactory; +import org.dom4j.io.OutputFormat; +import org.dom4j.io.SAXReader; +import org.dom4j.io.XMLWriter; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.naming.NameCoder; + +public class Dom4JDriver extends AbstractXmlDriver { + + private DocumentFactory documentFactory; + private OutputFormat outputFormat; + + public Dom4JDriver() { + this(new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + public Dom4JDriver(NameCoder nameCoder) { + this(new DocumentFactory(), OutputFormat.createPrettyPrint(), nameCoder); + outputFormat.setTrimText(false); + } + + public Dom4JDriver(DocumentFactory documentFactory, OutputFormat outputFormat) { + this(documentFactory, outputFormat, new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + public Dom4JDriver(DocumentFactory documentFactory, OutputFormat outputFormat, NameCoder nameCoder) { + super(nameCoder); + this.documentFactory = documentFactory; + this.outputFormat = outputFormat; + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link Dom4JDriver#Dom4JDriver(DocumentFactory, OutputFormat, NameCoder)} instead. + */ + public Dom4JDriver(DocumentFactory documentFactory, OutputFormat outputFormat, XmlFriendlyReplacer replacer) { + this(documentFactory, outputFormat, (NameCoder)replacer); + } + + + public DocumentFactory getDocumentFactory() { + return documentFactory; + } + + public void setDocumentFactory(DocumentFactory documentFactory) { + this.documentFactory = documentFactory; + } + + public OutputFormat getOutputFormat() { + return outputFormat; + } + + public void setOutputFormat(OutputFormat outputFormat) { + this.outputFormat = outputFormat; + } + + public HierarchicalStreamReader createReader(Reader text) { + try { + SAXReader reader = new SAXReader(); + Document document = reader.read(text); + return new Dom4JReader(document, getNameCoder()); + } catch (DocumentException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamReader createReader(InputStream in) { + try { + SAXReader reader = new SAXReader(); + Document document = reader.read(in); + return new Dom4JReader(document, getNameCoder()); + } catch (DocumentException e) { + throw new StreamException(e); + } + } + + /** + * @since 1.4 + */ + public HierarchicalStreamReader createReader(URL in) { + try { + SAXReader reader = new SAXReader(); + Document document = reader.read(in); + return new Dom4JReader(document, getNameCoder()); + } catch (DocumentException e) { + throw new StreamException(e); + } + } + + /** + * @since 1.4 + */ + public HierarchicalStreamReader createReader(File in) { + try { + SAXReader reader = new SAXReader(); + Document document = reader.read(in); + return new Dom4JReader(document, getNameCoder()); + } catch (DocumentException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamWriter createWriter(final Writer out) { + final HierarchicalStreamWriter[] writer = new HierarchicalStreamWriter[1]; + final FilterWriter filter = new FilterWriter(out){ + public void close() { + writer[0].close(); + } + }; + writer[0] = new Dom4JXmlWriter(new XMLWriter(filter, outputFormat), getNameCoder()); + return writer[0]; + } + + public HierarchicalStreamWriter createWriter(final OutputStream out) { + final Writer writer = new OutputStreamWriter(out); + return createWriter(writer); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JReader.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JReader.java new file mode 100644 index 0000000..8ffe174 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JReader.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.converters.ErrorWriter; +import com.thoughtworks.xstream.io.naming.NameCoder; +import java.util.List; +import org.dom4j.Document; +import org.dom4j.Element; + +public class Dom4JReader extends AbstractDocumentReader { + + private Element currentElement; + + public Dom4JReader(Element rootElement) { + this(rootElement, new XmlFriendlyNameCoder()); + } + + public Dom4JReader(Document document) { + this(document.getRootElement()); + } + + /** + * @since 1.4 + */ + public Dom4JReader(Element rootElement, NameCoder nameCoder) { + super(rootElement, nameCoder); + } + + /** + * @since 1.4 + */ + public Dom4JReader(Document document, NameCoder nameCoder) { + this(document.getRootElement(), nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link Dom4JReader#Dom4JReader(Element, NameCoder)} instead + */ + public Dom4JReader(Element rootElement, XmlFriendlyReplacer replacer) { + this(rootElement, (NameCoder)replacer); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link Dom4JReader#Dom4JReader(Document, NameCoder)} instead + */ + public Dom4JReader(Document document, XmlFriendlyReplacer replacer) { + this(document.getRootElement(), (NameCoder)replacer); + } + + public String getNodeName() { + return decodeNode(currentElement.getName()); + } + + public String getValue() { + return currentElement.getText(); + } + + public String getAttribute(String name) { + return currentElement.attributeValue(encodeAttribute(name)); + } + + public String getAttribute(int index) { + return currentElement.attribute(index).getValue(); + } + + public int getAttributeCount() { + return currentElement.attributeCount(); + } + + public String getAttributeName(int index) { + return decodeAttribute(currentElement.attribute(index).getQualifiedName()); + } + + protected Object getParent() { + return currentElement.getParent(); + } + + protected Object getChild(int index) { + return currentElement.elements().get(index); + } + + protected int getChildCount() { + return currentElement.elements().size(); + } + + protected void reassignCurrentElement(Object current) { + currentElement = (Element) current; + } + + public String peekNextChild() { + List list = currentElement.elements(); + if (null == list || list.isEmpty()) { + return null; + } + return decodeNode(((Element) list.get(0)).getName()); + } + + public void appendErrors(ErrorWriter errorWriter) { + errorWriter.add("xpath", currentElement.getPath()); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JWriter.java new file mode 100644 index 0000000..a981bad --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JWriter.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.naming.NameCoder; + +import org.dom4j.Branch; +import org.dom4j.DocumentFactory; +import org.dom4j.Element; + + +public class Dom4JWriter extends AbstractDocumentWriter { + + private final DocumentFactory documentFactory; + + /** + * @since 1.4 + */ + public Dom4JWriter( + final Branch root, final DocumentFactory factory, final NameCoder nameCoder) { + super(root, nameCoder); + documentFactory = factory; + } + + /** + * @since 1.4 + */ + public Dom4JWriter(final DocumentFactory factory, final NameCoder nameCoder) { + this(null, factory, nameCoder); + } + + /** + * @since 1.4 + */ + public Dom4JWriter(final Branch root, final NameCoder nameCoder) { + this(root, new DocumentFactory(), nameCoder); + } + + /** + * @since 1.2.1 + * @deprecated As of 1.4 use {@link Dom4JWriter#Dom4JWriter(Branch, DocumentFactory, NameCoder)} instead. + */ + public Dom4JWriter( + final Branch root, final DocumentFactory factory, final XmlFriendlyReplacer replacer) { + this(root, factory, (NameCoder)replacer); + } + + /** + * @since 1.2.1 + * @deprecated As of 1.4 use {@link Dom4JWriter#Dom4JWriter(DocumentFactory, NameCoder)} instead. + */ + public Dom4JWriter(final DocumentFactory factory, final XmlFriendlyReplacer replacer) { + this(null, factory, (NameCoder)replacer); + } + + /** + * @since 1.2.1 + */ + public Dom4JWriter(final DocumentFactory documentFactory) { + this(documentFactory, new XmlFriendlyNameCoder()); + } + + /** + * @since 1.2.1 + * @deprecated As of 1.4 use {@link Dom4JWriter#Dom4JWriter(Branch, NameCoder)} instead + */ + public Dom4JWriter(final Branch root, final XmlFriendlyReplacer replacer) { + this(root, new DocumentFactory(), (NameCoder)replacer); + } + + public Dom4JWriter(final Branch root) { + this(root, new DocumentFactory(), new XmlFriendlyNameCoder()); + } + + /** + * @since 1.2.1 + */ + public Dom4JWriter() { + this(new DocumentFactory(), new XmlFriendlyNameCoder()); + } + + protected Object createNode(final String name) { + final Element element = documentFactory.createElement(encodeNode(name)); + final Branch top = top(); + if (top != null) { + top().add(element); + } + return element; + } + + public void setValue(final String text) { + top().setText(text); + } + + public void addAttribute(final String key, final String value) { + ((Element)top()).addAttribute(encodeAttribute(key), value); + } + + private Branch top() { + return (Branch)getCurrent(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JXmlWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JXmlWriter.java new file mode 100644 index 0000000..f0c0f75 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/Dom4JXmlWriter.java @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.core.util.FastStack; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.naming.NameCoder; + +import org.dom4j.Element; +import org.dom4j.io.XMLWriter; +import org.dom4j.tree.DefaultElement; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +import java.io.IOException; + + +public class Dom4JXmlWriter extends AbstractXmlWriter { + + private final XMLWriter writer; + private final FastStack elementStack; + private AttributesImpl attributes; + private boolean started; + private boolean children; + + public Dom4JXmlWriter(XMLWriter writer) { + this(writer, new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + public Dom4JXmlWriter(XMLWriter writer, NameCoder nameCoder) { + super(nameCoder); + this.writer = writer; + this.elementStack = new FastStack(16); + this.attributes = new AttributesImpl(); + try { + writer.startDocument(); + } catch (SAXException e) { + throw new StreamException(e); + } + } + + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link Dom4JXmlWriter#Dom4JXmlWriter(XMLWriter, NameCoder)} instead. + */ + public Dom4JXmlWriter(XMLWriter writer, XmlFriendlyReplacer replacer) { + this(writer, (NameCoder)replacer); + } + + public void startNode(String name) { + if (elementStack.size() > 0) { + try { + startElement(); + } catch (SAXException e) { + throw new StreamException(e); + } + started = false; + } + elementStack.push(encodeNode(name)); + children = false; + } + + public void setValue(String text) { + char[] value = text.toCharArray(); + if (value.length > 0) { + try { + startElement(); + writer.characters(value, 0, value.length); + } catch (SAXException e) { + throw new StreamException(e); + } + children = true; + } + } + + public void addAttribute(String key, String value) { + attributes.addAttribute("", "", encodeAttribute(key), "string", value); + } + + public void endNode() { + try { + if (!children) { + Element element = new DefaultElement((String)elementStack.pop()); + for (int i = 0; i < attributes.getLength(); ++i) { + element.addAttribute(attributes.getQName(i), attributes.getValue(i)); + } + writer.write(element); + attributes.clear(); + children = true; // node just closed is child of node on top of stack + started = true; + } else { + startElement(); + writer.endElement("", "", (String)elementStack.pop()); + } + } catch (SAXException e) { + throw new StreamException(e); + } catch (IOException e) { + throw new StreamException(e); + } + } + + public void flush() { + try { + writer.flush(); + } catch (IOException e) { + throw new StreamException(e); + } + } + + public void close() { + try { + writer.endDocument(); + } catch (SAXException e) { + throw new StreamException(e); + } + } + + private void startElement() throws SAXException { + if (!started) { + writer.startElement("", "", (String)elementStack.peek(), attributes); + attributes.clear(); + started = true; + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/DomDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/DomDriver.java new file mode 100644 index 0000000..7b1709e --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/DomDriver.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.io.Writer; +import java.net.URL; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.FactoryConfigurationError; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.naming.NameCoder; + + +public class DomDriver extends AbstractXmlDriver { + + private final String encoding; + private final DocumentBuilderFactory documentBuilderFactory; + + /** + * Construct a DomDriver. + */ + public DomDriver() { + this(null); + } + + /** + * Construct a DomDriver with a specified encoding. The created DomReader will ignore any + * encoding attribute of the XML header though. + */ + public DomDriver(String encoding) { + this(encoding, new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + public DomDriver(String encoding, NameCoder nameCoder) { + super(nameCoder); + documentBuilderFactory = DocumentBuilderFactory.newInstance(); + this.encoding = encoding; + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link #DomDriver(String, NameCoder)} instead. + */ + public DomDriver(String encoding, XmlFriendlyReplacer replacer) { + this(encoding, (NameCoder)replacer); + } + + public HierarchicalStreamReader createReader(Reader in) { + return createReader(new InputSource(in)); + } + + public HierarchicalStreamReader createReader(InputStream in) { + return createReader(new InputSource(in)); + } + + public HierarchicalStreamReader createReader(URL in) { + return createReader(new InputSource(in.toExternalForm())); + } + + public HierarchicalStreamReader createReader(File in) { + return createReader(new InputSource(in.toURI().toASCIIString())); + } + + private HierarchicalStreamReader createReader(InputSource source) { + try { + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + if (encoding != null) { + source.setEncoding(encoding); + } + Document document = documentBuilder.parse(source); + return new DomReader(document, getNameCoder()); + } catch (FactoryConfigurationError e) { + throw new StreamException(e); + } catch (ParserConfigurationException e) { + throw new StreamException(e); + } catch (SAXException e) { + throw new StreamException(e); + } catch (IOException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamWriter createWriter(Writer out) { + return new PrettyPrintWriter(out, getNameCoder()); + } + + public HierarchicalStreamWriter createWriter(OutputStream out) { + try { + return createWriter(encoding != null + ? new OutputStreamWriter(out, encoding) + : new OutputStreamWriter(out)); + } catch (UnsupportedEncodingException e) { + throw new StreamException(e); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/DomReader.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/DomReader.java new file mode 100644 index 0000000..2774440 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/DomReader.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.naming.NameCoder; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; + +import java.util.ArrayList; +import java.util.List; + +public class DomReader extends AbstractDocumentReader { + + private Element currentElement; + private StringBuffer textBuffer; + private List childElements; + + public DomReader(Element rootElement) { + this(rootElement, new XmlFriendlyNameCoder()); + } + + public DomReader(Document document) { + this(document.getDocumentElement()); + } + + /** + * @since 1.4 + */ + public DomReader(Element rootElement, NameCoder nameCoder) { + super(rootElement, nameCoder); + textBuffer = new StringBuffer(); + } + + /** + * @since 1.4 + */ + public DomReader(Document document, NameCoder nameCoder) { + this(document.getDocumentElement(), nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link DomReader#DomReader(Element, NameCoder)} instead. + */ + public DomReader(Element rootElement, XmlFriendlyReplacer replacer) { + this(rootElement, (NameCoder)replacer); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link DomReader#DomReader(Document, NameCoder)} instead. + */ + public DomReader(Document document, XmlFriendlyReplacer replacer) { + this(document.getDocumentElement(), (NameCoder)replacer); + } + + public String getNodeName() { + return decodeNode(currentElement.getTagName()); + } + + public String getValue() { + NodeList childNodes = currentElement.getChildNodes(); + textBuffer.setLength(0); + int length = childNodes.getLength(); + for (int i = 0; i < length; i++) { + Node childNode = childNodes.item(i); + if (childNode instanceof Text) { + Text text = (Text) childNode; + textBuffer.append(text.getData()); + } + } + return textBuffer.toString(); + } + + public String getAttribute(String name) { + Attr attribute = currentElement.getAttributeNode(encodeAttribute(name)); + return attribute == null ? null : attribute.getValue(); + } + + public String getAttribute(int index) { + return ((Attr) currentElement.getAttributes().item(index)).getValue(); + } + + public int getAttributeCount() { + return currentElement.getAttributes().getLength(); + } + + public String getAttributeName(int index) { + return decodeAttribute(((Attr) currentElement.getAttributes().item(index)).getName()); + } + + protected Object getParent() { + return currentElement.getParentNode(); + } + + protected Object getChild(int index) { + return childElements.get(index); + } + + protected int getChildCount() { + return childElements.size(); + } + + protected void reassignCurrentElement(Object current) { + currentElement = (Element) current; + NodeList childNodes = currentElement.getChildNodes(); + childElements = new ArrayList(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node node = childNodes.item(i); + if (node instanceof Element) { + childElements.add(node); + } + } + } + + public String peekNextChild() { + NodeList childNodes = currentElement.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node node = childNodes.item(i); + if (node instanceof Element) { + return decodeNode(((Element) node).getTagName()); + } + } + return null; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/DomWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/DomWriter.java new file mode 100644 index 0000000..9c65e7a --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/DomWriter.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 02. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.naming.NameCoder; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + + +/** + * @author Michael Kopp + */ +public class DomWriter extends AbstractDocumentWriter { + + private final Document document; + private boolean hasRootElement; + + public DomWriter(final Document document) { + this(document, new XmlFriendlyNameCoder()); + } + + public DomWriter(final Element rootElement) { + this(rootElement, new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + public DomWriter(final Document document, final NameCoder nameCoder) { + this(document.getDocumentElement(), document, nameCoder); + } + + /** + * @since 1.4 + */ + public DomWriter(final Element element, final Document document, final NameCoder nameCoder) { + super(element, nameCoder); + this.document = document; + hasRootElement = document.getDocumentElement() != null; + } + + /** + * @since 1.4 + */ + public DomWriter(final Element rootElement, final NameCoder nameCoder) { + this(rootElement, rootElement.getOwnerDocument(), nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link DomWriter#DomWriter(Document, NameCoder)} instead. + */ + public DomWriter(final Document document, final XmlFriendlyReplacer replacer) { + this(document.getDocumentElement(), document, (NameCoder)replacer); + } + + /** + * @since 1.2.1 + * @deprecated As of 1.4 use {@link DomWriter#DomWriter(Element, Document, NameCoder)} instead. + */ + public DomWriter(final Element element, final Document document, final XmlFriendlyReplacer replacer) { + this(element, document, (NameCoder)replacer); + } + + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link DomWriter#DomWriter(Element, NameCoder)} instead. + */ + public DomWriter(final Element rootElement, final XmlFriendlyReplacer replacer) { + this(rootElement, rootElement.getOwnerDocument(), (NameCoder)replacer); + } + + protected Object createNode(final String name) { + final Element child = document.createElement(encodeNode(name)); + final Element top = top(); + if (top != null) { + top().appendChild(child); + } else if (!hasRootElement) { + document.appendChild(child); + hasRootElement = true; + } + return child; + } + + public void addAttribute(final String name, final String value) { + top().setAttribute(encodeAttribute(name), value); + } + + public void setValue(final String text) { + top().appendChild(document.createTextNode(text)); + } + + private Element top() { + return (Element)getCurrent(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/JDom2Driver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/JDom2Driver.java new file mode 100644 index 0000000..876630e --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/JDom2Driver.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. June 2012 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.Writer; +import java.net.URL; + +import org.jdom2.Document; +import org.jdom2.JDOMException; +import org.jdom2.input.SAXBuilder; + +import com.thoughtworks.xstream.io.AbstractDriver; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.naming.NameCoder; + +/** + * @since 1.4.5 + */ +public class JDom2Driver extends AbstractDriver { + + public JDom2Driver() { + super(new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4.5 + */ + public JDom2Driver(NameCoder nameCoder) { + super(nameCoder); + } + + public HierarchicalStreamReader createReader(Reader reader) { + try { + SAXBuilder builder = new SAXBuilder(); + Document document = builder.build(reader); + return new JDom2Reader(document, getNameCoder()); + } catch (IOException e) { + throw new StreamException(e); + } catch (JDOMException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamReader createReader(InputStream in) { + try { + SAXBuilder builder = new SAXBuilder(); + Document document = builder.build(in); + return new JDom2Reader(document, getNameCoder()); + } catch (IOException e) { + throw new StreamException(e); + } catch (JDOMException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamReader createReader(URL in) { + try { + SAXBuilder builder = new SAXBuilder(); + Document document = builder.build(in); + return new JDom2Reader(document, getNameCoder()); + } catch (IOException e) { + throw new StreamException(e); + } catch (JDOMException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamReader createReader(File in) { + try { + SAXBuilder builder = new SAXBuilder(); + Document document = builder.build(in); + return new JDom2Reader(document, getNameCoder()); + } catch (IOException e) { + throw new StreamException(e); + } catch (JDOMException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamWriter createWriter(Writer out) { + return new PrettyPrintWriter(out, getNameCoder()); + } + + public HierarchicalStreamWriter createWriter(OutputStream out) { + return new PrettyPrintWriter(new OutputStreamWriter(out)); + } +} + diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/JDom2Reader.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/JDom2Reader.java new file mode 100644 index 0000000..65cc7fd --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/JDom2Reader.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. June 2012 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.naming.NameCoder; +import java.util.List; +import org.jdom2.Document; +import org.jdom2.Element; + +/** + * @since 1.4.5 + */ +public class JDom2Reader extends AbstractDocumentReader { + + private Element currentElement; + + /** + * @since 1.4.5 + */ + public JDom2Reader(Element root) { + super(root); + } + + /** + * @since 1.4.5 + */ + public JDom2Reader(Document document) { + super(document.getRootElement()); + } + + /** + * @since 1.4.5 + */ + public JDom2Reader(Element root, NameCoder nameCoder) { + super(root, nameCoder); + } + + /** + * @since 1.4.5 + */ + public JDom2Reader(Document document, NameCoder nameCoder) { + super(document.getRootElement(), nameCoder); + } + + protected void reassignCurrentElement(Object current) { + currentElement = (Element) current; + } + + protected Object getParent() { + return currentElement.getParentElement(); + } + + protected Object getChild(int index) { + return currentElement.getChildren().get(index); + } + + protected int getChildCount() { + return currentElement.getChildren().size(); + } + + public String getNodeName() { + return decodeNode(currentElement.getName()); + } + + public String getValue() { + return currentElement.getText(); + } + + public String getAttribute(String name) { + return currentElement.getAttributeValue(encodeAttribute(name)); + } + + public String getAttribute(int index) { + return currentElement.getAttributes().get(index).getValue(); + } + + public int getAttributeCount() { + return currentElement.getAttributes().size(); + } + + public String getAttributeName(int index) { + return decodeAttribute(currentElement.getAttributes().get(index).getQualifiedName()); + } + + public String peekNextChild() { + List list = currentElement.getChildren(); + if (null == list || list.isEmpty()) { + return null; + } + return decodeNode(((Element) list.get(0)).getName()); + } +} + diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/JDom2Writer.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/JDom2Writer.java new file mode 100644 index 0000000..7c9047f --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/JDom2Writer.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. June 2012 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.naming.NameCoder; + +import org.jdom2.DefaultJDOMFactory; +import org.jdom2.Element; +import org.jdom2.JDOMFactory; + + +/** + * @since 1.4.5 + */ +public class JDom2Writer extends AbstractDocumentWriter { + + private final JDOMFactory documentFactory; + + /** + * @since 1.4.5 + */ + public JDom2Writer( + final Element container, final JDOMFactory factory, + final NameCoder nameCoder) { + super(container, nameCoder); + documentFactory = factory; + } + + /** + * @since 1.4.5 + */ + public JDom2Writer(final Element container, final JDOMFactory factory) { + this(container, factory, new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4.5 + */ + public JDom2Writer(final JDOMFactory factory, final NameCoder nameCoder) { + this(null, factory, nameCoder); + } + + /** + * @since 1.4.5 + */ + public JDom2Writer(final JDOMFactory factory) { + this(null, factory); + } + + /** + * @since 1.4.5 + */ + public JDom2Writer(final Element container, final NameCoder nameCoder) { + this(container, new DefaultJDOMFactory(), nameCoder); + } + + /** + * @since 1.4.5 + */ + public JDom2Writer(final Element container) { + this(container, new DefaultJDOMFactory()); + } + + /** + * @since 1.4.5 + */ + public JDom2Writer() { + this(new DefaultJDOMFactory()); + } + + protected Object createNode(final String name) { + final Element element = documentFactory.element(encodeNode(name)); + final Element parent = top(); + if (parent != null) { + parent.addContent(element); + } + return element; + } + + public void setValue(final String text) { + top().addContent(documentFactory.text(text)); + } + + public void addAttribute(final String key, final String value) { + top().setAttribute(documentFactory.attribute(encodeAttribute(key), value)); + } + + /** + * @since 1.4.5 + */ + private Element top() { + return (Element)getCurrent(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/JDomDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/JDomDriver.java new file mode 100644 index 0000000..6bc3255 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/JDomDriver.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.Writer; +import java.net.URL; + +import org.jdom.Document; +import org.jdom.JDOMException; +import org.jdom.input.SAXBuilder; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.naming.NameCoder; + +/** + * @author Laurent Bihanic + */ +public class JDomDriver extends AbstractXmlDriver { + + public JDomDriver() { + super(new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + public JDomDriver(NameCoder nameCoder) { + super(nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link JDomDriver#JDomDriver(NameCoder)} instead. + */ + public JDomDriver(XmlFriendlyReplacer replacer) { + this((NameCoder)replacer); + } + + public HierarchicalStreamReader createReader(Reader reader) { + try { + SAXBuilder builder = new SAXBuilder(); + Document document = builder.build(reader); + return new JDomReader(document, getNameCoder()); + } catch (IOException e) { + throw new StreamException(e); + } catch (JDOMException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamReader createReader(InputStream in) { + try { + SAXBuilder builder = new SAXBuilder(); + Document document = builder.build(in); + return new JDomReader(document, getNameCoder()); + } catch (IOException e) { + throw new StreamException(e); + } catch (JDOMException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamReader createReader(URL in) { + try { + SAXBuilder builder = new SAXBuilder(); + Document document = builder.build(in); + return new JDomReader(document, getNameCoder()); + } catch (IOException e) { + throw new StreamException(e); + } catch (JDOMException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamReader createReader(File in) { + try { + SAXBuilder builder = new SAXBuilder(); + Document document = builder.build(in); + return new JDomReader(document, getNameCoder()); + } catch (IOException e) { + throw new StreamException(e); + } catch (JDOMException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamWriter createWriter(Writer out) { + return new PrettyPrintWriter(out, getNameCoder()); + } + + public HierarchicalStreamWriter createWriter(OutputStream out) { + return new PrettyPrintWriter(new OutputStreamWriter(out)); + } + +} + diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/JDomReader.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/JDomReader.java new file mode 100644 index 0000000..f84478c --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/JDomReader.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.naming.NameCoder; +import java.util.List; +import org.jdom.Attribute; +import org.jdom.Document; +import org.jdom.Element; + +/** + * @author Laurent Bihanic + */ +public class JDomReader extends AbstractDocumentReader { + + private Element currentElement; + + public JDomReader(Element root) { + super(root); + } + + public JDomReader(Document document) { + super(document.getRootElement()); + } + + /** + * @since 1.4 + */ + public JDomReader(Element root, NameCoder nameCoder) { + super(root, nameCoder); + } + + /** + * @since 1.4 + */ + public JDomReader(Document document, NameCoder nameCoder) { + super(document.getRootElement(), nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link JDomReader#JDomReader(Element, NameCoder)} instead. + */ + public JDomReader(Element root, XmlFriendlyReplacer replacer) { + this(root, (NameCoder)replacer); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link JDomReader#JDomReader(Document, NameCoder)} instead. + */ + public JDomReader(Document document, XmlFriendlyReplacer replacer) { + this(document.getRootElement(), (NameCoder)replacer); + } + + protected void reassignCurrentElement(Object current) { + currentElement = (Element) current; + } + + protected Object getParent() { + // JDOM 1.0: + return currentElement.getParentElement(); + + // JDOM b10: + // Parent parent = currentElement.getParent(); + // return (parent instanceof Element) ? (Element)parent : null; + + // JDOM b9 and earlier: + // return currentElement.getParent(); + } + + protected Object getChild(int index) { + return currentElement.getChildren().get(index); + } + + protected int getChildCount() { + return currentElement.getChildren().size(); + } + + public String getNodeName() { + return decodeNode(currentElement.getName()); + } + + public String getValue() { + return currentElement.getText(); + } + + public String getAttribute(String name) { + return currentElement.getAttributeValue(encodeAttribute(name)); + } + + public String getAttribute(int index) { + return ((Attribute) currentElement.getAttributes().get(index)).getValue(); + } + + public int getAttributeCount() { + return currentElement.getAttributes().size(); + } + + public String getAttributeName(int index) { + return decodeAttribute(((Attribute) currentElement.getAttributes().get(index)).getQualifiedName()); + } + + public String peekNextChild() { + List list = currentElement.getChildren(); + if (null == list || list.isEmpty()) { + return null; + } + return decodeNode(((Element) list.get(0)).getName()); + } + +} + diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/JDomWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/JDomWriter.java new file mode 100644 index 0000000..6759609 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/JDomWriter.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.naming.NameCoder; + +import org.jdom.DefaultJDOMFactory; +import org.jdom.Element; +import org.jdom.JDOMFactory; + + +/** + * @author Laurent Bihanic + */ +public class JDomWriter extends AbstractDocumentWriter { + + private final JDOMFactory documentFactory; + + /** + * @since 1.4 + */ + public JDomWriter( + final Element container, final JDOMFactory factory, + final NameCoder nameCoder) { + super(container, nameCoder); + documentFactory = factory; + } + + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link JDomWriter#JDomWriter(Element, JDOMFactory, NameCoder)} instead. + */ + public JDomWriter( + final Element container, final JDOMFactory factory, + final XmlFriendlyReplacer replacer) { + this(container, factory, (NameCoder)replacer); + } + + public JDomWriter(final Element container, final JDOMFactory factory) { + this(container, factory, new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + public JDomWriter(final JDOMFactory factory, final NameCoder nameCoder) { + this(null, factory, nameCoder); + } + + /** + * @since 1.2.1 + * @deprecated As of 1.4 use {@link JDomWriter#JDomWriter(JDOMFactory, NameCoder)} instead. + */ + public JDomWriter(final JDOMFactory factory, final XmlFriendlyReplacer replacer) { + this(null, factory, (NameCoder)replacer); + } + + public JDomWriter(final JDOMFactory factory) { + this(null, factory); + } + + /** + * @since 1.4 + */ + public JDomWriter(final Element container, final NameCoder nameCoder) { + this(container, new DefaultJDOMFactory(), nameCoder); + } + + /** + * @since 1.2.1 + * @deprecated As of 1.4 use {@link JDomWriter#JDomWriter(Element, NameCoder)} instead. + */ + public JDomWriter(final Element container, final XmlFriendlyReplacer replacer) { + this(container, new DefaultJDOMFactory(), (NameCoder)replacer); + } + + public JDomWriter(final Element container) { + this(container, new DefaultJDOMFactory()); + } + + public JDomWriter() { + this(new DefaultJDOMFactory()); + } + + protected Object createNode(final String name) { + final Element element = documentFactory.element(encodeNode(name)); + final Element parent = top(); + if (parent != null) { + parent.addContent(element); + } + return element; + } + + public void setValue(final String text) { + top().addContent(documentFactory.text(text)); + } + + public void addAttribute(final String key, final String value) { + top().setAttribute(documentFactory.attribute(encodeAttribute(key), value)); + } + + private Element top() { + return (Element)getCurrent(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/KXml2DomDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/KXml2DomDriver.java new file mode 100644 index 0000000..0dd889f --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/KXml2DomDriver.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. May 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.HierarchicalStreamDriver; +import com.thoughtworks.xstream.io.naming.NameCoder; + +import org.kxml2.io.KXmlParser; +import org.xmlpull.v1.XmlPullParser; + +/** + * A {@link HierarchicalStreamDriver} for XPP DOM using the kXML2 parser. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class KXml2DomDriver extends AbstractXppDomDriver { + + /** + * Construct an KXml2DomDriver. + * + * @since 1.4 + */ + public KXml2DomDriver() { + super(new XmlFriendlyNameCoder()); + } + + /** + * Construct a KXml2DomDriver. + * + * @param nameCoder the replacer for XML friendly names + * @since 1.4 + */ + public KXml2DomDriver(NameCoder nameCoder) { + super(nameCoder); + } + + /** + * {@inheritDoc} + */ + protected XmlPullParser createParser() { + return new KXmlParser(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/KXml2Driver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/KXml2Driver.java new file mode 100644 index 0000000..c94f0c1 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/KXml2Driver.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. April 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + + +import com.thoughtworks.xstream.io.HierarchicalStreamDriver; +import com.thoughtworks.xstream.io.naming.NameCoder; + +import org.kxml2.io.KXmlParser; +import org.xmlpull.v1.XmlPullParser; + + +/** + * A {@link HierarchicalStreamDriver} using the kXML2 parser. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class KXml2Driver extends AbstractXppDriver { + + /** + * Construct a KXml2Driver. + * + * @since 1.4 + */ + public KXml2Driver() { + super(new XmlFriendlyNameCoder()); + } + + /** + * Construct a KXml2Driver. + * + * @param nameCoder the replacer for XML friendly names + * @since 1.4 + */ + public KXml2Driver(NameCoder nameCoder) { + super(nameCoder); + } + + /** + * {@inheritDoc} + */ + protected XmlPullParser createParser() { + return new KXmlParser(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/PrettyPrintWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/PrettyPrintWriter.java new file mode 100644 index 0000000..bf7ac34 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/PrettyPrintWriter.java @@ -0,0 +1,365 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.core.util.FastStack; +import com.thoughtworks.xstream.core.util.QuickWriter; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.naming.NameCoder; + +import java.io.Writer; + + +/** + * A simple writer that outputs XML in a pretty-printed indented stream. + *

+ * By default, the chars
& < > " ' \r
are escaped + * and replaced with a suitable XML entity. To alter this behavior, override + * the {@link #writeText(com.thoughtworks.xstream.core.util.QuickWriter, String)} and + * {@link #writeAttributeValue(com.thoughtworks.xstream.core.util.QuickWriter, String)} methods. + *

+ *

+ * The XML specification requires XML parsers to drop CR characters completely. This implementation + * will therefore use only a LF for line endings, never the platform encoding. You can overwrite the + * {@link #getNewLine()} method for a different behavior. + *

+ *

+ * Note: Depending on the XML version some characters cannot be written. Especially a 0 + * character is never valid in XML, neither directly nor as entity nor within CDATA. However, this writer + * works by default in a quirks mode, where it will write any character at least as character entity (even + * a null character). You may switch into XML_1_1 mode (which supports most characters) or XML_1_0 + * that does only support a very limited number of control characters. See XML specification for version + * 1.0 or + * 1.1. If a character is + * not supported, a {@link StreamException} is thrown. Select a proper parser implementation that + * respects the version in the XML header (the Xpp3 parser will also read character entities of normally + * invalid characters). + *

+ * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class PrettyPrintWriter extends AbstractXmlWriter { + + public static int XML_QUIRKS = -1; + public static int XML_1_0 = 0; + public static int XML_1_1 = 1; + + private final QuickWriter writer; + private final FastStack elementStack = new FastStack(16); + private final char[] lineIndenter; + private final int mode; + + private boolean tagInProgress; + protected int depth; + private boolean readyForNewLine; + private boolean tagIsEmpty; + private String newLine; + + private static final char[] NULL = "�".toCharArray(); + private static final char[] AMP = "&".toCharArray(); + private static final char[] LT = "<".toCharArray(); + private static final char[] GT = ">".toCharArray(); + private static final char[] CR = " ".toCharArray(); + private static final char[] QUOT = """.toCharArray(); + private static final char[] APOS = "'".toCharArray(); + private static final char[] CLOSE = " XML_1_1) { + throw new IllegalArgumentException("Not a valid XML mode"); + } + } + + /** + * @since 1.2 + * @deprecated As of 1.3 + */ + public PrettyPrintWriter( + Writer writer, char[] lineIndenter, String newLine, XmlFriendlyReplacer replacer) { + this(writer, XML_QUIRKS, lineIndenter, replacer, newLine); + } + + /** + * @since 1.4 + */ + public PrettyPrintWriter( + Writer writer, int mode, char[] lineIndenter, NameCoder nameCoder) { + this(writer, mode, lineIndenter, nameCoder, "\n"); + } + + /** + * @since 1.3 + * @deprecated As of 1.4 use {@link PrettyPrintWriter#PrettyPrintWriter(Writer, int, char[], NameCoder)} instead + */ + public PrettyPrintWriter( + Writer writer, int mode, char[] lineIndenter, XmlFriendlyReplacer replacer) { + this(writer, mode, lineIndenter, replacer, "\n"); + } + + /** + * @deprecated As of 1.3 + */ + public PrettyPrintWriter(Writer writer, char[] lineIndenter, String newLine) { + this(writer, lineIndenter, newLine, new XmlFriendlyReplacer()); + } + + /** + * @since 1.3 + */ + public PrettyPrintWriter(Writer writer, int mode, char[] lineIndenter) { + this(writer, mode, lineIndenter, new XmlFriendlyNameCoder()); + } + + public PrettyPrintWriter(Writer writer, char[] lineIndenter) { + this(writer, XML_QUIRKS, lineIndenter); + } + + /** + * @deprecated As of 1.3 + */ + public PrettyPrintWriter(Writer writer, String lineIndenter, String newLine) { + this(writer, lineIndenter.toCharArray(), newLine); + } + + /** + * @since 1.3 + */ + public PrettyPrintWriter(Writer writer, int mode, String lineIndenter) { + this(writer, mode, lineIndenter.toCharArray()); + } + + public PrettyPrintWriter(Writer writer, String lineIndenter) { + this(writer, lineIndenter.toCharArray()); + } + + /** + * @since 1.4 + */ + public PrettyPrintWriter(Writer writer, int mode, NameCoder nameCoder) { + this(writer, mode, new char[]{' ', ' '}, nameCoder); + } + + /** + * @since 1.3 + * @deprecated As of 1.4 use {@link PrettyPrintWriter#PrettyPrintWriter(Writer, int, NameCoder)} instead + */ + public PrettyPrintWriter(Writer writer, int mode, XmlFriendlyReplacer replacer) { + this(writer, mode, new char[]{' ', ' '}, replacer); + } + + /** + * @since 1.4 + */ + public PrettyPrintWriter(Writer writer, NameCoder nameCoder) { + this(writer, XML_QUIRKS, new char[]{' ', ' '}, nameCoder, "\n"); + } + + /** + * @deprecated As of 1.4 use {@link PrettyPrintWriter#PrettyPrintWriter(Writer, NameCoder)} instead. + */ + public PrettyPrintWriter(Writer writer, XmlFriendlyReplacer replacer) { + this(writer, new char[]{' ', ' '}, "\n", replacer); + } + + /** + * @since 1.3 + */ + public PrettyPrintWriter(Writer writer, int mode) { + this(writer, mode, new char[]{' ', ' '}); + } + + public PrettyPrintWriter(Writer writer) { + this(writer, new char[]{' ', ' '}); + } + + public void startNode(String name) { + String escapedName = encodeNode(name); + tagIsEmpty = false; + finishTag(); + writer.write('<'); + writer.write(escapedName); + elementStack.push(escapedName); + tagInProgress = true; + depth++ ; + readyForNewLine = true; + tagIsEmpty = true; + } + + public void startNode(String name, Class clazz) { + startNode(name); + } + + public void setValue(String text) { + readyForNewLine = false; + tagIsEmpty = false; + finishTag(); + + writeText(writer, text); + } + + public void addAttribute(String key, String value) { + writer.write(' '); + writer.write(encodeAttribute(key)); + writer.write('='); + writer.write('\"'); + writeAttributeValue(writer, value); + writer.write('\"'); + } + + protected void writeAttributeValue(QuickWriter writer, String text) { + writeText(text, true); + } + + protected void writeText(QuickWriter writer, String text) { + writeText(text, false); + } + + private void writeText(String text, boolean isAttribute) { + int length = text.length(); + for (int i = 0; i < length; i++ ) { + char c = text.charAt(i); + switch (c) { + case '\0': + if (mode == XML_QUIRKS) { + this.writer.write(NULL); + } else { + throw new StreamException("Invalid character 0x0 in XML stream"); + } + break; + case '&': + this.writer.write(AMP); + break; + case '<': + this.writer.write(LT); + break; + case '>': + this.writer.write(GT); + break; + case '"': + this.writer.write(QUOT); + break; + case '\'': + this.writer.write(APOS); + break; + case '\r': + this.writer.write(CR); + break; + case '\t': + case '\n': + if (!isAttribute) { + this.writer.write(c); + break; + } + default: + if (Character.isDefined(c) && !Character.isISOControl(c)) { + if (mode != XML_QUIRKS) { + if (c > '\ud7ff' && c < '\ue000') { + throw new StreamException("Invalid character 0x" + + Integer.toHexString(c) + + " in XML stream"); + } + } + this.writer.write(c); + } else { + if (mode == XML_1_0) { + if (c < 9 + || c == '\u000b' + || c == '\u000c' + || c == '\u000e' + || (c >= '\u000f' && c <= '\u001f')) { + throw new StreamException("Invalid character 0x" + + Integer.toHexString(c) + + " in XML 1.0 stream"); + } + } + if (mode != XML_QUIRKS) { + if (c == '\ufffe' || c == '\uffff') { + throw new StreamException("Invalid character 0x" + + Integer.toHexString(c) + + " in XML stream"); + } + } + this.writer.write("&#x"); + this.writer.write(Integer.toHexString(c)); + this.writer.write(';'); + } + } + } + } + + public void endNode() { + depth-- ; + if (tagIsEmpty) { + writer.write('/'); + readyForNewLine = false; + finishTag(); + elementStack.popSilently(); + } else { + finishTag(); + writer.write(CLOSE); + writer.write((String)elementStack.pop()); + writer.write('>'); + } + readyForNewLine = true; + if (depth == 0) { + writer.flush(); + } + } + + private void finishTag() { + if (tagInProgress) { + writer.write('>'); + } + tagInProgress = false; + if (readyForNewLine) { + endOfLine(); + } + readyForNewLine = false; + tagIsEmpty = false; + } + + protected void endOfLine() { + writer.write(getNewLine()); + for (int i = 0; i < depth; i++ ) { + writer.write(lineIndenter); + } + } + + public void flush() { + writer.flush(); + } + + public void close() { + writer.close(); + } + + /** + * Retrieve the line terminator. + * + * This method returns always a line feed, since according the XML specification any parser + * must ignore a carriage return. Overload this method, if you need different behavior. + * + * @return the line terminator + * @since 1.3 + */ + protected String getNewLine() { + return newLine; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/QNameMap.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/QNameMap.java new file mode 100644 index 0000000..e047b13 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/QNameMap.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. October 2004 by James Strachan + */ +package com.thoughtworks.xstream.io.xml; + +import javax.xml.namespace.QName; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Represents a mapping of {@link QName} instances to Java class names + * allowing class aliases and namespace aware mappings of QNames to class names. + * + * @author James Strachan + * @version $Revision: 1345 $ + */ +public class QNameMap { + + // lets make the mapping a no-op unless we specify some mapping + private Map qnameToJava; + private Map javaToQName; + private String defaultPrefix = ""; + private String defaultNamespace = ""; + + /** + * Returns the Java class name that should be used for the given QName. + * If no explicit mapping has been made then the localPart of the QName is used + * which is the normal default in XStream. + */ + public String getJavaClassName(QName qname) { + if (qnameToJava != null) { + String answer = (String) qnameToJava.get(qname); + if (answer != null) { + return answer; + } + } + return qname.getLocalPart(); + } + + /** + * Returns the Java class name that should be used for the given QName. + * If no explicit mapping has been made then the localPart of the QName is used + * which is the normal default in XStream. + */ + public QName getQName(String javaClassName) { + if (javaToQName != null) { + QName answer = (QName) javaToQName.get(javaClassName); + if (answer != null) { + return answer; + } + } + return new QName(defaultNamespace, javaClassName, defaultPrefix); + } + + /** + * Registers the mapping of the Java class name to the QName + */ + public synchronized void registerMapping(QName qname, String javaClassName) { + if (javaToQName == null) { + javaToQName = Collections.synchronizedMap(new HashMap()); + } + if (qnameToJava == null) { + qnameToJava = Collections.synchronizedMap(new HashMap()); + } + javaToQName.put(javaClassName, qname); + qnameToJava.put(qname, javaClassName); + } + + /** + * Registers the mapping of the type to the QName + */ + public synchronized void registerMapping(QName qname, Class type) { + registerMapping(qname, type.getName()); + } + + public String getDefaultNamespace() { + return defaultNamespace; + } + + public void setDefaultNamespace(String defaultNamespace) { + this.defaultNamespace = defaultNamespace; + } + + public String getDefaultPrefix() { + return defaultPrefix; + } + + public void setDefaultPrefix(String defaultPrefix) { + this.defaultPrefix = defaultPrefix; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/SaxWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/SaxWriter.java new file mode 100644 index 0000000..e4c9852 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/SaxWriter.java @@ -0,0 +1,728 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 14. August 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.naming.NameCoder; + +import org.xml.sax.ContentHandler; +import org.xml.sax.DTDHandler; +import org.xml.sax.EntityResolver; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.AttributesImpl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * A SAX {@link org.xml.sax.XMLReader parser} that acts as an XStream + * {@link com.thoughtworks.xstream.io.HierarchicalStreamWriter} to enable direct generation of a + * SAX event flow from the XStream serialization of a list of list of Java objects. + *

+ * As a + * custom SAX parser, this class ignores the arguments of the two standard parse methods ({@link #parse(java.lang.String)} + * and {@link #parse(org.xml.sax.InputSource)}) but relies on a proprietary SAX property + * {@link #SOURCE_OBJECT_LIST_PROPERTY} to define the list of objects to serialize. + *

+ *

+ * Configuration of this SAX parser is achieved through the standard + * {@link #setProperty SAX property mechanism}. While specific setter methods require direct + * access to the parser instance, SAX properties support configuration settings to be propagated + * through a chain of {@link org.xml.sax.XMLFilter filters} down to the underlying parser + * object. + *

+ *

+ * This mechanism shall be used to configure the + * {@link #SOURCE_OBJECT_LIST_PROPERTY objects to be serialized} as well as the + * {@link #CONFIGURED_XSTREAM_PROPERTY XStream facade}. + *

+ * + * @author Laurent Bihanic + */ +public final class SaxWriter extends AbstractXmlWriter implements XMLReader { + /** + * The {@link #setProperty SAX property} to configure the XStream + * facade to be used for object serialization. If the property + * is not set, a new XStream facade will be allocated for each + * parse. + */ + public final static String CONFIGURED_XSTREAM_PROPERTY = + "http://com.thoughtworks.xstream/sax/property/configured-xstream"; + + /** + * The {@link #setProperty SAX property} to configure the list of + * Java objects to serialize. Setting this property prior + * invoking one of the parse() methods is mandatory. + * + * @see #parse(java.lang.String) + * @see #parse(org.xml.sax.InputSource) + */ + public final static String SOURCE_OBJECT_LIST_PROPERTY = + "http://com.thoughtworks.xstream/sax/property/source-object-list"; + + //========================================================================= + // SAX XMLReader interface support + //========================================================================= + + /** + * The SAX EntityResolver associated to this XMLReader. + */ + private EntityResolver entityResolver = null; + + /** + * The SAX DTDHandler associated to this XMLReader. + */ + private DTDHandler dtdHandler = null; + + /** + * The SAX ContentHandler associated to this XMLReader. + */ + private ContentHandler contentHandler = null; + + /** + * The SAX ErrorHandler associated to this XMLReader. + */ + private ErrorHandler errorHandler = null; + + /** + * The SAX features defined for this XMLReader. + *

+ * This class does not define any feature (yet) and ignores + * the SAX mandatory feature. Thus, this member is present + * only to support the mandatory feature setting and retrieval + * logic defined by SAX.

+ */ + private Map features = new HashMap(); + + /** + * The SAX properties defined for this XMLReader. + */ + private final Map properties = new HashMap(); + + private final boolean includeEnclosingDocument; + + /** + * @since 1.4 + */ + public SaxWriter(NameCoder nameCoder) + { + this(true, nameCoder); + } + + /** + * @since 1.4 + */ + public SaxWriter(boolean includeEnclosingDocument, NameCoder nameCoder) + { + super(nameCoder); + this.includeEnclosingDocument = includeEnclosingDocument; + } + + /** + * @deprecated As of 1.4 use {@link SaxWriter#SaxWriter(NameCoder)} instead. + */ + public SaxWriter(XmlFriendlyReplacer replacer) + { + this(true, replacer); + } + + /** + * @deprecated As of 1.4 use {@link SaxWriter#SaxWriter(boolean, NameCoder)} instead. + */ + public SaxWriter(boolean includeEnclosingDocument, XmlFriendlyReplacer replacer) + { + this(includeEnclosingDocument, (NameCoder)replacer); + } + + public SaxWriter(boolean includeEnclosingDocument) { + this(includeEnclosingDocument, new XmlFriendlyNameCoder()); + } + + public SaxWriter() { + this(true); + } + + //------------------------------------------------------------------------- + // Configuration + //------------------------------------------------------------------------- + + /** + * Sets the state of a feature. + *

+ * The feature name is any fully-qualified URI.

+ *

+ * All XMLReaders are required to support setting + * http://xml.org/sax/features/namespaces to + * true and + * http://xml.org/sax/features/namespace-prefixes to + * false.

+ *

+ * Some feature values may be immutable or mutable only + * in specific contexts, such as before, during, or after + * a parse.

+ *

+ * Note: This implementation only supports the two + * mandatory SAX features.

+ * + * @param name the feature name, which is a fully-qualified URI. + * @param value the requested state of the feature (true or false). + * @throws SAXNotRecognizedException when the XMLReader does not + * recognize the feature name. + * @see #getFeature + */ + public void setFeature(String name, boolean value) + throws SAXNotRecognizedException { + if ((name.equals("http://xml.org/sax/features/namespaces")) || + (name.equals("http://xml.org/sax/features/namespace-prefixes"))) { + this.features.put(name, value ? Boolean.TRUE : Boolean.FALSE); // JDK 1.3 friendly + } else { + throw new SAXNotRecognizedException(name); + } + } + + /** + * Looks up the value of a feature. + *

+ * The feature name is any fully-qualified URI. It is + * possible for an XMLReader to recognize a feature name but + * to be unable to return its value; this is especially true + * in the case of an adapter for a SAX1 Parser, which has + * no way of knowing whether the underlying parser is + * performing validation or expanding external entities.

+ *

+ * All XMLReaders are required to recognize the + * http://xml.org/sax/features/namespaces and the + * http://xml.org/sax/features/namespace-prefixes feature + * names.

+ *

+ * Some feature values may be available only in specific + * contexts, such as before, during, or after a parse.

+ *

+ * Implementors are free (and encouraged) to invent their own + * features, using names built on their own URIs.

+ * + * @param name the feature name, which is a fully-qualified URI. + * @return the current state of the feature (true or false). + * @throws SAXNotRecognizedException when the XMLReader does not + * recognize the feature name. + * @see #setFeature + */ + public boolean getFeature(String name) + throws SAXNotRecognizedException { + if ((name.equals("http://xml.org/sax/features/namespaces")) || + (name.equals("http://xml.org/sax/features/namespace-prefixes"))) { + Boolean value = (Boolean) (this.features.get(name)); + + if (value == null) { + value = Boolean.FALSE; + } + return value.booleanValue(); + } else { + throw new SAXNotRecognizedException(name); + } + } + + /** + * Sets the value of a property. + *

+ * The property name is any fully-qualified URI. It is + * possible for an XMLReader to recognize a property name but + * to be unable to set its value.

+ *

+ * XMLReaders are not required to recognize setting any + * specific property names, though a core set is provided with + * SAX2.

+ *

+ * Some property values may be immutable or mutable only + * in specific contexts, such as before, during, or after + * a parse.

+ *

+ * This method is also the standard mechanism for setting + * extended handlers.

+ *

+ * Note: This implementation only supports two + * (proprietary) properties: {@link #CONFIGURED_XSTREAM_PROPERTY} + * and {@link #SOURCE_OBJECT_LIST_PROPERTY}.

+ * + * @param name the property name, which is a fully-qualified URI. + * @param value the requested value for the property. + * @throws SAXNotRecognizedException when the XMLReader does not + * recognize the property name. + * @throws SAXNotSupportedException when the XMLReader recognizes + * the property name but cannot set + * the requested value. + * @see #getProperty + */ + public void setProperty(String name, Object value) + throws SAXNotRecognizedException, + SAXNotSupportedException { + if (name.equals(CONFIGURED_XSTREAM_PROPERTY)) { + if (!(value instanceof XStream)) { + throw new SAXNotSupportedException("Value for property \"" + + CONFIGURED_XSTREAM_PROPERTY + + "\" must be a non-null XStream object"); + } + } else if (name.equals(SOURCE_OBJECT_LIST_PROPERTY)) { + if (value instanceof List) { + List list = (List) value; + + if (list.isEmpty()) { + throw new SAXNotSupportedException("Value for property \"" + + SOURCE_OBJECT_LIST_PROPERTY + + "\" shall not be an empty list"); + } else { + // Perform a copy of the list to prevent the application to + // modify its content while the parse is being performed. + value = Collections.unmodifiableList(new ArrayList(list)); + } + } else { + throw new SAXNotSupportedException("Value for property \"" + + SOURCE_OBJECT_LIST_PROPERTY + + "\" must be a non-null List object"); + } + } else { + throw new SAXNotRecognizedException(name); + } + this.properties.put(name, value); + } + + /** + * Looks up the value of a property. + *

+ * The property name is any fully-qualified URI. It is + * possible for an XMLReader to recognize a property name but + * to be unable to return its state.

+ *

+ * XMLReaders are not required to recognize any specific + * property names, though an initial core set is documented for + * SAX2.

+ *

+ * Some property values may be available only in specific + * contexts, such as before, during, or after a parse.

+ *

+ * Implementors are free (and encouraged) to invent their own properties, + * using names built on their own URIs.

+ * + * @param name the property name, which is a fully-qualified URI. + * @return the current value of the property. + * @throws SAXNotRecognizedException when the XMLReader does not + * recognize the property name. + * @see #getProperty + */ + public Object getProperty(String name) + throws SAXNotRecognizedException { + if ((name.equals(CONFIGURED_XSTREAM_PROPERTY)) || + (name.equals(SOURCE_OBJECT_LIST_PROPERTY))) { + return this.properties.get(name); + } else { + throw new SAXNotRecognizedException(name); + } + } + + //--------------------------------------------------------------------- + // Event handlers + //--------------------------------------------------------------------- + + /** + * Allows an application to register an entity resolver. + *

+ * If the application does not register an entity resolver, + * the XMLReader will perform its own default resolution.

+ *

+ * Applications may register a new or different resolver in the + * middle of a parse, and the SAX parser must begin using the new + * resolver immediately.

+ * + * @param resolver the entity resolver. + * @throws NullPointerException if the resolver argument is + * null. + * @see #getEntityResolver + */ + public void setEntityResolver(EntityResolver resolver) { + if (resolver == null) { + throw new NullPointerException("resolver"); + } + this.entityResolver = resolver; + return; + } + + /** + * Returns the current entity resolver. + * + * @return the current entity resolver, or null if none + * has been registered. + * @see #setEntityResolver + */ + public EntityResolver getEntityResolver() { + return this.entityResolver; + } + + /** + * Allows an application to register a DTD event handler. + *

+ * If the application does not register a DTD handler, all DTD + * events reported by the SAX parser will be silently ignored.

+ *

+ * Applications may register a new or different handler in the + * middle of a parse, and the SAX parser must begin using the new + * handler immediately.

+ * + * @param handler the DTD handler. + * @throws NullPointerException if the handler argument is + * null. + * @see #getDTDHandler + */ + public void setDTDHandler(DTDHandler handler) { + if (handler == null) { + throw new NullPointerException("handler"); + } + this.dtdHandler = handler; + return; + } + + /** + * Returns the current DTD handler. + * + * @return the current DTD handler, or null if none + * has been registered. + * @see #setDTDHandler + */ + public DTDHandler getDTDHandler() { + return this.dtdHandler; + } + + /** + * Allows an application to register a content event handler. + *

+ * If the application does not register a content handler, all + * content events reported by the SAX parser will be silently + * ignored.

+ *

+ * Applications may register a new or different handler in the + * middle of a parse, and the SAX parser must begin using the new + * handler immediately.

+ * + * @param handler the content handler. + * @throws NullPointerException if the handler argument is + * null. + * @see #getContentHandler + */ + public void setContentHandler(ContentHandler handler) { + if (handler == null) { + throw new NullPointerException("handler"); + } + this.contentHandler = handler; + return; + } + + /** + * Returns the current content handler. + * + * @return the current content handler, or null if none + * has been registered. + * @see #setContentHandler + */ + public ContentHandler getContentHandler() { + return this.contentHandler; + } + + /** + * Allows an application to register an error event handler. + *

+ * If the application does not register an error handler, all + * error events reported by the SAX parser will be silently + * ignored; however, normal processing may not continue. It is + * highly recommended that all SAX applications implement an + * error handler to avoid unexpected bugs.

+ *

+ * Applications may register a new or different handler in the + * middle of a parse, and the SAX parser must begin using the new + * handler immediately.

+ * + * @param handler the error handler. + * @throws NullPointerException if the handler argument is + * null. + * @see #getErrorHandler + */ + public void setErrorHandler(ErrorHandler handler) { + if (handler == null) { + throw new NullPointerException("handler"); + } + this.errorHandler = handler; + return; + } + + /** + * Returns the current error handler. + * + * @return the current error handler, or null if none + * has been registered. + * @see #setErrorHandler + */ + public ErrorHandler getErrorHandler() { + return this.errorHandler; + } + + //--------------------------------------------------------------------- + // Parsing + //--------------------------------------------------------------------- + + /** + * Parses an XML document from a system identifier (URI). + *

+ * This method is a shortcut for the common case of reading a + * document from a system identifier. It is the exact + * equivalent of the following:

+ *
+ *
+     *    parse(new InputSource(systemId));
+     *  
+ *
+ *

+ * If the system identifier is a URL, it must be fully resolved + * by the application before it is passed to the parser.

+ *

+ * Note: As a custom SAX parser, this class + * ignores the systemId argument of this method + * and relies on the proprietary SAX property + * {@link #SOURCE_OBJECT_LIST_PROPERTY}) to define the list of + * objects to serialize.

+ * + * @param systemId the system identifier (URI). + * @throws SAXException Any SAX exception, possibly wrapping + * another exception. + * @see #parse(org.xml.sax.InputSource) + */ + public void parse(String systemId) throws SAXException { + this.parse(); + } + + /** + * Parse an XML document. + *

+ * The application can use this method to instruct the XML + * reader to begin parsing an XML document from any valid input + * source (a character stream, a byte stream, or a URI).

+ *

+ * Applications may not invoke this method while a parse is in + * progress (they should create a new XMLReader instead for each + * nested XML document). Once a parse is complete, an + * application may reuse the same XMLReader object, possibly + * with a different input source.

+ *

+ * During the parse, the XMLReader will provide information + * about the XML document through the registered event + * handlers.

+ *

+ * This method is synchronous: it will not return until parsing + * has ended. If a client application wants to terminate + * parsing early, it should throw an exception.

+ *

+ * Note: As a custom SAX parser, this class + * ignores the source argument of this method + * and relies on the proprietary SAX property + * {@link #SOURCE_OBJECT_LIST_PROPERTY}) to define the list of + * objects to serialize.

+ * + * @param input The input source for the top-level of the + * XML document. + * @throws SAXException Any SAX exception, possibly wrapping + * another exception. + * @see org.xml.sax.InputSource + * @see #parse(java.lang.String) + * @see #setEntityResolver + * @see #setDTDHandler + * @see #setContentHandler + * @see #setErrorHandler + */ + public void parse(InputSource input) throws SAXException { + this.parse(); + } + + /** + * Serializes the Java objects of the configured list into a flow + * of SAX events. + * + * @throws SAXException if the configured object list is invalid + * or object serialization failed. + */ + private void parse() throws SAXException { + XStream xstream = (XStream) (this.properties.get(CONFIGURED_XSTREAM_PROPERTY)); + if (xstream == null) { + xstream = new XStream(); + } + + List source = (List) (this.properties.get(SOURCE_OBJECT_LIST_PROPERTY)); + if ((source == null) || (source.isEmpty())) { + throw new SAXException("Missing or empty source object list. Setting property \"" + + SOURCE_OBJECT_LIST_PROPERTY + "\" is mandatory"); + } + + try { + this.startDocument(true); + for (Iterator i = source.iterator(); i.hasNext();) { + xstream.marshal(i.next(), this); + } + this.endDocument(true); + } catch (StreamException e) { + if (e.getCause() instanceof SAXException) { + throw (SAXException) (e.getCause()); + } else { + throw new SAXException(e); + } + } + } + + + //========================================================================= + // XStream HierarchicalStreamWriter interface support + //========================================================================= + + private int depth = 0; + private List elementStack = new LinkedList(); + private char[] buffer = new char[128]; + private boolean startTagInProgress = false; + private final AttributesImpl attributeList = new AttributesImpl(); + + public void startNode(String name) { + try { + if (this.depth != 0) { + this.flushStartTag(); + } else if (includeEnclosingDocument) { + this.startDocument(false); + } + this.elementStack.add(0, escapeXmlName(name)); + + this.startTagInProgress = true; + this.depth++; + } catch (SAXException e) { + throw new StreamException(e); + } + } + + public void addAttribute(String name, String value) { + if (this.startTagInProgress) { + String escapedName = escapeXmlName(name); + this.attributeList.addAttribute("", escapedName, escapedName, "CDATA", value); + } else { + throw new StreamException(new IllegalStateException("No startElement being processed")); + } + } + + public void setValue(String text) { + try { + this.flushStartTag(); + + int lg = text.length(); + if (lg > buffer.length) { + buffer = new char[lg]; + } + text.getChars(0, lg, buffer, 0); + + this.contentHandler.characters(buffer, 0, lg); + } catch (SAXException e) { + throw new StreamException(e); + } + } + + public void endNode() { + try { + this.flushStartTag(); + + String tagName = (String) (this.elementStack.remove(0)); + + this.contentHandler.endElement("", tagName, tagName); + + this.depth--; + if (this.depth == 0 && includeEnclosingDocument) { + this.endDocument(false); + } + } catch (SAXException e) { + throw new StreamException(e); + } + } + + /** + * Fires the SAX startDocument event towards the configured + * ContentHandler. + * + * @param multiObjectMode whether serialization of several + * object will be merge into a single + * SAX document. + * @throws SAXException if thrown by the ContentHandler. + */ + private void startDocument(boolean multiObjectMode) throws SAXException { + if (this.depth == 0) { + // Notify contentHandler of document start. + this.contentHandler.startDocument(); + + if (multiObjectMode) { + // Prevent marshalling of each object to fire its own + // start/endDocument events. + this.depth++; + } + } + } + + /** + * Fires the SAX endDocument event towards the configured + * ContentHandler. + * + * @param multiObjectMode whether serialization of several + * object will be merge into a single + * SAX document. + * @throws SAXException if thrown by the ContentHandler. + */ + private void endDocument(boolean multiObjectMode) throws SAXException { + if ((this.depth == 0) || ((this.depth == 1) && (multiObjectMode))) { + this.contentHandler.endDocument(); + this.depth = 0; + } + } + + /** + * Fires any pending SAX startElement event towards the + * configured ContentHandler. + * + * @throws SAXException if thrown by the ContentHandler. + */ + private void flushStartTag() throws SAXException { + if (this.startTagInProgress) { + String tagName = (String) (this.elementStack.get(0)); + + this.contentHandler.startElement("", tagName, + tagName, this.attributeList); + this.attributeList.clear(); + this.startTagInProgress = false; + } + } + + public void flush() { + // don't need to do anything + } + + public void close() { + // don't need to do anything + } +} + diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/SjsxpDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/SjsxpDriver.java new file mode 100644 index 0000000..26d8009 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/SjsxpDriver.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2009, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. April 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.StreamException; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; + +/** + * A driver using the JDK 6 StAX implementation of Sun. + * + * @author Jörg Schaible + * @since 1.4 + * @deprecated As of 1.4.5 use {@link StandardStaxDriver} + */ +public class SjsxpDriver extends StaxDriver { + + /** + * @deprecated As of 1.4.5 use {@link StandardStaxDriver#StandardStaxDriver()} + */ + public SjsxpDriver() { + super(); + } + + /** + * @deprecated As of 1.4.5 use {@link StandardStaxDriver#StandardStaxDriver(QNameMap, XmlFriendlyNameCoder)} + */ + public SjsxpDriver(QNameMap qnameMap, XmlFriendlyNameCoder nameCoder) { + super(qnameMap, nameCoder); + } + + /** + * @deprecated As of 1.4.5 use {@link StandardStaxDriver#StandardStaxDriver(QNameMap)} + */ + public SjsxpDriver(QNameMap qnameMap) { + super(qnameMap); + } + + /** + * @deprecated As of 1.4.5 use {@link StandardStaxDriver#StandardStaxDriver(XmlFriendlyNameCoder)} + */ + public SjsxpDriver(XmlFriendlyNameCoder nameCoder) { + super(nameCoder); + } + + /** + * @deprecated As of 1.4.5 use {@link StandardStaxDriver#createInputFactory()} + */ + protected XMLInputFactory createInputFactory() { + Exception exception = null; + try { + return (XMLInputFactory)Class.forName("com.sun.xml.internal.stream.XMLInputFactoryImpl").newInstance(); + } catch (InstantiationException e) { + exception = e; + } catch (IllegalAccessException e) { + exception = e; + } catch (ClassNotFoundException e) { + exception = e; + } + throw new StreamException("Cannot create SJSXP (Sun JDK 6 StAX) XMLInputFaqctory instance.", exception); + } + + /** + * @deprecated As of 1.4.5 use {@link StandardStaxDriver#createOutputFactory()} + */ + protected XMLOutputFactory createOutputFactory() { + Exception exception = null; + try { + return (XMLOutputFactory)Class.forName("com.sun.xml.internal.stream.XMLOutputFactoryImpl").newInstance(); + } catch (InstantiationException e) { + exception = e; + } catch (IllegalAccessException e) { + exception = e; + } catch (ClassNotFoundException e) { + exception = e; + } + throw new StreamException("Cannot create SJSXP (Sun JDK 6 StAX) XMLOutputFaqctory instance.", exception); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/StandardStaxDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/StandardStaxDriver.java new file mode 100644 index 0000000..1fe744d --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/StandardStaxDriver.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 27. July 2013 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.naming.NameCoder; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; + + +/** + * A driver using the standard JDK StAX implementation provided by the Java runtime (since Java + * 6). + *

+ * In contrast to XMLInputFactory.newFactory() or XMLOutputFactory.newFactory() this + * implementation will ignore any implementations provided with the system properties + * javax.xml.stream.XMLInputFactory and javax.xml.stream.XMLOutputFactory, all + * implementations configured in lib/stax.properties or registered with the Service + * API. + *

+ * + * @author Jörg Schaible + * @since 1.4.5 + */ +public class StandardStaxDriver extends StaxDriver { + + public StandardStaxDriver() { + super(); + } + + /** + * @deprecated As of 1.4.6 use {@link #StandardStaxDriver(QNameMap, NameCoder)} + */ + public StandardStaxDriver(QNameMap qnameMap, XmlFriendlyNameCoder nameCoder) { + super(qnameMap, nameCoder); + } + + /** + * @since 1.4.6 + */ + public StandardStaxDriver(QNameMap qnameMap, NameCoder nameCoder) { + super(qnameMap, nameCoder); + } + + public StandardStaxDriver(QNameMap qnameMap) { + super(qnameMap); + } + + /** + * @deprecated As of 1.4.6 use {@link #StandardStaxDriver(NameCoder)} + */ + public StandardStaxDriver(XmlFriendlyNameCoder nameCoder) { + super(nameCoder); + } + + /** + * @since 1.4.6 + */ + public StandardStaxDriver(NameCoder nameCoder) { + super(nameCoder); + } + + protected XMLInputFactory createInputFactory() { + Exception exception = null; + try { + Class staxInputFactory = JVM.getStaxInputFactory(); + if (staxInputFactory != null) { + return (XMLInputFactory)staxInputFactory.newInstance(); + } else { + throw new StreamException("Java runtime has no standard XMLInputFactory implementation.", exception); + } + } catch (InstantiationException e) { + exception = e; + } catch (IllegalAccessException e) { + exception = e; + } catch (ClassNotFoundException e) { + exception = e; + } + throw new StreamException("Cannot create standard XMLInputFactory instance of Java runtime.", exception); + } + + protected XMLOutputFactory createOutputFactory() { + Exception exception = null; + try { + Class staxOutputFactory = JVM.getStaxOutputFactory(); + if (staxOutputFactory != null) { + return (XMLOutputFactory)staxOutputFactory.newInstance(); + } else { + throw new StreamException("Java runtime has no standard XMLOutputFactory implementation.", exception); + } + } catch (InstantiationException e) { + exception = e; + } catch (IllegalAccessException e) { + exception = e; + } catch (ClassNotFoundException e) { + exception = e; + } + throw new StreamException("Cannot create standard XMLOutputFactory instance of Java runtime.", exception); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/StaxDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/StaxDriver.java new file mode 100644 index 0000000..b4c0086 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/StaxDriver.java @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. September 2004 by James Strachan + */ +package com.thoughtworks.xstream.io.xml; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; +import java.net.URL; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.ReaderWrapper; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.naming.NameCoder; + +/** + * A driver using the StAX API to create XML reader and writer. + * + * @author James Strachan + * @author Jörg Schaible + * @version $Revision: 2116 $ + */ +public class StaxDriver extends AbstractXmlDriver { + + private QNameMap qnameMap; + private XMLInputFactory inputFactory; + private XMLOutputFactory outputFactory; + + public StaxDriver() { + this(new QNameMap()); + } + + public StaxDriver(QNameMap qnameMap) { + this(qnameMap, new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + public StaxDriver(QNameMap qnameMap, NameCoder nameCoder) { + super(nameCoder); + this.qnameMap = qnameMap; + } + + /** + * @since 1.4 + */ + public StaxDriver(NameCoder nameCoder) { + this(new QNameMap(), nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link StaxDriver#StaxDriver(QNameMap, NameCoder)} instead. + */ + public StaxDriver(QNameMap qnameMap, XmlFriendlyReplacer replacer) { + this(qnameMap, (NameCoder)replacer); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link StaxDriver#StaxDriver(NameCoder)} instead. + */ + public StaxDriver(XmlFriendlyReplacer replacer) { + this(new QNameMap(), (NameCoder)replacer); + } + + public HierarchicalStreamReader createReader(Reader xml) { + try { + return createStaxReader(createParser(xml)); + } catch (XMLStreamException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamReader createReader(InputStream in) { + try { + return createStaxReader(createParser(in)); + } catch (XMLStreamException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamReader createReader(URL in) { + final InputStream stream; + try { + stream = in.openStream(); + HierarchicalStreamReader reader = createStaxReader(createParser(new StreamSource( + stream, in.toExternalForm()))); + return new ReaderWrapper(reader) { + + public void close() { + super.close(); + try { + stream.close(); + } catch (IOException e) { + // ignore + } + } + }; + } catch (XMLStreamException e) { + throw new StreamException(e); + } catch (IOException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamReader createReader(File in) { + final InputStream stream; + try { + stream = new FileInputStream(in); + HierarchicalStreamReader reader = createStaxReader(createParser(new StreamSource( + stream, in.toURI().toASCIIString()))); + return new ReaderWrapper(reader) { + + public void close() { + super.close(); + try { + stream.close(); + } catch (IOException e) { + // ignore + } + } + }; + } catch (XMLStreamException e) { + throw new StreamException(e); + } catch (FileNotFoundException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamWriter createWriter(Writer out) { + try { + return createStaxWriter(getOutputFactory().createXMLStreamWriter(out)); + } + catch (XMLStreamException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamWriter createWriter(OutputStream out) { + try { + return createStaxWriter(getOutputFactory().createXMLStreamWriter(out)); + } + catch (XMLStreamException e) { + throw new StreamException(e); + } + } + + public AbstractPullReader createStaxReader(XMLStreamReader in) { + return new StaxReader(qnameMap, in, getNameCoder()); + } + + public StaxWriter createStaxWriter(XMLStreamWriter out, boolean writeStartEndDocument) throws XMLStreamException { + return new StaxWriter(qnameMap, out, writeStartEndDocument, isRepairingNamespace(), getNameCoder()); + } + + public StaxWriter createStaxWriter(XMLStreamWriter out) throws XMLStreamException { + return createStaxWriter(out, true); + } + + + // Properties + //------------------------------------------------------------------------- + public QNameMap getQnameMap() { + return qnameMap; + } + + public void setQnameMap(QNameMap qnameMap) { + this.qnameMap = qnameMap; + } + + public XMLInputFactory getInputFactory() { + if (inputFactory == null) { + inputFactory = createInputFactory(); + } + return inputFactory; + } + + public XMLOutputFactory getOutputFactory() { + if (outputFactory == null) { + outputFactory = createOutputFactory(); + } + return outputFactory; + } + + public boolean isRepairingNamespace() { + return Boolean.TRUE.equals(getOutputFactory().getProperty( + XMLOutputFactory.IS_REPAIRING_NAMESPACES)); + } + + /** + * @since 1.2 + */ + public void setRepairingNamespace(boolean repairing) { + getOutputFactory().setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, + repairing ? Boolean.TRUE : Boolean.FALSE); + } + + + // Implementation methods + //------------------------------------------------------------------------- + protected XMLStreamReader createParser(Reader xml) throws XMLStreamException { + return getInputFactory().createXMLStreamReader(xml); + } + + protected XMLStreamReader createParser(InputStream xml) throws XMLStreamException { + return getInputFactory().createXMLStreamReader(xml); + } + + protected XMLStreamReader createParser(Source source) throws XMLStreamException { + return getInputFactory().createXMLStreamReader(source); + } + + /** + * @since 1.4 + */ + protected XMLInputFactory createInputFactory() { + return XMLInputFactory.newInstance(); + } + + /** + * @since 1.4 + */ + protected XMLOutputFactory createOutputFactory() { + return XMLOutputFactory.newInstance(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/StaxReader.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/StaxReader.java new file mode 100644 index 0000000..08fe718 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/StaxReader.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. September 2004 by James Strachan + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.converters.ErrorWriter; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.naming.NameCoder; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +/** + * A reader using the StAX API. + * + * @author James Strachan + * @version $Revision: 1861 $ + */ +public class StaxReader extends AbstractPullReader { + + private final QNameMap qnameMap; + private final XMLStreamReader in; + + public StaxReader(QNameMap qnameMap, XMLStreamReader in) { + this(qnameMap, in, new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + public StaxReader(QNameMap qnameMap, XMLStreamReader in, NameCoder replacer) { + super(replacer); + this.qnameMap = qnameMap; + this.in = in; + moveDown(); + } + + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link StaxReader#StaxReader(QNameMap, XMLStreamReader, NameCoder)} instead. + */ + public StaxReader(QNameMap qnameMap, XMLStreamReader in, XmlFriendlyReplacer replacer) { + this(qnameMap, in, (NameCoder)replacer); + } + + protected int pullNextEvent() { + try { + switch(in.next()) { + case XMLStreamConstants.START_DOCUMENT: + case XMLStreamConstants.START_ELEMENT: + return START_NODE; + case XMLStreamConstants.END_DOCUMENT: + case XMLStreamConstants.END_ELEMENT: + return END_NODE; + case XMLStreamConstants.CHARACTERS: + return TEXT; + case XMLStreamConstants.COMMENT: + return COMMENT; + default: + return OTHER; + } + } catch (XMLStreamException e) { + throw new StreamException(e); + } + } + + protected String pullElementName() { + // let the QNameMap handle any mapping of QNames to Java class names + QName qname = in.getName(); + return qnameMap.getJavaClassName(qname); + } + + protected String pullText() { + return in.getText(); + } + + public String getAttribute(String name) { + return in.getAttributeValue(null, encodeAttribute(name)); + } + + public String getAttribute(int index) { + return in.getAttributeValue(index); + } + + public int getAttributeCount() { + return in.getAttributeCount(); + } + + public String getAttributeName(int index) { + return decodeAttribute(in.getAttributeLocalName(index)); + } + + public void appendErrors(ErrorWriter errorWriter) { + errorWriter.add("line number", String.valueOf(in.getLocation().getLineNumber())); + } + + public void close() { + try { + in.close(); + } catch (XMLStreamException e) { + throw new StreamException(e); + } + } + +} \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/StaxWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/StaxWriter.java new file mode 100644 index 0000000..79410cc --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/StaxWriter.java @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. September 2004 by James Strachan + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.naming.NameCoder; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; + + +/** + * A stream writing that outputs to a StAX stream writer + * + * @author James Strachan + * @version $Revision: 1906 $ + */ +public class StaxWriter extends AbstractXmlWriter { + + private final QNameMap qnameMap; + private final XMLStreamWriter out; + private final boolean writeEnclosingDocument; + private boolean namespaceRepairingMode; + + private int tagDepth; + + public StaxWriter(QNameMap qnameMap, XMLStreamWriter out) throws XMLStreamException { + this(qnameMap, out, true, true); + } + + /** + * Allows a StaxWriter to be created for partial XML output + * + * @param qnameMap is the mapper of Java class names to QNames + * @param out the stream to output to + * @param nameCoder the xml-friendly replacer to escape Java names + * @throws XMLStreamException if the events could not be written to the output + * @since 1.4 + */ + public StaxWriter(QNameMap qnameMap, XMLStreamWriter out, NameCoder nameCoder) + throws XMLStreamException { + this(qnameMap, out, true, true, nameCoder); + } + + /** + * Allows a StaxWriter to be created for partial XML output + * + * @param qnameMap is the mapper of Java class names to QNames + * @param out the stream to output to + * @param writeEnclosingDocument a flag to indicate whether or not the start/end document + * events should be written + * @param namespaceRepairingMode a flag to enable StAX' namespace repairing mode + * @param nameCoder the xml-friendly replacer to escape Java names + * @throws XMLStreamException if the events could not be written to the output + * @since 1.4 + */ + public StaxWriter( + QNameMap qnameMap, XMLStreamWriter out, boolean writeEnclosingDocument, + boolean namespaceRepairingMode, NameCoder nameCoder) throws XMLStreamException { + super(nameCoder); + this.qnameMap = qnameMap; + this.out = out; + this.writeEnclosingDocument = writeEnclosingDocument; + this.namespaceRepairingMode = namespaceRepairingMode; + if (writeEnclosingDocument) { + out.writeStartDocument(); + } + } + + /** + * Allows a StaxWriter to be created for partial XML output + * + * @param qnameMap is the mapper of Java class names to QNames + * @param out the stream to output to + * @param writeEnclosingDocument a flag to indicate whether or not the start/end document + * events should be written + * @throws XMLStreamException if the events could not be written to the output + */ + public StaxWriter( + QNameMap qnameMap, XMLStreamWriter out, boolean writeEnclosingDocument, + boolean namespaceRepairingMode) throws XMLStreamException { + this( + qnameMap, out, writeEnclosingDocument, namespaceRepairingMode, + new XmlFriendlyNameCoder()); + } + + /** + * Allows a StaxWriter to be created for partial XML output + * + * @param qnameMap is the mapper of Java class names to QNames + * @param out the stream to output to + * @param writeEnclosingDocument a flag to indicate whether or not the start/end document + * events should be written + * @param replacer the xml-friendly replacer to escape Java names + * @throws XMLStreamException if the events could not be written to the output + * @since 1.2 + * @deprecated As of 1.4 use + * {@link StaxWriter#StaxWriter(QNameMap, XMLStreamWriter, boolean, boolean, NameCoder)} + * instead + */ + public StaxWriter( + QNameMap qnameMap, XMLStreamWriter out, boolean writeEnclosingDocument, + boolean namespaceRepairingMode, XmlFriendlyReplacer replacer) throws XMLStreamException { + this(qnameMap, out, writeEnclosingDocument, namespaceRepairingMode, (NameCoder)replacer); + } + + public void flush() { + try { + out.flush(); + } catch (XMLStreamException e) { + throw new StreamException(e); + } + } + + /** + * Call this method when you're finished with me + */ + public void close() { + try { + out.close(); + } catch (XMLStreamException e) { + throw new StreamException(e); + } + } + + public void addAttribute(String name, String value) { + try { + out.writeAttribute(encodeAttribute(name), value); + } catch (XMLStreamException e) { + throw new StreamException(e); + } + } + + public void endNode() { + try { + tagDepth-- ; + out.writeEndElement(); + if (tagDepth == 0 && writeEnclosingDocument) { + out.writeEndDocument(); + } + } catch (XMLStreamException e) { + throw new StreamException(e); + } + } + + public void setValue(String text) { + try { + out.writeCharacters(text); + } catch (XMLStreamException e) { + throw new StreamException(e); + } + } + + public void startNode(String name) { + try { + QName qname = qnameMap.getQName(encodeNode(name)); + String prefix = qname.getPrefix(); + String uri = qname.getNamespaceURI(); + + // before you ask - yes it really is this complicated to output QNames to StAX + // handling both repair namespace modes :) + + boolean hasPrefix = prefix != null && prefix.length() > 0; + boolean hasURI = uri != null && uri.length() > 0; + boolean writeNamespace = false; + + if (hasURI) { + if (hasPrefix) { + String currentNamespace = out.getNamespaceContext().getNamespaceURI(prefix); + if (currentNamespace == null || !currentNamespace.equals(uri)) { + writeNamespace = true; + } + } else { + String defaultNamespace = out.getNamespaceContext().getNamespaceURI(""); + if (defaultNamespace == null || !defaultNamespace.equals(uri)) { + writeNamespace = true; + } + } + } + + out.writeStartElement(prefix, qname.getLocalPart(), uri); + if (hasPrefix) { + out.setPrefix(prefix, uri); + } else if (hasURI) { + if (writeNamespace) { + out.setDefaultNamespace(uri); + } + } + if (hasURI && writeNamespace && !isNamespaceRepairingMode()) { + if (hasPrefix) { + out.writeNamespace(prefix, uri); + } else { + out.writeDefaultNamespace(uri); + } + } + tagDepth++ ; + } catch (XMLStreamException e) { + throw new StreamException(e); + } + } + + /** + * Is StAX namespace repairing mode on or off? + */ + public boolean isNamespaceRepairingMode() { + return namespaceRepairingMode; + } + + protected QNameMap getQNameMap() { + return this.qnameMap; + } + + protected XMLStreamWriter getXMLStreamWriter() { + return this.out; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/TraxSource.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/TraxSource.java new file mode 100644 index 0000000..2f3b1ee --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/TraxSource.java @@ -0,0 +1,308 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 14. August 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.XStream; + +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLFilter; +import org.xml.sax.XMLReader; + +import javax.xml.transform.sax.SAXSource; + +import java.util.ArrayList; +import java.util.List; + + +/** + * A {@link SAXSource JAXP TrAX Source} that enables using XStream object serialization as + * direct input for XSLT processors without resorting to an intermediate representation such as + * text XML, DOM or DOM4J. + *

+ * The following example shows how to apply an XSL Transformation + * to a set of Java objects gathered into a List (source): + *

+ * + *

+ * public static String transform(List source, String stylesheet) {
+ *     try {
+ *         Transformer transformer = TransformerFactory.newInstance().newTransformer(
+ *             new StreamSource(stylesheet));
+ *         TraxSource in = new TraxSource(source);
+ *         Writer out = new StringWriter();
+ *         transformer.transform(in, new StreamResult(out));
+ *         return out.toString();
+ *     } catch (TransformerException e) {
+ *         throw new RuntimeException("XSLT Transformation failed", e);
+ *     }
+ * }
+ * 
+ * + * @author Laurent Bihanic + */ +public class TraxSource extends SAXSource { + + /** + * If {@link javax.xml.transform.TransformerFactory#getFeature} returns true + * when passed this value as an argument, the Transformer natively supports XStream. + *

+ * Note: This implementation does not override the + * {@link SAXSource#FEATURE} value defined by its superclass to be considered as a SAXSource + * by Transformer implementations not natively supporting this XStream-specific source + *

+ */ + public final static String XSTREAM_FEATURE = "http://com.thoughtworks.xstream/XStreamSource/feature"; + + /** + * The XMLReader object associated to this source or null if no XMLReader has + * yet been requested. + * + * @see #getXMLReader + */ + private XMLReader xmlReader = null; + + /** + * The configured XStream facade to use for serializing objects. + */ + private XStream xstream = null; + + /** + * The list of Java objects to be serialized. + */ + private List source = null; + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Creates a XStream TrAX source. + */ + public TraxSource() { + super(new InputSource()); + } + + /** + * Creates a XStream TrAX source, specifying the object to marshal. + * + * @param source the object to marshal. + * @throws IllegalArgumentException if source is null. + * @see #setSource(java.lang.Object) + */ + public TraxSource(Object source) { + super(new InputSource()); + + this.setSource(source); + } + + /** + * Creates a XStream TrAX source, specifying the object to marshal and a configured (with + * aliases) XStream facade. + * + * @param source the object to marshal. + * @param xstream a configured XStream facade. + * @throws IllegalArgumentException if source or xstream is + * null. + * @see #setSource(java.lang.Object) + * @see #setXStream(com.thoughtworks.xstream.XStream) + */ + public TraxSource(Object source, XStream xstream) { + super(new InputSource()); + + this.setSource(source); + this.setXStream(xstream); + } + + /** + * Creates a XStream TrAX source, setting the objects to marshal. + * + * @param source the list of objects to marshal. + * @throws IllegalArgumentException if source is null or + * empty. + * @see #setSourceAsList(java.util.List) + */ + public TraxSource(List source) { + super(new InputSource()); + + this.setSourceAsList(source); + } + + /** + * Creates a XStream TrAX source, setting the objects to marshal and a configured (with + * aliases) XStream facade. + * + * @param source the list of objects to marshal. + * @param xstream a configured XStream facade. + * @throws IllegalArgumentException if source or xstream is + * null or source is empty. + * @see #setSourceAsList(java.util.List) + * @see #setXStream(com.thoughtworks.xstream.XStream) + */ + public TraxSource(List source, XStream xstream) { + super(new InputSource()); + + this.setSourceAsList(source); + this.setXStream(xstream); + } + + // ------------------------------------------------------------------------- + // SAXSource overwritten methods + // ------------------------------------------------------------------------- + + /** + * Sets the SAX InputSource to be used for the Source. + *

+ * As this implementation only + * supports object lists as data source, this method always throws an + * {@link UnsupportedOperationException}. + *

+ * + * @param inputSource a valid InputSource reference. + * @throws UnsupportedOperationException always! + */ + public void setInputSource(InputSource inputSource) { + throw new UnsupportedOperationException(); + } + + /** + * Set the XMLReader to be used for the Source. + *

+ * As this implementation only supports + * object lists as data source, this method throws an {@link UnsupportedOperationException} + * if the provided reader object does not implement the SAX {@link XMLFilter} interface. + * Otherwise, a {@link SaxWriter} instance will be attached as parent of the filter chain. + *

+ * + * @param reader a valid XMLReader or XMLFilter reference. + * @throws UnsupportedOperationException if reader is not a SAX + * {@link XMLFilter}. + * @see #getXMLReader + */ + public void setXMLReader(XMLReader reader) { + this.createXMLReader(reader); + } + + /** + * Returns the XMLReader to be used for the Source. + *

+ * This implementation returns a + * specific XMLReader ({@link SaxWriter}) generating the XML from a list of input objects. + *

+ * + * @return an XMLReader generating the XML from a list of input objects. + */ + public XMLReader getXMLReader() { + if (this.xmlReader == null) { + this.createXMLReader(null); + } + return this.xmlReader; + } + + // ------------------------------------------------------------------------- + // Specific implementation + // ------------------------------------------------------------------------- + + /** + * Sets the XStream facade to use when marshalling objects. + * + * @param xstream a configured XStream facade. + * @throws IllegalArgumentException if xstream is null. + */ + public void setXStream(XStream xstream) { + if (xstream == null) { + throw new IllegalArgumentException("xstream"); + } + this.xstream = xstream; + + this.configureXMLReader(); + } + + /** + * Sets the object to marshal. + * + * @param obj the object to marshal. + * @throws IllegalArgumentException if source is null. + */ + public void setSource(Object obj) { + if (obj == null) { + throw new IllegalArgumentException("obj"); + } + List list = new ArrayList(1); + list.add(obj); + + this.setSourceAsList(list); + } + + /** + * Sets the list of objects to marshal. + *

+ * When dealing with non-text input (such as SAX + * or DOM), XSLT processors support multiple root node children for the source tree (see section 3.1 of the "XSL + * Transformations (XSLT) Version 1.0" specification. Using a list of objects as source + * makes use of this feature and allows creating XML documents merging the XML serialization + * of several Java objects. + * + * @param list the list of objects to marshal. + * @throws IllegalArgumentException if source is null or + * empty. + */ + public void setSourceAsList(List list) { + if ((list == null) || (list.isEmpty())) { + throw new IllegalArgumentException("list"); + } + this.source = list; + + this.configureXMLReader(); + } + + private void createXMLReader(XMLReader filterChain) { + if (filterChain == null) { + this.xmlReader = new SaxWriter(); + } else { + if (filterChain instanceof XMLFilter) { + // Connect the filter chain to a document reader. + XMLFilter filter = (XMLFilter)filterChain; + while (filter.getParent() instanceof XMLFilter) { + filter = (XMLFilter)(filter.getParent()); + } + if (!(filter.getParent() instanceof SaxWriter)) { + filter.setParent(new SaxWriter()); + } + + // Read XML data from filter chain. + this.xmlReader = filterChain; + } else { + throw new UnsupportedOperationException(); + } + } + this.configureXMLReader(); + } + + private void configureXMLReader() { + if (this.xmlReader != null) { + try { + if (this.xstream != null) { + this.xmlReader.setProperty( + SaxWriter.CONFIGURED_XSTREAM_PROPERTY, this.xstream); + } + if (this.source != null) { + this.xmlReader.setProperty( + SaxWriter.SOURCE_OBJECT_LIST_PROPERTY, this.source); + } + } catch (SAXException e) { + throw new IllegalArgumentException(e.getMessage()); + } + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/WstxDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/WstxDriver.java new file mode 100644 index 0000000..fd9b316 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/WstxDriver.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. April 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.ctc.wstx.stax.WstxInputFactory; +import com.ctc.wstx.stax.WstxOutputFactory; +import com.thoughtworks.xstream.io.naming.NameCoder; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; + +/** + * A driver using the Woodstox StAX implementation. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class WstxDriver extends StaxDriver { + + public WstxDriver() { + super(); + } + + /** + * @deprecated As of 1.4.6 use {@link #WstxDriver(QNameMap, NameCoder)} + */ + public WstxDriver(QNameMap qnameMap, XmlFriendlyNameCoder nameCoder) { + super(qnameMap, nameCoder); + } + + /** + * @since 1.4.6 + */ + public WstxDriver(QNameMap qnameMap, NameCoder nameCoder) { + super(qnameMap, nameCoder); + } + + public WstxDriver(QNameMap qnameMap) { + super(qnameMap); + } + + /** + * @deprecated As of 1.4.6 use {@link #WstxDriver(NameCoder)} + */ + public WstxDriver(XmlFriendlyNameCoder nameCoder) { + super(nameCoder); + } + + /** + * @since 1.4.6 + */ + public WstxDriver(NameCoder nameCoder) { + super(nameCoder); + } + + protected XMLInputFactory createInputFactory() { + return new WstxInputFactory(); + } + + protected XMLOutputFactory createOutputFactory() { + return new WstxOutputFactory(); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/XStream11NameCoder.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/XStream11NameCoder.java new file mode 100644 index 0000000..f4ec7fe --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/XStream11NameCoder.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. August 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + + +/** + * A XmlFriendlyNameCoder to support backward compatibility with XStream 1.1. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class XStream11NameCoder extends XmlFriendlyNameCoder { + + /** + * {@inheritDoc} Noop implementation that does not decode. Used for XStream 1.1 + * compatibility. + */ + public String decodeAttribute(String attributeName) { + return attributeName; + } + + /** + * {@inheritDoc} Noop implementation that does not decode. Used for XStream 1.1 + * compatibility. + */ + public String decodeNode(String elementName) { + return elementName; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/XStream11XmlFriendlyReplacer.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/XStream11XmlFriendlyReplacer.java new file mode 100644 index 0000000..ae3404a --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/XStream11XmlFriendlyReplacer.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. April 2006 by Mauro Talevi + */ +package com.thoughtworks.xstream.io.xml; + +/** + * Allows replacement of Strings in xml-friendly drivers to provide compatibility with XStream + * 1.1 format + * + * @author Mauro Talevi + * @since 1.2 + * @deprecated As of 1.4, use {@link XStream11NameCoder} instead + */ +public class XStream11XmlFriendlyReplacer extends XmlFriendlyReplacer { + + /** + * Default constructor. + * + * @deprecated As of 1.4, use {@link XStream11NameCoder} instead + */ + public XStream11XmlFriendlyReplacer() { + } + + /** + * {@inheritDoc} Noop implementation that does not decode. Used for XStream 1.1 + * compatibility. + */ + public String decodeAttribute(String attributeName) { + return attributeName; + } + + /** + * {@inheritDoc} Noop implementation that does not decode. Used for XStream 1.1 + * compatibility. + */ + public String decodeNode(String elementName) { + return elementName; + } + + /** + * Noop implementation that does not unescape name. Used for XStream 1.1 compatibility. + * + * @param name the name of attribute or node + * @return The String with unescaped name + */ + public String unescapeName(String name) { + return name; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/XmlFriendlyNameCoder.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/XmlFriendlyNameCoder.java new file mode 100644 index 0000000..bb64a2d --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/XmlFriendlyNameCoder.java @@ -0,0 +1,327 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. August 2009 by Joerg Schaible, copied from XmlFriendlyReplacer. + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; +import com.thoughtworks.xstream.io.naming.NameCoder; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + + +/** + * Encode and decode tag and attribute names in XML drivers. + *

+ * This NameCoder is designed to ensure the correct encoding and decoding of names used for Java + * types and fields to XML tags and attribute names. + *

+ *

+ * The default replacements are: + *

+ *
    + *
  • $ (dollar) chars are replaced with _- (underscore dash) string.
  • + *
  • _ (underscore) chars are replaced with __ (double underscore) string.
  • + *
  • other characters that are invalid in XML names are encoded with _.XXXX (underscore + * dot followed by hex representation of character).
  • + *
+ * + * @author Jörg Schaible + * @author Mauro Talevi + * @author Tatu Saloranta + * @author Michael Schnell + * @see XML 1.0 name definition + * @see XML 1.1 name definition + * @see Java + * identifier definition + * @since 1.4 + */ +public class XmlFriendlyNameCoder implements NameCoder, Cloneable { + private static final IntPair[] XML_NAME_START_CHAR_BOUNDS; + private static final IntPair[] XML_NAME_CHAR_EXTRA_BOUNDS; + static { + class IntPairList extends ArrayList { + void add(int min, int max) { + super.add(new IntPair(min, max)); + } + + void add(char cp) { + super.add(new IntPair(cp, cp)); + } + } + + // legal characters in XML names according to + // http://www.w3.org/TR/REC-xml/#NT-Name and + // http://www.w3.org/TR/xml11/#NT-Name + IntPairList list = new IntPairList(); + + list.add(':'); + list.add('A', 'Z'); + list.add('a', 'z'); + list.add('_'); + + list.add(0xC0, 0xD6); + list.add(0xD8, 0xF6); + list.add(0xF8, 0x2FF); + list.add(0x370, 0x37D); + list.add(0x37F, 0x1FFF); + list.add(0x200C, 0x200D); + list.add(0x2070, 0x218F); + list.add(0x2C00, 0x2FEF); + list.add(0x3001, 0xD7FF); + list.add(0xF900, 0xFDCF); + list.add(0xFDF0, 0xFFFD); + list.add(0x10000, 0xEFFFF); + XML_NAME_START_CHAR_BOUNDS = (IntPair[])list.toArray(new IntPair[list.size()]); + + list.clear(); + list.add('-'); + list.add('.'); + list.add('0', '9'); + list.add('\u00b7'); + list.add(0x0300, 0x036F); + list.add(0x203F, 0x2040); + XML_NAME_CHAR_EXTRA_BOUNDS = (IntPair[])list.toArray(new IntPair[list.size()]); + } + + private final String dollarReplacement; + private final String escapeCharReplacement; + private transient Map escapeCache; + private transient Map unescapeCache; + private final String hexPrefix; + + /** + * Construct a new XmlFriendlyNameCoder. + * + * @since 1.4 + */ + public XmlFriendlyNameCoder() { + this("_-", "__"); + } + + /** + * Construct a new XmlFriendlyNameCoder with custom replacement strings for dollar and the + * escape character. + * + * @param dollarReplacement + * @param escapeCharReplacement + * @since 1.4 + */ + public XmlFriendlyNameCoder(String dollarReplacement, String escapeCharReplacement) { + this(dollarReplacement, escapeCharReplacement, "_."); + } + + /** + * Construct a new XmlFriendlyNameCoder with custom replacement strings for dollar, the + * escape character and the prefix for hexadecimal encoding of invalid characters in XML + * names. + * + * @param dollarReplacement + * @param escapeCharReplacement + * @since 1.4 + */ + public XmlFriendlyNameCoder( + String dollarReplacement, String escapeCharReplacement, String hexPrefix) { + this.dollarReplacement = dollarReplacement; + this.escapeCharReplacement = escapeCharReplacement; + this.hexPrefix = hexPrefix; + readResolve(); + } + + /** + * {@inheritDoc} + */ + public String decodeAttribute(String attributeName) { + return decodeName(attributeName); + } + + /** + * {@inheritDoc} + */ + public String decodeNode(String elementName) { + return decodeName(elementName); + } + + /** + * {@inheritDoc} + */ + public String encodeAttribute(String name) { + return encodeName(name); + } + + /** + * {@inheritDoc} + */ + public String encodeNode(String name) { + return encodeName(name); + } + + private String encodeName(String name) { + String s = (String)escapeCache.get(name); + if (s == null) { + final int length = name.length(); + + // First, fast (common) case: nothing to escape + int i = 0; + + for (; i < length; i++ ) { + char c = name.charAt(i); + if (c == '$' || c == '_' || c <= 27 || c >= 127) { + break; + } + } + + if (i == length) { + return name; + } + + // Otherwise full processing + final StringBuffer result = new StringBuffer(length + 8); + + // We know first N chars are safe + if (i > 0) { + result.append(name.substring(0, i)); + } + + for (; i < length; i++ ) { + char c = name.charAt(i); + if (c == '$') { + result.append(dollarReplacement); + } else if (c == '_') { + result.append(escapeCharReplacement); + } else if ((i == 0 && !isXmlNameStartChar(c)) || (i > 0 && !isXmlNameChar(c))) { + result.append(hexPrefix); + if (c < 16) result.append("000"); + else if (c < 256) result.append("00"); + else if (c < 4096) result.append("0"); + result.append(Integer.toHexString(c)); + } else { + result.append(c); + } + } + s = result.toString(); + escapeCache.put(name, s); + } + return s; + } + + private String decodeName(String name) { + String s = (String)unescapeCache.get(name); + if (s == null) { + final char dollarReplacementFirstChar = dollarReplacement.charAt(0); + final char escapeReplacementFirstChar = escapeCharReplacement.charAt(0); + final char hexPrefixFirstChar = hexPrefix.charAt(0); + final int length = name.length(); + + // First, fast (common) case: nothing to decode + int i = 0; + + for (; i < length; i++ ) { + char c = name.charAt(i); + // We'll do a quick check for potential match + if (c == dollarReplacementFirstChar + || c == escapeReplacementFirstChar + || c == hexPrefixFirstChar) { + // and if it might be a match, just quit, will check later on + break; + } + } + + if (i == length) { + return name; + } + + // Otherwise full processing + final StringBuffer result = new StringBuffer(length + 8); + + // We know first N chars are safe + if (i > 0) { + result.append(name.substring(0, i)); + } + + for (; i < length; i++ ) { + char c = name.charAt(i); + if (c == dollarReplacementFirstChar && name.startsWith(dollarReplacement, i)) { + i += dollarReplacement.length() - 1; + result.append('$'); + } else if (c == hexPrefixFirstChar && name.startsWith(hexPrefix, i)) { + i += hexPrefix.length(); + c = (char)Integer.parseInt(name.substring(i, i + 4), 16); + i += 3; + result.append(c); + } else if (c == escapeReplacementFirstChar + && name.startsWith(escapeCharReplacement, i)) { + i += escapeCharReplacement.length() - 1; + result.append('_'); + } else { + result.append(c); + } + } + + s = result.toString(); + unescapeCache.put(name, s); + } + return s; + } + + public Object clone() { + try { + XmlFriendlyNameCoder coder = (XmlFriendlyNameCoder)super.clone(); + coder.readResolve(); + return coder; + + } catch (CloneNotSupportedException e) { + throw new ObjectAccessException("Cannot clone XmlFriendlyNameCoder", e); + } + } + + private Object readResolve() { + escapeCache = createCacheMap(); + unescapeCache = createCacheMap(); + return this; + } + + protected Map createCacheMap() { + return new HashMap(); + } + + private static class IntPair { + int min; + int max; + + public IntPair(int min, int max) { + this.min = min; + this.max = max; + } + } + + private static boolean isXmlNameStartChar(int cp) { + return isInNameCharBounds(cp, XML_NAME_START_CHAR_BOUNDS); + } + + private static boolean isXmlNameChar(int cp) { + if (isXmlNameStartChar(cp)) { + return true; + } + return isInNameCharBounds(cp, XML_NAME_CHAR_EXTRA_BOUNDS); + } + + private static boolean isInNameCharBounds(int cp, IntPair[] nameCharBounds) { + for (int i = 0; i < nameCharBounds.length; ++i) { + IntPair p = nameCharBounds[i]; + if (cp >= p.min && cp <= p.max) { + return true; + } + } + return false; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/XmlFriendlyReader.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/XmlFriendlyReader.java new file mode 100644 index 0000000..9cc4d83 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/XmlFriendlyReader.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +/** + * An interface for a {@link com.thoughtworks.xstream.io.HierarchicalStreamReader} supporting + * XML-friendly names. + * + * @author Jörg Schaible + * @author Mauro Talevi + * @since 1.3 + * @deprecated As of 1.4 + */ +public interface XmlFriendlyReader { + + /** + * Unescapes XML-friendly name (node or attribute) + * + * @param name the escaped XML-friendly name + * @return An unescaped name with original characters + * @deprecated As of 1.4 + */ + String unescapeXmlName(String name); + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/XmlFriendlyReplacer.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/XmlFriendlyReplacer.java new file mode 100644 index 0000000..0e2fce8 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/XmlFriendlyReplacer.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 17. April 2006 by Mauro Talevi + */ +package com.thoughtworks.xstream.io.xml; + +/** + * Allows replacement of Strings in XML-friendly drivers. The default replacements are: + *
    + *
  • $ (dollar) chars are replaced with _- (underscore dash) string.
    + *
  • + *
  • _ (underscore) chars are replaced with __ (double underscore) string.
    + *
  • + *
+ * + * @author Mauro Talevi + * @author Jörg Schaible + * @author Tatu Saloranta + * @since 1.2 + * @deprecated As of 1.4, use {@link XmlFriendlyNameCoder} instead + */ +public class XmlFriendlyReplacer extends XmlFriendlyNameCoder { + + /** + * Default constructor. + * + * @deprecated As of 1.4, use {@link XmlFriendlyNameCoder} instead + */ + public XmlFriendlyReplacer() { + this("_-", "__"); + } + + /** + * Creates an XmlFriendlyReplacer with custom replacements + * + * @param dollarReplacement the replacement for '$' + * @param underscoreReplacement the replacement for '_' + * @deprecated As of 1.4, use {@link XmlFriendlyNameCoder} instead + */ + public XmlFriendlyReplacer(String dollarReplacement, String underscoreReplacement) { + super(dollarReplacement, underscoreReplacement); + } + + /** + * Escapes name substituting '$' and '_' with replacement strings + * + * @param name the name of attribute or node + * @return The String with the escaped name + * @deprecated As of 1.4, use {@link XmlFriendlyNameCoder} instead + */ + public String escapeName(String name) { + return super.encodeNode(name); + } + + /** + * Unescapes name re-enstating '$' and '_' when replacement strings are found + * + * @param name the name of attribute or node + * @return The String with unescaped name + * @deprecated As of 1.4, use {@link XmlFriendlyNameCoder} instead + */ + public String unescapeName(String name) { + return super.decodeNode(name); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/XmlFriendlyWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/XmlFriendlyWriter.java new file mode 100644 index 0000000..1ea0cf5 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/XmlFriendlyWriter.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +/** + * An interface for a {@link com.thoughtworks.xstream.io.HierarchicalStreamWriter} supporting + * XML-friendly names. + * + * @author Jörg Schaible + * @author Mauro Talevi + * @since 1.3 + * @deprecated As of 1.4 + */ +public interface XmlFriendlyWriter { + + /** + * Escapes XML name (node or attribute) to be XML-friendly + * + * @param name the unescaped XML name + * @return An escaped name with original characters replaced + * @deprecated As of 1.4 + */ + String escapeXmlName(String name); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/XomDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/XomDriver.java new file mode 100644 index 0000000..5700ea6 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/XomDriver.java @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 12. April 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.Writer; +import java.net.URL; + +import nu.xom.Builder; +import nu.xom.Document; +import nu.xom.ParsingException; +import nu.xom.ValidityException; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.naming.NameCoder; + +public class XomDriver extends AbstractXmlDriver { + + private final Builder builder; + + public XomDriver() { + this(new Builder()); + } + + public XomDriver(Builder builder) { + this(builder, new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + public XomDriver(NameCoder nameCoder) { + this(new Builder(), nameCoder); + } + + /** + * @since 1.4 + */ + public XomDriver(Builder builder, NameCoder nameCoder) { + super(nameCoder); + this.builder = builder; + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link #XomDriver(Builder, NameCoder)} instead + */ + public XomDriver(XmlFriendlyReplacer replacer) { + this(new Builder(), replacer); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link #XomDriver(Builder, NameCoder)} instead + */ + public XomDriver(Builder builder, XmlFriendlyReplacer replacer) { + this((NameCoder)replacer); + } + + protected Builder getBuilder() { + return this.builder; + } + + public HierarchicalStreamReader createReader(Reader text) { + try { + Document document = builder.build(text); + return new XomReader(document, getNameCoder()); + } catch (ValidityException e) { + throw new StreamException(e); + } catch (ParsingException e) { + throw new StreamException(e); + } catch (IOException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamReader createReader(InputStream in) { + try { + Document document = builder.build(in); + return new XomReader(document, getNameCoder()); + } catch (ValidityException e) { + throw new StreamException(e); + } catch (ParsingException e) { + throw new StreamException(e); + } catch (IOException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamReader createReader(URL in) { + try { + Document document = builder.build(in.toExternalForm()); + return new XomReader(document, getNameCoder()); + } catch (ValidityException e) { + throw new StreamException(e); + } catch (ParsingException e) { + throw new StreamException(e); + } catch (IOException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamReader createReader(File in) { + try { + Document document = builder.build(in); + return new XomReader(document, getNameCoder()); + } catch (ValidityException e) { + throw new StreamException(e); + } catch (ParsingException e) { + throw new StreamException(e); + } catch (IOException e) { + throw new StreamException(e); + } + } + + public HierarchicalStreamWriter createWriter(final Writer out) { + return new PrettyPrintWriter(out, getNameCoder()); + } + + public HierarchicalStreamWriter createWriter(final OutputStream out) { + return new PrettyPrintWriter(new OutputStreamWriter(out), getNameCoder()); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/XomReader.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/XomReader.java new file mode 100644 index 0000000..4e9ad16 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/XomReader.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 02. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.naming.NameCoder; +import nu.xom.Document; +import nu.xom.Element; +import nu.xom.Elements; +import nu.xom.Node; +import nu.xom.Text; + +public class XomReader extends AbstractDocumentReader { + + private Element currentElement; + + public XomReader(Element rootElement) { + super(rootElement); + } + + public XomReader(Document document) { + super(document.getRootElement()); + } + + /** + * @since 1.4 + */ + public XomReader(Element rootElement, NameCoder nameCoder) { + super(rootElement, nameCoder); + } + + /** + * @since 1.4 + */ + public XomReader(Document document, NameCoder nameCoder) { + super(document.getRootElement(), nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link XomReader#XomReader(Element, NameCoder)} instead. + */ + public XomReader(Element rootElement, XmlFriendlyReplacer replacer) { + this(rootElement, (NameCoder)replacer); + } + + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link XomReader#XomReader(Element, NameCoder)} instead. + */ + public XomReader(Document document, XmlFriendlyReplacer replacer) { + this(document.getRootElement(), (NameCoder)replacer); + } + + public String getNodeName() { + return decodeNode(currentElement.getLocalName()); + } + + public String getValue() { + // currentElement.getValue() not used as this includes text of child elements, which we don't want. + StringBuffer result = new StringBuffer(); + int childCount = currentElement.getChildCount(); + for(int i = 0; i < childCount; i++) { + Node child = currentElement.getChild(i); + if (child instanceof Text) { + Text text = (Text) child; + result.append(text.getValue()); + } + } + return result.toString(); + } + + public String getAttribute(String name) { + return currentElement.getAttributeValue(encodeAttribute(name)); + } + + public String getAttribute(int index) { + return currentElement.getAttribute(index).getValue(); + } + + public int getAttributeCount() { + return currentElement.getAttributeCount(); + } + + public String getAttributeName(int index) { + return decodeAttribute(currentElement.getAttribute(index).getQualifiedName()); + } + + protected int getChildCount() { + return currentElement.getChildElements().size(); + } + + protected Object getParent() { + return currentElement.getParent(); + } + + protected Object getChild(int index) { + return currentElement.getChildElements().get(index); + } + + protected void reassignCurrentElement(Object current) { + currentElement = (Element) current; + } + + public String peekNextChild() { + Elements children = currentElement.getChildElements(); + if (null == children || children.size() == 0) { + return null; + } + return decodeNode(children.get(0).getLocalName()); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/XomWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/XomWriter.java new file mode 100644 index 0000000..d4ba9b0 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/XomWriter.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.naming.NameCoder; + +import nu.xom.Attribute; +import nu.xom.Element; + + +public class XomWriter extends AbstractDocumentWriter { + + /** + * @since 1.2.1 + */ + public XomWriter() { + this(null); + } + + public XomWriter(final Element parentElement) { + this(parentElement, new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + public XomWriter(final Element parentElement, final NameCoder nameCoder) { + super(parentElement, nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link XomWriter#XomWriter(Element, NameCoder)} instead + */ + public XomWriter(final Element parentElement, final XmlFriendlyReplacer replacer) { + this(parentElement, (NameCoder)replacer); + } + + protected Object createNode(final String name) { + final Element newNode = new Element(encodeNode(name)); + final Element top = top(); + if (top != null){ + top().appendChild(newNode); + } + return newNode; + } + + public void addAttribute(final String name, final String value) { + top().addAttribute(new Attribute(encodeAttribute(name), value)); + } + + public void setValue(final String text) { + top().appendChild(text); + } + + private Element top() { + return (Element)getCurrent(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/Xpp3DomDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/Xpp3DomDriver.java new file mode 100644 index 0000000..c5bb301 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/Xpp3DomDriver.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. May 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.HierarchicalStreamDriver; +import com.thoughtworks.xstream.io.naming.NameCoder; + +import org.xmlpull.mxp1.MXParser; +import org.xmlpull.v1.XmlPullParser; + +/** + * A {@link HierarchicalStreamDriver} for XPP DOM using the Xpp3 parser. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class Xpp3DomDriver extends AbstractXppDomDriver { + + /** + * Construct an Xpp3DomDriver. + * + * @since 1.4 + */ + public Xpp3DomDriver() { + super(new XmlFriendlyNameCoder()); + } + + /** + * Construct an Xpp3DomDriver. + * + * @param nameCoder the replacer for XML friendly names + * @since 1.4 + */ + public Xpp3DomDriver(NameCoder nameCoder) { + super(nameCoder); + } + + /** + * {@inheritDoc} + */ + protected XmlPullParser createParser() { + return new MXParser(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/Xpp3Driver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/Xpp3Driver.java new file mode 100644 index 0000000..83e5354 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/Xpp3Driver.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. April 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + + +import com.thoughtworks.xstream.io.HierarchicalStreamDriver; +import com.thoughtworks.xstream.io.naming.NameCoder; + +import org.xmlpull.mxp1.MXParser; +import org.xmlpull.v1.XmlPullParser; + + +/** + * A {@link HierarchicalStreamDriver} using the Xpp3 parser. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class Xpp3Driver extends AbstractXppDriver { + + /** + * Construct an Xpp3Driver. + * + * @since 1.4 + */ + public Xpp3Driver() { + super(new XmlFriendlyNameCoder()); + } + + /** + * Construct an Xpp3Driver. + * + * @param nameCoder the replacer for XML friendly names + * @since 1.4 + */ + public Xpp3Driver(NameCoder nameCoder) { + super(nameCoder); + } + + /** + * {@inheritDoc} + */ + protected XmlPullParser createParser() { + return new MXParser(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDomDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDomDriver.java new file mode 100644 index 0000000..cca241d --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDomDriver.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.HierarchicalStreamDriver; +import com.thoughtworks.xstream.io.naming.NameCoder; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + +/** + * A {@link HierarchicalStreamDriver} for XPP DOM using the XmlPullParserFactory to locate an parser. + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class XppDomDriver extends AbstractXppDomDriver { + + private static XmlPullParserFactory factory; + + public XppDomDriver() { + super(new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + public XppDomDriver(NameCoder nameCoder) { + super(nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link XppDomDriver#XppDomDriver(NameCoder)} instead. + */ + public XppDomDriver(XmlFriendlyReplacer replacer) { + super(replacer); + } + + /** + * {@inheritDoc} + */ + protected synchronized XmlPullParser createParser() throws XmlPullParserException { + if (factory == null) { + factory = XmlPullParserFactory.newInstance(null, XppDomDriver.class); + } + return factory.newPullParser(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDomReader.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDomReader.java new file mode 100644 index 0000000..f126910 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDomReader.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.naming.NameCoder; +import com.thoughtworks.xstream.io.xml.xppdom.XppDom; + +/** + * @author Jason van Zyl + */ +public class XppDomReader extends AbstractDocumentReader { + + private XppDom currentElement; + + public XppDomReader(XppDom xppDom) { + super(xppDom); + } + + /** + * @since 1.4 + */ + public XppDomReader(XppDom xppDom, NameCoder nameCoder) { + super(xppDom, nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link XppDomReader#XppDomReader(XppDom, NameCoder)} instead. + */ + public XppDomReader(XppDom xppDom, XmlFriendlyReplacer replacer) { + this(xppDom, (NameCoder)replacer); + } + + public String getNodeName() { + return decodeNode(currentElement.getName()); + } + + public String getValue() { + String text = null; + + try { + text = currentElement.getValue(); + } catch (Exception e) { + // do nothing. + } + + return text == null ? "" : text; + } + + public String getAttribute(String attributeName) { + return currentElement.getAttribute(encodeAttribute(attributeName)); + } + + public String getAttribute(int index) { + return currentElement.getAttribute(currentElement.getAttributeNames()[index]); + } + + public int getAttributeCount() { + return currentElement.getAttributeNames().length; + } + + public String getAttributeName(int index) { + return decodeAttribute(currentElement.getAttributeNames()[index]); + } + + protected Object getParent() { + return currentElement.getParent(); + } + + protected Object getChild(int index) { + return currentElement.getChild(index); + } + + protected int getChildCount() { + return currentElement.getChildCount(); + } + + protected void reassignCurrentElement(Object current) { + this.currentElement = (XppDom) current; + } + + public String peekNextChild() { + if (currentElement.getChildCount() == 0) { + return null; + } + return decodeNode(currentElement.getChild(0).getName()); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDomWriter.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDomWriter.java new file mode 100644 index 0000000..f72410d --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDomWriter.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.naming.NameCoder; +import com.thoughtworks.xstream.io.xml.xppdom.XppDom; + + +public class XppDomWriter extends AbstractDocumentWriter { + public XppDomWriter() { + this(null, new XmlFriendlyNameCoder()); + } + + /** + * @since 1.2.1 + */ + public XppDomWriter(final XppDom parent) { + this(parent, new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + public XppDomWriter(final NameCoder nameCoder) { + this(null, nameCoder); + } + + /** + * @since 1.4 + */ + public XppDomWriter(final XppDom parent, final NameCoder nameCoder) { + super(parent, nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link XppDomWriter#XppDomWriter(NameCoder)} instead + */ + public XppDomWriter(final XmlFriendlyReplacer replacer) { + this(null, replacer); + } + + /** + * @since 1.2.1 + * @deprecated As of 1.4 use {@link XppDomWriter#XppDomWriter(XppDom, NameCoder)} instead. + */ + public XppDomWriter(final XppDom parent, final XmlFriendlyReplacer replacer) { + this(parent, (NameCoder)replacer); + } + + public XppDom getConfiguration() { + return (XppDom)getTopLevelNodes().get(0); + } + + protected Object createNode(final String name) { + final XppDom newNode = new XppDom(encodeNode(name)); + final XppDom top = top(); + if (top != null) { + top().addChild(newNode); + } + return newNode; + } + + public void setValue(final String text) { + top().setValue(text); + } + + public void addAttribute(final String key, final String value) { + top().setAttribute(encodeAttribute(key), value); + } + + private XppDom top() { + return (XppDom)getCurrent(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDriver.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDriver.java new file mode 100644 index 0000000..0aad911 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/XppDriver.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 08. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + + +import com.thoughtworks.xstream.io.HierarchicalStreamDriver; +import com.thoughtworks.xstream.io.naming.NameCoder; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + + +/** + * A {@link HierarchicalStreamDriver} using the XmlPullParserFactory to locate an XML Pull Parser. + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class XppDriver extends AbstractXppDriver { + + private static XmlPullParserFactory factory; + + public XppDriver() { + super(new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + public XppDriver(NameCoder nameCoder) { + super(nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link XppDriver#XppDriver(NameCoder)} instead. + */ + public XppDriver(XmlFriendlyReplacer replacer) { + this((NameCoder)replacer); + } + + /** + * {@inheritDoc} + */ + protected synchronized XmlPullParser createParser() throws XmlPullParserException { + if (factory == null) { + factory = XmlPullParserFactory.newInstance(); + } + return factory.newPullParser(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/XppReader.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/XppReader.java new file mode 100644 index 0000000..804d19d --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/XppReader.java @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 08. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import java.io.IOException; +import java.io.Reader; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import com.thoughtworks.xstream.converters.ErrorWriter; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.naming.NameCoder; + +/** + * XStream reader that pulls directly from the stream using the XmlPullParser API. + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class XppReader extends AbstractPullReader { + + private final XmlPullParser parser; + private final Reader reader; + + /** + * Construct an XppReader. + * + * @param reader the reader with the input data + * @param parser the XPP parser to use + * @since 1.4 + */ + public XppReader(Reader reader, XmlPullParser parser) { + this(reader, parser, new XmlFriendlyNameCoder()); + } + + /** + * Construct an XppReader. + * + * @param reader the reader with the input data + * @param parser the XPP parser to use + * @param nameCoder the coder for XML friendly tag and attribute names + * @since 1.4 + */ + public XppReader(Reader reader, XmlPullParser parser, NameCoder nameCoder) { + super(nameCoder); + this.parser = parser; + this.reader = reader; + try { + parser.setInput(this.reader); + } catch (XmlPullParserException e) { + throw new StreamException(e); + } + moveDown(); + } + + /** + * @deprecated As of 1.4, use {@link #XppReader(Reader, XmlPullParser)} instead + */ + public XppReader(Reader reader) { + this(reader, new XmlFriendlyReplacer()); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link #XppReader(Reader, XmlPullParser, NameCoder)} instead + */ + public XppReader(Reader reader, XmlFriendlyReplacer replacer) { + super(replacer); + try { + parser = createParser(); + this.reader = reader; + parser.setInput(this.reader); + moveDown(); + } catch (XmlPullParserException e) { + throw new StreamException(e); + } + } + + /** + * To use another implementation of org.xmlpull.v1.XmlPullParser, override this method. + * @deprecated As of 1.4, use {@link #XppReader(Reader, XmlPullParser)} instead + */ + protected XmlPullParser createParser() { + Exception exception = null; + try { + return (XmlPullParser)Class.forName("org.xmlpull.mxp1.MXParser", true, XmlPullParser.class.getClassLoader()).newInstance(); + } catch (InstantiationException e) { + exception = e; + } catch (IllegalAccessException e) { + exception = e; + } catch (ClassNotFoundException e) { + exception = e; + } + throw new StreamException("Cannot create Xpp3 parser instance.", exception); + } + + protected int pullNextEvent() { + try { + switch(parser.next()) { + case XmlPullParser.START_DOCUMENT: + case XmlPullParser.START_TAG: + return START_NODE; + case XmlPullParser.END_DOCUMENT: + case XmlPullParser.END_TAG: + return END_NODE; + case XmlPullParser.TEXT: + return TEXT; + case XmlPullParser.COMMENT: + return COMMENT; + default: + return OTHER; + } + } catch (XmlPullParserException e) { + throw new StreamException(e); + } catch (IOException e) { + throw new StreamException(e); + } + } + + protected String pullElementName() { + return parser.getName(); + } + + protected String pullText() { + return parser.getText(); + } + + public String getAttribute(String name) { + return parser.getAttributeValue(null, encodeAttribute(name)); + } + + public String getAttribute(int index) { + return parser.getAttributeValue(index); + } + + public int getAttributeCount() { + return parser.getAttributeCount(); + } + + public String getAttributeName(int index) { + return decodeAttribute(parser.getAttributeName(index)); + } + + public void appendErrors(ErrorWriter errorWriter) { + errorWriter.add("line number", String.valueOf(parser.getLineNumber())); + } + + public void close() { + try { + reader.close(); + } catch (IOException e) { + throw new StreamException(e); + } + } + +} \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/xppdom/Xpp3Dom.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/xppdom/Xpp3Dom.java new file mode 100644 index 0000000..4c22086 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/xppdom/Xpp3Dom.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml.xppdom; + +/** + * Simple Document Object Model for XmlPullParser implementations. + * + * @author Jason van Zyl + * @author Joe Walnes + * @author Jörg Schaible + * @deprecated As of 1.4, use {@link XppDom} instead + */ +public class Xpp3Dom extends XppDom { + + /** + * @deprecated As of 1.4, use {@link XppDom} instead + */ + public Xpp3Dom(String name) { + super(name); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/xppdom/Xpp3DomBuilder.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/xppdom/Xpp3DomBuilder.java new file mode 100644 index 0000000..76f5869 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/xppdom/Xpp3DomBuilder.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml.xppdom; + +import org.xmlpull.mxp1.MXParser; +import org.xmlpull.v1.XmlPullParser; + +import java.io.Reader; + + +/** + * @author Jason van Zyl + * @author Joe Walnes + * @author Jörg Schaible + * @deprecated As of 1.4, use {@link XppDom#build(XmlPullParser)} instead + */ +public class Xpp3DomBuilder { + /** + * @deprecated As of 1.4, use {@link XppDom#build(XmlPullParser)} instead + */ + public static Xpp3Dom build(Reader reader) throws Exception { + XmlPullParser parser = new MXParser(); + parser.setInput(reader); + try { + return (Xpp3Dom)XppDom.build(parser); + } finally { + reader.close(); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/xppdom/XppDom.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/xppdom/XppDom.java new file mode 100644 index 0000000..654043d --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/xppdom/XppDom.java @@ -0,0 +1,239 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 02. May 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml.xppdom; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + + +/** + * Simple Document Object Model for XmlPullParser implementations. + * + * @author Jason van Zyl + * @author Joe Walnes + * @author Jörg Schaible + * @since 1.4 + */ +public class XppDom implements Serializable { + private static final long serialVersionUID = 1L; + + private String name; + private String value; + private Map attributes; + private List childList; + transient private Map childMap; + private XppDom parent; + + public XppDom(String name) { + this.name = name; + childList = new ArrayList(); + childMap = new HashMap(); + } + + // ---------------------------------------------------------------------- + // Name handling + // ---------------------------------------------------------------------- + + public String getName() { + return name; + } + + // ---------------------------------------------------------------------- + // Value handling + // ---------------------------------------------------------------------- + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + // ---------------------------------------------------------------------- + // Attribute handling + // ---------------------------------------------------------------------- + + public String[] getAttributeNames() { + if (null == attributes) { + return new String[0]; + } else { + return (String[])attributes.keySet().toArray(new String[0]); + } + } + + public String getAttribute(String name) { + return (null != attributes) ? (String)attributes.get(name) : null; + } + + public void setAttribute(String name, String value) { + if (null == attributes) { + attributes = new HashMap(); + } + + attributes.put(name, value); + } + + // ---------------------------------------------------------------------- + // Child handling + // ---------------------------------------------------------------------- + + public XppDom getChild(int i) { + return (XppDom)childList.get(i); + } + + public XppDom getChild(String name) { + return (XppDom)childMap.get(name); + } + + public void addChild(XppDom xpp3Dom) { + xpp3Dom.setParent(this); + childList.add(xpp3Dom); + childMap.put(xpp3Dom.getName(), xpp3Dom); + } + + public XppDom[] getChildren() { + if (null == childList) { + return new XppDom[0]; + } else { + return (XppDom[])childList.toArray(new XppDom[0]); + } + } + + public XppDom[] getChildren(String name) { + if (null == childList) { + return new XppDom[0]; + } else { + ArrayList children = new ArrayList(); + int size = this.childList.size(); + + for (int i = 0; i < size; i++ ) { + XppDom configuration = (XppDom)this.childList.get(i); + if (name.equals(configuration.getName())) { + children.add(configuration); + } + } + + return (XppDom[])children.toArray(new XppDom[0]); + } + } + + public int getChildCount() { + if (null == childList) { + return 0; + } + + return childList.size(); + } + + // ---------------------------------------------------------------------- + // Parent handling + // ---------------------------------------------------------------------- + + public XppDom getParent() { + return parent; + } + + public void setParent(XppDom parent) { + this.parent = parent; + } + + // ---------------------------------------------------------------------- + // Serialization + // ---------------------------------------------------------------------- + + Object readResolve() { + childMap = new HashMap(); + for (final Iterator iter = childList.iterator(); iter.hasNext();) { + final XppDom element = (XppDom)iter.next(); + childMap.put(element.getName(), element); + } + return this; + } + + // ---------------------------------------------------------------------- + // DOM builder + // ---------------------------------------------------------------------- + + /** + * Build an XPP DOM hierarchy. The {@link java.io.InputStream} or {@link java.io.Reader} + * used by the parser must have already been set. The method does not close it after reading + * the document's end. + * + * @param parser the XPP instance + * @throws XmlPullParserException if the parser turns into an invalid state or reads invalid + * XML + * @throws IOException if the data cannot be read + */ + public static XppDom build(XmlPullParser parser) throws XmlPullParserException, IOException { + List elements = new ArrayList(); + List values = new ArrayList(); + XppDom node = null; + + int eventType = parser.getEventType(); + while (eventType != XmlPullParser.END_DOCUMENT) { + if (eventType == XmlPullParser.START_TAG) { + String rawName = parser.getName(); + + // Use XppDom when deprecated Xpp3Dom is removed + XppDom child = new Xpp3Dom(rawName); + + int depth = elements.size(); + if (depth > 0) { + XppDom parent = (XppDom)elements.get(depth - 1); + parent.addChild(child); + } + + elements.add(child); + values.add(new StringBuffer()); + + int attributesSize = parser.getAttributeCount(); + for (int i = 0; i < attributesSize; i++ ) { + String name = parser.getAttributeName(i); + String value = parser.getAttributeValue(i); + child.setAttribute(name, value); + } + } else if (eventType == XmlPullParser.TEXT) { + int depth = values.size() - 1; + StringBuffer valueBuffer = (StringBuffer)values.get(depth); + valueBuffer.append(parser.getText()); + } else if (eventType == XmlPullParser.END_TAG) { + int depth = elements.size() - 1; + XppDom finalNode = (XppDom)elements.remove(depth); + String accumulatedValue = (values.remove(depth)).toString(); + + String finishedValue; + if (0 == accumulatedValue.length()) { + finishedValue = null; + } else { + finishedValue = accumulatedValue; + } + + finalNode.setValue(finishedValue); + if (0 == depth) { + node = finalNode; + } + } + + eventType = parser.next(); + } + + return node; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/xppdom/XppDomComparator.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/xppdom/XppDomComparator.java new file mode 100644 index 0000000..6574b51 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/xppdom/XppDomComparator.java @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 11. August 2011 by Joerg Schaible. + */ +package com.thoughtworks.xstream.io.xml.xppdom; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; + + +/** + * Comparator for {@link XppDom}. Comparator can trace the XPath where the comparison failed. + * + * @author Jörg Schaible + * @since 1.4.1 + */ +public class XppDomComparator implements Comparator { + private final ThreadLocal xpath; + + /** + * Creates a new Xpp3DomComparator object. + * + * @since 1.4.1 + */ + public XppDomComparator() { + this(null); + } + + /** + * Creates a new Xpp3DomComparator object with XPath identification. + * + * @param xpath the reference for the XPath + * @since 1.4.1 + */ + public XppDomComparator(final ThreadLocal xpath) { + this.xpath = xpath; + } + + public int compare(final Object dom1, final Object dom2) { + + final StringBuffer xpath = new StringBuffer("/"); + final int s = compareInternal((XppDom)dom1, (XppDom)dom2, xpath, -1); + if (this.xpath != null) { + if (s != 0) { + this.xpath.set(xpath.toString()); + } else { + this.xpath.set(null); + } + } + + return s; + } + + private int compareInternal(final XppDom dom1, final XppDom dom2, + final StringBuffer xpath, final int count) { + final int pathlen = xpath.length(); + final String name = dom1.getName(); + int s = name.compareTo(dom2.getName()); + xpath.append(name); + if (count >= 0) { + xpath.append('[').append(count).append(']'); + } + + if (s != 0) { + xpath.append('?'); + + return s; + } + + final String[] attributes = dom1.getAttributeNames(); + final String[] attributes2 = dom2.getAttributeNames(); + final int len = attributes.length; + s = attributes2.length - len; + if (s != 0) { + xpath.append("::count(@*)"); + + return s < 0 ? 1 : -1; + } + + Arrays.sort(attributes); + Arrays.sort(attributes2); + for (int i = 0; i < len; ++i) { + final String attribute = attributes[i]; + s = attribute.compareTo(attributes2[i]); + if (s != 0) { + xpath.append("[@").append(attribute).append("?]"); + + return s; + } + + s = dom1.getAttribute(attribute).compareTo(dom2.getAttribute(attribute)); + if (s != 0) { + xpath.append("[@").append(attribute).append(']'); + + return s; + } + } + + final int children = dom1.getChildCount(); + s = dom2.getChildCount() - children; + if (s != 0) { + xpath.append("::count(*)"); + + return s < 0 ? 1 : -1; + } + + if (children > 0) { + if (dom1.getValue() != null || dom2.getValue() != null) { + throw new IllegalArgumentException("XppDom cannot handle mixed mode at " + + xpath + + "::text()"); + } + + xpath.append('/'); + + final Map names = new HashMap(); + for (int i = 0; i < children; ++i) { + final XppDom child1 = dom1.getChild(i); + final XppDom child2 = dom2.getChild(i); + final String child = child1.getName(); + if (!names.containsKey(child)) { + names.put(child, new int[1]); + } + + s = compareInternal(child1, child2, xpath, ((int[])names.get(child))[0]++); + if (s != 0) { + return s; + } + } + } else { + final String value2 = dom2.getValue(); + final String value1 = dom1.getValue(); + if (value1 == null) { + s = value2 == null ? 0 : -1; + } else { + s = value2 == null ? 1 : value1.compareTo(value2); + } + + if (s != 0) { + xpath.append("::text()"); + + return s; + } + } + + xpath.setLength(pathlen); + + return s; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/io/xml/xppdom/XppFactory.java b/xstream/src/java/com/thoughtworks/xstream/io/xml/xppdom/XppFactory.java new file mode 100644 index 0000000..5b307f7 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/io/xml/xppdom/XppFactory.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 11. August 2011 by Joerg Schaible, code from XppDom. + */ +package com.thoughtworks.xstream.io.xml.xppdom; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.io.StringReader; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + +/** + * XmlPullParser utility methods. + * + * @author Jörg Schaible + * @since 1.4.1 + */ +public class XppFactory { + + /** + * Create a new XmlPullParser using the XPP factory. + * + * @return a new parser instance + * @throws XmlPullParserException if the factory fails + * @since 1.4.1 + */ + public static XmlPullParser createDefaultParser() throws XmlPullParserException { + XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); + return factory.newPullParser(); + } + + /** + * Build an XPP DOM hierarchy from a String. + * + * @param xml the XML data + * @throws XmlPullParserException if the default parser cannot be created or fails with invalid XML + * @throws IOException if the data cannot be read + * @see XppDom#build(XmlPullParser) + * @since 1.4.1 + */ + public static XppDom buildDom(String xml) throws XmlPullParserException, IOException { + return buildDom(new StringReader(xml)); + } + + /** + * Build an XPP DOM hierarchy from a Reader. + * + * @param r the reader + * @throws XmlPullParserException if the default parser cannot be created or fails with invalid XML + * @throws IOException if the data cannot be read + * @see XppDom#build(XmlPullParser) + * @since 1.4.1 + */ + public static XppDom buildDom(Reader r) throws XmlPullParserException, IOException { + XmlPullParser parser = createDefaultParser(); + parser.setInput(r); + return XppDom.build(parser); + } + + /** + * Build an XPP DOM hierarchy from an InputStream. + * + * @param in the input stream + * @param encoding the encoding of the input stream + * @throws XmlPullParserException if the default parser cannot be created or fails with invalid XML + * @throws IOException if the data cannot be read + * @see XppDom#build(XmlPullParser) + * @since 1.4.1 + */ + public static XppDom buildDom(InputStream in, String encoding) throws XmlPullParserException, IOException { + XmlPullParser parser = createDefaultParser(); + parser.setInput(in, encoding); + return XppDom.build(parser); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/AbstractAttributeAliasingMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/AbstractAttributeAliasingMapper.java new file mode 100644 index 0000000..05c8baa --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/AbstractAttributeAliasingMapper.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 09. October 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.mapper; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * Abstract base class for AttributeAliassingMapper and its system version. + * + * @author Jörg Schaible + * @since 1.3.1 + */ +public abstract class AbstractAttributeAliasingMapper extends MapperWrapper { + + protected final Map aliasToName = new HashMap(); + protected transient Map nameToAlias = new HashMap(); + + public AbstractAttributeAliasingMapper(Mapper wrapped) { + super(wrapped); + } + + public void addAliasFor(final String attributeName, final String alias) { + aliasToName.put(alias, attributeName); + nameToAlias.put(attributeName, alias); + } + + Object readResolve() { + nameToAlias = new HashMap(); + for (final Iterator iter = aliasToName.keySet().iterator(); iter.hasNext();) { + final Object alias = iter.next(); + nameToAlias.put(aliasToName.get(alias), alias); + } + return this; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/AbstractXmlFriendlyMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/AbstractXmlFriendlyMapper.java new file mode 100644 index 0000000..6725da3 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/AbstractXmlFriendlyMapper.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. May 2006 by Mauro Talevi + */ +package com.thoughtworks.xstream.mapper; + + +/** + * Mapper that ensures that all names in the serialization stream are XML friendly. + * The replacement chars and strings are: + *
    + *
  • $ (dollar) chars appearing in class names are replaced with _ (underscore) chars.
  • + *
  • $ (dollar) chars appearing in field names are replaced with _DOLLAR_ string.
  • + *
  • _ (underscore) chars appearing in field names are replaced with __ (double underscore) string.
  • + *
  • default as the prefix for class names with no package.
  • + *
+ * + * Note, this class is no longer in regular use for current XStream versions. It exists to provide backward compatibility + * to existing XML data written with older XStream versions. + * + * @author Joe Walnes + * @author Mauro Talevi + * @deprecated As of 1.4 use {@link com.thoughtworks.xstream.io.xml.XmlFriendlyReader} + */ +public class AbstractXmlFriendlyMapper extends MapperWrapper { + + private char dollarReplacementInClass = '-'; + private String dollarReplacementInField = "_DOLLAR_"; + private String underscoreReplacementInField = "__"; + private String noPackagePrefix = "default"; + + protected AbstractXmlFriendlyMapper(Mapper wrapped) { + super(wrapped); + } + + protected String escapeClassName(String className) { + // the $ used in inner class names is illegal as an xml element getNodeName + className = className.replace('$', dollarReplacementInClass); + + // special case for classes named $Blah with no package; <-Blah> is illegal XML + if (className.charAt(0) == dollarReplacementInClass) { + className = noPackagePrefix + className; + } + + return className; + } + + protected String unescapeClassName(String className) { + // special case for classes named $Blah with no package; <-Blah> is illegal XML + if (className.startsWith(noPackagePrefix+dollarReplacementInClass)) { + className = className.substring(noPackagePrefix.length()); + } + + // the $ used in inner class names is illegal as an xml element getNodeName + className = className.replace(dollarReplacementInClass, '$'); + + return className; + } + + protected String escapeFieldName(String fieldName) { + StringBuffer result = new StringBuffer(); + int length = fieldName.length(); + for(int i = 0; i < length; i++) { + char c = fieldName.charAt(i); + if (c == '$' ) { + result.append(dollarReplacementInField); + } else if (c == '_') { + result.append(underscoreReplacementInField); + } else { + result.append(c); + } + } + return result.toString(); + } + + protected String unescapeFieldName(String xmlName) { + StringBuffer result = new StringBuffer(); + int length = xmlName.length(); + for(int i = 0; i < length; i++) { + char c = xmlName.charAt(i); + if ( stringFoundAt(xmlName, i,underscoreReplacementInField)) { + i +=underscoreReplacementInField.length() - 1; + result.append('_'); + } else if ( stringFoundAt(xmlName, i,dollarReplacementInField)) { + i +=dollarReplacementInField.length() - 1; + result.append('$'); + } else { + result.append(c); + } + } + return result.toString(); + } + + private boolean stringFoundAt(String name, int i, String replacement) { + if ( name.length() >= i + replacement.length() + && name.substring(i, i + replacement.length()).equals(replacement) ){ + return true; + } + return false; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationConfiguration.java b/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationConfiguration.java new file mode 100644 index 0000000..78e8263 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationConfiguration.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2007, 2008, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. November 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.mapper; + +/** + * An interface for the configuration part of the AnnotationMapper. + * + * @author Jörg Schaible + * @since 1.3 + * @deprecated As of 1.4.5, minimal JDK version will be 1.6 for next major release + */ +public interface AnnotationConfiguration { + + void autodetectAnnotations(boolean mode); + + void processAnnotations(Class[] types); + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationMapper.java new file mode 100644 index 0000000..7d0e78e --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/AnnotationMapper.java @@ -0,0 +1,626 @@ +/* + * Copyright (C) 2007, 2008, 2009, 2011, 2012, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. November 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.mapper; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.thoughtworks.xstream.InitializationException; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamAliasType; +import com.thoughtworks.xstream.annotations.XStreamAsAttribute; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import com.thoughtworks.xstream.annotations.XStreamConverters; +import com.thoughtworks.xstream.annotations.XStreamImplicit; +import com.thoughtworks.xstream.annotations.XStreamImplicitCollection; +import com.thoughtworks.xstream.annotations.XStreamInclude; +import com.thoughtworks.xstream.annotations.XStreamOmitField; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.converters.ConverterMatcher; +import com.thoughtworks.xstream.converters.ConverterRegistry; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.SingleValueConverterWrapper; +import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; +import com.thoughtworks.xstream.core.ClassLoaderReference; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.core.util.DependencyInjectionFactory; +import com.thoughtworks.xstream.core.util.TypedNull; + + +/** + * A mapper that uses annotations to prepare the remaining mappers in the chain. + * + * @author Jörg Schaible + * @since 1.3 + */ +public class AnnotationMapper extends MapperWrapper implements AnnotationConfiguration { + + private boolean locked; + private transient Object[] arguments; + private final ConverterRegistry converterRegistry; + private transient ClassAliasingMapper classAliasingMapper; + private transient DefaultImplementationsMapper defaultImplementationsMapper; + private transient ImplicitCollectionMapper implicitCollectionMapper; + private transient FieldAliasingMapper fieldAliasingMapper; + private transient AttributeMapper attributeMapper; + private transient LocalConversionMapper localConversionMapper; + private final Map, Map, Converter>> converterCache = + new HashMap, Map, Converter>>(); + private final Set> annotatedTypes = + Collections.synchronizedSet(new HashSet>()); + + /** + * Construct an AnnotationMapper. + * + * @param wrapped the next {@link Mapper} in the chain + * @since 1.4.5 + */ + public AnnotationMapper( + final Mapper wrapped, final ConverterRegistry converterRegistry, final ConverterLookup converterLookup, + final ClassLoaderReference classLoaderReference, final ReflectionProvider reflectionProvider) { + super(wrapped); + this.converterRegistry = converterRegistry; + annotatedTypes.add(Object.class); + setupMappers(); + locked = true; + + final ClassLoader classLoader = classLoaderReference.getReference(); + arguments = new Object[]{ + this, classLoaderReference, reflectionProvider, converterLookup, new JVM(), + classLoader != null ? classLoader : new TypedNull(ClassLoader.class)}; + } + + /** + * Construct an AnnotationMapper. + * + * @param wrapped the next {@link Mapper} in the chain + * @since 1.3 + * @deprecated As of 1.4.5 use {@link #AnnotationMapper(Mapper, ConverterRegistry, ConverterLookup, ClassLoaderReference, ReflectionProvider)} + */ + public AnnotationMapper( + final Mapper wrapped, final ConverterRegistry converterRegistry, final ConverterLookup converterLookup, + final ClassLoader classLoader, final ReflectionProvider reflectionProvider, + final JVM jvm) { + this(wrapped, converterRegistry, converterLookup, new ClassLoaderReference(classLoader), reflectionProvider); + } + + @Override + public String realMember(final Class type, final String serialized) { + if (!locked) { + processAnnotations(type); + } + return super.realMember(type, serialized); + } + + @Override + public String serializedClass(final Class type) { + if (!locked) { + processAnnotations(type); + } + return super.serializedClass(type); + } + + @Override + public Class defaultImplementationOf(final Class type) { + if (!locked) { + processAnnotations(type); + } + final Class defaultImplementation = super.defaultImplementationOf(type); + if (!locked) { + processAnnotations(defaultImplementation); + } + return defaultImplementation; + } + + @Override + public Converter getLocalConverter(final Class definedIn, final String fieldName) { + if (!locked) { + processAnnotations(definedIn); + } + return super.getLocalConverter(definedIn, fieldName); + } + + public void autodetectAnnotations(final boolean mode) { + locked = !mode; + } + + public void processAnnotations(final Class[] initialTypes) { + if (initialTypes == null || initialTypes.length == 0) { + return; + } + locked = true; + + final Set> types = new UnprocessedTypesSet(); + for (final Class initialType : initialTypes) { + types.add(initialType); + } + processTypes(types); + } + + private void processAnnotations(final Class initialType) { + if (initialType == null) { + return; + } + + final Set> types = new UnprocessedTypesSet(); + types.add(initialType); + processTypes(types); + } + + private void processTypes(final Set> types) { + while (!types.isEmpty()) { + final Iterator> iter = types.iterator(); + final Class type = iter.next(); + iter.remove(); + + synchronized(type) { + if (annotatedTypes.contains(type)) { + continue; + } + try { + if (type.isPrimitive()) { + continue; + } + + addParametrizedTypes(type, types); + + processConverterAnnotations(type); + processAliasAnnotation(type, types); + processAliasTypeAnnotation(type); + + if (type.isInterface()) { + continue; + } + + processImplicitCollectionAnnotation(type); + + final Field[] fields = type.getDeclaredFields(); + for (int i = 0; i < fields.length; i++ ) { + final Field field = fields[i]; + if (field.isEnumConstant() + || (field.getModifiers() & (Modifier.STATIC | Modifier.TRANSIENT)) > 0) { + continue; + } + + addParametrizedTypes(field.getGenericType(), types); + + if (field.isSynthetic()) { + continue; + } + + processFieldAliasAnnotation(field); + processAsAttributeAnnotation(field); + processImplicitAnnotation(field); + processOmitFieldAnnotation(field); + processLocalConverterAnnotation(field); + } + } finally { + annotatedTypes.add(type); + } + } + } + } + + private void addParametrizedTypes(Type type, final Set> types) { + final Set processedTypes = new HashSet(); + final Set localTypes = new LinkedHashSet() { + + @Override + public boolean add(final Type o) { + if (o instanceof Class) { + return types.add((Class)o); + } + return o == null || processedTypes.contains(o) ? false : super.add(o); + } + + }; + while (type != null) { + processedTypes.add(type); + if (type instanceof Class) { + final Class clazz = (Class)type; + types.add(clazz); + if (!clazz.isPrimitive()) { + final TypeVariable[] typeParameters = clazz.getTypeParameters(); + for (final TypeVariable typeVariable : typeParameters) { + localTypes.add(typeVariable); + } + localTypes.add(clazz.getGenericSuperclass()); + for (final Type iface : clazz.getGenericInterfaces()) { + localTypes.add(iface); + } + } + } else if (type instanceof TypeVariable) { + final TypeVariable typeVariable = (TypeVariable)type; + final Type[] bounds = typeVariable.getBounds(); + for (final Type bound : bounds) { + localTypes.add(bound); + } + } else if (type instanceof ParameterizedType) { + final ParameterizedType parametrizedType = (ParameterizedType)type; + localTypes.add(parametrizedType.getRawType()); + final Type[] actualArguments = parametrizedType.getActualTypeArguments(); + for (final Type actualArgument : actualArguments) { + localTypes.add(actualArgument); + } + } else if (type instanceof GenericArrayType) { + final GenericArrayType arrayType = (GenericArrayType)type; + localTypes.add(arrayType.getGenericComponentType()); + } + + if (!localTypes.isEmpty()) { + final Iterator iter = localTypes.iterator(); + type = iter.next(); + iter.remove(); + } else { + type = null; + } + } + } + + private void processConverterAnnotations(final Class type) { + if (converterRegistry != null) { + final XStreamConverters convertersAnnotation = type + .getAnnotation(XStreamConverters.class); + final XStreamConverter converterAnnotation = type + .getAnnotation(XStreamConverter.class); + final List annotations = convertersAnnotation != null + ? new ArrayList(Arrays.asList(convertersAnnotation.value())) + : new ArrayList(); + if (converterAnnotation != null) { + annotations.add(converterAnnotation); + } + for (final XStreamConverter annotation : annotations) { + final Converter converter = cacheConverter( + annotation, converterAnnotation != null ? type : null); + if (converter != null) { + if (converterAnnotation != null || converter.canConvert(type)) { + converterRegistry.registerConverter(converter, annotation.priority()); + } else { + throw new InitializationException("Converter " + + annotation.value().getName() + + " cannot handle annotated class " + + type.getName()); + } + } + } + } + } + + private void processAliasAnnotation(final Class type, final Set> types) { + final XStreamAlias aliasAnnotation = type.getAnnotation(XStreamAlias.class); + if (aliasAnnotation != null) { + if (classAliasingMapper == null) { + throw new InitializationException("No " + + ClassAliasingMapper.class.getName() + + " available"); + } + classAliasingMapper.addClassAlias(aliasAnnotation.value(), type); + if (aliasAnnotation.impl() != Void.class) { + // Alias for Interface/Class with an impl + defaultImplementationsMapper.addDefaultImplementation( + aliasAnnotation.impl(), type); + if (type.isInterface()) { + types.add(aliasAnnotation.impl()); // alias Interface's impl + } + } + } + } + + private void processAliasTypeAnnotation(final Class type) { + final XStreamAliasType aliasAnnotation = type.getAnnotation(XStreamAliasType.class); + if (aliasAnnotation != null) { + if (classAliasingMapper == null) { + throw new InitializationException("No " + + ClassAliasingMapper.class.getName() + + " available"); + } + classAliasingMapper.addTypeAlias(aliasAnnotation.value(), type); + } + } + + @Deprecated + private void processImplicitCollectionAnnotation(final Class type) { + final XStreamImplicitCollection implicitColAnnotation = type + .getAnnotation(XStreamImplicitCollection.class); + if (implicitColAnnotation != null) { + if (implicitCollectionMapper == null) { + throw new InitializationException("No " + + ImplicitCollectionMapper.class.getName() + + " available"); + } + final String fieldName = implicitColAnnotation.value(); + final String itemFieldName = implicitColAnnotation.item(); + final Field field; + try { + field = type.getDeclaredField(fieldName); + } catch (final NoSuchFieldException e) { + throw new InitializationException(type.getName() + + " does not have a field named '" + + fieldName + + "' as required by " + + XStreamImplicitCollection.class.getName()); + } + Class itemType = null; + final Type genericType = field.getGenericType(); + if (genericType instanceof ParameterizedType) { + final Type typeArgument = ((ParameterizedType)genericType) + .getActualTypeArguments()[0]; + itemType = getClass(typeArgument); + } + if (itemType == null) { + implicitCollectionMapper.add(type, fieldName, null, Object.class); + } else { + if (itemFieldName.equals("")) { + implicitCollectionMapper.add(type, fieldName, null, itemType); + } else { + implicitCollectionMapper.add(type, fieldName, itemFieldName, itemType); + } + } + } + } + + private void processFieldAliasAnnotation(final Field field) { + final XStreamAlias aliasAnnotation = field.getAnnotation(XStreamAlias.class); + if (aliasAnnotation != null) { + if (fieldAliasingMapper == null) { + throw new InitializationException("No " + + FieldAliasingMapper.class.getName() + + " available"); + } + fieldAliasingMapper.addFieldAlias( + aliasAnnotation.value(), field.getDeclaringClass(), field.getName()); + } + } + + private void processAsAttributeAnnotation(final Field field) { + final XStreamAsAttribute asAttributeAnnotation = field + .getAnnotation(XStreamAsAttribute.class); + if (asAttributeAnnotation != null) { + if (attributeMapper == null) { + throw new InitializationException("No " + + AttributeMapper.class.getName() + + " available"); + } + attributeMapper.addAttributeFor(field); + } + } + + private void processImplicitAnnotation(final Field field) { + final XStreamImplicit implicitAnnotation = field.getAnnotation(XStreamImplicit.class); + if (implicitAnnotation != null) { + if (implicitCollectionMapper == null) { + throw new InitializationException("No " + + ImplicitCollectionMapper.class.getName() + + " available"); + } + final String fieldName = field.getName(); + final String itemFieldName = implicitAnnotation.itemFieldName(); + final String keyFieldName = implicitAnnotation.keyFieldName(); + boolean isMap = Map.class.isAssignableFrom(field.getType()); + Class itemType = null; + if (!field.getType().isArray()) { + final Type genericType = field.getGenericType(); + if (genericType instanceof ParameterizedType) { + final Type[] actualTypeArguments = ((ParameterizedType)genericType) + .getActualTypeArguments(); + final Type typeArgument = actualTypeArguments[isMap ? 1 : 0]; + itemType = getClass(typeArgument); + } + } + if (isMap) { + implicitCollectionMapper.add( + field.getDeclaringClass(), fieldName, + itemFieldName != null && !"".equals(itemFieldName) ? itemFieldName : null, + itemType, keyFieldName != null && !"".equals(keyFieldName) + ? keyFieldName + : null); + } else { + if (itemFieldName != null && !"".equals(itemFieldName)) { + implicitCollectionMapper.add( + field.getDeclaringClass(), fieldName, itemFieldName, itemType); + } else { + implicitCollectionMapper + .add(field.getDeclaringClass(), fieldName, itemType); + } + } + } + } + + private void processOmitFieldAnnotation(final Field field) { + final XStreamOmitField omitFieldAnnotation = field + .getAnnotation(XStreamOmitField.class); + if (omitFieldAnnotation != null) { + if (fieldAliasingMapper == null) { + throw new InitializationException("No " + + FieldAliasingMapper.class.getName() + + " available"); + } + fieldAliasingMapper.omitField(field.getDeclaringClass(), field.getName()); + } + } + + private void processLocalConverterAnnotation(final Field field) { + final XStreamConverter annotation = field.getAnnotation(XStreamConverter.class); + if (annotation != null) { + final Converter converter = cacheConverter(annotation, field.getType()); + if (converter != null) { + if (localConversionMapper == null) { + throw new InitializationException("No " + + LocalConversionMapper.class.getName() + + " available"); + } + localConversionMapper.registerLocalConverter( + field.getDeclaringClass(), field.getName(), converter); + } + } + } + + private Converter cacheConverter(final XStreamConverter annotation, + final Class targetType) { + Converter result = null; + final Object[] args; + final List parameter = new ArrayList(); + if (targetType != null && annotation.useImplicitType()) { + parameter.add(targetType); + } + final List arrays = new ArrayList(); + arrays.add(annotation.booleans()); + arrays.add(annotation.bytes()); + arrays.add(annotation.chars()); + arrays.add(annotation.doubles()); + arrays.add(annotation.floats()); + arrays.add(annotation.ints()); + arrays.add(annotation.longs()); + arrays.add(annotation.shorts()); + arrays.add(annotation.strings()); + arrays.add(annotation.types()); + for(Object array : arrays) { + if (array != null) { + int length = Array.getLength(array); + for (int i = 0; i < length; i++ ) { + Object object = Array.get(array, i); + if (!parameter.contains(object)) { + parameter.add(object); + } + } + } + } + final Class converterType = annotation.value(); + Map, Converter> converterMapping = converterCache.get(converterType); + if (converterMapping != null) { + result = converterMapping.get(parameter); + } + if (result == null) { + int size = parameter.size(); + if (size > 0) { + args = new Object[arguments.length + size]; + System.arraycopy(arguments, 0, args, size, arguments.length); + System.arraycopy(parameter.toArray(new Object[size]), 0, args, 0, size); + } else { + args = arguments; + } + + final Converter converter; + try { + if (SingleValueConverter.class.isAssignableFrom(converterType) + && !Converter.class.isAssignableFrom(converterType)) { + final SingleValueConverter svc = (SingleValueConverter)DependencyInjectionFactory + .newInstance(converterType, args); + converter = new SingleValueConverterWrapper(svc); + } else { + converter = (Converter)DependencyInjectionFactory.newInstance( + converterType, args); + } + } catch (final Exception e) { + throw new InitializationException("Cannot instantiate converter " + + converterType.getName() + + (targetType != null ? " for type " + targetType.getName() : ""), e); + } + if (converterMapping == null) { + converterMapping = new HashMap, Converter>(); + converterCache.put(converterType, converterMapping); + } + converterMapping.put(parameter, converter); + result = converter; + } + return result; + } + + private Class getClass(final Type typeArgument) { + Class type = null; + if (typeArgument instanceof ParameterizedType) { + type = (Class)((ParameterizedType)typeArgument).getRawType(); + } else if (typeArgument instanceof Class) { + type = (Class)typeArgument; + } + return type; + } + + private void setupMappers() { + classAliasingMapper = (ClassAliasingMapper)lookupMapperOfType(ClassAliasingMapper.class); + defaultImplementationsMapper = (DefaultImplementationsMapper)lookupMapperOfType(DefaultImplementationsMapper.class); + implicitCollectionMapper = (ImplicitCollectionMapper)lookupMapperOfType(ImplicitCollectionMapper.class); + fieldAliasingMapper = (FieldAliasingMapper)lookupMapperOfType(FieldAliasingMapper.class); + attributeMapper = (AttributeMapper)lookupMapperOfType(AttributeMapper.class); + localConversionMapper = (LocalConversionMapper)lookupMapperOfType(LocalConversionMapper.class); + } + + private void writeObject(final ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + int max = arguments.length - 2; + out.writeInt(max); + for (int i = 0; i < max; i++ ) { + out.writeObject(arguments[i]); + } + } + + private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + setupMappers(); + int max = in.readInt(); + arguments = new Object[max+2]; + for (int i = 0; i < max; i++ ) { + arguments[i] = in.readObject(); + if (arguments[i] instanceof ClassLoaderReference) { + arguments[max+1] = ((ClassLoaderReference)arguments[i]).getReference(); + } + } + arguments[max] = new JVM(); + } + + private final class UnprocessedTypesSet extends LinkedHashSet> { + @Override + public boolean add(Class type) { + if (type == null) { + return false; + } + while (type.isArray()) { + type = type.getComponentType(); + } + final String name = type.getName(); + if (name.startsWith("java.") || name.startsWith("javax.")) { + return false; + } + final boolean ret = annotatedTypes.contains(type) ? false : super.add(type); + if (ret) { + final XStreamInclude inc = type.getAnnotation(XStreamInclude.class); + if (inc != null) { + final Class[] incTypes = inc.value(); + if (incTypes != null) { + for (final Class incType : incTypes) { + add(incType); + } + } + } + } + return ret; + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/ArrayMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/ArrayMapper.java new file mode 100644 index 0000000..21ff4ea --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/ArrayMapper.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. January 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.mapper; + +import com.thoughtworks.xstream.core.util.Primitives; + +/** + * Mapper that detects arrays and changes the name so it can identified as an array + * (for example Foo[] gets serialized as foo-array). Supports multi-dimensional arrays. + * + * @author Joe Walnes + */ +public class ArrayMapper extends MapperWrapper { + + public ArrayMapper(Mapper wrapped) { + super(wrapped); + } + + public String serializedClass(Class type) { + StringBuffer arraySuffix = new StringBuffer(); + String name = null; + while (type.isArray()) { + name = super.serializedClass(type); + if (type.getName().equals(name)) { + type = type.getComponentType(); + arraySuffix.append("-array"); + name = null; + } else { + break; + } + } + if (name == null) { + name = boxedTypeName(type); + } + if (name == null) { + name = super.serializedClass(type); + } + if (arraySuffix.length() > 0) { + return name + arraySuffix; + } else { + return name; + } + } + + public Class realClass(String elementName) { + int dimensions = 0; + + // strip off "-array" suffix + while (elementName.endsWith("-array")) { + elementName = elementName.substring(0, elementName.length() - 6); // cut off -array + ++dimensions; + } + + if (dimensions > 0) { + Class componentType = Primitives.primitiveType(elementName); + if (componentType == null) { + componentType = super.realClass(elementName); + } + while (componentType.isArray()) { + componentType = componentType.getComponentType(); + ++dimensions; + } + return super.realClass(arrayType(dimensions, componentType)); + } else { + return super.realClass(elementName); + } + } + + private String arrayType(int dimensions, Class componentType) { + StringBuffer className = new StringBuffer(); + for (int i = 0; i < dimensions; i++) { + className.append('['); + } + if (componentType.isPrimitive()) { + className.append(Primitives.representingChar(componentType)); + return className.toString(); + } else { + className.append('L').append(componentType.getName()).append(';'); + return className.toString(); + } + } + + private String boxedTypeName(Class type) { + return Primitives.isBoxed(type) ? type.getName() : null; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/AttributeAliasingMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/AttributeAliasingMapper.java new file mode 100644 index 0000000..2e99fd4 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/AttributeAliasingMapper.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 27. March 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.mapper; + + + +/** + * Mapper that allows aliasing of attribute names. + * + * @author Jörg Schaible + * @author Guilherme Silveira + * @since 1.2 + */ +public class AttributeAliasingMapper extends AbstractAttributeAliasingMapper { + + public AttributeAliasingMapper(Mapper wrapped) { + super(wrapped); + } + + public String aliasForAttribute(String attribute) { + String alias = (String)nameToAlias.get(attribute); + return alias == null ? super.aliasForAttribute(attribute) : alias; + } + + public String attributeForAlias(String alias) { + String name = (String)aliasToName.get(alias); + return name == null ? super.attributeForAlias(alias) : name; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/AttributeMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/AttributeMapper.java new file mode 100644 index 0000000..38ce6ae --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/AttributeMapper.java @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 20. February 2006 by Mauro Talevi + */ +package com.thoughtworks.xstream.mapper; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; + +/** + * Mapper that allows the usage of attributes for fields and corresponding + * types or specified arbitrary types. It is responsible for the lookup of the + * {@link SingleValueConverter} for item types and attribute names. + * + * @author Paul Hammant + * @author Ian Cartwright + * @author Jörg Schaible + * @author Mauro Talevi + * @author Guilherme Silveira + * @since 1.2 + */ +public class AttributeMapper extends MapperWrapper { + + private final Map fieldNameToTypeMap = new HashMap(); + private final Set typeSet = new HashSet(); + private ConverterLookup converterLookup; + private ReflectionProvider reflectionProvider; + private final Set fieldToUseAsAttribute = new HashSet(); + + /** + * @deprecated As of 1.3 + */ + public AttributeMapper(Mapper wrapped) { + this(wrapped, null, null); + } + + public AttributeMapper(Mapper wrapped, ConverterLookup converterLookup, ReflectionProvider refProvider) { + super(wrapped); + this.converterLookup = converterLookup; + this.reflectionProvider = refProvider; + } + + /** + * @deprecated As of 1.3 + */ + public void setConverterLookup(ConverterLookup converterLookup) { + this.converterLookup = converterLookup; + } + + public void addAttributeFor(final String fieldName, final Class type) { + fieldNameToTypeMap.put(fieldName, type); + } + + public void addAttributeFor(final Class type) { + typeSet.add(type); + } + + private SingleValueConverter getLocalConverterFromItemType(Class type) { + Converter converter = converterLookup.lookupConverterForType(type); + if (converter != null && converter instanceof SingleValueConverter) { + return (SingleValueConverter)converter; + } else { + return null; + } + } + + /** + * @deprecated As of 1.3, use {@link #getConverterFromItemType(String, Class, Class)} + */ + public SingleValueConverter getConverterFromItemType(String fieldName, Class type) { + if (fieldNameToTypeMap.get(fieldName) == type) { + return getLocalConverterFromItemType(type); + } else { + return null; + } + } + + public SingleValueConverter getConverterFromItemType(String fieldName, Class type, + Class definedIn) { + if (shouldLookForSingleValueConverter(fieldName, type, definedIn)) { + SingleValueConverter converter = getLocalConverterFromItemType(type); + if (converter != null) { + return converter; + } + } + return super.getConverterFromItemType(fieldName, type, definedIn); + } + + public boolean shouldLookForSingleValueConverter(String fieldName, Class type, Class definedIn) { + if (typeSet.contains(type)) { + return true; + } else if (fieldNameToTypeMap.get(fieldName) == type) { + return true; + } else if (fieldName != null && definedIn != null) { + Field field = reflectionProvider.getField(definedIn, fieldName); + return fieldToUseAsAttribute.contains(field); + } + return false; + } + + /** + * @deprecated As of 1.3, use {@link #getConverterFromItemType(String, Class, Class)} + */ + public SingleValueConverter getConverterFromItemType(Class type) { + if (typeSet.contains(type)) { + return getLocalConverterFromItemType(type); + } else { + return null; + } + } + + /** + * @deprecated As of 1.3, use {@link #getConverterFromAttribute(Class, String, Class)} + */ + public SingleValueConverter getConverterFromAttribute(String attributeName) { + SingleValueConverter converter = null; + Class type = (Class)fieldNameToTypeMap.get(attributeName); + if (type != null) { + converter = getLocalConverterFromItemType(type); + } + return converter; + } + + /** + * @deprecated As of 1.3.1, use {@link #getConverterFromAttribute(Class, String, Class)} + */ + public SingleValueConverter getConverterFromAttribute(Class definedIn, String attribute) { + Field field = reflectionProvider.getField(definedIn, attribute); + return getConverterFromAttribute(definedIn, attribute, field.getType()); + } + + public SingleValueConverter getConverterFromAttribute(Class definedIn, String attribute, Class type) { + if (shouldLookForSingleValueConverter(attribute, type, definedIn)) { + SingleValueConverter converter = getLocalConverterFromItemType(type); + if (converter != null) { + return converter; + } + } + return super.getConverterFromAttribute(definedIn, attribute, type); + } + + /** + * Tells this mapper to use an attribute for this field. + * + * @param field the field itself + * @since 1.2.2 + */ + public void addAttributeFor(Field field) { + fieldToUseAsAttribute.add(field); + } + + /** + * Tells this mapper to use an attribute for this field. + * + * @param definedIn the declaring class of the field + * @param fieldName the name of the field + * @throws IllegalArgumentException if the field does not exist + * @since 1.3 + */ + public void addAttributeFor(Class definedIn, String fieldName) { + fieldToUseAsAttribute.add(reflectionProvider.getField(definedIn, fieldName)); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/CGLIBMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/CGLIBMapper.java new file mode 100644 index 0000000..d6dedae --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/CGLIBMapper.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2006, 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 08. April 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.mapper; + +import net.sf.cglib.proxy.Enhancer; + +/** + * Mapper that detects proxies generated by the CGLIB enhancer. The implementation modifies + * the name, so that it can identify these types. Note, that this mapper relies on the CGLIB + * converters: + *
    + *
  • CGLIBEnhancedConverter
  • + *
+ * + * @author Jörg Schaible + * @since 1.2 + */ +public class CGLIBMapper extends MapperWrapper { + + private static String DEFAULT_NAMING_MARKER = "$$EnhancerByCGLIB$$"; + private final String alias; + + public interface Marker { + } + + public CGLIBMapper(Mapper wrapped) { + this(wrapped, "CGLIB-enhanced-proxy"); + } + + public CGLIBMapper(Mapper wrapped, String alias) { + super(wrapped); + this.alias = alias; + } + + public String serializedClass(Class type) { + String serializedName = super.serializedClass(type); + if (type == null) { + return serializedName; + } + String typeName = type.getName(); + return typeName.equals(serializedName) + && typeName.indexOf(DEFAULT_NAMING_MARKER) > 0 + && Enhancer.isEnhanced(type) ? alias : serializedName; + } + + public Class realClass(String elementName) { + return elementName.equals(alias) ? Marker.class : super.realClass(elementName); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/CachingMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/CachingMapper.java new file mode 100644 index 0000000..c6dbee0 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/CachingMapper.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. January 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.mapper; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import com.thoughtworks.xstream.XStreamException; +import com.thoughtworks.xstream.core.Caching; +import com.thoughtworks.xstream.security.ForbiddenClassException; + +/** + * Mapper that caches which names map to which classes. Prevents repetitive searching and class loading. + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class CachingMapper extends MapperWrapper implements Caching { + + private transient Map realClassCache; + + public CachingMapper(Mapper wrapped) { + super(wrapped); + readResolve(); + } + + public Class realClass(String elementName) { + Object cached = realClassCache.get(elementName); + if (cached != null) { + if (cached instanceof Class) { + return (Class)cached; + } + throw (XStreamException)cached; + } + + try { + Class result = super.realClass(elementName); + realClassCache.put(elementName, result); + return result; + } catch (ForbiddenClassException e) { + realClassCache.put(elementName, e); + throw e; + } catch (CannotResolveClassException e) { + realClassCache.put(elementName, e); + throw e; + } + } + + public void flushCache() { + realClassCache.clear(); + } + + private Object readResolve() { + realClassCache = Collections.synchronizedMap(new HashMap(128)); + return this; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/CannotResolveClassException.java b/xstream/src/java/com/thoughtworks/xstream/mapper/CannotResolveClassException.java new file mode 100644 index 0000000..d1dfe58 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/CannotResolveClassException.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2003 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.xstream.mapper; + +import com.thoughtworks.xstream.XStreamException; + +/** + * Exception thrown if a mapper cannot locate the appropriate class for an element. + * + * @author Joe Walnes + * @author Jörg Schaible + * @since 1.2 + */ +public class CannotResolveClassException extends XStreamException { + public CannotResolveClassException(String className) { + super(className); + } + /** + * @since 1.4.2 + */ + public CannotResolveClassException(String className, Throwable cause) { + super(className, cause); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/ClassAliasingMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/ClassAliasingMapper.java new file mode 100644 index 0000000..c235db2 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/ClassAliasingMapper.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 09. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.mapper; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import com.thoughtworks.xstream.core.util.Primitives; + +/** + * Mapper that allows a fully qualified class name to be replaced with an alias. + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class ClassAliasingMapper extends MapperWrapper { + + private final Map typeToName = new HashMap(); + private final Map classToName = new HashMap(); + private transient Map nameToType = new HashMap(); + + public ClassAliasingMapper(Mapper wrapped) { + super(wrapped); + } + + public void addClassAlias(String name, Class type) { + nameToType.put(name, type.getName()); + classToName.put(type.getName(), name); + } + + /** + * @deprecated As of 1.3, method was a leftover of an old implementation + */ + public void addClassAttributeAlias(String name, Class type) { + addClassAlias(name, type); + } + + public void addTypeAlias(String name, Class type) { + nameToType.put(name, type.getName()); + typeToName.put(type, name); + } + + public String serializedClass(Class type) { + String alias = (String) classToName.get(type.getName()); + if (alias != null) { + return alias; + } else { + for (final Iterator iter = typeToName.keySet().iterator(); iter.hasNext();) { + final Class compatibleType = (Class)iter.next(); + if (compatibleType.isAssignableFrom(type)) { + return (String)typeToName.get(compatibleType); + } + } + return super.serializedClass(type); + } + } + + public Class realClass(String elementName) { + String mappedName = (String) nameToType.get(elementName); + + if (mappedName != null) { + Class type = Primitives.primitiveType(mappedName); + if (type != null) { + return type; + } + elementName = mappedName; + } + + return super.realClass(elementName); + } + + public boolean itemTypeAsAttribute(Class clazz) { + return classToName.containsKey(clazz); + } + + public boolean aliasIsAttribute(String name) { + return nameToType.containsKey(name); + } + + private Object readResolve() { + nameToType = new HashMap(); + for (final Iterator iter = classToName.keySet().iterator(); iter.hasNext();) { + final Object type = iter.next(); + nameToType.put(classToName.get(type), type); + } + for (final Iterator iter = typeToName.keySet().iterator(); iter.hasNext();) { + final Class type = (Class)iter.next(); + nameToType.put(typeToName.get(type), type.getName()); + } + return this; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/DefaultImplementationsMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/DefaultImplementationsMapper.java new file mode 100644 index 0000000..3a52b92 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/DefaultImplementationsMapper.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. January 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.mapper; + +import com.thoughtworks.xstream.InitializationException; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + + +/** + * Mapper that resolves default implementations of classes. For example, + * mapper.serializedClass(ArrayList.class) will return java.util.List. Calling + * mapper.defaultImplementationOf(List.class) will return ArrayList. + * + * @author Joe Walnes + */ +public class DefaultImplementationsMapper extends MapperWrapper { + + private final Map typeToImpl = new HashMap(); + private transient Map implToType = new HashMap(); + + public DefaultImplementationsMapper(Mapper wrapped) { + super(wrapped); + addDefaults(); + } + + protected void addDefaults() { + // null handling + addDefaultImplementation(null, Mapper.Null.class); + // register primitive types + addDefaultImplementation(Boolean.class, boolean.class); + addDefaultImplementation(Character.class, char.class); + addDefaultImplementation(Integer.class, int.class); + addDefaultImplementation(Float.class, float.class); + addDefaultImplementation(Double.class, double.class); + addDefaultImplementation(Short.class, short.class); + addDefaultImplementation(Byte.class, byte.class); + addDefaultImplementation(Long.class, long.class); + } + + public void addDefaultImplementation(Class defaultImplementation, Class ofType) { + if (defaultImplementation != null && defaultImplementation.isInterface()) { + throw new InitializationException( + "Default implementation is not a concrete class: " + + defaultImplementation.getName()); + } + typeToImpl.put(ofType, defaultImplementation); + implToType.put(defaultImplementation, ofType); + } + + public String serializedClass(Class type) { + Class baseType = (Class)implToType.get(type); + return baseType == null ? super.serializedClass(type) : super.serializedClass(baseType); + } + + public Class defaultImplementationOf(Class type) { + if (typeToImpl.containsKey(type)) { + return (Class)typeToImpl.get(type); + } else { + return super.defaultImplementationOf(type); + } + } + + private Object readResolve() { + implToType = new HashMap(); + for (final Iterator iter = typeToImpl.keySet().iterator(); iter.hasNext();) { + final Object type = iter.next(); + implToType.put(typeToImpl.get(type), type); + } + return this; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/DefaultMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/DefaultMapper.java new file mode 100644 index 0000000..4d029b8 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/DefaultMapper.java @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. January 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.mapper; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.core.ClassLoaderReference; +import com.thoughtworks.xstream.core.util.Primitives; + + +/** + * Default mapper implementation with 'vanilla' functionality. To build up the functionality required, wrap this mapper + * with other mapper implementations. + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class DefaultMapper implements Mapper { + + private static String XSTREAM_PACKAGE_ROOT; + static { + String packageName = DefaultMapper.class.getName(); + int idx = packageName.indexOf(".xstream."); + XSTREAM_PACKAGE_ROOT = idx > 0 ? packageName.substring(0, idx+9) : ".N/A"; + } + + private final ClassLoaderReference classLoaderReference; + + + /** + * Construct a DefaultMapper. + * + * @param classLoaderReference the reference to the classloader used by the XStream instance. + * @since 1.4.5 + */ + public DefaultMapper(ClassLoaderReference classLoaderReference) { + this.classLoaderReference = classLoaderReference; + } + + /** + * Construct a DefaultMapper. + * + * @param classLoader the ClassLoader used by the XStream instance. + * @deprecated As of 1.4.5 use {@link #DefaultMapper(ClassLoaderReference)} + */ + public DefaultMapper(ClassLoader classLoader) { + this(new ClassLoaderReference(classLoader)); + } + + public String serializedClass(Class type) { + return type.getName(); + } + + public Class realClass(String elementName) { + Class resultingClass = Primitives.primitiveType(elementName); + if( resultingClass != null ){ + return resultingClass; + } + try { + boolean initialize = true; + final ClassLoader classLoader; + if (elementName.startsWith(XSTREAM_PACKAGE_ROOT)) { + classLoader = DefaultMapper.class.getClassLoader(); + } else { + classLoader = classLoaderReference.getReference(); + initialize = elementName.charAt(0) == '['; + } + return Class.forName(elementName, initialize, classLoader); + } catch (ClassNotFoundException e) { + throw new CannotResolveClassException(elementName); + } + } + + public Class defaultImplementationOf(Class type) { + return type; + } + + public String aliasForAttribute(String attribute) { + return attribute; + } + + public String attributeForAlias(String alias) { + return alias; + } + + public String aliasForSystemAttribute(String attribute) { + return attribute; + } + + public boolean isImmutableValueType(Class type) { + return false; + } + + public String getFieldNameForItemTypeAndName(Class definedIn, Class itemType, String itemFieldName) { + return null; + } + + public Class getItemTypeForItemFieldName(Class definedIn, String itemFieldName) { + return null; + } + + public ImplicitCollectionMapping getImplicitCollectionDefForFieldName(Class itemType, String fieldName) { + return null; + } + + public boolean shouldSerializeMember(Class definedIn, String fieldName) { + return true; + } + + public String lookupName(Class type) { + return serializedClass(type); + } + + public Class lookupType(String elementName) { + return realClass(elementName); + } + + public String serializedMember(Class type, String memberName) { + return memberName; + } + + public String realMember(Class type, String serialized) { + return serialized; + } + + /** + * @deprecated As of 1.3, use {@link #getConverterFromAttribute(Class, String, Class)} + */ + public SingleValueConverter getConverterFromAttribute(String name) { + return null; + } + + /** + * @deprecated As of 1.3, use {@link #getConverterFromItemType(String, Class, Class)} + */ + public SingleValueConverter getConverterFromItemType(String fieldName, Class type) { + return null; + } + + /** + * @deprecated As of 1.3, use {@link #getConverterFromItemType(String, Class, Class)} + */ + public SingleValueConverter getConverterFromItemType(Class type) { + return null; + } + + public SingleValueConverter getConverterFromItemType(String fieldName, Class type, + Class definedIn) { + return null; + } + + public Converter getLocalConverter(Class definedIn, String fieldName) { + return null; + } + + public Mapper lookupMapperOfType(Class type) { + return null; + } + + /** + * @deprecated As of 1.3, use combination of {@link #serializedMember(Class, String)} and {@link #getConverterFromItemType(String, Class, Class)} + */ + public String aliasForAttribute(Class definedIn, String fieldName) { + return fieldName; + } + + /** + * @deprecated As of 1.3, use combination of {@link #realMember(Class, String)} and {@link #getConverterFromItemType(String, Class, Class)} + */ + public String attributeForAlias(Class definedIn, String alias) { + return alias; + } + + /** + * @deprecated As of 1.3.1, use {@link #getConverterFromAttribute(Class, String, Class)} + */ + public SingleValueConverter getConverterFromAttribute(Class definedIn, String attribute) { + return null; + } + + public SingleValueConverter getConverterFromAttribute(Class definedIn, String attribute, Class type) { + return null; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/DynamicProxyMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/DynamicProxyMapper.java new file mode 100644 index 0000000..e272f50 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/DynamicProxyMapper.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. January 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.mapper; + +import java.lang.reflect.Proxy; + +/** + * Mapper for handling special cases of aliasing dynamic proxies. The alias property specifies the name an instance + * of a dynamic proxy should be serialized with. + * + * @author Joe Walnes + */ +public class DynamicProxyMapper extends MapperWrapper { + + private String alias; + + public DynamicProxyMapper(Mapper wrapped) { + this(wrapped, "dynamic-proxy"); + } + + public DynamicProxyMapper(Mapper wrapped, String alias) { + super(wrapped); + this.alias = alias; + } + + public String getAlias() { + return alias; + } + + public void setAlias(String alias) { + this.alias = alias; + } + + public String serializedClass(Class type) { + if (Proxy.isProxyClass(type)) { + return alias; + } else { + return super.serializedClass(type); + } + } + + public Class realClass(String elementName) { + if (elementName.equals(alias)) { + return DynamicProxy.class; + } else { + return super.realClass(elementName); + } + } + + /** + * Place holder type used for dynamic proxies. + */ + public static class DynamicProxy {} + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/EnumMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/EnumMapper.java new file mode 100644 index 0000000..f46e4c2 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/EnumMapper.java @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 20. March 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.mapper; + +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.enums.EnumSingleValueConverter; +import com.thoughtworks.xstream.core.Caching; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; + + +/** + * Mapper that handles the special case of polymorphic enums in Java 1.5. This renames MyEnum$1 + * to MyEnum making it less bloaty in the XML and avoiding the need for an alias per enum value + * to be specified. Additionally every enum is treated automatically as immutable type and can + * be written as attribute. + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public class EnumMapper extends MapperWrapper implements Caching { + + private transient AttributeMapper attributeMapper; + private transient Map enumConverterMap; + + /** + * @deprecated As of 1.3.1, use {@link #EnumMapper(Mapper)} + */ + @Deprecated + public EnumMapper(Mapper wrapped, ConverterLookup lookup) { + super(wrapped); + readResolve(); + } + + public EnumMapper(Mapper wrapped) { + super(wrapped); + readResolve(); + } + + @Override + public String serializedClass(Class type) { + if (type == null) { + return super.serializedClass(type); + } + if (Enum.class.isAssignableFrom(type) && type.getSuperclass() != Enum.class) { + return super.serializedClass(type.getSuperclass()); + } else if (EnumSet.class.isAssignableFrom(type)) { + return super.serializedClass(EnumSet.class); + } else { + return super.serializedClass(type); + } + } + + @Override + public boolean isImmutableValueType(Class type) { + return (Enum.class.isAssignableFrom(type)) || super.isImmutableValueType(type); + } + + @Override + public SingleValueConverter getConverterFromItemType(String fieldName, Class type, + Class definedIn) { + SingleValueConverter converter = getLocalConverter(fieldName, type, definedIn); + return converter == null + ? super.getConverterFromItemType(fieldName, type, definedIn) + : converter; + } + + @Override + public SingleValueConverter getConverterFromAttribute(Class definedIn, String attribute, + Class type) { + SingleValueConverter converter = getLocalConverter(attribute, type, definedIn); + return converter == null + ? super.getConverterFromAttribute(definedIn, attribute, type) + : converter; + } + + private SingleValueConverter getLocalConverter(String fieldName, Class type, Class definedIn) { + if (attributeMapper != null + && Enum.class.isAssignableFrom(type) + && attributeMapper.shouldLookForSingleValueConverter(fieldName, type, definedIn)) { + synchronized (enumConverterMap) { + SingleValueConverter singleValueConverter = enumConverterMap.get(type); + if (singleValueConverter == null) { + singleValueConverter = super.getConverterFromItemType(fieldName, type, definedIn); + if (singleValueConverter == null) { + @SuppressWarnings("unchecked") + Class enumType = type; + singleValueConverter = new EnumSingleValueConverter(enumType); + } + enumConverterMap.put(type, singleValueConverter); + } + return singleValueConverter; + } + } + return null; + } + + public void flushCache() { + if (enumConverterMap.size() > 0) { + synchronized (enumConverterMap) { + enumConverterMap.clear(); + } + } + } + + private Object readResolve() { + this.enumConverterMap = new HashMap(); + this.attributeMapper = (AttributeMapper)lookupMapperOfType(AttributeMapper.class); + return this; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/FieldAliasingMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/FieldAliasingMapper.java new file mode 100644 index 0000000..7e627c2 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/FieldAliasingMapper.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 09. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.mapper; + +import com.thoughtworks.xstream.core.util.FastField; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +/** + * Mapper that allows a field of a specific class to be replaced with a shorter alias, or omitted + * entirely. + * + * @author Joe Walnes + */ +public class FieldAliasingMapper extends MapperWrapper { + + protected final Map fieldToAliasMap = new HashMap(); + protected final Map aliasToFieldMap = new HashMap(); + protected final Set fieldsToOmit = new HashSet(); + protected final Set unknownFieldsToIgnore = new LinkedHashSet(); + + public FieldAliasingMapper(Mapper wrapped) { + super(wrapped); + } + + public void addFieldAlias(String alias, Class type, String fieldName) { + fieldToAliasMap.put(key(type, fieldName), alias); + aliasToFieldMap.put(key(type, alias), fieldName); + } + + public void addFieldsToIgnore(final Pattern pattern) { + unknownFieldsToIgnore.add(pattern); + } + + private Object key(Class type, String name) { + return new FastField(type, name); + } + + public String serializedMember(Class type, String memberName) { + String alias = getMember(type, memberName, fieldToAliasMap); + if (alias == null) { + return super.serializedMember(type, memberName); + } else { + return alias; + } + } + + public String realMember(Class type, String serialized) { + String real = getMember(type, serialized, aliasToFieldMap); + if (real == null) { + return super.realMember(type, serialized); + } else { + return real; + } + } + + private String getMember(Class type, String name, Map map) { + String member = null; + for (Class declaringType = type; + member == null && declaringType != Object.class && declaringType != null; + declaringType = declaringType.getSuperclass()) { + member = (String) map.get(key(declaringType, name)); + } + return member; + } + + public boolean shouldSerializeMember(Class definedIn, String fieldName) { + if (fieldsToOmit.contains(key(definedIn, fieldName))) { + return false; + } else if (definedIn == Object.class && !unknownFieldsToIgnore.isEmpty()) { + for(Iterator iter = unknownFieldsToIgnore.iterator(); iter.hasNext();) { + Pattern pattern = (Pattern)iter.next(); + if (pattern.matcher(fieldName).matches()) { + return false; + } + } + } + return true; + } + + public void omitField(Class definedIn, String fieldName) { + fieldsToOmit.add(key(definedIn, fieldName)); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/ImmutableTypesMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/ImmutableTypesMapper.java new file mode 100644 index 0000000..f6db320 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/ImmutableTypesMapper.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. January 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.mapper; + +import java.util.HashSet; +import java.util.Set; + +/** + * Mapper that specifies which types are basic immutable types. Types that are marked as immutable will be written + * multiple times in the serialization stream without using references. + * + * @author Joe Walnes + */ +public class ImmutableTypesMapper extends MapperWrapper { + + private final Set immutableTypes = new HashSet(); + + public ImmutableTypesMapper(Mapper wrapped) { + super(wrapped); + } + + public void addImmutableType(Class type) { + immutableTypes.add(type); + } + + public boolean isImmutableValueType(Class type) { + if (immutableTypes.contains(type)) { + return true; + } else { + return super.isImmutableValueType(type); + } + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/ImplicitCollectionMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/ImplicitCollectionMapper.java new file mode 100644 index 0000000..36eca76 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/ImplicitCollectionMapper.java @@ -0,0 +1,298 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011, 2012, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 16. February 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.mapper; + +import com.thoughtworks.xstream.InitializationException; +import com.thoughtworks.xstream.core.util.Primitives; + +import java.lang.reflect.Field; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + + +public class ImplicitCollectionMapper extends MapperWrapper { + + public ImplicitCollectionMapper(Mapper wrapped) { + super(wrapped); + } + + // { definedIn (Class) -> (ImplicitCollectionMapperForClass) } + private final Map classNameToMapper = new HashMap(); + + private ImplicitCollectionMapperForClass getMapper(Class definedIn) { + while (definedIn != null) { + ImplicitCollectionMapperForClass mapper = (ImplicitCollectionMapperForClass)classNameToMapper + .get(definedIn); + if (mapper != null) { + return mapper; + } + definedIn = definedIn.getSuperclass(); + } + return null; + } + + private ImplicitCollectionMapperForClass getOrCreateMapper(Class definedIn) { + ImplicitCollectionMapperForClass mapper = (ImplicitCollectionMapperForClass)classNameToMapper + .get(definedIn); + if (mapper == null) { + mapper = new ImplicitCollectionMapperForClass(definedIn); + classNameToMapper.put(definedIn, mapper); + } + return mapper; + } + + public String getFieldNameForItemTypeAndName(Class definedIn, Class itemType, + String itemFieldName) { + ImplicitCollectionMapperForClass mapper = getMapper(definedIn); + if (mapper != null) { + return mapper.getFieldNameForItemTypeAndName(itemType, itemFieldName); + } else { + return null; + } + } + + public Class getItemTypeForItemFieldName(Class definedIn, String itemFieldName) { + ImplicitCollectionMapperForClass mapper = getMapper(definedIn); + if (mapper != null) { + return mapper.getItemTypeForItemFieldName(itemFieldName); + } else { + return null; + } + } + + public ImplicitCollectionMapping getImplicitCollectionDefForFieldName(Class itemType, + String fieldName) { + ImplicitCollectionMapperForClass mapper = getMapper(itemType); + if (mapper != null) { + return mapper.getImplicitCollectionDefForFieldName(fieldName); + } else { + return null; + } + } + + public void add(Class definedIn, String fieldName, Class itemType) { + add(definedIn, fieldName, null, itemType); + } + + public void add(Class definedIn, String fieldName, String itemFieldName, Class itemType) { + add(definedIn, fieldName, itemFieldName, itemType, null); + } + + public void add(Class definedIn, String fieldName, String itemFieldName, Class itemType, String keyFieldName) { + Field field = null; + Class declaredIn = definedIn; + while (declaredIn != Object.class && definedIn != null) { + try { + field = declaredIn.getDeclaredField(fieldName); + break; + } catch (SecurityException e) { + throw new InitializationException( + "Access denied for field with implicit collection", e); + } catch (NoSuchFieldException e) { + declaredIn = declaredIn.getSuperclass(); + } + } + if (field == null) { + throw new InitializationException("No field \"" + + fieldName + + "\" for implicit collection"); + } else if (Map.class.isAssignableFrom(field.getType())) { + if (itemFieldName == null && keyFieldName == null) { + itemType = Map.Entry.class; + } + } else if (!Collection.class.isAssignableFrom(field.getType())) { + Class fieldType = field.getType(); + if (!fieldType.isArray()) { + throw new InitializationException("Field \"" + + fieldName + + "\" declares no collection or array"); + } else { + Class componentType = fieldType.getComponentType(); + componentType = componentType.isPrimitive() ? Primitives.box(componentType) : componentType; + if (itemType == null) { + itemType = componentType; + } else { + itemType = itemType.isPrimitive() ? Primitives.box(itemType) : itemType; + if (!componentType.isAssignableFrom(itemType)) { + throw new InitializationException("Field \"" + + fieldName + + "\" declares an array, but the array type is not compatible with " + itemType.getName()); + + } + } + } + } + ImplicitCollectionMapperForClass mapper = getOrCreateMapper(definedIn); + mapper.add(new ImplicitCollectionMappingImpl(fieldName, itemType, itemFieldName, keyFieldName)); + } + + private class ImplicitCollectionMapperForClass { + private Class definedIn; + // { (NamedItemType) -> (ImplicitCollectionDefImpl) } + private Map namedItemTypeToDef = new HashMap(); + // { itemFieldName (String) -> (ImplicitCollectionDefImpl) } + private Map itemFieldNameToDef = new HashMap(); + // { fieldName (String) -> (ImplicitCollectionDefImpl) } + private Map fieldNameToDef = new HashMap(); + + ImplicitCollectionMapperForClass(Class definedIn) { + this.definedIn = definedIn; + } + + public String getFieldNameForItemTypeAndName(Class itemType, String itemFieldName) { + ImplicitCollectionMappingImpl unnamed = null; + for (Iterator iterator = namedItemTypeToDef.keySet().iterator(); iterator.hasNext();) { + NamedItemType itemTypeForFieldName = (NamedItemType)iterator.next(); + ImplicitCollectionMappingImpl def = (ImplicitCollectionMappingImpl)namedItemTypeToDef + .get(itemTypeForFieldName); + if (itemType == Mapper.Null.class) { + unnamed = def; + break; + } else if (itemTypeForFieldName.itemType.isAssignableFrom(itemType)) { + if (def.getItemFieldName() != null) { + if (def.getItemFieldName().equals(itemFieldName)) { + return def.getFieldName(); + } + } else { + if (unnamed == null + || unnamed.getItemType() == null + || (def.getItemType() != null + && unnamed.getItemType().isAssignableFrom(def.getItemType()))) { + unnamed = def; + } + } + } + } + if (unnamed != null) { + return unnamed.getFieldName(); + } else { + ImplicitCollectionMapperForClass mapper = ImplicitCollectionMapper.this.getMapper(definedIn.getSuperclass()); + return mapper != null ? mapper.getFieldNameForItemTypeAndName(itemType, itemFieldName) : null; + } + } + + public Class getItemTypeForItemFieldName(String itemFieldName) { + ImplicitCollectionMappingImpl def = getImplicitCollectionDefByItemFieldName(itemFieldName); + if (def != null) { + return def.getItemType(); + } else { + ImplicitCollectionMapperForClass mapper = ImplicitCollectionMapper.this.getMapper(definedIn.getSuperclass()); + return mapper != null ? mapper.getItemTypeForItemFieldName(itemFieldName) : null; + } + } + + private ImplicitCollectionMappingImpl getImplicitCollectionDefByItemFieldName( + String itemFieldName) { + if (itemFieldName == null) { + return null; + } else { + ImplicitCollectionMappingImpl mapping = (ImplicitCollectionMappingImpl)itemFieldNameToDef.get(itemFieldName); + if (mapping != null) { + return mapping; + } else { + ImplicitCollectionMapperForClass mapper = ImplicitCollectionMapper.this.getMapper(definedIn.getSuperclass()); + return mapper != null ? mapper.getImplicitCollectionDefByItemFieldName(itemFieldName) : null; + } + } + } + + public ImplicitCollectionMapping getImplicitCollectionDefForFieldName(String fieldName) { + ImplicitCollectionMapping mapping = (ImplicitCollectionMapping)fieldNameToDef.get(fieldName); + if (mapping != null) { + return mapping; + } else { + ImplicitCollectionMapperForClass mapper = ImplicitCollectionMapper.this.getMapper(definedIn.getSuperclass()); + return mapper != null ? mapper.getImplicitCollectionDefForFieldName(fieldName) : null; + } + } + + public void add(ImplicitCollectionMappingImpl def) { + fieldNameToDef.put(def.getFieldName(), def); + namedItemTypeToDef.put(def.createNamedItemType(), def); + if (def.getItemFieldName() != null) { + itemFieldNameToDef.put(def.getItemFieldName(), def); + } + } + + } + + private static class ImplicitCollectionMappingImpl implements ImplicitCollectionMapping { + private final String fieldName; + private final String itemFieldName; + private final Class itemType; + private final String keyFieldName; + + ImplicitCollectionMappingImpl(String fieldName, Class itemType, String itemFieldName, String keyFieldName) { + this.fieldName = fieldName; + this.itemFieldName = itemFieldName; + this.itemType = itemType; + this.keyFieldName = keyFieldName; + } + + public NamedItemType createNamedItemType() { + return new NamedItemType(itemType, itemFieldName); + } + + public String getFieldName() { + return fieldName; + } + + public String getItemFieldName() { + return itemFieldName; + } + + public Class getItemType() { + return itemType; + } + + public String getKeyFieldName() { + return keyFieldName; + } + } + + private static class NamedItemType { + Class itemType; + String itemFieldName; + + NamedItemType(Class itemType, String itemFieldName) { + this.itemType = itemType == null ? Object.class : itemType; + this.itemFieldName = itemFieldName; + } + + public boolean equals(Object obj) { + if (obj instanceof NamedItemType) { + NamedItemType b = (NamedItemType)obj; + return itemType.equals(b.itemType) && isEquals(itemFieldName, b.itemFieldName); + } else { + return false; + } + } + + private static boolean isEquals(Object a, Object b) { + if (a == null) { + return b == null; + } else { + return a.equals(b); + } + } + + public int hashCode() { + int hash = itemType.hashCode() << 7; + if (itemFieldName != null) { + hash += itemFieldName.hashCode(); + } + return hash; + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/LambdaMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/LambdaMapper.java new file mode 100644 index 0000000..6416105 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/LambdaMapper.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2015 XStream Committers. + * All rights reserved. + * + * Created on 15. January 2015 by Joerg Schaible + */ +package com.thoughtworks.xstream.mapper; + +import java.io.Serializable; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import com.thoughtworks.xstream.core.util.Types; + + +/** + * Mapper to map serializable lambda types to the name of their functional interface and non-serializable ones to + * Mapper.Null. + * + * @author Jörg Schaible + * @since 1.4.8 + */ +public class LambdaMapper extends MapperWrapper { + + /** + * Constructs a LambdaMapper. + * + * @param wrapped mapper + * @since 1.4.8 + */ + public LambdaMapper(final Mapper wrapped) { + super(wrapped); + } + + @Override + public String serializedClass(final Class type) { + Class replacement = null; + if (Types.isLambdaType(type)) { + if (Serializable.class.isAssignableFrom(type)) { + final Class[] interfaces = type.getInterfaces(); + if (interfaces.length > 1) { + for (int i = 0; replacement == null && i < interfaces.length; i++) { + final Class iface = interfaces[i]; + for (final Method method : iface.getMethods()) { + if (!method.isDefault() && !Modifier.isStatic(method.getModifiers())) { + replacement = iface; + break; + } + } + } + } else { + replacement = interfaces[0]; + } + } else { + replacement = Null.class; + } + } + return super.serializedClass(replacement == null ? type : replacement); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/LocalConversionMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/LocalConversionMapper.java new file mode 100644 index 0000000..6bc4359 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/LocalConversionMapper.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. November 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.mapper; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.core.util.FastField; + +import java.util.HashMap; +import java.util.Map; + + +/** + * A Mapper for locally defined converters for a member field. + * + * @author Jörg Schaible + * @since 1.3 + */ +public class LocalConversionMapper extends MapperWrapper { + + private final Map localConverters = new HashMap(); + private transient AttributeMapper attributeMapper; + + /** + * Constructs a LocalConversionMapper. + * + * @param wrapped + * @since 1.3 + */ + public LocalConversionMapper(Mapper wrapped) { + super(wrapped); + readResolve(); + } + + public void registerLocalConverter(Class definedIn, String fieldName, Converter converter) { + localConverters.put(new FastField(definedIn, fieldName), converter); + } + + public Converter getLocalConverter(Class definedIn, String fieldName) { + return (Converter)localConverters.get(new FastField(definedIn, fieldName)); + } + + public SingleValueConverter getConverterFromAttribute(Class definedIn, String attribute, + Class type) { + SingleValueConverter converter = getLocalSingleValueConverter( + definedIn, attribute, type); + return converter == null + ? super.getConverterFromAttribute(definedIn, attribute, type) + : converter; + } + + public SingleValueConverter getConverterFromItemType(String fieldName, Class type, + Class definedIn) { + SingleValueConverter converter = getLocalSingleValueConverter( + definedIn, fieldName, type); + return converter == null + ? super.getConverterFromItemType(fieldName, type, definedIn) + : converter; + } + + private SingleValueConverter getLocalSingleValueConverter(Class definedIn, + String fieldName, Class type) { + if (attributeMapper != null + && attributeMapper.shouldLookForSingleValueConverter(fieldName, type, definedIn)) { + Converter converter = getLocalConverter(definedIn, fieldName); + if (converter != null && converter instanceof SingleValueConverter) { + return (SingleValueConverter)converter; + } + } + return null; + } + + private Object readResolve() { + this.attributeMapper = (AttributeMapper)lookupMapperOfType(AttributeMapper.class); + return this; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/Mapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/Mapper.java new file mode 100644 index 0000000..17bcaeb --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/Mapper.java @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. January 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.mapper; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.SingleValueConverter; + +public interface Mapper { + /** + * Place holder type used for null values. + */ + class Null {} + + /** + * How a class name should be represented in its serialized form. + */ + String serializedClass(Class type); + + /** + * How a serialized class representation should be mapped back to a real class. + */ + Class realClass(String elementName); + + /** + * How a class member should be represented in its serialized form. + */ + String serializedMember(Class type, String memberName); + + /** + * How a serialized member representation should be mapped back to a real member. + */ + String realMember(Class type, String serialized); + + /** + * Whether this type is a simple immutable value (int, boolean, String, URL, etc. + * Immutable types will be repeatedly written in the serialized stream, instead of using object references. + */ + boolean isImmutableValueType(Class type); + + Class defaultImplementationOf(Class type); + + /** + * Get the alias for an attribute's name. + * + * @param attribute the attribute + * @return the alias + * @since 1.2 + */ + String aliasForAttribute(String attribute); + + /** + * Get the attribute's name for an alias. + * + * @param alias the alias + * @return the attribute's name + * @since 1.2 + */ + String attributeForAlias(String alias); + + /** + * Get the alias for a system attribute's name. + * + * @param attribute the system attribute + * @return the alias + * @since 1.3.1 + */ + String aliasForSystemAttribute(String attribute); + + /** + * Get the name of the field that acts as the default collection for an object, or return null if there is none. + * + * @param definedIn owning type + * @param itemType item type + * @param itemFieldName optional item element name + */ + String getFieldNameForItemTypeAndName(Class definedIn, Class itemType, String itemFieldName); + + Class getItemTypeForItemFieldName(Class definedIn, String itemFieldName); + + ImplicitCollectionMapping getImplicitCollectionDefForFieldName(Class itemType, String fieldName); + + /** + * Determine whether a specific member should be serialized. + * + * @since 1.1.3 + */ + boolean shouldSerializeMember(Class definedIn, String fieldName); + + interface ImplicitCollectionMapping { + String getFieldName(); + String getItemFieldName(); + Class getItemType(); + String getKeyFieldName(); + } + + /** + * @deprecated As of 1.3, use {@link #getConverterFromItemType(String, Class, Class)} + */ + SingleValueConverter getConverterFromItemType(String fieldName, Class type); + + /** + * @deprecated As of 1.3, use {@link #getConverterFromItemType(String, Class, Class)} + */ + SingleValueConverter getConverterFromItemType(Class type); + + /** + * @deprecated As of 1.3, use {@link #getConverterFromAttribute(Class, String, Class)} + */ + SingleValueConverter getConverterFromAttribute(String name); + + Converter getLocalConverter(Class definedIn, String fieldName); + + Mapper lookupMapperOfType(Class type); + + /** + * Returns a single value converter to be used in a specific field. + * + * @param fieldName the field name + * @param type the field type + * @param definedIn the type which defines this field + * @return a SingleValueConverter or null if there no such converter should be used for this + * field. + * @since 1.2.2 + */ + SingleValueConverter getConverterFromItemType(String fieldName, Class type, Class definedIn); + + /** + * Returns an alias for a single field defined in an specific type. + * + * @param definedIn the type where the field was defined + * @param fieldName the field name + * @return the alias for this field or its own name if no alias was defined + * @since 1.2.2 + * @deprecated As of 1.3, use combination of {@link #serializedMember(Class, String)} and {@link #getConverterFromItemType(String, Class, Class)} + */ + String aliasForAttribute(Class definedIn, String fieldName); + + /** + * Returns the field name for an aliased attribute. + * + * @param definedIn the type where the field was defined + * @param alias the alias + * @return the original attribute name + * @since 1.2.2 + * @deprecated As of 1.3, use combination of {@link #realMember(Class, String)} and {@link #getConverterFromItemType(String, Class, Class)} + */ + String attributeForAlias(Class definedIn, String alias); + + /** + * Returns which converter to use for an specific attribute in a type. + * + * @param definedIn the field's parent + * @param attribute the attribute name + * @deprecated As of 1.3.1, use {@link #getConverterFromAttribute(Class, String, Class)} + */ + SingleValueConverter getConverterFromAttribute(Class definedIn, String attribute); + + /** + * Returns which converter to use for an specific attribute in a type. + * + * @param definedIn the field's parent + * @param attribute the attribute name + * @param type the type the converter should create + * @since 1.3.1 + */ + SingleValueConverter getConverterFromAttribute(Class definedIn, String attribute, Class type); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/MapperWrapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/MapperWrapper.java new file mode 100644 index 0000000..93ced3d --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/MapperWrapper.java @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. January 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.mapper; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.SingleValueConverter; + +public abstract class MapperWrapper implements Mapper { + + private final Mapper wrapped; + + public MapperWrapper(Mapper wrapped) { + this.wrapped = wrapped; + } + + public String serializedClass(Class type) { + return wrapped.serializedClass(type); + } + + public Class realClass(String elementName) { + return wrapped.realClass(elementName); + } + + public String serializedMember(Class type, String memberName) { + return wrapped.serializedMember(type, memberName); + } + + public String realMember(Class type, String serialized) { + return wrapped.realMember(type, serialized); + } + + public boolean isImmutableValueType(Class type) { + return wrapped.isImmutableValueType(type); + } + + public Class defaultImplementationOf(Class type) { + return wrapped.defaultImplementationOf(type); + } + + public String aliasForAttribute(String attribute) { + return wrapped.aliasForAttribute(attribute); + } + + public String attributeForAlias(String alias) { + return wrapped.attributeForAlias(alias); + } + + public String aliasForSystemAttribute(String attribute) { + return wrapped.aliasForSystemAttribute(attribute); + } + + public String getFieldNameForItemTypeAndName(Class definedIn, Class itemType, String itemFieldName) { + return wrapped.getFieldNameForItemTypeAndName(definedIn, itemType, itemFieldName); + } + + public Class getItemTypeForItemFieldName(Class definedIn, String itemFieldName) { + return wrapped.getItemTypeForItemFieldName(definedIn, itemFieldName); + } + + public ImplicitCollectionMapping getImplicitCollectionDefForFieldName(Class itemType, String fieldName) { + return wrapped.getImplicitCollectionDefForFieldName(itemType, fieldName); + } + + public boolean shouldSerializeMember(Class definedIn, String fieldName) { + return wrapped.shouldSerializeMember(definedIn, fieldName); + } + + /** + * @deprecated As of 1.3, use {@link #getConverterFromItemType(String, Class, Class)} + */ + public SingleValueConverter getConverterFromItemType(String fieldName, Class type) { + return wrapped.getConverterFromItemType(fieldName, type); + } + + /** + * @deprecated As of 1.3, use {@link #getConverterFromItemType(String, Class, Class)} + */ + public SingleValueConverter getConverterFromItemType(Class type) { + return wrapped.getConverterFromItemType(type); + } + + /** + * @deprecated As of 1.3, use {@link #getConverterFromAttribute(Class, String, Class)} + */ + public SingleValueConverter getConverterFromAttribute(String name) { + return wrapped.getConverterFromAttribute(name); + } + + public Converter getLocalConverter(Class definedIn, String fieldName) { + return wrapped.getLocalConverter(definedIn, fieldName); + } + + public Mapper lookupMapperOfType(Class type) { + return type.isAssignableFrom(getClass()) ? this : wrapped.lookupMapperOfType(type); + } + + public SingleValueConverter getConverterFromItemType(String fieldName, Class type, Class definedIn) { + return wrapped.getConverterFromItemType(fieldName, type, definedIn); + } + + /** + * @deprecated As of 1.3, use combination of {@link #serializedMember(Class, String)} and {@link #getConverterFromItemType(String, Class, Class)} + */ + public String aliasForAttribute(Class definedIn, String fieldName) { + return wrapped.aliasForAttribute(definedIn, fieldName); + } + + /** + * @deprecated As of 1.3, use combination of {@link #realMember(Class, String)} and {@link #getConverterFromItemType(String, Class, Class)} + */ + public String attributeForAlias(Class definedIn, String alias) { + return wrapped.attributeForAlias(definedIn, alias); + } + + /** + * @deprecated As of 1.3.1, use {@link #getConverterFromAttribute(Class, String, Class)} + */ + public SingleValueConverter getConverterFromAttribute(Class type, String attribute) { + return wrapped.getConverterFromAttribute(type, attribute); + } + + public SingleValueConverter getConverterFromAttribute(Class definedIn, String attribute, Class type) { + return wrapped.getConverterFromAttribute(definedIn, attribute, type); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/OuterClassMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/OuterClassMapper.java new file mode 100644 index 0000000..f98c514 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/OuterClassMapper.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 31. January 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.mapper; + +/** + * Mapper that uses a more meaningful alias for the field in an inner class (this$0) that refers to the outer class. + * + * @author Joe Walnes + */ +public class OuterClassMapper extends MapperWrapper { + + private final String alias; + + public OuterClassMapper(Mapper wrapped) { + this(wrapped, "outer-class"); + } + + public OuterClassMapper(Mapper wrapped, String alias) { + super(wrapped); + this.alias = alias; + } + + public String serializedMember(Class type, String memberName) { + if (memberName.equals("this$0")) { + return alias; + } else { + return super.serializedMember(type, memberName); + } + } + + public String realMember(Class type, String serialized) { + if (serialized.equals(alias)) { + return "this$0"; + } else { + return super.realMember(type, serialized); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/PackageAliasingMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/PackageAliasingMapper.java new file mode 100644 index 0000000..5d8ef56 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/PackageAliasingMapper.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 10. November 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.mapper; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; + + +/** + * Mapper that allows a package name to be replaced with an alias. + * + * @author Jörg Schaible + */ +public class PackageAliasingMapper extends MapperWrapper implements Serializable { + + private static final Comparator REVERSE = new Comparator() { + + public int compare(final Object o1, final Object o2) { + return ((String)o2).compareTo((String)o1); + } + }; + + private Map packageToName = new TreeMap(REVERSE); + protected transient Map nameToPackage = new HashMap(); + + public PackageAliasingMapper(final Mapper wrapped) { + super(wrapped); + } + + public void addPackageAlias(String name, String pkg) { + if (name.length() > 0 && name.charAt(name.length() - 1) != '.') { + name += '.'; + } + if (pkg.length() > 0 && pkg.charAt(pkg.length() - 1) != '.') { + pkg += '.'; + } + nameToPackage.put(name, pkg); + packageToName.put(pkg, name); + } + + public String serializedClass(final Class type) { + final String className = type.getName(); + int length = className.length(); + int dot = -1; + do { + dot = className.lastIndexOf('.', length); + final String pkg = dot < 0 ? "" : className.substring(0, dot + 1); + final String alias = (String)packageToName.get(pkg); + if (alias != null) { + return alias + (dot < 0 ? className : className.substring(dot + 1)); + } + length = dot - 1; + } while (dot >= 0); + return super.serializedClass(type); + } + + public Class realClass(String elementName) { + int length = elementName.length(); + int dot = -1; + do { + dot = elementName.lastIndexOf('.', length); + final String name = dot < 0 ? "" : elementName.substring(0, dot) + '.'; + final String packageName = (String)nameToPackage.get(name); + + if (packageName != null) { + elementName = packageName + + (dot < 0 ? elementName : elementName.substring(dot + 1)); + break; + } + length = dot - 1; + } while (dot >= 0); + + return super.realClass(elementName); + } + + private void writeObject(final ObjectOutputStream out) throws IOException { + out.writeObject(new HashMap(packageToName)); + } + + private void readObject(final ObjectInputStream in) + throws IOException, ClassNotFoundException { + packageToName = new TreeMap(REVERSE); + packageToName.putAll((Map)in.readObject()); + nameToPackage = new HashMap(); + for (final Iterator iter = packageToName.keySet().iterator(); iter.hasNext();) { + final Object type = iter.next(); + nameToPackage.put(packageToName.get(type), type); + } + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/SecurityMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/SecurityMapper.java new file mode 100644 index 0000000..d650c92 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/SecurityMapper.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2014 XStream Committers. + * All rights reserved. + * + * Created on 08. January 2014 by Joerg Schaible + */ +package com.thoughtworks.xstream.mapper; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.thoughtworks.xstream.security.AnyTypePermission; +import com.thoughtworks.xstream.security.ForbiddenClassException; +import com.thoughtworks.xstream.security.NoTypePermission; +import com.thoughtworks.xstream.security.TypePermission; + + +/** + * A Mapper implementation injecting a security layer based on permission rules for any type required in the + * unmarshalling process. + * + * @author Jörg Schaible + * @since 1.4.7 + */ +public class SecurityMapper extends MapperWrapper { + + private final List permissions; + + /** + * Construct a SecurityMapper. + * + * @param wrapped the mapper chain + * @since 1.4.7 + */ + public SecurityMapper(final Mapper wrapped) { + this(wrapped, (TypePermission[])null); + } + + /** + * Construct a SecurityMapper. + * + * @param wrapped the mapper chain + * @param permissions the predefined permissions + * @since 1.4.7 + */ + public SecurityMapper(final Mapper wrapped, final TypePermission[] permissions) { + super(wrapped); + this.permissions = permissions == null // + ? new ArrayList() + : new ArrayList(Arrays.asList(permissions)); + } + + /** + * Add a new permission. + *

+ * Permissions are evaluated in the added sequence. An instance of {@link NoTypePermission} or + * {@link AnyTypePermission} will implicitly wipe any existing permission. + *

+ * + * @param permission the permission to add. + * @since 1.4.7 + */ + public void addPermission(final TypePermission permission) { + if (permission.equals(NoTypePermission.NONE) || permission.equals(AnyTypePermission.ANY)) + permissions.clear(); + permissions.add(0, permission); + } + + public Class realClass(final String elementName) { + final Class type = super.realClass(elementName); + for (int i = 0; i < permissions.size(); ++i) { + final TypePermission permission = (TypePermission)permissions.get(i); + if (permission.allows(type)) + return type; + } + throw new ForbiddenClassException(type); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/SystemAttributeAliasingMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/SystemAttributeAliasingMapper.java new file mode 100644 index 0000000..e372129 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/SystemAttributeAliasingMapper.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 09. October 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.mapper; + + +/** + * Mapper that allows aliasing of system attribute names. + * + * @author Jörg Schaible + * @since 1.3.1 + */ +public class SystemAttributeAliasingMapper extends AbstractAttributeAliasingMapper { + + public SystemAttributeAliasingMapper(Mapper wrapped) { + super(wrapped); + } + + public String aliasForSystemAttribute(String attribute) { + String alias = (String)nameToAlias.get(attribute); + if (alias == null && !nameToAlias.containsKey(attribute)) { + alias = super.aliasForSystemAttribute(attribute); + if (alias == attribute) { + alias = super.aliasForAttribute(attribute); + } + } + return alias; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/XStream11XmlFriendlyMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/XStream11XmlFriendlyMapper.java new file mode 100644 index 0000000..41e974d --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/XStream11XmlFriendlyMapper.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. May 2006 by Mauro Talevi + */ +package com.thoughtworks.xstream.mapper; + + +/** + * Mapper that ensures that all names in the serialization stream are read in an XML friendly way. + *
    + *
  • _ (underscore) chars appearing in class names are replaced with $ (dollar)
  • + *
  • _DOLLAR_ string appearing in field names are replaced with $ (dollar)
  • + *
  • __ string appearing in field names are replaced with _ (underscore)
  • + *
  • default is the prefix for class names with no package.
  • + *
+ * + * Note, this class is no longer in regular use for current XStream versions. It exists to provide backward compatibility + * to existing XML data written with older XStream versions (<= 1.1). + * + * @author Joe Walnes + * @author Mauro Talevi + * @deprecated As of 1.4 use {@link com.thoughtworks.xstream.io.xml.XmlFriendlyReader} + */ +public class XStream11XmlFriendlyMapper extends AbstractXmlFriendlyMapper { + + public XStream11XmlFriendlyMapper(Mapper wrapped) { + super(wrapped); + } + + public Class realClass(String elementName) { + return super.realClass(unescapeClassName(elementName)); + } + + public String realMember(Class type, String serialized) { + return unescapeFieldName(super.realMember(type, serialized)); + } + + public String mapNameFromXML(String xmlName) { + return unescapeFieldName(xmlName); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/mapper/XmlFriendlyMapper.java b/xstream/src/java/com/thoughtworks/xstream/mapper/XmlFriendlyMapper.java new file mode 100644 index 0000000..1758b79 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/mapper/XmlFriendlyMapper.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. January 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.mapper; + +/** + * Mapper that ensures that all names in the serialization stream are XML friendly. + * The replacement chars and strings are: + *
    + *
  • $ (dollar) chars appearing in class names are replaced with _ (underscore) chars.
  • + *
  • $ (dollar) chars appearing in field names are replaced with _DOLLAR_ string.
  • + *
  • _ (underscore) chars appearing in field names are replaced with __ (double underscore) string.
  • + *
  • default as the prefix for class names with no package.
  • + *
+ * + * @author Joe Walnes + * @author Mauro Talevi + * @deprecated As of 1.3 use {@link com.thoughtworks.xstream.io.xml.XmlFriendlyReader} + */ +public class XmlFriendlyMapper extends AbstractXmlFriendlyMapper { + + /** + * @deprecated As of 1.3 use {@link com.thoughtworks.xstream.io.xml.XmlFriendlyReader} + */ + public XmlFriendlyMapper(Mapper wrapped) { + super(wrapped); + } + + public String serializedClass(Class type) { + return escapeClassName(super.serializedClass(type)); + } + + public Class realClass(String elementName) { + return super.realClass(unescapeClassName(elementName)); + } + + public String serializedMember(Class type, String memberName) { + return escapeFieldName(super.serializedMember(type, memberName)); + } + + public String realMember(Class type, String serialized) { + return unescapeFieldName(super.realMember(type, serialized)); + } + + public String mapNameToXML(String javaName) { + return escapeFieldName(javaName); + } + + public String mapNameFromXML(String xmlName) { + return unescapeFieldName(xmlName); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/persistence/AbstractFilePersistenceStrategy.java b/xstream/src/java/com/thoughtworks/xstream/persistence/AbstractFilePersistenceStrategy.java new file mode 100644 index 0000000..fcdb1de --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/persistence/AbstractFilePersistenceStrategy.java @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 18. November 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.persistence; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.Writer; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + + +/** + * Abstract base class for file based persistence strategies. + * + * @author Guilherme Silveira + * @author Joerg Schaible + * @since 1.3.1 + */ +public abstract class AbstractFilePersistenceStrategy implements PersistenceStrategy { + + private final FilenameFilter filter; + private final File baseDirectory; + private final String encoding; + private final transient XStream xstream; + + public AbstractFilePersistenceStrategy( + final File baseDirectory, final XStream xstream, final String encoding) { + this.baseDirectory = baseDirectory; + this.xstream = xstream; + this.encoding = encoding; + filter = new ValidFilenameFilter(); + } + + protected ConverterLookup getConverterLookup() { + return xstream.getConverterLookup(); + } + + protected Mapper getMapper() { + return xstream.getMapper(); + } + + protected boolean isValid(final File dir, final String name) { + return name.endsWith(".xml"); + } + + /** + * Given a filename, the unescape method returns the key which originated it. + * + * @param name the filename + * @return the original key + */ + protected abstract Object extractKey(String name); + + /** + * Given a key, the escape method returns the filename which shall be used. + * + * @param key the key + * @return the desired and escaped filename + */ + protected abstract String getName(Object key); + + protected class ValidFilenameFilter implements FilenameFilter { + public boolean accept(final File dir, final String name) { + return new File(dir, name).isFile() && isValid(dir, name); + } + } + + protected class XmlMapEntriesIterator implements Iterator { + + private final File[] files = baseDirectory.listFiles(filter); + + private int position = -1; + + private File current = null; + + public boolean hasNext() { + return position + 1 < files.length; + } + + public void remove() { + if (current == null) { + throw new IllegalStateException(); + } + // removes without loading + current.delete(); + } + + public Object next() { + return new Map.Entry() { + private final File file = current = files[ ++position]; + private final Object key = extractKey(file.getName()); + + public Object getKey() { + return key; + } + + public Object getValue() { + return readFile(file); + } + + public Object setValue(final Object value) { + return put(key, value); + } + + public boolean equals(final Object obj) { + if (!(obj instanceof Entry)) { + return false; + } + Object value = getValue(); + final Entry e2 = (Entry)obj; + Object key2 = e2.getKey(); + Object value2 = e2.getValue(); + return (key == null ? key2 == null : key.equals(key2)) + && (value == null ? value2 == null : getValue().equals(e2.getValue())); + } + }; + } + } + + private void writeFile(final File file, final Object value) { + try { + final FileOutputStream out = new FileOutputStream(file); + final Writer writer = encoding != null + ? new OutputStreamWriter(out, encoding) + : new OutputStreamWriter(out); + try { + xstream.toXML(value, writer); + } finally { + writer.close(); + } + } catch (final IOException e) { + throw new StreamException(e); + } + } + + private File getFile(final String filename) { + return new File(baseDirectory, filename); + } + + private Object readFile(final File file) { + try { + final FileInputStream in = new FileInputStream(file); + final Reader reader = encoding != null + ? new InputStreamReader(in, encoding) + : new InputStreamReader(in); + try { + return xstream.fromXML(reader); + } finally { + reader.close(); + } + } catch (final FileNotFoundException e) { + // not found... file.exists might generate a sync problem + return null; + } catch (final IOException e) { + throw new StreamException(e); + } + } + + public Object put(final Object key, final Object value) { + final Object oldValue = get(key); + final String filename = getName(key); + writeFile(new File(baseDirectory, filename), value); + return oldValue; + } + + public Iterator iterator() { + return new XmlMapEntriesIterator(); + } + + public int size() { + return baseDirectory.list(filter).length; + } + + public boolean containsKey(final Object key) { + // faster lookup + final File file = getFile(getName(key)); + return file.isFile(); + } + + public Object get(final Object key) { + return readFile(getFile(getName(key))); + } + + public Object remove(final Object key) { + // faster lookup + final File file = getFile(getName(key)); + Object value = null; + if (file.isFile()) { + value = readFile(file); + file.delete(); + } + return value; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/persistence/FilePersistenceStrategy.java b/xstream/src/java/com/thoughtworks/xstream/persistence/FilePersistenceStrategy.java new file mode 100644 index 0000000..ea973e8 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/persistence/FilePersistenceStrategy.java @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 20. November 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.persistence; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.xml.DomDriver; + +import java.io.File; + + +/** + * PersistenceStrategy to assign keys with single value to objects persisted in files. The + * default naming strategy is based on the key's type and its {@link SingleValueConverter}. It + * escapes all characters that are normally illegal in the most common file systems. Such a + * character is escaped with percent escaping as it is done by URL encoding. The XStream used to + * marshal the values is also requested for the key's SingleValueConverter. A + * {@link StreamException} is thrown if no such converter is registered. + * + * @author Jörg Schaible + * @author Guilherme Silveira + * @since 1.3.1 + */ +public class FilePersistenceStrategy extends AbstractFilePersistenceStrategy { + + private final String illegalChars; + + /** + * Create a new FilePersistenceStrategy. Use a standard XStream instance with a + * {@link DomDriver}. + * + * @param baseDirectory the directory for the serialized values + * @since 1.3.1 + */ + public FilePersistenceStrategy(final File baseDirectory) { + this(baseDirectory, new XStream(new DomDriver())); + } + + /** + * Create a new FilePersistenceStrategy with a provided XStream instance. + * + * @param baseDirectory the directory for the serialized values + * @param xstream the XStream instance to use for (de)serialization + * @since 1.3.1 + */ + public FilePersistenceStrategy(final File baseDirectory, final XStream xstream) { + this(baseDirectory, xstream, "utf-8", "<>?:/\\\"|*%"); + } + + /** + * Create a new FilePersistenceStrategy with a provided XStream instance and the characters + * to encode. + * + * @param baseDirectory the directory for the serialized values + * @param xstream the XStream instance to use for (de)serialization + * @param encoding encoding used to write the files + * @param illegalChars illegal characters for file names (should always include '%' as long + * as you do not overwrite the (un)escape methods) + * @since 1.3.1 + */ + public FilePersistenceStrategy( + final File baseDirectory, final XStream xstream, final String encoding, + final String illegalChars) { + super(baseDirectory, xstream, encoding); + this.illegalChars = illegalChars; + } + + protected boolean isValid(final File dir, final String name) { + return super.isValid(dir, name) && name.indexOf('@') > 0; + } + + /** + * Given a filename, the unescape method returns the key which originated it. + * + * @param name the filename + * @return the original key + */ + protected Object extractKey(final String name) { + final String key = unescape(name.substring(0, name.length() - 4)); + if ("null@null".equals(key)) { + return null; + } + int idx = key.indexOf('@'); + if (idx < 0) { + throw new StreamException("Not a valid key: " + key); + } + Class type = getMapper().realClass(key.substring(0, idx)); + Converter converter = getConverterLookup().lookupConverterForType(type); + if (converter instanceof SingleValueConverter) { + final SingleValueConverter svConverter = (SingleValueConverter)converter; + return svConverter.fromString(key.substring(idx + 1)); + } else { + throw new StreamException("No SingleValueConverter for type " + + type.getName() + + " available"); + } + } + + protected String unescape(String name) { + final StringBuffer buffer = new StringBuffer(); + for (int idx = name.indexOf('%'); idx >= 0; idx = name.indexOf('%')) { + buffer.append(name.substring(0, idx)); + int c = Integer.parseInt(name.substring(idx + 1, idx + 3), 16); + buffer.append((char)c); + name = name.substring(idx + 3); + } + buffer.append(name); + return buffer.toString(); + } + + /** + * Given a key, the escape method returns the filename which shall be used. + * + * @param key the key + * @return the desired and escaped filename + */ + protected String getName(final Object key) { + if (key == null) { + return "null@null.xml"; + } + Class type = key.getClass(); + Converter converter = getConverterLookup().lookupConverterForType(type); + if (converter instanceof SingleValueConverter) { + final SingleValueConverter svConverter = (SingleValueConverter)converter; + return getMapper().serializedClass(type) + + '@' + + escape(svConverter.toString(key)) + + ".xml"; + } else { + throw new StreamException("No SingleValueConverter for type " + + type.getName() + + " available"); + } + } + + protected String escape(final String key) { + final StringBuffer buffer = new StringBuffer(); + final char[] array = key.toCharArray(); + for (int i = 0; i < array.length; i++ ) { + final char c = array[i]; + if (c >= ' ' && illegalChars.indexOf(c) < 0) { + buffer.append(c); + } else { + buffer.append("%" + Integer.toHexString(c).toUpperCase()); + } + } + return buffer.toString(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/persistence/FileStreamStrategy.java b/xstream/src/java/com/thoughtworks/xstream/persistence/FileStreamStrategy.java new file mode 100644 index 0000000..9a03672 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/persistence/FileStreamStrategy.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. June 2006 by Guilherme Silveira + */ +package com.thoughtworks.xstream.persistence; + +import com.thoughtworks.xstream.XStream; + +import java.io.File; + + +/** + * PersistenceStrategy to assign string based keys to objects persisted in files. The file + * naming strategy is based on the key's type name and its toString method. It escapes non + * digit, non a-z and A-Z characters. In order to change the escaping/unescaping algorithm, + * simply extend this class and rewrite its getName/extractKey methods. Note, this + * implementation silently implies that the keys actually are Strings, since the keys will be + * turned into string keys at deserialization time. + * + * @author Guilherme Silveira + * @deprecated As of 1.3.1, use FilePersistenceStrategy + */ +public class FileStreamStrategy extends AbstractFilePersistenceStrategy implements + StreamStrategy { + public FileStreamStrategy(final File baseDirectory) { + this(baseDirectory, new XStream()); + } + + public FileStreamStrategy(final File baseDirectory, final XStream xstream) { + super(baseDirectory, xstream, null); + } + + /** + * Given a filename, the unescape method returns the key which originated it. + * + * @param name the filename + * @return the original key + */ + protected Object extractKey(final String name) { + final String key = unescape(name.substring(0, name.length() - 4)); + return key.equals("\0") ? null : key; + } + + protected String unescape(final String name) { + final StringBuffer buffer = new StringBuffer(); + char lastC = '\uffff'; + int currentValue = -1; + // do we have a regex master to do it? + final char[] array = name.toCharArray(); + for (int i = 0; i < array.length; i++ ) { + final char c = array[i]; + if (c == '_' && currentValue != -1) { + if (lastC == '_') { + buffer.append('_'); + } else { + buffer.append((char)currentValue); + } + currentValue = -1; + } else if (c == '_') { + currentValue = 0; + } else if (currentValue != -1) { + currentValue = currentValue * 16 + Integer.parseInt(String.valueOf(c), 16); + } else { + buffer.append(c); + } + lastC = c; + } + return buffer.toString(); + } + + /** + * Given a key, the escape method returns the filename which shall be used. + * + * @param key the key + * @return the desired and escaped filename + */ + protected String getName(final Object key) { + return escape(key == null ? "\0" : key.toString()) + ".xml"; + } + + protected String escape(final String key) { + // do we have a regex master to do it? + final StringBuffer buffer = new StringBuffer(); + final char[] array = key.toCharArray(); + for (int i = 0; i < array.length; i++ ) { + final char c = array[i]; + if (Character.isDigit(c) || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) { + buffer.append(c); + } else if (c == '_') { + buffer.append("__"); + } else { + buffer.append("_" + (Integer.toHexString(c)) + "_"); + } + } + return buffer.toString(); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/persistence/PersistenceStrategy.java b/xstream/src/java/com/thoughtworks/xstream/persistence/PersistenceStrategy.java new file mode 100644 index 0000000..9144c18 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/persistence/PersistenceStrategy.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 20. November 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.persistence; + +import java.util.Iterator; + + +/** + * A key to a persistent storage and vice-versa strategy interface. + * + * @author Guilherme Silveira + * @since 1.3.1 + */ +public interface PersistenceStrategy { + + Iterator iterator(); + + int size(); + + Object get(Object key); + + Object put(Object key, Object value); + + Object remove(Object key); + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/persistence/StreamStrategy.java b/xstream/src/java/com/thoughtworks/xstream/persistence/StreamStrategy.java new file mode 100644 index 0000000..618ee11 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/persistence/StreamStrategy.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. June 2006 by Guilherme Silveira + */ +package com.thoughtworks.xstream.persistence; + +/** + * A key to filename and vice-versa strategy interface. + * + * @author Guilherme Silveira + * @deprecated As of 1.3.1, use {@link PersistenceStrategy} instead + */ +public interface StreamStrategy extends PersistenceStrategy { +} \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/persistence/XmlArrayList.java b/xstream/src/java/com/thoughtworks/xstream/persistence/XmlArrayList.java new file mode 100644 index 0000000..2a16e37 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/persistence/XmlArrayList.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. July 2006 by Guilherme Silveira + */ +package com.thoughtworks.xstream.persistence; + +import java.util.AbstractList; + +/** + * A persistent list implementation backed on a XmlMap. + * + * @author Guilherme Silveira + */ +public class XmlArrayList extends AbstractList { + + private final XmlMap map; + + public XmlArrayList(PersistenceStrategy persistenceStrategy) { + this.map = new XmlMap(persistenceStrategy); + } + + public int size() { + return map.size(); + } + + public Object set(int index, Object element) { + rangeCheck(index); + Object value = get(index); + map.put(new Integer(index), element); + return value; + } + + public void add(int index, Object element) { + int size = size(); + if (index >= (size + 1) || index < 0) { + throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + + size); + } + int to = index != size ? index - 1 : index; + for (int i = size; i > to; i--) { + map.put(new Integer(i + 1), map.get(new Integer(i))); + } + map.put(new Integer(index), element); + } + + private void rangeCheck(int index) { + int size = size(); + if (index >= size || index < 0) { + throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + + size); + } + } + + public Object get(int index) { + rangeCheck(index); + return map.get(new Integer(index)); + } + + public Object remove(int index) { + int size = size(); + rangeCheck(index); + Object value = map.get(new Integer(index)); + for (int i = index; i < size - 1; i++) { + map.put(new Integer(i), map.get(new Integer(i + 1))); + } + map.remove(new Integer(size - 1)); + return value; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/persistence/XmlMap.java b/xstream/src/java/com/thoughtworks/xstream/persistence/XmlMap.java new file mode 100644 index 0000000..3c456fc --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/persistence/XmlMap.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. June 2006 by Guilherme Silveira + */ +package com.thoughtworks.xstream.persistence; + +import java.util.AbstractMap; +import java.util.AbstractSet; +import java.util.Iterator; +import java.util.Set; + +/** + * A persistent map. Its values are actually serialized as xml files. If you + * need an application-wide synchronized version of this map, try the respective + * Collections methods. + * + * @author Guilherme Silveira + */ +public class XmlMap extends AbstractMap { + + private final PersistenceStrategy persistenceStrategy; + + public XmlMap(PersistenceStrategy streamStrategy) { + this.persistenceStrategy = streamStrategy; + } + + public int size() { + return persistenceStrategy.size(); + } + + public Object get(Object key) { + // faster lookup + return persistenceStrategy.get(key); + } + + public Object put(Object key, Object value) { + return persistenceStrategy.put(key,value); + } + + public Object remove(Object key) { + return persistenceStrategy.remove(key); + } + + public Set entrySet() { + return new XmlMapEntries(); + } + + class XmlMapEntries extends AbstractSet { + + public int size() { + return XmlMap.this.size(); + } + + public boolean isEmpty() { + return XmlMap.this.isEmpty(); + } + + public Iterator iterator() { + return persistenceStrategy.iterator(); + } + + } + +} \ No newline at end of file diff --git a/xstream/src/java/com/thoughtworks/xstream/persistence/XmlSet.java b/xstream/src/java/com/thoughtworks/xstream/persistence/XmlSet.java new file mode 100644 index 0000000..c48ef39 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/persistence/XmlSet.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 28. June 2006 by Guilherme Silveira + */ +package com.thoughtworks.xstream.persistence; + +import java.util.AbstractSet; +import java.util.Iterator; + +/** + * A persistent set implementation. + * + * @author Guilherme Silveira + */ +public class XmlSet extends AbstractSet { + + private final XmlMap map; + + public XmlSet(PersistenceStrategy persistenceStrategy) { + this.map = new XmlMap(persistenceStrategy); + } + + public Iterator iterator() { + return map.values().iterator(); + } + + public int size() { + return map.size(); + } + + public boolean add(Object o) { + if (map.containsValue(o)) { + return false; + } else { + // not-synchronized! + map.put(findEmptyKey(), o); + return true; + } + } + + private Long findEmptyKey() { + long i = System.currentTimeMillis(); + while (map.containsKey(new Long(i))) { + i++; + } + return new Long(i); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/security/AnyTypePermission.java b/xstream/src/java/com/thoughtworks/xstream/security/AnyTypePermission.java new file mode 100644 index 0000000..d1524a9 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/security/AnyTypePermission.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 XStream Committers. + * All rights reserved. + * + * Created on 08. January 2014 by Joerg Schaible + */ +package com.thoughtworks.xstream.security; + +/** + * Permission for any type and null. + * + * @author Jörg Schaible + * @since 1.4.7 + */ +public class AnyTypePermission implements TypePermission { + /** + * @since 1.4.7 + */ + public static final TypePermission ANY = new AnyTypePermission(); + + public boolean allows(Class type) { + return true; + } + + public int hashCode() { + return 3; + } + + public boolean equals(Object obj) { + return obj != null && obj.getClass() == AnyTypePermission.class; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/security/ArrayTypePermission.java b/xstream/src/java/com/thoughtworks/xstream/security/ArrayTypePermission.java new file mode 100644 index 0000000..1e856ec --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/security/ArrayTypePermission.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 XStream Committers. + * All rights reserved. + * + * Created on 09. January 2014 by Joerg Schaible + */ +package com.thoughtworks.xstream.security; + +/** + * Permission for any array type. + * + * @author Jörg Schaible + * @since 1.4.7 + */ +public class ArrayTypePermission implements TypePermission { + /** + * @since 1.4.7 + */ + public static final TypePermission ARRAYS = new ArrayTypePermission(); + + public boolean allows(Class type) { + return type != null && type.isArray(); + } + + public int hashCode() { + return 13; + } + + public boolean equals(Object obj) { + return obj != null && obj.getClass() == ArrayTypePermission.class; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/security/CGLIBProxyTypePermission.java b/xstream/src/java/com/thoughtworks/xstream/security/CGLIBProxyTypePermission.java new file mode 100644 index 0000000..88b32ec --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/security/CGLIBProxyTypePermission.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2014 XStream Committers. + * All rights reserved. + * + * Created on 19. January 2014 by Joerg Schaible + */ +package com.thoughtworks.xstream.security; + +import net.sf.cglib.proxy.Proxy; + + +/** + * Permission for any array type. + * + * @author Jörg Schaible + * @since 1.4.7 + */ +public class CGLIBProxyTypePermission implements TypePermission { + /** + * @since 1.4.7 + */ + public static final TypePermission PROXIES = new CGLIBProxyTypePermission(); + + public boolean allows(final Class type) { + return type != null && type != Object.class && !type.isInterface() + && (Proxy.isProxyClass(type) || type.getName().startsWith(Proxy.class.getPackage().getName() + ".")); + } + + public int hashCode() { + return 19; + } + + public boolean equals(final Object obj) { + return obj != null && obj.getClass() == CGLIBProxyTypePermission.class; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/security/ExplicitTypePermission.java b/xstream/src/java/com/thoughtworks/xstream/security/ExplicitTypePermission.java new file mode 100644 index 0000000..196380b --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/security/ExplicitTypePermission.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2014 XStream Committers. + * All rights reserved. + * + * Created on 09. January 2014 by Joerg Schaible + */ +package com.thoughtworks.xstream.security; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + + +/** + * Explicit permission for a type with a name matching one in the provided list. + * + * @author Jörg Schaible + * @since 1.4.7 + */ +public class ExplicitTypePermission implements TypePermission { + + final Set names; + + /** + * @since 1.4.7 + */ + public ExplicitTypePermission(final Class[] types) { + this(new Object() { + public String[] getNames() { + if (types == null) + return null; + String[] names = new String[types.length]; + for (int i = 0; i < types.length; ++i) + names[i] = types[i].getName(); + return names; + } + }.getNames()); + } + + /** + * @since 1.4.7 + */ + public ExplicitTypePermission(String[] names) { + this.names = names == null ? Collections.EMPTY_SET : new HashSet(Arrays.asList(names)); + } + + public boolean allows(Class type) { + if (type == null) + return false; + return names.contains(type.getName()); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/security/ForbiddenClassException.java b/xstream/src/java/com/thoughtworks/xstream/security/ForbiddenClassException.java new file mode 100644 index 0000000..017fc30 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/security/ForbiddenClassException.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2014 XStream Committers. + * All rights reserved. + * + * Created on 08. January 2014 by Joerg Schaible + */ +package com.thoughtworks.xstream.security; + +import com.thoughtworks.xstream.XStreamException; + +/** + * Exception thrown for a forbidden class. + * + * @author Jörg Schaible + * @since 1.4.7 + */ +public class ForbiddenClassException extends XStreamException { + + /** + * Construct a ForbiddenClassException. + * @param type the forbidden class + * @since 1.4.7 + */ + public ForbiddenClassException(Class type) { + super(type == null ? "null" : type.getName()); + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/security/InterfaceTypePermission.java b/xstream/src/java/com/thoughtworks/xstream/security/InterfaceTypePermission.java new file mode 100644 index 0000000..c5b8002 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/security/InterfaceTypePermission.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2014 XStream Committers. + * All rights reserved. + * + * Created on 27. January 2014 by Joerg Schaible + */ +package com.thoughtworks.xstream.security; + +/** + * Permission for any interface type. + * + * @author Jörg Schaible + * @since 1.4.7 + */ +public class InterfaceTypePermission implements TypePermission { + /** + * @since 1.4.7 + */ + public static final TypePermission INTERFACES = new InterfaceTypePermission(); + + public boolean allows(Class type) { + return type != null && type.isInterface(); + } + + public int hashCode() { + return 31; + } + + public boolean equals(Object obj) { + return obj != null && obj.getClass() == InterfaceTypePermission.class; + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/security/NoPermission.java b/xstream/src/java/com/thoughtworks/xstream/security/NoPermission.java new file mode 100644 index 0000000..17115b0 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/security/NoPermission.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2014 XStream Committers. + * All rights reserved. + * + * Created on 09. January 2014 by Joerg Schaible + */ +package com.thoughtworks.xstream.security; + +/** + * Wrapper to negate another type permission. + *

+ * If the wrapped {@link TypePermission} allows the type, this instance will throw a {@link ForbiddenClassException} + * instead. An instance of this permission cannot be used to allow a type. + *

+ * + * @author Jörg Schaible + * @since 1.4.7 + */ +public class NoPermission implements TypePermission { + + private final TypePermission permission; + + /** + * Construct a NoPermission. + * + * @param permission the permission to negate or null to forbid any type + * @since 1.4.7 + */ + public NoPermission(final TypePermission permission) { + this.permission = permission; + } + + public boolean allows(final Class type) { + if (permission == null || permission.allows(type)) { + throw new ForbiddenClassException(type); + } + return false; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/security/NoTypePermission.java b/xstream/src/java/com/thoughtworks/xstream/security/NoTypePermission.java new file mode 100644 index 0000000..802537b --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/security/NoTypePermission.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2014 XStream Committers. + * All rights reserved. + * + * Created on 08. January 2014 by Joerg Schaible + */ +package com.thoughtworks.xstream.security; + +/** + * No permission for any type. + *

+ * Can be used to skip any existing default permission. + *

+ * + * @author Jörg Schaible + * @since 1.4.7 + */ +public class NoTypePermission implements TypePermission { + + /** + * @since 1.4.7 + */ + public static final TypePermission NONE = new NoTypePermission(); + + public boolean allows(Class type) { + throw new ForbiddenClassException(type); + } + + public int hashCode() { + return 1; + } + + public boolean equals(Object obj) { + return obj != null && obj.getClass() == NoTypePermission.class; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/security/NullPermission.java b/xstream/src/java/com/thoughtworks/xstream/security/NullPermission.java new file mode 100644 index 0000000..d241641 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/security/NullPermission.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2014 XStream Committers. + * All rights reserved. + * + * Created on 09. January 2014 by Joerg Schaible + */ +package com.thoughtworks.xstream.security; + +import com.thoughtworks.xstream.mapper.Mapper; + +/** + * Permission for null or XStream's null replacement type. + * + * @author Jörg Schaible + * @since 1.4.7 + */ +public class NullPermission implements TypePermission { + /** + * @since 1.4.7 + */ + public static final TypePermission NULL = new NullPermission(); + + public boolean allows(Class type) { + return type == null || type == Mapper.Null.class; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/security/PrimitiveTypePermission.java b/xstream/src/java/com/thoughtworks/xstream/security/PrimitiveTypePermission.java new file mode 100644 index 0000000..fb69b95 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/security/PrimitiveTypePermission.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2014 XStream Committers. + * All rights reserved. + * + * Created on 09. January 2014 by Joerg Schaible + */ +package com.thoughtworks.xstream.security; + +import com.thoughtworks.xstream.core.util.Primitives; + +/** + * Permission for any primitive type and its boxed counterpart (incl. void). + * + * @author Jörg Schaible + * @since 1.4.7 + */ +public class PrimitiveTypePermission implements TypePermission { + /** + * @since 1.4.7 + */ + public static final TypePermission PRIMITIVES = new PrimitiveTypePermission(); + + public boolean allows(Class type) { + return type != null && type.isPrimitive() || Primitives.isBoxed(type); + } + + public int hashCode() { + return 7; + } + + public boolean equals(Object obj) { + return obj != null && obj.getClass() == PrimitiveTypePermission.class; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/security/ProxyTypePermission.java b/xstream/src/java/com/thoughtworks/xstream/security/ProxyTypePermission.java new file mode 100644 index 0000000..1f3d3be --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/security/ProxyTypePermission.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2014 XStream Committers. + * All rights reserved. + * + * Created on 19. January 2014 by Joerg Schaible + */ +package com.thoughtworks.xstream.security; + +import java.lang.reflect.Proxy; + +import com.thoughtworks.xstream.mapper.DynamicProxyMapper; + + +/** + * Permission for any array type. + * + * @author Jörg Schaible + * @since 1.4.7 + */ +public class ProxyTypePermission implements TypePermission { + /** + * @since 1.4.7 + */ + public static final TypePermission PROXIES = new ProxyTypePermission(); + + public boolean allows(final Class type) { + return type != null && (Proxy.isProxyClass(type) || type == DynamicProxyMapper.DynamicProxy.class); + } + + public int hashCode() { + return 17; + } + + public boolean equals(final Object obj) { + return obj != null && obj.getClass() == ProxyTypePermission.class; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/security/RegExpTypePermission.java b/xstream/src/java/com/thoughtworks/xstream/security/RegExpTypePermission.java new file mode 100644 index 0000000..31ddbd6 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/security/RegExpTypePermission.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2014 XStream Committers. + * All rights reserved. + * + * Created on 09. January 2014 by Joerg Schaible + */ +package com.thoughtworks.xstream.security; + +import java.util.regex.Pattern; + + +/** + * Permission for any type with a name matching one of the provided regular expressions. + * + * @author Jörg Schaible + * @since 1.4.7 + */ +public class RegExpTypePermission implements TypePermission { + + private final Pattern[] patterns; + + public RegExpTypePermission(final String[] patterns) { + this(getPatterns(patterns)); + } + + public RegExpTypePermission(final Pattern[] patterns) { + this.patterns = patterns == null ? new Pattern[0] : patterns; + } + + public boolean allows(final Class type) { + if (type != null) { + final String name = type.getName(); + for (int i = 0; i < patterns.length; ++i) + if (patterns[i].matcher(name).matches()) + return true; + } + return false; + } + + private static Pattern[] getPatterns(final String[] patterns) { + if (patterns == null) + return null; + final Pattern[] array = new Pattern[patterns.length]; + for (int i = 0; i < array.length; ++i) + array[i] = Pattern.compile(patterns[i]); + return array; + } +} diff --git a/xstream/src/java/com/thoughtworks/xstream/security/TypeHierarchyPermission.java b/xstream/src/java/com/thoughtworks/xstream/security/TypeHierarchyPermission.java new file mode 100644 index 0000000..d476ddf --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/security/TypeHierarchyPermission.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 XStream Committers. + * All rights reserved. + * + * Created on 23. January 2014 by Joerg Schaible + */ +package com.thoughtworks.xstream.security; + +/** + * Permission for a type hierarchy with a name matching one in the provided list. + * + * @author Jörg Schaible + * @since 1.4.7 + */ +public class TypeHierarchyPermission implements TypePermission { + + private Class type; + + /** + * @since 1.4.7 + */ + public TypeHierarchyPermission(Class type) { + this.type = type; + } + + public boolean allows(Class type) { + if (type == null) + return false; + return this.type.isAssignableFrom(type); + } + +} diff --git a/xstream/src/java/com/thoughtworks/xstream/security/TypePermission.java b/xstream/src/java/com/thoughtworks/xstream/security/TypePermission.java new file mode 100644 index 0000000..03f02ec --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/security/TypePermission.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2014 XStream Committers. + * All rights reserved. + * + * Created on 08. January 2014 by Joerg Schaible + */ +package com.thoughtworks.xstream.security; + +/** + * Definition of a type permission. + * + * @author Jörg Schaible + * @since 1.4.7 + */ +public interface TypePermission { + /** + * Check permission for a provided type. + * + * @param type the type to check + * @return true if provided type is allowed, false if permission does not handle the type + * @throws ForbiddenClassException if provided type is explicitly forbidden + * @since 1.4.7 + */ + boolean allows(Class type); +} diff --git a/xstream/src/java/com/thoughtworks/xstream/security/WildcardTypePermission.java b/xstream/src/java/com/thoughtworks/xstream/security/WildcardTypePermission.java new file mode 100644 index 0000000..9da8249 --- /dev/null +++ b/xstream/src/java/com/thoughtworks/xstream/security/WildcardTypePermission.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2014 XStream Committers. + * All rights reserved. + * + * Created on 09. January 2014 by Joerg Schaible + */ +package com.thoughtworks.xstream.security; + +/** + * Permission for any type with a name matching one of the provided wildcard expressions. + * + *

+ * Supported are patterns with path expressions using dot as separator: + *

+ *
    + *
  • ?: one non-control character except separator, e.g. for 'java.net.Inet?Address'
  • + *
  • *: arbitrary number of non-control characters except separator, e.g. for types in a package like 'java.lang.*'
  • + *
  • **: arbitrary number of non-control characters including separator, e.g. for types in a package and subpackages like 'java.lang.**'
  • + *
+ *

+ * The complete range of UTF-8 characters is supported except control characters. + *

+ * + * @author Jörg Schaible + * @since 1.4.7 + */ +public class WildcardTypePermission extends RegExpTypePermission { + + /** + * @since 1.4.7 + */ + public WildcardTypePermission(final String[] patterns) { + super(getRegExpPatterns(patterns)); + } + + private static String[] getRegExpPatterns(final String[] wildcards) { + if (wildcards == null) + return null; + final String[] regexps = new String[wildcards.length]; + for (int i = 0; i < wildcards.length; ++i) { + final String wildcardExpression = wildcards[i]; + final StringBuffer result = new StringBuffer(wildcardExpression.length() * 2); + result.append("(?u)"); + final int length = wildcardExpression.length(); + for (int j = 0; j < length; j++) { + final char ch = wildcardExpression.charAt(j); + switch (ch) { + case '\\': + case '.': + case '+': + case '|': + case '[': + case ']': + case '(': + case ')': + case '^': + case '$': + result.append('\\').append(ch); + break; + + case '?': + result.append('.'); + break; + + case '*': + // see "General Category Property" in http://www.unicode.org/reports/tr18/ + if (j + 1 < length && wildcardExpression.charAt(j + 1) == '*') { + result.append("[\\P{C}]*"); + j++; + } else { + result.append("[\\P{C}&&[^").append('.').append("]]*"); + } + break; + + default: + result.append(ch); + break; + } + } + regexps[i] = result.toString(); + } + return regexps; + } +} diff --git a/xstream/src/test/$Package.java b/xstream/src/test/$Package.java new file mode 100644 index 0000000..4a4b9f0 --- /dev/null +++ b/xstream/src/test/$Package.java @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2013 XStream Committers. + * All rights reserved. + * + * Created on 22. February 2013 by Joerg Schaible + */ + +/** + * Dummy class in default package starting with dollar. + * + *

The Java compiler used to generate such class names for dynamic proxies. + * However, the Oracle/Sun compilers changed behavior with version 1.7.0.13 / + * 1.6.0.39 and its generated proxy classes are now in package com.sun.proxy. + * It is expected that other vendors will follow.

+ */ +public class $Package { + // empty +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/AbsoluteSingleNodeXPathReferenceTest.java b/xstream/src/test/com/thoughtworks/acceptance/AbsoluteSingleNodeXPathReferenceTest.java new file mode 100644 index 0000000..d8bf85f --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/AbsoluteSingleNodeXPathReferenceTest.java @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2006, 2007, 2009, 2010, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. July 2011 by Joerg Schaible by merging + * AbsolutSingleNodeXPathCircularReferenceTest, AbsolutSingleNodeXPathDuplicateReferenceTest + * and AbsolutSingleNodeXPathReplacedReferenceTest. + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.util.ArrayList; +import java.util.List; + + +public class AbsoluteSingleNodeXPathReferenceTest extends AbstractReferenceTest { + + // tests inherited from superclass + + protected void setUp() throws Exception { + super.setUp(); + xstream.setMode(XStream.SINGLE_NODE_XPATH_ABSOLUTE_REFERENCES); + } + + public void testXmlContainsReferencePaths() { + + Thing sameThing = new Thing("hello"); + Thing anotherThing = new Thing("hello"); + + List list = new ArrayList(); + list.add(sameThing); + list.add(sameThing); + list.add(anotherThing); + + String expected = "" + + "\n" + + " \n" + + " hello\n" + + " \n" + + " \n" + + " \n" + + " hello\n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(list)); + } + + public void testCircularReferenceXml() { + Person bob = new Person("bob"); + Person jane = new Person("jane"); + bob.likes = jane; + jane.likes = bob; + + String expected = "" + + "\n" + + " bob\n" + + " \n" + + " jane\n" + + " \n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(bob)); + } + + public void testCircularReferenceToSelfXml() { + Person bob = new Person("bob"); + bob.likes = bob; + + String expected = "" + + "\n" + + " bob\n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(bob)); + } + + public void testRing() { + LinkedElement tom = new LinkedElement("Tom"); + LinkedElement dick = new LinkedElement("Dick"); + LinkedElement harry = new LinkedElement("Harry"); + tom.next = dick; + dick.next = harry; + harry.next = tom; + + xstream.alias("elem", LinkedElement.class); + String expected = "" + + "\n" + + " Tom\n" + + " \n" + + " Dick\n" + + " \n" + + " Harry\n" + + " \n" + + " \n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(tom)); + } + + public void testTree() { + TreeElement root = new TreeElement("X"); + TreeElement left = new TreeElement("Y"); + TreeElement right = new TreeElement("Z"); + root.left = left; + root.right = right; + left.left = new TreeElement(root.name); + right.right = new TreeElement(left.name); + right.left = left.left; + + xstream.alias("elem", TreeElement.class); + String expected = "" + + "\n" + + " X\n" + + " \n" + + " Y\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " Z\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(root)); + } + + public void testReplacedReference() { + String expectedXml = "" + + "\n" + + " parent\n" + + " \n" + + " \n" + + " child\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + replacedReference(expectedXml); + } + + public void testCanReferenceDeserializedNullValues() { + xstream.alias("test", Mapper.Null.class); + String xml = "" + + "\n" + + " \n" + + " \n" + + ""; + List list = (List)xstream.fromXML(xml); + assertEquals(2, list.size()); + assertNull(list.get(0)); + assertNull(list.get(1)); + } + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/AbsoluteXPathReferenceTest.java b/xstream/src/test/com/thoughtworks/acceptance/AbsoluteXPathReferenceTest.java new file mode 100644 index 0000000..25d7b03 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/AbsoluteXPathReferenceTest.java @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2006, 2007, 2009, 2010, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. July 2011 by Joerg Schaible by merging AbsolutXPathCircularReferenceTest, + * AbsolutXPathDuplicateReferenceTest, AbsolutXPathNestedCircularReferenceTest and + * AbsolutXPathReplacedReferenceTest. + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.util.ArrayList; +import java.util.List; + + +public class AbsoluteXPathReferenceTest extends AbstractReferenceTest { + + // tests inherited from superclass + + protected void setUp() throws Exception { + super.setUp(); + xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES); + } + + public void testXmlContainsReferencePaths() { + + Thing sameThing = new Thing("hello"); + Thing anotherThing = new Thing("hello"); + + List list = new ArrayList(); + list.add(sameThing); + list.add(sameThing); + list.add(anotherThing); + + String expected = "" + + "\n" + + " \n" + + " hello\n" + + " \n" + + " \n" + + " \n" + + " hello\n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(list)); + } + + public void testCircularReferenceXml() { + Person bob = new Person("bob"); + Person jane = new Person("jane"); + bob.likes = jane; + jane.likes = bob; + + String expected = "" + + "\n" + + " bob\n" + + " \n" + + " jane\n" + + " \n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(bob)); + } + + public void testCircularReferenceToSelfXml() { + Person bob = new Person("bob"); + bob.likes = bob; + + String expected = "" + + "\n" + + " bob\n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(bob)); + } + + public void testRing() { + LinkedElement tom = new LinkedElement("Tom"); + LinkedElement dick = new LinkedElement("Dick"); + LinkedElement harry = new LinkedElement("Harry"); + tom.next = dick; + dick.next = harry; + harry.next = tom; + + xstream.alias("elem", LinkedElement.class); + String expected = "" + + "\n" + + " Tom\n" + + " \n" + + " Dick\n" + + " \n" + + " Harry\n" + + " \n" + + " \n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(tom)); + } + + public void testTree() { + TreeElement root = new TreeElement("X"); + TreeElement left = new TreeElement("Y"); + TreeElement right = new TreeElement("Z"); + root.left = left; + root.right = right; + left.left = new TreeElement(root.name); + right.right = new TreeElement(left.name); + right.left = left.left; + + xstream.alias("elem", TreeElement.class); + String expected = "" + + "\n" + + " X\n" + + " \n" + + " Y\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " Z\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(root)); + } + + public void testReplacedReference() { + String expectedXml = "" + + "\n" + + " parent\n" + + " \n" + + " \n" + + " child\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + replacedReference(expectedXml); + } + + public void testCanReferenceDeserializedNullValues() { + xstream.alias("test", Mapper.Null.class); + String xml = "" + + "\n" + + " \n" + + " \n" + + ""; + List list = (List)xstream.fromXML(xml); + assertEquals(2, list.size()); + assertNull(list.get(0)); + assertNull(list.get(1)); + } + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/AbstractAcceptanceTest.java b/xstream/src/test/com/thoughtworks/acceptance/AbstractAcceptanceTest.java new file mode 100644 index 0000000..7fcf9f6 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/AbstractAcceptanceTest.java @@ -0,0 +1,257 @@ +/* + * Copyright (C) 2003, 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Array; +import java.net.URL; +import java.nio.charset.Charset; +import java.text.DecimalFormatSymbols; +import java.util.BitSet; +import java.util.Calendar; +import java.util.Collection; +import java.util.Currency; +import java.util.Date; +import java.util.Locale; +import java.util.Map; +import java.util.TimeZone; +import java.util.regex.Pattern; +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.StringReader; +import java.io.StringWriter; + +import junit.framework.AssertionFailedError; +import junit.framework.TestCase; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.HierarchicalStreamDriver; +import com.thoughtworks.xstream.io.binary.BinaryStreamWriter; +import com.thoughtworks.xstream.io.binary.BinaryStreamReader; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.security.ArrayTypePermission; +import com.thoughtworks.xstream.security.InterfaceTypePermission; +import com.thoughtworks.xstream.security.NoTypePermission; +import com.thoughtworks.xstream.security.NullPermission; +import com.thoughtworks.xstream.security.PrimitiveTypePermission; + +public abstract class AbstractAcceptanceTest extends TestCase { + + protected transient XStream xstream = createXStream(); + + protected XStream createXStream() { + XStream xstream = new XStream(createDriver()); + setupSecurity(xstream); + return xstream; + } + + protected HierarchicalStreamDriver createDriver() { + // if the system property is set, use it to load the driver + String driver = null; + try { + driver = System.getProperty("xstream.driver"); + if (driver != null) { + System.out.println("Using driver: " + driver); + Class type = Class.forName(driver); + return (HierarchicalStreamDriver) type.newInstance(); + } + } + catch (Exception e) { + throw new RuntimeException("Could not load driver: " + driver); + } + return new XppDriver(); + } + + protected void setupSecurity(XStream xstream) { + xstream.addPermission(NoTypePermission.NONE); // clear out defaults + xstream.addPermission(NullPermission.NULL); + xstream.addPermission(ArrayTypePermission.ARRAYS); + xstream.addPermission(InterfaceTypePermission.INTERFACES); + xstream.addPermission(PrimitiveTypePermission.PRIMITIVES); + xstream.allowTypeHierarchy(AccessibleObject.class); + xstream.allowTypeHierarchy(Calendar.class); + xstream.allowTypeHierarchy(Collection.class); + xstream.allowTypeHierarchy(Map.class); + xstream.allowTypeHierarchy(Map.Entry.class); + xstream.allowTypeHierarchy(Number.class); + xstream.allowTypeHierarchy(TimeZone.class); + xstream.allowTypeHierarchy(Throwable.class); + xstream.allowTypes(new Class[]{ + BitSet.class, Charset.class, Class.class, Currency.class, Date.class, DecimalFormatSymbols.class, + File.class, Locale.class, Object.class, Pattern.class, StackTraceElement.class, String.class, + StringBuffer.class, URL.class}); + xstream.allowTypesByWildcard(new String[]{ + AbstractAcceptanceTest.class.getPackage().getName()+".*objects.**", + this.getClass().getName()+"$*" + }); + } + + protected Object assertBothWaysNormalized(Object root, String xml, final String match, + final String templateSelect, final String sortSelect) { + try { + // First, serialize the object to XML and check it matches the expected XML. + String resultXml = normalizedXML( + toXML(root), new String[]{match}, templateSelect, sortSelect); + assertEquals( + normalizedXML(xml, new String[]{match}, templateSelect, sortSelect), resultXml); + + // Now deserialize the XML back into the object and check it equals the original + // object. + Object resultRoot = xstream.fromXML(resultXml); + assertObjectsEqual(root, resultRoot); + + // While we're at it, let's check the binary serialization works... + assertBinarySerialization(root); + + return resultRoot; + + } catch (TransformerException e) { + throw new AssertionFailedError("Cannot normalize XML: " + e.getMessage()); + // .initCause(e); ... still JDK 1.3 + } + } + + protected Object assertBothWays(Object root, String xml) { + + // First, serialize the object to XML and check it matches the expected XML. + String resultXml = toXML(root); + assertEquals(xml, resultXml); + + // Now deserialize the XML back into the object and check it equals the original object. + Object resultRoot = xstream.fromXML(resultXml); + assertObjectsEqual(root, resultRoot); + + // While we're at it, let's check the binary serialization works... + assertBinarySerialization(root); + + return resultRoot; + } + + private void assertBinarySerialization(Object root) { + // Serialize as binary + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + xstream.marshal(root, new BinaryStreamWriter(outputStream)); + + // Deserialize the binary and check it equals the original object. + ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); + Object binaryResult = xstream.unmarshal(new BinaryStreamReader(inputStream)); + assertObjectsEqual(root, binaryResult); + } + + protected Object assertWithAsymmetricalXml(Object root, String inXml, String outXml) { + String resultXml = toXML(root); + assertEquals(outXml, resultXml); + Object resultRoot = xstream.fromXML(inXml); + assertObjectsEqual(root, resultRoot); + return resultRoot; + } + + /** + * Allow derived classes to decide how to turn the object into XML text + */ + protected String toXML(Object root) { + return xstream.toXML(root); + } + + /** + * More descriptive version of assertEquals + */ + protected void assertObjectsEqual(Object expected, Object actual) { + if (expected == null) { + assertNull(actual); + } else { + assertNotNull("Should not be null", actual); + if (actual.getClass().isArray()) { + assertArrayEquals(expected, actual); + } else { +// assertEquals(expected.getClass(), actual.getClass()); + if (!expected.equals(actual)) { + assertEquals("Object deserialization failed", + "DESERIALIZED OBJECT\n" + xstream.toXML(expected), + "DESERIALIZED OBJECT\n" + xstream.toXML(actual)); + } + } + } + } + + protected void assertArrayEquals(Object expected, Object actual) { + assertEquals(Array.getLength(expected), Array.getLength(actual)); + for (int i = 0; i < Array.getLength(expected); i++) { + assertObjectsEqual(Array.get(expected, i), Array.get(actual, i)); + } + } + + protected void assertByteArrayEquals(byte expected[], byte actual[]) { + assertEquals(dumpBytes(expected), dumpBytes(actual)); + } + + private String dumpBytes(byte bytes[]) { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < bytes.length; i++) { + result.append(bytes[i]).append(' '); + if (bytes[i] < 100) result.append(' '); + if (bytes[i] < 10) result.append(' '); + if (bytes[i] >= 0) result.append(' '); + if (i % 16 == 15) result.append('\n'); + } + return result.toString(); + } + + protected String normalizedXML(final String xml, final String[] matches, + final String templateSelect, final String sortSelect) throws TransformerException { + final StringBuffer match = new StringBuffer(); + for (int i = 0; i < matches.length; i++) { + if (i > 0) { + match.append('|'); + } + match.append(matches[i]); + } + final StringBuffer sort = new StringBuffer(); + if (sortSelect != null) { + sort.append(" select=\""); + sort.append(sortSelect); + sort.append('"'); + } + + final TransformerFactory transformerFactory = TransformerFactory.newInstance(); + final Transformer transformer = transformerFactory + .newTransformer(new StreamSource( + new StringReader( + "" + + "\n" + + "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + "\n" + + ""))); + final StringWriter writer = new StringWriter(); + transformer + .transform(new StreamSource(new StringReader(xml)), new StreamResult(writer)); + return writer.toString(); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/AbstractReferenceTest.java b/xstream/src/test/com/thoughtworks/acceptance/AbstractReferenceTest.java new file mode 100644 index 0000000..514187c --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/AbstractReferenceTest.java @@ -0,0 +1,475 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2010, 2011, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. July 2011 by Joerg Schaible by merging AbstractCircularReferenceTest, + * AbstractDuplicateReferenceTest, AbstractNestedCircularReferenceTest and + * AbstractReplacedReferenceTest. + */ +package com.thoughtworks.acceptance; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.acceptance.someobjects.WithNamedList; +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.core.AbstractReferenceMarshaller; + + +public abstract class AbstractReferenceTest extends AbstractAcceptanceTest { + protected void setUp() throws Exception { + super.setUp(); + xstream.alias("person", Person.class); + xstream.alias("thing", Thing.class); + xstream.allowTypesByWildcard(new String[]{AbstractReferenceTest.class.getName()+"$*"}); + } + + public void testReferencesAreWorking() { + + Thing sameThing = new Thing("hello"); + Thing anotherThing = new Thing("hello"); + + List list = new ArrayList(); + list.add(sameThing); + list.add(sameThing); + list.add(anotherThing); + + String xml = xstream.toXML(list); + List result = (List)xstream.fromXML(xml); + + assertEquals(list, result); + } + + public void testReferencesAreTheSameObjectWhenDeserialized() { + + Thing sameThing = new Thing("hello"); + Thing anotherThing = new Thing("hello"); + + List list = new ArrayList(); + list.add(sameThing); + list.add(sameThing); + list.add(anotherThing); + + String xml = xstream.toXML(list); + List result = (List)xstream.fromXML(xml); + + Thing t0 = (Thing)result.get(0); + Thing t1 = (Thing)result.get(1); + Thing t2 = (Thing)result.get(2); + + t0.field = "bye"; + + assertEquals("bye", t0.field); + assertEquals("bye", t1.field); + assertEquals("hello", t2.field); + + } + + public static class Thing extends StandardObject { + public String field; + + public Thing() { + } + + public Thing(String field) { + this.field = field; + } + } + + public static class MultRef { + public Object s1 = new Object(); + public Object s2 = s1; + } + + public void testMultipleReferencesToObjectsWithNoChildren() { + MultRef in = new MultRef(); + assertSame(in.s1, in.s2); + + String xml = xstream.toXML(in); + MultRef out = (MultRef)xstream.fromXML(xml); + + assertSame(out.s1, out.s2); + } + + public void testReferencesNotUsedForImmutableValueTypes() { + MultRef in = new MultRef(); + in.s1 = new Integer(4); + in.s2 = in.s1; + + String xml = xstream.toXML(in); + MultRef out = (MultRef)xstream.fromXML(xml); + + assertEquals(out.s1, out.s2); + assertNotSame(out.s1, out.s2); + } + + public void testReferencesUsedForMutableValueTypes() { + MultRef in = new MultRef(); + in.s1 = new StringBuffer("hi"); + in.s2 = in.s1; + + String xml = xstream.toXML(in); + MultRef out = (MultRef)xstream.fromXML(xml); + + StringBuffer buffer = (StringBuffer)out.s2; + buffer.append("bye"); + + assertEquals("hibye", out.s1.toString()); + assertSame(out.s1, out.s2); + } + + public void testReferencesToImplicitCollectionIsNotPossible() { + xstream.alias("strings", WithNamedList.class); + xstream.addImplicitCollection(WithNamedList.class, "things"); + WithNamedList[] wls = new WithNamedList[]{ + new WithNamedList("foo"), new WithNamedList("bar")}; + wls[0].things.add("Hello"); + wls[0].things.add("Daniel"); + wls[1].things = wls[0].things; + + try { + xstream.toXML(wls); + fail("Thrown " + + AbstractReferenceMarshaller.ReferencedImplicitElementException.class + .getName() + " expected"); + } catch (final AbstractReferenceMarshaller.ReferencedImplicitElementException e) { + // OK + } + } + + public void testReferencesToElementsOfImplicitCollectionIsPossible() { + xstream.alias("strings", WithNamedList.class); + xstream.addImplicitCollection(WithNamedList.class, "things"); + WithNamedList[] wls = new WithNamedList[]{ + new WithNamedList("foo"), new WithNamedList("bar")}; + wls[0].things.add("Hello"); + wls[0].things.add("Daniel"); + wls[1].things.add(wls[0]); + + String xml = xstream.toXML(wls); + WithNamedList[] out = (WithNamedList[])xstream.fromXML(xml); + + assertSame(out[0], out[1].things.get(0)); + } + + public void testReferencesToElementsOfNthImplicitCollectionIsPossible() { + xstream.alias("strings", WithNamedList.class); + xstream.addImplicitCollection(WithNamedList.class, "things"); + WithNamedList[] wls = new WithNamedList[]{ + new WithNamedList("foo"), new WithNamedList("bar"), new WithNamedList("foobar")}; + wls[1].things.add("Hello"); + wls[1].things.add("Daniel"); + wls[2].things.add(wls[1]); + + String xml = xstream.toXML(wls); + WithNamedList[] out = (WithNamedList[])xstream.fromXML(xml); + + assertSame(out[1], out[2].things.get(0)); + } + + public void testThrowsForInvalidReference() { + String xml = "" // + + "\n" + + " \n" + + " Hello\n" + + " \n" + + " \n" + + ""; + + try { + xstream.fromXML(xml); + fail("Thrown " + ConversionException.class.getName() + " expected"); + } catch (final ConversionException e) { + assertEquals("foo", e.get("reference")); + } + } + + public static class Person { + public String firstname; + public Person likes; + public Person loathes; + + public Person() { + } + + public Person(String name) { + this.firstname = name; + } + } + + static class LinkedElement { + String name; + LinkedElement next; + + LinkedElement(String name) { + this.name = name; + } + } + + static class TreeElement { + StringBuffer name; + TreeElement left; + TreeElement right; + + TreeElement(StringBuffer name) { + this.name = name; + } + + TreeElement(String name) { + this.name = new StringBuffer(name); + } + } + + public void testCircularReference() { + Person bob = new Person("bob"); + Person jane = new Person("jane"); + bob.likes = jane; + jane.likes = bob; + + String xml = xstream.toXML(bob); + + Person bobOut = (Person)xstream.fromXML(xml); + assertEquals("bob", bobOut.firstname); + Person janeOut = bobOut.likes; + + assertEquals("jane", janeOut.firstname); + + assertSame(bobOut.likes, janeOut); + assertSame(bobOut, janeOut.likes); + } + + public void testCircularReferenceToSelf() { + Person bob = new Person("bob"); + bob.likes = bob; + + String xml = xstream.toXML(bob); + + Person bobOut = (Person)xstream.fromXML(xml); + assertEquals("bob", bobOut.firstname); + assertSame(bobOut, bobOut.likes); + } + + public void testDeepCircularReferences() { + Person bob = new Person("bob"); + Person jane = new Person("jane"); + Person ann = new Person("ann"); + Person poo = new Person("poo"); + + bob.likes = jane; + bob.loathes = ann; + ann.likes = jane; + ann.loathes = poo; + poo.likes = jane; + poo.loathes = ann; + jane.likes = jane; + jane.loathes = bob; + + String xml = xstream.toXML(bob); + Person bobOut = (Person)xstream.fromXML(xml); + Person janeOut = bobOut.likes; + Person annOut = bobOut.loathes; + Person pooOut = annOut.loathes; + + assertEquals("bob", bobOut.firstname); + assertEquals("jane", janeOut.firstname); + assertEquals("ann", annOut.firstname); + assertEquals("poo", pooOut.firstname); + + assertSame(janeOut, bobOut.likes); + assertSame(annOut, bobOut.loathes); + assertSame(janeOut, annOut.likes); + assertSame(pooOut, annOut.loathes); + assertSame(janeOut, pooOut.likes); + assertSame(annOut, pooOut.loathes); + assertSame(janeOut, janeOut.likes); + assertSame(bobOut, janeOut.loathes); + } + + public static class WeirdThing implements Serializable { + public transient Object anotherObject; + private NestedThing nestedThing = new NestedThing(); + + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException { + in.defaultReadObject(); + anotherObject = in.readObject(); + } + + private void writeObject(ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + out.writeObject(anotherObject); + } + + private class NestedThing implements Serializable { + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException { + in.defaultReadObject(); + } + + private void writeObject(ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + } + + } + } + + public void testWeirdCircularReference() { + // I cannot fully explain what's special about WeirdThing, however without ensuring that + // a reference is only + // put in the references map once, this fails. + + // This case was first noticed when serializing JComboBox, deserializing it and then + // serializing it again. + // Upon the second serialization, it would cause the Sun 1.4.1 JVM to crash: + // Object in = new javax.swing.JComboBox(); + // Object out = xstream.fromXML(xstream.toXML(in)); + // xstream.toXML(out); ....causes JVM crash on 1.4.1 + + // WeirdThing is the least possible code I can create to reproduce the problem. + + // This also fails for JRockit 1.4.2 deeply nested, when it tries to set the final field + // AbstractNestedCircularReferenceTest$WeirdThing$NestedThing$this$1. + + // setup + WeirdThing in = new WeirdThing(); + in.anotherObject = in; + + String xml = xstream.toXML(in); + // System.out.println(xml + "\n"); + + // execute + WeirdThing out = (WeirdThing)xstream.fromXML(xml); + + // verify + assertSame(out, out.anotherObject); + } + + public static class TreeData implements Serializable { + String data; + TreeData parent; + List children; + + public TreeData(String data) { + this.data = data; + children = new ArrayList(); + } + + private TreeData(TreeData clone) { + data = clone.data; + parent = clone.parent; + children = clone.children; + } + + public void add(TreeData child) { + child.parent = this; + children.add(child); + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.children == null) ? 0 : this.children.hashCode()); + result = prime * result + ((this.data == null) ? 0 : this.data.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (!(obj instanceof TreeData)) return false; + TreeData other = (TreeData)obj; + if (this.children == null) { + if (other.children != null) return false; + } else if (!this.children.equals(other.children)) return false; + if (this.data == null) { + if (other.data != null) return false; + } else if (!this.data.equals(other.data)) return false; + return true; + } + + protected Object writeReplace() { + if (getClass() == TreeData.class) { + return this; + } + return new TreeData(this); + } + } + + public abstract void testReplacedReference(); + + public void replacedReference(String expectedXml) { + TreeData parent = new TreeData("parent"); + parent.add(new TreeData("child") { + // anonymous type + }); + + xstream.alias("element", TreeData.class); + xstream.alias("anonymous-element", parent.children.get(0).getClass()); + + assertEquals(expectedXml, xstream.toXML(parent)); + TreeData clone = (TreeData)xstream.fromXML(expectedXml); + assertEquals(parent, clone); + } + + static class Email extends StandardObject { + String email; + private final Email alias; + + Email(String email) { + this(email, null); + } + Email(String email, Email alias) { + this.email = email; + this.alias = alias; + } + } + + static class EmailList extends StandardObject { + List addresses = new ArrayList(); + Email main; + } + + public void testReferenceElementInImplicitCollection() { + EmailList emails = new EmailList(); + emails.addresses.add(new Email("private@joewalnes.com")); + emails.addresses.add(new Email("joe@joewalnes.com")); + emails.addresses.add(new Email("joe.walnes@thoughtworks.com")); + emails.addresses.add(new Email("joe@thoughtworks.com", (Email)emails.addresses.get(2))); + emails.main = (Email)emails.addresses.get(1); + + xstream.addImplicitCollection(EmailList.class, "addresses", "address", Email.class); + String xml = xstream.toXML(emails); + assertEquals(emails, xstream.fromXML(xml)); + } + + static class EmailArray extends StandardObject { + Email[] addresses; + Email main; + } + + public void testReferenceElementInImplicitArrays() { + EmailArray emails = new EmailArray(); + Email alias = new Email("joe.walnes@thoughtworks.com"); + emails.addresses = new Email[]{ + new Email("private@joewalnes.com"), + new Email("joe@joewalnes.com"), + alias, + new Email("joe@thoughtworks.com", alias) + }; + emails.main = emails.addresses[1]; + + xstream.addImplicitArray(EmailArray.class, "addresses", "address"); + String xml = xstream.toXML(emails); + assertEquals(emails, xstream.fromXML(xml)); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/AliasTest.java b/xstream/src/test/com/thoughtworks/acceptance/AliasTest.java new file mode 100644 index 0000000..b7f29cc --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/AliasTest.java @@ -0,0 +1,440 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. March 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.Category; +import com.thoughtworks.acceptance.objects.Product; +import com.thoughtworks.acceptance.objects.Software; +import com.thoughtworks.acceptance.someobjects.WithList; +import com.thoughtworks.acceptance.someobjects.X; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.extended.JavaClassConverter; +import com.thoughtworks.xstream.converters.extended.JavaFieldConverter; +import com.thoughtworks.xstream.converters.extended.JavaMethodConverter; +import com.thoughtworks.xstream.core.util.Primitives; +import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.mapper.ArrayMapper; +import com.thoughtworks.xstream.mapper.CannotResolveClassException; +import com.thoughtworks.xstream.mapper.Mapper; +import com.thoughtworks.xstream.mapper.MapperWrapper; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +/** + * @author Paul Hammant + * @author Jörg Schaible + */ +public class AliasTest extends AbstractAcceptanceTest { + + public void testBarfsIfItDoesNotExist() { + + String xml = "" + + "\n" + + " \n" + + " 0\n" + + " \n" + + ""; + + // now change the alias + xstream.alias("Xxxxxxxx", X.class); + try { + xstream.fromXML(xml); + fail("ShouldCannotResolveClassException expected"); + } catch (CannotResolveClassException expectedException) { + // expected + } + } + + public void testWithUnderscore() { + xstream = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_"))); + setupSecurity(xstream); + String xml = "" + + "\n" + + " 0\n" + + ""; + + // now change the alias + xstream.alias("X_alias", X.class); + X x = new X(0); + assertBothWays(x, xml); + } + + public static class HasUnderscore { + private String _attr = "foo"; + } + + public void testWithPrefixedUnderscore(){ + HasUnderscore x = new HasUnderscore(); + + xstream.alias("underscore", HasUnderscore.class); + xstream.aliasField("attr", HasUnderscore.class, "_attr"); + + String xml = "" + + "\n" + + " foo\n" + + ""; + + assertBothWays(x, xml); + } + + public void testForFieldAsAttribute() { + Software software = new Software("walness", "xstream"); + + xstream.alias("software", Software.class); + xstream.useAttributeFor(String.class); + xstream.aliasAttribute("id", "name"); + + String xml = ""; + + assertBothWays(software, xml); + } + + public void testForReferenceSystemAttribute() { + List list = new ArrayList(); + Software software = new Software("walness", "xstream"); + list.add(software); + list.add(software); + + xstream.alias("software", Software.class); + xstream.useAttributeFor(String.class); + xstream.aliasAttribute("refid", "reference"); + + String xml = "" + + "\n" + + " \n" + + " \n" + + ""; + + assertBothWays(list, xml); + } + + public void testForSystemAttributes() { + List list = new LinkedList(); + Category category = new Category("walness", "xstream"); + category.setProducts(list); + list.add(category); + + xstream.alias("category", Category.class); + xstream.useAttributeFor(Category.class, "id"); + xstream.aliasAttribute("class", "id"); + xstream.aliasSystemAttribute("type", "class"); + xstream.aliasSystemAttribute("refid", "reference"); + + String xml = "" + + "\n" + + " walness\n" + + " \n" + + " \n" + + " \n" + + ""; + + assertBothWays(category, xml); + } + + public void testIdentityForFields() { + Software software = new Software("walness", "xstream"); + + xstream.alias("software", Software.class); + xstream.aliasField("name", Software.class, "name"); + xstream.aliasField("vendor", Software.class, "vendor"); + + String xml = "" + + "\n" + + " walness\n" + + " xstream\n" + + ""; + + assertBothWays(software, xml); + } + + private static class FieldsWithInternalNames { + String clazz; + String ref; + } + + public void testCanUseInternalNameAsFieldAlias() { + FieldsWithInternalNames object = new FieldsWithInternalNames(); + object.clazz = "TestIt"; + object.ref = "MyReference"; + + xstream.alias("internalNames", FieldsWithInternalNames.class); + xstream.aliasField("class", FieldsWithInternalNames.class, "clazz"); + xstream.aliasField("reference", FieldsWithInternalNames.class, "ref"); + + String xml = "" + + "\n" + + " TestIt\n" + + " MyReference\n" + + ""; + + assertBothWays(object, xml); + } + + public void testCanAliasPrimitiveTypes() { + Object object = new boolean[]{true, false}; + xstream.alias("bo", Boolean.TYPE); + String xml = "" + + "\n" + + " true\n" + + " false\n" + + ""; + assertBothWays(object, xml); + } + + public void testCanAliasArray() { + Object object = new boolean[]{true, false}; + xstream.alias("boa", boolean[].class); + String xml = "" + + "\n" + + " true\n" + + " false\n" + + ""; + assertBothWays(object, xml); + } + + public void testCanAliasArrayInMultiDimension() { + Object object = new boolean[][]{{true, false}}; + xstream.alias("boa", boolean[].class); + String xml = "" + + "\n" + + " \n" + + " true\n" + + " false\n" + + " \n" + + ""; + assertBothWays(object, xml); + } + + public static class TypeA { + private String attrA = "testA"; + } + + public static class TypeB extends TypeA { + private String attrB = "testB"; + } + + public static class TypeC extends TypeB { + private String attrC = "testC"; + } + + public void testCanAliasInheritedFields() { + xstream.alias("test", TypeC.class); + xstream.aliasField("a", TypeA.class, "attrA"); + xstream.aliasField("b", TypeB.class, "attrB"); + xstream.aliasField("c", TypeC.class, "attrC"); + TypeC object = new TypeC(); + String xml = "" + + "\n" + + " testA\n" + + " testB\n" + + " testC\n" + + ""; + assertBothWays(object, xml); + } + + public void testCanDeserializeAliasedInheritedFieldsToSameName() { + xstream.alias("test", TypeC.class); + xstream.alias("A", TypeA.class); + xstream.alias("B", TypeB.class); + xstream.aliasField("attr", TypeA.class, "attrA"); + xstream.aliasField("attr", TypeB.class, "attrB"); + xstream.aliasField("attr", TypeC.class, "attrC"); + TypeC object = new TypeC(); + String xml = "" + + "\n" + + " testA\n" + + " testB\n" + + " testC\n" + + ""; + assertObjectsEqual(object, xstream.fromXML(xml)); + //assertBothWays(object, xml); + } + + public void testCanOverwriteInheritedAlias() { + xstream.alias("test", TypeC.class); + xstream.aliasField("a", TypeA.class, "attrA"); + xstream.aliasField("b", TypeB.class, "attrB"); + xstream.aliasField("c", TypeC.class, "attrC"); + xstream.aliasField("y", TypeC.class, "attrA"); + TypeC object = new TypeC(); + String xml = "" + + "\n" + + " testA\n" + + " testB\n" + + " testC\n" + + ""; + assertBothWays(object, xml); + } + + public void testCanAliasArrayElements() { + Object[] software = new Object[]{new Software("walness", "xstream")}; + + xstream.alias("software", Software.class); + xstream.aliasField("Name", Software.class, "name"); + xstream.aliasField("Vendor", Software.class, "vendor"); + + String xml = "" // + + "\n" + + " \n" + + " walness\n" + + " xstream\n" + + " \n" + + ""; + + assertBothWays(software, xml); + } + + public void testCanAliasCompletePackage() { + Software software = new Software("walness", "xstream"); + xstream.aliasPackage("org.codehaus", "com.thoughtworks.acceptance.objects"); + + String xml = "" // + + "\n" + + " walness\n" + + " xstream\n" + + ""; + + assertBothWays(software, xml); + } + + public void testCanAliasSubPackage() { + Software software = new Software("walness", "xstream"); + xstream.aliasPackage("org.codehaus", "com.thoughtworks"); + + String xml = "" // + + "\n" + + " walness\n" + + " xstream\n" + + ""; + + assertBothWays(software, xml); + } + + public void testToDefaultPackage() { + Software software = new Software("walness", "xstream"); + xstream.aliasPackage("", "com.thoughtworks.acceptance.objects"); + + String xml = "" // + + "\n" + + " walness\n" + + " xstream\n" + + ""; + + assertBothWays(software, xml); + } + + public void testForLongerPackageNameTakesPrecedence() { + WithList withList = new WithList(); + withList.things.add(new Software("walness", "xstream")); + withList.things.add(new TypeA()); + xstream.aliasPackage("model", "com.thoughtworks.acceptance.objects"); + xstream.aliasPackage("org.codehaus", "com.thoughtworks"); + xstream.aliasPackage("model.foo", "com.thoughtworks.acceptance.someobjects"); + + String xml = "" // + + "\n" + + " \n" + + " \n" + + " walness\n" + + " xstream\n" + + " \n" + + " \n" + + " testA\n" + + " \n" + + " \n" + + ""; + + assertBothWays(withList, xml); + } + + public void testClassTakesPrecedenceOfPackage() { + WithList withList = new WithList(); + withList.things.add(new Software("walness", "xstream")); + xstream.alias("MySoftware", Software.class); + xstream.aliasPackage("org.codehaus", "com.thoughtworks"); + xstream.aliasPackage("model.foo", "com.thoughtworks.acceptance.someobjects"); + + String xml = "" // + + "\n" + + " \n" + + " \n" + + " walness\n" + + " xstream\n" + + " \n" + + " \n" + + ""; + + assertBothWays(withList, xml); + } + + private void takingDoubles(Double d1, double d2) {} + + public void testCanCreateAliasingJavaTypeConverter() throws NoSuchFieldException, NoSuchMethodException { + Mapper mapper = new MapperWrapper(xstream.getMapper().lookupMapperOfType(ArrayMapper.class)) { + public Class realClass(String elementName) { + Class primitiveType = Primitives.primitiveType(elementName); + return primitiveType != null ? primitiveType : super.realClass(elementName); + } + }; + SingleValueConverter javaClassConverter = new JavaClassConverter(mapper) {}; + xstream.registerConverter(javaClassConverter); + xstream.registerConverter(new JavaMethodConverter(javaClassConverter){}); + xstream.registerConverter(new JavaFieldConverter(javaClassConverter, mapper){}); + xstream.alias("A", TypeA.class); + xstream.alias("Prod", Product.class); + xstream.aliasField("a", TypeA.class, "attrA"); + xstream.alias("Test", getClass()); + + List list = new ArrayList(); + list.add(TypeA.class); + list.add(int[][][].class); + list.add(Integer[][][].class); + list.add(TypeA.class.getDeclaredField("attrA")); + list.add(Product.class.getConstructor(new Class[]{String.class, String.class, double.class})); + list.add(getClass().getDeclaredMethod("takingDoubles", new Class[]{Double.class, double.class})); + list.add(ArrayList.class); + + String xml = "" // + + "\n" + + " A\n" + + " int-array-array-array\n" + + " java.lang.Integer-array-array-array\n" + + " \n" + + " a\n" + + " A\n" + + " \n" + + " \n" + + " Prod\n" + + " \n" + + " string\n" + + " string\n" + + " double\n" + + " \n" + + " \n" + + " \n" + + " Test\n" + + " takingDoubles\n" + + " \n" + + " java.lang.Double\n" + + " double\n" + + " \n" + + " \n" + + " java.util.ArrayList\n" + + ""; + + assertBothWays(list, xml); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/ArraysTest.java b/xstream/src/test/com/thoughtworks/acceptance/ArraysTest.java new file mode 100644 index 0000000..1ceecb8 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/ArraysTest.java @@ -0,0 +1,267 @@ +/* + * Copyright (C) 2003, 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. October 2003 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.StandardObject; + +public class ArraysTest extends AbstractAcceptanceTest { + + public void testStringArray() { + String[] array = new String[]{"a", "b", "c"}; + + String expected = "" + + "\n" + + " a\n" + + " b\n" + + " c\n" + + ""; + + assertBothWays(array, expected); + } + + public void testPrimitiveArray() { + int[] array = new int[]{1, 2}; + + String expected = "" + + "\n" + + " 1\n" + + " 2\n" + + ""; + + assertBothWays(array, expected); + } + + public void testBoxedTypeArray() { + Integer[] array = new Integer[]{new Integer(1), new Integer(2)}; + + String expected = "" + + "\n" + + " 1\n" + + " 2\n" + + ""; + + assertBothWays(array, expected); + } + + public static class X extends StandardObject { + String s = "hi"; + } + + public void testCustomObjectArray() { + + X[] array = new X[]{new X(), new X()}; + + String expected = "" + + "\n" + + " \n" + + " hi\n" + + " \n" + + " \n" + + " hi\n" + + " \n" + + ""; + + assertBothWays(array, expected); + } + + public void testArrayOfMixedTypes() { + + Object[] array = new Number[]{new Long(2), new Integer(3)}; + + String expected = "" + + "\n" + + " 2\n" + + " 3\n" + + ""; + + assertBothWays(array, expected); + + } + + public void testEmptyArray() { + int[] array = new int[]{}; + + String expected = ""; + + assertBothWays(array, expected); + + } + + public void testUninitializedArray() { + String[] array = new String[4]; + array[0] = "zero"; + array[2] = "two"; + + String expected = "" + + "\n" + + " zero\n" + + " \n" + + " two\n" + + " \n" + + ""; + + assertBothWays(array, expected); + + } + + public void testArrayInCustomObject() { + ObjWithArray objWithArray = new ObjWithArray(); + objWithArray.strings = new String[]{"hi", "bye"}; + xstream.alias("owa", ObjWithArray.class); + String expected = "" + + "\n" + + " \n" + + " hi\n" + + " bye\n" + + " \n" + + ""; + assertBothWays(objWithArray, expected); + } + + public void testNullArrayInCustomObject() { + ObjWithArray objWithArray = new ObjWithArray(); + xstream.alias("owa", ObjWithArray.class); + String expected = ""; + assertBothWays(objWithArray, expected); + } + + public static class ObjWithArray extends StandardObject { + String[] strings; + } + + public void testDeserializingObjectWhichContainsAPrimitiveLongArray() { + String xml = + "" + + " " + + " 0" + + " 1" + + " 2" + + " " + + ""; + + xstream.alias("owla", ObjectWithLongArray.class); + + ObjectWithLongArray o = (ObjectWithLongArray) xstream.fromXML(xml); + + assertEquals(o.bits[0], 0); + assertEquals(o.bits[1], 1); + assertEquals(o.bits[2], 2); + } + + public static class ObjectWithLongArray { + long[] bits; + } + + public void testMultidimensionalArray() { + int[][] array = new int[3][2]; + array[0][0] = 2; + array[0][1] = 4; + array[1][0] = 8; + array[1][1] = 16; + array[2] = new int[3]; + array[2][0] = 33; + array[2][1] = 66; + array[2][2] = 99; + + String expectedXml = "" + + "\n" + + " \n" + + " 2\n" + + " 4\n" + + " \n" + + " \n" + + " 8\n" + + " 16\n" + + " \n" + + " \n" + + " 33\n" + + " 66\n" + + " 99\n" + + " \n" + + ""; + + String actualXml = xstream.toXML(array); + assertEquals(expectedXml, actualXml); + + int[][] result = (int[][]) xstream.fromXML(actualXml); + assertEquals(2, result[0][0]); + assertEquals(4, result[0][1]); + assertEquals(8, result[1][0]); + assertEquals(16, result[1][1]); + assertEquals(99, result[2][2]); + assertEquals(3, result.length); + assertEquals(2, result[0].length); + assertEquals(2, result[1].length); + assertEquals(3, result[2].length); + } + + public static class Thing { + } + + public static class SpecialThing extends Thing { + } + + public void testMultidimensionalArrayOfMixedTypes() { + xstream.alias("thing", Thing.class); + xstream.alias("special-thing", SpecialThing.class); + + Object[][] array = new Object[2][2]; + array[0][0] = new Object(); + array[0][1] = "a string"; + array[1] = new Thing[2]; + array[1][0] = new Thing(); + array[1][1] = new SpecialThing(); + String expectedXml = "" + + "\n" + + " \n" + + " \n" + + " a string\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + String actualXml = xstream.toXML(array); + assertEquals(expectedXml, actualXml); + + Object[][] result = (Object[][]) xstream.fromXML(actualXml); + assertEquals(Object.class, result[0][0].getClass()); + assertEquals("a string", result[0][1]); + assertEquals(Thing.class, result[1][0].getClass()); + assertEquals(SpecialThing.class, result[1][1].getClass()); + } + + public static class NoOneLikesMe extends StandardObject { + private int name; + + public NoOneLikesMe(int name) { + this.name = name; + } + } + + public void testHandlesArrayClassesThatHaveNotYetBeenLoaded() { + // Catch weirdness in classloader. + // Resolved by using Class.forName(x, false, classLoader), instead of classLoader.loadClass(x); + String xml = "" + + "\n" + + " \n" + + " 99\n" + + " \n" + + ""; + NoOneLikesMe[] result = (NoOneLikesMe[]) xstream.fromXML(xml); + assertEquals(1, result.length); + assertEquals(99, result[0].name); + } + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/AttributeTest.java b/xstream/src/test/com/thoughtworks/acceptance/AttributeTest.java new file mode 100644 index 0000000..e6aca00 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/AttributeTest.java @@ -0,0 +1,380 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 20. February 2006 by Mauro Talevi + */ +package com.thoughtworks.acceptance; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; +import com.thoughtworks.xstream.testutil.TimeZoneChanger; + +/** + * @author Paul Hammant + * @author Ian Cartwright + * @author Mauro Talevi + * @author Jörg Schaible + * @author Guilherme Silveira + */ +public class AttributeTest extends AbstractAcceptanceTest { + + protected void setUp() throws Exception { + super.setUp(); + TimeZoneChanger.change("GMT"); + } + + protected void tearDown() throws Exception { + TimeZoneChanger.reset(); + super.tearDown(); + } + + public static class One implements HasID { + public ID id; + public Two two; + + public void setID(ID id) { + this.id = id; + } + } + + public static interface HasID { + void setID(ID id); + } + + public static class Two {} + + public static class Three { + public Date date; + } + + public static class Four extends One { + public ID id; + } + + public static class ID { + public ID(String value) { + this.value = value; + } + + public String value; + } + + private static class MyIDConverter extends AbstractSingleValueConverter { + public boolean canConvert(Class type) { + return type.equals(ID.class); + } + + public String toString(Object obj) { + return obj == null ? null : ((ID) obj).value; + } + + public Object fromString(String str) { + return new ID(str); + } + } + + static class C + { + private Date dt; + private String str; + private int i; + + C() { + // for JDK 1.3 + } + + C(Date dt, String st, int i) + { + this.dt = dt; + this.str = st; + this.i = i; + } + } + + public void testAllowsAttributeWithCustomConverterAndFieldName() { + One one = new One(); + one.two = new Two(); + one.id = new ID("hullo"); + + xstream.alias("one", One.class); + xstream.useAttributeFor("id", ID.class); + xstream.registerConverter(new MyIDConverter()); + + String expected = + "\n" + + " \n" + + ""; + assertBothWays(one, expected); + } + + public void testDoesNotAllowAttributeWithCustomConverterAndDifferentFieldName() { + One one = new One(); + one.two = new Two(); + one.id = new ID("hullo"); + + xstream.alias("one", One.class); + xstream.useAttributeFor("foo", ID.class); + xstream.registerConverter(new MyIDConverter()); + + String expected = + "\n" + + " hullo\n" + + " \n" + + ""; + assertBothWays(one, expected); + } + + // TODO: Currently not possible, see comment in AbstractReflectionProvider.doUnmarshal + public void todoTestHidingMemberCanBeWrittenIfAliasDiffers() { + Four four = new Four(); + four.two = new Two(); + four.id = new ID("4"); + four.setID(new ID("1")); + + xstream.alias("four", Four.class); + xstream.aliasField("id4", Four.class, "id"); + xstream.useAttributeFor(ID.class); + xstream.registerConverter(new MyIDConverter()); + + String expected = + "\n" + + " \n" + + ""; + assertBothWays(four, expected); + } + + public void testAllowsAttributeWithKnownConverterAndFieldName() throws Exception { + Three three = new Three(); + DateFormat format = new SimpleDateFormat("dd/MM/yyyy"); + three.date = format.parse("19/02/2006"); + + xstream.alias("three", Three.class); + xstream.useAttributeFor("date", Date.class); + + String expected = + ""; + assertBothWays(three, expected); + } + + public void testAllowsAttributeWithArbitraryFieldType() { + One one = new One(); + one.two = new Two(); + one.id = new ID("hullo"); + + xstream.alias("one", One.class); + xstream.useAttributeFor(ID.class); + xstream.registerConverter(new MyIDConverter()); + + String expected = + "\n" + + " \n" + + ""; + assertBothWays(one, expected); + } + + public void testDoesNotAllowAttributeWithNullAttribute() { + One one = new One(); + one.two = new Two(); + + xstream.alias("one", One.class); + xstream.useAttributeFor(ID.class); + xstream.registerConverter(new MyIDConverter()); + + String expected = + "\n" + + " \n" + + ""; + assertBothWays(one, expected); + } + + public void testAllowsAttributeToBeAliased() { + One one = new One(); + one.two = new Two(); + one.id = new ID("hullo"); + + xstream.alias("one", One.class); + xstream.aliasAttribute("id-alias", "id"); + xstream.useAttributeFor("id", ID.class); + xstream.registerConverter(new MyIDConverter()); + + String expected = + "\n" + + " \n" + + ""; + assertBothWays(one, expected); + } + + public void testCanHandleNullValues() { + C c = new C(null, null, 0); + xstream.alias("C", C.class); + xstream.useAttributeFor(Date.class); + xstream.useAttributeFor(String.class); + String expected = + "\n" + + " 0\n" + + ""; + assertBothWays(c, expected); + } + + public void testCanHandlePrimitiveValues() { + C c = new C(null, null, 0); + xstream.alias("C", C.class); + xstream.useAttributeFor(Date.class); + xstream.useAttributeFor(String.class); + xstream.useAttributeFor(int.class); + String expected =""; + assertBothWays(c, expected); + } + + static class Name { + private String name; + Name() { + // for JDK 1.3 + } + Name(String name) { + this.name = name; + } + } + + static class Camera { + private String name; + protected Name n; + + Camera() { + // for JDK 1.3 + } + + Camera(String name) { + this.name = name; + } + } + + public void testAllowsAnAttributeForASpecificField() { + xstream.alias("camera", Camera.class); + xstream.useAttributeFor(Camera.class, "name"); + Camera camera = new Camera("Rebel 350"); + camera.n = new Name("foo"); + String expected = "" + + "\n" + + " \n" + + " foo\n" + + " \n" + + ""; + assertBothWays(camera, expected); + } + + public void testAllowsAnAttributeForASpecificAliasedField() { + xstream.alias("camera", Camera.class); + xstream.aliasAttribute(Camera.class, "name", "model"); + Camera camera = new Camera("Rebel 350"); + camera.n = new Name("foo"); + String expected = "" + + "\n" + + " \n" + + " foo\n" + + " \n" + + ""; + assertBothWays(camera, expected); + } + + static class PersonalizedCamera extends Camera { + private String owner; + + PersonalizedCamera() { + // for JDK 1.3 + } + + PersonalizedCamera(String name, String owner) { + super(name); + this.owner = owner; + } + } + + public void testAllowsAnAttributeForASpecificFieldInASuperClass() { + xstream.alias("camera", PersonalizedCamera.class); + xstream.useAttributeFor(Camera.class, "name"); + PersonalizedCamera camera = new PersonalizedCamera("Rebel 350", "Guilherme"); + camera.n = new Name("foo"); + String expected = "" + + "\n" + + " \n" + + " foo\n" + + " \n" + + " Guilherme\n" + + ""; + assertBothWays(camera, expected); + } + + public void testAllowsAnAttributeForAFieldOfASpecialTypeAlsoInASuperClass() { + xstream.alias("camera", PersonalizedCamera.class); + xstream.useAttributeFor("name", String.class); + PersonalizedCamera camera = new PersonalizedCamera("Rebel 350", "Guilherme"); + camera.n = new Name("foo"); + String expected = "" + + "\n" + + " \n" + + " Guilherme\n" + + ""; + assertBothWays(camera, expected); + } + + public static class TransientIdField { + transient String id; + String name; + + public TransientIdField() { + // for JDK 1.3 + } + + public TransientIdField(String id, String name) { + this.id = id; + this.name = name; + } + + public boolean equals(Object obj) { + return name.equals(((TransientIdField)obj).name); + } + } + + public void testAttributeNamedLikeTransientFieldDoesNotAbortDeserializationOfFollowingFields() { + xstream.setMode(XStream.ID_REFERENCES); + xstream.alias("transient", TransientIdField.class); + + TransientIdField field = new TransientIdField("foo", "test"); + String xml = "" // + + "\n" // + + " test\n" // + + ""; + + assertBothWays(field, xml); + } + + static class Person { + String _name; + int _age; + Person() {} // JDK 1.3 + Person(String name, int age) { + this._name = name; + this._age = age; + } + }; + + public void testAttributeMayHaveXmlUnfriendlyName() { + xstream.alias("person", Person.class); + xstream.useAttributeFor(Person.class, "_name"); + xstream.useAttributeFor(Person.class, "_age"); + Person person = new Person("joe", 25); + String xml = ""; + assertBothWays(person, xml); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/Basic15TypesTest.java b/xstream/src/test/com/thoughtworks/acceptance/Basic15TypesTest.java new file mode 100644 index 0000000..3cb92fd --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/Basic15TypesTest.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2008, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. January 2008 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import java.util.UUID; + +import com.thoughtworks.xstream.XStream; + +public class Basic15TypesTest extends AbstractAcceptanceTest { + + @Override + protected void setupSecurity(XStream xstream) { + super.setupSecurity(xstream); + xstream.allowTypes(new Class[]{StringBuilder.class, UUID.class}); + } + + public void testUUID() { + UUID uuid = UUID.randomUUID(); + assertBothWays(uuid, "" + uuid + ""); + } + + public void testStringBuilder() { + StringBuilder builder = new StringBuilder(); + builder.append("woo"); + String xml = xstream.toXML(builder); + assertEquals(xml, "woo"); + StringBuilder out = (StringBuilder) xstream.fromXML(xml); + assertEquals("woo", out.toString()); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/BasicTypesTest.java b/xstream/src/test/com/thoughtworks/acceptance/BasicTypesTest.java new file mode 100644 index 0000000..6d57bf5 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/BasicTypesTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2003, 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import java.math.BigDecimal; +import java.math.BigInteger; + + +public class BasicTypesTest extends AbstractAcceptanceTest { + + public void testPrimitiveNumbers() { + assertBothWays(new Integer(99), "99"); + assertBothWays(new Integer(-99), "-99"); + assertBothWays(new Integer(0), "0"); + assertBothWays(new Float(-123.45f), "-123.45"); + assertBothWays(new Double(-1234567890.12345), "-1.23456789012345E9"); + assertBothWays(new Long(123456789123456L), "123456789123456"); + assertBothWays(new Short((short)123), "123"); + } + + public void testDifferentBaseIntegers() { + assertEquals(new Integer(255), xstream.fromXML("0xFF")); + assertEquals(new Integer(255), xstream.fromXML("#FF")); + assertEquals(new Integer(8), xstream.fromXML("010")); + assertEquals(new Long(01777777773427777777773L), xstream.fromXML("01777777773427777777773")); + } + + public void testNegativeIntegersInHex() { + assertEquals(new Byte((byte)-1), xstream.fromXML("0xFF")); + assertEquals(new Short((short)-1), xstream.fromXML("0xFFFF")); + assertEquals(new Integer(-1), xstream.fromXML("0xFFFFFFFF")); + assertEquals(new Long(-1), xstream.fromXML("0xFFFFFFFFFFFFFFFF")); + } + + public void testNegativeIntegersInOctal() { + assertEquals(new Byte((byte)-1), xstream.fromXML("0377")); + assertEquals(new Short((short)-1), xstream.fromXML("0177777")); + assertEquals(new Integer(-1), xstream.fromXML("037777777777")); + assertEquals(new Long(-1), xstream.fromXML("01777777777777777777777")); + } + + public void testOtherPrimitives() { + assertBothWays(new Character('z'), "z"); + assertBothWays(Boolean.TRUE, "true"); + assertBothWays(Boolean.FALSE, "false"); + assertBothWays(new Byte((byte)44), "44"); + } + + public void testNullCharacter() { + assertEquals(new Character('\0'), xstream.fromXML("")); // pre XStream 1.3 + assertBothWays(new Character('\0'), ""); + } + + public void testNonUnicodeCharacter() { + assertBothWays(new Character('\uffff'), "￿"); + } + + public void testStrings() { + assertBothWays("hello world", "hello world"); + assertBothWays("-0770", "-0770"); + } + + public void testStringsWithISOControlCharacter() { + assertBothWays("hello\u0004world", "helloworld"); + assertBothWays("hello\u0096world", "hello–world"); + } + + public void testStringBuffer() { + StringBuffer buffer = new StringBuffer(); + buffer.append("woo"); + String xml = xstream.toXML(buffer); + assertEquals(xml, "woo"); + StringBuffer out = (StringBuffer)xstream.fromXML(xml); + assertEquals("woo", out.toString()); + } + + public void testBigInteger() { + BigInteger bigInteger = new BigInteger("1234567890123456"); + assertBothWays(bigInteger, "1234567890123456"); + } + + public void testBigDecimal() { + BigDecimal bigDecimal = new BigDecimal("1234567890123456.987654321"); + assertBothWays(bigDecimal, "1234567890123456.987654321"); + } + + public void testNull() { + assertBothWays(null, ""); + } + + public void testNumberFormats() { + assertEquals(1.0, ((Double)xstream.fromXML("1")).doubleValue(), 0.001); + assertEquals(1.0f, ((Float)xstream.fromXML("1")).floatValue(), 0.001); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/BeanIDCircularReferenceTest.java b/xstream/src/test/com/thoughtworks/acceptance/BeanIDCircularReferenceTest.java new file mode 100644 index 0000000..2563eea --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/BeanIDCircularReferenceTest.java @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2008, 2010, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 12. November 2008 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.core.ReferenceByIdMarshaller; +import com.thoughtworks.xstream.core.ReferenceByIdMarshallingStrategy; +import com.thoughtworks.xstream.core.TreeMarshaller; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + + +public class BeanIDCircularReferenceTest extends AbstractReferenceTest { + + private ReferenceByFirstnameMarshallingStrategy marshallingStrategy; + + private static final class ReferenceByFirstnameMarshallingStrategy extends + ReferenceByIdMarshallingStrategy { + protected TreeMarshaller createMarshallingContext(HierarchicalStreamWriter writer, + ConverterLookup converterLookup, Mapper mapper) { + return new ReferenceByIdMarshaller( + writer, converterLookup, mapper, new ReferenceByIdMarshaller.IDGenerator() { + int id = 0; + + public String next(Object item) { + final String id; + if (item instanceof Person) { + id = ((Person)item).firstname; + } else if (item instanceof TreeData) { + id = ((TreeData)item).data; + } else { + id = String.valueOf(this.id++ ); + } + return id; + } + }); + } + } + + // inherits test from superclass + protected void setUp() throws Exception { + super.setUp(); + marshallingStrategy = new ReferenceByFirstnameMarshallingStrategy(); + xstream.setMarshallingStrategy(marshallingStrategy); + } + + public void testCircularReferenceXml() { + Person bob = new Person("bob"); + Person jane = new Person("jane"); + bob.likes = jane; + jane.likes = bob; + + String expected = "" + + "\n" + + " bob\n" + + " \n" + + " jane\n" + + " \n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(bob)); + } + + public void testCircularReferenceToSelfXml() { + Person bob = new Person("bob"); + bob.likes = bob; + + String expected = "" + + "\n" + + " bob\n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(bob)); + } + + public void testCanAvoidMemberIfUsedAsId() throws Exception { + xstream.omitField(Person.class, "firstname"); + + Person bob = new Person("bob"); + Person jane = new Person("jane"); + bob.likes = jane; + jane.likes = bob; + + String expected = "" + + "\n" + + " \n" + + " \n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(bob)); + + // new XStream instance, since marshal and unmarshal is asymmetric + xstream = createXStream(); + setUp(); + xstream.useAttributeFor("firstname", String.class); + xstream.aliasField("id", Person.class, "firstname"); + + Person bobAgain = (Person)xstream.fromXML(expected); + assertEquals("bob", bobAgain.firstname); + assertEquals("jane", bobAgain.likes.firstname); + } + + public void testReplacedReference() { + String expectedXml = "" + + "\n" + + " parent\n" + + " \n" + + " \n" + + " child\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + replacedReference(expectedXml); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/BooleanFieldsTest.java b/xstream/src/test/com/thoughtworks/acceptance/BooleanFieldsTest.java new file mode 100644 index 0000000..042abfa --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/BooleanFieldsTest.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 19. October 2006 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.converters.basic.BooleanConverter; + +import java.util.List; +import java.util.ArrayList; + +/** + * @author David Blevins + */ +public class BooleanFieldsTest extends AbstractAcceptanceTest { + + public static class Musican { + public String name; + public String genre; + public boolean alive; + + public Musican() { + // for JDK 1.3 + } + + public Musican(String name, String genre, boolean alive) { + this.name = name; + this.genre = genre; + this.alive = alive; + } + } + + public void testTrueFalseValues() { + List jazzIcons = new ArrayList(); + jazzIcons.add(new Musican("Miles Davis", "jazz", false)); + jazzIcons.add(new Musican("Wynton Marsalis", "jazz", true)); + + xstream.alias("musician", Musican.class); + + String expectedXml = + "\n" + + " \n" + + " Miles Davis\n" + + " jazz\n" + + " false\n" + + " \n" + + " \n" + + " Wynton Marsalis\n" + + " jazz\n" + + " true\n" + + " \n" + + ""; + + assertBothWays(jazzIcons, expectedXml); + } + + public void testYesNoValues() { + List jazzIcons = new ArrayList(); + jazzIcons.add(new Musican("Miles Davis", "jazz", false)); + jazzIcons.add(new Musican("Wynton Marsalis", "jazz", true)); + + xstream.alias("musician", Musican.class); + xstream.registerConverter(BooleanConverter.YES_NO); + + String expectedXml = + "\n" + + " \n" + + " Miles Davis\n" + + " jazz\n" + + " no\n" + + " \n" + + " \n" + + " Wynton Marsalis\n" + + " jazz\n" + + " yes\n" + + " \n" + + ""; + + assertBothWays(jazzIcons, expectedXml); + } + + public void testBinaryValues() { + List jazzIcons = new ArrayList(); + jazzIcons.add(new Musican("Miles Davis", "jazz", false)); + jazzIcons.add(new Musican("Wynton Marsalis", "jazz", true)); + + xstream.alias("musician", Musican.class); + xstream.registerConverter(BooleanConverter.BINARY); + + String expectedXml = + "\n" + + " \n" + + " Miles Davis\n" + + " jazz\n" + + " 0\n" + + " \n" + + " \n" + + " Wynton Marsalis\n" + + " jazz\n" + + " 1\n" + + " \n" + + ""; + + assertBothWays(jazzIcons, expectedXml); + } + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/BufferedImagesTest.java b/xstream/src/test/com/thoughtworks/acceptance/BufferedImagesTest.java new file mode 100644 index 0000000..346f729 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/BufferedImagesTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 28. October 2008 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.core.JVM; + +import junit.framework.TestSuite; + +import javax.imageio.ImageIO; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.image.BufferedImage; +import java.awt.image.RenderedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + + +/** + * Tests with buffered images. + * + * Note, these tests are deactivated by default. They normally work at first sight, but they are highly dangerous, + * since some of the serialized objects contain member variables that reference native memory. Typical result is + * a JVM crash somewhat later because of double freed memory. + * + * @author Jörg Schaible + */ +public class BufferedImagesTest extends AbstractAcceptanceTest { + + public static TestSuite suite() { + final TestSuite suite = new TestSuite("BufferedImagesSuite"); + //suite.addTestSuite(BufferedImagesTest.class); + return suite; + } + + public void testInBWCanBeMarshalled() throws IOException { + boolean isHeadless = Boolean.valueOf(System.getProperty("java.awt.headless", "false")).booleanValue(); + if (!isHeadless || JVM.is15()) { + final BufferedImage image = new BufferedImage(3, 3, BufferedImage.TYPE_BYTE_BINARY); + final Graphics2D graphics = image.createGraphics(); + graphics.setBackground(Color.WHITE); + graphics.clearRect(0, 0, 2, 2); + graphics.setColor(Color.BLACK); + graphics.drawLine(0, 0, 2, 2); + + final ByteArrayOutputStream baosOriginal = new ByteArrayOutputStream(); + ImageIO.write(image, "tiff", baosOriginal); + + xstream.alias("image", BufferedImage.class); + final String xml = xstream.toXML(image); + + final ByteArrayOutputStream baosSerialized = new ByteArrayOutputStream(); + ImageIO.write((RenderedImage)xstream.fromXML(xml), "tiff", baosSerialized); + + assertArrayEquals(baosOriginal.toByteArray(), baosSerialized.toByteArray()); + } + } + + public void testInRGBACanBeMarshalled() throws IOException { + boolean isHeadless = Boolean.valueOf(System.getProperty("java.awt.headless", "false")).booleanValue(); + if (!isHeadless || JVM.is15()) { + final BufferedImage image = new BufferedImage(3, 3, BufferedImage.TYPE_INT_ARGB); + final Graphics2D graphics = image.createGraphics(); + graphics.setBackground(Color.WHITE); + graphics.clearRect(0, 0, 2, 2); + graphics.setColor(Color.RED); + graphics.drawLine(0, 0, 2, 2); + + final ByteArrayOutputStream baosOriginal = new ByteArrayOutputStream(); + ImageIO.write(image, "png", baosOriginal); + + xstream.alias("image", BufferedImage.class); + final String xml = xstream.toXML(image); + + final ByteArrayOutputStream baosSerialized = new ByteArrayOutputStream(); + ImageIO.write((RenderedImage)xstream.fromXML(xml), "png", baosSerialized); + + assertArrayEquals(baosOriginal.toByteArray(), baosSerialized.toByteArray()); + } + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/CglibCompatibilityTest.java b/xstream/src/test/com/thoughtworks/acceptance/CglibCompatibilityTest.java new file mode 100644 index 0000000..b36caf4 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/CglibCompatibilityTest.java @@ -0,0 +1,404 @@ +/* + * Copyright (C) 2006, 2007, 2008, 2010, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 08. April 2006 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.reflection.CGLIBEnhancedConverter; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.mapper.CGLIBMapper; +import com.thoughtworks.xstream.mapper.MapperWrapper; +import com.thoughtworks.xstream.security.CGLIBProxyTypePermission; + +import net.sf.cglib.proxy.Callback; +import net.sf.cglib.proxy.CallbackFilter; +import net.sf.cglib.proxy.Dispatcher; +import net.sf.cglib.proxy.Enhancer; +import net.sf.cglib.proxy.Factory; +import net.sf.cglib.proxy.InvocationHandler; +import net.sf.cglib.proxy.MethodInterceptor; +import net.sf.cglib.proxy.MethodProxy; +import net.sf.cglib.proxy.NoOp; + +import java.io.Serializable; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + + +/** + * @author Jörg Schaible + */ +public class CglibCompatibilityTest extends AbstractAcceptanceTest { + + protected XStream createXStream() { + XStream xstream = new XStream(createDriver()) { + protected MapperWrapper wrapMapper(MapperWrapper next) { + return new CGLIBMapper(next); + } + }; + setupSecurity(xstream); + xstream.addPermission(CGLIBProxyTypePermission.PROXIES); + xstream.registerConverter(new CGLIBEnhancedConverter(xstream.getMapper(), xstream + .getReflectionProvider(), xstream.getClassLoaderReference())); + return xstream; + } + + public static class DelegatingHandler implements InvocationHandler, Serializable { + private Object delegate; + + public DelegatingHandler(Object delegate) { + this.delegate = delegate; + } + + public Object invoke(Object obj, Method method, Object[] args) throws Throwable { + return method.invoke(delegate, args); + } + } + + public static class DelegatingInterceptor implements MethodInterceptor, Serializable, + Runnable { + private Object delegate; + + public DelegatingInterceptor(Object delegate) { + this.delegate = delegate; + } + + public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) + throws Throwable { + return method.invoke(delegate, args); + } + + public void run() { + } + } + + public static class DelegatingDispatcher implements Dispatcher, Serializable { + private Object delegate; + + public DelegatingDispatcher(Object delegate) { + this.delegate = delegate; + } + + public Object loadObject() throws Exception { + return delegate; + } + } + + public void testSupportsClassBasedProxiesWithFactory() + throws NullPointerException, MalformedURLException { + final Enhancer enhancer = new Enhancer(); + enhancer.setSuperclass(HashMap.class); + enhancer.setCallback(new DelegatingHandler(new HashMap())); + enhancer.setUseFactory(true); // true by default + final Map orig = (Map)enhancer.create(); + final URL url = new URL("http://xstream.codehaus.org"); + orig.put("URL", url); + final String xml = "" + + "\n" + + " java.util.HashMap\n" + + " \n" + + " true\n" + + " \n" + + " \n" + + " \n" + + " URL\n" + + " http://xstream.codehaus.org\n" + + " \n" + + " \n" + + " \n" + + ""; + + final Map serialized = (Map)assertBothWays(orig, xml); + assertEquals(url, serialized.get("URL")); + } + + public void testSupportsClassBasedProxiesWithoutFactory() + throws NullPointerException, MalformedURLException { + final Enhancer enhancer = new Enhancer(); + enhancer.setSuperclass(HashMap.class); + enhancer.setCallback(new DelegatingHandler(new HashMap())); + enhancer.setUseFactory(false); + final Map orig = (Map)enhancer.create(); + final URL url = new URL("http://xstream.codehaus.org"); + orig.put("URL", url); + final String xml = "" + + "\n" + + " java.util.HashMap\n" + + " \n" + + " false\n" + + " \n" + + " \n" + + " \n" + + " URL\n" + + " http://xstream.codehaus.org\n" + + " \n" + + " \n" + + " \n" + + ""; + + final Map serialized = (Map)assertBothWays(orig, xml); + assertEquals(url, serialized.get("URL")); + } + + public void testSupportForClassBasedProxyWithAdditionalInterface() + throws NullPointerException { + final Enhancer enhancer = new Enhancer(); + enhancer.setSuperclass(HashMap.class); + enhancer.setCallback(NoOp.INSTANCE); + enhancer.setInterfaces(new Class[]{Runnable.class}); + final Map orig = (Map)enhancer.create(); + final String xml = "" + + "\n" + + " java.util.HashMap\n" + + " \n" + + " java.lang.Runnable\n" + + " \n" + + " true\n" + + " \n" + + ""; + + final Object serialized = assertBothWays(orig, xml); + assertTrue(serialized instanceof HashMap); + assertTrue(serialized instanceof Map); + assertTrue(serialized instanceof Runnable); + } + + public void testSupportsProxiesWithMultipleInterfaces() throws NullPointerException { + final Enhancer enhancer = new Enhancer(); + enhancer.setCallback(NoOp.INSTANCE); + enhancer.setInterfaces(new Class[]{Map.class, Runnable.class}); + final Map orig = (Map)enhancer.create(); + final String xml = "" + + "\n" + + " java.lang.Object\n" + + " \n" + + " java.util.Map\n" + + " java.lang.Runnable\n" + + " \n" + + " true\n" + + " \n" + + ""; + + final Object serialized = assertBothWays(orig, xml); + assertTrue(serialized instanceof Map); + assertTrue(serialized instanceof Runnable); + } + + public void testSupportProxiesUsingFactoryWithMultipleCallbacks() + throws NullPointerException { + final Enhancer enhancer = new Enhancer(); + enhancer.setCallbacks(new Callback[]{ + + new DelegatingInterceptor(null), new DelegatingHandler(null), + new DelegatingDispatcher(null), NoOp.INSTANCE}); + enhancer.setCallbackFilter(new CallbackFilter() { + int i = 1; + + public int accept(Method method) { + if (method.getDeclaringClass() == Runnable.class) { + return 0; + } + return i < 3 ? i++ : i; + } + }); + enhancer.setInterfaces(new Class[]{Runnable.class}); + enhancer.setUseFactory(true); + final Runnable orig = (Runnable)enhancer.create(); + final String xml = xstream.toXML(orig); + final Factory deserialized = (Factory)xstream.fromXML(xml); + assertTrue("Not a Runnable anymore", deserialized instanceof Runnable); + Callback[] callbacks = deserialized.getCallbacks(); + assertEquals(4, callbacks.length); + assertTrue(callbacks[0] instanceof DelegatingInterceptor); + assertTrue(callbacks[1] instanceof DelegatingHandler); + assertTrue(callbacks[2] instanceof DelegatingDispatcher); + assertTrue(callbacks[3] instanceof NoOp); + } + + public void testThrowsExceptionForProxiesNotUsingFactoryWithMultipleCallbacks() + throws NullPointerException { + final Enhancer enhancer = new Enhancer(); + enhancer.setCallbacks(new Callback[]{ + + new DelegatingInterceptor(null), new DelegatingHandler(null), + new DelegatingDispatcher(null), NoOp.INSTANCE}); + enhancer.setCallbackFilter(new CallbackFilter() { + int i = 1; + + public int accept(Method method) { + if (method.getDeclaringClass() == Runnable.class) { + return 0; + } + return i < 3 ? i++ : i; + } + }); + enhancer.setInterfaces(new Class[]{Runnable.class}); + enhancer.setUseFactory(false); + final Runnable orig = (Runnable)enhancer.create(); + try { + xstream.toXML(orig); + fail("Thrown " + ConversionException.class.getName() + " expected"); + } catch (final ConversionException e) { + + } + } + + public void testSupportProxiesWithMultipleCallbackSetToNull() throws NullPointerException { + final Enhancer enhancer = new Enhancer(); + enhancer.setSuperclass(HashMap.class); + enhancer.setCallback(NoOp.INSTANCE); + final HashMap orig = (HashMap)enhancer.create(); + ((Factory)orig).setCallback(0, null); + final String xml = "" + + "\n" + + " java.util.HashMap\n" + + " \n" + + " true\n" + + " \n" + + ""; + + assertBothWays(orig, xml); + } + + public void testSupportsSerialVersionUID() + throws NullPointerException, NoSuchFieldException, IllegalAccessException { + final Enhancer enhancer = new Enhancer(); + enhancer.setCallback(NoOp.INSTANCE); + enhancer.setInterfaces(new Class[]{Runnable.class}); + enhancer.setSerialVersionUID(new Long(20060804L)); + final Runnable orig = (Runnable)enhancer.create(); + final String xml = "" + + "\n" + + " java.lang.Object\n" + + " \n" + + " java.lang.Runnable\n" + + " \n" + + " true\n" + + " \n" + + " 20060804\n" + + ""; + + final Object serialized = assertBothWays(orig, xml); + final Field field = serialized.getClass().getDeclaredField("serialVersionUID"); + field.setAccessible(true); + assertEquals(20060804L, field.getLong(null)); + } + + public static class InterceptingHandler implements MethodInterceptor { + + public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) + throws Throwable { + return proxy.invokeSuper(obj, args); + } + } + + private final static String THRESHOLD_PARAM = "$THRESHOLD$"; + private final static String CAPACITY_PARAM = "$CAPACITY$"; + + public void testSupportsInterceptedClassBasedProxies() + throws NullPointerException, MalformedURLException { + final Enhancer enhancer = new Enhancer(); + enhancer.setSuperclass(HashMap.class); + enhancer.setCallback(new InterceptingHandler()); + enhancer.setUseFactory(true); + final Map orig = (Map)enhancer.create(); + orig.put("URL", new URL("http://xstream.codehaus.org")); + final StringBuffer xml = new StringBuffer("" + + "\n" + + " java.util.HashMap\n" + + " \n" + + " true\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 0.75\n" + + " $THRESHOLD$\n" + + " \n" + + " $CAPACITY$\n" + + " 1\n" + + " URL\n" + + " http://xstream.codehaus.org\n" + + " \n" + + " \n" + + ""); + + // JDK 1.3 has different threshold and capacity algorithms + int idx = xml.toString().indexOf(THRESHOLD_PARAM); + xml.replace(idx, idx + THRESHOLD_PARAM.length(), JVM.is14() ? "12" : "8"); + idx = xml.toString().indexOf(CAPACITY_PARAM); + xml.replace(idx, idx + CAPACITY_PARAM.length(), JVM.is14() ? "16" : "11"); + + Map serialized = (Map)assertBothWays(orig, xml.toString()); + assertEquals(orig.toString(), serialized.toString()); + } + + public static class ClassWithProxyMember { + Runnable runnable; + Map map; + }; + + public void testSupportsProxiesAsFieldMember() throws NullPointerException { + ClassWithProxyMember expected = new ClassWithProxyMember(); + xstream.alias("with-proxy", ClassWithProxyMember.class); + final Enhancer enhancer = new Enhancer(); + enhancer.setCallback(NoOp.INSTANCE); + enhancer.setInterfaces(new Class[]{Map.class, Runnable.class}); + final Map orig = (Map)enhancer.create(); + expected.runnable = (Runnable)orig; + expected.map = orig; + final String xml = "" + + "\n" + + " \n" + + " java.lang.Object\n" + + " \n" + + " java.util.Map\n" + + " java.lang.Runnable\n" + + " \n" + + " true\n" + + " \n" + + " \n" + + " \n" + + ""; + + final Object serialized = assertBothWays(expected, xml); + assertTrue(serialized instanceof ClassWithProxyMember); + } + + public void testProxyTypeCanBeAliased() throws MalformedURLException { + final Enhancer enhancer = new Enhancer(); + enhancer.setSuperclass(HashMap.class); + enhancer.setCallback(new DelegatingHandler(new HashMap())); + final Map orig = (Map)enhancer.create(); + orig.put("URL", new URL("http://xstream.codehaus.org")); + xstream.aliasType("cglib", Map.class); + final String expected = "" + + "\n" + + " java.util.HashMap\n" + + " \n" + + " true\n" + + " \n" + + " \n" + + " \n" + + " URL\n" + + " http://xstream.codehaus.org\n" + + " \n" + + " \n" + + " \n" + + ""; + assertEquals(expected, xstream.toXML(orig)); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/ClassLoaderTest.java b/xstream/src/test/com/thoughtworks/acceptance/ClassLoaderTest.java new file mode 100644 index 0000000..2510af0 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/ClassLoaderTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2005 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; + +import com.thoughtworks.xstream.mapper.CannotResolveClassException; + + +public class ClassLoaderTest extends AbstractAcceptanceTest { + + public void testAllowsClassLoaderToBeOverriden() throws MalformedURLException { + String name = "com.thoughtworks.proxy.kit.SimpleReference"; + String xml = ""; + xstream.allowTypes(new String[]{name}); + try { + xstream.fromXML(xml); + fail("Thrown " + CannotResolveClassException.class.getName() + " expected"); + } catch (final CannotResolveClassException e) { + assertEquals(name, e.getMessage()); + } + + File proxyToys = new File("target/lib/proxytoys-0.2.1.jar"); + ClassLoader classLoader = new URLClassLoader( + new URL[]{proxyToys.toURI().toURL()}, getClass().getClassLoader()); + // will not work, since class has already been cached + xstream.setClassLoader(classLoader); + + try { + xstream.fromXML(xml); + fail("Thrown " + CannotResolveClassException.class.getName() + " expected"); + } catch (final CannotResolveClassException e) { + assertEquals(name, e.getMessage()); + } + + xstream = createXStream(); + xstream.setClassLoader(classLoader); + xstream.allowTypes(new String[]{name}); + assertEquals(name, xstream.fromXML(xml).getClass().getName()); + + xstream = createXStream(); + xstream.allowTypes(new String[]{name}); + try { + xstream.fromXML(xml); + fail("Thrown " + CannotResolveClassException.class.getName() + " expected"); + } catch (final CannotResolveClassException e) { + assertEquals(name, e.getMessage()); + } + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/CollectionsTest.java b/xstream/src/test/com/thoughtworks/acceptance/CollectionsTest.java new file mode 100644 index 0000000..d4aa876 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/CollectionsTest.java @@ -0,0 +1,395 @@ +/* + * Copyright (C) 2003, 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. October 2003 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.Hardware; +import com.thoughtworks.acceptance.objects.SampleLists; +import com.thoughtworks.acceptance.objects.Software; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.core.JVM; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.Vector; + +public class CollectionsTest extends AbstractAcceptanceTest { + + public void testListsCanContainCustomObjects() { + SampleLists lists = new SampleLists(); + lists.good.add(new Software("apache", "geronimo")); + lists.good.add(new Software("caucho", "resin")); + lists.good.add(new Hardware("risc", "strong-arm")); + lists.bad.add(new Software("apache", "jserv")); + + xstream.alias("lists", SampleLists.class); + xstream.alias("software", Software.class); + xstream.alias("hardware", Hardware.class); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " apache\n" + + " geronimo\n" + + " \n" + + " \n" + + " caucho\n" + + " resin\n" + + " \n" + + " \n" + + " risc\n" + + " strong-arm\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " apache\n" + + " jserv\n" + + " \n" + + " \n" + + ""; + + assertBothWays(lists, expected); + } + + public void testListsCanContainBasicObjects() { + SampleLists lists = new SampleLists(); + lists.good.add("hello"); + lists.good.add(new Integer(3)); + lists.good.add(Boolean.TRUE); + + xstream.alias("lists", SampleLists.class); + + String expected = "" + + "\n" + + " \n" + + " hello\n" + + " 3\n" + + " true\n" + + " \n" + + " \n" + + ""; + + assertBothWays(lists, expected); + } + + public void testListCanBeRootObject() { + Collection list = new ArrayList(); + list.add("hi"); + list.add("bye"); + + String expected = "" + + "\n" + + " hi\n" + + " bye\n" + + ""; + + assertBothWays(list, expected); + } + + public void testSetCanBeRootObject() { + Collection set = new HashSet(); + set.add("hi"); + set.add("bye"); + + String expected = "" + + "\n" + + " hi\n" + + " bye\n" + + ""; + + assertBothWaysNormalized(set, expected, "set", "string", null); + } + + public void testVector() { + Vector vector = new Vector(); + vector.addElement("a"); + vector.addElement("b"); + + assertBothWays(vector, + "\n" + + " a\n" + + " b\n" + + ""); + } + + public void testSyncronizedList() { + final String xml; + if (JVM.is15()) { + xml = + "\n" + + " \n" + + " \n" + + " \n" + + " hi\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + } else { + xml = + "\n" + + " \n" + + " hi\n" + + " \n" + + " \n" + + " \n" + + ""; + } + + // synchronized list has circular reference + xstream.setMode(XStream.XPATH_RELATIVE_REFERENCES); + + List list = Collections.synchronizedList(new LinkedList()); + list.add("hi"); + + assertBothWays(list, xml); + } + + public void testSyncronizedArrayList() { + final String xml; + if (JVM.is15()) { + xml = + "\n" + + " \n" + + " \n" + + " \n" + + " hi\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + } else { + xml = + "\n" + + " \n" + + " hi\n" + + " \n" + + " \n" + + " \n" + + ""; + } + + // synchronized list has circular reference + xstream.setMode(XStream.XPATH_RELATIVE_REFERENCES); + + List list = Collections.synchronizedList(new ArrayList()); + list.add("hi"); + + assertBothWays(list, xml); + } + + public void testEmptyList() { + assertBothWays(Collections.EMPTY_LIST, ""); + } + + public void testEmptySet() { + assertBothWays(Collections.EMPTY_SET, ""); + } + + public void testEmptyListIsImmutable() { + List list = new ArrayList(); + list.add(Collections.EMPTY_LIST); + list.add(Collections.EMPTY_LIST); + assertBothWays(list, + "\n" + + " \n" + + " \n" + + ""); + } + + public void testEmptySetIsImmutable() { + List list = new ArrayList(); + list.add(Collections.EMPTY_SET); + list.add(Collections.EMPTY_SET); + assertBothWays(list, + "\n" + + " \n" + + " \n" + + ""); + } + + public void testEmptyListIsSingleton() { + assertSame(Collections.EMPTY_LIST, xstream.fromXML("")); + } + + public void testEmptySetIsSingleton() { + assertSame(Collections.EMPTY_SET, xstream.fromXML("")); + } + + public void testSingletonList() { + assertBothWays(Collections.singletonList("XStream"), + "\n" + + " XStream\n" + + ""); + } + + public void testSingletonSet() { + assertBothWays(Collections.singleton("XStream"), + "\n" + + " XStream\n" + + ""); + } + + public void testPropertiesWithDefaults() { + Properties defaults = new Properties(); + defaults.setProperty("1", "one"); + defaults.setProperty("2", "two"); + Properties properties = new Properties(defaults); + properties.setProperty("1", "I"); + properties.setProperty("3", "III"); + + assertBothWays(properties, + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""); + } + + public void testUnmodifiableList() { + // unmodifiable list has duplicate references + xstream.setMode(XStream.XPATH_RELATIVE_REFERENCES); + + List list = new ArrayList(); + list.add("hi"); + list = Collections.unmodifiableList(list); + + assertBothWays(list, + "\n" + + " \n" + + " hi\n" + + " \n" + + " \n" + + ""); + } + + public void testLinkedHashSetRetainsOrdering() { + Set set = new LinkedHashSet(); + set.add("Z"); + set.add("C"); + set.add("X"); + + LinkedHashSet result = (LinkedHashSet) assertBothWays(set, + "\n" + + " Z\n" + + " C\n" + + " X\n" + + ""); + + Object[] values = result.toArray(); + assertEquals("Z", values[0]); + assertEquals("C", values[1]); + assertEquals("X", values[2]); + } + + public void testListFromArrayAsList() { + List list = Arrays.asList(new String[] {"hi", "bye"}); + + assertBothWays(list, + "\n" + + " \n" + + " hi\n" + + " bye\n" + + " \n" + + ""); + } + + public void testKeySetOfHashMapCanBeSerialized() { + final Map map = new HashMap(); + map.put("JUnit", null); + final Collection set = map.keySet(); + + xstream.alias("key-set", set.getClass()); + + assertBothWays(set, + "\n" + + " \n" + + " \n" + + " JUnit\n" + + " \n" + + " \n" + + " \n" + + ""); + } + + public void testValueSetOfHashMapCanBeSerialized() { + final Map map = new HashMap(); + map.put(Boolean.TRUE, "JUnit"); + final Collection set = map.values(); + xstream.alias("value-set", set.getClass()); + + assertBothWays(set, + "\n" + + " \n" + + " \n" + + " true\n" + + " JUnit\n" + + " \n" + + " \n" + + ""); + } + + public void testEntrySetOfHashMapCanBeSerialized() { + final Map map = new HashMap(); + map.put(Boolean.TRUE, "JUnit"); + final Collection set = map.entrySet(); + xstream.alias("entry-set", set.getClass()); + + if (JVM.is16() && System.getProperty("java.vm.vendor").indexOf("IBM") >= 0) { + assertBothWays(set, + "\n" + + " \n" + + " \n" + + " true\n" + + " JUnit\n" + + " \n" + + " \n" + + ""); + } else { + assertBothWays(set, + "\n" + + " \n" + + " \n" + + " true\n" + + " JUnit\n" + + " \n" + + " \n" + + ""); + } + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/ConcreteClassesTest.java b/xstream/src/test/com/thoughtworks/acceptance/ConcreteClassesTest.java new file mode 100644 index 0000000..711e7fa --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/ConcreteClassesTest.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2003, 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.acceptance.someobjects.WithList; +import com.thoughtworks.xstream.converters.ConversionException; + +import java.util.ArrayList; +import java.util.LinkedList; + +public class ConcreteClassesTest extends AbstractAcceptanceTest { + + public void testDefaultImplementationOfInterface() { + + xstream.alias("with-list", WithList.class); + + WithList withList = new WithList(); + withList.things = new ArrayList(); + + String expected = + "\n" + + " \n" + + ""; + + assertBothWays(withList, expected); + + } + + public void testAlternativeImplementationOfInterface() { + + xstream.alias("with-list", WithList.class); + xstream.alias("linked-list", LinkedList.class); + + WithList withList = new WithList(); + withList.things = new LinkedList(); + + String expected = + "\n" + + " \n" + + ""; + + assertBothWays(withList, expected); + + } + + interface MyInterface { + } + + public static class MyImp1 extends StandardObject implements MyInterface { + int x = 1; + } + + public static class MyImp2 extends StandardObject implements MyInterface { + int y = 2; + } + + public static class MyHolder extends StandardObject { + MyInterface field1; + MyInterface field2; + } + + public void testCustomInterfaceCanHaveMultipleImplementations() { + xstream.alias("intf", MyInterface.class); + xstream.alias("imp1", MyImp1.class); + xstream.alias("imp2", MyImp2.class); + xstream.alias("h", MyHolder.class); + + MyHolder in = new MyHolder(); + in.field1 = new MyImp1(); + in.field2 = new MyImp2(); + + String expected = "" + + "\n" + + " \n" + + " 1\n" + + " \n" + + " \n" + + " 2\n" + + " \n" + + ""; + + String xml = xstream.toXML(in); + assertEquals(expected, xml); + + MyHolder out = (MyHolder) xstream.fromXML(xml); + assertEquals(MyImp1.class, out.field1.getClass()); + assertEquals(MyImp2.class, out.field2.getClass()); + assertEquals(2, ((MyImp2) out.field2).y); + } + + public void testUnknownChildMatchingATypeThrowsConversionException() { + xstream.alias("h", MyHolder.class); + + String xml = "" + + "\n" + + " 100\n" + + ""; + + try { + xstream.fromXML(xml); + fail("Thrown " + ConversionException.class.getName() + " expected"); + } catch (final ConversionException e) { + // ok + } + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/ConcurrencyTest.java b/xstream/src/test/com/thoughtworks/acceptance/ConcurrencyTest.java new file mode 100644 index 0000000..c6338a9 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/ConcurrencyTest.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. March 2006 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.thoughtworks.acceptance.objects.Software; +import com.thoughtworks.acceptance.someobjects.WithNamedList; + + +/** + * @author Jörg Schaible + */ +public class ConcurrencyTest extends AbstractAcceptanceTest { + + public void testConcurrentXStreaming() throws InterruptedException { + xstream.alias("thing", WithNamedList.class); + xstream.addImplicitCollection(WithNamedList.class, "things"); + + final List reference = Arrays.asList(new String[]{"A", "B", "C", "D"}); + final WithNamedList[] namedLists = new WithNamedList[5]; + for (int i = 0; i < namedLists.length; ++i) { + namedLists[i] = new WithNamedList("Name " + (i + 1)); + namedLists[i].things.add(new Software("walnes", "XStream 1." + i)); + namedLists[i].things.add(reference); + namedLists[i].things.add(new RuntimeException("JUnit " + i)); // a Serializable + } + + final Map exceptions = new HashMap(); + final ThreadGroup tg = new ThreadGroup(getName()) { + public void uncaughtException(Thread t, Throwable e) { + exceptions.put(e, t.getName()); + super.uncaughtException(t, e); + } + }; + + final Object object = Arrays.asList(namedLists); + final String xml = xstream.toXML(object); + final int[] counter = new int[1]; + counter[0] = 0; + final Thread[] threads = new Thread[5]; + for (int i = 0; i < threads.length; ++i) { + threads[i] = new Thread(tg, "JUnit Thread " + i) { + + public void run() { + int i = 0; + try { + synchronized (this) { + notifyAll(); + wait(); + } + while (!interrupted()) { + assertBothWays(object, xml); + ++i; + } + } catch (InterruptedException e) { + fail("Unexpected InterruptedException"); + } + synchronized (counter) { + counter[0] += i; + } + } + + }; + } + + for (int i = 0; i < threads.length; ++i) { + synchronized (threads[i]) { + threads[i].start(); + threads[i].wait(); + } + } + + for (int i = 0; i < threads.length; ++i) { + synchronized (threads[i]) { + threads[i].notifyAll(); + } + } + + Thread.sleep(1000); + + for (int i = 0; i < threads.length; ++i) { + threads[i].interrupt(); + } + for (int i = 0; i < threads.length; ++i) { + synchronized (threads[i]) { + threads[i].join(); + } + } + + assertEquals("Exceptions has been thrown: " + exceptions, 0, exceptions.size()); + assertTrue("Each thread should have made at least 1 conversion", counter[0] >= threads.length); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/Concurrent15TypesTest.java b/xstream/src/test/com/thoughtworks/acceptance/Concurrent15TypesTest.java new file mode 100644 index 0000000..a5915e5 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/Concurrent15TypesTest.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2012, 2015 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 21. March 2012 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import com.thoughtworks.xstream.core.JVM; + + +public class Concurrent15TypesTest extends AbstractAcceptanceTest { + + public void testConcurrentHashMap() { + ConcurrentHashMap map = new ConcurrentHashMap(); + map.put("walnes", "joe"); + String xml = xstream.toXML(map); + String expected = "" + + "\n" + + " \n" + + " walnes\n" + + " joe\n" + + " \n" + + ""; + assertEquals(xml, expected); + @SuppressWarnings("unchecked") + ConcurrentHashMap out = (ConcurrentHashMap)xstream.fromXML(xml); + assertEquals("{walnes=joe}", out.toString()); + } + + public static class DerivedConcurrentHashMap extends ConcurrentHashMap { + private static final long serialVersionUID = 1L; + } + + public void testDerivedConcurrentHashMap() { + if (JVM.is18()) { + xstream.alias("derived-map", DerivedConcurrentHashMap.class); + + Map map = new DerivedConcurrentHashMap(); + map.put("test", "JUnit"); + + String xml = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " 15\n" + + " \n" + + " test\n" + + " JUnit\n" + + " \n" + + " \n" + + " \n" + + ""; + + assertBothWays(map, xml); + } + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/CustomClassesTest.java b/xstream/src/test/com/thoughtworks/acceptance/CustomClassesTest.java new file mode 100644 index 0000000..0560b87 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/CustomClassesTest.java @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2003, 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.io.xml.XppReader; + +import java.io.StringReader; + +public class CustomClassesTest extends AbstractAcceptanceTest { + + public static class SamplePerson extends StandardObject { + int anInt; + String firstName; + String lastName; + transient String aComment = ""; + } + + public void testCustomObjectWithBasicFields() { + + xstream.alias("friend", SamplePerson.class); + + SamplePerson person = new SamplePerson(); + person.anInt = 3; + person.firstName = "Joe"; + person.lastName = "Walnes"; + + String expected = + "\n" + + " 3\n" + + " Joe\n" + + " Walnes\n" + + ""; + + assertBothWays(person, expected); + + } + + public static class SamplePersonHolder { + String aString; + SamplePerson brother; + + public boolean equals(Object obj) { + SamplePersonHolder containerObject = (SamplePersonHolder) obj; + return (aString == null ? containerObject.aString == null : aString.equals(containerObject.aString)) + && brother.equals(containerObject.brother); + } + } + + public void testCustomObjectWithCustomObjectField() { + xstream.alias("friend", SamplePerson.class); + xstream.alias("personHolder", SamplePersonHolder.class); + + SamplePersonHolder personHolder = new SamplePersonHolder(); + personHolder.aString = "hello world"; + + SamplePerson person = new SamplePerson(); + person.anInt = 3; + person.firstName = "Joe"; + person.lastName = "Walnes"; + + personHolder.brother = person; + + String expected = + "\n" + + " hello world\n" + + " \n" + + " 3\n" + + " Joe\n" + + " Walnes\n" + + " \n" + + ""; + + assertBothWays(personHolder, expected); + + } + + public void testCustomObjectWithCustomObjectFieldsSetToNull() { + xstream.alias("friend", SamplePerson.class); + xstream.alias("personHolder", SamplePersonHolder.class); + + SamplePersonHolder personHolder = new SamplePersonHolder(); + personHolder.aString = null; + + SamplePerson person = new SamplePerson(); + person.anInt = 3; + person.firstName = "Joe"; + person.lastName = null; + + personHolder.brother = person; + + String expected = + "\n" + + " \n" + + " 3\n" + + " Joe\n" + + " \n" + + ""; + + assertBothWays(personHolder, expected); + + } + + public void testCustomObjectCanBeInstantiatedExternallyBeforeDeserialization() { + xstream.alias("friend", SamplePerson.class); + xstream.alias("personHolder", SamplePersonHolder.class); + + String xml = + "\n" + + " hello world\n" + + " \n" + + " 3\n" + + " Joe\n" + + " Walnes\n" + + " \n" + + ""; + + // execute + SamplePersonHolder alreadyInstantiated = new SamplePersonHolder(); + xstream.unmarshal(new XppReader(new StringReader(xml)), alreadyInstantiated); + + // verify + SamplePersonHolder expectedResult = new SamplePersonHolder(); + expectedResult.aString = "hello world"; + + SamplePerson expectedPerson = new SamplePerson(); + expectedPerson.anInt = 3; + expectedPerson.firstName = "Joe"; + expectedPerson.lastName = "Walnes"; + expectedResult.brother = expectedPerson; + + assertEquals(expectedResult, alreadyInstantiated); + } + + public void testCustomObjectWillNotUnmarshalTransientFields() { + + xstream.alias("friend", SamplePerson.class); + + String xml = + "\n" + + " 3\n" + + " Joe\n" + + " Walnes\n" + + " XStream Despot\n" + + ""; + + SamplePerson person = (SamplePerson)xstream.fromXML(xml); + if (JVM.is14()) { + assertNull(person.aComment); + } else { + assertEquals("", person.aComment); + } + } + + static class Joe extends SamplePerson { + boolean aBoolean; + } + + public void testCustomObjectWillNotUnmarshalInheritedTransientFields() { + + xstream.alias("joe", Joe.class); + + String xml = + "\n" + + " 3\n" + + " Joe\n" + + " Walnes\n" + + " XStream Despot\n" + + " true\n" + + ""; + + Joe joe = (Joe)xstream.fromXML(xml); + if (JVM.is14()) { + assertNull(joe.aComment); + } else { + assertEquals("", joe.aComment); + } + } + + public void testCustomObjectWillNotUnmarshalTransientFieldsFromAttributes() { + + xstream.alias("friend", SamplePerson.class); + + String xml = + "\n" + + " 3\n" + + " Joe\n" + + " Walnes\n" + + ""; + + // without attribute definition + SamplePerson person = (SamplePerson)xstream.fromXML(xml); + if (JVM.is14()) { + assertNull(person.aComment); + } else { + assertEquals("", person.aComment); + } + + xstream.useAttributeFor("aComment", String.class); + + // with attribute definition + person = (SamplePerson)xstream.fromXML(xml); + if (JVM.is14()) { + assertNull(person.aComment); + } else { + assertEquals("", person.aComment); + } + } + + public void testNullObjectsDoNotHaveFieldsWritten() { + + xstream.alias("cls", WithSomeFields.class); + + WithSomeFields obj = new WithSomeFields(); + + String expected = ""; + + assertBothWays(obj, expected); + } + + public void testEmptyStringsAreNotTreatedAsNulls() { + xstream.alias("cls", WithSomeFields.class); + + WithSomeFields obj = new WithSomeFields(); + obj.b = ""; + + String expected = "" + + "\n" + + " \n" + + ""; + + assertBothWays(obj, expected); + } + + public static class WithSomeFields extends StandardObject { + Object a; + String b; + } + + public void testNullsAreDistinguishedFromEmptyStrings() { + LotsOfStrings in = new LotsOfStrings(); + in.a = "."; + in.b = ""; + in.c = null; + + String xml = xstream.toXML(in); + LotsOfStrings out = (LotsOfStrings) xstream.fromXML(xml); + + assertEquals(".", out.a); + assertEquals("", out.b); + assertNull(out.c); + } + + public static class LotsOfStrings { + String a; + String b; + String c; + } + + public void testFieldWithObjectType() { + String expected = "" + + "\n" + + " 1.0\n" + + " 2.0\n" + + ""; + xstream.alias("thing", FieldWithObjectType.class); + + assertBothWays(new FieldWithObjectType(), expected); + } + + public static class FieldWithObjectType extends StandardObject { + Double one = new Double(1.0); + Object two = new Double(2.0); + } + + public void testFailsFastIfFieldIsDefinedTwice() { + String input = "" + + "\n" + + " 1.0\n" + + " 2.0\n" + + ""; + xstream.alias("thing", FieldWithObjectType.class); + + try { + + xstream.fromXML(input); + fail("Expected exception"); + + } catch (ReflectionConverter.DuplicateFieldException expected) { + assertEquals("one", expected.get("field")); + } + } + + public static class TransientInitializingClass extends StandardObject { + private transient String s = ""; + private Object readResolve() { + this.s = "foo"; + return this; + } + } + + public void testCustomObjectWithTransientFieldInitialization() { + + xstream.alias("tran", TransientInitializingClass.class); + + TransientInitializingClass tran = new TransientInitializingClass(); + + String expected = ""; + + TransientInitializingClass serialized = (TransientInitializingClass)assertBothWays(tran, expected); + assertEquals("foo", serialized.s); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/CustomConverterTest.java b/xstream/src/test/com/thoughtworks/acceptance/CustomConverterTest.java new file mode 100644 index 0000000..be82478 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/CustomConverterTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 17. March 2006 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.SingleValueConverter; + +import java.text.DecimalFormat; +import java.text.ParseException; + +public class CustomConverterTest extends AbstractAcceptanceTest { + + private final class DoubleConverter implements SingleValueConverter { + private final DecimalFormat formatter; + + private DoubleConverter() { + formatter = new DecimalFormat("#,###,##0"); + } + + public boolean canConvert(Class type) { + return type == double.class || type == Double.class; + } + + public String toString(Object obj) { + return this.formatter.format(obj); + } + + public Object fromString(String str) { + try { + // the formatter will chose the most appropriate format ... Long + return this.formatter.parseObject(str); + } catch (ParseException e) { + throw new ConversionException(e); + } + } + } + + public static class DoubleWrapper { + Double d; + + public DoubleWrapper(double d) { + this.d = new Double(d); + } + + protected DoubleWrapper() { + // JDK 1.3 issue + } + } + + public void testWrongObjectTypeReturned() { + xstream.alias("dw", DoubleWrapper.class); + xstream.registerConverter(new DoubleConverter()); + + String xml = "" + + "\n" + + " -92.000.000\n" + + ""; + + try { + xstream.fromXML(xml); + fail("Thrown " + ConversionException.class.getName() + " expected"); + } catch (final ConversionException e) { + assertTrue(e.getMessage().indexOf(Long.class.getName()) > 0); + } + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/CustomFieldKeySorterTest.java b/xstream/src/test/com/thoughtworks/acceptance/CustomFieldKeySorterTest.java new file mode 100644 index 0000000..fe8e899 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/CustomFieldKeySorterTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2007, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 17. May 2007 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.reflection.FieldDictionary; +import com.thoughtworks.xstream.converters.reflection.FieldKey; +import com.thoughtworks.xstream.converters.reflection.FieldKeySorter; +import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; + +import java.util.Comparator; +import java.util.Map; +import java.util.TreeMap; + + +/** + * @author Jörg Schaible + */ +public class CustomFieldKeySorterTest extends AbstractAcceptanceTest { + + protected XStream createXStream() { + XStream xstream = new XStream(new PureJavaReflectionProvider(new FieldDictionary( + new AlphabeticalFieldkeySorter()))); + setupSecurity(xstream); + return xstream; + } + + static class Base { + String yyy = "y"; + String ccc = "c"; + String bbb = "b"; + } + + static class First extends Base { + String aaa = "a"; + } + + static class Second extends First { + String xxx = "x"; + String zzz = "z"; + } + + public void testSortsAlphabetically() { + xstream.alias("second", Second.class); + + String xml = "" + + "\n" + + " a\n" + + " b\n" + + " c\n" + + " x\n" + + " y\n" + + " z\n" + + ""; + + assertBothWays(new Second(), xml); + } + + private static class AlphabeticalFieldkeySorter implements FieldKeySorter { + + public Map sort(Class type, Map keyedByFieldKey) { + Map map = new TreeMap(new Comparator() { + + public int compare(Object o1, Object o2) { + final FieldKey fieldKey1 = (FieldKey)o1; + final FieldKey fieldKey2 = (FieldKey)o2; + return fieldKey1.getFieldName().compareTo(fieldKey2.getFieldName()); + } + }); + map.putAll(keyedByFieldKey); + return map; + } + + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/CustomMapperTest.java b/xstream/src/test/com/thoughtworks/acceptance/CustomMapperTest.java new file mode 100644 index 0000000..840be61 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/CustomMapperTest.java @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. March 2005 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; + +import com.thoughtworks.acceptance.objects.Software; +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.acceptance.someobjects.WithList; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; +import com.thoughtworks.xstream.core.ClassLoaderReference; +import com.thoughtworks.xstream.io.xml.DomDriver; +import com.thoughtworks.xstream.mapper.CannotResolveClassException; +import com.thoughtworks.xstream.mapper.DefaultMapper; +import com.thoughtworks.xstream.mapper.Mapper; +import com.thoughtworks.xstream.mapper.MapperWrapper; + +public class CustomMapperTest extends AbstractAcceptanceTest { + + /** + * A sample mapper strips the underscore prefix of field names in the XML + */ + private static class FieldPrefixStrippingMapper extends MapperWrapper { + public FieldPrefixStrippingMapper(Mapper wrapped) { + super(wrapped); + } + + public String serializedMember(Class type, String memberName) { + if (memberName.startsWith("_")) { + // _blah -> blah + memberName = memberName.substring(1); // chop off leading char (the underscore) + } else if (memberName.startsWith("my")) { + // myBlah -> blah + memberName = memberName.substring(2, 3).toLowerCase() + memberName.substring(3); + } + return super.serializedMember(type, memberName); + } + + public String realMember(Class type, String serialized) { + String fieldName = super.realMember(type, serialized); + // Not very efficient or elegant, but enough to get the point across. + // Luckily the CachingMapper will ensure this is only ever called once per field per class. + try { + type.getDeclaredField("_" + fieldName); + return "_" + fieldName; + } catch (NoSuchFieldException e) { + try { + String myified = "my" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); + type.getDeclaredField(myified); + return myified; + } catch (NoSuchFieldException e2) { + return fieldName; + } + } + } + } + + public static class ThingWithStupidNamingConventions extends StandardObject { + String _firstName; + String lastName; + int myAge; + + public ThingWithStupidNamingConventions(String firstname, String lastname, int age) { + _firstName = firstname; + this.lastName = lastname; + myAge = age; + } + } + + public void testUserDefinedMappingCanAlterFieldName() { + xstream = new XStream() { + protected MapperWrapper wrapMapper(MapperWrapper next) { + return new FieldPrefixStrippingMapper(next); + } + }; + setupSecurity(xstream); + xstream.alias("thing", ThingWithStupidNamingConventions.class); + + ThingWithStupidNamingConventions in = new ThingWithStupidNamingConventions("Joe", "Walnes", 10); + String expectedXml = "" + + "\n" + + " Joe\n" // look, no underscores! + + " Walnes\n" + + " 10\n" + + ""; + + assertBothWays(in, expectedXml); + } + + private static class PackageStrippingMapper extends MapperWrapper { + public PackageStrippingMapper(Mapper wrapped) { + super(wrapped); + } + + public String serializedClass(Class type) { + return type.getName().replaceFirst(".*\\.", ""); + } + } + + public void testStripsPackagesUponDeserialization() { + // obviously this isn't deserializable! + xstream = new XStream() { + protected MapperWrapper wrapMapper(MapperWrapper next) { + return new PackageStrippingMapper(next); + } + }; + + // NOTE: no aliases defined! + + String expectedXml = "" + + "\n" + + " ms\n" + + " word\n" + + ""; + assertEquals(expectedXml, xstream.toXML(new Software("ms", "word"))); + } + + public void testOwnMapperChainCanBeRegistered() { + ClassLoaderReference classLoaderReference = new ClassLoaderReference(getClass().getClassLoader()); + Mapper mapper = new DefaultMapper(classLoaderReference); + xstream = new XStream(new PureJavaReflectionProvider(), new DomDriver(), getClass().getClassLoader(), mapper); + + String expected = "" + + "\n" + + " ms\n" + + " word\n" + + ""; + assertEquals(expected, xstream.toXML(new Software("ms", "word"))); + } + + public void testCanBeUsedToOmitUnexpectedElements() { + String expectedXml = "" + + "\n" + + " 1.0\n" + + " Joe\n" + + " XStream\n" + + ""; + + xstream = new XStream() { + + protected MapperWrapper wrapMapper(MapperWrapper next) { + return new MapperWrapper(next) { + + public boolean shouldSerializeMember(Class definedIn, String fieldName) { + return definedIn != Object.class ? super.shouldSerializeMember(definedIn, fieldName) : false; + } + + }; + } + + }; + setupSecurity(xstream); + xstream.alias("software", Software.class); + + Software out = (Software) xstream.fromXML(expectedXml); + assertEquals("Joe", out.vendor); + assertEquals("XStream", out.name); + } + + public void testInjectingReplacements() { + XStream xstream = new XStream() { + + protected MapperWrapper wrapMapper(MapperWrapper next) { + return new MapperWrapper(next) { + public Class realClass(String elementName) { + try { + return super.realClass(elementName); + + } catch (CannotResolveClassException e) { + if (elementName.endsWith("oo")) { + return Integer.class; + } + if (elementName.equals("UnknownList")) { + return LinkedList.class; + } + throw e; + } + } + + }; + } + + }; + setupSecurity(xstream); + xstream.alias("wl", WithList.class); + WithList wl = (WithList)xstream.fromXML("" + + "\n" + + " \n" + + " 1\n" + + " 2\n" + + " \n" + + ""); + assertEquals(new ArrayList(Arrays.asList(new Integer[]{new Integer(1), new Integer(2)})), wl.things); + assertTrue(wl.things instanceof LinkedList); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/CustomSerializationTest.java b/xstream/src/test/com/thoughtworks/acceptance/CustomSerializationTest.java new file mode 100644 index 0000000..34cecf1 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/CustomSerializationTest.java @@ -0,0 +1,560 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2015 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 23. August 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.Hardware; +import com.thoughtworks.acceptance.objects.Software; +import com.thoughtworks.acceptance.objects.StandardObject; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamField; +import java.io.Serializable; + +public class CustomSerializationTest extends AbstractAcceptanceTest { + + public static class ObjectWithCustomSerialization extends StandardObject implements Serializable { + + private int a; + private transient int b; + private transient String c; + private transient Object d; + private transient Software e; + + public ObjectWithCustomSerialization() { + } + + public ObjectWithCustomSerialization(int a, int b, String c, Software e) { + this.a = a; + this.b = b; + this.c = c; + this.e = e; + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + b = in.readInt(); + in.defaultReadObject(); + c = (String) in.readObject(); + d = in.readObject(); + e = (Software) in.readObject(); + } + + private void writeObject(ObjectOutputStream out) throws IOException { + out.writeInt(b); + out.defaultWriteObject(); + out.writeObject(c); + out.writeObject(d); + out.writeObject(e); + } + + } + + public void testWritesCustomFieldsToStream() { + ObjectWithCustomSerialization obj = new ObjectWithCustomSerialization(1, 2, "hello", new Software("tw", "xs")); + xstream.alias("custom", ObjectWithCustomSerialization.class); + xstream.alias("software", Software.class); + + String expectedXml = "" + + "\n" + + " \n" + + " 2\n" + + " \n" + + " 1\n" + + " \n" + + " hello\n" + + " \n" + + " \n" + + " tw\n" + + " xs\n" + + " \n" + + " \n" + + ""; + + assertBothWays(obj, expectedXml); + } + + public static class Parent extends StandardObject implements Serializable { + + private transient int parentA; + private int parentB; + private transient int parentC; + + public Parent() { + } + + public Parent(int parentA, int parentB, int parentC) { + this.parentA = parentA; + this.parentB = parentB; + this.parentC = parentC; + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + parentA = in.readInt(); + in.defaultReadObject(); + parentC = in.readInt(); + } + + private void writeObject(ObjectOutputStream out) throws IOException { + out.writeInt(parentA); + out.defaultWriteObject(); + out.writeInt(parentC); + } + } + + public static class Child extends Parent { + + private transient int childA; + private int childB; + private transient int childC; + + public Child() { + } + + public Child(int parentA, int parentB, int parentC, int childA, int childB, int childC) { + super(parentA, parentB, parentC); + this.childA = childA; + this.childB = childB; + this.childC = childC; + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + childA = in.readInt(); + in.defaultReadObject(); + childC = in.readInt(); + } + + private void writeObject(ObjectOutputStream out) throws IOException { + out.writeInt(childA); + out.defaultWriteObject(); + out.writeInt(childC); + } + } + + public void testIncludesCompleteClassHierarchyWhenParentAndChildHaveSerializationMethods() { + Child child = new Child(1, 2, 3, 10, 20, 30); + xstream.alias("child", Child.class); + xstream.alias("parent", Parent.class); + + String expectedXml = "" + + "\n" + + " \n" + + " 1\n" + + " \n" + + " 2\n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 10\n" + + " \n" + + " 20\n" + + " \n" + + " 30\n" + + " \n" + + ""; + + assertBothWays(child, expectedXml); + } + + public static class Child2 extends Parent { + + private int childA; + + public Child2(int parentA, int parentB, int parentC, int childA) { + super(parentA, parentB, parentC); + this.childA = childA; + } + + } + + public void testIncludesCompleteClassHierarchyWhenOnlyParentHasSerializationMethods() { + Child2 child = new Child2(1, 2, 3, 20); + xstream.alias("child2", Child2.class); + xstream.alias("parent", Parent.class); + + String expectedXml = "" + + "\n" + + " \n" + + " 1\n" + + " \n" + + " 2\n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " \n" + + " 20\n" + + " \n" + + " \n" + + ""; + + assertBothWays(child, expectedXml); + } + + static class MyDate extends java.util.Date { + public MyDate(int time) { + super(time); + } + } + + static class MyHashtable extends java.util.Hashtable { + private String name; + + public MyHashtable(String name) { + this.name = name; + } + + public synchronized boolean equals(Object o) { + return super.equals(o) && ((MyHashtable)o).name.equals(name); + } + } + + public void testSupportsSubclassesOfClassesThatAlreadyHaveConverters() { + MyDate in = new MyDate(1234567890); + String xml = xstream.toXML(in); + assertObjectsEqual(in, xstream.fromXML(xml)); + + MyHashtable in2 = new MyHashtable("hi"); + in2.put("cheese", "curry"); + in2.put("apple", new Integer(3)); + String xml2 = xstream.toXML(in2); + assertObjectsEqual(in2, xstream.fromXML(xml2)); + } + + public static class ObjectWithNamedFields extends StandardObject implements Serializable { + + private String name; + private int number; + private Software someSoftware; + private Object polymorphic; + private Object nothing; + + private static final ObjectStreamField[] serialPersistentFields = { + new ObjectStreamField("theName", String.class), + new ObjectStreamField("theNumber", int.class), + new ObjectStreamField("theSoftware", Software.class), + new ObjectStreamField("thePolymorphic", Object.class), + new ObjectStreamField("theNothing", Object.class) + }; + + private void writeObject(ObjectOutputStream out) throws IOException { + // don't call defaultWriteObject() + ObjectOutputStream.PutField fields = out.putFields(); + fields.put("theName", name); + fields.put("theNumber", number); + fields.put("theSoftware", someSoftware); + fields.put("thePolymorphic", polymorphic); + fields.put("theNothing", nothing); + out.writeFields(); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + // don't call defaultReadObject() + ObjectInputStream.GetField fields = in.readFields(); + name = (String) fields.get("theName", "unknown"); + number = fields.get("theNumber", -1); + someSoftware = (Software) fields.get("theSoftware", null); + polymorphic = fields.get("thePolymorphic", null); + nothing = fields.get("theNothing", null); + } + + } + + public void testAllowsNamedFields() { + ObjectWithNamedFields obj = new ObjectWithNamedFields(); + obj.name = "Joe"; + obj.number = 99; + obj.someSoftware = new Software("tw", "xs"); + obj.polymorphic = new Hardware("small", "ipod"); + obj.nothing = null; + + xstream.alias("with-named-fields", ObjectWithNamedFields.class); + xstream.alias("software", Software.class); + + String expectedXml = "" + + "\n" + + " \n" + + " \n" + + " Joe\n" + + " 99\n" + + " \n" + + " tw\n" + + " xs\n" + + " \n" + + " \n" + + " small\n" + + " ipod\n" + + " \n" + + " \n" + + " \n" + + ""; + + assertBothWays(obj, expectedXml); + } + + public void testUsesDefaultIfNamedFieldNotFound() { + xstream.alias("with-named-fields", ObjectWithNamedFields.class); + xstream.alias("software", Software.class); + + String inputXml = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " tw\n" + + " xs\n" + + " \n" + + " \n" + + " small\n" + + " ipod\n" + + " \n" + + " \n" + + " \n" + + ""; + + ObjectWithNamedFields result = (ObjectWithNamedFields) xstream.fromXML(inputXml); + assertEquals(-1, result.number); + assertEquals("unknown", result.name); + assertEquals(new Software("tw", "xs"), result.someSoftware); + } + + public void testCustomStreamWithNestedCustomStream() { + ObjectWithNamedFields outer = new ObjectWithNamedFields(); + outer.name = "Joe"; + outer.someSoftware = new Software("tw", "xs"); + outer.nothing = null; + + ObjectWithNamedFields inner = new ObjectWithNamedFields(); + inner.name = "Thing"; + + outer.polymorphic = inner; + + xstream.alias("with-named-fields", ObjectWithNamedFields.class); + xstream.alias("software", Software.class); + + String expectedXml = "" + + "\n" + + " \n" + + " \n" + + " Joe\n" + + " 0\n" + + " \n" + + " tw\n" + + " xs\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " Thing\n" + + " 0\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + assertBothWays(outer, expectedXml); + } + + public static class NoDefaultFields extends StandardObject implements Serializable { + + private transient int something; + + public NoDefaultFields() { + } + + public NoDefaultFields(int something) { + this.something = something; + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + something = in.readInt(); + } + + private void writeObject(ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + out.writeInt(something); + } + + } + + public void testObjectWithCallToDefaultWriteButNoDefaultFields() { + xstream.alias("x", NoDefaultFields.class); + + String expectedXml = "" + + "\n" + + " \n" + + " \n" + + " 77\n" + + " \n" + + ""; + assertBothWays(new NoDefaultFields(77), expectedXml); + } + + public void testMaintainsBackwardsCompatabilityWithXStream1_1_0FieldFormat() { + ObjectWithNamedFields outer = new ObjectWithNamedFields(); + outer.name = "Joe"; + outer.someSoftware = new Software("tw", "xs"); + outer.nothing = null; + + ObjectWithNamedFields inner = new ObjectWithNamedFields(); + inner.name = "Thing"; + + outer.polymorphic = inner; + + xstream.alias("with-named-fields", ObjectWithNamedFields.class); + xstream.alias("software", Software.class); + + String oldFormatOfXml = "" + + "\n" + + " \n" + + " \n" + + " Joe\n" + + " 0\n" + + " \n" + + " tw\n" + + " xs\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " Thing\n" + + " 0\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + + assertEquals(outer, xstream.fromXML(oldFormatOfXml)); + } + + public static class ObjectWithNamedThatMatchRealFields extends StandardObject implements Serializable { + + private String name; + private int number; + + private void writeObject(ObjectOutputStream out) throws IOException { + ObjectOutputStream.PutField fields = out.putFields(); + fields.put("name", name.toUpperCase()); + fields.put("number", number * 100); + out.writeFields(); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + ObjectInputStream.GetField fields = in.readFields(); + name = ((String) fields.get("name", "unknown")).toLowerCase(); + number = fields.get("number", 10000) / 100; + } + + } + + public void testSupportsWritingFieldsForObjectsThatDoNotExplicitlyDefineThem() { + xstream.alias("an-object", ObjectWithNamedThatMatchRealFields.class); + + ObjectWithNamedThatMatchRealFields input = new ObjectWithNamedThatMatchRealFields(); + input.name = "a name"; + input.number = 5; + + String expectedXml = "" + + "\n" + + " \n" + + " \n" + + " A NAME\n" + + " 500\n" + + " \n" + + " \n" + + ""; + + assertBothWays(input, expectedXml); + } + + public static class ObjectThatReadsCustomFieldsButDoesNotWriteThem extends StandardObject implements Serializable { + + private String name; + private int number; + + private void writeObject(ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + ObjectInputStream.GetField fields = in.readFields(); + name = ((String) fields.get("name", "unknown")); + number = fields.get("number", 10000); + } + + } + + public void testSupportsGetFieldsWithoutPutFields() { + xstream.alias("an-object", ObjectThatReadsCustomFieldsButDoesNotWriteThem.class); + + ObjectThatReadsCustomFieldsButDoesNotWriteThem input = new ObjectThatReadsCustomFieldsButDoesNotWriteThem(); + input.name = "a name"; + input.number = 5; + + String expectedXml = "" + + "\n" + + " \n" + + " \n" + + " 5\n" + + " a name\n" + + " \n" + + " \n" + + ""; + + assertBothWays(input, expectedXml); + } + + public static class ObjectThatWritesCustomFieldsButDoesNotReadThem extends StandardObject implements Serializable { + + private static final ObjectStreamField[] serialPersistentFields = { + new ObjectStreamField("number", int.class), + new ObjectStreamField("name", String.class), + }; + + private void writeObject(ObjectOutputStream out) throws IOException { + ObjectOutputStream.PutField fields = out.putFields(); + fields.put("name", "test"); + fields.put("number", 42); + out.writeFields(); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + } + + } + + public void testSupportsPutFieldsWithoutGetFields() { + xstream.alias("an-object", ObjectThatWritesCustomFieldsButDoesNotReadThem.class); + + ObjectThatWritesCustomFieldsButDoesNotReadThem input = new ObjectThatWritesCustomFieldsButDoesNotReadThem(); + + String expectedXml = "" + + "\n" + + " \n" + + " \n" + + " test\n" + + " 42\n" + + " \n" + + " \n" + + ""; + + assertBothWays(input, expectedXml); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/DataHolderTest.java b/xstream/src/test/com/thoughtworks/acceptance/DataHolderTest.java new file mode 100644 index 0000000..ef44a8f --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/DataHolderTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. October 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.DataHolder; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; +import com.thoughtworks.xstream.io.xml.XppReader; + +import java.io.StringReader; +import java.io.StringWriter; + +public class DataHolderTest extends AbstractAcceptanceTest { + + class StringWithPrefixConverter implements Converter { + + public boolean canConvert(Class type) { + return type == String.class; + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + String prefix = (String) context.get("prefix"); + if (prefix != null) { + writer.addAttribute("prefix", prefix); + } + writer.setValue(source.toString()); + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + context.put("saw-this", reader.getAttribute("can-you-see-me")); + return reader.getValue(); + } + + } + + public void testCanBePassedInToMarshallerExternally() { + // setup + xstream.registerConverter(new StringWithPrefixConverter()); + StringWriter writer = new StringWriter(); + DataHolder dataHolder = xstream.newDataHolder(); + + // execute + dataHolder.put("prefix", "additional stuff"); + xstream.marshal("something", new PrettyPrintWriter(writer), dataHolder); + + // verify + String expected = "something"; + assertEquals(expected, writer.toString()); + } + + public void testCanBePassedInToUnmarshallerExternally() { + // setup + xstream.registerConverter(new StringWithPrefixConverter()); + DataHolder dataHolder = xstream.newDataHolder(); + + // execute + String xml = "something"; + Object result = xstream.unmarshal(new XppReader(new StringReader(xml)), null, dataHolder); + + // verify + assertEquals("something", result); + assertEquals("yes", dataHolder.get("saw-this")); + } + + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/DefaultImplementationTest.java b/xstream/src/test/com/thoughtworks/acceptance/DefaultImplementationTest.java new file mode 100644 index 0000000..14952ee --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/DefaultImplementationTest.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 08. July 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.testutil.TimeZoneChanger; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; +import java.util.TimeZone; + +public class DefaultImplementationTest extends AbstractAcceptanceTest { + + + public static class Farm extends StandardObject { + int size; + List animals = new ArrayList(); + String name; + + public Farm(int size, String name) { + this.size = size; + this.name = name; + } + + public void add(Animal animal) { + animals.add(animal); + } + } + + public static class Animal extends StandardObject { + String name; + + public Animal(String name) { + this.name = name; + } + } + + protected void setUp() throws Exception { + super.setUp(); + TimeZoneChanger.change("GMT"); + xstream.alias("farm", Farm.class); + xstream.alias("animal", Animal.class); + xstream.alias("age", Age.class); + } + + /** + * @see junit.framework.TestCase#tearDown() + */ + protected void tearDown() throws Exception { + TimeZoneChanger.reset(); + super.tearDown(); + } + + public void testArrayList() { + Farm farm = new Farm(100, "Old McDonald's"); + farm.add(new Animal("Cow")); + farm.add(new Animal("Sheep")); + + String expected = "" + + "\n" + + " 100\n" + + " \n" + + " \n" + + " Cow\n" + + " \n" + + " \n" + + " Sheep\n" + + " \n" + + " \n" + + " Old McDonald's\n" + + ""; + + assertBothWays(farm, expected); + } + + public static class Age extends StandardObject { + java.util.Date date; + + public Age(java.util.Date age) { + this.date = age; + } + } + + public void testCustomDate() { + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + cal.clear(); + cal.set(2007, Calendar.DECEMBER, 18); + Age age = new Age(new java.sql.Date(cal.getTime().getTime())); + + xstream.addDefaultImplementation(java.sql.Date.class, java.util.Date.class); + + String expected = "" + + "\n" + + " 2007-12-18\n" + + ""; + + assertBothWays(age, expected); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/DynamicProxyTest.java b/xstream/src/test/com/thoughtworks/acceptance/DynamicProxyTest.java new file mode 100644 index 0000000..aa79630 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/DynamicProxyTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2004, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2010, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 25. March 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import java.util.ArrayList; +import java.util.List; + +import com.thoughtworks.acceptance.objects.SampleDynamicProxy; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.security.ProxyTypePermission; + + +public class DynamicProxyTest extends AbstractAcceptanceTest { + public static class ClassWithProxyMember { + SampleDynamicProxy.InterfaceOne one; + SampleDynamicProxy.InterfaceTwo two; + }; + + protected void setupSecurity(XStream xstream) { + super.setupSecurity(xstream); + xstream.addPermission(ProxyTypePermission.PROXIES); + } + + public void testCanBeMarshaled() { + assertBothWays( + SampleDynamicProxy.newInstance(), + "" + + "\n" + + " com.thoughtworks.acceptance.objects.SampleDynamicProxy$InterfaceOne\n" + + " com.thoughtworks.acceptance.objects.SampleDynamicProxy$InterfaceTwo\n" + + " \n" + + " hello\n" + + " \n" + + ""); + } + + public void testAsFieldMember() { + ClassWithProxyMember expected = new ClassWithProxyMember(); + expected.one = (SampleDynamicProxy.InterfaceOne)SampleDynamicProxy.newInstance(); + expected.two = (SampleDynamicProxy.InterfaceTwo)expected.one; + xstream.alias("with-proxy", ClassWithProxyMember.class); + assertBothWays( + expected, + "" + + "\n" + + " \n" + + " com.thoughtworks.acceptance.objects.SampleDynamicProxy$InterfaceOne\n" + + " com.thoughtworks.acceptance.objects.SampleDynamicProxy$InterfaceTwo\n" + + " \n" + + " hello\n" + + " \n" + + " \n" + + " \n" + + ""); + } + + public void testTypeCanBeAliased() { + xstream.aliasType("one", SampleDynamicProxy.InterfaceOne.class); + xstream.alias("two", SampleDynamicProxy.InterfaceTwo.class); + xstream.alias("handler", SampleDynamicProxy.class); + String expected = "" + + "\n" + + " one\n" + + " two\n" + + " \n" + + " hello\n" + + " \n" + + ""; + assertEquals(expected, xstream.toXML(SampleDynamicProxy.newInstance())); + } + + public void testCanBeReferenced() { + List list = new ArrayList(); + Object proxy = SampleDynamicProxy.newInstance(list); + list.add(proxy); + assertBothWays( + proxy, + "" + + "\n" + + " com.thoughtworks.acceptance.objects.SampleDynamicProxy$InterfaceOne\n" + + " com.thoughtworks.acceptance.objects.SampleDynamicProxy$InterfaceTwo\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/EncodingTestSuite.java b/xstream/src/test/com/thoughtworks/acceptance/EncodingTestSuite.java new file mode 100644 index 0000000..7b99f2c --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/EncodingTestSuite.java @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 25. June 2006 by Guilherme Silveira + */ +package com.thoughtworks.acceptance; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.util.Properties; + +import javax.xml.stream.XMLInputFactory; + +import junit.framework.Assert; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import com.bea.xml.stream.MXParserFactory; +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.HierarchicalStreamDriver; +import com.thoughtworks.xstream.io.xml.Dom4JDriver; +import com.thoughtworks.xstream.io.xml.DomDriver; +import com.thoughtworks.xstream.io.xml.JDomDriver; +import com.thoughtworks.xstream.io.xml.StaxDriver; +import com.thoughtworks.xstream.io.xml.XomDriver; +import com.thoughtworks.xstream.io.xml.XppDomDriver; +import com.thoughtworks.xstream.io.xml.XppDriver; + + +/** + * @author Sanjiv Jivan + * @author Guilherme Silveira + * @author Jörg Schaible + */ +public class EncodingTestSuite extends TestSuite { + + public static class TestObject extends StandardObject { + private String data; + } + + public EncodingTestSuite() { + super(EncodingTestSuite.class.getName()); + addDriverTest(new Dom4JDriver()); + addDriverTest(new DomDriver()); + addDriverTest(new JDomDriver()); + addDriverTest(new StaxDriver()); + addDriverTest(new XppDomDriver()); + addDriverTest(new XppDriver()); + addDriverTest(new XomDriver()); + } + + private void test(HierarchicalStreamDriver driver, String encoding) throws IOException { + String headerLine = encoding != null + ? ("\n") + : ""; + String xmlData = headerLine // force code format + + "\n" + + " J\u00f6rg\n" + + ""; + + XStream xstream = new XStream(driver); + xstream.alias("test", TestObject.class); + TestObject obj = new TestObject(); + obj.data = "J\u00f6rg"; + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + OutputStreamWriter writer = encoding != null + ? new OutputStreamWriter(bos, encoding) + : new OutputStreamWriter(bos); + xstream.toXML(obj, writer); + writer.close(); + + String generated = encoding != null ? bos.toString(encoding) : bos.toString(); + Assert.assertTrue("'" + obj.data + "' was not found", generated.indexOf(obj.data) > 0); + + Object restored = xstream.fromXML(new ByteArrayInputStream(encoding != null ? xmlData + .getBytes(encoding) : xmlData.getBytes())); + Assert.assertEquals(obj, restored); + } + + private void addDriverTest(final HierarchicalStreamDriver driver) { + String testName = getShortName(driver); + final String allEncodingTests = System.getProperty("xstream.test.encoding.all"); + if ("true".equals(allEncodingTests)) { + // Native encoding normally fails on most systems!! + addTest(new TestCase(testName + "Native") { + protected void runTest() throws Throwable { + test(driver, null); + } + }); + // System encoding fails on US-ASCII systems, like Codehaus Bamboo + final String systemEncoding = System.getProperty("file.encoding"); + addTest(new TestCase(testName + "With" + systemEncoding + "SystemEncoding") { + protected void runTest() throws Throwable { + final Properties systemProperties = new Properties(); + systemProperties.putAll(System.getProperties()); + try { + // Use BEA reference implementation for StAX + // (Woodstox will fail on Windows because of unknown system encoding) + System.setProperty( + XMLInputFactory.class.getName(), MXParserFactory.class.getName()); + test(driver, systemEncoding); + } finally { + System.setProperties(systemProperties); + } + } + }); + } + addTest(new TestCase(testName + "WithUTF_8Encoding") { + protected void runTest() throws Throwable { + test(driver, "UTF-8"); + } + }); + addTest(new TestCase(testName + "WithIS0_8859_1Encoding") { + protected void runTest() throws Throwable { + test(driver, "ISO-8859-1"); + } + }); + } + + private String getShortName(HierarchicalStreamDriver driver) { + String result = driver.getClass().getName(); + result = result.substring(result.lastIndexOf('.') + 1); + return result; + } + + public static Test suite() { + return new EncodingTestSuite(); + } + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/ErrorTest.java b/xstream/src/test/com/thoughtworks/acceptance/ErrorTest.java new file mode 100644 index 0000000..13f3abb --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/ErrorTest.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 08. May 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.io.StreamException; + +public class ErrorTest extends AbstractAcceptanceTest { + + public static class Thing { + String one; + int two; + } + + protected void setUp() throws Exception { + super.setUp(); + xstream.alias("thing", Thing.class); + } + + public void testUnmarshallerThrowsExceptionWithDebuggingInfo() { + try { + xstream.fromXML("" + + "\n" + + " string 1\n" + + " another string\n" + + ""); + fail("Error expected"); + } catch (ConversionException e) { + assertEquals("java.lang.NumberFormatException", + e.get("cause-exception")); + if (JVM.is14()) { + assertEquals("For input string: \"another string\"", + e.get("cause-message")); + } else { + assertEquals("another string", + e.get("cause-message")); + } + assertEquals(Integer.class.getName(), + e.get("class")); + assertEquals("/thing/two", + e.get("path")); + assertEquals("3", + e.get("line number")); + assertEquals("java.lang.Integer", + e.get("required-type")); + assertEquals(Thing.class.getName(), + e.get("class[1]")); + } + } + + public void testInvalidXml() { + try { + xstream.fromXML("" + + "\n" + + " string 1\n" + + " <<\n" + + ""); + fail("Error expected"); + } catch (ConversionException e) { + assertEquals(StreamException.class.getName(), + e.get("cause-exception")); + assertNotNull(e.get("cause-message")); // depends on parser + assertEquals("/thing/two", + e.get("path")); + assertEquals("3", + e.get("line number")); + } + } + + public void testNonExistingMember() { + try { + xstream.fromXML("" + + "\n" + + " string 1\n" + + " 3\n" + + ""); + fail("Error expected"); + } catch (ConversionException e) { + assertEquals("three", + e.get("field")); + assertEquals("/thing/three", + e.get("path")); + assertEquals("3", + e.get("line number")); + } + } + + public void testNonExistingMemberMatchingAlias() { + try { + xstream.fromXML("" + + "\n" + + " string 1\n" + + ""); + fail("Error expected"); + } catch (ConversionException e) { + assertEquals("/thing/string", + e.get("path")); + assertEquals("2", + e.get("line number")); + } + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/Extended14TypesTest.java b/xstream/src/test/com/thoughtworks/acceptance/Extended14TypesTest.java new file mode 100644 index 0000000..632e1f5 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/Extended14TypesTest.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2006, 2007, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 12. January 2006 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.testutil.TimeZoneChanger; + +import javax.security.auth.Subject; +import javax.security.auth.x500.X500Principal; + +import java.nio.charset.Charset; +import java.security.Principal; +import java.util.Calendar; +import java.util.Currency; +import java.util.Locale; +import java.util.TimeZone; +import java.util.regex.Pattern; + +public class Extended14TypesTest extends AbstractAcceptanceTest { + + protected void setUp() throws Exception { + super.setUp(); + + // Ensure that this test always run as if it were in the EST timezone. + // This prevents failures when running the tests in different zones. + // Note: 'EST' has no relevance - it was just a randomly chosen zone. + TimeZoneChanger.change("EST"); + } + + protected void tearDown() throws Exception { + TimeZoneChanger.reset(); + super.tearDown(); + } + + public void testLocaleWithVariant() { + assertBothWays(new Locale("zh", "CN", "cc"), "zh_CN_cc"); + assertBothWays(new Locale("zh", "", "cc"), "zh__cc"); + } + + public void testCurrency() { + assertBothWays(Currency.getInstance("USD"), "USD"); + } + + public void testGregorianCalendar() { + Calendar in = Calendar.getInstance(); + in.setTimeZone(TimeZone.getTimeZone("AST")); + in.setTimeInMillis(44444); + String expected = "" + + "\n" + + " \n" + + " AST\n" + + ""; + Calendar out = (Calendar) assertBothWays(in, expected); + assertEquals(in.getTime(), out.getTime()); + assertEquals(TimeZone.getTimeZone("AST"), out.getTimeZone()); + } + + public void testGregorianCalendarCompat() { // compatibility to 1.1.2 and below + Calendar in = Calendar.getInstance(); + in.setTimeInMillis(44444); + String oldXML = "" + + "\n" + + " \n" + + ""; + Calendar out = (Calendar) xstream.fromXML(oldXML); + assertEquals(in.getTime(), out.getTime()); + assertEquals(TimeZone.getTimeZone("EST"), out.getTimeZone()); + } + + public void testRegexPattern() { + // setup + Pattern pattern = Pattern.compile("^[ae]*$", Pattern.MULTILINE | Pattern.UNIX_LINES); + String expectedXml = "" + + "\n" + + " ^[ae]*$\n" + + " 9\n" + + ""; + + // execute + String actualXml = xstream.toXML(pattern); + Pattern result = (Pattern) xstream.fromXML(actualXml); + + // verify + assertEquals(expectedXml, actualXml); + assertEquals(pattern.pattern(), result.pattern()); + assertEquals(pattern.flags(), result.flags()); + + assertFalse("regex should not hava matched", result.matcher("oooo").matches()); + assertTrue("regex should have matched", result.matcher("aeae").matches()); + } + + public void testSubject() { + xstream.allowTypes(new Class[]{Subject.class}); + xstream.allowTypeHierarchy(Principal.class); + + Subject subject = new Subject(); + Principal principal = new X500Principal("c=uk, o=Thoughtworks, ou=XStream"); + subject.getPrincipals().add(principal); + String expectedXml = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " MDYxEDAOBgNVBAsTB1hTdHJlYW0xFTATBgNVBAoTDFRob3VnaHR3b3JrczELMAkGA1UEBhMCdWs=\n\n" + + " \n" + + " \n" + + " \n" + + " false\n" + + ""; + + assertBothWays(subject, expectedXml); + } + + public void testCharset() { + Charset charset = Charset.forName("utf-8"); + String expectedXml = "UTF-8"; + + assertBothWays(charset, expectedXml); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/ExtendedTypesTest.java b/xstream/src/test/com/thoughtworks/acceptance/ExtendedTypesTest.java new file mode 100644 index 0000000..af41ac2 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/ExtendedTypesTest.java @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2003, 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2012, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. October 2003 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.testutil.TimeZoneChanger; + +import org.jdom.Element; + +import java.awt.Color; +import java.io.File; +import java.io.IOException; +import java.sql.Date; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Locale; + +public class ExtendedTypesTest extends AbstractAcceptanceTest { + + protected void setUp() throws Exception { + super.setUp(); + xstream.allowTypes(new Class[]{Element.class, Date.class, Time.class, Timestamp.class}); + + // Ensure that this test always run as if it were in the EST timezone. + // This prevents failures when running the tests in different zones. + // Note: 'EST' has no relevance - it was just a randomly chosen zone. + TimeZoneChanger.change("EST"); + } + + protected void tearDown() throws Exception { + TimeZoneChanger.reset(); + super.tearDown(); + } + + public void testAwtColor() { + boolean isHeadless = Boolean.valueOf(System.getProperty("java.awt.headless", "false")).booleanValue(); + if (!isHeadless || JVM.is15()) { + xstream.allowTypes(new Class[]{Color.class}); + Color color = new Color(0, 10, 20, 30); + + String expected = "" + + "\n" + + " 0\n" + + " 10\n" + + " 20\n" + + " 30\n" + + ""; + + assertBothWays(color, expected); + } + } + + public void testSqlTimestamp() { + Timestamp timestamp = new Timestamp(1234); + timestamp.setNanos(78900); + assertBothWays(timestamp, + "1970-01-01 00:00:01.0000789"); + } + + public void testSqlTime() { + assertBothWays(new Time(14, 7, 33), + "14:07:33"); + } + + public void testSqlDate() { + assertBothWays(new Date(78, 7, 25), + "1978-08-25"); + } + + public void testFile() throws IOException { + // using temp file to avoid os specific or directory layout issues + File absFile = File.createTempFile("bleh", ".tmp"); + absFile.deleteOnExit(); + assertTrue(absFile.isAbsolute()); + String expectedXml = "" + absFile.getPath() + ""; + assertFilesBothWay(absFile, expectedXml); + + // test a relative file now + File relFile = new File("bloh.tmp"); + relFile.deleteOnExit(); + assertFalse(relFile.isAbsolute()); + expectedXml = "" + relFile.getPath() + ""; + assertFilesBothWay(relFile, expectedXml); + } + + private void assertFilesBothWay(File f, String expectedXml) { + String resultXml = xstream.toXML(f); + assertEquals(expectedXml, resultXml); + Object resultObj = xstream.fromXML(resultXml); + assertEquals(File.class, resultObj.getClass()); + assertEquals(f, resultObj); + // now comes the part that fails without a specific converter + // in the case of a relative file, this will work, because we run the comparison test from the same working directory + assertEquals(f.getAbsolutePath(), ((File)resultObj).getAbsolutePath()); + assertEquals(f.isAbsolute(), ((File)resultObj).isAbsolute()); // needed because File's equals method only compares the path getAttribute, at least in the win32 implementation + } + + public void testLocale() { + assertBothWays(new Locale("zh", "", ""), "zh"); + assertBothWays(new Locale("zh", "CN", ""), "zh_CN"); + } + + public void testCanHandleJDomElement() { + Element element = new Element("JUnit"); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " 0\n" + + " \n" + + " \n" + + " \n" + + " 0\n" + + " \n" + + " \n" + + " JUnit\n" + + " \n" + + " \n" + + " \n" + + " 0\n" + + " \n" + + ""; + + assertBothWays(element, expected); + } + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/ExternalizableTest.java b/xstream/src/test/com/thoughtworks/acceptance/ExternalizableTest.java new file mode 100644 index 0000000..f1e6147 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/ExternalizableTest.java @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2010, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. August 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.OwnerOfExternalizable; +import com.thoughtworks.acceptance.objects.SomethingExternalizable; +import com.thoughtworks.acceptance.objects.StandardObject; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; + +public class ExternalizableTest extends AbstractAcceptanceTest { + + public void testExternalizable() { + xstream.alias("something", SomethingExternalizable.class); + + SomethingExternalizable in = new SomethingExternalizable("Joe", "Walnes"); + + String expected = "" + + "\n" + + " 3\n" + + " JoeWalnes\n" + + " \n" + + " XStream\n" + + ""; + + assertBothWays(in, expected); + } + + public void testExternalizableAsFieldOfAnotherObject() { + xstream.alias("something", SomethingExternalizable.class); + xstream.alias("owner", OwnerOfExternalizable.class); + + OwnerOfExternalizable in = new OwnerOfExternalizable(); + in.target = new SomethingExternalizable("Joe", "Walnes"); + + String expected = "" + + "\n" + + " \n" + + " 3\n" + + " JoeWalnes\n" + + " \n" + + " XStream\n" + + " \n" + + ""; + + assertBothWays(in, expected); + } + + public static class CircularExternalizable implements Externalizable { + private String name; + private CircularExternalizable parent; + private CircularExternalizable child; + + public CircularExternalizable() { + } + + public CircularExternalizable(String name) { + this.name = name; + } + + public void setParent(CircularExternalizable parent) { + this.parent = parent; + if (parent != null) { + parent.child = this; + } + } + + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + name = (String)in.readObject(); + parent = (CircularExternalizable)in.readObject(); + child = (CircularExternalizable)in.readObject(); + } + + public void writeExternal(ObjectOutput out) throws IOException { + out.writeObject(name); + out.writeObject(parent); + out.writeObject(child); + } + + // StandardObject uses EqualsBuilder.reflectionEquals of commons-lang, + // that does not handle circular dependencies + public boolean equals(Object obj) { + return obj instanceof CircularExternalizable && name.equals(obj.toString()); + } + + public int hashCode() { + return name.hashCode()+1; + } + + public String toString() { + return name; + } + + } + + public void testCircularExternalizable() { + xstream.alias("elem", CircularExternalizable.class); + + CircularExternalizable parent = new CircularExternalizable("parent"); + CircularExternalizable child = new CircularExternalizable("child"); + child.setParent(parent); + + String expected = "" + + "\n" + + " parent\n" + + " \n" + + " \n" + + " child\n" + + " \n" + + " \n" + + " \n" + + ""; + + assertBothWays(parent, expected); + } + + public static class OtherOwner extends StandardObject { + Object member1; + Object member2; + public OtherOwner(int i) { + member1 = new InnerExternalizable1(i); + member2 = new InnerExternalizable2(i); + } + + private static class InnerExternalizable1 extends StandardObject implements Externalizable { + private int i; + + public InnerExternalizable1() { + } + + InnerExternalizable1(int i) { + this.i = i; + } + + public void writeExternal(ObjectOutput out) throws IOException { + out.writeInt(i); + } + + public void readExternal(ObjectInput in) + throws IOException { + this.i = in.readInt(); + } + }; + + private static class InnerExternalizable2 extends StandardObject implements Externalizable { + private int i; + + private InnerExternalizable2() { + } + + InnerExternalizable2(int i) { + this.i = i; + } + + public void writeExternal(ObjectOutput out) throws IOException { + out.writeInt(i); + } + + public void readExternal(ObjectInput in) + throws IOException { + this.i = in.readInt(); + } + }; + } + + public void testWithPrivateDefaultConstructor() { + String name1 = OtherOwner.class.getDeclaredClasses()[0].getName(); + String name2 = OtherOwner.class.getDeclaredClasses()[1].getName(); + xstream.alias("owner", OtherOwner.class); + xstream.alias("inner" + name1.charAt(name1.length() - 1), + OtherOwner.class.getDeclaredClasses()[0]); + xstream.alias("inner" + name2.charAt(name2.length() - 1), + OtherOwner.class.getDeclaredClasses()[1]); + + OtherOwner owner = new OtherOwner(42); + + String expected = "" + + "\n" + + " \n" + + " 42\n" + + " \n" + + " \n" + + " 42\n" + + " \n" + + ""; + + assertBothWays(owner, expected); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/FinalFieldsTest.java b/xstream/src/test/com/thoughtworks/acceptance/FinalFieldsTest.java new file mode 100644 index 0000000..ea8d806 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/FinalFieldsTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 09. May 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; +import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; +import com.thoughtworks.xstream.core.JVM; + +public class FinalFieldsTest extends AbstractAcceptanceTest { + + static class ThingWithFinalField extends StandardObject { + final int number = 9; + } + + public void testSerializeFinalFieldsIfSupported() { + xstream = new XStream(JVM.newReflectionProvider()); + setupSecurity(xstream); + xstream.alias("thing", ThingWithFinalField.class); + + assertBothWays(new ThingWithFinalField(), + "\n" + + " 9\n" + + ""); + } + + public void testExceptionThrownUponSerializationIfNotSupport() { + xstream = new XStream(new PureJavaReflectionProvider()); + xstream.alias("thing", ThingWithFinalField.class); + + try { + xstream.toXML(new ThingWithFinalField()); + if (!JVM.is15()) { + fail("Expected exception"); + } + } catch (ObjectAccessException expectedException) { + assertEquals("Invalid final field " + ThingWithFinalField.class.getName() + ".number", + expectedException.getMessage()); + } + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/IDReferenceTest.java b/xstream/src/test/com/thoughtworks/acceptance/IDReferenceTest.java new file mode 100644 index 0000000..11d0b1d --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/IDReferenceTest.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2010 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. July 2011 by Joerg Schaible by merging IDCircularReferenceTest, + * IDDuplicateReferenceTest, IDNestedCircularReferenceTest and + * IDReplacedReferenceTest. + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.util.ArrayList; +import java.util.List; + +public class IDReferenceTest extends AbstractReferenceTest { + + // tests inherited from superclass + + protected void setUp() throws Exception { + super.setUp(); + xstream.setMode(XStream.ID_REFERENCES); + } + + public void testXmlContainsReferenceIds() { + + Thing sameThing = new Thing("hello"); + Thing anotherThing = new Thing("hello"); + + List list = new ArrayList(); + list.add(sameThing); + list.add(sameThing); + list.add(anotherThing); + + String expected = "" + + "\n" + + " \n" + + " hello\n" + + " \n" + + " \n" + + " \n" + + " hello\n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(list)); + } + + public void testCircularReferenceXml() { + Person bob = new Person("bob"); + Person jane = new Person("jane"); + bob.likes = jane; + jane.likes = bob; + + String expected = "" + + "\n" + + " bob\n" + + " \n" + + " jane\n" + + " \n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(bob)); + } + + public void testCircularReferenceToSelfXml() { + Person bob = new Person("bob"); + bob.likes = bob; + + String expected = "" + + "\n" + + " bob\n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(bob)); + } + + public void testReplacedReference() { + String expectedXml = "" + + "\n" + + " parent\n" + + " \n" + + " \n" + + " child\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + replacedReference(expectedXml); + } + + public void testCanReferenceDeserializedNullValues() { + xstream.alias("test", Mapper.Null.class); + String xml = "" + + "\n" + + " \n" + + " \n" + + ""; + List list = (List)xstream.fromXML(xml); + assertEquals(2, list.size()); + assertNull(list.get(0)); + assertNull(list.get(1)); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/ImplicitArrayTest.java b/xstream/src/test/com/thoughtworks/acceptance/ImplicitArrayTest.java new file mode 100644 index 0000000..b98c519 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/ImplicitArrayTest.java @@ -0,0 +1,583 @@ +/* + * Copyright (C) 2011, 2012, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. July 2011 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.InitializationException; + +/** + * @author Jörg Schaible + */ +public class ImplicitArrayTest extends AbstractAcceptanceTest { + + protected void setUp() throws Exception { + super.setUp(); + xstream.alias("farm", Farm.class); + xstream.alias("animal", Animal.class); + xstream.alias("MEGA-farm", MegaFarm.class); + xstream.ignoreUnknownElements(); + } + + public static class Farm extends StandardObject { + private transient int idx; + Animal[] animals; + } + + public static class Animal extends StandardObject implements Comparable { + String name; + + public Animal(String name) { + this.name = name; + } + + public int compareTo(Object o) { + return name.compareTo(((Animal)o).name); + } + } + + public void testWithDirectType() { + Farm farm = new Farm(); + farm.animals = new Animal[] { + new Animal("Cow"), + new Animal("Sheep") + }; + + String expected = "" + + "\n" + + " \n" + + " Cow\n" + + " \n" + + " \n" + + " Sheep\n" + + " \n" + + ""; + + xstream.addImplicitArray(Farm.class, "animals"); + assertBothWays(farm, expected); + } + + public static class MegaFarm extends Farm { + String separator = "---"; + String[] names; + } + + public void testInheritsImplicitArrayFromSuperclass() { + Farm farm = new MegaFarm(); // subclass + farm.animals = new Animal[] { + new Animal("Cow"), + new Animal("Sheep") + }; + + String expected = "" + + "\n" + + " \n" + + " Cow\n" + + " \n" + + " \n" + + " Sheep\n" + + " \n" + + " ---\n" + + ""; + + xstream.addImplicitCollection(Farm.class, "animals"); + assertBothWays(farm, expected); + } + + public void testSupportsInheritedAndDirectDeclaredImplicitArraysAtOnce() { + MegaFarm farm = new MegaFarm(); // subclass + farm.animals = new Animal[] { + new Animal("Cow"), + new Animal("Sheep") + }; + farm.names = new String[] { + "McDonald", + "Ponte Rosa" + }; + + String expected = "" + + "\n" + + " \n" + + " Cow\n" + + " \n" + + " \n" + + " Sheep\n" + + " \n" + + " ---\n" + + " McDonald\n" + + " Ponte Rosa\n" + + ""; + + xstream.addImplicitArray(Farm.class, "animals"); + xstream.addImplicitArray(MegaFarm.class, "names", "name"); + assertBothWays(farm, expected); + } + + public void testInheritedAndDirectDeclaredImplicitArraysAtOnceIsNotDeclarationSequenceDependent() { + MegaFarm farm = new MegaFarm(); // subclass + farm.animals = new Animal[] { + new Animal("Cow"), + new Animal("Sheep") + }; + farm.names = new String[] { + "McDonald", + "Ponte Rosa" + }; + + String expected = "" + + "\n" + + " \n" + + " Cow\n" + + " \n" + + " \n" + + " Sheep\n" + + " \n" + + " ---\n" + + " McDonald\n" + + " Ponte Rosa\n" + + ""; + + xstream.addImplicitArray(MegaFarm.class, "names", "name"); + xstream.addImplicitArray(Farm.class, "animals"); + assertBothWays(farm, expected); + } + + public void testAllowsSubclassToOverrideImplicitCollectionInSuperclass() { + Farm farm = new MegaFarm(); // subclass + farm.animals = new Animal[] { + new Animal("Cow"), + new Animal("Sheep") + }; + + String expected = "" + + "\n" + + " \n" + + " Cow\n" + + " \n" + + " \n" + + " Sheep\n" + + " \n" + + " ---\n" + + ""; + + xstream.addImplicitCollection(MegaFarm.class, "animals"); + assertBothWays(farm, expected); + } + + public void testAllowDifferentImplicitArrayDefinitionsInSubclass() { + Farm farm = new Farm(); + farm.animals = new Animal[] { + new Animal("Cod"), + new Animal("Salmon") + }; + MegaFarm megaFarm = new MegaFarm(); // subclass + megaFarm.animals = new Animal[] { + new Animal("Cow"), + new Animal("Sheep") + }; + megaFarm.names = new String[] { + "McDonald", + "Ponte Rosa" + }; + + List list = new ArrayList(); + list.add(farm); + list.add(megaFarm); + String expected = "" + + "\n" + + " \n" + + " \n" + + " Cod\n" + + " \n" + + " \n" + + " Salmon\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " Cow\n" + + " \n" + + " \n" + + " Sheep\n" + + " \n" + + " ---\n" + + " McDonald\n" + + " Ponte Rosa\n" + + " \n" + + ""; + + xstream.addImplicitArray(Farm.class, "animals", "fish"); + xstream.addImplicitArray(MegaFarm.class, "animals"); + xstream.addImplicitArray(MegaFarm.class, "names", "name"); + assertBothWays(list, expected); + } + + public static class House extends StandardObject { + private Room[] rooms; + private String separator = "---"; + private Person[] people; + + public List getPeople() { + return Arrays.asList(people); + } + + public List getRooms() { + return Arrays.asList(rooms); + } + } + + public static class Room extends StandardObject { + private String name; + + public Room(String name) { + this.name = name; + } + } + + public static class Person extends StandardObject { + private String name; + private String[] emailAddresses; + + public Person(String name) { + this.name = name; + } + } + + public void testMultipleArraysBasedOnDifferentType() { + House house = new House(); + house.rooms = new Room[] { + new Room("kitchen"), + new Room("bathroom") + }; + Person joe = new Person("joe"); + joe.emailAddresses = new String[]{ + "joe@house.org", + "joe.farmer@house.org" + }; + Person jaimie = new Person("jaimie"); + jaimie.emailAddresses = new String[]{ + "jaimie@house.org", + "jaimie.farmer@house.org", + "jaimie.ann.farmer@house.org" + }; + house.people = new Person[]{ + joe, + jaimie + }; + + String expected = "" + + "\n" + + " \n" + + " kitchen\n" + + " \n" + + " \n" + + " bathroom\n" + + " \n" + + " ---\n" + + " \n" + + " joe\n" + + " joe@house.org\n" + + " joe.farmer@house.org\n" + + " \n" + + " \n" + + " jaimie\n" + + " jaimie@house.org\n" + + " jaimie.farmer@house.org\n" + + " jaimie.ann.farmer@house.org\n" + + " \n" + + ""; + + xstream.alias("room", Room.class); + xstream.alias("house", House.class); + xstream.alias("person", Person.class); + xstream.addImplicitArray(House.class, "rooms"); + xstream.addImplicitArray(House.class, "people"); + xstream.addImplicitArray(Person.class, "emailAddresses", "email"); + + House serializedHouse = (House)assertBothWays(house, expected); + assertEquals(house.getPeople(), serializedHouse.getPeople()); + assertEquals(house.getRooms(), serializedHouse.getRooms()); + } + + public static class NumberedRoom extends Room { + private int number; + + public NumberedRoom(int number) { + super("room"); + this.number = number; + } + } + + public void testArraysWithDerivedElements() { + House house = new House(); + house.rooms = new Room[] { + new Room("kitchen"), + new NumberedRoom(13) + }; + + String expected = "" + + "\n" + + " \n" + + " kitchen\n" + + " \n" + + " \n" + + " room\n" + + " \n" + + " ---\n" + + ""; + + xstream.alias("house", House.class); + xstream.alias("chamber", NumberedRoom.class); + xstream.addImplicitArray(House.class, "rooms", "room"); + xstream.useAttributeFor(int.class); + + House serializedHouse = (House)assertBothWays(house, expected); + assertEquals(house.getRooms(), serializedHouse.getRooms()); + } + + public static class Aquarium extends StandardObject { + private String name; + private String[] fish; + + public Aquarium(String name) { + this.name = name; + } + } + + public void testWithExplicitItemNameMatchingTheNameOfTheFieldWithTheArray() { + Aquarium aquarium = new Aquarium("hatchery"); + aquarium.fish = new String[]{ + "salmon", + "halibut", + "snapper" + }; + + String expected = "" + + "\n" + + " hatchery\n" + + " salmon\n" + + " halibut\n" + + " snapper\n" + + ""; + + xstream.alias("aquarium", Aquarium.class); + xstream.addImplicitArray(Aquarium.class, "fish", "fish"); + + assertBothWays(aquarium, expected); + } + + public void testWithImplicitNameMatchingTheNameOfTheFieldWithTheArray() { + Aquarium aquarium = new Aquarium("hatchery"); + aquarium.fish = new String[]{ + "salmon", + "halibut", + "snapper" + }; + + String expected = "" + + "\n" + + " hatchery\n" + + " salmon\n" + + " halibut\n" + + " snapper\n" + + ""; + + xstream.alias("aquarium", Aquarium.class); + xstream.alias("fish", String.class); + xstream.addImplicitArray(Aquarium.class, "fish"); + + assertBothWays(aquarium, expected); + } + + public void testWithAliasedItemNameMatchingTheAliasedNameOfTheFieldWithTheArray() { + Aquarium aquarium = new Aquarium("hatchery"); + aquarium.fish = new String[]{ + "salmon", + "halibut", + "snapper" + }; + + String expected = "" + + "\n" + + " hatchery\n" + + " salmon\n" + + " halibut\n" + + " snapper\n" + + ""; + + xstream.alias("aquarium", Aquarium.class); + xstream.aliasField("animal", Aquarium.class, "fish"); + xstream.addImplicitArray(Aquarium.class, "fish", "animal"); + + assertBothWays(aquarium, expected); + } + + public void testCanBeDeclaredOnlyForMatchingType() { + try { + xstream.addImplicitArray(Animal.class, "name"); + fail("Thrown " + InitializationException.class.getName() + " expected"); + } catch (final InitializationException e) { + assertTrue(e.getMessage().indexOf("declares no collection") >= 0); + } + } + + public void testCanBeDeclaredOnlyForMatchingComponentType() { + try { + xstream.addImplicitArray(Aquarium.class, "fish", Farm.class); + fail("Thrown " + InitializationException.class.getName() + " expected"); + } catch (final InitializationException e) { + assertTrue(e.getMessage().indexOf("array type is not compatible") >= 0); + } + } + + public void testWithNullElement() { + Farm farm = new Farm(); + farm.animals = new Animal[] { + new Animal("Cow"), + null, + new Animal("Sheep") + }; + + String expected = "" + + "\n" + + " \n" + + " Cow\n" + + " \n" + + " \n" + + " \n" + + " Sheep\n" + + " \n" + + ""; + + xstream.addImplicitArray(Farm.class, "animals"); + assertBothWays(farm, expected); + } + + public void testWithAliasAndNullElement() { + Farm farm = new Farm(); + farm.animals = new Animal[] { + null, + new Animal("Sheep") + }; + + String expected = "" + + "\n" + + " \n" + + " \n" + + " Sheep\n" + + " \n" + + ""; + + xstream.addImplicitArray(Farm.class, "animals", "beast"); + assertBothWays(farm, expected); + } + + static class PrimitiveArray { + int[] ints; + }; + + public void testWithPrimitiveArray() { + PrimitiveArray pa = new PrimitiveArray(); + pa.ints = new int[]{ 47, 11 }; + + String expected = "" + + "\n" + + " 47\n" + + " 11\n" + + ""; + + xstream.alias("primitives", PrimitiveArray.class); + xstream.addImplicitArray(PrimitiveArray.class, "ints"); + assertBothWays(pa, expected); + } + + static class MultiDimenstionalArrays { + Object[][] multiObject; + String[][] multiString; + int[][] multiInt; + }; + + public void testMultiDimensionalDirectArray() { + MultiDimenstionalArrays multiDim = new MultiDimenstionalArrays(); + multiDim.multiString = new String[][]{ + new String[]{ "1", "2" }, + new String[]{ "a", "b", "c" } + }; + + String expected = "" + + "\n" + + " \n" + + " 1\n" + + " 2\n" + + " \n" + + " \n" + + " a\n" + + " b\n" + + " c\n" + + " \n" + + ""; + + xstream.alias("N", MultiDimenstionalArrays.class); + xstream.addImplicitArray(MultiDimenstionalArrays.class, "multiString"); + assertBothWays(multiDim, expected); + } + + public void testMultiDimensionalPrimitiveArray() { + MultiDimenstionalArrays multiDim = new MultiDimenstionalArrays(); + multiDim.multiInt = new int[][]{ + new int[]{ 1, 2 }, + new int[]{ 0, -1, -2 } + }; + + String expected = "" + + "\n" + + " \n" + + " 1\n" + + " 2\n" + + " \n" + + " \n" + + " 0\n" + + " -1\n" + + " -2\n" + + " \n" + + ""; + + xstream.alias("N", MultiDimenstionalArrays.class); + xstream.addImplicitArray(MultiDimenstionalArrays.class, "multiInt"); + assertBothWays(multiDim, expected); + } + + public void testMultiDimensionalArrayWithAlias() { + MultiDimenstionalArrays multiDim = new MultiDimenstionalArrays(); + multiDim.multiObject = new Object[][]{ + new String[]{ "1" }, + new Object[]{ "a", Boolean.FALSE } + }; + + String expected = "" + + "\n" + + " \n" + + " 1\n" + + " \n" + + " \n" + + " a\n" + + " false\n" + + " \n" + + ""; + + xstream.alias("N", MultiDimenstionalArrays.class); + xstream.addImplicitArray(MultiDimenstionalArrays.class, "multiObject", "M"); + assertBothWays(multiDim, expected); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/ImplicitCollectionTest.java b/xstream/src/test/com/thoughtworks/acceptance/ImplicitCollectionTest.java new file mode 100644 index 0000000..c489c13 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/ImplicitCollectionTest.java @@ -0,0 +1,552 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 14. August 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.InitializationException; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +public class ImplicitCollectionTest extends AbstractAcceptanceTest { + + public static class Farm extends StandardObject { + int size; + List animals = new ArrayList(); + + public Farm(int size) { + this.size = size; + } + + public void add(Animal animal) { + animals.add(animal); + } + } + + public static class Animal extends StandardObject implements Comparable { + String name; + + public Animal(String name) { + this.name = name; + } + + public int compareTo(Object o) { + return name.compareTo(((Animal)o).name); + } + } + + protected void setUp() throws Exception { + super.setUp(); + xstream.alias("zoo", Zoo.class); + xstream.alias("farm", Farm.class); + xstream.alias("animal", Animal.class); + xstream.alias("room", Room.class); + xstream.alias("house", House.class); + xstream.alias("person", Person.class); + xstream.ignoreUnknownElements(); + } + + public void testWithout() { + Farm farm = new Farm(100); + farm.add(new Animal("Cow")); + farm.add(new Animal("Sheep")); + + String expected = "" + + "\n" + + " 100\n" + + " \n" + + " \n" + + " Cow\n" + + " \n" + + " \n" + + " Sheep\n" + + " \n" + + " \n" + + ""; + + assertBothWays(farm, expected); + } + + public void testWithList() { + Farm farm = new Farm(100); + farm.add(new Animal("Cow")); + farm.add(new Animal("Sheep")); + + String expected = "" + + "\n" + + " 100\n" + + " \n" + + " Cow\n" + + " \n" + + " \n" + + " Sheep\n" + + " \n" + + ""; + + xstream.addImplicitCollection(Farm.class, "animals"); + assertBothWays(farm, expected); + } + + public static class MegaFarm extends Farm { + String separator = "---"; + List names; + public MegaFarm(int size) { + super(size); + } + } + + public void testInheritsImplicitCollectionFromSuperclass() { + xstream.alias("MEGA-farm", MegaFarm.class); + + Farm farm = new MegaFarm(100); // subclass + farm.add(new Animal("Cow")); + farm.add(new Animal("Sheep")); + + String expected = "" + + "\n" + + " 100\n" + + " \n" + + " Cow\n" + + " \n" + + " \n" + + " Sheep\n" + + " \n" + + " ---\n" + + ""; + + xstream.addImplicitCollection(Farm.class, "animals"); + assertBothWays(farm, expected); + } + + public void testSupportsInheritedAndDirectDeclaredImplicitCollectionAtOnce() { + xstream.alias("MEGA-farm", MegaFarm.class); + + MegaFarm farm = new MegaFarm(100); // subclass + farm.add(new Animal("Cow")); + farm.add(new Animal("Sheep")); + farm.names = new ArrayList(); + farm.names.add("McDonald"); + farm.names.add("Ponte Rosa"); + + String expected = "" + + "\n" + + " 100\n" + + " \n" + + " Cow\n" + + " \n" + + " \n" + + " Sheep\n" + + " \n" + + " ---\n" + + " McDonald\n" + + " Ponte Rosa\n" + + ""; + + xstream.addImplicitCollection(Farm.class, "animals"); + xstream.addImplicitCollection(MegaFarm.class, "names", "name", String.class); + assertBothWays(farm, expected); + } + + public void testInheritedAndDirectDeclaredImplicitCollectionAtOnceIsNotDeclarationSequenceDependent() { + xstream.alias("MEGA-farm", MegaFarm.class); + + MegaFarm farm = new MegaFarm(100); // subclass + farm.add(new Animal("Cow")); + farm.add(new Animal("Sheep")); + farm.names = new ArrayList(); + farm.names.add("McDonald"); + farm.names.add("Ponte Rosa"); + + String expected = "" + + "\n" + + " 100\n" + + " \n" + + " Cow\n" + + " \n" + + " \n" + + " Sheep\n" + + " \n" + + " ---\n" + + " McDonald\n" + + " Ponte Rosa\n" + + ""; + + xstream.addImplicitCollection(MegaFarm.class, "names", "name", String.class); + xstream.addImplicitCollection(Farm.class, "animals"); + assertBothWays(farm, expected); + } + + public void testAllowsSubclassToOverrideImplicitCollectionInSuperclass() { + xstream.alias("MEGA-farm", MegaFarm.class); + + Farm farm = new MegaFarm(100); // subclass + farm.add(new Animal("Cow")); + farm.add(new Animal("Sheep")); + + String expected = "" + + "\n" + + " 100\n" + + " \n" + + " Cow\n" + + " \n" + + " \n" + + " Sheep\n" + + " \n" + + " ---\n" + + ""; + + xstream.addImplicitCollection(MegaFarm.class, "animals"); + assertBothWays(farm, expected); + } + + public void testAllowDifferentImplicitCollectionDefinitionsInSubclass() { + xstream.alias("MEGA-farm", MegaFarm.class); + + Farm farm = new Farm(10); + farm.add(new Animal("Cod")); + farm.add(new Animal("Salmon")); + MegaFarm megaFarm = new MegaFarm(100); // subclass + megaFarm.add(new Animal("Cow")); + megaFarm.add(new Animal("Sheep")); + megaFarm.names = new ArrayList(); + megaFarm.names.add("McDonald"); + megaFarm.names.add("Ponte Rosa"); + + List list = new ArrayList(); + list.add(farm); + list.add(megaFarm); + String expected = "" + + "\n" + + " \n" + + " 10\n" + + " \n" + + " Cod\n" + + " \n" + + " \n" + + " Salmon\n" + + " \n" + + " \n" + + " \n" + + " 100\n" + + " \n" + + " Cow\n" + + " \n" + + " \n" + + " Sheep\n" + + " \n" + + " ---\n" + + " McDonald\n" + + " Ponte Rosa\n" + + " \n" + + ""; + + xstream.addImplicitCollection(Farm.class, "animals", "fish", Animal.class); + xstream.addImplicitCollection(MegaFarm.class, "animals"); + xstream.addImplicitCollection(MegaFarm.class, "names", "name", String.class); + assertBothWays(list, expected); + } + + public static class House extends StandardObject { + private List rooms = new ArrayList(); + private String separator = "---"; + private List people = new ArrayList(); + + public void add(Room room) { + rooms.add(room); + } + + public void add(Person person) { + people.add(person); + } + + public List getPeople() { + return Collections.unmodifiableList(people); + } + + public List getRooms() { + return Collections.unmodifiableList(rooms); + } + } + + public static class Room extends StandardObject { + private String name; + + public Room(String name) { + this.name = name; + } + } + + public static class Person extends StandardObject { + private String name; + private LinkedList emailAddresses = new LinkedList(); + + public Person(String name) { + this.name = name; + } + + public void addEmailAddress(String email) { + emailAddresses.add(email); + } + } + + public void testDefaultCollectionBasedOnType() { + House house = new House(); + house.add(new Room("kitchen")); + house.add(new Room("bathroom")); + Person joe = new Person("joe"); + joe.addEmailAddress("joe@house.org"); + joe.addEmailAddress("joe.farmer@house.org"); + house.add(joe); + Person jaimie = new Person("jaimie"); + jaimie.addEmailAddress("jaimie@house.org"); + jaimie.addEmailAddress("jaimie.farmer@house.org"); + jaimie.addEmailAddress("jaimie.ann.farmer@house.org"); + house.add(jaimie); + + String expected = "" + + "\n" + + " \n" + + " kitchen\n" + + " \n" + + " \n" + + " bathroom\n" + + " \n" + + " ---\n" + + " \n" + + " joe\n" + + " joe@house.org\n" + + " joe.farmer@house.org\n" + + " \n" + + " \n" + + " jaimie\n" + + " jaimie@house.org\n" + + " jaimie.farmer@house.org\n" + + " jaimie.ann.farmer@house.org\n" + + " \n" + + ""; + + xstream.addImplicitCollection(House.class, "rooms", Room.class); + xstream.addImplicitCollection(House.class, "people", Person.class); + xstream.addImplicitCollection(Person.class, "emailAddresses", "email", String.class); + + House serializedHouse = (House)assertBothWays(house, expected); + assertEquals(house.getPeople(), serializedHouse.getPeople()); + assertEquals(house.getRooms(), serializedHouse.getRooms()); + } + + public void testWithEMPTY_LIST() { + House house = new House(); + house.people = Collections.EMPTY_LIST; + house.rooms = Collections.EMPTY_LIST; + xstream.addImplicitCollection(House.class, "rooms", Room.class); + xstream.addImplicitCollection(House.class, "people", Person.class); + String expected = "" + + "\n" + + " ---\n" + + ""; + assertEquals(expected, xstream.toXML(house)); + } + + public static class Zoo extends StandardObject { + private Set animals; + public Zoo() { + this(new HashSet()); + } + public Zoo(Set set) { + animals = set; + } + public void add(Animal animal) { + animals.add(animal); + } + } + + public void testWithSet() { + Zoo zoo = new Zoo(); + zoo.add(new Animal("Lion")); + zoo.add(new Animal("Ape")); + + String expected = "" + + "\n" + + " \n" + + " Lion\n" + + " \n" + + " \n" + + " Ape\n" + + " \n" + + ""; + + xstream.addImplicitCollection(Zoo.class, "animals"); + assertBothWaysNormalized(zoo, expected, "zoo", "animal", "name"); + } + + public void testWithDifferentDefaultImplementation() { + String xml = "" + + "\n" + + " \n" + + " Lion\n" + + " \n" + + " \n" + + " Ape\n" + + " \n" + + ""; + + xstream.addImplicitCollection(Zoo.class, "animals"); + xstream.addDefaultImplementation(TreeSet.class, Set.class); + Zoo zoo = (Zoo)xstream.fromXML(xml); + assertTrue("Collection was a " + zoo.animals.getClass().getName(), zoo.animals instanceof TreeSet); + } + + public void testWithSortedSet() { + Zoo zoo = new Zoo(new TreeSet()); + zoo.add(new Animal("Lion")); + zoo.add(new Animal("Ape")); + + String expected = "" + + "\n" + + " \n" + + " Ape\n" + + " \n" + + " \n" + + " Lion\n" + + " \n" + + ""; + + xstream.addImplicitCollection(Zoo.class, "animals"); + xstream.addDefaultImplementation(TreeSet.class, Set.class); + assertBothWays(zoo, expected); + } + + public static class Aquarium extends StandardObject { + private String name; + private List fish = new ArrayList(); + + public Aquarium(String name) { + this.name = name; + } + + public void addFish(String fish) { + this.fish.add(fish); + } + } + + public void testWithExplicitItemNameMatchingTheNameOfTheFieldWithTheCollection() { + Aquarium aquarium = new Aquarium("hatchery"); + aquarium.addFish("salmon"); + aquarium.addFish("halibut"); + aquarium.addFish("snapper"); + + String expected = "" + + "\n" + + " hatchery\n" + + " salmon\n" + + " halibut\n" + + " snapper\n" + + ""; + + xstream.alias("aquarium", Aquarium.class); + xstream.addImplicitCollection(Aquarium.class, "fish", "fish", String.class); + + assertBothWays(aquarium, expected); + } + + public void testWithImplicitNameMatchingTheNameOfTheFieldWithTheCollection() { + Aquarium aquarium = new Aquarium("hatchery"); + aquarium.addFish("salmon"); + aquarium.addFish("halibut"); + aquarium.addFish("snapper"); + + String expected = "" + + "\n" + + " hatchery\n" + + " salmon\n" + + " halibut\n" + + " snapper\n" + + ""; + + xstream.alias("aquarium", Aquarium.class); + xstream.alias("fish", String.class); + xstream.addImplicitCollection(Aquarium.class, "fish"); + + assertBothWays(aquarium, expected); + } + + public void testWithAliasedItemNameMatchingTheAliasedNameOfTheFieldWithTheCollection() { + Aquarium aquarium = new Aquarium("hatchery"); + aquarium.addFish("salmon"); + aquarium.addFish("halibut"); + aquarium.addFish("snapper"); + + String expected = "" + + "\n" + + " hatchery\n" + + " salmon\n" + + " halibut\n" + + " snapper\n" + + ""; + + xstream.alias("aquarium", Aquarium.class); + xstream.aliasField("animal", Aquarium.class, "fish"); + xstream.addImplicitCollection(Aquarium.class, "fish", "animal", String.class); + + assertBothWays(aquarium, expected); + } + + public void testCanBeDeclaredOnlyForMatchingType() { + try { + xstream.addImplicitCollection(Animal.class, "name"); + fail("Thrown " + InitializationException.class.getName() + " expected"); + } catch (final InitializationException e) { + assertTrue(e.getMessage().indexOf("declares no collection") >= 0); + } + } + + public void testWithNullElement() { + Farm farm = new Farm(100); + farm.add(null); + farm.add(new Animal("Cow")); + + String expected = "" + + "\n" + + " 100\n" + + " \n" + + " \n" + + " Cow\n" + + " \n" + + ""; + + xstream.addImplicitCollection(Farm.class, "animals"); + assertBothWays(farm, expected); + } + + public void testWithAliasAndNullElement() { + Farm farm = new Farm(100); + farm.add(null); + farm.add(new Animal("Cow")); + + String expected = "" + + "\n" + + " 100\n" + + " \n" + + " \n" + + " Cow\n" + + " \n" + + ""; + + xstream.addImplicitCollection(Farm.class, "animals", "beast", Animal.class); + assertBothWays(farm, expected); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/ImplicitMapTest.java b/xstream/src/test/com/thoughtworks/acceptance/ImplicitMapTest.java new file mode 100644 index 0000000..7a3d13d --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/ImplicitMapTest.java @@ -0,0 +1,588 @@ +/* + * Copyright (C) 2011, 2012, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 05. August 2011 Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.Hardware; +import com.thoughtworks.acceptance.objects.Product; +import com.thoughtworks.acceptance.objects.SampleMaps; +import com.thoughtworks.acceptance.objects.Software; +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.converters.collections.MapConverter; +import com.thoughtworks.xstream.core.util.OrderRetainingMap; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +public class ImplicitMapTest extends AbstractAcceptanceTest { + + public static class Farm extends StandardObject { + int size; + List animals = new ArrayList(); + + public Farm(int size) { + this.size = size; + } + + public void add(Animal animal) { + animals.add(animal); + } + } + + public static class Animal extends StandardObject implements Comparable { + String name; + + public Animal(String name) { + this.name = name; + } + + public int compareTo(Object o) { + return name.compareTo(((Animal)o).name); + } + } + + protected void setUp() throws Exception { + super.setUp(); + xstream.registerConverter(new MapConverter(xstream.getMapper()) { + public boolean canConvert(Class type) { + return type == OrderRetainingMap.class; + } + }); + xstream.addDefaultImplementation(OrderRetainingMap.class, Map.class); + xstream.alias("sample", SampleMaps.class); + xstream.alias("software", Software.class); + xstream.alias("hardware", Hardware.class); + xstream.alias("product", Product.class); + xstream.ignoreUnknownElements(); + } + + public void testWithout() { + SampleMaps sample = new SampleMaps(); + sample.good = new OrderRetainingMap(); + sample.good.put("Windows", new Software("Microsoft", "Windows")); + sample.good.put("Linux", new Software("Red Hat", "Linux")); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " Windows\n" + + " \n" + + " Microsoft\n" + + " Windows\n" + + " \n" + + " \n" + + " \n" + + " Linux\n" + + " \n" + + " Red Hat\n" + + " Linux\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + assertBothWays(sample, expected); + } + + public void testWithMap() { + SampleMaps sample = new SampleMaps(); + sample.good = new OrderRetainingMap(); + sample.good.put("Windows", new Software("Microsoft", "Windows")); + sample.good.put("Linux", new Software("Red Hat", "Linux")); + + String expected = "" + + "\n" + + " \n" + + " Microsoft\n" + + " Windows\n" + + " \n" + + " \n" + + " Red Hat\n" + + " Linux\n" + + " \n" + + " \n" + + ""; + + xstream.addImplicitMap(SampleMaps.class, "good", Software.class, "name"); + assertBothWays(sample, expected); + } + + public static class MegaSampleMaps extends SampleMaps { + String separator = "---"; + Map other = new OrderRetainingMap(); + { + good = new OrderRetainingMap(); + bad = new OrderRetainingMap(); + } + } + + public void testInheritsImplicitMapFromSuperclass() { + xstream.alias("MEGA-sample", MegaSampleMaps.class); + + SampleMaps sample = new MegaSampleMaps(); // subclass + sample.good.put("Windows", new Software("Microsoft", "Windows")); + sample.good.put("Linux", new Software("Red Hat", "Linux")); + + String expected = "" + + "\n" + + " \n" + + " Microsoft\n" + + " Windows\n" + + " \n" + + " \n" + + " Red Hat\n" + + " Linux\n" + + " \n" + + " \n" + + " ---\n" + + " \n" + + ""; + + xstream.addImplicitMap(SampleMaps.class, "good", Software.class, "name"); + assertBothWays(sample, expected); + } + + public void testSupportsInheritedAndDirectDeclaredImplicitMapAtOnce() { + xstream.alias("MEGA-sample", MegaSampleMaps.class); + + MegaSampleMaps sample = new MegaSampleMaps(); // subclass + sample.good.put("Windows", new Software("Microsoft", "Windows")); + sample.good.put("Linux", new Software("Red Hat", "Linux")); + sample.other.put("i386", new Hardware("i386", "Intel")); + + String expected = "" + + "\n" + + " \n" + + " Microsoft\n" + + " Windows\n" + + " \n" + + " \n" + + " Red Hat\n" + + " Linux\n" + + " \n" + + " \n" + + " ---\n" + + " \n" + + " i386\n" + + " Intel\n" + + " \n" + + ""; + + xstream.addImplicitMap(SampleMaps.class, "good", Software.class, "name"); + xstream.addImplicitMap(MegaSampleMaps.class, "other", Hardware.class, "arch"); + assertBothWays(sample, expected); + } + + public void testInheritedAndDirectDeclaredImplicitMapAtOnceIsNotDeclarationSequenceDependent() { + xstream.alias("MEGA-sample", MegaSampleMaps.class); + + MegaSampleMaps sample = new MegaSampleMaps(); // subclass + sample.good.put("Windows", new Software("Microsoft", "Windows")); + sample.good.put("Linux", new Software("Red Hat", "Linux")); + sample.other.put("i386", new Hardware("i386", "Intel")); + + String expected = "" + + "\n" + + " \n" + + " Microsoft\n" + + " Windows\n" + + " \n" + + " \n" + + " Red Hat\n" + + " Linux\n" + + " \n" + + " \n" + + " ---\n" + + " \n" + + " i386\n" + + " Intel\n" + + " \n" + + ""; + + xstream.addImplicitMap(MegaSampleMaps.class, "other", Hardware.class, "arch"); + xstream.addImplicitMap(SampleMaps.class, "good", Software.class, "name"); + assertBothWays(sample, expected); + } + + public void testAllowsSubclassToOverrideImplicitMapInSuperclass() { + xstream.alias("MEGA-sample", MegaSampleMaps.class); + + SampleMaps sample = new MegaSampleMaps(); // subclass + sample.good.put("Windows", new Software("Microsoft", "Windows")); + sample.good.put("Linux", new Software("Red Hat", "Linux")); + + String expected = "" + + "\n" + + " \n" + + " Microsoft\n" + + " Windows\n" + + " \n" + + " \n" + + " Red Hat\n" + + " Linux\n" + + " \n" + + " \n" + + " ---\n" + + " \n" + + ""; + + xstream.addImplicitMap(MegaSampleMaps.class, "good", Software.class, "name"); + assertBothWays(sample, expected); + } + + public void testAllowDifferentImplicitMapDefinitionsInSubclass() { + xstream.alias("MEGA-sample", MegaSampleMaps.class); + + SampleMaps sample = new SampleMaps(); + sample.good.put("Google", new Software("Google", "Android")); + MegaSampleMaps megaSample = new MegaSampleMaps(); // subclass + megaSample.good.put("Windows", new Software("Microsoft", "Windows")); + megaSample.good.put("Linux", new Software("Red Hat", "Linux")); + megaSample.other.put("i386", new Hardware("i386", "Intel")); + + List list = new ArrayList(); + list.add(sample); + list.add(megaSample); + String expected = "" + + "\n" + + " \n" + + " \n" + + " Google\n" + + " Android\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " Microsoft\n" + + " Windows\n" + + " \n" + + " \n" + + " Red Hat\n" + + " Linux\n" + + " \n" + + " \n" + + " ---\n" + + " \n" + + " i386\n" + + " Intel\n" + + " \n" + + " \n" + + ""; + + xstream.addImplicitMap(SampleMaps.class, "good", "mobile", Software.class, "vendor"); + xstream.addImplicitMap(MegaSampleMaps.class, "good", Software.class, "name"); + xstream.addImplicitMap(MegaSampleMaps.class, "other", Hardware.class, "arch"); + assertBothWays(list, expected); + } + + public void testDefaultMapBasedOnType() { + xstream.alias("MEGA-sample", MegaSampleMaps.class); + + MegaSampleMaps sample = new MegaSampleMaps(); + sample.good.put("Windows", new Software("Microsoft", "Windows")); + sample.good.put("Linux", new Software("Red Hat", "Linux")); + sample.good.put("Chrome", new Software("Google", "Chrome")); + sample.bad.put("iPhone", new Product("iPhone", "i", 399.99)); + sample.other.put("Intel", new Hardware("i386", "Intel")); + sample.other.put("AMD", new Hardware("amd64", "AMD")); + + String expected = "" + + "\n" + + " \n" + + " Microsoft\n" + + " Windows\n" + + " \n" + + " \n" + + " Red Hat\n" + + " Linux\n" + + " \n" + + " \n" + + " Google\n" + + " Chrome\n" + + " \n" + + " \n" + + " iPhone\n" + + " i\n" + + " 399.99\n" + + " \n" + + " ---\n" + + " \n" + + " i386\n" + + " Intel\n" + + " \n" + + " \n" + + " amd64\n" + + " AMD\n" + + " \n" + + ""; + + xstream.addImplicitMap(SampleMaps.class, "good", Software.class, "name"); + xstream.addImplicitMap(SampleMaps.class, "bad", Product.class, "name"); + xstream.addImplicitMap(MegaSampleMaps.class, "other", Hardware.class, "name"); + assertBothWays(sample, expected); + } + + public void testWithEMPTY_MAP() { + SampleMaps sample = new SampleMaps(); + sample.good = Collections.EMPTY_MAP; + sample.bad = Collections.EMPTY_MAP; + + xstream.addImplicitMap(SampleMaps.class, "good", Software.class, "name"); + xstream.addImplicitMap(SampleMaps.class, "bad", Software.class, "name"); + assertEquals("", xstream.toXML(sample)); + } + + public void testWithSortedMap() { + SampleMaps sample = new SampleMaps(); + sample.good = new TreeMap(); + sample.good.put("Windows", new Software("Microsoft", "Windows")); + sample.good.put("Linux", new Software("Red Hat", "Linux")); + + String expected = "" + + "\n" + + " \n" + + " Red Hat\n" + + " Linux\n" + + " \n" + + " \n" + + " Microsoft\n" + + " Windows\n" + + " \n" + + " \n" + + ""; + + xstream.addDefaultImplementation(TreeMap.class, Map.class); + xstream.addImplicitMap(SampleMaps.class, "good", Software.class, "name"); + assertBothWays(sample, expected); + } + + public void testWithExplicitItemNameMatchingTheNameOfTheFieldWithTheMap() { + SampleMaps sample = new SampleMaps(); + sample.bad = new OrderRetainingMap(); + sample.bad.put("Windows", new Software("Microsoft", "Windows")); + sample.bad.put("Linux", new Software("Red Hat", "Linux")); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " Microsoft\n" + + " Windows\n" + + " \n" + + " \n" + + " Red Hat\n" + + " Linux\n" + + " \n" + + ""; + + xstream.addImplicitMap(SampleMaps.class, "bad", "bad", Software.class, "name"); + assertBothWays(sample, expected); + } + + public void testWithImplicitNameMatchingTheNameOfTheFieldWithTheMap() { + SampleMaps sample = new SampleMaps(); + sample.bad = new OrderRetainingMap(); + sample.bad.put("Windows", new Software("Microsoft", "Windows")); + sample.bad.put("Linux", new Software("Red Hat", "Linux")); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " Microsoft\n" + + " Windows\n" + + " \n" + + " \n" + + " Red Hat\n" + + " Linux\n" + + " \n" + + ""; + + xstream.addImplicitMap(SampleMaps.class, "bad", Software.class, "name"); + xstream.alias("bad", Software.class); + assertBothWays(sample, expected); + } + + public void testWithAliasedItemNameMatchingTheAliasedNameOfTheFieldWithTheMap() { + SampleMaps sample = new SampleMaps(); + sample.bad = new OrderRetainingMap(); + sample.bad.put("Windows", new Software("Microsoft", "Windows")); + sample.bad.put("Linux", new Software("Red Hat", "Linux")); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " Microsoft\n" + + " Windows\n" + + " \n" + + " \n" + + " Red Hat\n" + + " Linux\n" + + " \n" + + ""; + + xstream.addImplicitMap(SampleMaps.class, "bad", "test", Software.class, "name"); + xstream.aliasField("test", SampleMaps.class, "bad"); + assertBothWays(sample, expected); + } + + public void testWithNullElement() { + SampleMaps sample = new SampleMaps(); + sample.good = new OrderRetainingMap(); + sample.good.put(null, null); + sample.good.put("Linux", new Software("Red Hat", "Linux")); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " Red Hat\n" + + " Linux\n" + + " \n" + + " \n" + + ""; + + xstream.addImplicitMap(SampleMaps.class, "good", Software.class, "name"); + assertBothWays(sample, expected); + } + + public void testWithAliasAndNullElement() { + SampleMaps sample = new SampleMaps(); + sample.good = new OrderRetainingMap(); + sample.good.put(null, null); + sample.good.put("Linux", new Software("Red Hat", "Linux")); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " Red Hat\n" + + " Linux\n" + + " \n" + + " \n" + + ""; + + xstream.addImplicitMap(SampleMaps.class, "good", "code", Software.class, "name"); + assertBothWays(sample, expected); + } + + public void testCollectsDifferentTypesWithFieldOfSameName() { + SampleMaps sample = new SampleMaps(); + sample.good = new OrderRetainingMap(); + sample.good.put("iPhone", new Product("iPhone", "i", 399.99)); + sample.good.put("Linux", new Software("Red Hat", "Linux")); + sample.good.put("Intel", new Hardware("i386", "Intel")); + + String expected = "" + + "\n" + + " \n" + + " iPhone\n" + + " i\n" + + " 399.99\n" + + " \n" + + " \n" + + " Red Hat\n" + + " Linux\n" + + " \n" + + " \n" + + " i386\n" + + " Intel\n" + + " \n" + + " \n" + + ""; + + xstream.addImplicitMap(SampleMaps.class, "good", null, "name"); + assertBothWays(sample, expected); + } + + public void testSeparatesItemsBasedOnItemName() { + SampleMaps sample = new SampleMaps(); + sample.good = new OrderRetainingMap(); + sample.good.put("Chrome", new Software("Google", "Chrome")); + sample.bad = new OrderRetainingMap(); + sample.bad.put("Linux", new Software("Red Hat", "Linux")); + sample.bad.put("Windows", new Software("Microsoft", "Windows")); + + String expected = "" + + "\n" + + " \n" + + " Google\n" + + " Chrome\n" + + " \n" + + " \n" + + " Red Hat\n" + + " Linux\n" + + " \n" + + " \n" + + " Microsoft\n" + + " Windows\n" + + " \n" + + ""; + + xstream.addImplicitMap(SampleMaps.class, "good", "g", Software.class, "name"); + xstream.addImplicitMap(SampleMaps.class, "bad", "b", Software.class, "name"); + assertBothWays(sample, expected); + } + + public void testWithoutKeyField() { + SampleMaps sample = new SampleMaps(); + sample.good = new OrderRetainingMap(); + sample.good.put("Windows", new Software("Microsoft", "Windows")); + sample.good.put("Linux", new Software("Red Hat", "Linux")); + + String expected = "" + + "\n" + + " \n" + + " Windows\n" + + " \n" + + " Microsoft\n" + + " Windows\n" + + " \n" + + " \n" + + " \n" + + " Linux\n" + + " \n" + + " Red Hat\n" + + " Linux\n" + + " \n" + + " \n" + + " \n" + + ""; + + xstream.addImplicitMap(SampleMaps.class, "good", null, null); + assertBothWays(sample, expected); + } + + public void testCanUsePrimitiveAsKey() { + SampleMaps sample = new SampleMaps(); + sample.good = new OrderRetainingMap(); + sample.good.put(new Double(399.99), new Product("iPhone", "i", 399.99)); + + String expected = "" + + "\n" + + " \n" + + " iPhone\n" + + " i\n" + + " 399.99\n" + + " \n" + + " \n" + + ""; + + xstream.addImplicitMap(SampleMaps.class, "good", Product.class, "price"); + assertBothWays(sample, expected); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/ImplicitTest.java b/xstream/src/test/com/thoughtworks/acceptance/ImplicitTest.java new file mode 100644 index 0000000..fa04248 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/ImplicitTest.java @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. April 2013 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import com.thoughtworks.xstream.core.util.OrderRetainingMap; + +public class ImplicitTest extends AbstractAcceptanceTest { + + public static class AllImplicitTypes { + + public static class A { + public int val; + } + + public static class B { + public int val; + } + + public static class C { + public Integer val; + } + + public A[] aArray = new A[2]; + public String separator1 = "--1--"; + public List bList = new ArrayList(); + public String separator2 = "--2--"; + public Map cMap = new OrderRetainingMap(); + } + + public void testAllImplicitTypesAtOnceWithImplicitElementTypes() + { + xstream.alias("implicits", AllImplicitTypes.class); + xstream.alias("a", AllImplicitTypes.A.class); + xstream.alias("b", AllImplicitTypes.B.class); + xstream.alias("c", AllImplicitTypes.C.class); + xstream.addDefaultImplementation(OrderRetainingMap.class, Map.class); + xstream.addImplicitArray(AllImplicitTypes.class, "aArray"); + xstream.addImplicitCollection(AllImplicitTypes.class, "bList"); + xstream.addImplicitMap(AllImplicitTypes.class, "cMap", AllImplicitTypes.C.class, "val"); + String expected = "" + + "\n" + + " \n" + + " 1\n" + + " \n" + + " \n" + + " 2\n" + + " \n" + + " --1--\n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 4\n" + + " \n" + + " --2--\n" + + " \n" + + " 5\n" + + " \n" + + " \n" + + " 6\n" + + " \n" + + ""; + + AllImplicitTypes implicits = new AllImplicitTypes(); + implicits.aArray[0] = new AllImplicitTypes.A(); + implicits.aArray[0].val = 1; + implicits.aArray[1] = new AllImplicitTypes.A(); + implicits.aArray[1].val = 2; + implicits.bList.add(new AllImplicitTypes.B()); + ((AllImplicitTypes.B)implicits.bList.get(0)).val = 3; + implicits.bList.add(new AllImplicitTypes.B()); + ((AllImplicitTypes.B)implicits.bList.get(1)).val = 4; + AllImplicitTypes.C c = new AllImplicitTypes.C(); + c.val = new Integer(5); + implicits.cMap.put(c.val, c); + c = new AllImplicitTypes.C(); + c.val = new Integer(6); + implicits.cMap.put(c.val, c); + assertBothWays(implicits, expected); + } + + public void testAllImplicitTypesAtOnceWithExplicitElementTypes() + { + xstream.alias("implicits", AllImplicitTypes.class); + xstream.alias("a", AllImplicitTypes.A.class); + xstream.alias("b", AllImplicitTypes.B.class); + xstream.alias("c", AllImplicitTypes.C.class); + xstream.addDefaultImplementation(OrderRetainingMap.class, Map.class); + xstream.addImplicitArray(AllImplicitTypes.class, "aArray"); + xstream.addImplicitCollection(AllImplicitTypes.class, "bList", AllImplicitTypes.B.class); + xstream.addImplicitMap(AllImplicitTypes.class, "cMap", AllImplicitTypes.C.class, "val"); + String expected = "" + + "\n" + + " \n" + + " 1\n" + + " \n" + + " \n" + + " 2\n" + + " \n" + + " --1--\n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 4\n" + + " \n" + + " --2--\n" + + " \n" + + " 5\n" + + " \n" + + " \n" + + " 6\n" + + " \n" + + ""; + + AllImplicitTypes implicits = new AllImplicitTypes(); + implicits.aArray[0] = new AllImplicitTypes.A(); + implicits.aArray[0].val = 1; + implicits.aArray[1] = new AllImplicitTypes.A(); + implicits.aArray[1].val = 2; + implicits.bList.add(new AllImplicitTypes.B()); + ((AllImplicitTypes.B)implicits.bList.get(0)).val = 3; + implicits.bList.add(new AllImplicitTypes.B()); + ((AllImplicitTypes.B)implicits.bList.get(1)).val = 4; + AllImplicitTypes.C c = new AllImplicitTypes.C(); + c.val = new Integer(5); + implicits.cMap.put(c.val, c); + c = new AllImplicitTypes.C(); + c.val = new Integer(6); + implicits.cMap.put(c.val, c); + assertBothWays(implicits, expected); + } + + public void testAllImplicitTypesAtOnceWithExplicitElementNames() + { + xstream.alias("implicits", AllImplicitTypes.class); + xstream.addDefaultImplementation(OrderRetainingMap.class, Map.class); + xstream.addImplicitArray(AllImplicitTypes.class, "aArray", "a"); + xstream.addImplicitCollection(AllImplicitTypes.class, "bList", "b", AllImplicitTypes.B.class); + xstream.addImplicitMap(AllImplicitTypes.class, "cMap", "c", AllImplicitTypes.C.class, "val"); + String expected = "" + + "\n" + + " \n" + + " 1\n" + + " \n" + + " \n" + + " 2\n" + + " \n" + + " --1--\n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 4\n" + + " \n" + + " --2--\n" + + " \n" + + " 5\n" + + " \n" + + " \n" + + " 6\n" + + " \n" + + ""; + + AllImplicitTypes implicits = new AllImplicitTypes(); + implicits.aArray[0] = new AllImplicitTypes.A(); + implicits.aArray[0].val = 1; + implicits.aArray[1] = new AllImplicitTypes.A(); + implicits.aArray[1].val = 2; + implicits.bList.add(new AllImplicitTypes.B()); + ((AllImplicitTypes.B)implicits.bList.get(0)).val = 3; + implicits.bList.add(new AllImplicitTypes.B()); + ((AllImplicitTypes.B)implicits.bList.get(1)).val = 4; + AllImplicitTypes.C c = new AllImplicitTypes.C(); + c.val = new Integer(5); + implicits.cMap.put(c.val, c); + c = new AllImplicitTypes.C(); + c.val = new Integer(6); + implicits.cMap.put(c.val, c); + assertBothWays(implicits, expected); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/InheritanceTest.java b/xstream/src/test/com/thoughtworks/acceptance/InheritanceTest.java new file mode 100644 index 0000000..5ca1d80 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/InheritanceTest.java @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2003, 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.OpenSourceSoftware; +import com.thoughtworks.acceptance.objects.StandardObject; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +public class InheritanceTest extends AbstractAcceptanceTest { + public void testHandlesInheritanceHierarchies() { + OpenSourceSoftware openSourceSoftware = new OpenSourceSoftware("apache", "geronimo", "license"); + String xml = + "\n" + + " apache\n" + + " geronimo\n" + + " license\n" + + ""; + + xstream.alias("oss", OpenSourceSoftware.class); + assertBothWays(openSourceSoftware, xml); + } + + public static class ParentClass { + private String name; + + public ParentClass() { + } + + public ParentClass(String name) { + this.name = name; + } + + public String getParentName() { + return name; + } + } + + public static class ChildClass extends ParentClass { + private String name; + + public ChildClass() { + } + + public ChildClass(String parentName, String childName) { + super(parentName); + this.name = childName; + } + + public String getChildName() { + return name; + } + + public String toString() { + return getParentName() + "/" + getChildName(); + } + + public boolean equals(Object obj) { + return toString().equals(obj.toString()); + } + } + + public void testInheritanceHidingPrivateFieldOfSameName() { + xstream.alias("parent", ParentClass.class); + xstream.alias("child", ChildClass.class); + + ChildClass child = new ChildClass("PARENT", "CHILD"); + // sanity checks + assertEquals("PARENT", child.getParentName()); + assertEquals("CHILD", child.getChildName()); + + String expected = "" + + "\n" + + " PARENT\n" + + " CHILD\n" + + ""; + + assertBothWays(child, expected); + } + + public static class StaticChildClass extends ParentClass { + private static String name = "CHILD"; + + public StaticChildClass() { + } + + public StaticChildClass(String parentName) { + super(parentName); + } + } + + public void testHandlesStaticFieldInChildDoesNotHideFieldInParent() { + xstream.alias("child", StaticChildClass.class); + + StaticChildClass child = new StaticChildClass("PARENT"); + String expected = "" + + "\n" + + " PARENT\n" + + ""; + + assertBothWays(child, expected); + assertEquals("PARENT", child.getParentName()); + assertEquals("CHILD", StaticChildClass.name); + } + + public static class ParentA extends StandardObject { + private List stuff = new ArrayList(); + + public List getParentStuff() { + return stuff; + } + } + + public static class ChildA extends ParentA { + private Map stuff = new HashMap(); + + public Map getChildStuff() { + return stuff; + } + + public boolean equals(Object obj) { + ChildA a = (ChildA) obj; + if (!getChildStuff().getClass().equals(a.getChildStuff().getClass())) { + return false; + } + if (!getParentStuff().getClass().equals(a.getParentStuff().getClass())) { + return false; + } + return getChildStuff().equals(a.getChildStuff()) + && getParentStuff().equals(a.getParentStuff()); + } + } + + public void testHiddenFieldsWithDifferentType() { + xstream.alias("child-a", ChildA.class); + xstream.alias("parent-a", ParentA.class); + ChildA childA = new ChildA(); + childA.getChildStuff().put("hello", "world"); + childA.getParentStuff().add("woo"); + String expected = "" + + "\n" + + " \n" + + " woo\n" + + " \n" + + " \n" + + " \n" + + " hello\n" + + " world\n" + + " \n" + + " \n" + + ""; + assertBothWays(childA, expected); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/InnerClassesTest.java b/xstream/src/test/com/thoughtworks/acceptance/InnerClassesTest.java new file mode 100644 index 0000000..1952400 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/InnerClassesTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 31. January 2005 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +public class InnerClassesTest extends AbstractAcceptanceTest { + + public void testSerializedInnerClassMaintainsReferenceToOuterClass() { + xstream.allowTypes(new Class[]{Outer.class, Outer.Inner.class}); + + Outer outer = new Outer("THE-OUTER-NAME", "THE-INNER-NAME"); + Outer.Inner inner = outer.getInner(); + + assertEquals("Hello from THE-INNER-NAME (inside THE-OUTER-NAME)", inner.getMessage()); + + String xml = xstream.toXML(inner); + + String expectedXml = "" + + "\n" + + " THE-INNER-NAME\n" + + " \n" + + " \n" + + " THE-OUTER-NAME\n" + + " \n" + + ""; + assertEquals(expectedXml, xml); + + Outer.Inner newInner = (Outer.Inner) xstream.fromXML(xml); + + assertEquals("Hello from THE-INNER-NAME (inside THE-OUTER-NAME)", newInner.getMessage()); + } +} + +class Outer { + + private Inner inner; + private String outerName; + + public Outer(String outerName, String innerName) { + inner = new Inner(innerName); + this.outerName = outerName; + } + + public Inner getInner() { + return inner; + } + + public class Inner { + private String innerName; + + public Inner(String innerName) { + this.innerName = innerName; + } + + public String getMessage() { + return "Hello from " + innerName + " (inside " + outerName + ")"; + } + } +} + + diff --git a/xstream/src/test/com/thoughtworks/acceptance/JodaTimeTypesTest.java b/xstream/src/test/com/thoughtworks/acceptance/JodaTimeTypesTest.java new file mode 100644 index 0000000..9ab9c80 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/JodaTimeTypesTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008, 2009, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 23. October 2008 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.core.JVM; + +import org.joda.time.DateTimeZone; +import org.joda.time.LocalDate; + +/** + * Tests Joda Time types + * + * @author Jörg Schaible + */ +public class JodaTimeTypesTest extends AbstractAcceptanceTest { + + public void testCanHandleLocateDate() { + if (!JVM.is14()) { + // inner class, must use enhanced mode for this test + return; + } + xstream.allowTypesByWildcard(new String[]{"org.joda.time.**"}); + DateTimeZone.setDefault(DateTimeZone.forID("America/Los_Angeles")); + final LocalDate localDate = new LocalDate(2008, 07, 03); + final String expected = "" + + "\n" + + " 1215043200000\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " UTC\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + assertBothWays(localDate, expected); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/LambdaTest.java b/xstream/src/test/com/thoughtworks/acceptance/LambdaTest.java new file mode 100644 index 0000000..5cb4247 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/LambdaTest.java @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2014, 2015 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 31. December 2014 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import java.io.Serializable; +import java.lang.invoke.SerializedLambda; +import java.util.concurrent.Callable; + + +/** + * @author Jörg Schaible + */ +public class LambdaTest extends AbstractAcceptanceTest { + public static class LambdaKeeper { + private Callable callable; + @SuppressWarnings("unused") + private Object referenced; + + void keep(final Callable c) { + callable = c; + } + + void reference() { + referenced = callable; + } + } + + public void testLambdaExpression() { + final LambdaKeeper keeper = new LambdaKeeper(); + keeper.keep((Callable)() -> "result"); + + final String expected = "" + "\n" + " \n" + ""; + xstream.alias("keeper", LambdaKeeper.class); + xstream.allowTypes(new Class[]{SerializedLambda.class}); + + assertEquals(expected, xstream.toXML(keeper)); + assertBothWays(xstream.fromXML(expected), ""); + } + + public void testSerializableLambdaExpression() { + final LambdaKeeper keeper = new LambdaKeeper(); + keeper.keep((Callable & Serializable)() -> "result"); + + final String expected = "" + + "\n" + + " \n" + + " com.thoughtworks.acceptance.LambdaTest\n" + + " java/util/concurrent/Callable\n" + + " call\n" + + " ()Ljava/lang/Object;\n" + + " com/thoughtworks/acceptance/LambdaTest\n" + + " lambda$0\n" + + " ()Ljava/lang/String;\n" + + " 6\n" + + " ()Ljava/lang/String;\n" + + " \n" + + " \n" + + ""; + xstream.alias("keeper", LambdaKeeper.class); + xstream.allowTypes(new Class[]{SerializedLambda.class}); + + assertBothWaysNormalized(keeper, expected); + + // ... deserialization fails if code was compiled with compiler of different vendor + // Object resultRoot = xstream.fromXML(expected); + // assertNotNull(resultRoot); + } + + public void testReferencedLambdaExpression() { + final LambdaKeeper keeper = new LambdaKeeper(); + keeper.keep((Callable & Serializable)() -> "result"); + keeper.reference(); + + final String expected = "" + + "\n" + + " \n" + + " com.thoughtworks.acceptance.LambdaTest\n" + + " java/util/concurrent/Callable\n" + + " call\n" + + " ()Ljava/lang/Object;\n" + + " com/thoughtworks/acceptance/LambdaTest\n" + + " lambda$0\n" + + " ()Ljava/lang/String;\n" + + " 6\n" + + " ()Ljava/lang/String;\n" + + " \n" + + " \n" + + " \n" + + ""; + xstream.alias("keeper", LambdaKeeper.class); + xstream.allowTypes(new Class[]{SerializedLambda.class}); + + assertBothWaysNormalized(keeper, expected); + } + + public interface X { + static int getTwo() { + return 2; + } + + default int getOne() { + return 1; + } + } + + public interface SerializableCallable extends X, Serializable, Callable {} + + public void testLambdaArray() { + Object[] lambdas = { + (Callable & Serializable)() -> "result", (SerializableCallable)() -> "result", + (Runnable & Serializable)() -> run(), (X & Serializable & Callable)() -> "result", + (Runnable)() -> run(), null}; + lambdas[lambdas.length - 1] = lambdas[0]; + + final String expected = "" + + "\n" + + " \n" + + " com.thoughtworks.acceptance.LambdaTest\n" + + " java/util/concurrent/Callable\n" + + " call\n" + + " ()Ljava/lang/Object;\n" + + " com/thoughtworks/acceptance/LambdaTest\n" + + " lambda$0\n" + + " ()Ljava/lang/String;\n" + + " 6\n" + + " ()Ljava/lang/String;\n" + + " \n" + + " \n" + + " \n" + + " com.thoughtworks.acceptance.LambdaTest\n" + + " com/thoughtworks/acceptance/LambdaTest$SerializableCallable\n" + + " call\n" + + " ()Ljava/lang/Object;\n" + + " com/thoughtworks/acceptance/LambdaTest\n" + + " lambda$0\n" + + " ()Ljava/lang/String;\n" + + " 6\n" + + " ()Ljava/lang/String;\n" + + " \n" + + " \n" + + " \n" + + " com.thoughtworks.acceptance.LambdaTest\n" + + " java/lang/Runnable\n" + + " run\n" + + " ()V\n" + + " com/thoughtworks/acceptance/LambdaTest\n" + + " lambda$0\n" + + " ()V\n" + + " 7\n" + + " ()V\n" + + " \n" + + " \n" + + " testLambdaArray\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " com.thoughtworks.acceptance.LambdaTest\n" + + " java/util/concurrent/Callable\n" + + " call\n" + + " ()Ljava/lang/Object;\n" + + " com/thoughtworks/acceptance/LambdaTest\n" + + " lambda$0\n" + + " ()Ljava/lang/String;\n" + + " 6\n" + + " ()Ljava/lang/String;\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + xstream.alias("callable", Callable.class); + xstream.alias("runnable", Runnable.class); + xstream.alias("serializable-callable", SerializableCallable.class); + xstream.allowTypes(new Class[]{SerializedLambda.class, LambdaTest.class}); + + assertBothWaysNormalized(lambdas, expected); + } + + private void assertBothWaysNormalized(final Object original, final String expected) { + String resultXml = toXML(original); + assertEquals(normalizeLambda(expected), normalizeLambda(resultXml)); + + final Object resultRoot = xstream.fromXML(resultXml); + resultXml = toXML(resultRoot); + assertEquals(normalizeLambda(expected), normalizeLambda(resultXml)); + } + + private String normalizeLambda(final String xml) { + // unify compiler specific name for implMethodName, Eclipse uses always "lambda$0" + return xml.replaceAll(">lambda\\$[^<]+<", ">lambda\\$0<"); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/LocalConverterTest.java b/xstream/src/test/com/thoughtworks/acceptance/LocalConverterTest.java new file mode 100644 index 0000000..1baaaff --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/LocalConverterTest.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. November 2007 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.basic.BooleanConverter; +import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; +import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; + + +/** + * @author Jörg Schaible + */ +public class LocalConverterTest extends AbstractAcceptanceTest { + + public static class MultiBoolean { + private boolean bool; + private boolean speech; + private boolean bit; + + private MultiBoolean() { + this(false, false, false); + } + + public MultiBoolean(boolean bool, boolean speech, boolean bit) { + this.bool = bool; + this.speech = speech; + this.bit = bit; + } + + } + + protected void setUp() throws Exception { + super.setUp(); + xstream.alias("mbool", MultiBoolean.class); + xstream.registerConverter(new ReflectionConverter( + xstream.getMapper(), new PureJavaReflectionProvider()), XStream.PRIORITY_VERY_LOW); + } + + public void testCanBeAppliedToIndividualFields() { + MultiBoolean multiBool = new MultiBoolean(true, true, true); + String xml = "" + + "\n" + + " true\n" + + " yes\n" + + " 1\n" + + ""; + + xstream.registerLocalConverter(MultiBoolean.class, "speech", BooleanConverter.YES_NO); + xstream.registerLocalConverter(MultiBoolean.class, "bit", BooleanConverter.BINARY); + assertBothWays(multiBool, xml); + } + + public static class SymbolParameter { + private int type; + private int color; + private int width; + + public SymbolParameter() { + } + + public SymbolParameter(int type, int color, int width) { + this.type = type; + this.color = color; + this.width = width; + } + + } + + public static class HexNumberConverter implements SingleValueConverter { + public boolean canConvert(Class type) { + return type.equals(int.class) || type.equals(Integer.class); + } + + public Object fromString(String value) { + return new Integer(Integer.parseInt(value, 16)); + } + + public String toString(Object obj) { + return Integer.toHexString(((Integer)obj).intValue()); + } + } + + public void testCanBeUsedForAttributeValue() { + SymbolParameter multiBool = new SymbolParameter(1, 0xff00ff, 100); + String xml = "" + + "\n" + + " 1\n" + + " 100\n" + + ""; + + xstream.alias("param", SymbolParameter.class); + xstream.useAttributeFor("color", int.class); + xstream.registerLocalConverter(SymbolParameter.class, "color", new HexNumberConverter()); + assertBothWays(multiBool, xml); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/MapTest.java b/xstream/src/test/com/thoughtworks/acceptance/MapTest.java new file mode 100644 index 0000000..5162dba --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/MapTest.java @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2003, 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.Hardware; +import com.thoughtworks.acceptance.objects.Software; +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.core.JVM; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class MapTest extends AbstractAcceptanceTest { + + public void testMapCanContainBasicObjects() { + Map map = new HashMap(); + map.put("benny", "hill"); + map.put("joe", "walnes"); + + String expected = "" + + "\n" + + " \n" + + " benny\n" + + " hill\n" + + " \n" + + " \n" + + " joe\n" + + " walnes\n" + + " \n" + + ""; + + assertBothWaysNormalized(map, expected, "map", "entry", "string[1]"); + } + + public void testMapCanContainCustomObjects() { + Map map = new HashMap(); + map.put(new Software("microsoft", "windows"), new Hardware("x86", "p4")); + + xstream.alias("software", Software.class); + xstream.alias("hardware", Hardware.class); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " microsoft\n" + + " windows\n" + + " \n" + + " \n" + + " x86\n" + + " p4\n" + + " \n" + + " \n" + + ""; + + assertBothWays(map, expected); + } + + static class ThingWithMap extends StandardObject { + Map stuff = new HashMap(); + } + + public void testObjectCanContainMapAsField() { + ThingWithMap t = new ThingWithMap(); + t.stuff.put("hi", "bye"); + + xstream.alias("thing-with-map", ThingWithMap.class); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " hi\n" + + " bye\n" + + " \n" + + " \n" + + ""; + + assertBothWays(t, expected); + } + + public void testSupportsOldHashtables() { + + Hashtable hashtable = new Hashtable(); + hashtable.put("hello", "world"); + + String expected = "" + + "\n" + + " \n" + + " hello\n" + + " world\n" + + " \n" + + ""; + + assertBothWays(hashtable, expected); + } + + static class ThingWithDifferentTypesOfMaps extends StandardObject { + private Map m1 = new HashMap(); + private Map m2 = new Hashtable(); + private HashMap m3 = new HashMap(); + private Hashtable m4 = new Hashtable(); + } + + public void testObjectCanContainDifferentMapImplementations() { + + xstream.alias("thing", ThingWithDifferentTypesOfMaps.class); + + ThingWithDifferentTypesOfMaps thing = new ThingWithDifferentTypesOfMaps(); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + assertBothWays(thing, expected); + + } + + public void testLinkedHashMapRetainsOrdering() { + Map map = new LinkedHashMap(); + map.put("Z", "a"); + map.put("C", "c"); + map.put("X", "b"); + + LinkedHashMap result = (LinkedHashMap) assertBothWays(map, + "\n" + + " \n" + + " Z\n" + + " a\n" + + " \n" + + " \n" + + " C\n" + + " c\n" + + " \n" + + " \n" + + " X\n" + + " b\n" + + " \n" + + ""); + + Object[] keys = result.keySet().toArray(); + assertEquals("Z", keys[0]); + assertEquals("C", keys[1]); + assertEquals("X", keys[2]); + } + + public void testAllowsEntryToBeAliasedToSomethingElse() { + Map map = new HashMap(); + map.put("benny", "hill"); + map.put("joe", "walnes"); + + String expected = "" + + "\n" + + " \n" + + " benny\n" + + " hill\n" + + " \n" + + " \n" + + " joe\n" + + " walnes\n" + + " \n" + + ""; + + xstream.alias("thing", Map.Entry.class); + assertBothWaysNormalized(map, expected, "map", "thing", "string[1]"); + } + + public static class MyMap extends HashMap { + + } + + public void testSubclassesOfMapAreHandled() { + MyMap myMap = new MyMap(); + myMap.put("hehe", "hoho"); + String xml = xstream.toXML(myMap); + MyMap myOtherMap = (MyMap) xstream.fromXML(xml); + assertEquals(myMap, myOtherMap); + } + + public void testSynchronizedMap() { + final String expected; + if (JVM.is15()) { + expected = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + } else { + expected = "" + + "\n" + + " \n" + + " \n" + + ""; + } + + assertBothWays(Collections.synchronizedMap(new HashMap()), expected); + } + + public void testUnmodifiableMap() { + String expected = "" + + "\n" + + " \n" + + ""; + + assertBothWays(Collections.unmodifiableMap(new HashMap()), expected); + } + + public void testEmptyMap() { + assertBothWays(Collections.EMPTY_MAP, ""); + } + + public void testEmptyMapIsImmutable() { + List list = new ArrayList(); + list.add(Collections.EMPTY_MAP); + list.add(Collections.EMPTY_MAP); + assertBothWays(list, + "\n" + + " \n" + + " \n" + + ""); + } + + public void testEmptyMapIsSingleton() { + assertSame(Collections.EMPTY_MAP, xstream.fromXML("")); + } + + public void testSingletonMap() { + String expected =""+ + "\n" + + " \n" + + " \n" + + " microsoft\n" + + " windows\n" + + " \n" + + " \n" + + " x86\n" + + " p4\n" + + " \n" + + " \n" + + ""; + + assertBothWays(Collections.singletonMap(new Software("microsoft", "windows"), new Hardware("x86", "p4")), expected); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/MultipleObjectsInOneStreamTest.java b/xstream/src/test/com/thoughtworks/acceptance/MultipleObjectsInOneStreamTest.java new file mode 100644 index 0000000..902d9a4 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/MultipleObjectsInOneStreamTest.java @@ -0,0 +1,306 @@ +/* + * Copyright (C) 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 09. December 2005 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.Software; +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.MarshallingStrategy; +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.converters.DataHolder; +import com.thoughtworks.xstream.core.ReferenceByIdMarshaller; +import com.thoughtworks.xstream.core.ReferenceByIdUnmarshaller; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; +import com.thoughtworks.xstream.io.xml.XppReader; +import com.thoughtworks.xstream.mapper.Mapper; +import com.thoughtworks.xstream.testutil.CallLog; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; +import java.util.zip.Deflater; +import java.util.zip.DeflaterOutputStream; +import java.util.zip.Inflater; +import java.util.zip.InflaterInputStream; + + +public class MultipleObjectsInOneStreamTest extends AbstractAcceptanceTest { + + public static class Person extends StandardObject { + + private String firstName; + private String lastName; + private Person secretary; + + public Person(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + } + + public void testReadAndWriteMultipleObjectsInOneStream() { + xstream.alias("person", Person.class); + StringWriter buffer = new StringWriter(); + + // serialize + HierarchicalStreamWriter writer = new PrettyPrintWriter(buffer); + writer.startNode("people"); + xstream.marshal(new Person("Postman", "Pat"), writer); + xstream.marshal(new Person("Bob", "Builder"), writer); + xstream.marshal(new Person("Tinky", "Winky"), writer); + writer.endNode(); + + assertEquals("" + + "\n" + + " \n" + + " Postman\n" + + " Pat\n" + + " \n" + + " \n" + + " Bob\n" + + " Builder\n" + + " \n" + + " \n" + + " Tinky\n" + + " Winky\n" + + " \n" + + "", buffer.toString()); + + // deserialize + HierarchicalStreamReader reader = new XppReader(new StringReader(buffer.toString())); + + assertTrue("should be another object to read (1)", reader.hasMoreChildren()); + reader.moveDown(); + assertEquals(new Person("Postman", "Pat"), xstream.unmarshal(reader)); + reader.moveUp(); + + assertTrue("should be another object to read (2)", reader.hasMoreChildren()); + reader.moveDown(); + assertEquals(new Person("Bob", "Builder"), xstream.unmarshal(reader)); + reader.moveUp(); + + assertTrue("should be another object to read (3)", reader.hasMoreChildren()); + reader.moveDown(); + assertEquals(new Person("Tinky", "Winky"), xstream.unmarshal(reader)); + reader.moveUp(); + + assertFalse("should be no more objects", reader.hasMoreChildren()); + } + + public void testDrivenThroughObjectStream() throws IOException, ClassNotFoundException { + Writer writer = new StringWriter(); + xstream.alias("software", Software.class); + + ObjectOutputStream oos = xstream.createObjectOutputStream(writer); + oos.writeInt(123); + oos.writeObject("hello"); + oos.writeObject(new Software("tw", "xs")); + oos.close(); + + String expectedXml = "" + + "\n" + + " 123\n" + + " hello\n" + + " \n" + + " tw\n" + + " xs\n" + + " \n" + + ""; + + assertEquals(expectedXml, writer.toString()); + + ObjectInputStream ois = xstream.createObjectInputStream(new StringReader(writer + .toString())); + assertEquals(123, ois.readInt()); + assertEquals("hello", ois.readObject()); + assertEquals(new Software("tw", "xs"), ois.readObject()); + + try { + ois.readObject(); // As far as I can see this is the only clue the + // ObjectInputStream gives that it's done. + fail("Expected EOFException"); + } catch (EOFException expectedException) { + // good + } + } + + public void testDrivenThroughCompressedObjectStream() + throws IOException, ClassNotFoundException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + Writer writer = new OutputStreamWriter(new DeflaterOutputStream(baos, new Deflater( + Deflater.BEST_COMPRESSION)), "UTF-8"); + xstream.alias("software", Software.class); + + ObjectOutputStream oos = xstream.createObjectOutputStream(writer); + oos.writeInt(123); + oos.writeObject("hello"); + oos.writeObject(new Software("tw", "xs")); + oos.flush(); + oos.close(); + + byte[] data = baos.toByteArray(); + assertTrue("Too less data: " + data.length, data.length > 2); + + ObjectInputStream ois = xstream.createObjectInputStream(new InputStreamReader( + new InflaterInputStream(new ByteArrayInputStream(data), new Inflater()), "UTF-8")); + assertEquals(123, ois.readInt()); + assertEquals("hello", ois.readObject()); + assertEquals(new Software("tw", "xs"), ois.readObject()); + + try { + ois.readObject(); // As far as I can see this is the only clue the + // ObjectInputStream gives that it's done. + fail("Expected EOFException"); + } catch (EOFException expectedException) { + // good + } + } + + public void testObjectOutputStreamPropagatesCloseAndFlushEvents() throws IOException { + // setup + final CallLog log = new CallLog(); + Writer loggingWriter = new Writer() { + public void close() { + log.actual("close"); + } + + public void flush() { + log.actual("flush"); + } + + public void write(char cbuf[], int off, int len) { + // don't care about this + } + }; + + // expectations + log.expect("flush"); // TWO flushes are currently caused. Only one is needed, but + // this is no big deal. + log.expect("flush"); + log.expect("close"); + + // execute + ObjectOutputStream objectOutputStream = xstream.createObjectOutputStream(loggingWriter); + objectOutputStream.flush(); + objectOutputStream.close(); + + // verify + log.verify(); + } + + public void testObjectInputStreamPropegatesCloseEvent() throws IOException { + // setup + final CallLog log = new CallLog(); + Reader loggingReader = new StringReader("1") { + public void close() { + log.actual("close"); + } + }; + + // expectations + log.expect("close"); + + // execute + ObjectInputStream objectInputStream = xstream.createObjectInputStream(loggingReader); + objectInputStream.close(); + + // verify + log.verify(); + } + + public void testByDefaultDoesNotPreserveReferencesAcrossDifferentObjectsInStream() + throws Exception { + xstream.alias("person", Person.class); + + // Setup initial data: two object, one referencing another... + Person alice = new Person("Alice", "Thing"); + Person jane = new Person("Jane", "Blah"); + jane.secretary = alice; + + // Serialize the two individual objects. + StringWriter writer = new StringWriter(); + ObjectOutputStream out = xstream.createObjectOutputStream(writer); + out.writeObject(alice); + out.writeObject(jane); + out.close(); + + // Deserialize the two objects. + ObjectInputStream in = xstream.createObjectInputStream(new StringReader(writer + .toString())); + alice = (Person)in.readObject(); + jane = (Person)in.readObject(); + in.close(); + + assertNotSame(alice, jane.secretary); // NOT SAME + } + + static class ReusingReferenceByIdMarshallingStrategy implements MarshallingStrategy { + + private ReferenceByIdMarshaller marshaller; + private ReferenceByIdUnmarshaller unmarshaller; + + public void marshal(HierarchicalStreamWriter writer, Object obj, + ConverterLookup converterLookup, Mapper mapper, DataHolder dataHolder) { + if (marshaller == null) { + marshaller = new ReferenceByIdMarshaller(writer, converterLookup, mapper); + } + marshaller.start(obj, dataHolder); + } + + public Object unmarshal(Object root, HierarchicalStreamReader reader, + DataHolder dataHolder, ConverterLookup converterLookup, Mapper mapper) { + if (unmarshaller == null) { + unmarshaller = new ReferenceByIdUnmarshaller( + root, reader, converterLookup, mapper); + } + return unmarshaller.start(dataHolder); + } + } + + public void testSupportsOptionToPreserveReferencesAcrossDifferentObjectsInStream() + throws Exception { + xstream.alias("person", Person.class); + xstream.setMarshallingStrategy(new ReusingReferenceByIdMarshallingStrategy()); + + // Setup initial data: two object, one referencing another... + Person alice = new Person("Alice", "Thing"); + Person jane = new Person("Jane", "Blah"); + jane.secretary = alice; + + // Serialize the two individual objects. + StringWriter writer = new StringWriter(); + ObjectOutputStream out = xstream.createObjectOutputStream(writer); + out.writeObject(alice); + out.writeObject(jane); + out.close(); + + // Deserialize the two objects. + ObjectInputStream in = xstream.createObjectInputStream(new StringReader(writer + .toString())); + alice = (Person)in.readObject(); + jane = (Person)in.readObject(); + in.close(); + + assertSame(alice, jane.secretary); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/NamedLocalElementsTest.java b/xstream/src/test/com/thoughtworks/acceptance/NamedLocalElementsTest.java new file mode 100644 index 0000000..94b92c6 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/NamedLocalElementsTest.java @@ -0,0 +1,603 @@ +/* + * Copyright (C) 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 20. September 2013 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import com.thoughtworks.acceptance.objects.Category; +import com.thoughtworks.acceptance.objects.SampleMaps; +import com.thoughtworks.xstream.converters.extended.NamedArrayConverter; +import com.thoughtworks.xstream.converters.extended.NamedCollectionConverter; +import com.thoughtworks.xstream.converters.extended.NamedMapConverter; + +/** + * Tests named elements of collections and maps. + * + * @author Jörg Schaible + */ +public class NamedLocalElementsTest extends AbstractAcceptanceTest { + + protected void setUp() throws Exception { + super.setUp(); + xstream.alias("category", Category.class); + xstream.alias("maps", SampleMaps.class); + xstream.alias("arrays", Arrays.class); + xstream.aliasField("products", SampleMaps.class, "good"); + xstream.addDefaultImplementation(LinkedHashMap.class, Map.class); + } + + public void testListElementsWithFinalType() { + xstream.registerLocalConverter(Category.class, "products", + new NamedCollectionConverter(xstream.getMapper(), "product", String.class)); + + List products = new ArrayList(); + products.add("SiteMesh"); + products.add("XStream"); + Category category = new Category("Joe Walnes", "joe"); + category.setProducts(products); + + String expected = "" + + "\n" + + " Joe Walnes\n" + + " joe\n" + + " \n" + + " SiteMesh\n" + + " XStream\n" + + " \n" + + ""; + + assertBothWays(category, expected); + } + + public void testListElementsWithSuperTypes() { + xstream.registerLocalConverter(Category.class, "products", + new NamedCollectionConverter(xstream.getMapper(), "product", Object.class)); + + List products = new ArrayList(); + products.add("SiteMesh"); + products.add(new StringBuffer("XStream")); + Category category = new Category("Joe Walnes", "joe"); + category.setProducts(products); + + String expected = ("" + + "\n" + + " Joe Walnes\n" + + " joe\n" + + " \n" + + " SiteMesh\n" + + " XStream\n" + + " \n" + + "").replace('\'', '"'); + + assertBothWays(category, expected); + } + + public void testListWithNullElements() { + xstream.registerLocalConverter(Category.class, "products", + new NamedCollectionConverter(xstream.getMapper(), "product", String.class)); + + List products = new ArrayList(); + products.add("SiteMesh"); + products.add(null); + products.add("XStream"); + Category category = new Category("Joe Walnes", "joe"); + category.setProducts(products); + + String expected = ("" + + "\n" + + " Joe Walnes\n" + + " joe\n" + + " \n" + + " SiteMesh\n" + + " \n" + + " XStream\n" + + " \n" + + "").replace('\'', '"'); + + assertBothWays(category, expected); + } + + public void testMapElementsWithFinalType() { + xstream.registerLocalConverter(SampleMaps.class, "good", + new NamedMapConverter(xstream.getMapper(), "product", "name", String.class, "domain", String.class)); + + SampleMaps maps = new SampleMaps(); + maps.bad = null; + maps.good = new LinkedHashMap(); + maps.good.put("SiteMesh", "com.opensymphony"); + maps.good.put("XStream", "com.thoughtworks"); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " SiteMesh\n" + + " com.opensymphony\n" + + " \n" + + " \n" + + " XStream\n" + + " com.thoughtworks\n" + + " \n" + + " \n" + + ""; + + assertBothWays(maps, expected); + } + + public void testMapElementsWithSuperType() { + xstream.registerLocalConverter(SampleMaps.class, "good", + new NamedMapConverter(xstream.getMapper(), "product", "name", Object.class, "price", Number.class)); + + SampleMaps maps = new SampleMaps(); + maps.bad = null; + maps.good = new LinkedHashMap(); + maps.good.put("SiteMesh", new Integer(42)); + maps.good.put(new StringBuffer("XStream"), new Double(42)); + + String expected = ("" + + "\n" + + " \n" + + " \n" + + " SiteMesh\n" + + " 42\n" + + " \n" + + " \n" + + " XStream\n" + + " 42.0\n" + + " \n" + + " \n" + + "").replace('\'', '"'); + + assertBothWays(maps, expected); + } + + public void testMapWithNullElements() { + xstream.registerLocalConverter(SampleMaps.class, "good", + new NamedMapConverter(xstream.getMapper(), "product", "name", String.class, "domain", String.class)); + + SampleMaps maps = new SampleMaps(); + maps.bad = null; + maps.good = new LinkedHashMap(); + maps.good.put(null, "com.opensymphony"); + maps.good.put("XStream", null); + + String expected = ("" + + "\n" + + " \n" + + " \n" + + " \n" + + " com.opensymphony\n" + + " \n" + + " \n" + + " XStream\n" + + " \n" + + " \n" + + " \n" + + "").replace('\'', '"'); + + assertBothWays(maps, expected); + } + + public void testMapWithSwappedKeyAndValueElements() { + xstream.registerLocalConverter(SampleMaps.class, "good", + new NamedMapConverter(xstream.getMapper(), "product", "name", String.class, "domain", String.class)); + + SampleMaps maps = new SampleMaps(); + maps.bad = null; + maps.good = new LinkedHashMap(); + maps.good.put("SiteMesh", "com.opensymphony"); + maps.good.put("XStream", "com.thoughtworks"); + + String xml = "" + + "\n" + + " \n" + + " \n" + + " SiteMesh\n" + + " com.opensymphony\n" + + " \n" + + " \n" + + " com.thoughtworks\n" + + " XStream\n" + + " \n" + + " \n" + + ""; + + assertEquals(maps, xstream.fromXML(xml)); + } + + public void testMapElementsUsingSameNames() { + xstream.registerLocalConverter(SampleMaps.class, "good", + new NamedMapConverter(xstream.getMapper(), "test", "test", String.class, "test", String.class)); + + SampleMaps maps = new SampleMaps(); + maps.bad = null; + maps.good = new LinkedHashMap(); + maps.good.put("SiteMesh", "com.opensymphony"); + maps.good.put("XStream", "com.thoughtworks"); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " SiteMesh\n" + + " com.opensymphony\n" + + " \n" + + " \n" + + " XStream\n" + + " com.thoughtworks\n" + + " \n" + + " \n" + + ""; + + assertBothWays(maps, expected); + } + + public void testMapElementsWithoutEntry() { + xstream.registerLocalConverter(SampleMaps.class, "good", + new NamedMapConverter(xstream.getMapper(), null, "name", String.class, "domain", String.class)); + + SampleMaps maps = new SampleMaps(); + maps.bad = null; + maps.good = new LinkedHashMap(); + maps.good.put("SiteMesh", "com.opensymphony"); + maps.good.put("XStream", "com.thoughtworks"); + + String expected = "" + + "\n" + + " \n" + + " SiteMesh\n" + + " com.opensymphony\n" + + " XStream\n" + + " com.thoughtworks\n" + + " \n" + + ""; + + assertBothWays(maps, expected); + } + + public void testMapWithNullElementsWithoutEntry() { + xstream.registerLocalConverter(SampleMaps.class, "good", + new NamedMapConverter(xstream.getMapper(), null, "name", String.class, "domain", String.class)); + + SampleMaps maps = new SampleMaps(); + maps.bad = null; + maps.good = new LinkedHashMap(); + maps.good.put(null, "com.opensymphony"); + maps.good.put("XStream", null); + + String expected = ("" + + "\n" + + " \n" + + " \n" + + " com.opensymphony\n" + + " XStream\n" + + " \n" + + " \n" + + "").replace('\'', '"'); + + assertBothWays(maps, expected); + } + + public void testMapWithSwappedKeyAndValueElementsWithoutEntry() { + xstream.registerLocalConverter(SampleMaps.class, "good", + new NamedMapConverter(xstream.getMapper(), null, "name", String.class, "domain", String.class)); + + SampleMaps maps = new SampleMaps(); + maps.bad = null; + maps.good = new LinkedHashMap(); + maps.good.put("SiteMesh", "com.opensymphony"); + maps.good.put("XStream", "com.thoughtworks"); + + String xml = "" + + "\n" + + " \n" + + " com.opensymphony\n" + + " SiteMesh\n" + + " XStream\n" + + " com.thoughtworks\n" + + " \n" + + ""; + + assertEquals(maps, xstream.fromXML(xml)); + } + + public void testMapElementsUsingSameNamesWithoutEntry() { + xstream.registerLocalConverter(SampleMaps.class, "good", + new NamedMapConverter(xstream.getMapper(), null, "test", String.class, "test", String.class)); + + SampleMaps maps = new SampleMaps(); + maps.bad = null; + maps.good = new LinkedHashMap(); + maps.good.put("SiteMesh", "com.opensymphony"); + maps.good.put("XStream", "com.thoughtworks"); + + String expected = "" + + "\n" + + " \n" + + " SiteMesh\n" + + " com.opensymphony\n" + + " XStream\n" + + " com.thoughtworks\n" + + " \n" + + ""; + + assertBothWays(maps, expected); + } + + public void testMapElementsUsingAttributesOnly() { + xstream.registerLocalConverter( + SampleMaps.class, "good", new NamedMapConverter( + xstream.getMapper(), "product", "name", String.class, "domain", String.class, + true, true, xstream.getConverterLookup())); + + SampleMaps maps = new SampleMaps(); + maps.bad = null; + maps.good = new LinkedHashMap(); + maps.good.put("SiteMesh", "com.opensymphony"); + maps.good.put("XStream", "com.thoughtworks"); + + String expected = ("" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "").replace('\'', '"'); + + assertBothWays(maps, expected); + } + + public void testMapElementsWithNullUsingAttributesOnly() { + xstream.registerLocalConverter( + SampleMaps.class, "good", new NamedMapConverter( + xstream.getMapper(), "product", "name", String.class, "domain", String.class, + true, true, xstream.getConverterLookup())); + + SampleMaps maps = new SampleMaps(); + maps.bad = null; + maps.good = new LinkedHashMap(); + maps.good.put(null, "com.opensymphony"); + maps.good.put("XStream", null); + + String expected = ("" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "").replace('\'', '"'); + + assertBothWays(maps, expected); + } + + public void testMapElementsUsingAttributeAndText() { + xstream.registerLocalConverter( + SampleMaps.class, "good", new NamedMapConverter( + xstream.getMapper(), "product", "name", String.class, null, String.class, + true, false, xstream.getConverterLookup())); + + SampleMaps maps = new SampleMaps(); + maps.bad = null; + maps.good = new LinkedHashMap(); + maps.good.put("SiteMesh", "com.opensymphony"); + maps.good.put("XStream", "com.thoughtworks"); + + String expected = ("" + + "\n" + + " \n" + + " com.opensymphony\n" + + " com.thoughtworks\n" + + " \n" + + "").replace('\'', '"'); + + assertBothWays(maps, expected); + } + + public void testMapElementsUsingAttributeForKeyOnly() { + xstream.registerLocalConverter( + SampleMaps.class, "good", new NamedMapConverter( + xstream.getMapper(), "product", "name", String.class, "domain", String.class, + true, false, xstream.getConverterLookup())); + + SampleMaps maps = new SampleMaps(); + maps.bad = null; + maps.good = new LinkedHashMap(); + maps.good.put("SiteMesh", "com.opensymphony"); + maps.good.put("XStream", "com.thoughtworks"); + + String expected = ("" + + "\n" + + " \n" + + " \n" + + " com.opensymphony\n" + + " \n" + + " \n" + + " com.thoughtworks\n" + + " \n" + + " \n" + + "").replace('\'', '"'); + + assertBothWays(maps, expected); + } + + public void testMapElementsUsingAttributeForValueOnly() { + xstream.registerLocalConverter( + SampleMaps.class, "good", new NamedMapConverter( + xstream.getMapper(), "product", "name", String.class, "domain", String.class, + false, true, xstream.getConverterLookup())); + + SampleMaps maps = new SampleMaps(); + maps.bad = null; + maps.good = new LinkedHashMap(); + maps.good.put("SiteMesh", "com.opensymphony"); + maps.good.put("XStream", "com.thoughtworks"); + + String expected = ("" + + "\n" + + " \n" + + " \n" + + " SiteMesh\n" + + " \n" + + " \n" + + " XStream\n" + + " \n" + + " \n" + + "").replace('\'', '"'); + + assertBothWays(maps, expected); + } + + public void testInvalidMapConfiguration() { + test(null, "key", "value", true, true); + test(null, "key", "value", false, true); + test(null, "key", "value", true, false); + test(null, "key", null, false, false); + test("entry", "key", null, false, false); + test("entry", "key", null, false, true); + test("entry", null, "value", false, false); + test("entry", null, "value", true, false); + test("entry", "foo", "foo", true, true); + } + + private void test(String entry, String key, String value, boolean keyAttr, boolean valueAttr) { + try { + new NamedMapConverter( + xstream.getMapper(), entry, key, String.class, value, String.class, keyAttr, + valueAttr, xstream.getConverterLookup()); + fail("Thrown " + IllegalArgumentException.class.getName() + " expected"); + } catch (final IllegalArgumentException e) { + // OK + } + } + + public static class Arrays { + String[] strings; + Object[] objects; + int[] ints; + short[][] shortArrays; + } + + public void testArrayWithFinalType() { + xstream.registerLocalConverter(Arrays.class, "strings", + new NamedArrayConverter(String[].class, xstream.getMapper(), "name")); + + Arrays arrays = new Arrays(); + arrays.strings = new String[] { + "joe", "mauro" + }; + + String expected = "" + + "\n" + + " \n" + + " joe\n" + + " mauro\n" + + " \n" + + ""; + + assertBothWays(arrays, expected); + } + + public void testArrayWithSuperTypes() { + xstream.registerLocalConverter(Arrays.class, "objects", + new NamedArrayConverter(Object[].class, xstream.getMapper(), "item")); + + Arrays arrays = new Arrays(); + arrays.objects = new Object[] { + "joe", Boolean.TRUE, new Integer(47) + }; + + String expected = ("" + + "\n" + + " \n" + + " joe\n" + + " true\n" + + " 47\n" + + " \n" + + "").replace('\'', '"'); + + assertBothWays(arrays, expected); + } + + public void testArrayWithNullElement() { + xstream.registerLocalConverter(Arrays.class, "strings", + new NamedArrayConverter(String[].class, xstream.getMapper(), "name")); + + Arrays arrays = new Arrays(); + arrays.strings = new String[] { + "joe", null, "mauro" + }; + + String expected = "" + + "\n" + + " \n" + + " joe\n" + + " \n" + + " mauro\n" + + " \n" + + ""; + + assertBothWays(arrays, expected); + } + + public void testArrayWithPrimitives() { + xstream.registerLocalConverter(Arrays.class, "ints", + new NamedArrayConverter(int[].class, xstream.getMapper(), "value")); + + Arrays arrays = new Arrays(); + arrays.ints = new int[] { + 47, 0, -3 + }; + + String expected = "" + + "\n" + + " \n" + + " 47\n" + + " 0\n" + + " -3\n" + + " \n" + + ""; + + assertBothWays(arrays, expected); + } + + public void testArrayWithPrimitiveArrays() { + xstream.registerLocalConverter(Arrays.class, "shortArrays", + new NamedArrayConverter(short[][].class, xstream.getMapper(), "values")); + + Arrays arrays = new Arrays(); + arrays.shortArrays = new short[][] { + {47, 0, -3}, + null, + {13, 7} + }; + + String expected = "" + + "\n" + + " \n" + + " \n" + + " 47\n" + + " 0\n" + + " -3\n" + + " \n" + + " \n" + + " \n" + + " 13\n" + + " 7\n" + + " \n" + + " \n" + + ""; + + assertBothWays(arrays, expected); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/OmitFieldsTest.java b/xstream/src/test/com/thoughtworks/acceptance/OmitFieldsTest.java new file mode 100644 index 0000000..3d10cf3 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/OmitFieldsTest.java @@ -0,0 +1,404 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2010, 2012, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 20. June 2005 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.mapper.Mapper; +import com.thoughtworks.xstream.mapper.MapperWrapper; + + +public class OmitFieldsTest extends AbstractAcceptanceTest { + + public static class Thing extends StandardObject { + transient String alwaysIgnore; + String sometimesIgnore; + String neverIgnore; + } + + public void testTransientFieldsAreOmittedByDefault() { + Thing in = new Thing(); + in.alwaysIgnore = "a"; + in.sometimesIgnore = "b"; + in.neverIgnore = "c"; + + String expectedXml = "" + + "\n" + + " b\n" + + " c\n" + + ""; + + xstream.alias("thing", Thing.class); + + String actualXml = xstream.toXML(in); + assertEquals(expectedXml, actualXml); + + Thing out = (Thing)xstream.fromXML(actualXml); + assertEquals(null, out.alwaysIgnore); + assertEquals("b", out.sometimesIgnore); + assertEquals("c", out.neverIgnore); + } + + public void testAdditionalFieldsCanBeExplicitlyOmitted() { + Thing in = new Thing(); + in.alwaysIgnore = "a"; + in.sometimesIgnore = "b"; + in.neverIgnore = "c"; + + String expectedXml = "" // + + "\n" // + + " c\n" // + + ""; + + xstream.alias("thing", Thing.class); + xstream.omitField(Thing.class, "sometimesIgnore"); + + String actualXml = xstream.toXML(in); + assertEquals(expectedXml, actualXml); + + Thing out = (Thing)xstream.fromXML(actualXml); + assertEquals(null, out.alwaysIgnore); + assertEquals(null, out.sometimesIgnore); + assertEquals("c", out.neverIgnore); + } + + public static class DerivedThing extends Thing { + String derived; + } + + public void testInheritedFieldsCanBeExplicitlyOmittedThroughFacade() { + DerivedThing in = new DerivedThing(); + in.alwaysIgnore = "a"; + in.sometimesIgnore = "b"; + in.neverIgnore = "c"; + in.derived = "d"; + + String expectedXml = "" + + "\n" + + " c\n" + + " d\n" + + ""; + + xstream.alias("thing", DerivedThing.class); + xstream.omitField(Thing.class, "sometimesIgnore"); + + String actualXml = xstream.toXML(in); + assertEquals(expectedXml, actualXml); + + DerivedThing out = (DerivedThing)xstream.fromXML(actualXml); + assertEquals(null, out.alwaysIgnore); + assertEquals(null, out.sometimesIgnore); + assertEquals("c", out.neverIgnore); + assertEquals("d", out.derived); + } + + public void testFieldsOfDerivedTypesCanBeExplicitlyOmittedThroughFacade() { + DerivedThing in = new DerivedThing(); + in.alwaysIgnore = "a"; + in.sometimesIgnore = "b"; + in.neverIgnore = "c"; + in.derived = "d"; + + String expectedXml = "" + + "\n" + + " b\n" + + " c\n" + + ""; + + xstream.alias("thing", DerivedThing.class); + xstream.omitField(DerivedThing.class, "derived"); + + String actualXml = xstream.toXML(in); + assertEquals(expectedXml, actualXml); + + DerivedThing out = (DerivedThing)xstream.fromXML(actualXml); + assertEquals(null, out.alwaysIgnore); + assertEquals("b", out.sometimesIgnore); + assertEquals("c", out.neverIgnore); + assertEquals(null, out.derived); + } + + public static class AnotherThing extends StandardObject { + String stuff; + String cheese; + String myStuff; + String myCheese; + } + + public void testFieldsCanBeIgnoredUsingCustomStrategy() { + AnotherThing in = new AnotherThing(); + in.stuff = "a"; + in.cheese = "b"; + in.myStuff = "c"; + in.myCheese = "d"; + + String expectedXml = "" + + "\n" + + " a\n" + + " b\n" + + ""; + + class OmitFieldsWithMyPrefixMapper extends MapperWrapper { + public OmitFieldsWithMyPrefixMapper(Mapper wrapped) { + super(wrapped); + } + + public boolean shouldSerializeMember(Class definedIn, String fieldName) { + return !fieldName.startsWith("my"); + } + } + + xstream = new XStream() { + protected MapperWrapper wrapMapper(MapperWrapper next) { + return new OmitFieldsWithMyPrefixMapper(next); + } + }; + + xstream.allowTypes(new Class[]{AnotherThing.class}); + xstream.alias("thing", AnotherThing.class); + + String actualXml = xstream.toXML(in); + assertEquals(expectedXml, actualXml); + + AnotherThing out = (AnotherThing)xstream.fromXML(actualXml); + assertEquals("a", out.stuff); + assertEquals("b", out.cheese); + assertEquals(null, out.myStuff); + assertEquals(null, out.myCheese); + } + + public void testDeletedElementCanBeOmitted() { + String expectedXml = "" + + "\n" + + " c\n" + + " b\n" + + " c\n" + + ""; + + xstream.alias("thing", Thing.class); + xstream.omitField(Thing.class, "meanwhileDeletedIgnore"); + + Thing out = (Thing)xstream.fromXML(expectedXml); + assertEquals("b", out.sometimesIgnore); + assertEquals("c", out.neverIgnore); + } + + public void testDeletedElementWithReferenceCanBeOmitted() { + String expectedXml = "" + + "\n" + + " \n" + + " b\n" + + " c\n" + + ""; + + xstream.alias("thing", Thing.class); + xstream.omitField(Thing.class, "meanwhileDeletedIgnore"); + + Thing out = (Thing)xstream.fromXML(expectedXml); + assertEquals("b", out.sometimesIgnore); + assertEquals("c", out.neverIgnore); + } + + public void testDeletedElementWithClassAttributeCanBeOmitted() { + String expectedXml = "" + + "\n" + + " \n" + + " b\n" + + " c\n" + + ""; + + xstream.alias("thing", Thing.class); + xstream.omitField(Thing.class, "meanwhileDeletedIgnore"); + + Thing out = (Thing)xstream.fromXML(expectedXml); + assertEquals("b", out.sometimesIgnore); + assertEquals("c", out.neverIgnore); + } + + public void testDeletedAttributeCanBeOmitted() { + String expectedXml = "" + + "\n" + + " b\n" + + " c\n" + + ""; + + xstream.alias("thing", Thing.class); + xstream.omitField(Thing.class, "meanwhileDeletedIgnore"); + + Thing out = (Thing)xstream.fromXML(expectedXml); + assertEquals("b", out.sometimesIgnore); + assertEquals("c", out.neverIgnore); + } + + public void testAttributeCanBeOmitted() { + String expectedXml = ""; + + xstream.alias("thing", Thing.class); + xstream.useAttributeFor(String.class); + xstream.omitField(Thing.class, "sometimesIgnore"); + + Thing in = new Thing(); + in.alwaysIgnore = "a"; + in.sometimesIgnore = "b"; + in.neverIgnore = "c"; + assertEquals(expectedXml, xstream.toXML(in)); + + Thing out = (Thing)xstream.fromXML(expectedXml); + assertNull(out.sometimesIgnore); + assertEquals("c", out.neverIgnore); + } + + public void testExistingFieldsCanBeExplicitlyOmittedAtDeserialization() { + String actualXml = "" + + "\n" + + " foo\n" + + " c\n" + + ""; + + xstream.alias("thing", Thing.class); + xstream.omitField(Thing.class, "sometimesIgnore"); + + Thing out = (Thing)xstream.fromXML(actualXml); + assertEquals(null, out.alwaysIgnore); + assertEquals(null, out.sometimesIgnore); + assertEquals("c", out.neverIgnore); + } + + public void testExistingFieldsInDerivedClassesCanBeExplicitlyOmittedAtDeserialization() { + String actualXml = "" + + "\n" + + " b\n" + + " c\n" + + " foo\n" + + ""; + + xstream.alias("thing", DerivedThing.class); + xstream.omitField(DerivedThing.class, "derived"); + + DerivedThing out = (DerivedThing)xstream.fromXML(actualXml); + assertEquals(null, out.alwaysIgnore); + assertEquals("b", out.sometimesIgnore); + assertEquals("c", out.neverIgnore); + assertEquals(null, out.derived); + } + + public void testExistingInheritedFieldsCanBeExplicitlyOmittedAtDeserialization() { + String actualXml = "" + + "\n" + + " foo\n" + + " c\n" + + " d\n" + + ""; + + xstream.alias("thing", DerivedThing.class); + xstream.omitField(Thing.class, "sometimesIgnore"); + + DerivedThing out = (DerivedThing)xstream.fromXML(actualXml); + assertEquals(null, out.alwaysIgnore); + assertEquals(null, out.sometimesIgnore); + assertEquals("c", out.neverIgnore); + assertEquals("d", out.derived); + } + + public void testIgnoreUnknownElementsMatchingPattern() { + String actualXml = "" + + "\n" + + " foo\n" + + " c\n" + + " f\n" + + " d\n" + + ""; + + xstream.alias("thing", DerivedThing.class); + xstream.omitField(Thing.class, "sometimesIgnore"); + xstream.ignoreUnknownElements("foo.*"); + + DerivedThing out = (DerivedThing)xstream.fromXML(actualXml); + assertEquals(null, out.alwaysIgnore); + assertEquals(null, out.sometimesIgnore); + assertEquals("c", out.neverIgnore); + assertEquals("d", out.derived); + + try { + xstream.fromXML(actualXml.replaceAll("foobar", "unknown")); + fail("Thrown " + ConversionException.class.getName() + " expected"); + } catch (final ConversionException e) { + String message = e.getMessage(); + assertTrue(message, + e.getMessage().substring(0, message.indexOf('\n')).endsWith( + DerivedThing.class.getName() + ".unknown")); + } + } + + public void testIgnoreNonExistingElementsMatchingTypeAlias() { + xstream.alias("thing", Thing.class); + xstream.ignoreUnknownElements("string"); + Thing thing = new Thing(); + String provided = "" + + "\n" + + " string 1\n" + + ""; + String expected = ""; + assertWithAsymmetricalXml(thing, provided, expected); + } + + public void testIgnoredElementIsNotInstantiated() { + xstream.alias("thing", Thing.class); + xstream.ignoreUnknownElements("int"); + Thing thing = new Thing(); + String provided = "" + + "\n" + + " invalid\n" + + ""; + String expected = ""; + assertWithAsymmetricalXml(thing, provided, expected); + } + + static class ThingAgain extends Thing { + String sometimesIgnore; + + void setHidden(String s) { + super.sometimesIgnore = s; + } + + String getHidden() { + return super.sometimesIgnore; + } + } + + public void testAnOmittedFieldMakesADefinedInAttributeSuperfluous() { + ThingAgain in = new ThingAgain(); + in.alwaysIgnore = "a"; + in.setHidden("b"); + in.neverIgnore = "c"; + in.sometimesIgnore = "d"; + + xstream.alias("thing", ThingAgain.class); + xstream.omitField(ThingAgain.class, "sometimesIgnore"); + + String expectedXml = "" + + "\n" + + " b\n" + + " c\n" + + ""; + + String actualXml = xstream.toXML(in); + assertEquals(expectedXml, actualXml); + + ThingAgain out = (ThingAgain)xstream.fromXML(expectedXml); + assertNull(out.alwaysIgnore); + assertEquals("b", out.getHidden()); + assertEquals("c", out.neverIgnore); + assertNull(out.sometimesIgnore); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/PersistenceTest.java b/xstream/src/test/com/thoughtworks/acceptance/PersistenceTest.java new file mode 100644 index 0000000..0dda549 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/PersistenceTest.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. November 2008 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.SampleLists; +import com.thoughtworks.acceptance.objects.Software; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.persistence.FilePersistenceStrategy; +import com.thoughtworks.xstream.persistence.XmlArrayList; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; + +/** + * Tests the persistence package. + * + * @author Jörg Schaible + */ +public class PersistenceTest extends AbstractAcceptanceTest { + + private File dir; + + protected void setUp() throws Exception { + super.setUp(); + dir = new File("target/test-storage"); + dir.mkdirs(); + cleanUp(); + } + + protected void tearDown() throws Exception { + cleanUp(); + dir.delete(); + super.tearDown(); + } + + private void cleanUp() { + File[] files = dir.listFiles(); + for(int i = 0; i < files.length; ++i) { + if (files[i].isFile()) { + files[i].delete(); + } + } + } + + private final class PersistenceArrayListConverter implements Converter { + public void marshal(Object source, HierarchicalStreamWriter writer, + MarshallingContext context) { + final XmlArrayList list = new XmlArrayList(new FilePersistenceStrategy(dir, xstream)); + context.convertAnother(dir); + list.addAll((Collection)source); + } + + public Object unmarshal(HierarchicalStreamReader reader, + UnmarshallingContext context) { + final File directory = (File)context.convertAnother(null, File.class); + final XmlArrayList persistentList = new XmlArrayList(new FilePersistenceStrategy(directory, xstream)); + final ArrayList list = new ArrayList(persistentList); + //persistentList.clear(); // remove files + return list; + } + + public boolean canConvert(Class type) { + return type == ArrayList.class; + } + } + + public void testCanUsePersistenceCollectionAsConverter() throws IOException { + xstream.alias("lists", SampleLists.class); + xstream.alias("software", Software.class); + xstream.registerLocalConverter(SampleLists.class, "good", new PersistenceArrayListConverter()); + + SampleLists lists = new SampleLists(); + lists.good.add("Guilherme"); + lists.good.add(new Integer(1970)); + lists.good.add(new Software("Codehaus", "XStream")); + + String expected = "" + + "\n" + + " " + dir.getPath() + "\n" + + " \n" + + ""; + + // assumes 'lists' is serialized first + SampleLists serialized = (SampleLists)assertBothWays(lists, expected); + + // compare original list and list written in separate XML file + assertEquals(lists.good, serialized.good); + + // retrieve value from external file + FileInputStream inputStream = new FileInputStream(new File(dir, "int@2.xml")); + try { + assertEquals(lists.good.get(2), xstream.fromXML(inputStream)); + } finally { + inputStream.close(); + } + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/QNameMappedConcreteClassesTest.java b/xstream/src/test/com/thoughtworks/acceptance/QNameMappedConcreteClassesTest.java new file mode 100644 index 0000000..2d363f9 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/QNameMappedConcreteClassesTest.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2011, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. October 2004 by James Strachan + */ +package com.thoughtworks.acceptance; + +import java.util.ArrayList; + +import javax.xml.namespace.QName; + +import com.thoughtworks.acceptance.someobjects.Handler; +import com.thoughtworks.acceptance.someobjects.Protocol; +import com.thoughtworks.acceptance.someobjects.WithList; +import com.thoughtworks.acceptance.someobjects.X; +import com.thoughtworks.acceptance.someobjects.Y; +import com.thoughtworks.xstream.io.HierarchicalStreamDriver; +import com.thoughtworks.xstream.io.xml.BEAStaxDriver; +import com.thoughtworks.xstream.io.xml.QNameMap; +import com.thoughtworks.xstream.io.xml.StaxDriver; + +public class QNameMappedConcreteClassesTest extends AbstractAcceptanceTest { + + public static final String XML_HEADER = ""; + + protected QNameMap qnameMap; + protected String namespace = getDefaultNS(WithList.class); + + public void testUsingNamespace() { + // lets register some qnames + QName qname = new QName(namespace, "withList", "w"); + qnameMap.registerMapping(qname, WithList.class); + + WithList withList = new WithList(); + withList.things = new ArrayList(); + + String expected ="" + + XML_HEADER + + "" + + "" + + ""; + + assertBothWays(withList, expected); + } + + public void testUsingDefaultNamespace() { + qnameMap.setDefaultNamespace(namespace); + xstream.alias("withList", WithList.class); + + WithList withList = new WithList(); + withList.things = new ArrayList(); + + String expected = + XML_HEADER + + "" + + "" + + ""; + + assertBothWays(withList, expected); + } + + public void testUsingDefaultNamespaceAndPrefix() { + qnameMap.setDefaultNamespace(namespace); + qnameMap.setDefaultPrefix("x"); + QName qname = new QName(namespace, "withList", "x"); + qnameMap.registerMapping(qname, WithList.class); + + WithList withList = new WithList(); + withList.things = new ArrayList(); + + String expected = + XML_HEADER + + "" + + "" + + ""; + + assertBothWays(withList, expected); + } + + public void testUsingDifferentNamespaces() { + // lets register some qnames + qnameMap.registerMapping(new QName(namespace, "withList", "w"), WithList.class); + qnameMap.registerMapping(new QName("urn:foo", "things", "f"), "things"); + + WithList withList = new WithList(); + withList.things = new ArrayList(); + + String expected = + XML_HEADER + + "" + + "" + + ""; + + assertBothWays(withList, expected); + } + + public void testUsingDifferentNamespacesWithAliases() { + xstream.alias("handler", X.class); + xstream.alias("protocol", Y.class); + + qnameMap.registerMapping(new QName(getDefaultNS(Handler.class)+1, "handler", "h"), "handler"); + qnameMap.registerMapping(new QName(getDefaultNS(Protocol.class)+2, "protocol", "p"), "innerObj"); + + X x = new X(); + x.aStr = "foo"; + x.anInt = 42; + x.innerObj = new Y(); + x.innerObj.yField = "YField"; + + String expected = + XML_HEADER + + "" + + "foo" + + "42" + + "" + + "YField" + + "" + + ""; + + assertBothWays(x, expected); + } + + protected HierarchicalStreamDriver createDriver() { + // careful, called from inside base class constructor + qnameMap = new QNameMap(); + StaxDriver driver = new BEAStaxDriver(qnameMap); + driver.setRepairingNamespace(false); + return driver; + } + + protected String getDefaultNS(Class type) { + return "java://" + type.getPackage().getName(); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/ReadResolveTest.java b/xstream/src/test/com/thoughtworks/acceptance/ReadResolveTest.java new file mode 100644 index 0000000..f8c5213 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/ReadResolveTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. May 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.StatusEnum; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +/** + * @author Chris Kelly + * @author Joe Walnes + */ +public class ReadResolveTest extends AbstractAcceptanceTest { + + public void testReadResolveWithDefaultSerialization() throws IOException, ClassNotFoundException { + StatusEnum status = StatusEnum.STARTED; + + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + ObjectOutputStream os = new ObjectOutputStream(bout); + os.writeObject(status); + + byte[] bArray = bout.toByteArray(); + StatusEnum rStatus = null; + ObjectInputStream in = null; + + ByteArrayInputStream bin = new ByteArrayInputStream(bArray); + in = new ObjectInputStream(bin); + rStatus = (StatusEnum) in.readObject(); + assertNotNull(rStatus); + + assertSame(status, rStatus); + } + + public void testReadResolveWithXStream() { + StatusEnum status = StatusEnum.STARTED; + + String xml = xstream.toXML(status); + StatusEnum rStatus = (StatusEnum) xstream.fromXML(xml); + + assertSame(status, rStatus); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/ReflectionClassesTest.java b/xstream/src/test/com/thoughtworks/acceptance/ReflectionClassesTest.java new file mode 100644 index 0000000..fe11115 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/ReflectionClassesTest.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 08. April 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +public class ReflectionClassesTest extends AbstractAcceptanceTest { + public static class StupidObject { + public String aField; + public static int aStaticField; + public StupidObject(String arg) { + } + + public void aMethod(String something) { + } + + public void aMethod(int cheese) { + } + + public static void aStaticMethod(boolean bool) { + } + } + + public void testReflectionMethod() throws NoSuchMethodException { + Method method = StupidObject.class.getMethod("aMethod", new Class[]{String.class}); + + String expected = + "\n" + + " com.thoughtworks.acceptance.ReflectionClassesTest$StupidObject\n" + + " aMethod\n" + + " \n" + + " java.lang.String\n" + + " \n" + + ""; + + assertBothWays(method, expected); + } + + public void testReflectionStaticMethod() throws NoSuchMethodException { + Method method = StupidObject.class.getMethod("aStaticMethod", new Class[]{boolean.class}); + + String expected = + "\n" + + " com.thoughtworks.acceptance.ReflectionClassesTest$StupidObject\n" + + " aStaticMethod\n" + + " \n" + + " boolean\n" + + " \n" + + ""; + + assertBothWays(method, expected); + } + + public void testReflectionConstructor() throws NoSuchMethodException { + Constructor constructor = StupidObject.class.getConstructor(new Class[]{String.class}); + + String expected = + "\n" + + " com.thoughtworks.acceptance.ReflectionClassesTest$StupidObject\n" + + " \n" + + " java.lang.String\n" + + " \n" + + ""; + + assertBothWays(constructor, expected); + } + + public void testSupportsPrimitiveTypes() { + assertBothWays(int.class, "int"); + } + + public void testReflectionField() throws NoSuchFieldException { + Field field = StupidObject.class.getField("aField"); + + String expected = + "\n" + + " aField\n" + + " com.thoughtworks.acceptance.ReflectionClassesTest$StupidObject\n" + + ""; + + assertBothWays(field, expected); + } + + public void testReflectionStaticField() throws NoSuchFieldException { + Field field = StupidObject.class.getField("aStaticField"); + + String expected = + "\n" + + " aStaticField\n" + + " com.thoughtworks.acceptance.ReflectionClassesTest$StupidObject\n" + + ""; + + assertBothWays(field, expected); + } + + public void testReflectionFieldMigrationFrom13() throws NoSuchFieldException { + Field field = StupidObject.class.getField("aField"); + + String xml = + "\n" + + " false\n" + + " com.thoughtworks.acceptance.ReflectionClassesTest$StupidObject\n" + + " 0\n" + + " aField\n" + + " java.lang.String\n" + + " 1\n" + + " \n" + + " false\n" + + " com.thoughtworks.acceptance.ReflectionClassesTest$StupidObject\n" + + " 0\n" + + " aField\n" + + " java.lang.String\n" + + " 1\n" + + " \n" + + ""; + + assertEquals(field, xstream.fromXML(xml)); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/RelativeSingleNodeXPathReferenceTest.java b/xstream/src/test/com/thoughtworks/acceptance/RelativeSingleNodeXPathReferenceTest.java new file mode 100644 index 0000000..d313db1 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/RelativeSingleNodeXPathReferenceTest.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. July 2011 by Joerg Schaible by merging + * RelativeSingleNodeXPathCircularReferenceTest and + * RelativeSingleNodeXPathDuplicateReferenceTest. + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.util.ArrayList; +import java.util.List; + + +public class RelativeSingleNodeXPathReferenceTest extends AbstractReferenceTest { + + // tests inherited from superclass + + protected void setUp() throws Exception { + super.setUp(); + xstream.setMode(XStream.SINGLE_NODE_XPATH_RELATIVE_REFERENCES); + } + + public void testXmlContainsReferencePaths() { + + Thing sameThing = new Thing("hello"); + Thing anotherThing = new Thing("hello"); + + List list = new ArrayList(); + list.add(sameThing); + list.add(sameThing); + list.add(anotherThing); + + String expected = "" + + "\n" + + " \n" + + " hello\n" + + " \n" + + " \n" + + " \n" + + " hello\n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(list)); + } + + public void testTree() { + TreeElement root = new TreeElement("X"); + TreeElement left = new TreeElement("Y"); + TreeElement right = new TreeElement("Z"); + root.left = left; + root.right = right; + left.left = new TreeElement(root.name); + right.right = new TreeElement(left.name); + right.left = left.left; + + xstream.alias("elem", TreeElement.class); + String expected = "" + + "\n" + + " X\n" + + " \n" + + " Y\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " Z\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(root)); + } + + public void testReplacedReference() { + String expectedXml = "" + + "\n" + + " parent\n" + + " \n" + + " \n" + + " child\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + replacedReference(expectedXml); + } + + public void testCanReferenceDeserializedNullValues() { + xstream.alias("test", Mapper.Null.class); + String xml = "" + + "\n" + + " \n" + + " \n" + + ""; + List list = (List)xstream.fromXML(xml); + assertEquals(2, list.size()); + assertNull(list.get(0)); + assertNull(list.get(1)); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/RelativeXPathReferenceTest.java b/xstream/src/test/com/thoughtworks/acceptance/RelativeXPathReferenceTest.java new file mode 100644 index 0000000..33c90df --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/RelativeXPathReferenceTest.java @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. July 2011 by Joerg Schaible by merging RelativeXPathCircularReferenceTest, + * RelativeXPathDuplicateReferenceTest, RelativeXPathNestedCircularReferenceTest and + * RelativeXPathReplacedReferenceTest. + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +public class RelativeXPathReferenceTest extends AbstractReferenceTest { + + // tests inherited from superclass + + protected void setUp() throws Exception { + super.setUp(); + xstream.setMode(XStream.XPATH_RELATIVE_REFERENCES); + } + + public void testXmlContainsReferencePaths() { + + Thing sameThing = new Thing("hello"); + Thing anotherThing = new Thing("hello"); + + List list = new ArrayList(); + list.add(sameThing); + list.add(sameThing); + list.add(anotherThing); + + String expected = "" + + "\n" + + " \n" + + " hello\n" + + " \n" + + " \n" + + " \n" + + " hello\n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(list)); + } + + public void testCircularReferenceXml() { + Person bob = new Person("bob"); + Person jane = new Person("jane"); + bob.likes = jane; + jane.likes = bob; + + String expected = "" + + "\n" + + " bob\n" + + " \n" + + " jane\n" + + " \n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(bob)); + } + + public void testCircularReferenceToSelfXml() { + Person bob = new Person("bob"); + bob.likes = bob; + + String expected = "" + + "\n" + + " bob\n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(bob)); + } + + public void testRing() { + LinkedElement tom = new LinkedElement("Tom"); + LinkedElement dick = new LinkedElement("Dick"); + LinkedElement harry = new LinkedElement("Harry"); + tom.next = dick; + dick.next = harry; + harry.next = tom; + + xstream.alias("elem", LinkedElement.class); + String expected = "" + + "\n" + + " Tom\n" + + " \n" + + " Dick\n" + + " \n" + + " Harry\n" + + " \n" + + " \n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(tom)); + } + + public void testTree() { + TreeElement root = new TreeElement("X"); + TreeElement left = new TreeElement("Y"); + TreeElement right = new TreeElement("Z"); + root.left = left; + root.right = right; + left.left = new TreeElement(root.name); + right.right = new TreeElement(left.name); + right.left = left.left; + + xstream.alias("elem", TreeElement.class); + String expected = "" + + "\n" + + " X\n" + + " \n" + + " Y\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " Z\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(root)); + } + + public void testReplacedReference() { + String expectedXml = "" + + "\n" + + " parent\n" + + " \n" + + " \n" + + " child\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + replacedReference(expectedXml); + } + + public void testCanReferenceDeserializedNullValues() { + xstream.alias("test", Mapper.Null.class); + String xml = "" + + "\n" + + " \n" + + " \n" + + ""; + List list = (List)xstream.fromXML(xml); + assertEquals(2, list.size()); + assertNull(list.get(0)); + assertNull(list.get(1)); + } + + static class RecursiveThing { + final Map map = new HashMap(); + final String name; // wrong definition order for HashMap! + public RecursiveThing(String name) { + this.name = name; + } + public int hashCode() { + return name.hashCode(); + } + public boolean equals(Object obj) { + return obj.getClass().equals(RecursiveThing.class) && name.equals(((RecursiveThing)obj).name); + } + } + + public void todoTestRecursiveMap() { + RecursiveThing thing = new RecursiveThing("joe"); + thing.map.put(thing, "walnes"); + + xstream.alias("rec-thing", RecursiveThing.class); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " walnes\n" + + " \n" + + " \n" + + " joe\n" + + ""; + assertBothWays(thing, expected); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/SecurityManagerTest.java b/xstream/src/test/com/thoughtworks/acceptance/SecurityManagerTest.java new file mode 100644 index 0000000..b0beced --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/SecurityManagerTest.java @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2006, 2007, 2009, 2010, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. March 2006 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.Software; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; +import com.thoughtworks.xstream.io.xml.DomDriver; +import com.thoughtworks.xstream.testutil.DynamicSecurityManager; + +import junit.framework.TestCase; + +import org.apache.commons.lang.StringUtils; + +import java.io.File; +import java.io.FilePermission; +import java.lang.reflect.ReflectPermission; +import java.net.NetPermission; +import java.security.CodeSource; +import java.security.Permission; +import java.security.Policy; +import java.security.cert.Certificate; +import java.util.Iterator; +import java.util.PropertyPermission; + + +/** + * Test XStream with an active SecurityManager. Note, that it is intentional, that this test is + * not derived from AbstractAcceptanceTest to avoid loaded classes before the SecurityManager is + * in action. Also run each fixture in its own to avoid side-effects. + * + * @author Jörg Schaible + */ +public class SecurityManagerTest extends TestCase { + + private XStream xstream; + private DynamicSecurityManager sm; + private CodeSource source; + + protected void setUp() throws Exception { + super.setUp(); + System.setSecurityManager(null); + source = new CodeSource(new File("target").toURI().toURL(), (Certificate[])null); + + sm = new DynamicSecurityManager(); + Policy policy = Policy.getPolicy(); + sm.setPermissions(source, policy.getPermissions(source)); + sm.addPermission(source, new RuntimePermission("setSecurityManager")); + + File mainClasses = new File(System.getProperty("user.dir"), "target/classes/-"); + File testClasses = new File(System.getProperty("user.dir"), "target/test-classes/-"); + String[] javaClassPath = StringUtils.split(System.getProperty("java.class.path"), File.pathSeparatorChar); + File javaHome = new File(System.getProperty("java.home"), "-"); + + // necessary permission start here + sm.addPermission(source, new FilePermission(mainClasses.toString(), "read")); + sm.addPermission(source, new FilePermission(testClasses.toString(), "read")); + sm.addPermission(source, new FilePermission(javaHome.toString(), "read")); + for (int i = 0; i < javaClassPath.length; ++i) { + if (javaClassPath[i].endsWith(".jar")) { + sm.addPermission(source, new FilePermission(javaClassPath[i], "read")); + } + } + } + + protected void tearDown() throws Exception { + System.setSecurityManager(null); + super.tearDown(); + } + + protected void runTest() throws Throwable { + try { + super.runTest(); + } catch(Throwable e) { + for (final Iterator iter = sm.getFailedPermissions().iterator(); iter.hasNext();) { + final Permission permission = (Permission)iter.next(); + System.out.println("SecurityException: Permission " + permission.toString()); + } + throw e; + } + } + + public void testSerializeWithXppDriverAndSun14ReflectionProviderAndActiveSecurityManager() { + sm.addPermission(source, new RuntimePermission("accessClassInPackage.sun.reflect")); + sm.addPermission(source, new RuntimePermission("accessClassInPackage.sun.misc")); + sm.addPermission(source, new RuntimePermission("accessClassInPackage.sun.text.resources")); + sm.addPermission(source, new RuntimePermission("accessClassInPackage.sun.util.resources")); + sm.addPermission(source, new RuntimePermission("accessDeclaredMembers")); + sm.addPermission(source, new RuntimePermission("createClassLoader")); + sm.addPermission(source, new RuntimePermission("fileSystemProvider")); + sm.addPermission(source, new RuntimePermission("loadLibrary.nio")); + sm.addPermission(source, new RuntimePermission("modifyThreadGroup")); + sm.addPermission(source, new RuntimePermission("reflectionFactoryAccess")); + sm.addPermission(source, new PropertyPermission("ibm.dst.compatibility", "read")); + sm.addPermission(source, new PropertyPermission("java.home", "read")); + sm.addPermission(source, new PropertyPermission("java.nio.file.spi.DefaultFileSystemProvider", "read")); + sm.addPermission(source, new PropertyPermission("java.security.debug", "read")); + sm.addPermission(source, new PropertyPermission("javax.xml.datatype.DatatypeFactory", "read")); + sm.addPermission(source, new PropertyPermission("jaxp.debug", "read")); + sm.addPermission(source, new PropertyPermission("jdk.util.TimeZone.allowSetDefault", "read")); + sm.addPermission(source, new PropertyPermission("sun.boot.class.path", "read")); + sm.addPermission(source, new PropertyPermission("sun.nio.fs.chdirAllowed", "read")); + sm.addPermission(source, new PropertyPermission("sun.timezone.ids.oldmapping", "read")); + sm.addPermission(source, new PropertyPermission("user.country", "read")); + sm.addPermission(source, new PropertyPermission("user.dir", "read")); + sm.addPermission(source, new PropertyPermission("user.timezone", "read,write")); + sm.addPermission(source, new ReflectPermission("suppressAccessChecks")); + sm.addPermission(source, new NetPermission("specifyStreamHandler")); + sm.setReadOnly(); + System.setSecurityManager(sm); + + xstream = new XStream(); + + assertBothWays(); + } + + public void testSerializeWithXppDriverAndPureJavaReflectionProviderAndActiveSecurityManager() { + sm.addPermission(source, new RuntimePermission("accessClassInPackage.sun.misc")); + sm.addPermission(source, new RuntimePermission("accessClassInPackage.sun.text.resources")); + sm.addPermission(source, new RuntimePermission("accessClassInPackage.sun.util.resources")); + sm.addPermission(source, new RuntimePermission("accessDeclaredMembers")); + sm.addPermission(source, new RuntimePermission("createClassLoader")); + sm.addPermission(source, new RuntimePermission("fileSystemProvider")); + sm.addPermission(source, new RuntimePermission("loadLibrary.nio")); + sm.addPermission(source, new RuntimePermission("modifyThreadGroup")); + sm.addPermission(source, new PropertyPermission("ibm.dst.compatibility", "read")); + sm.addPermission(source, new PropertyPermission("java.home", "read")); + sm.addPermission(source, new PropertyPermission("java.nio.file.spi.DefaultFileSystemProvider", "read")); + sm.addPermission(source, new PropertyPermission("java.security.debug", "read")); + sm.addPermission(source, new PropertyPermission("javax.xml.datatype.DatatypeFactory", "read")); + sm.addPermission(source, new PropertyPermission("jaxp.debug", "read")); + sm.addPermission(source, new PropertyPermission("jdk.util.TimeZone.allowSetDefault", "read")); + sm.addPermission(source, new PropertyPermission("sun.boot.class.path", "read")); + sm.addPermission(source, new PropertyPermission("sun.io.serialization.extendedDebugInfo", "read")); + sm.addPermission(source, new PropertyPermission("sun.nio.fs.chdirAllowed", "read")); + sm.addPermission(source, new PropertyPermission("sun.timezone.ids.oldmapping", "read")); + sm.addPermission(source, new PropertyPermission("user.country", "read")); + sm.addPermission(source, new PropertyPermission("user.dir", "read")); + sm.addPermission(source, new PropertyPermission("user.timezone", "read,write")); + sm.addPermission(source, new ReflectPermission("suppressAccessChecks")); + sm.addPermission(source, new NetPermission("specifyStreamHandler")); + sm.setReadOnly(); + System.setSecurityManager(sm); + + xstream = new XStream(new PureJavaReflectionProvider()); + + assertBothWays(); + } + + public void testSerializeWithDomDriverAndPureJavaReflectionProviderAndActiveSecurityManager() { + sm.addPermission(source, new RuntimePermission("accessClassInPackage.sun.text.resources")); + sm.addPermission(source, new RuntimePermission("accessClassInPackage.sun.util.resources")); + sm.addPermission(source, new RuntimePermission("accessDeclaredMembers")); + sm.addPermission(source, new RuntimePermission("createClassLoader")); + sm.addPermission(source, new RuntimePermission("fileSystemProvider")); + sm.addPermission(source, new RuntimePermission("loadLibrary.nio")); + sm.addPermission(source, new RuntimePermission("modifyThreadGroup")); + sm.addPermission(source, new RuntimePermission("reflectionFactoryAccess")); + sm.addPermission(source, new PropertyPermission("com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration", "read")); + sm.addPermission(source, new PropertyPermission("elementAttributeLimit", "read")); + sm.addPermission(source, new PropertyPermission("entityExpansionLimit", "read")); + sm.addPermission(source, new PropertyPermission("http://java.sun.com/xml/dom/properties/ancestor-check", "read")); + sm.addPermission(source, new PropertyPermission("ibm.dst.compatibility", "read")); + sm.addPermission(source, new PropertyPermission("java.home", "read")); + sm.addPermission(source, new PropertyPermission("java.nio.file.spi.DefaultFileSystemProvider", "read")); + sm.addPermission(source, new PropertyPermission("java.security.debug", "read")); + sm.addPermission(source, new PropertyPermission("javax.xml.datatype.DatatypeFactory", "read")); + sm.addPermission(source, new PropertyPermission("javax.xml.parsers.DocumentBuilderFactory", "read")); + sm.addPermission(source, new PropertyPermission("javax.xml.accessExternalDTD", "read")); + sm.addPermission(source, new PropertyPermission("javax.xml.accessExternalSchema", "read")); + sm.addPermission(source, new PropertyPermission("jaxp.debug", "read")); + sm.addPermission(source, new PropertyPermission("jdk.util.TimeZone.allowSetDefault", "read")); + sm.addPermission(source, new PropertyPermission("jdk.xml.elementAttributeLimit", "read")); + sm.addPermission(source, new PropertyPermission("jdk.xml.entityExpansionLimit", "read")); + sm.addPermission(source, new PropertyPermission("jdk.xml.maxElementDepth", "read")); + sm.addPermission(source, new PropertyPermission("jdk.xml.maxGeneralEntitySizeLimit", "read")); + sm.addPermission(source, new PropertyPermission("jdk.xml.maxParameterEntitySizeLimit", "read")); + sm.addPermission(source, new PropertyPermission("jdk.xml.maxOccurLimit", "read")); + sm.addPermission(source, new PropertyPermission("jdk.xml.totalEntitySizeLimit", "read")); + sm.addPermission(source, new PropertyPermission("maxOccurLimit", "read")); + sm.addPermission(source, new PropertyPermission("sun.boot.class.path", "read")); + sm.addPermission(source, new PropertyPermission("sun.nio.fs.chdirAllowed", "read")); + sm.addPermission(source, new PropertyPermission("sun.timezone.ids.oldmapping", "read")); + sm.addPermission(source, new PropertyPermission("user.country", "read")); + sm.addPermission(source, new PropertyPermission("user.dir", "read")); + sm.addPermission(source, new PropertyPermission("user.timezone", "read,write")); + sm.addPermission(source, new NetPermission("specifyStreamHandler")); + sm.addPermission(source, new ReflectPermission("suppressAccessChecks")); + sm.setReadOnly(); + System.setSecurityManager(sm); + + xstream = new XStream(new PureJavaReflectionProvider(), new DomDriver()); + + assertBothWays(); + } + + private void assertBothWays() { + + xstream.alias("software", Software.class); + + final Software sw = new Software("jw", "xstr"); + final String xml = "\n" + + " jw\n" + + " xstr\n" + + ""; + + String resultXml = xstream.toXML(sw); + assertEquals(xml, resultXml); + Object resultRoot = xstream.fromXML(resultXml); + if (!sw.equals(resultRoot)) { + assertEquals("Object deserialization failed", "DESERIALIZED OBJECT\n" + + xstream.toXML(sw), "DESERIALIZED OBJECT\n" + xstream.toXML(resultRoot)); + } + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java new file mode 100644 index 0000000..c77b3ce --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 23. December 2013 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import java.beans.EventHandler; + +import com.thoughtworks.xstream.XStreamException; +import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; +import com.thoughtworks.xstream.security.ProxyTypePermission; + +/** + * @author Jörg Schaible + */ +public class SecurityVulnerabilityTest extends AbstractAcceptanceTest { + + private final static StringBuffer BUFFER = new StringBuffer(); + + protected void setUp() throws Exception { + super.setUp(); + BUFFER.setLength(0); + xstream.alias("runnable", Runnable.class); + xstream.allowTypes(new Class[]{EventHandler.class}); + xstream.allowTypeHierarchy(Runnable.class); + xstream.addPermission(ProxyTypePermission.PROXIES); + } + + public void testCannotInjectEventHandler() { + final String xml = "" + + "\n" + + " \n" + + " java.lang.Runnable\n" + + " \n" + + " \n" + + " exec\n" + + " \n" + + " \n" + + ""; + + try { + xstream.fromXML(xml); + fail("Thrown " + XStreamException.class.getName() + " expected"); + } catch (final XStreamException e) { + assertTrue(e.getMessage().indexOf(EventHandler.class.getName()) > 0); + } + assertEquals(0, BUFFER.length()); + } + + public void testExplicitlyConvertEventHandler() { + final String xml = "" + + "\n" + + " \n" + + " java.lang.Runnable\n" + + " \n" + + " \n" + + " exec\n" + + " \n" + + " \n" + + ""; + + xstream.registerConverter(new ReflectionConverter(xstream.getMapper(), xstream + .getReflectionProvider(), EventHandler.class)); + + final Runnable[] array = (Runnable[])xstream.fromXML(xml); + assertEquals(0, BUFFER.length()); + array[0].run(); + assertEquals("Executed!", BUFFER.toString()); + } + + public static class Exec { + + public void exec() { + BUFFER.append("Executed!"); + } + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/SerializationCallbackOrderTest.java b/xstream/src/test/com/thoughtworks/acceptance/SerializationCallbackOrderTest.java new file mode 100644 index 0000000..c8db4cd --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/SerializationCallbackOrderTest.java @@ -0,0 +1,903 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 02. February 2005 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.testutil.CallLog; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectInputValidation; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +public class SerializationCallbackOrderTest extends AbstractAcceptanceTest { + + // static so it can be accessed by objects under test, without them needing a reference back to the testcase + private static CallLog log = new CallLog(); + + protected void setUp() throws Exception { + super.setUp(); + log.reset(); + } + + + // --- Sample class hierarchy + + public static class PrivateBase implements Serializable{ + + private void writeObject(ObjectOutputStream out) throws IOException { + log.actual("PrivateBase.writeObject() start"); + out.defaultWriteObject(); + log.actual("PrivateBase.writeObject() end"); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + log.actual("PrivateBase.readObject() start"); + in.defaultReadObject(); + log.actual("PrivateBase.readObject() end"); + } + + private Object writeReplace() { + log.actual("PrivateBase.writeReplace()"); + return this; + } + + private Object readResolve() { + log.actual("PrivateBase.readResolve()"); + return this; + } + } + + public static class PrivateChildOwnRR extends PrivateBase implements Serializable{ + + private void writeObject(ObjectOutputStream out) throws IOException { + log.actual("PrivateChildOwnRR.writeObject() start"); + out.defaultWriteObject(); + log.actual("PrivateChildOwnRR.writeObject() end"); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + log.actual("PrivateChildOwnRR.readObject() start"); + in.defaultReadObject(); + log.actual("PrivateChildOwnRR.readObject() end"); + } + + private Object writeReplace() { + log.actual("PrivateChildOwnRR.writeReplace()"); + return this; + } + + private Object readResolve() { + log.actual("PrivateChildOwnRR.readResolve()"); + return this; + } + } + + public static class PrivateChildNoRR extends PrivateBase implements Serializable{ + + private void writeObject(ObjectOutputStream out) throws IOException { + log.actual("PrivateChildNoRR.writeObject() start"); + out.defaultWriteObject(); + log.actual("PrivateChildNoRR.writeObject() end"); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + log.actual("PrivateChildNoRR.readObject() start"); + in.defaultReadObject(); + log.actual("PrivateChildNoRR.readObject() end"); + } + } + + public static class ProtectedBase implements Serializable{ + + private void writeObject(ObjectOutputStream out) throws IOException { + log.actual("ProtectedBase.writeObject() start"); + out.defaultWriteObject(); + log.actual("ProtectedBase.writeObject() end"); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + log.actual("ProtectedBase.readObject() start"); + in.defaultReadObject(); + log.actual("ProtectedBase.readObject() end"); + } + + protected Object writeReplace() { + log.actual("ProtectedBase.writeReplace()"); + return this; + } + + protected Object readResolve() { + log.actual("ProtectedBase.readResolve()"); + return this; + } + } + + public static class ProtectedChildOwnRR extends ProtectedBase implements Serializable{ + + private void writeObject(ObjectOutputStream out) throws IOException { + log.actual("ProtectedChildOwnRR.writeObject() start"); + out.defaultWriteObject(); + log.actual("ProtectedChildOwnRR.writeObject() end"); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + log.actual("ProtectedChildOwnRR.readObject() start"); + in.defaultReadObject(); + log.actual("ProtectedChildOwnRR.readObject() end"); + } + + protected Object writeReplace() { + log.actual("ProtectedChildOwnRR.writeReplace()"); + return this; + } + + protected Object readResolve() { + log.actual("ProtectedChildOwnRR.readResolve()"); + return this; + } + } + + public static class ProtectedChildInheritedRR extends ProtectedBase implements Serializable{ + + private void writeObject(ObjectOutputStream out) throws IOException { + log.actual("ProtectedChildInheritedRR.writeObject() start"); + out.defaultWriteObject(); + log.actual("ProtectedChildInheritedRR.writeObject() end"); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + log.actual("ProtectedChildInheritedRR.readObject() start"); + in.defaultReadObject(); + log.actual("ProtectedChildInheritedRR.readObject() end"); + } + } + + public static class PackageBase implements Serializable{ + + private void writeObject(ObjectOutputStream out) throws IOException { + log.actual("PackageBase.writeObject() start"); + out.defaultWriteObject(); + log.actual("PackageBase.writeObject() end"); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + log.actual("PackageBase.readObject() start"); + in.defaultReadObject(); + log.actual("PackageBase.readObject() end"); + } + + Object writeReplace() { + log.actual("PackageBase.writeReplace()"); + return this; + } + + Object readResolve() { + log.actual("PackageBase.readResolve()"); + return this; + } + } + + public static class PackageChildOwnRR extends PackageBase implements Serializable{ + + private void writeObject(ObjectOutputStream out) throws IOException { + log.actual("PackageChildOwnRR.writeObject() start"); + out.defaultWriteObject(); + log.actual("PackageChildOwnRR.writeObject() end"); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + log.actual("PackageChildOwnRR.readObject() start"); + in.defaultReadObject(); + log.actual("PackageChildOwnRR.readObject() end"); + } + + Object writeReplace() { + log.actual("PackageChildOwnRR.writeReplace()"); + return this; + } + + Object readResolve() { + log.actual("PackageChildOwnRR.readResolve()"); + return this; + } + } + + public static class PackageChildInheritedRR extends PackageBase implements Serializable{ + + private void writeObject(ObjectOutputStream out) throws IOException { + log.actual("PackageChildInheritedRR.writeObject() start"); + out.defaultWriteObject(); + log.actual("PackageChildInheritedRR.writeObject() end"); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + log.actual("PackageChildInheritedRR.readObject() start"); + in.defaultReadObject(); + log.actual("PackageChildInheritedRR.readObject() end"); + } + } + + // --- Convenience wrappers around Java Object Serialization + + private byte[] javaSerialize(Object object) throws IOException { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + ObjectOutputStream objectOutputStream = new ObjectOutputStream(bytes); + objectOutputStream.writeObject(object); + objectOutputStream.close(); + return bytes.toByteArray(); + } + + private Object javaDeserialize(byte[] data) throws IOException, ClassNotFoundException { + ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(data)); + return objectInputStream.readObject(); + } + + // --- Tests + + public void testJavaSerializationOwnPrivateRR() throws IOException { + // expectations + log.expect("PrivateChildOwnRR.writeReplace()"); + log.expect("PrivateBase.writeObject() start"); + log.expect("PrivateBase.writeObject() end"); + log.expect("PrivateChildOwnRR.writeObject() start"); + log.expect("PrivateChildOwnRR.writeObject() end"); + + // execute + javaSerialize(new PrivateChildOwnRR()); + + // verify + log.verify(); + } + + public void testJavaSerializationNoRR() throws IOException { + // expectations + log.expect("PrivateBase.writeObject() start"); + log.expect("PrivateBase.writeObject() end"); + log.expect("PrivateChildNoRR.writeObject() start"); + log.expect("PrivateChildNoRR.writeObject() end"); + + // execute + javaSerialize(new PrivateChildNoRR()); + + // verify + log.verify(); + } + + public void testJavaSerializationOwnProtectedRR() throws IOException { + // expectations + log.expect("ProtectedChildOwnRR.writeReplace()"); + log.expect("ProtectedBase.writeObject() start"); + log.expect("ProtectedBase.writeObject() end"); + log.expect("ProtectedChildOwnRR.writeObject() start"); + log.expect("ProtectedChildOwnRR.writeObject() end"); + + // execute + javaSerialize(new ProtectedChildOwnRR()); + + // verify + log.verify(); + } + + public void testJavaSerializationInheritedRR() throws IOException { + // expectations + log.expect("ProtectedBase.writeReplace()"); + log.expect("ProtectedBase.writeObject() start"); + log.expect("ProtectedBase.writeObject() end"); + log.expect("ProtectedChildInheritedRR.writeObject() start"); + log.expect("ProtectedChildInheritedRR.writeObject() end"); + + // execute + javaSerialize(new ProtectedChildInheritedRR()); + + // verify + log.verify(); + } + + public void testJavaSerializationOwnPackageRR() throws IOException { + // expectations + log.expect("PackageChildOwnRR.writeReplace()"); + log.expect("PackageBase.writeObject() start"); + log.expect("PackageBase.writeObject() end"); + log.expect("PackageChildOwnRR.writeObject() start"); + log.expect("PackageChildOwnRR.writeObject() end"); + + // execute + javaSerialize(new PackageChildOwnRR()); + + // verify + log.verify(); + } + + public void testJavaSerializationInheritedPackageRR() throws IOException { + // expectations + log.expect("PackageBase.writeReplace()"); + log.expect("PackageBase.writeObject() start"); + log.expect("PackageBase.writeObject() end"); + log.expect("PackageChildInheritedRR.writeObject() start"); + log.expect("PackageChildInheritedRR.writeObject() end"); + + // execute + javaSerialize(new PackageChildInheritedRR()); + + // verify + log.verify(); + } + + public void testXStreamSerializationOwnPrivateRR() { + // expectations + log.expect("PrivateChildOwnRR.writeReplace()"); + log.expect("PrivateBase.writeObject() start"); + log.expect("PrivateBase.writeObject() end"); + log.expect("PrivateChildOwnRR.writeObject() start"); + log.expect("PrivateChildOwnRR.writeObject() end"); + + // execute + xstream.toXML(new PrivateChildOwnRR()); + + // verify + log.verify(); + } + + public void testXStreamSerializationNoRR() { + // expectations + log.expect("PrivateBase.writeObject() start"); + log.expect("PrivateBase.writeObject() end"); + log.expect("PrivateChildNoRR.writeObject() start"); + log.expect("PrivateChildNoRR.writeObject() end"); + + // execute + xstream.toXML(new PrivateChildNoRR()); + + // verify + log.verify(); + } + + public void testXStreamSerializationOwnProtectedRR() { + // expectations + log.expect("ProtectedChildOwnRR.writeReplace()"); + log.expect("ProtectedBase.writeObject() start"); + log.expect("ProtectedBase.writeObject() end"); + log.expect("ProtectedChildOwnRR.writeObject() start"); + log.expect("ProtectedChildOwnRR.writeObject() end"); + + // execute + xstream.toXML(new ProtectedChildOwnRR()); + + // verify + log.verify(); + } + + public void testXStreamSerializationOwnInheritedRR() { + // expectations + log.expect("ProtectedBase.writeReplace()"); + log.expect("ProtectedBase.writeObject() start"); + log.expect("ProtectedBase.writeObject() end"); + log.expect("ProtectedChildInheritedRR.writeObject() start"); + log.expect("ProtectedChildInheritedRR.writeObject() end"); + + // execute + xstream.toXML(new ProtectedChildInheritedRR()); + + // verify + log.verify(); + } + + public void testXStreamSerializationOwnPackageRR() { + // expectations + log.expect("PackageChildOwnRR.writeReplace()"); + log.expect("PackageBase.writeObject() start"); + log.expect("PackageBase.writeObject() end"); + log.expect("PackageChildOwnRR.writeObject() start"); + log.expect("PackageChildOwnRR.writeObject() end"); + + // execute + xstream.toXML(new PackageChildOwnRR()); + + // verify + log.verify(); + } + + public void testXStreamSerializationOwnInheritedPackageRR() { + // expectations + log.expect("PackageBase.writeReplace()"); + log.expect("PackageBase.writeObject() start"); + log.expect("PackageBase.writeObject() end"); + log.expect("PackageChildInheritedRR.writeObject() start"); + log.expect("PackageChildInheritedRR.writeObject() end"); + + // execute + xstream.toXML(new PackageChildInheritedRR()); + + // verify + log.verify(); + } + + public void testJavaDeserializationOwnPrivateRR() throws IOException, ClassNotFoundException { + // setup + byte[] data = javaSerialize(new PrivateChildOwnRR()); + log.reset(); + + // expectations + log.expect("PrivateBase.readObject() start"); + log.expect("PrivateBase.readObject() end"); + log.expect("PrivateChildOwnRR.readObject() start"); + log.expect("PrivateChildOwnRR.readObject() end"); + log.expect("PrivateChildOwnRR.readResolve()"); + + // execute + javaDeserialize(data); + + // verify + log.verify(); + } + + public void testJavaDeserializationNoRR() throws IOException, ClassNotFoundException { + // setup + byte[] data = javaSerialize(new PrivateChildNoRR()); + log.reset(); + + // expectations + log.expect("PrivateBase.readObject() start"); + log.expect("PrivateBase.readObject() end"); + log.expect("PrivateChildNoRR.readObject() start"); + log.expect("PrivateChildNoRR.readObject() end"); + + // execute + javaDeserialize(data); + + // verify + log.verify(); + } + + public void testJavaDeserializationOwnProtectedRR() throws IOException, ClassNotFoundException { + // setup + byte[] data = javaSerialize(new ProtectedChildOwnRR()); + log.reset(); + + // expectations + log.expect("ProtectedBase.readObject() start"); + log.expect("ProtectedBase.readObject() end"); + log.expect("ProtectedChildOwnRR.readObject() start"); + log.expect("ProtectedChildOwnRR.readObject() end"); + log.expect("ProtectedChildOwnRR.readResolve()"); + + // execute + javaDeserialize(data); + + // verify + log.verify(); + } + + public void testJavaDeserializationInheritedRR() throws IOException, ClassNotFoundException { + // setup + byte[] data = javaSerialize(new ProtectedChildInheritedRR()); + log.reset(); + + // expectations + log.expect("ProtectedBase.readObject() start"); + log.expect("ProtectedBase.readObject() end"); + log.expect("ProtectedChildInheritedRR.readObject() start"); + log.expect("ProtectedChildInheritedRR.readObject() end"); + log.expect("ProtectedBase.readResolve()"); + + // execute + javaDeserialize(data); + + // verify + log.verify(); + } + + public void testJavaDeserializationOwnPackageRR() throws IOException, ClassNotFoundException { + // setup + byte[] data = javaSerialize(new PackageChildOwnRR()); + log.reset(); + + // expectations + log.expect("PackageBase.readObject() start"); + log.expect("PackageBase.readObject() end"); + log.expect("PackageChildOwnRR.readObject() start"); + log.expect("PackageChildOwnRR.readObject() end"); + log.expect("PackageChildOwnRR.readResolve()"); + + // execute + javaDeserialize(data); + + // verify + log.verify(); + } + + public void testJavaDeserializationInheritedPackageRR() throws IOException, ClassNotFoundException { + // setup + byte[] data = javaSerialize(new PackageChildInheritedRR()); + log.reset(); + + // expectations + log.expect("PackageBase.readObject() start"); + log.expect("PackageBase.readObject() end"); + log.expect("PackageChildInheritedRR.readObject() start"); + log.expect("PackageChildInheritedRR.readObject() end"); + log.expect("PackageBase.readResolve()"); + + // execute + javaDeserialize(data); + + // verify + log.verify(); + } + + public void testXStreamDeserializationOwnPrivateRR() { + // setup + String data = xstream.toXML(new PrivateChildOwnRR()); + log.reset(); + + // expectations + log.expect("PrivateBase.readObject() start"); + log.expect("PrivateBase.readObject() end"); + log.expect("PrivateChildOwnRR.readObject() start"); + log.expect("PrivateChildOwnRR.readObject() end"); + log.expect("PrivateChildOwnRR.readResolve()"); + + // execute + xstream.fromXML(data); + + // verify + log.verify(); + } + + public void testXStreamDeserializationNoRR() { + // setup + String data = xstream.toXML(new PrivateChildNoRR()); + log.reset(); + + // expectations + log.expect("PrivateBase.readObject() start"); + log.expect("PrivateBase.readObject() end"); + log.expect("PrivateChildNoRR.readObject() start"); + log.expect("PrivateChildNoRR.readObject() end"); + + // execute + xstream.fromXML(data); + + // verify + log.verify(); + } + + public void testXStreamDeserializationOwnProtectedRR() { + // setup + String data = xstream.toXML(new ProtectedChildOwnRR()); + log.reset(); + + // expectations + log.expect("ProtectedBase.readObject() start"); + log.expect("ProtectedBase.readObject() end"); + log.expect("ProtectedChildOwnRR.readObject() start"); + log.expect("ProtectedChildOwnRR.readObject() end"); + log.expect("ProtectedChildOwnRR.readResolve()"); + + // execute + xstream.fromXML(data); + + // verify + log.verify(); + } + + public void testXStreamDeserializationInheritedRR() { + // setup + String data = xstream.toXML(new ProtectedChildInheritedRR()); + log.reset(); + + // expectations + log.expect("ProtectedBase.readObject() start"); + log.expect("ProtectedBase.readObject() end"); + log.expect("ProtectedChildInheritedRR.readObject() start"); + log.expect("ProtectedChildInheritedRR.readObject() end"); + log.expect("ProtectedBase.readResolve()"); + + // execute + xstream.fromXML(data); + + // verify + log.verify(); + } + + public void testXStreamDeserializationOwnPackageRR() { + // setup + String data = xstream.toXML(new PackageChildOwnRR()); + log.reset(); + + // expectations + log.expect("PackageBase.readObject() start"); + log.expect("PackageBase.readObject() end"); + log.expect("PackageChildOwnRR.readObject() start"); + log.expect("PackageChildOwnRR.readObject() end"); + log.expect("PackageChildOwnRR.readResolve()"); + + // execute + xstream.fromXML(data); + + // verify + log.verify(); + } + + public void testXStreamDeserializationInheritedPackageRR() { + // setup + String data = xstream.toXML(new PackageChildInheritedRR()); + log.reset(); + + // expectations + log.expect("PackageBase.readObject() start"); + log.expect("PackageBase.readObject() end"); + log.expect("PackageChildInheritedRR.readObject() start"); + log.expect("PackageChildInheritedRR.readObject() end"); + log.expect("PackageBase.readResolve()"); + + // execute + xstream.fromXML(data); + + // verify + log.verify(); + } + + public static class ParentNotTransient implements Serializable { + + public int somethingNotTransient; + + public ParentNotTransient(int somethingNotTransient) { + this.somethingNotTransient = somethingNotTransient; + } + + } + + public static class ChildWithTransient extends ParentNotTransient implements Serializable { + + public transient int somethingTransient; + + public ChildWithTransient(int somethingNotTransient, int somethingTransient) { + super(somethingNotTransient); + this.somethingTransient = somethingTransient; + } + + private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { + s.defaultReadObject(); + somethingTransient = 99999; + } + } + + public void testCallsReadObjectEvenWithoutNonTransientFields() { + xstream.alias("parent", ParentNotTransient.class); + xstream.alias("child", ChildWithTransient.class); + + Object in = new ChildWithTransient(10, 22222); + String expectedXml = "" + + "\n" + + " \n" + + " \n" + + " 10\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + String xml = xstream.toXML(in); + assertEquals(expectedXml, xml); + + ChildWithTransient childWithTransient = (ChildWithTransient) xstream.fromXML(xml); + + assertEquals(10, childWithTransient.somethingNotTransient); + assertEquals(99999, childWithTransient.somethingTransient); + } + + + public static class SomethingThatValidates implements Serializable { + + private void readObject(ObjectInputStream s) throws IOException { + + final int LOW_PRIORITY = -5; + final int MEDIUM_PRIORITY = 0; + final int HIGH_PRIORITY = 5; + + s.registerValidation(new ObjectInputValidation() { + public void validateObject() { + log.actual("validateObject() medium priority 1"); + } + }, MEDIUM_PRIORITY); + + s.registerValidation(new ObjectInputValidation() { + public void validateObject() { + log.actual("validateObject() high priority"); + } + }, HIGH_PRIORITY); + + s.registerValidation(new ObjectInputValidation() { + public void validateObject() { + log.actual("validateObject() low priority"); + } + }, LOW_PRIORITY); + + s.registerValidation(new ObjectInputValidation() { + public void validateObject() { + log.actual("validateObject() medium priority 2"); + } + }, MEDIUM_PRIORITY); + } + + private Object readResolve() { + log.actual("readResolve()"); + return this; + } + } + + public void testJavaSerializationValidatesObjectIsCalledInPriorityOrder() throws IOException, ClassNotFoundException { + // expect + log.expect("readResolve()"); + log.expect("validateObject() high priority"); + log.expect("validateObject() medium priority 2"); + log.expect("validateObject() medium priority 1"); + log.expect("validateObject() low priority"); + + // execute + javaDeserialize(javaSerialize(new SomethingThatValidates())); + + // verify + log.verify(); + } + + public void testXStreamSerializationValidatesObjectIsCalledInPriorityOrder() { + // expect + log.expect("readResolve()"); + log.expect("validateObject() high priority"); + log.expect("validateObject() medium priority 2"); + log.expect("validateObject() medium priority 1"); + log.expect("validateObject() low priority"); + + // execute + xstream.fromXML(xstream.toXML(new SomethingThatValidates())); + + // verify + log.verify(); + } + + public static class UnserializableParent { + public int x; + + public UnserializableParent() { + x = 5; + } + } + + public static class CustomSerializableChild extends UnserializableParent implements Serializable { + public int y; + + public CustomSerializableChild() { + y = 10; + } + + private void writeObject(ObjectOutputStream stream) throws IOException { + log.actual("Child.writeObject() start"); + stream.defaultWriteObject(); + log.actual("Child.writeObject() end"); + } + + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + log.actual("Child.readObject() start"); + stream.defaultReadObject(); + log.actual("Child.readObject() end"); + } + + private Object writeReplace() { + log.actual("Child.writeReplace()"); + return this; + } + + private Object readResolve() { + log.actual("Child.readResolve()"); + return this; + } + } + + public void testFieldsOfUnserializableParentsArePreserved() { + xstream.alias("parent", UnserializableParent.class); + xstream.alias("child", CustomSerializableChild.class); + + CustomSerializableChild child = new CustomSerializableChild(); + String expected = "" + + "\n" + + " \n" + + " 5\n" + + " \n" + + " \n" + + " \n" + + " 10\n" + + " \n" + + " \n" + + ""; + + CustomSerializableChild serialized =(CustomSerializableChild)assertBothWays(child, expected); + assertEquals(5, serialized.x); + assertEquals(10, serialized.y); + } + + public static class SerializableGrandChild extends CustomSerializableChild implements Serializable { + public int z; + + public SerializableGrandChild() { + super(); + z = 42; + } + } + + public void testUnserializableParentsAreWrittenOnlyOnce() { + xstream.alias("parent", UnserializableParent.class); + xstream.alias("child", CustomSerializableChild.class); + xstream.alias("grandchild", SerializableGrandChild.class); + + SerializableGrandChild grandChild = new SerializableGrandChild(); + String expected = "" + + "\n" + + " \n" + + " 5\n" + + " \n" + + " \n" + + " \n" + + " 10\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 42\n" + + " \n" + + " \n" + + ""; + + SerializableGrandChild serialized =(SerializableGrandChild)assertBothWays(grandChild, expected); + assertEquals(5, serialized.x); + assertEquals(10, serialized.y); + assertEquals(42, serialized.z); + } + + public void testXStreamSerializationForObjectsWithUnserializableParents() { + // expectations + log.expect("Child.writeReplace()"); + log.expect("Child.writeObject() start"); + log.expect("Child.writeObject() end"); + + // execute + xstream.toXML(new CustomSerializableChild()); + + // verify + log.verify(); + } + + public void testXStreamDeserializationForObjectsWithUnserializableParents() { + // setup + String data = xstream.toXML(new CustomSerializableChild()); + log.reset(); + + // expectations + log.expect("Child.readObject() start"); + log.expect("Child.readObject() end"); + log.expect("Child.readResolve()"); + + // execute + xstream.fromXML(data); + + // verify + log.verify(); + } + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/SerializationNestedWriteObjectsTest.java b/xstream/src/test/com/thoughtworks/acceptance/SerializationNestedWriteObjectsTest.java new file mode 100644 index 0000000..bad500a --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/SerializationNestedWriteObjectsTest.java @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2006, 2007, 2010, 2012, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 12. June 2006 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.LinkedList; +import java.util.List; +import java.util.TimeZone; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; + +/** + *

+ * A class {@link Serializable} {@link Parent} class implements + * writeObject() and holds a {@link Child} class that also + * implements writeObject() + *

+ * + * @author Cyrille Le Clerc + */ +public class SerializationNestedWriteObjectsTest extends AbstractAcceptanceTest { + + public static class Child implements Serializable { + + private int i = 3; + + public Child(int i) { + this.i = i; + } + + public int getI() { + return i; + } + + private void readObject(java.io.ObjectInputStream in) throws IOException, + ClassNotFoundException { + in.defaultReadObject(); + } + + private void writeObject(ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + } + } + + public static class Parent implements Serializable { + + private String name; + + private transient Child child; + + public Parent(String name, Child child) { + this.name = name; + this.child = child; + } + + public Child getChild() { + return child; + } + + public String getName() { + return name; + } + + private void readObject(java.io.ObjectInputStream in) throws IOException, + ClassNotFoundException { + this.child = (Child) in.readObject(); + in.defaultReadObject(); + } + + private void writeObject(ObjectOutputStream out) throws IOException { + out.writeObject(this.child); + out.defaultWriteObject(); + } + } + + public void testObjectInputStream() throws Exception { + xstream.alias("parent", Parent.class); + xstream.alias("child", Child.class); + + String sourceXml = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " ze-name\n" + + " \n" + + " \n" + + " \n" + + ""; + + ObjectInputStream objectInputStream = xstream.createObjectInputStream(new StringReader( + sourceXml)); + + Parent parent = (Parent) objectInputStream.readObject(); + + assertEquals("ze-name", parent.getName()); + assertEquals(1, parent.getChild().getI()); + } + + public void testObjectOutputStream() throws Exception { + xstream.alias("parent", Parent.class); + xstream.alias("child", Child.class); + + String expectedXml = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " ze-name\n" + + " \n" + + " \n" + + " \n" + + ""; + + Parent parent = new Parent("ze-name", new Child(1)); + StringWriter stringWriter = new StringWriter(); + ObjectOutputStream os = xstream.createObjectOutputStream(stringWriter); + os.writeObject(parent); + os.close(); + String actualXml = stringWriter.getBuffer().toString(); + assertEquals(expectedXml, actualXml); + } + + public void testToXML() { + + xstream.alias("parent", Parent.class); + xstream.alias("child", Child.class); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " ze-name\n" + + " \n" + + " \n" + + ""; + + Parent parent = new Parent("ze-name", new Child(1)); + + assertBothWays(parent, expected); + } + + public static class RawString implements Serializable { + + private String s; + + public RawString(String s) { + this.s = s; + } + + public String getS() { + return s; + } + + private void readObject(java.io.ObjectInputStream in) throws IOException { + int i = in.read(); + byte[] b = new byte[i]; + in.read(b); + s = new String(b); + } + + private void writeObject(ObjectOutputStream out) throws IOException { + byte[] b = s.getBytes(); + out.write(b.length); + out.write(b); + } + } + + public void testCanHandleRawBytes() throws IOException, ClassNotFoundException { + xstream.alias("raw", RawString.class); + + String expectedXml = "" + + "\n" + + " \n" + + " \n" + + " 7\n" + + " WFN0cmVhbQ==\n" + + " \n" + + " \n" + + ""; + + StringWriter stringWriter = new StringWriter(); + ObjectOutputStream os = xstream.createObjectOutputStream(stringWriter, "root"); + os.writeObject(new RawString("XStream")); + os.close(); + String actualXml = stringWriter.getBuffer().toString(); + assertEquals(expectedXml, actualXml); + + ObjectInputStream objectInputStream = xstream.createObjectInputStream(new StringReader(actualXml)); + + RawString rawString = (RawString) objectInputStream.readObject(); + assertEquals("XStream", rawString.getS()); + } + + static class Store implements Serializable { + List store; + public Store() { + store = new ArrayList(); + } + private void writeObject(ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + } + } + static class OtherStore extends Store { + private Object readResolve() { + if (this.store instanceof LinkedList) { + Store replacement = new MyStore(); + replacement.store = store; + return replacement; + } + return this; + } + } + static class MyStore extends OtherStore { + public MyStore() { + store = new LinkedList(); + } + private Object writeReplace() { + Store replacement = new OtherStore(); + replacement.store = store; + return replacement; + } + } + + public void testCachingInheritedWriteObject() throws Exception { + xstream.alias("store", Store.class); + xstream.alias("my", MyStore.class); + xstream.alias("other", OtherStore.class); + + String expectedXml = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " one\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " two\n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + Store[] stores = new Store[]{ + new MyStore(), + new OtherStore() + }; + stores[0].store.add("one"); + stores[1].store.add("two"); + + assertBothWays(stores, expectedXml); + } + + static class MoscowCalendar extends GregorianCalendar { + public MoscowCalendar() { + super(TimeZone.getTimeZone("Europe/Moscow")); + } + } + + public void testNestedSerializationOfDefaultType() { + Calendar in = new MoscowCalendar(); + in.setTimeInMillis(44444); + String xml = xstream.toXML(in); + Calendar out = (Calendar) xstream.fromXML(xml); + assertEquals(in.getTime(), out.getTime()); + } +} \ No newline at end of file diff --git a/xstream/src/test/com/thoughtworks/acceptance/SortableFieldListTest.java b/xstream/src/test/com/thoughtworks/acceptance/SortableFieldListTest.java new file mode 100644 index 0000000..c511c0d --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/SortableFieldListTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2007, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 10. April 2007 by Guilherme Silveira + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.reflection.FieldDictionary; +import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; +import com.thoughtworks.xstream.converters.reflection.SortableFieldKeySorter; + +public class SortableFieldListTest extends AbstractAcceptanceTest { + + public void testSortsFieldOrderWithArray() { + + SortableFieldKeySorter sorter = new SortableFieldKeySorter(); + sorter.registerFieldOrder(MommyBear.class, + new String[] { "b", "c", "a" }); + + xstream = new XStream(new PureJavaReflectionProvider(new FieldDictionary(sorter))); + setupSecurity(xstream); + xstream.alias("mommy", MommyBear.class); + MommyBear root = new MommyBear(); + root.c = "ccc"; + root.b = "bbb"; + root.a = "aaa"; + assertBothWays(root, "\n" + " bbb\n" + " ccc\n" + + " aaa\n" + ""); + } + + public void testSortsFieldOrderWhileUsingInheritance() { + + SortableFieldKeySorter sorter = new SortableFieldKeySorter(); + sorter.registerFieldOrder(BabyBear.class, + new String[] { "b", "d", "c", "a" }); + + xstream = new XStream(new PureJavaReflectionProvider(new FieldDictionary(sorter))); + setupSecurity(xstream); + xstream.alias("baby", BabyBear.class); + BabyBear root = new BabyBear(); + root.c = "ccc"; + root.b = "bbb"; + root.a = "aaa"; + root.d = "ddd"; + assertBothWays(root, "\n" + " bbb\n" + " ddd\n" + + " ccc\n" + " aaa\n" + ""); + } + + public static class MommyBear { + protected String c, a, b; + } + + public static class BabyBear extends MommyBear { + private String d; + } + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/SwingTest.java b/xstream/src/test/com/thoughtworks/acceptance/SwingTest.java new file mode 100644 index 0000000..4f62d2d --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/SwingTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. April 2005 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.core.JVM; + +import javax.swing.DefaultListModel; +import javax.swing.JList; +import javax.swing.JTable; +import javax.swing.LookAndFeel; +import javax.swing.plaf.metal.MetalLookAndFeel; + +public class SwingTest extends AbstractAcceptanceTest { + + protected void setupSecurity(XStream xstream) { + super.setupSecurity(xstream); + xstream.allowTypesByWildcard(new String[]{"javax.swing.**", "java.awt.**", "java.beans.**", "sun.swing.**"}); + } + + // JTable is one of the nastiest components to serialize. If this works, we're in good shape :) + public void testJTable() { + boolean isHeadless = Boolean.valueOf(System.getProperty("java.awt.headless", "false")).booleanValue(); + if (!isHeadless || JVM.is15()) { + // Note: JTable does not have a sensible .equals() method, so we compare the XML instead. + JTable original = new JTable(); + String originalXml = xstream.toXML(original); + + JTable deserialized = (JTable) xstream.fromXML(originalXml); + String deserializedXml = xstream.toXML(deserialized); + + assertEquals(originalXml, deserializedXml); + } + } + + public void testDefaultListModel() { + boolean isHeadless = Boolean.valueOf(System.getProperty("java.awt.headless", "false")).booleanValue(); + if (!isHeadless || JVM.is15()) { + final DefaultListModel original = new DefaultListModel(); + final JList list = new JList(); + list.setModel(original); + + String originalXml = xstream.toXML(original); + + DefaultListModel deserialized = (DefaultListModel) xstream.fromXML(originalXml); + String deserializedXml = xstream.toXML(deserialized); + + assertEquals(originalXml, deserializedXml); + + list.setModel(deserialized); + } + } + + public void testMetalLookAndFeel() { + LookAndFeel plaf = new MetalLookAndFeel(); + String originalXml = xstream.toXML(plaf); + assertBothWays(plaf, originalXml); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/TreeMapAndTreeSetTest.java b/xstream/src/test/com/thoughtworks/acceptance/TreeMapAndTreeSetTest.java new file mode 100644 index 0000000..9809793 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/TreeMapAndTreeSetTest.java @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2010, 2011, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 08. May 2005 by Joe Walnes + */ +package com.thoughtworks.acceptance; + + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.TreeMap; +import java.util.TreeSet; + +import com.thoughtworks.xstream.core.JVM; + +public class TreeMapAndTreeSetTest extends AbstractAcceptanceTest { + + public static class MyComparator implements Comparator { + private String something = "stuff"; + + public int compare(Object o1, Object o2) { + return ((String) o1).compareTo((String) o2); + } + } + + public static class UnusedComparator implements Comparator { + + private final static Comparator THROWING_COMPARATOR = new Comparator() { + + public int compare(Object o1, Object o2) { + throw new UnsupportedOperationException(); + } + + }; + + public int compare(Object o1, Object o2) { + return ((String) o1).compareTo((String) o2); + } + + private Object readResolve() { + return THROWING_COMPARATOR; + } + } + + protected void setUp() throws Exception { + super.setUp(); + xstream.alias("my-comparator", MyComparator.class); + xstream.alias("unused-comparator", UnusedComparator.class); + } + + public void testTreeMapWithComparator() { + TreeMap map = new TreeMap(new MyComparator()); + map.put("benny", "hill"); + map.put("joe", "walnes"); + + String expected = "" + + "\n" + + " \n" + + " stuff\n" + + " \n" + + " \n" + + " benny\n" + + " hill\n" + + " \n" + + " \n" + + " joe\n" + + " walnes\n" + + " \n" + + ""; + + TreeMap result = (TreeMap) assertBothWays(map, expected); + assertEquals(MyComparator.class, result.comparator().getClass()); + } + + public void testTreeMapWithoutComparator() { + TreeMap map = new TreeMap(); + map.put("benny", "hill"); + map.put("joe", "walnes"); + + String expected = "" + + "\n" + + " \n" + + " benny\n" + + " hill\n" + + " \n" + + " \n" + + " joe\n" + + " walnes\n" + + " \n" + + ""; + + TreeMap result = (TreeMap) assertBothWays(map, expected); + assertNull(result.comparator()); + } + + public void testEmptyTreeMap() { + TreeMap map = new TreeMap(); + + String expected = ""; + TreeMap result = (TreeMap) assertBothWays(map, expected); + assertNull(result.comparator()); + } + + public void testTreeMapDoesNotUseComparatorAtDeserialization() { + if (JVM.hasOptimizedTreeMapPutAll()) { + TreeMap map = new TreeMap(new UnusedComparator()); + map.put("john", "doe"); + map.put("benny", "hill"); + map.put("joe", "walnes"); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " benny\n" + + " hill\n" + + " \n" + + " \n" + + " joe\n" + + " walnes\n" + + " \n" + + " \n" + + " john\n" + + " doe\n" + + " \n" + + ""; + + assertEquals(expected, xstream.toXML(map)); + TreeMap result = (TreeMap) xstream.fromXML(expected); + assertSame(UnusedComparator.THROWING_COMPARATOR, result.comparator()); + assertEquals(new ArrayList(map.entrySet()), new ArrayList(result.entrySet())); + } + } + + public void testTreeSetWithComparator() { + TreeSet set = new TreeSet(new MyComparator()); + set.add("hi"); + set.add("bye"); + + String expected = "" + + "\n" + + " \n" + + " stuff\n" + + " \n" + + " bye\n" + + " hi\n" + + ""; + + TreeSet result = (TreeSet) assertBothWays(set, expected); + assertEquals(MyComparator.class, result.comparator().getClass()); + } + + public void testTreeSetWithoutComparator() { + TreeSet set = new TreeSet(); + set.add("hi"); + set.add("bye"); + + String expected = "" + + "\n" + + " bye\n" + + " hi\n" + + ""; + + TreeSet result = (TreeSet)assertBothWays(set, expected); + assertNull(result.comparator()); + } + + public void testEmptyTreeSet() { + TreeSet set = new TreeSet(); + + String expected = ""; + TreeSet result = (TreeSet)assertBothWays(set, expected); + assertNull(result.comparator()); + } + + public void testTreeSetDoesNotUseComparatorAtDeserialization() { + if (JVM.hasOptimizedTreeSetAddAll()) { + TreeSet set = new TreeSet(new UnusedComparator()); + set.add("guy"); + set.add("hi"); + set.add("bye"); + + String expected = "" + + "\n" + + " \n" + + " bye\n" + + " guy\n" + + " hi\n" + + ""; + + assertEquals(expected, xstream.toXML(set)); + TreeSet result = (TreeSet) xstream.fromXML(expected); + assertSame(UnusedComparator.THROWING_COMPARATOR, result.comparator()); + assertEquals(new ArrayList(set), new ArrayList(result)); + } + } + + public void testTreeSetRemoveWorksProperlyAfterDeserialization() { + TreeSet set = new TreeSet(); + set.add("guy"); + set.add("hi"); + set.add("bye"); + + TreeSet result = (TreeSet) xstream.fromXML(xstream.toXML(set)); + assertTrue(result.remove("hi")); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/WriteReplaceTest.java b/xstream/src/test/com/thoughtworks/acceptance/WriteReplaceTest.java new file mode 100644 index 0000000..62d9a4c --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/WriteReplaceTest.java @@ -0,0 +1,348 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2014, 2015 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. August 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.Original; +import com.thoughtworks.acceptance.objects.Replaced; +import com.thoughtworks.acceptance.objects.StandardObject; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectInputStream; +import java.io.ObjectOutput; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.StringUtils; + +public class WriteReplaceTest extends AbstractAcceptanceTest { + + public static class Thing extends StandardObject implements Serializable { + + int a; + int b; + + public Thing() { + } + + public Thing(int a, int b) { + this.a = a; + this.b = b; + } + + private Object writeReplace() { + return new Thing(a * 1000, b * 1000); + } + + private Object readResolve() { + return new Thing(a / 1000, b / 1000); + } + + } + + public void testReplacesAndResolves() throws IOException, ClassNotFoundException { + Thing thing = new Thing(3, 6); + + // ensure that Java serialization does not cause endless loop for a Thing + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(thing); + oos.close(); + + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream ios = new ObjectInputStream(bais); + assertEquals(thing, ios.readObject()); + ios.close(); + + // ensure that XStream does not cause endless loop for a Thing + xstream.alias("thing", Thing.class); + + String expectedXml = "" + + "\n" + + " 3000\n" + + " 6000\n" + + ""; + + assertBothWays(thing, expectedXml); + } + + public void testAllowsDifferentTypeToBeSubstituted() { + xstream.alias("original-class", Original.class); + xstream.alias("replaced-class", Replaced.class); + + Original in = new Original("hello world"); + + String expectedXml = "" + + "\n" + + " HELLO WORLD\n" + + ""; + + assertBothWays(in, expectedXml); + } + + public void testAllowsDifferentTypeToBeSubstitutedInList() { + xstream.alias("original-class", Original.class); + xstream.alias("replaced-class", Replaced.class); + + List in = new ArrayList(); + in.add(new Original("hello world")); + + String expectedXml = "" + + "\n" + + " \n" + + " HELLO WORLD\n" + + " \n" + + ""; + + assertBothWays(in, expectedXml); + } + + public static class Container extends StandardObject { + Original original; + } + + public void testAllowsDifferentTypeToBeSubstitutedAsMember() { + xstream.alias("container", Container.class); + xstream.alias("original-class", Original.class); + xstream.alias("replaced-class", Replaced.class); + + Container in = new Container(); + in.original = new Original("hello world"); + + String expectedXml = "" + + "\n" + + " \n" + + " HELLO WORLD\n" + + " \n" + + ""; + + assertBothWays(in, expectedXml); + } + + public static class ExternalizableContainer extends StandardObject implements Externalizable { + Original original; + + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + original = (Original)in.readObject(); + } + + public void writeExternal(ObjectOutput out) throws IOException { + out.writeObject(original); + } + } + + public void testAllowsDifferentTypeToBeSubstitutedInExternalizable() { + xstream.alias("container", ExternalizableContainer.class); + xstream.alias("original-class", Original.class); + xstream.alias("replaced-class", Replaced.class); + + ExternalizableContainer in = new ExternalizableContainer(); + in.original = new Original("hello world"); + + String expectedXml = "" + + "\n" + + " \n" + + " HELLO WORLD\n" + + " \n" + + ""; + + assertBothWays(in, expectedXml); + } + + public void testAllowsDifferentTypeToBeSubstitutedWithNonExistingClass() { + xstream.alias("original-class", Original.class); + xstream.alias("replaced-class", Replaced.class); + + Original in = new Original("hello world"); + + String xml = "" + + "\n" + + " HELLO WORLD\n" + + ""; + + assertEquals(in, xstream.fromXML(xml)); + } + + public void testAllowsDifferentTypeToBeSubstitutedWithNonExistingClassInList() { + xstream.alias("original-class", Original.class); + xstream.alias("replaced-class", Replaced.class); + + List in = new ArrayList(); + in.add(new Original("hello world")); + + String xml = "" + + "\n" + + " \n" + + " HELLO WORLD\n" + + " \n" + + ""; + + assertEquals(in, xstream.fromXML(xml)); + } + + public void testAllowsDifferentTypeToBeSubstitutedWithNonExistingClassAsMember() { + xstream.alias("container", Container.class); + xstream.alias("original-class", Original.class); + xstream.alias("replaced-class", Replaced.class); + + Container in = new Container(); + in.original = new Original("hello world"); + + String xml = "" + + "\n" + + " \n" + + " HELLO WORLD\n" + + " \n" + + ""; + + assertEquals(in, xstream.fromXML(xml)); + } + + public void testAllowsDifferentTypeToBeSubstitutedWithNonExistingClassInExternalizable() { + xstream.alias("container", ExternalizableContainer.class); + xstream.alias("original-class", Original.class); + xstream.alias("replaced-class", Replaced.class); + + ExternalizableContainer in = new ExternalizableContainer(); + in.original = new Original("hello world"); + + String xml = "" + + "\n" + + " \n" + + " HELLO WORLD\n" + + " \n" + + ""; + + assertEquals(in, xstream.fromXML(xml)); + } + + public static class OriginalSerializable extends StandardObject { + String originalValue; + + public OriginalSerializable() { + } + + public OriginalSerializable(String originalValue) { + this.originalValue = originalValue; + } + + private Object writeReplace() { + return new ReplacedSerializable(originalValue.toUpperCase()); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + } + } + + public static class ReplacedSerializable extends StandardObject { + String replacedValue; + + public ReplacedSerializable() { + } + + public ReplacedSerializable(String replacedValue) { + this.replacedValue = replacedValue; + } + + private Object readResolve() { + return new OriginalSerializable(replacedValue.toLowerCase()); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + } + } + + public void testAllowsDifferentTypeToBeSubstitutedForCustomSerializableObjects() { + xstream.alias("original-serializable-class", OriginalSerializable.class); + xstream.alias("replaced-serializable-class", ReplacedSerializable.class); + + OriginalSerializable in = new OriginalSerializable("hello world"); + + String expectedXml = "" + + "\n" + + " \n" + + " \n" + + " HELLO WORLD\n" + + " \n" + + " \n" + + ""; + + assertBothWays(in, expectedXml); + } + + public static class OriginalExternalizable extends StandardObject implements Externalizable { + String originalValue; + + public OriginalExternalizable() { + } + + public OriginalExternalizable(String originalValue) { + this.originalValue = originalValue; + } + + private Object writeReplace() { + return new ReplacedExternalizable(originalValue.toUpperCase()); + } + + public void writeExternal(ObjectOutput out) throws IOException { + out.writeObject(originalValue); + } + + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + originalValue = (String)in.readObject(); + } + } + + public static class ReplacedExternalizable extends StandardObject implements Externalizable { + String replacedValue; + + public ReplacedExternalizable() { + } + + public ReplacedExternalizable(String replacedValue) { + this.replacedValue = replacedValue; + } + + private Object readResolve() { + return new OriginalExternalizable(replacedValue.toLowerCase()); + } + + public void writeExternal(ObjectOutput out) throws IOException { + out.writeObject(StringUtils.reverse(replacedValue)); + } + + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + replacedValue = StringUtils.reverse((String)in.readObject()); + } + } + + public void testAllowsDifferentTypeToBeSubstitutedForCustomExternalizableObjects() { + xstream.alias("original-externalizable-class", OriginalExternalizable.class); + xstream.alias("replaced-externalizable-class", ReplacedExternalizable.class); + + OriginalExternalizable in = new OriginalExternalizable("hello world"); + + String expectedXml = "" + + "\n" + + " DLROW OLLEH\n" + + ""; + + assertBothWays(in, expectedXml); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/XStream11XmlFriendlyTest.java b/xstream/src/test/com/thoughtworks/acceptance/XStream11XmlFriendlyTest.java new file mode 100644 index 0000000..3e8e8b2 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/XStream11XmlFriendlyTest.java @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. July 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.XStream11XmlFriendlyReplacer; +import com.thoughtworks.xstream.io.xml.XppDriver; + +public class XStream11XmlFriendlyTest extends AbstractAcceptanceTest { + + protected XStream createXStream() { + XStream xstream = new XStream(new XppDriver(new XStream11XmlFriendlyReplacer())) { + protected boolean useXStream11XmlFriendlyMapper() { + return true; + } + + }; + setupSecurity(xstream); + return xstream; + } + + public static class WithDollarCharField extends StandardObject { + String $field; + String field$; + String fi$eld; + String fi$$eld; + } + + public void testSupportsFieldsWithDollarChar() { + xstream.alias("dollar", WithDollarCharField.class); + + WithDollarCharField in = new WithDollarCharField(); + in.$field = "a"; + in.field$ = "b"; + in.fi$eld = "c"; + in.fi$$eld = "d"; + + String expected11 = "" + + "\n" + + " <_DOLLAR_field>a\n" + + " b\n" + + " c\n" + + " d\n" + + ""; + + String expected12 = "" + + "\n" + + " <_-field>a\n" + + " b\n" + + " c\n" + + " d\n" + + ""; + + assertWithAsymmetricalXml(in, expected11, expected12); + } + + public static class WithUnderscoreCharField extends StandardObject { + String _field; + String field_; + String fi_eld; + String fi__eld; + } + + public void testSupportsFieldsWithUnderscoreChar() { + xstream.alias("underscore", WithUnderscoreCharField.class); + + WithUnderscoreCharField in = new WithUnderscoreCharField(); + in._field = "a"; + in.field_ = "b"; + in.fi_eld = "c"; + in.fi__eld = "d"; + + String expected11 = "" + + "\n" + + " <__field>a\n" + + " b\n" + + " c\n" + + " d\n" + + ""; + + assertWithAsymmetricalXml(in, expected11, expected11); + } + + public void testSupportsAliasWithDashChar() { + xstream.alias("under-score", WithUnderscoreCharField.class); + + WithUnderscoreCharField in = new WithUnderscoreCharField(); + in._field = "a"; + in.field_ = "b"; + in.fi_eld = "c"; + in.fi__eld = "d"; + + String expected11 = "" + + "\n" + + " <__field>a\n" + + " b\n" + + " c\n" + + " d\n" + + ""; + + assertWithAsymmetricalXml(in, expected11, expected11); + } + + public static class A_B extends StandardObject { + private int x; + + public A_B(int x) { + this.x = x; + } + + } + + public void testSupportsUnderscoreInShortClassName() { + String expected11 = "" + + "\n" + + " 3\n" + + ""; + + String expected12 = "" + + "\n" + + " 3\n" + + ""; + + assertWithAsymmetricalXml(new A_B(3), expected11, expected12); + } + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/XStream12CompatibilityTest.java b/xstream/src/test/com/thoughtworks/acceptance/XStream12CompatibilityTest.java new file mode 100644 index 0000000..d50457a --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/XStream12CompatibilityTest.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 27. June 2007 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.OpenSourceSoftware; +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.converters.reflection.FieldDictionary; +import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; +import com.thoughtworks.xstream.converters.reflection.XStream12FieldKeySorter; +import com.thoughtworks.xstream.core.ReferenceByXPathMarshallingStrategy; +import com.thoughtworks.xstream.core.ReferenceByXPathUnmarshaller; +import com.thoughtworks.xstream.core.TreeUnmarshaller; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * Test XStream 1.2 compatibility. + * + * @author Jörg Schaible + */ +public class XStream12CompatibilityTest extends AbstractAcceptanceTest { + + public static class ParentClass { + String name; + } + + public static class ChildClass extends ParentClass { + String name; + + ChildClass() { + this("JDK", "1.3"); + } + + ChildClass(final String parent, final String child) { + ((ParentClass)this).name = parent; + name = child; + } + + public String toString() { + return ((ParentClass)this).name + "/" + name; + } + } + + public void testCanDeserializeHiddenFieldsWithSameTypeWrittenWithXStream11() { + xstream.alias("parent", ParentClass.class); + xstream.alias("child", ChildClass.class); + + final String in = "" + + "\n" + + " CHILD\n" + + " PARENT\n" + + ""; + + final ChildClass child = (ChildClass)xstream.fromXML(in); + assertEquals("PARENT/CHILD", child.toString()); + } + + public static class ParentA extends StandardObject { + private List stuff = new ArrayList(); + + public List getParentStuff() { + return stuff; + } + } + + public static class ChildA extends ParentA { + private Map stuff = new HashMap(); + + public Map getChildStuff() { + return stuff; + } + } + + public void testCanDeserializeHiddenFieldsWithDifferentTypeWrittenWithXStream11() { + xstream.alias("child-a", ChildA.class); + xstream.alias("parent-a", ParentA.class); + String expected = "" + + "\n" + + " \n" + + " \n" + + " hello\n" + + " world\n" + + " \n" + + " \n" + + " \n" + + " foo\n" + + " \n" + + ""; + + ChildA childA = (ChildA)xstream.fromXML(expected); + assertEquals("world", childA.getChildStuff().get("hello")); + assertEquals("foo", childA.getParentStuff().iterator().next()); + } + + public void testCanWriteInheritanceHierarchiesInOldOrder() { + xstream = new XStream(new PureJavaReflectionProvider(new FieldDictionary(new XStream12FieldKeySorter()))); + OpenSourceSoftware openSourceSoftware = new OpenSourceSoftware("apache", "geronimo", "license"); + String xml = + "\n" + + " license\n" + + " apache\n" + + " geronimo\n" + + ""; + + xstream.alias("oss", OpenSourceSoftware.class); + assertEquals(xml, xstream.toXML(openSourceSoftware)); + } + + private final class XStream12ReferenceByXPathUnmarshaller extends + ReferenceByXPathUnmarshaller { + private XStream12ReferenceByXPathUnmarshaller( + Object root, HierarchicalStreamReader reader, ConverterLookup converterLookup, + Mapper mapper) { + super(root, reader, converterLookup, mapper); + isNameEncoding = false; + } + } + + public void testCanReadXmlUnfriendlyXPathReferences() { + xstream.setMarshallingStrategy(new ReferenceByXPathMarshallingStrategy(ReferenceByXPathMarshallingStrategy.RELATIVE) { + + protected TreeUnmarshaller createUnmarshallingContext(Object root, + HierarchicalStreamReader reader, ConverterLookup converterLookup, Mapper mapper) { + return new XStream12ReferenceByXPathUnmarshaller(root, reader, converterLookup, mapper); + } + + }); + xstream.alias("foo$bar", StringBuffer.class); + xstream.alias("x_y", StringBuffer.class); + String xml = + "\n" + + " foo\n" + + " \n" + + " bar\n" + + " \n" + + ""; + + List list = (List)xstream.fromXML(xml); + assertEquals(4, list.size()); + assertSame(list.get(0), list.get(1)); + assertEquals("foo", list.get(0).toString()); + assertSame(list.get(2), list.get(3)); + assertEquals("bar", list.get(2).toString()); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/XStream13CompatibilityTest.java b/xstream/src/test/com/thoughtworks/acceptance/XStream13CompatibilityTest.java new file mode 100644 index 0000000..1796384 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/XStream13CompatibilityTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. August 2011 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import java.util.TreeMap; +import java.util.TreeSet; + + +/** + * Test XStream 1.3 compatibility. + * + * @author Jörg Schaible + */ +public class XStream13CompatibilityTest extends AbstractAcceptanceTest { + + public void testCanReadOldTreeSet() { + final String in = "" + + "\n" + + " \n" + + " one\n" + + " two\n" + + ""; + TreeSet expected = new TreeSet(); + expected.add("two"); + expected.add("one"); + assertEquals(expected, xstream.fromXML(in)); + } + + public void testCanReadOldTreeMap() { + final String in = "" + + "\n" + + " \n" + + " \n" + + " one\n" + + " 1\n" + + " \n" + + " \n" + + " two\n" + + " 2\n" + + " \n" + + ""; + TreeMap expected = new TreeMap(); + expected.put("two", new Integer(2)); + expected.put("one", new Integer(1)); + assertEquals(expected, xstream.fromXML(in)); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/XStreamer.xsl b/xstream/src/test/com/thoughtworks/acceptance/XStreamer.xsl new file mode 100644 index 0000000..b2200b4 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/XStreamer.xsl @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/xstream/src/test/com/thoughtworks/acceptance/XStreamerTest.java b/xstream/src/test/com/thoughtworks/acceptance/XStreamerTest.java new file mode 100644 index 0000000..400f314 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/XStreamerTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. April 2006 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.OpenSourceSoftware; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.XStreamer; +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.security.TypePermission; + +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import java.io.ObjectStreamException; +import java.io.StringReader; +import java.io.StringWriter; +import java.net.URL; + + +/** + * @author Jörg Schaible + */ +public class XStreamerTest extends AbstractAcceptanceTest { + + private Transformer transformer; + + protected void setUp() throws Exception { + super.setUp(); + + final TransformerFactory transformerFactory = TransformerFactory.newInstance(); + final URL url = getClass().getResource("XStreamer.xsl"); + transformer = transformerFactory.newTransformer(new StreamSource(url.openStream())); + } + + final static class ImplicitXStreamContainer { + private XStream myXStream; + } + + public void testDetectsSelfMarshalling() { + ImplicitXStreamContainer c = new ImplicitXStreamContainer(); + c.myXStream = xstream; + try { + xstream.toXML(c); + fail("Thrown " + ConversionException.class.getName() + " expected"); + } catch (final ConversionException e) { + assertTrue(e.getMessage().indexOf("XStream instance")>=0); + } + } + + public void testCanConvertAnotherInstance() throws TransformerException { + XStream x = createXStream(); + final String xml = normalizedXStreamXML(xstream.toXML(x)); + final TypePermission[] permissions = XStreamer.getDefaultPermissions(); + for(int i = 0; i < permissions.length; ++i) + xstream.addPermission(permissions[i]); + final XStream serialized = (XStream)xstream.fromXML(xml); + final String xmlSerialized = normalizedXStreamXML(xstream.toXML(serialized)); + assertEquals(xml, xmlSerialized); + } + + public void testCanBeUsedAfterSerialization() throws TransformerException { + final String xml = xstream.toXML(createXStream()); + final TypePermission[] permissions = XStreamer.getDefaultPermissions(); + for(int i = 0; i < permissions.length; ++i) + xstream.addPermission(permissions[i]); + xstream = (XStream)xstream.fromXML(xml); + testCanConvertAnotherInstance(); + } + + public void testCanSerializeSelfContained() throws ClassNotFoundException, ObjectStreamException { + final OpenSourceSoftware oos = new OpenSourceSoftware("Walnes", "XStream", "BSD"); + xstream.alias("software", OpenSourceSoftware.class); + String xml = new XStreamer().toXML(xstream, oos); + assertEquals(oos, new XStreamer().fromXML(xml)); + } + + private String normalizedXStreamXML(String xml) throws TransformerException { + final StringWriter writer = new StringWriter(); + transformer.transform(new StreamSource(new StringReader(xml)), new StreamResult(writer)); + return writer.toString(); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/XmlFriendlyDollarOnlyTest.java b/xstream/src/test/com/thoughtworks/acceptance/XmlFriendlyDollarOnlyTest.java new file mode 100644 index 0000000..df2e122 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/XmlFriendlyDollarOnlyTest.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2007, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 12. September 2007 by Joerg Schaible + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder; +import com.thoughtworks.xstream.io.xml.XppDriver; + + +public class XmlFriendlyDollarOnlyTest extends XmlFriendlyTest { + + protected XStream createXStream() { + XStream xstream = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_"))); + setupSecurity(xstream); + xstream.allowTypesByWildcard(new String[]{getClass().getSuperclass().getName()+"$*"}); + return xstream; + } + + protected Object assertBothWays(Object root, String xml) { + return super.assertBothWays(root, replaceAll(xml, "__", "_")); + } + + // String.replaceAll is JDK 1.4 + protected String replaceAll(String s, final String occurance, final String replacement) { + final int len = occurance.length(); + final int inc = len - replacement.length(); + int i = -inc; + final StringBuffer buff = new StringBuffer(s); + // StringBuffer has no indexOf in JDK 1.3 + while((i = buff.toString().indexOf(occurance, i + inc)) >= 0) { + buff.replace(i, i + len, replacement); + } + return buff.toString(); + } + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/XmlFriendlyTest.java b/xstream/src/test/com/thoughtworks/acceptance/XmlFriendlyTest.java new file mode 100644 index 0000000..fc6b56f --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/XmlFriendlyTest.java @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 18. April 2006 by Mauro Talevi + */ +package com.thoughtworks.acceptance; + +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.core.JVM; + +import java.text.DecimalFormatSymbols; +import java.util.Locale; + + +public class XmlFriendlyTest extends AbstractAcceptanceTest { + + public static class WithDollarCharField extends StandardObject { + String $field; + String field$; + String fi$eld; + String fi$$eld; + } + + public void testSupportsFieldsWithDollarChar() { + xstream.alias("dollar", WithDollarCharField.class); + + WithDollarCharField in = new WithDollarCharField(); + in.$field = "a"; + in.field$ = "b"; + in.fi$eld = "c"; + in.fi$$eld = "d"; + + String expected = "" + + "\n" + + " <_-field>a\n" + + " b\n" + + " c\n" + + " d\n" + + ""; + assertBothWays(in, expected); + } + + public static class WithUnderscoreCharField extends StandardObject { + String _field; + String field_; + String fi_eld; + } + + public void testSupportsFieldsWithUnderscoreChar() { + xstream.alias("underscore", WithUnderscoreCharField.class); + + WithUnderscoreCharField in = new WithUnderscoreCharField(); + in._field = "a"; + in.field_ = "b"; + in.fi_eld = "c"; + + String expected = "" + + "\n" + + " <__field>a\n" + + " b\n" + + " c\n" + + ""; + assertBothWays(in, expected); + } + + public static class WithDoubleUnderscoreCharField extends StandardObject { + String __field; + String field__; + String fi__eld; + } + + public void testSupportsFieldsWithDoubleUnderscoreChar() { + xstream.alias("underscore", WithDoubleUnderscoreCharField.class); + + WithDoubleUnderscoreCharField in = new WithDoubleUnderscoreCharField(); + in.__field = "a"; + in.field__ = "b"; + in.fi__eld = "c"; + + String expected = "" + + "\n" + + " <____field>a\n" + + " b\n" + + " c\n" + + ""; + assertBothWays(in, expected); + } + + public static class WithDollarAndUnderscoreCharField extends StandardObject { + String $_$field; + String field$_$; + String fi_$_eld; + String fi_$$_eld; + String fi$__$eld; + } + + public void testSupportsFieldsWithDollarAndUnderScoreChar() { + xstream.alias("dollar", WithDollarAndUnderscoreCharField.class); + + WithDollarAndUnderscoreCharField in = new WithDollarAndUnderscoreCharField(); + in.$_$field = "a"; + in.field$_$ = "b"; + in.fi_$_eld = "c"; + in.fi_$$_eld = "d"; + in.fi$__$eld = "e"; + + String expected = "" + + "\n" + + " <_-___-field>a\n" + + " b\n" + + " c\n" + + " d\n" + + " e\n" + + ""; + assertBothWays(in, expected); + } + + public static class WithUnusualCharacters extends StandardObject { + String µ_; + String _µ; + String ¢¥€£äöüß; + } + + public void testSupportsFieldsWithUnusualChars() { + xstream.alias("unusual", WithUnusualCharacters.class); + + WithUnusualCharacters in = new WithUnusualCharacters(); + in.µ_ = "a"; + in._µ = "b"; + in.¢¥€£äöüß = "c"; + + String expected = "" + + "\n" + + " <_.00b5__>a\n" + + " <___.00b5>b\n" + + " <_.00a2_.00a5€_.00a3äöüß>c\n" + + ""; + assertBothWays(in, expected); + } + + public static class __ { + public static class A_B extends StandardObject { + private int x; + + public A_B(int x) { + this.x = x; + } + + } + } + + public void testSupportsUnderscoreInShortClassName() { + assertBothWays(new __.A_B(3), "" + + "\n" + + " 3\n" + + ""); + } + + public void testSlashRSlashSlashSlashN() { + String before = "\r\\\n"; + String xml = xstream.toXML(before); + assertEquals(before, xstream.fromXML(xml)); + } + + public void testCanDealWithUtfText() { + assertBothWays("J\u00F6rg", "J\u00F6rg"); + } + + public void testCanDealWithNullCharactersInText() { + assertBothWays("X\0Y", "X�Y"); + } + + public void testEscapesXmlUnfriendlyChars() { + assertBothWays("<", "<"); + assertBothWays(">", ">"); + assertBothWays("<>", "<>"); + assertBothWays("<=", "<="); + assertBothWays(">=", ">="); + assertBothWays("&", "&"); + assertBothWays("'", "'"); + assertBothWays("\"", """); + } + + public void testDecimalFormatSymbols() { + final String xml; + if (!JVM.is14()) { + xml = "\n" + + " \n" + + " \n" + + " ,\n" + + " #\n" + + " E\n" + + " .\n" + + " -\n" + + " ,\n" + + " ;\n" + + " \u2030\n" + + " %\n" + + " 1\n" + + " 0\n" + + " \ufffd\n" + + " DM\n" + + " \u221e\n" + + " DEM\n" + + " \n" + + " \n" + + ""; + } else if (!JVM.is16()) { + xml = "\n" + + " \n" + + " \n" + + " ,\n" + + " #\n" + + " E\n" + + " .\n" + + " -\n" + + " ,\n" + + " ;\n" + + " \u2030\n" + + " %\n" + + " 2\n" + + " 0\n" + + " \ufffd\n" + + " \u20ac\n" + + " \u221e\n" + + " EUR\n" + + " de_DE\n" + + " \n" + + " \n" + + ""; + } else { + xml = "\n" + + " \n" + + " \n" + + " ,\n" + + " #\n" + + " E\n" + + " .\n" + + " -\n" + + " ,\n" + + " ;\n" + + " \u2030\n" + + " %\n" + + " 3\n" + + " 0\n" + + " \ufffd\n" + + " \u20ac\n" + + " E\n" + + " \u221e\n" + + " EUR\n" + + " de_DE\n" + + " \n" + + " \n" + + ""; + } + final DecimalFormatSymbols format = new DecimalFormatSymbols(Locale.GERMANY); + assertBothWays(format, xml); + } + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/annotations/AliasTest.java b/xstream/src/test/com/thoughtworks/acceptance/annotations/AliasTest.java new file mode 100644 index 0000000..3bc3247 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/annotations/AliasTest.java @@ -0,0 +1,340 @@ +/* + * Copyright (C) 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 23. November 2007 by Joerg Schaible + */ +package com.thoughtworks.acceptance.annotations; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamAliasType; +import com.thoughtworks.xstream.annotations.XStreamAsAttribute; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * Tests annotations defining aliases for classes or fields. + * + * @author Chung-Onn Cheong + * @author Mauro Talevi + * @author Guilherme Silveira + * @author Jörg Schaible + */ +public class AliasTest extends AbstractAcceptanceTest { + + @Override + protected XStream createXStream() { + XStream xstream = super.createXStream(); + xstream.autodetectAnnotations(true); + return xstream; + } + + public void testAnnotationForClassWithAnnotatedConverter() { + Map map = new HashMap(); + map.put("first person", new Person("john doe")); + map.put("second person", new Person("jane doe")); + String xml = "" + + "\n" + + " \n" + + " second person\n" + + " jane doe\n" + + " \n" + + " \n" + + " first person\n" + + " john doe\n" + + " \n" + + ""; + assertBothWaysNormalized(map, xml, "map", "entry", "string"); + } + + public void testAnnotationForFieldWithAliasCycle() { + Cycle cycle = new Cycle(); + cycle.internal = cycle; + String xml = "" // + + "\n" // + + " \n" // + + ""; + assertBothWays(cycle, xml); + } + + @XStreamAlias("cycle") + public static class Cycle { + @XStreamAlias("oops") + private Cycle internal; + } + + public void testAnnotationForField() { + List nickNames = new ArrayList(); + nickNames.add("johnny"); + nickNames.add("jack"); + CustomPerson person = new CustomPerson("john", "doe", 25, nickNames); + String expectedXml = "" + + "\n" + + " john\n" + + " doe\n" + + " 25\n" + + " \n" + + " johnny\n" + + " jack\n" + + " \n" + + ""; + assertBothWays(person, expectedXml); + } + + @XStreamAlias("person") + public static class CustomPerson { + @XStreamAlias("first-name") + String firstName; + @XStreamAlias("last-name") + String lastName; + @XStreamAlias("age-in-years") + int ageInYears; + @XStreamAlias("nick-names") + List nickNames; + + public CustomPerson( + String firstName, String lastName, int ageInYears, List nickNames) { + this.firstName = firstName; + this.lastName = lastName; + this.ageInYears = ageInYears; + this.nickNames = nickNames; + } + + public boolean equals(Object obj) { + if ((obj == null) || !(obj instanceof CustomPerson)) return false; + return toString().equals(obj.toString()); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb + .append("firstName:") + .append(firstName) + .append(",lastName:") + .append(lastName) + .append(",ageInYears:") + .append(ageInYears) + .append(",nickNames:") + .append(nickNames); + return sb.toString(); + } + + } + + @XStreamAlias("person") + @XStreamConverter(PersonConverter.class) + public static class Person { + String name; + AddressBookInfo addressBook; + + public Person(String name) { + this.name = name; + addressBook = new AddressBook(); + } + + public boolean equals(Object obj) { + if ((obj == null) || !(obj instanceof Person)) return false; + return addressBook.equals(((Person)obj).addressBook); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("name:").append(name).append("addresbook:").append(addressBook); + return sb.toString(); + } + + } + + @XStreamAlias(value = "addressbook-info", impl = AddressBook.class) + public interface AddressBookInfo { + public List getAddresses(); + + public void setAddresses(List address); + } + + @XStreamAlias("addressbookAlias") + public static class AddressBook implements AddressBookInfo { + + // @XStreamContainedType + private List addresses; + + public AddressBook() { + addresses = new ArrayList(); + addresses.add(new Address("Home Address", 111)); + addresses.add(new Address("Office Address", 222)); + } + + public List getAddresses() { + return addresses; + } + + public void setAddresses(List addresses) { + this.addresses = addresses; + + } + + public boolean equals(Object obj) { + if ((obj == null) || !(obj instanceof AddressBookInfo)) return false; + return addresses.containsAll(((AddressBookInfo)obj).getAddresses()); + } + + } + + @XStreamAlias(value = "addressinfoAlias", impl = Address.class) + public interface AddressInfo { + public String addr(); + + public int zipcode(); + } + + @XStreamAlias(value = "addressAlias") + public static class Address implements AddressInfo { + + private String addr; + private int zipcode; + + public Address(String addr, int zipcode) { + this.addr = addr; + this.zipcode = zipcode; + } + + public String addr() { + return addr; + } + + public int zipcode() { + return zipcode; + } + + } + + public static class PersonConverter implements Converter { + public PersonConverter() { + } + + public String toString(Object obj) { + return ((Person)obj).name; + } + + public Object fromString(String str) { + return new Person(str); + } + + public boolean canConvert(Class type) { + return type == Person.class; + } + + public void marshal(Object source, HierarchicalStreamWriter writer, + MarshallingContext context) { + writer.setValue(toString(source)); + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + return fromString(reader.getValue()); + } + } + + static class Dash { + + @XStreamAlias("camel-case") + int camelCase = 5; + } + + public void testAnnotationForFieldWithAttributeDefinitionForFieldType() { + xstream.alias("dash", Dash.class); + xstream.useAttributeFor(int.class); + String xml = ""; + assertBothWays(new Dash(), xml); + } + + public static abstract class Aged { + @XStreamAlias("age") + @XStreamAsAttribute + private Integer id; + + Aged(Integer id) { + this.id = id; + } + } + + @XStreamAlias("thing") + public static class AgedThing extends Aged { + + @XStreamAsAttribute + private String name; + + AgedThing(String name, Integer id) { + super(id); + this.name = name; + } + } + + public void testAnnotationIsInheritedTogetherWithAsAttribute() { + String xml = ""; + assertBothWays(new AgedThing("Name", 99), xml); + } + + @XStreamAliasType("any") + public static abstract class Base { + String type = getClass().getName(); + } + public static class A extends Base { + } + public static class B extends Base { + } + public static class BB extends B { + } + + public void testAnnotationForATypeAlias() { + xstream.registerConverter(new SingleValueConverter() { + Mapper mapper = xstream.getMapper(); + public boolean canConvert(Class type) { + return Base.class.isAssignableFrom(type); + } + public String toString(Object obj) { + return ((Base)obj).type; + } + public Object fromString(String str) { + Class realClass = mapper.realClass(str); + try { + return realClass.newInstance(); + } catch (InstantiationException e) { + throw new ConversionException(e); + } catch (IllegalAccessException e) { + throw new ConversionException(e); + } + } + }); + + Base[] array = new Base[]{ new A(), new B(), new BB()}; + + String expectedXml = "" + + "\n" + + " com.thoughtworks.acceptance.annotations.AliasTest$A\n" + + " com.thoughtworks.acceptance.annotations.AliasTest$B\n" + + " com.thoughtworks.acceptance.annotations.AliasTest$BB\n" + + ""; + assertBothWays(array, expectedXml); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/annotations/AnnotationsTest.java b/xstream/src/test/com/thoughtworks/acceptance/annotations/AnnotationsTest.java new file mode 100644 index 0000000..5a63a4d --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/annotations/AnnotationsTest.java @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 16. September 2005 by Mauro Talevi + */ +package com.thoughtworks.acceptance.annotations; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamInclude; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.List; + + +/** + * Tests for annotation detection. + * + * @author Chung-Onn Cheong + * @author Mauro Talevi + * @author Guilherme Silveira + * @author Jörg Schaible + */ +public class AnnotationsTest extends AbstractAcceptanceTest { + + @Override + protected XStream createXStream() { + XStream xstream = super.createXStream(); + xstream.autodetectAnnotations(true); + return xstream; + } + + @XStreamAlias("param") + public static class ParameterizedContainer { + + private ParameterizedType type; + + public ParameterizedContainer() { + type = new ParameterizedType(new InternalType()); + } + + } + + @XStreamAlias("param") + public static class DoubleParameterizedContainer { + + private ArrayList> list; + + public DoubleParameterizedContainer() { + list = new ArrayList>(); + list.add(new ArrayList()); + list.get(0).add(new InternalType()); + } + + } + + @XStreamAlias("second") + public static class InternalType { + @XStreamAlias("aliased") + private String original = "value"; + + @Override + public boolean equals(Object obj) { + return obj instanceof InternalType + ? original.equals(((InternalType)obj).original) + : false; + } + + } + + @XStreamAlias("typeAlias") + public static class ParameterizedType { + @XStreamAlias("fieldAlias") + private T object; + + public ParameterizedType(T object) { + this.object = object; + } + + @Override + public boolean equals(Object obj) { + return obj instanceof ParameterizedType ? object + .equals(((ParameterizedType)obj).object) : false; + } + } + + public void testAreDetectedInParameterizedTypes() { + String xml = "" + + "\n" + + " \n" + + " \n" + + " value\n" + + " \n" + + " \n" + + ""; + assertBothWays(new ParameterizedContainer(), xml); + } + + public void testAreDetectedInNestedParameterizedTypes() { + String xml = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " value\n" + + " \n" + + " \n" + + " \n" + + ""; + assertBothWays(new DoubleParameterizedContainer(), xml); + } + + public void testAreDetectedInArrays() { + InternalType[] internalTypes = new InternalType[]{ + new InternalType(), new InternalType()}; + String xml = "" + + "\n" + + " \n" + + " value\n" + + " \n" + + " \n" + + " value\n" + + " \n" + + ""; + assertBothWays(internalTypes, xml); + } + + public void testAreDetectedInParametrizedArrays() { + ParameterizedType[] types = new ParameterizedType[]{ + new ParameterizedType("foo"), new ParameterizedType("bar")}; + String xml = "" + + "\n" + + " \n" + + " foo\n" + + " \n" + + " \n" + + " bar\n" + + " \n" + + ""; + assertBothWays(types, xml); + } + + public void testAreDetectedInJDKCollection() { + List list = new ArrayList(); + list.add(new InternalType()); + String xml = "" + + "\n" + + " \n" + + " value\n" + + " \n" + + ""; + assertBothWays(list, xml); + } + + public void testForClassIsDetectedAtDeserialization() { + // must preprocess annotations here + xstream.processAnnotations(InternalType.class); + InternalType internalType = new InternalType(); + String xml = "" // + + "\n" // + + " value\n" // + + ""; + assertEquals(internalType, xstream.fromXML(xml)); + } + + public void testForClassInObjectStreamIsDetectedAtDeserialization() throws IOException, ClassNotFoundException { + // must preprocess annotations here + xstream.processAnnotations(InternalType.class); + xstream.ignoreUnknownElements(); + InternalType internalType = new InternalType(); + String xml = "" + + "\n" + + " \n" + + " value\n" + + " 1\n" + + " \n" + + ""; + ObjectInputStream in = xstream.createObjectInputStream(new StringReader(xml)); + assertEquals(internalType, in.readObject()); + in.close(); + } + + @XStreamInclude({InternalType.class}) + interface Include { + } + + public void testCanBeIncluded() { + // must preprocess annotations from marker interface with inclusion + xstream.processAnnotations(Include.class); + InternalType internalType = new InternalType(); + String xml = "" // + + "\n" // + + " value\n" // + + ""; + assertEquals(internalType, xstream.fromXML(xml)); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/annotations/AttributesTest.java b/xstream/src/test/com/thoughtworks/acceptance/annotations/AttributesTest.java new file mode 100644 index 0000000..eea5094 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/annotations/AttributesTest.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2007, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 23. November 2007 by Joerg Schaible + */ +package com.thoughtworks.acceptance.annotations; + +import java.io.Serializable; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamAsAttribute; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import com.thoughtworks.xstream.converters.extended.ToStringConverter; + + +/** + * Tests annotations defining fields to be rendered as attributes. + * + * @author Chung-Onn Cheong + * @author Mauro Talevi + * @author Guilherme Silveira + * @author Jörg Schaible + */ +public class AttributesTest extends AbstractAcceptanceTest { + + @Override + protected XStream createXStream() { + XStream xstream = super.createXStream(); + xstream.autodetectAnnotations(true); + return xstream; + } + + @XStreamAlias("annotated") + public static class AnnotatedAttribute { + @XStreamAsAttribute + private String myField; + } + + public void testAnnotation() { + AnnotatedAttribute value = new AnnotatedAttribute(); + value.myField = "hello"; + String expected = ""; + assertBothWays(value, expected); + } + + @XStreamAlias("annotated") + public static class AnnotatedAliasedAttribute { + @XStreamAsAttribute + @XStreamAlias("field") + private String myField; + } + + public void testAnnotationInCombinationWithAlias() { + AnnotatedAliasedAttribute value = new AnnotatedAliasedAttribute(); + value.myField = "hello"; + String expected = ""; + assertBothWays(value, expected); + } + + @XStreamAlias("annotated") + public static class AnnotatedAttributeParameterized implements Serializable { + @XStreamAsAttribute + private String myField; + } + + public void testAnnotationInParameterizedClass() { + AnnotatedAttributeParameterized value = new AnnotatedAttributeParameterized(); + value.myField = "hello"; + String expected = ""; + assertBothWays(value, expected); + } + + @XStreamAlias("annotated") + public static class AnnotatedGenericAttributeParameterized implements Serializable { + @XStreamAsAttribute + private T myField; + } + + public void testAnnotationAtGenericTypeInParameterizedClass() { + AnnotatedGenericAttributeParameterized value = new AnnotatedGenericAttributeParameterized(); + value.myField = "hello"; + String expected = "" + + "\n" + + " hello\n" + + ""; + assertBothWays(value, expected); + } + + @XStreamAlias("annotated") + public static class AnnotatedGenericAttributeBounded implements Serializable { + @XStreamAsAttribute + private T myField; + } + + public void testAnnotationAtGenericTypeInBoundedClass() { + AnnotatedGenericAttributeBounded value = new AnnotatedGenericAttributeBounded(); + value.myField = "hello"; + String expected = "" + + "\n" + + " hello\n" + + ""; + assertBothWays(value, expected); + } + + @XStreamAlias("annotated") + public static class AnnotatedGenericAttributeAndConverterParameterized implements Serializable { + @XStreamAsAttribute + @XStreamConverter(value=ToStringConverter.class, useImplicitType=false, types={String.class}) + private T myField; + } + + public void testAnnotationAtGenericTypeWithLocalConverterInParameterizedClass() { + AnnotatedGenericAttributeAndConverterParameterized value = new AnnotatedGenericAttributeAndConverterParameterized(); + value.myField = "hello"; + String expected = ""; + assertBothWays(value, expected); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/annotations/FieldConverterTest.java b/xstream/src/test/com/thoughtworks/acceptance/annotations/FieldConverterTest.java new file mode 100644 index 0000000..06d8c3b --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/annotations/FieldConverterTest.java @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 02. March 2006 by Mauro Talevi + */ +package com.thoughtworks.acceptance.annotations; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.annotations.XStreamAsAttribute; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + + +/** + * Tests for using annotations to override field converters + * + * @author Guilherme Silveira + * @author Mauro Talevi + * @author Jörg Schaible + */ +public class FieldConverterTest extends AbstractAcceptanceTest { + + @Override + protected XStream createXStream() { + XStream xstream = super.createXStream(); + xstream.autodetectAnnotations(true); + return xstream; + } + + protected void setUp() throws Exception { + super.setUp(); + xstream.alias("annotatedTask", TaskWithAnnotations.class); + xstream.alias("derivedTask", DerivedTask.class); + xstream.alias("taskContainer", TaskContainer.class); + } + + public void testAnnotationForFieldsOfSameType() { + final TaskWithAnnotations task = new TaskWithAnnotations("Tom", "Dick", "Harry"); + final String xml = "" + + "\n" + + " \n" + + " Harry\n" + + ""; + assertBothWays(task, xml); + } + + public void testAnnotationForHiddenFields() { + final DerivedTask task = new DerivedTask("Tom", "Dick", "Harry"); + final String xml = "" + + "\n" + + " \n" + + " Harry\n" + + " Harry\n" + + " \n" + + ""; + assertBothWays(task, xml); + } + + public void testIsFoundInReferencedTypes() { + final TaskContainer taskContainer = new TaskContainer(); + final String xml = "" + + "\n" + + " \n" + + " \n" + + " Harry\n" + + " Harry\n" + + " \n" + + " \n" + + ""; + assertEquals(taskContainer, xstream.fromXML(xml)); + } + + public static class TaskWithAnnotations { + + @XStreamConverter(FirstConverter.class) + private final String name1; + + @XStreamConverter(SecondaryConverter.class) + @XStreamAsAttribute + private final String name2; + private final String name3; + + public TaskWithAnnotations(final String name1, final String name2, final String name3) { + this.name1 = name1; + this.name2 = name2; + this.name3 = name3; + } + + @Override + public boolean equals(final Object obj) { + return obj != null + && TaskWithAnnotations.class.isAssignableFrom(obj.getClass()) + && ((TaskWithAnnotations)obj).name1.equals(name1) + && ((TaskWithAnnotations)obj).name2.equals(name2) + && ((TaskWithAnnotations)obj).name3.equals(name3); + } + } + + public static class DerivedTask extends TaskWithAnnotations { + private final String name1; + + @XStreamConverter(FirstConverter.class) + private final String name3; + + public DerivedTask(final String name1, final String name2, final String name3) { + super(name1, name2, name3); + this.name1 = name3; + this.name3 = name1; + } + + @Override + public boolean equals(final Object obj) { + return obj != null + && DerivedTask.class.isAssignableFrom(obj.getClass()) + && ((DerivedTask)obj).name1.equals(name1) + && ((DerivedTask)obj).name3.equals(name3) + && super.equals(obj); + } + } + + public static class TaskContainer { + private final DerivedTask task = new DerivedTask("Tom", "Dick", "Harry"); + + @Override + public boolean equals(final Object obj) { + return obj != null + && TaskContainer.class.equals(obj.getClass()) + && task.equals(((TaskContainer)obj).task); + } + } + + public static class FirstConverter implements Converter { + + public void marshal(final Object source, final HierarchicalStreamWriter writer, + final MarshallingContext context) { + final String str = source.toString(); + writer.addAttribute("str", str); + } + + public Object unmarshal(final HierarchicalStreamReader reader, + final UnmarshallingContext context) { + final String str = reader.getAttribute("str"); + return str; + } + + public boolean canConvert(final Class type) { + return type.equals(String.class); + } + } + + public static class SecondaryConverter implements SingleValueConverter { + + public boolean canConvert(final Class type) { + return type.equals(String.class); + } + + public Object fromString(String value) { + return value.substring(1, value.length() - 1); + } + + public String toString(Object source) { + return "_" + source.toString() + "_"; + } + } + + public static class CustomConverter implements Converter { + + private static int total = 0; + + public CustomConverter() { + total++ ; + } + + public void marshal(Object source, HierarchicalStreamWriter writer, + MarshallingContext context) { + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + return null; + } + + public boolean canConvert(Class type) { + return type.equals(Double.class); + } + + } + + public static class Account { + @XStreamConverter(CustomConverter.class) + private Double value; + + public Account() { + this.value = Math.random(); + } + } + + public static class Client { + @XStreamConverter(CustomConverter.class) + private Double value; + + public Client() { + this.value = Math.random(); + } + } + + public void testAreCachedPerField() { + int before = CustomConverter.total; + toXML(new Account()); + int after = CustomConverter.total; + assertEquals(before + 1, after); + } + + public void testAreCachedPerFieldInDifferentContexts() { + int before = CustomConverter.total; + toXML(new Account()); + toXML(new Client()); + int after = CustomConverter.total; + assertEquals(before + 1, after); + } + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/annotations/ImplicitArrayTest.java b/xstream/src/test/com/thoughtworks/acceptance/annotations/ImplicitArrayTest.java new file mode 100644 index 0000000..cc890de --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/annotations/ImplicitArrayTest.java @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. July 2011 by Joerg Schaible + */ +package com.thoughtworks.acceptance.annotations; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamAsAttribute; +import com.thoughtworks.xstream.annotations.XStreamImplicit; + + +/** + * Test for annotations mapping implicit arrays. + * + * @author Jörg Schaible + */ +public class ImplicitArrayTest extends AbstractAcceptanceTest { + + @Override + protected XStream createXStream() { + XStream xstream = super.createXStream(); + xstream.autodetectAnnotations(true); + return xstream; + } + + public void testAnnotation() { + String expected = "" + + "\n" + + " one\n" + + " two\n" + + ""; + ImplicitRootOne implicitRoot = new ImplicitRootOne(); + implicitRoot.values = new String[]{ + "one", "two" + }; + assertBothWays(implicitRoot, expected); + } + + public void testAnnotationWithItemFieldName() { + String expected = "" + + "\n" + + " one\n" + + " two\n" + + ""; + ImplicitRootTwo implicitRoot = new ImplicitRootTwo(); + implicitRoot.values = new String[]{ + "one", "two" + }; + assertBothWays(implicitRoot, expected); + } + + @XStreamAlias("root") + public static class ImplicitRootOne { + @XStreamImplicit() + String[] values; + } + + @XStreamAlias("root") + public static class ImplicitRootTwo { + @XStreamImplicit(itemFieldName = "value") + String[] values; + } + + @XStreamAlias("component") + public static class ParameterizedComponentType { + @XStreamImplicit(itemFieldName = "line") + private Point[][] signatureLines; + } + + @XStreamAlias("point") + public static class Point { + @XStreamAsAttribute + private int x; + @XStreamAsAttribute + private int y; + + public Point(int x, int y) { + this.x = x; + this.y = y; + } + } + + public void testAnnotationHandlesParameterizedComponentTypes() { + String xml = "" + + "\n" + + " \n" + + " \n" + + " \n" + + ""; + ParameterizedComponentType root = new ParameterizedComponentType(); + root.signatureLines = new Point[][] { + new Point[] { new Point(33, 11) } + }; + assertBothWays(root, xml); + } + + @XStreamAlias("point3d") + public static class Point3D extends Point { + @XStreamAsAttribute + private int z; + + public Point3D(int x, int y, int z) { + super(x,y); + this.z = z; + } + } + + @XStreamAlias("root") + public static class VariantArray { + @XStreamImplicit + private Point[] points; + } + + public void testCanHandleVariantArrays() + { + VariantArray array = new VariantArray(); + array.points = new Point[] { + new Point(1, 2), + new Point3D(3, 4, 5), + new Point(6, 7) + }; + String xml = "" // + + "\n" // + + " \n" + + " \n" + + " \n" + + ""; + assertBothWays(array, xml); + } + + @XStreamAlias("primitives") + public static class PrimitiveArrays { + @XStreamImplicit() + private char[] chars; + } + + public void testWorksForTypesThatArePrimitiveArrays() { + PrimitiveArrays type = new PrimitiveArrays(); + type.chars = new char[]{'f', 'o', 'o'}; + String xml = "" // + + "\n" // + + " f\n" // + + " o\n" // + + " o\n" // + + ""; + assertBothWays(type, xml); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/annotations/ImplicitCollectionTest.java b/xstream/src/test/com/thoughtworks/acceptance/annotations/ImplicitCollectionTest.java new file mode 100644 index 0000000..49dace8 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/annotations/ImplicitCollectionTest.java @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. December 2006 by Joerg Schaible + */ +package com.thoughtworks.acceptance.annotations; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.xstream.InitializationException; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamAsAttribute; +import com.thoughtworks.xstream.annotations.XStreamImplicit; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * Test for annotations mapping implicit collections. + * + * @author Lucio Benfante + * @author Jörg Schaible + */ +public class ImplicitCollectionTest extends AbstractAcceptanceTest { + + @Override + protected XStream createXStream() { + XStream xstream = super.createXStream(); + xstream.autodetectAnnotations(true); + return xstream; + } + + public void testAnnotation() { + String expected = "" + + "\n" + + " one\n" + + " two\n" + + ""; + ImplicitRootOne implicitRoot = new ImplicitRootOne(); + implicitRoot.getValues().add("one"); + implicitRoot.getValues().add("two"); + assertBothWays(implicitRoot, expected); + } + + public void testAnnotationWithItemFieldName() { + String expected = "" + + "\n" + + " one\n" + + " two\n" + + ""; + ImplicitRootTwo implicitRoot = new ImplicitRootTwo(); + implicitRoot.getValues().add("one"); + implicitRoot.getValues().add("two"); + assertBothWays(implicitRoot, expected); + } + + public void testAnnotationFailsForInvalidFieldType() { + try { + xstream.processAnnotations(InvalidImplicitRoot.class); + fail("Thrown " + InitializationException.class.getName() + " expected"); + } catch (final InitializationException e) { + assertTrue(e.getMessage().indexOf("\"value\"") > 0); + } + } + + @XStreamAlias("root") + public static class ImplicitRootOne { + @XStreamImplicit() + private List values = new ArrayList(); + + public List getValues() { + return values; + } + + public void setValues(List values) { + this.values = values; + } + } + + @XStreamAlias("root") + public static class ImplicitRootTwo { + @XStreamImplicit(itemFieldName = "value") + private List values = new ArrayList(); + + public List getValues() { + return values; + } + + public void setValues(List values) { + this.values = values; + } + } + + @XStreamAlias("root") + public static class InvalidImplicitRoot { + @XStreamImplicit(itemFieldName = "outch") + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + @XStreamAlias("implicit") + public static class ImplicitParameterizedType { + @XStreamImplicit(itemFieldName = "line") + private ArrayList> signatureLines; + } + + @XStreamAlias("point") + public static class Point { + @XStreamAsAttribute + private int x; + @XStreamAsAttribute + private int y; + + public Point(int x, int y) { + this.x = x; + this.y = y; + } + } + + public void testAnnotationHandlesParameterizedTypes() { + String xml = "" + + "\n" + + " \n" + + " \n" + + " \n" + + ""; + ImplicitParameterizedType root = new ImplicitParameterizedType(); + root.signatureLines = new ArrayList>(); + root.signatureLines.add(new ArrayList()); + root.signatureLines.get(0).add(new Point(33, 11)); + assertBothWays(root, xml); + } + + @XStreamAlias("type") + public static class ParametrizedTypeIsInterface { + @XStreamImplicit() + private ArrayList list = new ArrayList(); + } + + public void testWorksForTypesThatAreInterfaces() { + ParametrizedTypeIsInterface type = new ParametrizedTypeIsInterface(); + type.list = new ArrayList(); + type.list.add(new HashMap()); + String xml = "" // + + "\n" // + + " \n" // + + ""; + assertBothWays(type, xml); + } + + @XStreamAlias("untyped") + private static class Untyped { + @XStreamImplicit + private List list = new ArrayList(); + + public Untyped() { + list.add("1"); + } + } + + public void testCanHandleUntypedCollections() { + Untyped untyped = new Untyped(); + String xml = "" // + + "\n" // + + " 1\n" // + + ""; + assertBothWays(untyped, xml); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/annotations/ImplicitMapTest.java b/xstream/src/test/com/thoughtworks/acceptance/annotations/ImplicitMapTest.java new file mode 100644 index 0000000..a4dfc90 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/annotations/ImplicitMapTest.java @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 05. August 2011 by Joerg Schaible + */ +package com.thoughtworks.acceptance.annotations; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamAsAttribute; +import com.thoughtworks.xstream.annotations.XStreamImplicit; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + + +/** + * Test for annotations mapping implicit maps. + * + * @author Jörg Schaible + */ +public class ImplicitMapTest extends AbstractAcceptanceTest { + + @Override + protected XStream createXStream() { + XStream xstream = super.createXStream(); + xstream.autodetectAnnotations(true); + xstream.addDefaultImplementation(LinkedHashMap.class, Map.class); + return xstream; + } + + public void testAnnotation() { + String expected = "" + + "\n" + + " \n" + + " Microsoft\n" + + " Windows\n" + + " \n" + + " \n" + + " Red Hat\n" + + " Linux\n" + + " \n" + + ""; + ImplicitRootOne implicitRoot = new ImplicitRootOne(); + implicitRoot.getValues().put("Windows", new Software("Microsoft", "Windows")); + implicitRoot.getValues().put("Linux", new Software("Red Hat", "Linux")); + assertBothWays(implicitRoot, expected); + } + + public void testAnnotationWithItemFieldName() { + String expected = "" + + "\n" + + " \n" + + " Microsoft\n" + + " Windows\n" + + " \n" + + " \n" + + " Red Hat\n" + + " Linux\n" + + " \n" + + ""; + ImplicitRootTwo implicitRoot = new ImplicitRootTwo(); + implicitRoot.getValues().put("Windows", new Software("Microsoft", "Windows")); + implicitRoot.getValues().put("Linux", new Software("Red Hat", "Linux")); + assertBothWays(implicitRoot, expected); + } + + @XStreamAlias("root") + public static class ImplicitRootOne { + @XStreamImplicit(keyFieldName = "name") + private Map values = new LinkedHashMap(); + + public Map getValues() { + return values; + } + + public void setValues(Map values) { + this.values = values; + } + } + + @XStreamAlias("root") + public static class ImplicitRootTwo { + @XStreamImplicit(keyFieldName = "name", itemFieldName = "value") + private Map values = new LinkedHashMap(); + + public Map getValues() { + return values; + } + + public void setValues(Map values) { + this.values = values; + } + } + + @XStreamAlias("implicit") + public static class ImplicitParameterizedType { + @XStreamImplicit(itemFieldName = "line", keyFieldName="id") + private LinkedHashMap> signatureLines; + } + + @XStreamAlias("point") + public static class Point { + @XStreamAsAttribute + private int x; + @XStreamAsAttribute + private int y; + private final T id; + + public Point(T id, int x, int y) { + this.id = id; + this.x = x; + this.y = y; + } + } + + public void testAnnotationHandlesParameterizedTypes() { + String xml = "" + + "\n" + + " \n" + + " 42\n" + + " \n" + + ""; + ImplicitParameterizedType root = new ImplicitParameterizedType(); + root.signatureLines = new LinkedHashMap>(); + root.signatureLines.put(42L, new Point(42L, 33, 11)); + assertBothWays(root, xml); + } + + @XStreamAlias("type") + public static class ParametrizedTypeIsInterface { + @XStreamImplicit(keyFieldName="name") + private Map map = new LinkedHashMap(); + } + + public void testWorksForTypesThatAreInterfaces() { + ParametrizedTypeIsInterface type = new ParametrizedTypeIsInterface(); + type.map.put("Windows", new Software("Microsoft", "Windows")); + String xml = "" // + + "\n" // + + " \n" + + " Microsoft\n" + + " Windows\n" + + " \n" + + ""; + assertBothWays(type, xml); + } + + @XStreamAlias("untyped") + private static class Untyped { + @XStreamImplicit(keyFieldName="name") + private Map map = new HashMap(); + + public Untyped() { + map.put("Windows", new Software("Microsoft", "Windows")); + } + } + + public void testCanHandleUntypedCollections() { + Untyped untyped = new Untyped(); + String xml = "" // + + "\n" // + + " \n" + + " Microsoft\n" + + " Windows\n" + + " \n" + + ""; + assertBothWays(untyped, xml); + } + + public interface Code {} + + @XStreamAlias("software") + public static class Software extends StandardObject implements Code { + + public String vendor; + public String name; + + public Software() { + } + + public Software(String vendor, String name) { + this.vendor = vendor; + this.name = name; + } + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/annotations/OmitFieldTest.java b/xstream/src/test/com/thoughtworks/acceptance/annotations/OmitFieldTest.java new file mode 100644 index 0000000..99e5474 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/annotations/OmitFieldTest.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 23. November 2007 by Joerg Schaible + */ +package com.thoughtworks.acceptance.annotations; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamOmitField; + + +/** + * Tests annotation to omit a field. + * + * @author Chung-Onn Cheong + * @author Mauro Talevi + * @author Guilherme Silveira + * @author Jörg Schaible + */ +public class OmitFieldTest extends AbstractAcceptanceTest { + + @Override + protected XStream createXStream() { + XStream xstream = super.createXStream(); + xstream.autodetectAnnotations(true); + return xstream; + } + + @XStreamAlias("apartment") + public static class Apartment { + + @XStreamOmitField + int size; + + protected Apartment(int size) { + this.size = size; + } + } + + public void testAnnotation() { + Apartment ap = new Apartment(5); + String expectedXml = ""; + assertBothWays(ap, expectedXml); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/annotations/ParametrizedConverterTest.java b/xstream/src/test/com/thoughtworks/acceptance/annotations/ParametrizedConverterTest.java new file mode 100644 index 0000000..954a778 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/annotations/ParametrizedConverterTest.java @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2008, 2009, 2011, 2012, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. January 2008 by Joerg Schaible + */ +package com.thoughtworks.acceptance.annotations; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import com.thoughtworks.xstream.annotations.XStreamConverters; +import com.thoughtworks.xstream.annotations.XStreamInclude; +import com.thoughtworks.xstream.converters.basic.BooleanConverter; +import com.thoughtworks.xstream.converters.collections.MapConverter; +import com.thoughtworks.xstream.converters.extended.NamedMapConverter; +import com.thoughtworks.xstream.converters.extended.ToAttributedValueConverter; +import com.thoughtworks.xstream.converters.extended.ToStringConverter; +import com.thoughtworks.xstream.converters.javabean.JavaBeanConverter; +import com.thoughtworks.xstream.mapper.Mapper; + + +/** + * Tests for using annotations for classes. + * + * @author Chung-Onn, Cheong + * @author Jörg Schaible + * @author Jason Greanya + */ +public class ParametrizedConverterTest extends AbstractAcceptanceTest { + + @Override + protected XStream createXStream() { + XStream xstream = super.createXStream(); + xstream.autodetectAnnotations(true); + return xstream; + } + + protected void setUp() throws Exception { + super.setUp(); + xstream.alias("my-map", MyMap.class); + xstream.alias("decimal", Decimal.class); + xstream.alias("type", Type.class); + xstream.processAnnotations(MyMap.class); + xstream.processAnnotations(DerivedType.class); + xstream.processAnnotations(SimpleBean.class); + xstream.processAnnotations(ContainsMap.class); + } + + public void testAnnotationForConvertersWithParameters() { + final MyMap value = new MyMap(); + value.put("key1", "value1"); + String expected = "" + + "\n" + + " \n" + + " key1\n" + + " value1\n" + + " \n" + + ""; + assertBothWays(value, expected); + } + + @XStreamConverters({ + @XStreamConverter(value = MyMapConverter.class, priority = XStream.PRIORITY_NORMAL + 1, types = {MyMap.class}) + }) + public static class MyMap extends HashMap { + } + + public static class MyMapConverter extends MapConverter { + + private final Class myType; + + public MyMapConverter(Mapper classMapper, Class myType) { + super(classMapper); + this.myType = myType; + } + + public boolean canConvert(Class type) { + return type.equals(myType); + } + + } + + /** + * Tests a class-level XStreamConverter annotation subclassed from BigDecimal + */ + public void testCanUseCurrentTypeAsParameter() { + final Decimal value = new Decimal("5.5"); + String expected = "5.5"; + + assertBothWays(value, expected); + } + + /** + * Tests three field-level XStreamConverter annotations for different types, which guarantees + * the internal converterCache on AnnotationMapper is functioning properly. + */ + public void testSameConverterWithDifferentType() { + final Type value = new Type(new Decimal("1.5"), new Boolean(true)); + String expected = "" + + "\n" + + " 1.5\n" + + " true\n" + + " yes\n" + + ""; + + assertBothWays(value, expected); + } + + @XStreamConverter(ToStringConverter.class) + public static class Decimal extends BigDecimal { + public Decimal(String str) { + super(str); + } + } + + public static class Type { + @XStreamConverter(ToStringConverter.class) + private Decimal decimal = null; + @XStreamConverter(ToStringConverter.class) + @XStreamAlias("boolean") + private Boolean bool = null; + @XStreamConverter(value=BooleanConverter.class, booleans={true}, strings={"yes", "no"}) + private Boolean agreement = null; + + public Type(Decimal decimal, Boolean bool) { + this.decimal = decimal; + this.bool = bool; + this.agreement = bool; + } + } + + public void testConverterWithSecondTypeParameter() { + final Type value = new DerivedType(new Decimal("1.5"), new Boolean(true), DerivedType.E.FOO); + String expected = "1.5".replace('\'', '"'); + assertBothWays(value, expected); + } + + @XStreamAlias("dtype") + @XStreamConverter(value=ToAttributedValueConverter.class, types={Type.class}, strings={"decimal"}) + public static class DerivedType extends Type { + public enum E { FOO, BAR }; + @XStreamAlias("enum") + private E e; + + public DerivedType(Decimal decimal, Boolean bool, E e) { + super(decimal, bool); + this.e = e; + } + } + + public void testAnnotatedJavaBeanConverter() { + final SimpleBean value = new SimpleBean(); + value.setName("joe"); + String expected = "" + + "\n" + + " joe\n" + + ""; + assertBothWays(value, expected); + } + + @XStreamAlias("bean") + @XStreamConverter(JavaBeanConverter.class) + public static class SimpleBean extends StandardObject { + private String myName; + + public String getName() { + return myName; + } + + public void setName(String name) { + myName = name; + } + } + + public void testAnnotatedNamedMapConverter() { + Map map = new MyEnumMap(); + map.put(ContainsMap.E.FOO, "foo"); + map.put(ContainsMap.E.BAR, "bar"); + final ContainsMap value = new ContainsMap(map); + String expected = ("" + + "\n" + + " \n" + + " foo\n" + + " bar\n" + + " \n" + + "").replace('\'', '"'); + assertBothWays(value, expected); + } + + @XStreamInclude({MyEnumMap.class}) + @XStreamAlias("container") + public static class ContainsMap extends StandardObject { + public enum E { + FOO, BAR + }; + + @XStreamConverter(value = NamedMapConverter.class, strings = {"issue", "key", ""}, types = { + MyEnumMap.class, E.class, String.class}, booleans = {true, false}, useImplicitType = false) + private Map map; + + public ContainsMap(Map map) { + this.map = map; + } + } + + @XStreamAlias("my-enums") + public static class MyEnumMap extends LinkedHashMap { + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/annotations/XStream12AnnotationCompatibilityTest.java b/xstream/src/test/com/thoughtworks/acceptance/annotations/XStream12AnnotationCompatibilityTest.java new file mode 100644 index 0000000..9de2e40 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/annotations/XStream12AnnotationCompatibilityTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 10. November 2007 by Joerg Schaible + */ +package com.thoughtworks.acceptance.annotations; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.annotations.AnnotationProvider; +import com.thoughtworks.xstream.annotations.AnnotationReflectionConverter; +import com.thoughtworks.xstream.annotations.Annotations; + + +/** + * Tests XStream 1.2.x annotation compatibility. + * @author Jörg Schaible + */ +public class XStream12AnnotationCompatibilityTest extends AbstractAcceptanceTest { + + @Override + protected void setUp() throws Exception { + super.setUp(); + xstream = new XStream(); + xstream.registerConverter( + new AnnotationReflectionConverter(xstream.getMapper(), xstream + .getReflectionProvider(), new AnnotationProvider()), XStream.PRIORITY_VERY_LOW); + xstream.alias("annotatedTask", FieldConverterTest.TaskWithAnnotations.class); + } + + public void testDifferentConverterCanBeAnnotatedForFieldsOfSameType() { + final FieldConverterTest.TaskWithAnnotations task = new FieldConverterTest.TaskWithAnnotations( + "Tom", "Dick", "Harry"); + final String xml = "" + + "\n" + + " \n" + + " _Dick_\n" + + " Harry\n" + + ""; + assertBothWays(task, xml); + } + + public void testImplicitCollection() { + String expected = "" + + "\n" + + " one\n" + + " two\n" + + ""; + Annotations.configureAliases(xstream, ImplicitCollectionTest.ImplicitRootOne.class); + ImplicitCollectionTest.ImplicitRootOne implicitRoot = new ImplicitCollectionTest.ImplicitRootOne(); + implicitRoot.getValues().add("one"); + implicitRoot.getValues().add("two"); + assertBothWays(implicitRoot, expected); + } + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/objects/Category.java b/xstream/src/test/com/thoughtworks/acceptance/objects/Category.java new file mode 100644 index 0000000..3919aa4 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/objects/Category.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. April 2007 by Joerg Schaible + */ +package com.thoughtworks.acceptance.objects; + +import java.util.List; + +public class Category { + + String name; + String id; + List products; + + public Category() {} // JDK 1.3 + + public Category(String name, String id) { + super(); + this.name = name; + this.id = id; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getProducts() { + return products; + } + + public void setProducts(List products) { + this.products = products; + } + + public String toString() { + String ret = "[" + name + ", " + id; + if (products != null) { + ret += "\n{"; + for (java.util.Iterator it = products.iterator(); it.hasNext();) { + Product product = (Product) it.next(); + ret += product + "\n"; + } + ret += "}"; + } + ret += "]"; + return ret; + } + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/objects/Hardware.java b/xstream/src/test/com/thoughtworks/acceptance/objects/Hardware.java new file mode 100644 index 0000000..43814e7 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/objects/Hardware.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2003, 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.acceptance.objects; + + +public class Hardware extends StandardObject { + public String arch; + public String name; + + public Hardware() { + } + + public Hardware(String arch, String name) { + this.arch = arch; + this.name = name; + } + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/objects/OpenSourceSoftware.java b/xstream/src/test/com/thoughtworks/acceptance/objects/OpenSourceSoftware.java new file mode 100644 index 0000000..db72dcb --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/objects/OpenSourceSoftware.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2003, 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.acceptance.objects; + +public class OpenSourceSoftware extends Software { + + private String license; + + public OpenSourceSoftware() { + } + + public OpenSourceSoftware(String vendor, String name, String license) { + super(vendor, name); + this.license = license; + } + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/objects/Original.java b/xstream/src/test/com/thoughtworks/acceptance/objects/Original.java new file mode 100644 index 0000000..a7305ec --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/objects/Original.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. October 2008 by Joerg Schaible + */ + +/** + * @author Joe Walnes + */ +package com.thoughtworks.acceptance.objects; + + +public class Original extends StandardObject { + String originalValue; + + public Original() { + } + + public Original(String originalValue) { + this.originalValue = originalValue; + } + + private Object writeReplace() { + return new Replaced(originalValue.toUpperCase()); + } +} \ No newline at end of file diff --git a/xstream/src/test/com/thoughtworks/acceptance/objects/OwnerOfExternalizable.java b/xstream/src/test/com/thoughtworks/acceptance/objects/OwnerOfExternalizable.java new file mode 100644 index 0000000..4fc98e1 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/objects/OwnerOfExternalizable.java @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2010, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 05. July 2011 by Joerg Schaible, factored out of ExternalizableTest. + */ +package com.thoughtworks.acceptance.objects; + + +public class OwnerOfExternalizable extends StandardObject { + public SomethingExternalizable target; +} \ No newline at end of file diff --git a/xstream/src/test/com/thoughtworks/acceptance/objects/Product.java b/xstream/src/test/com/thoughtworks/acceptance/objects/Product.java new file mode 100644 index 0000000..f1ed200 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/objects/Product.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. April 2007 by Joerg Schaible + */ +package com.thoughtworks.acceptance.objects; + +import java.util.ArrayList; + + +public class Product { + + String name; + String id; + double price; + ArrayList tags; + + public Product(String name, String id, double price) { + super(); + this.name = name; + this.id = id; + this.price = price; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + public ArrayList getTags() { + return tags; + } + + public void setTags(ArrayList tags) { + this.tags = tags; + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.id == null) ? 0 : this.id.hashCode()); + result = prime * result + ((this.name == null) ? 0 : this.name.hashCode()); + long temp; + temp = Double.doubleToLongBits(this.price); + result = prime * result + (int)(temp ^ (temp >>> 32)); + result = prime * result + ((this.tags == null) ? 0 : this.tags.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + Product other = (Product)obj; + if (this.id == null) { + if (other.id != null) return false; + } else if (!this.id.equals(other.id)) return false; + if (this.name == null) { + if (other.name != null) return false; + } else if (!this.name.equals(other.name)) return false; + if (Double.doubleToLongBits(this.price) != Double.doubleToLongBits(other.price)) + return false; + if (this.tags == null) { + if (other.tags != null) return false; + } else if (!this.tags.equals(other.tags)) return false; + return true; + } + + public String toString() { + String ret = "[" + name + ", " + id + ", " + price; + if (tags != null) { + ret += "\n{"; + for (java.util.Iterator it = tags.iterator(); it.hasNext();) { + String tag = (String)it.next(); + ret += tag + "\n"; + } + ret += "}"; + } + ret += "]"; + return ret; + } + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/objects/Replaced.java b/xstream/src/test/com/thoughtworks/acceptance/objects/Replaced.java new file mode 100644 index 0000000..75d27d9 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/objects/Replaced.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. October 2008 by Joerg Schaible + */ + +/** + * @author Joe Walnes + */ +package com.thoughtworks.acceptance.objects; + + +public class Replaced extends StandardObject { + String replacedValue; + + public Replaced() { + } + + public Replaced(String replacedValue) { + this.replacedValue = replacedValue; + } + + private Object readResolve() { + return new Original(replacedValue.toLowerCase()); + } +} \ No newline at end of file diff --git a/xstream/src/test/com/thoughtworks/acceptance/objects/SampleDynamicProxy.java b/xstream/src/test/com/thoughtworks/acceptance/objects/SampleDynamicProxy.java new file mode 100644 index 0000000..0652292 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/objects/SampleDynamicProxy.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2010 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 25. April 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance.objects; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +public class SampleDynamicProxy implements InvocationHandler { + + private Object aField; + private transient boolean recursion; + + private SampleDynamicProxy(Object value) { + aField = value; + } + + public static interface InterfaceOne { + Object doSomething(); + } + + public static interface InterfaceTwo { + Object doSomething(); + } + + public static Object newInstance() { + return newInstance("hello"); + } + + public static Object newInstance(Object value) { + return Proxy.newProxyInstance(InterfaceOne.class.getClassLoader(), + new Class[]{InterfaceOne.class, InterfaceTwo.class}, + new SampleDynamicProxy(value)); + } + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + if (method.getName().equals("equals")) { + return (recursion || equals(args[0])) ? Boolean.TRUE : Boolean.FALSE; + } else if (method.getName().equals("hashCode")) { + return new Integer(System.identityHashCode(proxy)); + } else { + return aField; + } + } + + public boolean equals(Object obj) { + try { + recursion = true; + return equalsInterfaceOne(obj) && equalsInterfaceTwo(obj); + } finally { + recursion = false; + } + } + + private boolean equalsInterfaceOne(Object o) { + if (o instanceof InterfaceOne) { + InterfaceOne interfaceOne = (InterfaceOne) o; + return aField.equals(interfaceOne.doSomething()); + } else { + return false; + } + } + + private boolean equalsInterfaceTwo(Object o) { + if (o instanceof InterfaceTwo) { + InterfaceTwo interfaceTwo = (InterfaceTwo) o; + return aField.equals(interfaceTwo.doSomething()); + } else { + return false; + } + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/objects/SampleLists.java b/xstream/src/test/com/thoughtworks/acceptance/objects/SampleLists.java new file mode 100644 index 0000000..0553627 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/objects/SampleLists.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2003 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.acceptance.objects; + + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class SampleLists extends StandardObject { + public List good = new ArrayList(); + public Collection bad = new ArrayList(); + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/objects/SampleMaps.java b/xstream/src/test/com/thoughtworks/acceptance/objects/SampleMaps.java new file mode 100644 index 0000000..33cba03 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/objects/SampleMaps.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 05. August 2011 by Joerg Schaible + */ +package com.thoughtworks.acceptance.objects; + +import java.util.HashMap; +import java.util.Map; + + +public class SampleMaps extends StandardObject { + public Map good = new HashMap(); + public Map bad = new HashMap(); +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/objects/Software.java b/xstream/src/test/com/thoughtworks/acceptance/objects/Software.java new file mode 100644 index 0000000..1066012 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/objects/Software.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2003, 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.acceptance.objects; + + +public class Software extends StandardObject { + + public String vendor; + public String name; + + public Software() { + } + + public Software(String vendor, String name) { + this.vendor = vendor; + this.name = name; + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/objects/SomethingExternalizable.java b/xstream/src/test/com/thoughtworks/acceptance/objects/SomethingExternalizable.java new file mode 100644 index 0000000..ba1490c --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/objects/SomethingExternalizable.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2010, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 05. July 2011 by Joerg Schaible, factored out of ExternalizableTest. + */ +package com.thoughtworks.acceptance.objects; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; + + +public class SomethingExternalizable extends StandardObject implements Externalizable { + + private String first; + private String last; + private String nothing = null; + private String constant = "XStream"; + + public SomethingExternalizable() { + } + + public SomethingExternalizable(String first, String last) { + this.first = first; + this.last = last; + } + + public void writeExternal(ObjectOutput out) throws IOException { + out.writeInt(first.length()); + out.writeObject(first + last); + out.writeObject(nothing); + out.writeObject(constant); + } + + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + int offset = in.readInt(); + String full = (String) in.readObject(); + first = full.substring(0, offset); + last = full.substring(offset); + nothing = (String) in.readObject(); + constant = (String) in.readObject(); + } +} \ No newline at end of file diff --git a/xstream/src/test/com/thoughtworks/acceptance/objects/StandardObject.java b/xstream/src/test/com/thoughtworks/acceptance/objects/StandardObject.java new file mode 100644 index 0000000..f75270b --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/objects/StandardObject.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2003, 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 25. October 2003 by Joe Walnes + */ +package com.thoughtworks.acceptance.objects; + +import org.apache.commons.lang.builder.CompareToBuilder; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import java.io.Serializable; + +public class StandardObject implements Serializable, Comparable { + public boolean equals(Object obj) { + return EqualsBuilder.reflectionEquals(this, obj); + } + + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } + + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + public int compareTo(Object obj) { + return CompareToBuilder.reflectionCompare(this, obj); + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/objects/StatusEnum.java b/xstream/src/test/com/thoughtworks/acceptance/objects/StatusEnum.java new file mode 100644 index 0000000..1daa701 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/objects/StatusEnum.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. May 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance.objects; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class StatusEnum implements Serializable, Comparable { + + private static int nextOrdinal = 0; + private int ordinal = nextOrdinal++; + + public static final StatusEnum STARTED = new StatusEnum("STARTED"); + + public static final StatusEnum FINISHED = new StatusEnum("FINISHED"); + + private static final StatusEnum[] PRIVATE_VALUES = {STARTED, FINISHED}; + + public static final List VALUES = Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES)); + + private String name; // for debug only + + private StatusEnum() { + } + + private StatusEnum(String name) { + this.name = name; + } + + public String toString() { + return name; + } + + public int compareTo(Object o) { + return ordinal - ((StatusEnum) o).ordinal; + } + + private Object readResolve() { + return PRIVATE_VALUES[ordinal]; //Canonicalize + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/someobjects/FunnyConstructor.java b/xstream/src/test/com/thoughtworks/acceptance/someobjects/FunnyConstructor.java new file mode 100644 index 0000000..2f5dcf9 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/someobjects/FunnyConstructor.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance.someobjects; + +import com.thoughtworks.acceptance.objects.StandardObject; + +public class FunnyConstructor extends StandardObject { + public int i; + + public FunnyConstructor(int i) { + this.i = i; + } + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/someobjects/Handler.java b/xstream/src/test/com/thoughtworks/acceptance/someobjects/Handler.java new file mode 100644 index 0000000..a7654d6 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/someobjects/Handler.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance.someobjects; + +/** + * + * + * @author Jason van Zyl + * + * @version $Id: Handler.java 2034 2013-03-12 22:15:00Z joehni $ + */ +public class Handler +{ + private Protocol protocol; + + public Handler(Protocol p) { + protocol = p; + } + + public Protocol getProtocol() + { + return protocol; + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/someobjects/HandlerManager.java b/xstream/src/test/com/thoughtworks/acceptance/someobjects/HandlerManager.java new file mode 100644 index 0000000..3896a74 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/someobjects/HandlerManager.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance.someobjects; + +import java.util.List; + +/** + * + * + * @author Jason van Zyl + * + * @version $Id: HandlerManager.java 1345 2007-12-11 01:50:12Z joehni $ + */ +public class HandlerManager +{ + List handlers; + + public List getHandlers() + { + return handlers; + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/someobjects/Protocol.java b/xstream/src/test/com/thoughtworks/acceptance/someobjects/Protocol.java new file mode 100644 index 0000000..1ece4f8 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/someobjects/Protocol.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance.someobjects; + +/** + * + * + * @author Jason van Zyl + * + * @version $Id: Protocol.java 2034 2013-03-12 22:15:00Z joehni $ + */ +public class Protocol +{ + private String id; + + public Protocol(String id) { + this.id = id; + } + + public String getId() + { + return id; + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/someobjects/U.java b/xstream/src/test/com/thoughtworks/acceptance/someobjects/U.java new file mode 100644 index 0000000..6d3e26c --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/someobjects/U.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. October 2005 by Mauro Talevi + */ +package com.thoughtworks.acceptance.someobjects; + +import com.thoughtworks.acceptance.objects.StandardObject; + +public class U extends StandardObject { + public String aStr; + public String a_Str; + public U() { + } + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/someobjects/WithList.java b/xstream/src/test/com/thoughtworks/acceptance/someobjects/WithList.java new file mode 100644 index 0000000..11faee6 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/someobjects/WithList.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance.someobjects; + +import com.thoughtworks.acceptance.objects.StandardObject; + +import java.util.ArrayList; +import java.util.List; + +public class WithList extends StandardObject { + + public List things = new ArrayList(); + +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/someobjects/WithNamedList.java b/xstream/src/test/com/thoughtworks/acceptance/someobjects/WithNamedList.java new file mode 100644 index 0000000..d864c96 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/someobjects/WithNamedList.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. March 2006 by Joerg Schaible + */ +package com.thoughtworks.acceptance.someobjects; + + +public class WithNamedList extends WithList { + private String name; + + public WithNamedList(final String name) { + this.name = name; + } + + public String getName() { + return name; + } +} \ No newline at end of file diff --git a/xstream/src/test/com/thoughtworks/acceptance/someobjects/X.java b/xstream/src/test/com/thoughtworks/acceptance/someobjects/X.java new file mode 100644 index 0000000..e4efd13 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/someobjects/X.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance.someobjects; + +import com.thoughtworks.acceptance.objects.StandardObject; + +public class X extends StandardObject { + public String aStr; + public int anInt; + public Y innerObj; + + public X() { + } + + public X(int anInt) { + this.anInt = anInt; + } +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/someobjects/Y.java b/xstream/src/test/com/thoughtworks/acceptance/someobjects/Y.java new file mode 100644 index 0000000..4d76a96 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/someobjects/Y.java @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.acceptance.someobjects; + +import com.thoughtworks.acceptance.objects.StandardObject; + +public class Y extends StandardObject { + public String yField; +} diff --git a/xstream/src/test/com/thoughtworks/acceptance/someobjects/Z.java b/xstream/src/test/com/thoughtworks/acceptance/someobjects/Z.java new file mode 100644 index 0000000..57e03b2 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/acceptance/someobjects/Z.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 19. December 2004 by Mauro Talevi + */ +package com.thoughtworks.acceptance.someobjects; + +import com.thoughtworks.acceptance.objects.StandardObject; + +public class Z extends StandardObject { + public String field; + + public Z(String z){ + this.field = z; + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/XStreamTest.java b/xstream/src/test/com/thoughtworks/xstream/XStreamTest.java new file mode 100644 index 0000000..c6adf05 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/XStreamTest.java @@ -0,0 +1,429 @@ +/* + * Copyright (C) 2003, 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2011, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. September 2003 by Joe Walnes + */ +package com.thoughtworks.xstream; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.acceptance.someobjects.FunnyConstructor; +import com.thoughtworks.acceptance.someobjects.Handler; +import com.thoughtworks.acceptance.someobjects.HandlerManager; +import com.thoughtworks.acceptance.someobjects.Protocol; +import com.thoughtworks.acceptance.someobjects.U; +import com.thoughtworks.acceptance.someobjects.WithList; +import com.thoughtworks.acceptance.someobjects.X; +import com.thoughtworks.acceptance.someobjects.Y; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.xml.AbstractDocumentReader; +import com.thoughtworks.xstream.io.xml.Dom4JDriver; +import com.thoughtworks.xstream.security.NoTypePermission; + +import junit.framework.TestCase; + +import org.dom4j.Element; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; + +public class XStreamTest extends TestCase { + + private transient XStream xstream; + + protected void setUp() throws Exception { + super.setUp(); + xstream = new XStream(); + xstream.addPermission(NoTypePermission.NONE); // clear out defaults + xstream.allowTypesByWildcard(new String[]{ + AbstractAcceptanceTest.class.getPackage().getName()+".*objects.**", + this.getClass().getName()+"$*" + }); + xstream.alias("x", X.class); + xstream.alias("y", Y.class); + xstream.alias("funny", FunnyConstructor.class); + xstream.alias("with-list", WithList.class); + } + + public void testUnmarshalsObjectFromXmlWithUnderscores() { + String xml = + "" + + " foo" + + " _foo" + + ""; + + xstream.alias("u-u", U.class); + xstream.aliasField("u-f", U.class, "aStr"); + xstream.aliasField("u_f", U.class, "a_Str"); + U u = (U) xstream.fromXML(xml); + + assertEquals("foo", u.aStr); + assertEquals("_foo", u.a_Str); + } + + public void testUnmarshalsObjectFromXmlWithClassContainingUnderscores() { + String xml = + "" + + " custom value" + + ""; + + U_U u = (U_U) xstream.fromXML(xml); + + assertEquals("custom value", u.aStr); + } + + + public void testUnmarshalsObjectFromXmlWithUnderscoresWithoutAliasingFields() { + String xml = + "" + + " custom value" + + ""; + + xstream.alias("u-u", U.class); + + U u = (U) xstream.fromXML(xml); + + assertEquals("custom value", u.a_Str); + } + + public static class U_U { + String aStr; + } + + public void testUnmarshalsObjectFromXml() { + + String xml = + "" + + " joe" + + " 8" + + " " + + " walnes" + + " " + + ""; + + X x = (X) xstream.fromXML(xml); + + assertEquals("joe", x.aStr); + assertEquals(8, x.anInt); + assertEquals("walnes", x.innerObj.yField); + } + + public void testMarshalsObjectToXml() { + X x = new X(); + x.anInt = 9; + x.aStr = "zzz"; + x.innerObj = new Y(); + x.innerObj.yField = "ooo"; + + String expected = + "\n" + + " zzz\n" + + " 9\n" + + " \n" + + " ooo\n" + + " \n" + + ""; + + assertEquals(xstream.fromXML(expected), x); + } + + public void testUnmarshalsClassWithoutDefaultConstructor() { + if (!JVM.is14()) return; + + String xml = + "" + + " 999" + + ""; + + FunnyConstructor funnyConstructor = (FunnyConstructor) xstream.fromXML(xml); + + assertEquals(999, funnyConstructor.i); + } + + public void testHandlesLists() { + WithList original = new WithList(); + Y y = new Y(); + y.yField = "a"; + original.things.add(y); + original.things.add(new X(3)); + original.things.add(new X(1)); + + String xml = xstream.toXML(original); + + String expected = + "\n" + + " \n" + + " \n" + + " a\n" + + " \n" + + " \n" + + " 3\n" + + " \n" + + " \n" + + " 1\n" + + " \n" + + " \n" + + ""; + + assertEquals(expected, xml); + + WithList result = (WithList) xstream.fromXML(xml); + assertEquals(original, result); + + } + + public void testCanHandleNonStaticPrivateInnerClass() { + if (!JVM.is14()) return; + + NonStaticInnerClass obj = new NonStaticInnerClass(); + obj.field = 3; + + xstream.alias("inner", NonStaticInnerClass.class); + + String xml = xstream.toXML(obj); + + String expected = "" + + "\n" + + " 3\n" + + " \n" + + " testCanHandleNonStaticPrivateInnerClass\n" + + " \n" + + ""; + + assertEquals(xstream.fromXML(expected), obj); + + NonStaticInnerClass result = (NonStaticInnerClass) xstream.fromXML(xml); + assertEquals(obj.field, result.field); + } + + public void testClassWithoutMappingUsesFullyQualifiedName() { + Person obj = new Person(); + + String xml = xstream.toXML(obj); + + String expected = ""; + + assertEquals(expected, xml); + + Person result = (Person) xstream.fromXML(xml); + assertEquals(obj, result); + } + + private class NonStaticInnerClass extends StandardObject { + int field; + } + + public void testCanBeBeUsedMultipleTimesWithSameInstance() { + Y obj = new Y(); + obj.yField = "x"; + + assertEquals(xstream.toXML(obj), xstream.toXML(obj)); + } + + public void testAccessToUnderlyingDom4JImplementation() + throws Exception { + + String xml = + "" + + " jason" + + " van Zyl" + + " " + + " bar" + + " " + + ""; + + xstream.registerConverter(new ElementConverter()); + xstream.alias("person", Person.class); + + Dom4JDriver driver = new Dom4JDriver(); + Person person = (Person) xstream.unmarshal(driver.createReader(new StringReader(xml))); + + assertEquals("jason", person.firstName); + assertEquals("van Zyl", person.lastName); + assertNotNull(person.element); + assertEquals("bar", person.element.element("foo").getText()); + } + + public static class Person extends StandardObject { + String firstName; + String lastName; + Element element; + } + + private class ElementConverter implements Converter { + + public boolean canConvert(Class type) { + return Element.class.isAssignableFrom(type); + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + + AbstractDocumentReader documentReader = (AbstractDocumentReader)reader.underlyingReader(); + Element element = (Element) documentReader.getCurrent(); + + while (reader.hasMoreChildren()) { + reader.moveDown(); + reader.moveUp(); + } + + return element; + } + } + + public void testPopulationOfAnObjectGraphStartingWithALiveRootObject() + throws Exception { + + String xml = + "" + + " host" + + " 8000" + + ""; + + xstream.alias("component", Component.class); + + Component component0 = new Component(); + Component component1 = (Component) xstream.fromXML(xml, component0); + assertSame(component0, component1); + assertEquals("host", component0.host); + assertEquals(8000, component0.port); + } + + static class Component { + String host; + int port; + } + + public void testPopulationOfThisAsRootObject() + throws Exception { + + String xml ="" + + "\n" + + " host\n" + + " 8000\n" + + ""; + + xstream.alias("component", SelfSerializingComponent.class); + SelfSerializingComponent component = new SelfSerializingComponent(); + component.host = "host"; + component.port = 8000; + assertEquals(xml, component.toXML(xstream)); + component.host = "foo"; + component.port = -1; + component.fromXML(xstream, xml); + assertEquals("host", component.host); + assertEquals(8000, component.port); + } + + static class SelfSerializingComponent extends Component { + String toXML(XStream xstream) { + return xstream.toXML(this); + } + void fromXML(XStream xstream, String xml) { + xstream.fromXML(xml, this); + } + } + + public void testUnmarshalsWhenAllImplementationsAreSpecifiedUsingAClassIdentifier() + throws Exception { + + String xml = + "" + + " " + + " " + + " " + + " foo " + + " " + + " " + + " " + + ""; + + HandlerManager hm = (HandlerManager) xstream.fromXML(xml); + Handler h = (Handler) hm.getHandlers().get(0); + Protocol p = h.getProtocol(); + assertEquals("foo", p.getId()); + } + + public void testObjectOutputStreamCloseTwice() throws IOException { + ObjectOutputStream oout = xstream.createObjectOutputStream(new StringWriter()); + oout.writeObject(new Integer(1)); + oout.close(); + oout.close(); + } + + public void testObjectOutputStreamCloseAndFlush() throws IOException { + ObjectOutputStream oout = xstream.createObjectOutputStream(new StringWriter()); + oout.writeObject(new Integer(1)); + oout.close(); + try { + oout.flush(); + fail("Closing and flushing should throw a StreamException"); + } catch (StreamException e) { + // ok + } + } + + public void testObjectOutputStreamCloseAndWrite() throws IOException { + ObjectOutputStream oout = xstream.createObjectOutputStream(new StringWriter()); + oout.writeObject(new Integer(1)); + oout.close(); + try { + oout.writeObject(new Integer(2)); + fail("Closing and writing should throw a StreamException"); + } catch (StreamException e) { + // ok + } + } + + public void testUnmarshalsFromFile() throws IOException { + File file = createTestFile(); + xstream.registerConverter(new ElementConverter()); + xstream.alias("component", Component.class); + Component person = (Component)xstream.fromXML(file); + assertEquals(8000, person.port); + } + + public void testUnmarshalsFromURL() throws IOException { + File file = createTestFile(); + xstream.alias("component", Component.class); + Component person = (Component)xstream.fromXML(file); + assertEquals(8000, person.port); + } + + private File createTestFile() + throws FileNotFoundException, IOException, UnsupportedEncodingException { + String xml ="" + + "\n" + + " host\n" + + " 8000\n" + + ""; + + File dir = new File("target/test-data"); + dir.mkdirs(); + File file = new File(dir, "test.xml"); + FileOutputStream fos = new FileOutputStream(file); + fos.write(xml.getBytes("UTF-8")); + fos.close(); + return file; + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/ConversionExceptionTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/ConversionExceptionTest.java new file mode 100644 index 0000000..2536b8a --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/ConversionExceptionTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. November 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters; + +import com.thoughtworks.xstream.mapper.CannotResolveClassException; + +import junit.framework.TestCase; + +import java.util.StringTokenizer; + +/** + * @author Jörg Schaible + */ +public class ConversionExceptionTest extends TestCase { + + public void testDebugMessageIsNotNested() { + Exception ex = new CannotResolveClassException("JUnit"); + ConversionException innerEx = new ConversionException("Inner", ex); + ConversionException outerEx = new ConversionException("Outer", innerEx); + StringTokenizer tokenizer = new StringTokenizer(outerEx.getMessage(), "\n\r"); + int ends = 0; + while(tokenizer.hasMoreTokens()) { + if (tokenizer.nextToken().startsWith("---- Debugging information ----")) { + ++ends; + } + } + assertEquals(1, ends); + } + + public void testInfoRetainsOrder() { + ConversionException ex = new ConversionException("Message"); + ex.add("1st", "first"); + ex.add("2nd", "second"); + ex.add("3rd", "third"); + StringTokenizer tokenizer = new StringTokenizer(ex.getMessage(), "\n\r"); + tokenizer.nextToken(); + tokenizer.nextToken(); + assertEquals("1st : first", tokenizer.nextToken()); + assertEquals("2nd : second", tokenizer.nextToken()); + assertEquals("3rd : third", tokenizer.nextToken()); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/basic/DateConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/basic/DateConverterTest.java new file mode 100644 index 0000000..16f9fb9 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/basic/DateConverterTest.java @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2012, 2014, 2015 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. February 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.basic; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.testutil.TimeZoneChanger; + +import junit.framework.TestCase; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; + + +public class DateConverterTest extends TestCase { + + private DateConverter converter = new DateConverter(); + + protected void setUp() throws Exception { + super.setUp(); + + // Ensure that this test always run as if it were in the IST timezone. + // This prevents failures when running the tests in different zones. + // Note: 'IST' has no relevance - it was just a randomly chosen zone + // without daylight saving. + TimeZoneChanger.change("IST"); + } + + protected void tearDown() throws Exception { + TimeZoneChanger.reset(); + super.tearDown(); + } + + public void testRetainsDetailDownToMillisecondLevel() { + // setup + Date in = new Date(); + + // execute + String text = converter.toString(in); + Date out = (Date)converter.fromString(text); + + // verify + assertEquals(in, out); + assertEquals(in.toString(), out.toString()); + assertEquals(in.getTime(), out.getTime()); + } + + public void testUnmarshalsOldXStreamDatesThatLackMillisecond() { + converter = new DateConverter((TimeZone)null); // use default TZ + Date expected = (Date)converter.fromString("2004-02-22 15:16:04.0 EST"); + + assertEquals(expected, converter.fromString("2004-02-22 15:16:04.0 EST")); + assertEquals(expected, converter.fromString("2004-02-22 15:16:04 EST")); + assertEquals(expected, converter.fromString("2004-02-22 15:16:04EST")); + + TimeZone.setDefault(TimeZone.getTimeZone("EST")); // Need correct local time, no TZ info in string + assertEquals(expected, converter.fromString("2004-02-22 15:16:04.0 PM")); + assertEquals(expected, converter.fromString("2004-02-22 15:16:04PM")); + } + + public void testUnmarshalsDatesWithDifferentTimeZones() { + converter = new DateConverter(true); // Needed by JDK 5 running on Codehaus' Bamboo installation + Date expected = (Date)converter.fromString("2004-02-22 15:16:04.0 EST"); + + assertEquals(expected, converter.fromString("2004-02-22 15:16:04.0 EST")); + assertEquals(expected, converter.fromString("2004-02-22 15:16:04.0 GMT-05:00")); + assertEquals(expected, converter.fromString("2004-02-22 20:16:04.0 UTC")); + assertEquals(expected, converter.fromString("2004-02-23 01:46:04.0 IST")); + assertEquals(expected, converter.fromString("2004-02-23 01:46:04.0 GMT+05:30")); + + if (JVM.canParseISO8601TimeZoneInDateFormat()) { + // W3C subset of ISO 8601 date time representations + assertEquals(expected, converter.fromString("2004-02-22T15:16:04-05:00")); + assertEquals(expected, converter.fromString("2004-02-22T20:16:04Z")); + assertEquals(expected, converter.fromString("2004-02-22T20:16:04.0Z")); + expected.setTime(expected.getTime()-4000); + assertEquals(expected, converter.fromString("2004-02-22T15:16-05:00")); + } + } + + public void testUnmarshalsDateWithDifferentDefaultTimeZones() throws ParseException { + converter = new DateConverter((TimeZone)null); // use default TZ + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.set(2004, Calendar.FEBRUARY, 23, 1, 46, 4); + Date date = cal.getTime(); + String strIST = converter.toString(date); + assertEquals("2004-02-23 01:46:04.0 IST", strIST); + // select arbitrary TZ + TimeZone.setDefault(TimeZone.getTimeZone("EST")); + // compare parsed date with JDK implementation + Date dateRetrieved = (Date)converter.fromString(strIST); + SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S z"); + Date simpleDate = f.parse(strIST); + assertEquals(simpleDate, dateRetrieved); + // DateConverter does not get influenced by change of current TZ ... + TimeZone.setDefault(TimeZone.getTimeZone("Europe/Berlin")); + dateRetrieved = (Date)converter.fromString(strIST); + assertEquals(simpleDate, dateRetrieved); + // ... as well as the SimpleDateFormat + f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S z"); + simpleDate = f.parse(strIST); + assertEquals(simpleDate, dateRetrieved); + assertEquals(date, f.parse("2004-02-22 20:16:04.0 UTC")); + // 'date' was created for IST time zone, so let parser return in IST + f.setTimeZone(TimeZone.getTimeZone("IST")); + simpleDate = f.parse(strIST); + assertEquals(date, simpleDate); + assertEquals(date, f.parse("2004-02-22 20:16:04.0 UTC")); + } + + public void testIsThreadSafe() throws InterruptedException { + final List results = Collections.synchronizedList(new ArrayList()); + final DateConverter converter = new DateConverter(); + final Object monitor = new Object(); + final int numberOfCallsPerThread = 20; + final int numberOfThreads = 20; + + // spawn some concurrent threads, that hammer the converter + Runnable runnable = new Runnable() { + public void run() { + for (int i = 0; i < numberOfCallsPerThread; i++) { + try { + converter.fromString("2004-02-22 15:16:04.0 EST"); + results.add("PASS"); + } catch (ConversionException e) { + results.add("FAIL"); + } finally { + synchronized (monitor) { + monitor.notifyAll(); + } + } + } + } + }; + for (int i = 0; i < numberOfThreads; i++) { + new Thread(runnable).start(); + } + + // wait for all results + while (results.size() < numberOfThreads * numberOfCallsPerThread) { + synchronized (monitor) { + monitor.wait(100); + } + } + + assertTrue("Nothing suceeded", results.contains("PASS")); + assertFalse("At least one attempt failed", results.contains("FAIL")); + } + + public void testDatesInNonLenientMode() { + String[] dateFormats = new String[] { "yyyyMMdd", "yyyy-MM-dd'T'HH:mm:ss'Z'", "yyyy-MM-dd" }; + converter = new DateConverter("yyyy-MM-dd'T'HH:mm:ss.S'Z'", dateFormats); + Date expected = (Date)converter.fromString("2004-02-22T15:16:04.0Z"); + assertEquals(expected, converter.fromString("2004-02-22T15:16:04Z")); + } + + public void testDatesInLenientMode() { + converter = new DateConverter("yyyy-MM-dd HH:mm:ss.S z", new String[0], true); + Date expected = (Date)converter.fromString("2004-02-22 15:16:04.0 IST"); + assertEquals(expected, converter.fromString("2004-02-21 39:16:04.0 IST")); + } + + public void testDatesIn70sInTimeZoneGMT() throws ParseException { + converter = new DateConverter((TimeZone)null); // use default TZ + + final String pattern = "yyyy-MM-dd HH:mm:ss.S z"; + final SimpleDateFormat format; + + format = new SimpleDateFormat(pattern, Locale.UK); + format.setTimeZone(TimeZone.getTimeZone("GMT")); + + final String[] expected = new String[]{ + "1970-01-01 11:20:34.0 GMT", + "1971-01-01 11:20:34.0 GMT", + "1972-01-01 11:20:34.0 GMT", + "1973-01-01 11:20:34.0 GMT", + "1974-01-01 11:20:34.0 GMT", + }; + + final String[] actual = new String[expected.length]; + for (int i = 0; i < actual.length; i++ ) { + final String converted = converter.toString(format.parseObject(expected[i])); + // Note, XStream's string representation of the date is in IST + actual[i] = format.format(converter.fromString(converted)); + } + + assertEquals(Arrays.asList(expected).toString(), Arrays.asList(actual).toString()); + } + + public void testDatesWithAmbiguous3LetterTimeZones() { + TimeZone.setDefault(TimeZone.getTimeZone("Australia/Brisbane")); // EST also used e.g. for America/Toronto + Date expected = new Date(0); + assertEquals(expected, converter.fromString(converter.toString(expected))); + } + + public void testDatesWithEpoche() { + Calendar cal = Calendar.getInstance(); + cal.setTimeZone(TimeZone.getTimeZone("UTC")); + assertEquals(GregorianCalendar.AD, cal.get(Calendar.ERA)); + cal.clear(); + cal.set(1, Calendar.JANUARY, 1); + cal.add(Calendar.MILLISECOND, -1); + Date date = cal.getTime(); + assertEquals("0001-12-31 BC 23:59:59.999 UTC", converter.toString(date)); + assertEquals(date, converter.fromString("0001-12-31 BC 23:59:59.999 UTC")); + cal.add(Calendar.MILLISECOND, 1); + assertEquals(cal.getTime(), converter.fromString("0001-01-01 AD 00:00:00.000 UTC")); + } + + public void testDatesWithEnglishLocaleOfDefault() { + converter = new DateConverter(null, "EEEE, dd MMMM yyyy z", + null, Locale.ENGLISH, TimeZone.getTimeZone("UTC"), false); + Calendar cal = Calendar.getInstance(); + cal.setTimeZone(TimeZone.getTimeZone("UTC")); + cal.clear(); + cal.set(2000, Calendar.JANUARY, 1); + Date date = cal.getTime(); + assertEquals("Saturday, 01 January 2000 UTC", converter.toString(date)); + assertEquals(date, converter.fromString("Saturday, 01 January 2000 UTC")); + } + + public void testDatesWithGermanLocale() { + converter = new DateConverter(null, "EEEE, dd MMMM yyyy z", + null, Locale.GERMAN, TimeZone.getTimeZone("UTC"), false); + Calendar cal = Calendar.getInstance(); + cal.setTimeZone(TimeZone.getTimeZone("UTC")); + cal.clear(); + cal.set(2000, Calendar.JANUARY, 1); + Date date = cal.getTime(); + assertEquals("Samstag, 01 Januar 2000 UTC", converter.toString(date)); + assertEquals(date, converter.fromString("Samstag, 01 Januar 2000 UTC")); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/basic/URIConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/basic/URIConverterTest.java new file mode 100644 index 0000000..1001d46 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/basic/URIConverterTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2010 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 3. August 2010 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.basic; + +import java.net.URI; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.DomDriver; + +/** + * @author Carlos Roman + */ +public class URIConverterTest extends AbstractAcceptanceTest { + + private static final String TEST_URI_STRING = "rtmp://cp12345.edgefcs.net/od/public/file.flv"; + private static URI TEST_URI; + + public URIConverterTest() { + } + + public void setUp() throws Exception{ + xstream = new XStream(new DomDriver("UTF-8")); + xstream.registerConverter(new URIConverter()); + TEST_URI = new URI(TEST_URI_STRING); + assertNotNull(xstream); + assertNotNull(TEST_URI); + } + + /** + * Test of canConvert method, of class URIConverter. + */ + public void testCanConvert() { + final Class type = URI.class; + final URIConverter instance = new URIConverter(); + final boolean expResult = true; + final boolean result = instance.canConvert(type); + assertEquals(expResult, result); + } + + /** + * Test of fromString method, of class URIConverter. + */ + public void testFromString() throws Exception{ + final URIConverter instance = new URIConverter(); + final Object expResult = new URI(TEST_URI_STRING); + final Object result = instance.fromString(TEST_URI_STRING); + assertEquals(expResult, result); + } +} \ No newline at end of file diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/basic/URLConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/basic/URLConverterTest.java new file mode 100644 index 0000000..7dc6e5d --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/basic/URLConverterTest.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 25. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.basic; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; + +import java.net.MalformedURLException; +import java.net.URL; + +public class URLConverterTest extends AbstractAcceptanceTest { + + public void testConvertsToSingleString() throws MalformedURLException { + + assertBothWays( + new URL("http://www.apple.com:2020/path/blah.html?abc#2"), + "http://www.apple.com:2020/path/blah.html?abc#2"); + + assertBothWays( + new URL("file:/c:/winnt/blah.txt"), + "file:/c:/winnt/blah.txt"); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/collections/BitSetConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/collections/BitSetConverterTest.java new file mode 100644 index 0000000..64110e0 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/collections/BitSetConverterTest.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.collections; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; + +import java.util.BitSet; + +public class BitSetConverterTest extends AbstractAcceptanceTest { + + public void testConvertsToSingleCommaDelimitedString() { + BitSet bitSet = new BitSet(); + bitSet.set(0); + bitSet.set(1); + bitSet.set(3); + bitSet.set(5); + bitSet.set(6); + bitSet.set(8); + bitSet.set(10); + + String expected = "0,1,3,5,6,8,10"; + + assertBothWays(bitSet, expected); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/collections/ByteArrayConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/collections/ByteArrayConverterTest.java new file mode 100644 index 0000000..e7b7872 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/collections/ByteArrayConverterTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 25. April 2004 by James Strachan + */ +package com.thoughtworks.xstream.converters.collections; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; + +public class ByteArrayConverterTest extends AbstractAcceptanceTest { + + + public void testMarshallByteArrays() { + Dummy input = new Dummy(new byte[0]); + + String expected = "\n \n"; + assertBothWays(input, expected); + } + + public static class Dummy { + byte[] data; + + private Dummy() { + } + + public Dummy(byte[] data) { + this.data = data; + } + + public byte[] getData() { + return data; + } + + public boolean equals(Object that) { + if (that instanceof Dummy) { + return equals((Dummy) that); + } + return false; + } + + public boolean equals(Dummy that) { + if (this.data == that.data) { + return true; + } + if (this.data != null && that.data != null) { + if (this.data.length == that.data.length) { + for (int i = 0; i < data.length; i++) { + byte b1 = data[i]; + byte b2 = that.data[i]; + if (b1 != b2) { + return false; + } + } + return true; + } + } + return false; + + } + } + + protected void setUp() throws Exception { + super.setUp(); + xstream.alias("dummy", Dummy.class); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/collections/CharArrayConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/collections/CharArrayConverterTest.java new file mode 100644 index 0000000..41fd681 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/collections/CharArrayConverterTest.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.collections; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; + +public class CharArrayConverterTest extends AbstractAcceptanceTest { + + public void testMarshallsCharArrayAsSingleString() { + char[] input = new char[] {'h','e','l','l','o'}; + + String expected = "hello"; + assertBothWays(input, expected); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/collections/PropertiesConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/collections/PropertiesConverterTest.java new file mode 100644 index 0000000..b9e7718 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/collections/PropertiesConverterTest.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 23. February 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.collections; + +import com.thoughtworks.xstream.XStream; + +import junit.framework.TestCase; + +import java.util.Properties; + +public class PropertiesConverterTest extends TestCase { + + public void testConvertsPropertiesObjectToShortKeyValueElements() { + Properties in = new Properties(); + in.setProperty("hello", "world"); + in.setProperty("foo", "cheese"); + + String expectedXML = "" + + "\n" + + " \n" + + " \n" + + ""; + XStream xstream = new XStream(); + String actualXML = xstream.toXML(in); + assertEquals(expectedXML, actualXML); + + Properties expectedOut = new Properties(); + expectedOut.setProperty("hello", "world"); + expectedOut.setProperty("foo", "cheese"); + Properties actualOut = (Properties) xstream.fromXML(actualXML); + assertEquals(in, actualOut); + assertEquals(in.toString(), actualOut.toString()); + + } + + public void testIncludesDefaultProperties() { + Properties defaults = new Properties(); + defaults.setProperty("host", "localhost"); + defaults.setProperty("port", "80"); + + Properties override = new Properties(defaults); + override.setProperty("port", "999"); + + // sanity check + assertEquals("Unexpected overriden property", "999", override.getProperty("port")); + assertEquals("Unexpected default property", "localhost", override.getProperty("host")); + + String expectedXML = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + XStream xstream = new XStream(); + String actualXML = xstream.toXML(override); + assertEquals(expectedXML, actualXML); + + Properties out = (Properties) xstream.fromXML(actualXML); + assertEquals("Unexpected overriden property", "999", out.getProperty("port")); + assertEquals("Unexpected default property", "localhost", out.getProperty("host")); + assertEquals(override, out); + } + + public void testCanSortElements() { + Properties defaults = new Properties(); + defaults.setProperty("host", "localhost"); + defaults.setProperty("port", "80"); + + Properties override = new Properties(defaults); + override.setProperty("port", "999"); + override.setProperty("domain", "codehaus.org"); + + String expectedXML = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + XStream xstream = new XStream(); + xstream.registerConverter(new PropertiesConverter(true)); + String actualXML = xstream.toXML(override); + assertEquals(expectedXML, actualXML); + + Properties out = (Properties) xstream.fromXML(actualXML); + assertEquals("Unexpected overriden property", "999", out.getProperty("port")); + assertEquals("Unexpected default property", "localhost", out.getProperty("host")); + assertEquals(override, out); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/enums/BigEnum.java b/xstream/src/test/com/thoughtworks/xstream/converters/enums/BigEnum.java new file mode 100644 index 0000000..b529a7d --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/enums/BigEnum.java @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.enums; + +enum BigEnum { + A1, B1, C1, D1, E1, F1, G1, H1, I1, J1, K1, L1, M1, N1, O1, P1, Q1, R1, S1, T1, U1, V1, W1, X1, Y1, Z1, + A2, B2, C2, D2, E2, F2, G2, H2, I2, J2, K2, L2, M2, N2, O2, P2, Q2, R2, S2, T2, U2, V2, W2, X2, Y2, Z2, + A3, B3, C3, D3, E3, F3, G3, H3, I3, J3, K3, L3, M3, N3, O3, P3, Q3, R3, S3, T3, U3, V3, W3, X3, Y3, Z3; +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumConverterTest.java new file mode 100644 index 0000000..43463fc --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumConverterTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 18. March 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.enums; + +import com.thoughtworks.xstream.XStream; +import junit.framework.TestCase; + +// ***** READ THIS ***** +// This class will only compile with JDK 1.5.0 or above as it test Java enums. +// If you are using an earlier version of Java, just don't try to build this class. XStream should work fine without it. + +/** + * @author Joe Walnes + * @author Bryan Coleman + */ +public class EnumConverterTest extends TestCase { + + private XStream xstream; + + protected void setUp() throws Exception { + super.setUp(); + xstream = new XStream(); + xstream.alias("simple", SimpleEnum.class); + xstream.alias("polymorphic", PolymorphicEnum.class); + } + + public void testRepresentsEnumAsSingleStringValue() { + String expectedXml = "GREEN"; + SimpleEnum in = SimpleEnum.GREEN; + assertEquals(expectedXml, xstream.toXML(in)); + assertEquals(in, xstream.fromXML(expectedXml)); + } + + public void testRepresentsPolymorphicEnumAsSingleStringValue() { + String expectedXml = "B"; + PolymorphicEnum in = PolymorphicEnum.B; + assertEquals(expectedXml, xstream.toXML(in)); + assertEquals(in, xstream.fromXML(expectedXml)); + } + + public void testDeserializedEnumIsTheSameNotJustEqual() { + assertSame(SimpleEnum.GREEN, xstream.fromXML(xstream.toXML(SimpleEnum.GREEN))); + assertSame(PolymorphicEnum.B, xstream.fromXML(xstream.toXML(PolymorphicEnum.B))); + } + + public void testResolvesSpecializedPolymorphicEnum() { + PolymorphicEnum in; + PolymorphicEnum out; + + in = PolymorphicEnum.A; + out = (PolymorphicEnum) xstream.fromXML(xstream.toXML(in)); + assertEquals("apple", ((Fruit)out).fruit()); // see Bug ID: 6522780 + + in = PolymorphicEnum.B; + out = (PolymorphicEnum) xstream.fromXML(xstream.toXML(in)); + assertEquals("banana", ((Fruit)out).fruit()); // see Bug ID: 6522780 + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumCustomConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumCustomConverterTest.java new file mode 100644 index 0000000..05221a0 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumCustomConverterTest.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 08. October 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.enums; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.enums.EnumMapperTest.TypeWithEnums; + +import junit.framework.TestCase; + + +// ***** READ THIS ***** +// This class will only compile with JDK 1.5.0 or above as it test Java enums. +// If you are using an earlier version of Java, just don't try to build this class. XStream should work fine without it. + +/** + * @author Jörg Schaible + */ +public class EnumCustomConverterTest extends TestCase { + + private XStream xstream; + + protected void setUp() throws Exception { + super.setUp(); + xstream = new XStream(); + xstream.alias("simple", SimpleEnum.class); + xstream.alias("polymorphic", PolymorphicEnum.class); + } + + public void testCanBeUsedDirectly() { + xstream.registerConverter(new PolymorphicEnumConverter(PolymorphicEnum.class)); + String expectedXml = "b"; + PolymorphicEnum in = PolymorphicEnum.B; + assertEquals(expectedXml, xstream.toXML(in)); + assertEquals(in, xstream.fromXML(expectedXml)); + } + + public void testCanBeUsedForMember() { + xstream.registerConverter(new PolymorphicEnumConverter(PolymorphicEnum.class)); + xstream.alias("type", TypeWithEnums.class); + xstream.autodetectAnnotations(true); + String expectedXml = "" // force format + + "\n" + + " b\n" + + " C3\n" + + ""; + TypeWithEnums in = new TypeWithEnums(); + in.poly = PolymorphicEnum.B; + in.simple = SimpleEnum.GREEN; + in.big = BigEnum.C3; + assertEquals(expectedXml, xstream.toXML(in)); + TypeWithEnums out = (TypeWithEnums)xstream.fromXML(expectedXml); + assertSame(out.poly, PolymorphicEnum.B); + assertSame(out.simple, SimpleEnum.GREEN); + } + + public void testCanBeUsedForAttribute() { + xstream.registerConverter(new PolymorphicEnumConverter(PolymorphicEnum.class)); + xstream.alias("type", TypeWithEnums.class); + xstream.useAttributeFor(PolymorphicEnum.class); + xstream.autodetectAnnotations(true); + String expectedXml = "" // force format + + "\n" + + " C3\n" + + ""; + TypeWithEnums in = new TypeWithEnums(); + in.poly = PolymorphicEnum.B; + in.simple = SimpleEnum.GREEN; + in.big = BigEnum.C3; + assertEquals(expectedXml, xstream.toXML(in)); + TypeWithEnums out = (TypeWithEnums)xstream.fromXML(expectedXml); + assertSame(out.poly, PolymorphicEnum.B); + assertSame(out.simple, SimpleEnum.GREEN); + } + + public void testCanBeUsedLocallyForAttribute() { + xstream.registerLocalConverter( + TypeWithEnums.class, "poly", new PolymorphicEnumConverter(PolymorphicEnum.class)); + xstream.alias("type", TypeWithEnums.class); + xstream.useAttributeFor(PolymorphicEnum.class); + xstream.autodetectAnnotations(true); + String expectedXml = "" // force format + + "\n" + + " C3\n" + + ""; + TypeWithEnums in = new TypeWithEnums(); + in.poly = PolymorphicEnum.B; + in.simple = SimpleEnum.GREEN; + in.big = BigEnum.C3; + assertEquals(expectedXml, xstream.toXML(in)); + TypeWithEnums out = (TypeWithEnums)xstream.fromXML(expectedXml); + assertSame(out.poly, PolymorphicEnum.B); + assertSame(out.simple, SimpleEnum.GREEN); + } + + private final static class PolymorphicEnumConverter extends EnumSingleValueConverter { + private PolymorphicEnumConverter(Class type) { + super(type); + } + + @Override + public Object fromString(String str) { + return super.fromString(str.toUpperCase()); + } + + @Override + public String toString(Object obj) { + return super.toString(obj).toLowerCase(); + } + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumMapConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumMapConverterTest.java new file mode 100644 index 0000000..b27b251 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumMapConverterTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.enums; + +import com.thoughtworks.xstream.XStream; + +import junit.framework.TestCase; + +import java.util.EnumMap; + +public class EnumMapConverterTest extends TestCase { + + private XStream xstream; + + protected void setUp() throws Exception { + super.setUp(); + xstream = new XStream(); + } + + public void testIncludesEnumTypeInSerializedForm() { + xstream.alias("simple", SimpleEnum.class); + EnumMap map = new EnumMap(SimpleEnum.class); + map.put(SimpleEnum.BLUE, "sky"); + map.put(SimpleEnum.GREEN, "grass"); + + String expectedXml = "" + + "\n" + + " \n" + + " GREEN\n" + + " grass\n" + + " \n" + + " \n" + + " BLUE\n" + + " sky\n" + + " \n" + + ""; + + assertEquals(expectedXml, xstream.toXML(map)); + assertEquals(map, xstream.fromXML(expectedXml)); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumMapperTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumMapperTest.java new file mode 100644 index 0000000..a9a8b6b --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumMapperTest.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 12. February 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.enums; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.annotations.XStreamAsAttribute; + +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.List; + + +// ***** READ THIS ***** +// This class will only compile with JDK 1.5.0 or above as it test Java enums. +// If you are using an earlier version of Java, just don't try to build this class. XStream +// should work fine without it. + +/** + * @author Jörg Schaible + */ +public class EnumMapperTest extends TestCase { + + private XStream xstream; + + protected void setUp() throws Exception { + super.setUp(); + xstream = new XStream(); + xstream.alias("simple", SimpleEnum.class); + xstream.alias("polymorphic", PolymorphicEnum.class); + } + + static class Bowl { + Fruit fruit; + } + + public void testSupportsDefaultImplementationToBeAnEnum() { + xstream.alias("bowl", Bowl.class); + xstream.addDefaultImplementation(PolymorphicEnum.class, Fruit.class); + String expectedXml = "" // force format + + "\n" + + " B\n" + + ""; + Bowl in = new Bowl(); + in.fruit = PolymorphicEnum.B; + assertEquals(expectedXml, xstream.toXML(in)); + Bowl out = (Bowl)xstream.fromXML(expectedXml); + assertSame(out.fruit, PolymorphicEnum.B); + } + + static class TypeWithEnums { + PolymorphicEnum poly; + @XStreamAsAttribute + SimpleEnum simple; + BigEnum big; + } + + public void testSupportsEnumAsAttribute() { + xstream.alias("type", TypeWithEnums.class); + xstream.useAttributeFor(PolymorphicEnum.class); + xstream.autodetectAnnotations(true); + String expectedXml = "" // force format + + "\n" + + " C3\n" + + ""; + TypeWithEnums in = new TypeWithEnums(); + in.poly = PolymorphicEnum.B; + in.simple = SimpleEnum.GREEN; + in.big = BigEnum.C3; + assertEquals(expectedXml, xstream.toXML(in)); + TypeWithEnums out = (TypeWithEnums)xstream.fromXML(expectedXml); + assertSame(out.poly, PolymorphicEnum.B); + assertSame(out.simple, SimpleEnum.GREEN); + } + + public void testEnumsAreImmutable() { + List in = new ArrayList(); + in.add(SimpleEnum.GREEN); + in.add(SimpleEnum.GREEN); + in.add(PolymorphicEnum.A); + in.add(PolymorphicEnum.A); + String expectedXml = "" + + "\n" + + " GREEN\n" + + " GREEN\n" + + " A\n" + + " A\n" + + ""; + assertEquals(expectedXml, xstream.toXML(in)); + assertEquals(in, xstream.fromXML(expectedXml)); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumSetConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumSetConverterTest.java new file mode 100644 index 0000000..e5cf8d3 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumSetConverterTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.enums; + +import com.thoughtworks.xstream.XStream; +import junit.framework.TestCase; + +import java.util.EnumSet; + +public class EnumSetConverterTest extends TestCase { + + private XStream xstream; + + protected void setUp() throws Exception { + super.setUp(); + xstream = new XStream(); + } + + public void testPutsEnumsInCompactCommaSeparatedString() { + xstream.alias("simple", SimpleEnum.class); + EnumSet set = EnumSet.of(SimpleEnum.GREEN, SimpleEnum.BLUE); + + String expectedXml = "GREEN,BLUE"; + + assertEquals(expectedXml, xstream.toXML(set)); + assertEquals(set, xstream.fromXML(expectedXml)); + } + + public void testSupportsJumboEnumSetsForMoreThan64Elements() { + xstream.alias("big", BigEnum.class); + EnumSet jumboSet = EnumSet.allOf(BigEnum.class); + + String expectedXml = "" + + "A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1," + + "A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2,N2,O2,P2,Q2,R2,S2,T2,U2,V2,W2,X2,Y2,Z2," + + "A3,B3,C3,D3,E3,F3,G3,H3,I3,J3,K3,L3,M3,N3,O3,P3,Q3,R3,S3,T3,U3,V3,W3,X3,Y3,Z3" + + ""; + + assertEquals(expectedXml, xstream.toXML(jumboSet)); + assertEquals(jumboSet, xstream.fromXML(expectedXml)); + } + + public void testSupportsPolymorphicEnums() { + xstream.alias("poly", PolymorphicEnum.class); + EnumSet set = EnumSet.allOf(PolymorphicEnum.class); + + String expectedXml = "A,B,C"; + + assertEquals(expectedXml, xstream.toXML(set)); + assertEquals(set, xstream.fromXML(expectedXml)); + } + + public void testEmptyEnumSet() { + xstream.alias("simple", SimpleEnum.class); + EnumSet set = EnumSet.noneOf(SimpleEnum.class); + + String expectedXml = ""; + + assertEquals(expectedXml, xstream.toXML(set)); + assertEquals(set, xstream.fromXML(expectedXml)); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumToStringConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumToStringConverterTest.java new file mode 100644 index 0000000..32dfdea --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/enums/EnumToStringConverterTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 14. March 2013 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.enums; + +import java.util.HashMap; +import java.util.Map; + +import com.thoughtworks.xstream.XStream; +import junit.framework.TestCase; + + +// ***** READ THIS ***** +// This class will only compile with JDK 1.5.0 or above as it test Java enums. +// If you are using an earlier version of Java, just don't try to build this class. XStream should work fine without it. + +/** + * @author Jörg Schaible + */ +public class EnumToStringConverterTest extends TestCase { + + private XStream xstream; + + protected void setUp() throws Exception { + super.setUp(); + xstream = new XStream(); + xstream.alias("simple", SimpleEnum.class); + xstream.alias("big", BigEnum.class); + xstream.alias("polymorphic", PolymorphicEnum.class); + + Map map = new HashMap(); + map.put("0xff0000", SimpleEnum.RED); + map.put("0x00ff00", SimpleEnum.GREEN); + map.put("0x0000ff", SimpleEnum.BLUE); + xstream.registerConverter(new EnumToStringConverter(SimpleEnum.class, map)); + xstream.registerConverter(new EnumToStringConverter(BigEnum.class)); + xstream.registerConverter(new EnumToStringConverter( + PolymorphicEnum.class)); + } + + public void testMapsEnumToProvidedStringValue() { + String expectedXml = "0x00ff00"; + SimpleEnum in = SimpleEnum.GREEN; + assertEquals(expectedXml, xstream.toXML(in)); + assertEquals(in, xstream.fromXML(expectedXml)); + } + + public void testMapsEnumToStringDefaultValue() { + String expectedXml = "C3"; + BigEnum in = BigEnum.C3; + assertEquals(expectedXml, xstream.toXML(in)); + assertEquals(in, xstream.fromXML(expectedXml)); + } + + public void testMapsToPolymorphicStringValue() { + String expectedXml = "banana"; + PolymorphicEnum in = PolymorphicEnum.B; + assertEquals(expectedXml, xstream.toXML(in)); + assertEquals(in, xstream.fromXML(expectedXml)); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/enums/Fruit.java b/xstream/src/test/com/thoughtworks/xstream/converters/enums/Fruit.java new file mode 100644 index 0000000..2d4de0b --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/enums/Fruit.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 11. February 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.enums; + +/** + * A fruit used as base for the polymorphic enum. + * + * @author Jörg Schaible + */ +public interface Fruit { + + String fruit(); +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/enums/PolymorphicEnum.java b/xstream/src/test/com/thoughtworks/xstream/converters/enums/PolymorphicEnum.java new file mode 100644 index 0000000..a0a910d --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/enums/PolymorphicEnum.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.enums; + +enum PolymorphicEnum implements Fruit { + A() { + public String fruit() { + return "apple"; + } + }, + B() { + public String fruit() { + return "banana"; + } + }, + C; + + public String fruit() { + return "unknown"; + } + + @Override + public String toString() { + return fruit(); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/enums/SimpleEnum.java b/xstream/src/test/com/thoughtworks/xstream/converters/enums/SimpleEnum.java new file mode 100644 index 0000000..2b691d1 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/enums/SimpleEnum.java @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.enums; + +enum SimpleEnum { + RED, GREEN, BLUE; +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/extended/CharsetConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/extended/CharsetConverterTest.java new file mode 100644 index 0000000..87b1134 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/extended/CharsetConverterTest.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 28. July 2006 by Guilerme Silveira + */ +package com.thoughtworks.xstream.converters.extended; + +import java.nio.charset.Charset; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; + +public class CharsetConverterTest extends AbstractAcceptanceTest { + + public void testHandlesSimpleCharset() { + assertBothWays(Charset.forName("US-ASCII"), "US-ASCII"); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/extended/DurationConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/extended/DurationConverterTest.java new file mode 100644 index 0000000..583a305 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/extended/DurationConverterTest.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 21. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.SingleValueConverter; + +import junit.framework.TestCase; + +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.Duration; + + +/** + * @author John Kristian + */ +public class DurationConverterTest extends TestCase { + private static final String[] STRINGS = {"-P1Y2M3DT4H5M6.7S", "P1Y", "PT1H2M"}; + + public void testConversion() throws Exception { + final SingleValueConverter converter = new DurationConverter(); + DatatypeFactory factory = DatatypeFactory.newInstance(); + for (int i = 0; i < STRINGS.length; i++) { + final String s = STRINGS[i]; + Duration o = factory.newDuration(s); + assertEquals(s, converter.toString(o)); + assertEquals(o, converter.fromString(s)); + } + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/extended/EncodedByteArrayConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/extended/EncodedByteArrayConverterTest.java new file mode 100644 index 0000000..6bcb2cd --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/extended/EncodedByteArrayConverterTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.acceptance.objects.StandardObject; + +public class EncodedByteArrayConverterTest extends AbstractAcceptanceTest { + + public void testMarshallsCharArrayAsSingleString() { + byte[] input = {0, 120, -124, 22, 33, 0, 5}; + String expected = "AHiEFiEABQ=="; + + assertBothWays(input, expected); + } + + public void testUnmarshallsOldByteArraysThatHaveNotBeenEncoding() { + // for backwards compatability + String input = "" + + "\n" + + " 0\n" + + " 120\n" + + " -124\n" + + " 22\n" + + " 33\n" + + " 0\n" + + " 5\n" + + ""; + + byte[] expected = {0, 120, -124, 22, 33, 0, 5}; + assertByteArrayEquals(expected, (byte[])xstream.fromXML(input)); + } + + public void testUnmarshallsEmptyByteArrays() { + byte[] input = {}; + String expected = ""; + + assertBothWays(input, expected); + } + + public static class TestObject extends StandardObject { + private byte[] data; + private boolean something; + } + + public void testUnmarshallsEmptyByteArrayAsFieldOfAnotherObject() { + // exposes a weird bug that was in the XML pull readers. + TestObject in = new TestObject(); + in.data = new byte[0]; + + xstream.alias("TestObject", TestObject.class); + String expectedXml = "" + + "\n" + + " \n" + + " false\n" + + ""; + assertBothWays(in, expectedXml); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/extended/FontConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/extended/FontConverterTest.java new file mode 100644 index 0000000..fac9ebf --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/extended/FontConverterTest.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 08. July 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; +import com.thoughtworks.xstream.core.JVM; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import java.awt.Font; +import java.awt.Toolkit; +import java.awt.font.TextAttribute; +import java.util.Map; + +public class FontConverterTest extends TestCase { + private XStream xstream; + private Font in; + + public static Test suite() { + // Only try to run this test case if graphics environment is available + try { + new Font("Arial", Font.BOLD, 20); + return new TestSuite(FontConverterTest.class); + } catch (Throwable t) { + return new TestSuite(); + } + } + + protected void setUp() throws Exception { + super.setUp(); + // fonts should be serializable also with pure Java + xstream = new XStream(new PureJavaReflectionProvider()); + in = new Font("Arial", Font.BOLD, 20); + } + + public void testConvertsToFontThatEqualsOriginal() { + // execute + Font out = (Font) xstream.fromXML(xstream.toXML(in)); + + // assert + assertEquals(in, out); + } + + public void testProducesFontThatHasTheSameAttributes() { + // execute + Font out = (Font) xstream.fromXML(xstream.toXML(in)); + + // assert + Map inAttributes = in.getAttributes(); + Map outAttributes = out.getAttributes(); + + // these attributes don't have a valid .equals() method (bad Sun!), so we can't use them in the test. + if (!JVM.is16()) { // it seems even old 1.5 JDKs fail here (Codehaus Bamboo) + inAttributes.remove(TextAttribute.TRANSFORM); + outAttributes.remove(TextAttribute.TRANSFORM); + } + + assertEquals(inAttributes, outAttributes); + } + + public void testUnmarshalsCurrentFormat() { + // XML representation since 1.4.5 + String xml= ("" + + "\n" + + " \n" + + " 2.0\n" + + " \n" + + " \n" + + " 20.0\n" + + " \n" + + " Arial\n" + + "").replace('\'', '"'); + Font out = (Font) xstream.fromXML(xml); + + // assert + assertEquals(in, out); + } + + public void testUnmarshalsOldFormat() { + // XML representation pre 1.4.5 + String xml = "" + + "\n" + + " \n" + + " \n" + + " posture\n" + + " \n" + + " \n" + + " \n" + + " weight\n" + + " 2.0\n" + + " \n" + + " \n" + + " superscript\n" + + " \n" + + " \n" + + " \n" + + " transform\n" + + " \n" + + " \n" + + " \n" + + " size\n" + + " 20.0\n" + + " \n" + + " \n" + + " width\n" + + " \n" + + " \n" + + " \n" + + " family\n" + + " Arial\n" + + " \n" + + " \n" + + ""; + Font out = (Font) xstream.fromXML(xml); + + // assert + assertEquals(in, out); + } + + public void testCorrectlyInitializesFontToPreventJvmCrash() { + // If a font has not been constructed in the correct way, the JVM crashes horribly through some internal + // native code, whenever the font is rendered to screen. + + // execute + Font out = (Font) xstream.fromXML(xstream.toXML(in)); + + Toolkit.getDefaultToolkit().getFontMetrics(out); + // if the JVM hasn't crashed yet, we're good. + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/extended/GregorianCalendarConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/extended/GregorianCalendarConverterTest.java new file mode 100644 index 0000000..a1a64f0 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/extended/GregorianCalendarConverterTest.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 14. May 2005 by Mauro Talevi + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.XStream; + +import junit.framework.TestCase; + +import java.util.Calendar; +import java.util.TimeZone; + +/** + * @author Jörg Schaible + */ +public class GregorianCalendarConverterTest extends TestCase { + + public void testCalendar() { + final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + final XStream xstream = new XStream(); + final String xml = xstream.toXML(cal); + final Calendar serialized = (Calendar)xstream.fromXML(xml); + assertEquals(cal, serialized); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/extended/ISO8601DateConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/extended/ISO8601DateConverterTest.java new file mode 100644 index 0000000..bb659f8 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/extended/ISO8601DateConverterTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. November 2004 by Mauro Talevi + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.testutil.TimeZoneChanger; + +import junit.framework.TestCase; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +public class ISO8601DateConverterTest extends TestCase { + + private ISO8601DateConverter converter; + + protected void setUp() throws Exception { + super.setUp(); + converter = new ISO8601DateConverter(); + + // Ensure that this test always run as if it were in the EST timezone. + // This prevents failures when running the tests in different zones. + // Note: 'EST' has no relevance - it was just a randomly chosen zone. + TimeZoneChanger.change("EST"); + } + + protected void tearDown() throws Exception { + TimeZoneChanger.reset(); + super.tearDown(); + } + + public void testUnmashallsInCorrectTimeZone() { + // setup + Date in = new Date(); + + // execute + String text = converter.toString(in); + Date out = (Date) converter.fromString(text); + + // verify + assertEquals(in, out); + assertEquals(in.toString(), out.toString()); + assertEquals(in.getTime(), out.getTime()); + } + + public void testUnmarshallsISOFormatInUTC() throws ParseException { + // setup + String isoFormat = "1993-02-14T13:10:30-05:00"; + String simpleFormat = "1993-02-14 13:10:30EST"; + // execute + Date out = (Date) converter.fromString(isoFormat); + Date control = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(simpleFormat); + // verify for EST + assertEquals("Sun Feb 14 13:10:30 EST 1993", out.toString()); + assertEquals(control, out); + } + + public void testUnmarshallsISOFormatInLocalTime() { + // setup + String isoFormat = "1993-02-14T13:10:30"; + // execute + Date out = (Date) converter.fromString(isoFormat); + // verify for EST + Calendar calendar = Calendar.getInstance(); + calendar.set(1993, 1, 14, 13, 10, 30); + assertEquals(calendar.getTime().toString(), out.toString()); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverter17Test.java b/xstream/src/test/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverter17Test.java new file mode 100644 index 0000000..348fbd0 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverter17Test.java @@ -0,0 +1,55 @@ +/* + * 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 21. June 2013 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.testutil.TimeZoneChanger; + +import junit.framework.TestCase; + +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.Locale; + +public class ISO8601GregorianCalendarConverter17Test extends TestCase { + + protected void setUp() throws Exception { + super.setUp(); + + // Ensure that this test always run as if it were in the timezone of Panama. + // This prevents failures when running the tests in different zones. + // Note: 'America/Panama' has no relevance - it was just a randomly chosen zone. + TimeZoneChanger.change("America/Panama"); + } + + protected void tearDown() throws Exception { + TimeZoneChanger.reset(); + super.tearDown(); + } + + public void testCanLoadTimeWithDefaultDifferentLocaleForFormat() { + final ISO8601GregorianCalendarConverter converter = new ISO8601GregorianCalendarConverter(); + + Locale defaultLocale = Locale.getDefault(); + Locale defaultLocaleForFormat = Locale.getDefault(Locale.Category.FORMAT); + try { + Locale.setDefault(Locale.US); + Locale.setDefault(Locale.Category.FORMAT, Locale.GERMANY); + Calendar in = new GregorianCalendar(2013, Calendar.JUNE, 17, 16, 0, 0); + + String converterXML = converter.toString(in); + Calendar out = (Calendar) converter.fromString(converterXML); + assertEquals(in, out); + } finally { + Locale.setDefault(defaultLocale); + Locale.setDefault(defaultLocaleForFormat); + } + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverterTest.java new file mode 100644 index 0000000..255f627 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverterTest.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. October 2005 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.testutil.TimeZoneChanger; + +import junit.framework.TestCase; + +import org.joda.time.DateTime; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.List; +import java.util.TimeZone; + +public class ISO8601GregorianCalendarConverterTest extends TestCase { + + private ISO8601GregorianCalendarConverter converter; + + protected void setUp() throws Exception { + super.setUp(); + converter = new ISO8601GregorianCalendarConverter(); + + // Ensure that this test always run as if it were in the timezone of Panama. + // This prevents failures when running the tests in different zones. + // Note: 'America/Panama' has no relevance - it was just a randomly chosen zone. + TimeZoneChanger.change("America/Panama"); + } + + protected void tearDown() throws Exception { + TimeZoneChanger.reset(); + super.tearDown(); + } + + public void testRetainsDetailDownToMillisecondLevel() { + // setup + Calendar in = Calendar.getInstance(); + + // execute + String text = converter.toString(in); + Calendar out = (Calendar) converter.fromString(text); + + // verify + assertEquals(in, out); + } + + public void testSavedTimeIsInUTC() { + Calendar in = Calendar.getInstance(); + final String iso8601; + iso8601 = new DateTime(in).toString(); + String converterXML = converter.toString(in); + assertEquals(iso8601, converterXML); + + Calendar out = (Calendar) converter.fromString(converterXML); + assertEquals(in, out); + } + + public void testCanLoadTimeInDifferentTimeZone() { + Calendar in = Calendar.getInstance(); + String converterXML = converter.toString(in); + + TimeZone.setDefault(TimeZone.getTimeZone("Europe/Moscow")); + Calendar timeInMoscow = Calendar.getInstance(); + timeInMoscow.setTime(in.getTime()); + Calendar out = (Calendar) converter.fromString(converterXML); + assertEquals(timeInMoscow, out); + } + + public void testCalendarWithExplicitTimeZone() { + Calendar timeInMoscow = Calendar.getInstance(); + timeInMoscow.set(2010, 6, 3, 10, 20, 36); + timeInMoscow.setTimeZone(TimeZone.getTimeZone("Europe/Moscow")); + + String converterXML = converter.toString(timeInMoscow); + Calendar out = (Calendar) converter.fromString(converterXML); + assertEquals(timeInMoscow.getTimeInMillis(), out.getTimeInMillis()); + + out.setTimeZone(TimeZone.getTimeZone("Europe/Moscow")); + assertEquals(timeInMoscow, out); + } + + public void testIsThreadSafe() throws InterruptedException { + final List results = Collections.synchronizedList(new ArrayList()); + final ISO8601GregorianCalendarConverter converter = new ISO8601GregorianCalendarConverter(); + final Object monitor = new Object(); + final int numberOfCallsPerThread = 20; + final int numberOfThreads = 20; + + // spawn some concurrent threads, that hammer the converter + Runnable runnable = new Runnable() { + public void run() { + for (int i = 0; i < numberOfCallsPerThread; i++) { + try { + converter.fromString("1993-02-14T13:10:30"); + results.add("PASS"); + } catch (ConversionException e) { + results.add("FAIL"); + } finally { + synchronized (monitor) { + monitor.notifyAll(); + } + } + } + } + }; + for (int i = 0; i < numberOfThreads; i++) { + new Thread(runnable).start(); + } + + // wait for all results + while (results.size() < numberOfThreads * numberOfCallsPerThread) { + synchronized (monitor) { + monitor.wait(100); + } + } + + assertTrue("Nothing succeded", results.contains("PASS")); + assertFalse("At least one attempt failed", results.contains("FAIL")); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/extended/ISO8601SqlTimestampConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/extended/ISO8601SqlTimestampConverterTest.java new file mode 100644 index 0000000..80ef203 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/extended/ISO8601SqlTimestampConverterTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. October 2005 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.testutil.TimeZoneChanger; + +import junit.framework.TestCase; + +import java.sql.Timestamp; + + +/** + * @author Chung-Onn Cheong + * @author Jörg Schaible + */ +public class ISO8601SqlTimestampConverterTest extends TestCase { + private ISO8601SqlTimestampConverter converter; + + protected void setUp() throws Exception { + super.setUp(); + converter = new ISO8601SqlTimestampConverter(); + + // Ensure that this test always run as if it were in the EST timezone. + // This prevents failures when running the tests in different zones. + // Note: 'EST' has no relevance - it was just a randomly chosen zone. + TimeZoneChanger.change("EST"); + } + + protected void tearDown() throws Exception { + TimeZoneChanger.reset(); + super.tearDown(); + } + + public void testISO8601SqlTimestamp() { + XStream xs = new XStream(); + xs.registerConverter(converter); + + long currentTime = System.currentTimeMillis(); + + Timestamp ts1 = new Timestamp(currentTime); + String xmlString = xs.toXML(ts1); + + Timestamp ts2 = (Timestamp)xs.fromXML(xmlString); + + assertEquals("ISO Timestamp Converted is not the same ", ts1, ts2); + assertEquals( + "Current time not equal to converted timestamp", currentTime, + (ts2.getTime() / 1000) * 1000 + ts2.getNanos() / 1000000); + } + + public void testISO8601SqlTimestampWith1Milli() { + XStream xs = new XStream(); + xs.registerConverter(converter); + + long currentTime = (System.currentTimeMillis() / 1000 * 1000) + 1; + + Timestamp ts1 = new Timestamp(currentTime); + String xmlString = xs.toXML(ts1); + + Timestamp ts2 = (Timestamp)xs.fromXML(xmlString); + + assertEquals("ISO Timestamp Converted is not the same ", ts1, ts2); + assertEquals( + "Current time not equal to converted timestamp", currentTime, + (ts2.getTime() / 1000) * 1000 + ts2.getNanos() / 1000000); + } + + public void testISO8601SqlTimestampWithNanos() { + XStream xs = new XStream(); + xs.registerConverter(converter); + + Timestamp ts1 = new Timestamp(System.currentTimeMillis()); + ts1.setNanos(987654321); + String xmlString = xs.toXML(ts1); + + Timestamp ts2 = (Timestamp)xs.fromXML(xmlString); + + assertEquals("ISO Timestamp Converted is not the same ", ts1, ts2); + assertEquals("Nanos are not equal", ts1.getNanos(), ts2.getNanos()); + } + + public void testTimestampWithoutFraction() { + String isoFormat = "1993-02-14T13:10:30-05:00"; + Timestamp out = (Timestamp)converter.fromString(isoFormat); + assertEquals("1993-02-14T13:10:30.000000000-05:00", converter.toString(out)); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/extended/JavaClassConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/extended/JavaClassConverterTest.java new file mode 100644 index 0000000..c660e85 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/extended/JavaClassConverterTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 16. February 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; + +public class JavaClassConverterTest extends AbstractAcceptanceTest { + + public void testHandlesPrimitivesAndWrappers() { + assertBothWays(int.class, "int"); + assertBothWays(Integer.class, "java.lang.Integer"); + + assertBothWays(boolean.class, "boolean"); + assertBothWays(Boolean.class, "java.lang.Boolean"); + + assertBothWays(void.class, "void"); + assertBothWays(Void.class, "java.lang.Void"); + } + + public static class A {} + + public void testHandlesArrays() { + assertBothWays(A[].class, + "[Lcom.thoughtworks.xstream.converters.extended.JavaClassConverterTest$A;"); + assertBothWays(int[].class, + "[I"); + } + + public void testHandlesMultidimensioanlArrays() { + assertBothWays(A[][].class, + "[[Lcom.thoughtworks.xstream.converters.extended.JavaClassConverterTest$A;"); + assertBothWays(A[][][][].class, + "[[[[Lcom.thoughtworks.xstream.converters.extended.JavaClassConverterTest$A;"); + + assertBothWays(int[][].class, + "[[I"); + assertBothWays(int[][][][].class, + "[[[[I"); + } + + public static class B {} + + public void testResolvesUnloadedClassThatIsAnArray() { + // subtleties in classloaders make this an awkward one + String input = "[Lcom.thoughtworks.xstream.converters.extended.JavaClassConverterTest$B;"; + Class result = (Class) xstream.fromXML(input); + assertEquals("[Lcom.thoughtworks.xstream.converters.extended.JavaClassConverterTest$B;", result.getName()); + assertTrue("Should be an array", result.isArray()); + assertEquals("com.thoughtworks.xstream.converters.extended.JavaClassConverterTest$B", result.getComponentType().getName()); + } + + public void testHandlesJavaClassArray() { + xstream.registerConverter(new JavaClassConverter(xstream.getMapper()){}); + + Class[] classes = new Class[] { + Object.class, + Comparable.class, + null, + Throwable.class + }; + + assertBothWays(classes, "" + + "\n" + + " object\n" + + " java.lang.Comparable\n" + + " \n" + + " java.lang.Throwable\n" + + ""); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/extended/JavaMethodConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/extended/JavaMethodConverterTest.java new file mode 100644 index 0000000..e623372 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/extended/JavaMethodConverterTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 23. December 2004 by Mauro Talevi + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + +public class JavaMethodConverterTest extends AbstractAcceptanceTest { + + public void testSupportsPublicMethods() throws Exception { + Method method = AnIntClass.class.getDeclaredMethod("setValue", new Class[]{Integer.TYPE}); + String expected = + "\n" + + " com.thoughtworks.xstream.converters.extended.JavaMethodConverterTest$AnIntClass\n" + + " setValue\n" + + " \n" + + " int\n" + + " \n" + + ""; + assertBothWays(method, expected); + } + + public void testSupportsPrivateMethods() throws NoSuchMethodException { + Method method = AnIntClass.class.getDeclaredMethod("privateMethod", new Class[]{}); + String expected = + "\n" + + " com.thoughtworks.xstream.converters.extended.JavaMethodConverterTest$AnIntClass\n" + + " privateMethod\n" + + " \n" + + ""; + assertBothWays(method, expected); + } + + public void testSupportsConstructor() throws NoSuchMethodException { + Constructor constructor = AnIntClass.class.getDeclaredConstructor(new Class[] { int.class }); + String expected = + "\n" + + " com.thoughtworks.xstream.converters.extended.JavaMethodConverterTest$AnIntClass\n" + + " \n" + + " int\n" + + " \n" + + ""; + assertBothWays(constructor, expected); + } + + static class AnIntClass { + private int value = 0; + + protected AnIntClass(int integer) { + this.value = integer; + } + + public int getValue() { + return value; + } + + public void setValue(int integer) { + this.value = integer; + } + + private void privateMethod() { + } + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/extended/PropertyEditorCapableConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/extended/PropertyEditorCapableConverterTest.java new file mode 100644 index 0000000..d874ee6 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/extended/PropertyEditorCapableConverterTest.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 20. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.acceptance.objects.Software; +import com.thoughtworks.xstream.converters.SingleValueConverter; + +import junit.framework.TestCase; + +import java.beans.PropertyEditorSupport; +import java.util.HashMap; +import java.util.Map; + + +/** + * @author Jörg Schaible + */ +public class PropertyEditorCapableConverterTest extends TestCase { + + public static class SoftwarePropertyEditor extends PropertyEditorSupport { + + public String getAsText() { + Software software = (Software)getValue(); + return software.vendor + ":" + software.name; + } + + public void setAsText(String text) throws IllegalArgumentException { + int idx = text.indexOf(':'); + setValue(new Software(text.substring(0, idx), text.substring(idx + 1))); + } + + } + + public void testCanBeUsedForCustomTypes() { + Software software = new Software("Joe Walnes", "XStream"); + SingleValueConverter converter = new PropertyEditorCapableConverter( + SoftwarePropertyEditor.class, Software.class); + assertTrue(converter.canConvert(Software.class)); + assertEquals("Joe Walnes:XStream", converter.toString(software)); + assertEquals(software, converter.fromString("Joe Walnes:XStream")); + } + + public void testConcurrentConversion() throws InterruptedException { + final SingleValueConverter converter = new PropertyEditorCapableConverter( + SoftwarePropertyEditor.class, Software.class); + + final Map exceptions = new HashMap(); + final ThreadGroup tg = new ThreadGroup(getName()) { + public void uncaughtException(Thread t, Throwable e) { + exceptions.put(e, t.getName()); + super.uncaughtException(t, e); + } + }; + + final Map references = new HashMap(); + final int[] counter = new int[1]; + counter[0] = 0; + final Thread[] threads = new Thread[10]; + for (int i = 0; i < threads.length; ++i) { + final String name = "JUnit Thread:" + i; + references.put(name, new Software("JUnit Thread", Integer.toString(i))); + threads[i] = new Thread(tg, name) { + + public void run() { + int i = 0; + try { + synchronized (this) { + notifyAll(); + wait(); + } + final Software software = (Software)references.get(Thread + .currentThread() + .getName()); + while (i < 1000 && !interrupted()) { + String formatted = converter.toString(software); + Thread.yield(); + assertEquals(software, converter.fromString(formatted)); + ++i; + } + } catch (InterruptedException e) { + fail("Unexpected InterruptedException"); + } + synchronized (counter) { + counter[0] += i; + } + } + + }; + } + + for (int i = 0; i < threads.length; ++i) { + synchronized (threads[i]) { + threads[i].start(); + threads[i].wait(); + } + } + + for (int i = 0; i < threads.length; ++i) { + synchronized (threads[i]) { + threads[i].notifyAll(); + } + } + + Thread.sleep(1000); + + for (int i = 0; i < threads.length; ++i) { + threads[i].interrupt(); + } + for (int i = 0; i < threads.length; ++i) { + synchronized (threads[i]) { + threads[i].join(); + } + } + + assertEquals("Exceptions have been thrown: " + exceptions, 0, exceptions.size()); + assertTrue( + "Each thread should have made at least 1 conversion", counter[0] >= threads.length); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/extended/RegexPatternConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/extended/RegexPatternConverterTest.java new file mode 100644 index 0000000..58786ef --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/extended/RegexPatternConverterTest.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 28. July 2006 by Guilerme Silveira + */ +package com.thoughtworks.xstream.converters.extended; + +import java.util.regex.Pattern; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; + +public class RegexPatternConverterTest extends AbstractAcceptanceTest { + + public void testHandlesSimplePattern() { + Pattern root = Pattern.compile(".*"); + String xml = "\n" + + " .*\n" + " 0\n" + + ""; + assertBothWays(root, xml); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/extended/StackTraceElementConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/extended/StackTraceElementConverterTest.java new file mode 100644 index 0000000..b6c40b2 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/extended/StackTraceElementConverterTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. May 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; + +/** + * @author B. K. Oxley (binkley) + * @author Joe Walnes + */ +public class StackTraceElementConverterTest extends AbstractAcceptanceTest { + + private StackTraceElementFactory factory = new StackTraceElementFactory(); + + public void testSerializesStackTraceElement() { + StackTraceElement trace = factory.unknownSourceElement("com.blah.SomeClass", "someMethod"); + String expectedXml = "com.blah.SomeClass.someMethod(Unknown Source)"; + assertBothWays(trace, expectedXml); + } + + public void testIncludesDebugInformation() { + StackTraceElement trace = factory.element("com.blah.SomeClass", "someMethod", "SomeClass.java", 22); + String expectedXml = "com.blah.SomeClass.someMethod(SomeClass.java:22)"; + assertBothWays(trace, expectedXml); + } + + public void testIncludesPartialDebugInformation() { + StackTraceElement trace = factory.element("com.blah.SomeClass", "someMethod", "SomeClass.java"); + String expectedXml = "com.blah.SomeClass.someMethod(SomeClass.java)"; + assertBothWays(trace, expectedXml); + } + + public void testIncludesNativeMethods() { + StackTraceElement trace = factory.nativeMethodElement("com.blah.SomeClass", "someMethod"); + String expectedXml = "com.blah.SomeClass.someMethod(Native Method)"; + assertBothWays(trace, expectedXml); + } + + public void testSupportsInnerClasses() { + StackTraceElement trace = factory.unknownSourceElement("com.blah.SomeClass$Inner$2", "someMethod"); + String expectedXml = "com.blah.SomeClass$Inner$2.someMethod(Unknown Source)"; + assertBothWays(trace, expectedXml); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/extended/ThrowableConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/extended/ThrowableConverterTest.java new file mode 100644 index 0000000..caf297b --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/extended/ThrowableConverterTest.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. May 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.xstream.XStream; + +import java.math.BigDecimal; + +/** + * @author B. K. Oxley (binkley) + */ +public class ThrowableConverterTest extends AbstractAcceptanceTest { + + public void testDeserializesThrowable() { + Throwable expected = new Throwable(); + Throwable result = (Throwable) xstream.fromXML(xstream.toXML(expected)); + assertThrowableEquals(expected, result); + } + + public void testDeserializesException() { + Exception expected = new Exception(); + Throwable result = (Throwable) xstream.fromXML(xstream.toXML(expected)); + assertThrowableEquals(expected, result); + } + + public void testIncludesMessage() { + Throwable expected = new Throwable("A MESSAGE"); + Throwable result = (Throwable) xstream.fromXML(xstream.toXML(expected)); + assertThrowableEquals(expected, result); + } + + public void testIncludesCause() { + Throwable expected = new Throwable(new Throwable()); + Throwable result = (Throwable) xstream.fromXML(xstream.toXML(expected)); + assertThrowableEquals(expected, result); + } + + public void testIncludesCauseAndMessage() { + Throwable expected = new Throwable("MESSAGE", new Throwable("CAUSE MESSAGE")); + Throwable result = (Throwable) xstream.fromXML(xstream.toXML(expected)); + assertThrowableEquals(expected, result); + } + + public void testIncludesStackTrace() { + try { + throw new Exception(); + } catch (Exception exception) { + Throwable result = (Throwable) xstream.fromXML(xstream.toXML(exception)); + assertThrowableEquals(exception, result); + } + } + + public static class MyException extends Exception { + private BigDecimal number; + + public MyException(String msg, BigDecimal number) { + super(msg); + this.number = number; + } + + public boolean equals(Object o) { + return super.equals(o) && o instanceof MyException && number.equals(((MyException)o).number); + } + + } + + public void testSerializesExtraFields() { + try { + throw new MyException("A MESSAGE", new BigDecimal(123.4)); + } catch (MyException exception) { + Throwable result = (Throwable) xstream.fromXML(xstream.toXML(exception)); + assertThrowableEquals(exception, result); + } + } + + public void testSerializesWithNoSelfReferenceForUninitializedCauseInJdk14() { + xstream.setMode(XStream.NO_REFERENCES); + try { + throw new RuntimeException("Without cause"); + } catch (RuntimeException exception) { + Throwable result = (Throwable) xstream.fromXML(xstream.toXML(exception)); + assertThrowableEquals(exception, result); + assertNull(exception.getCause()); + assertNull(result.getCause()); + } + } + + public void testSerializesWithInitializedCauseInJdk14() { + xstream.setMode(XStream.NO_REFERENCES); + try { + throw new RuntimeException("Without cause", null); + } catch (RuntimeException exception) { + Throwable result = (Throwable) xstream.fromXML(xstream.toXML(exception)); + assertThrowableEquals(exception, result); + assertNull(exception.getCause()); + assertNull(result.getCause()); + } + } + + private static void assertThrowableEquals(final Throwable a, + final Throwable b) { + assertBoth(a, b, new MoreAssertions() { + public void assertMoreSafely(final Object a, + final Object b) { + final Throwable ta = (Throwable) a, tb = (Throwable) b; + assertEquals(ta.getClass(), tb.getClass()); + assertEquals(ta.getMessage(), tb.getMessage()); + assertThrowableEquals(ta.getCause(), tb.getCause()); + assertArrayEquals(ta.getStackTrace(), tb.getStackTrace()); + } + }); + } + + private static void assertArrayEquals(final Object[] expected, final Object[] actual) { + StringBuffer expectedJoined = new StringBuffer(); + StringBuffer actualJoined = new StringBuffer(); + for (int i = 0; i < expected.length; i++) { + expectedJoined.append(expected[i]).append('\n'); + } + for (int i = 0; i < actual.length; i++) { + // JRockit adds ":???" for invalid line number + actualJoined.append(actual[i].toString().replaceFirst(":\\?\\?\\?", "")).append('\n'); + } + assertEquals(expectedJoined.toString(), actualJoined.toString()); + } + + private static void assertBoth(Object a, Object b, MoreAssertions moreAssertions) { + if (null == a) { + if (null == b) { + return; + } else { + fail("Expected null, but was <" + b + ">"); + } + } else if (null == b) { + fail("Expected <" + a + "> but was null"); + } else { + moreAssertions.assertMoreSafely(a, b); + } + } + + private interface MoreAssertions { + void assertMoreSafely(final Object a, final Object b); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverterTest.java new file mode 100644 index 0000000..c7703ab --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverterTest.java @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2011, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. July 2011 by Joerg Schaible + */ + +package com.thoughtworks.xstream.converters.extended; + +import java.io.StringReader; +import java.io.StringWriter; + +import com.thoughtworks.acceptance.objects.OpenSourceSoftware; +import com.thoughtworks.acceptance.objects.Software; +import com.thoughtworks.acceptance.someobjects.X; +import com.thoughtworks.acceptance.someobjects.Y; +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.SingleValueConverterWrapper; +import com.thoughtworks.xstream.converters.basic.IntConverter; +import com.thoughtworks.xstream.converters.basic.StringConverter; +import com.thoughtworks.xstream.converters.collections.ArrayConverter; +import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; +import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; +import com.thoughtworks.xstream.converters.reflection.SunUnsafeReflectionProvider; +import com.thoughtworks.xstream.core.ClassLoaderReference; +import com.thoughtworks.xstream.core.DefaultConverterLookup; +import com.thoughtworks.xstream.core.TreeMarshaller; +import com.thoughtworks.xstream.core.TreeUnmarshaller; +import com.thoughtworks.xstream.io.HierarchicalStreamDriver; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.xml.CompactWriter; +import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.mapper.ArrayMapper; +import com.thoughtworks.xstream.mapper.ClassAliasingMapper; +import com.thoughtworks.xstream.mapper.DefaultImplementationsMapper; +import com.thoughtworks.xstream.mapper.DefaultMapper; +import com.thoughtworks.xstream.mapper.Mapper; + +import junit.framework.TestCase; + + +/** + * Tests {@link ToAttributedValueConverter}. + * + * @author jos / last modified by $Author: joehni $ + */ +public class ToAttributedValueConverterTest extends TestCase { + private HierarchicalStreamDriver driver; + private DefaultConverterLookup converterLookup; + private ReflectionProvider reflectionProvider; + private Mapper mapper; + + protected void setUp() throws Exception { + super.setUp(); + + final ClassAliasingMapper classAliasingMapper = new ClassAliasingMapper( + new DefaultMapper(new ClassLoaderReference(getClass().getClassLoader()))); + classAliasingMapper.addClassAlias("x", X.class); + classAliasingMapper.addClassAlias("software", Software.class); + classAliasingMapper.addClassAlias("open-source", OpenSourceSoftware.class); + mapper = new DefaultImplementationsMapper(new ArrayMapper(classAliasingMapper)); + + reflectionProvider = new SunUnsafeReflectionProvider(); + driver = new XppDriver(); + + converterLookup = new DefaultConverterLookup(); + converterLookup.registerConverter( + new SingleValueConverterWrapper(new StringConverter()), 0); + converterLookup.registerConverter( + new SingleValueConverterWrapper(new IntConverter()), 0); + converterLookup.registerConverter(new ArrayConverter(mapper), 0); + converterLookup.registerConverter( + new ReflectionConverter(mapper, reflectionProvider), -1); + } + + /** + * Tests conversion with field defined in converted class. + */ + public void testWithValueInConvertedClass() { + converterLookup.registerConverter(new ToAttributedValueConverter( + Software.class, mapper, reflectionProvider, converterLookup, "name"), 0); + + final Software name = new Software(null, "XStream"); + final StringWriter writer = new StringWriter(); + final CompactWriter compactWriter = new CompactWriter(writer); + new TreeMarshaller(compactWriter, converterLookup, mapper).start(name, null); + compactWriter.flush(); + assertEquals("XStream", writer.toString()); + + final HierarchicalStreamReader reader = driver.createReader(new StringReader( + writer.toString())); + assertEquals( + name, new TreeUnmarshaller(null, reader, converterLookup, mapper).start(null)); + } + + /** + * Tests conversion with field defined in superclass. + */ + public void testWithValueInSuperclass() { + converterLookup.registerConverter(new ToAttributedValueConverter( + OpenSourceSoftware.class, mapper, reflectionProvider, converterLookup, "name", + Software.class), 0); + + final Software software = new OpenSourceSoftware("Codehaus", "XStream", "BSD"); + final StringWriter writer = new StringWriter(); + final CompactWriter compactWriter = new CompactWriter(writer); + new TreeMarshaller(compactWriter, converterLookup, mapper).start(software, null); + compactWriter.flush(); + assertEquals( + "XStream", + writer.toString()); + + final HierarchicalStreamReader reader = driver.createReader(new StringReader( + writer.toString())); + assertEquals( + software, new TreeUnmarshaller(null, reader, converterLookup, mapper).start(null)); + } + + /** + * Tests conversion distinguishes between different types. + */ + public void testWillDistinguishBetweenDifferentTypes() { + converterLookup.registerConverter(new ToAttributedValueConverter( + Software.class, mapper, reflectionProvider, converterLookup, "name"), 0); + converterLookup.registerConverter( + new ToAttributedValueConverter( + OpenSourceSoftware.class, mapper, reflectionProvider, converterLookup, + "license"), 0); + + final Software[] software = new Software[]{ + new Software("Microsoft", "Windows"), + new OpenSourceSoftware("Codehaus", "XStream", "BSD")}; + final StringWriter writer = new StringWriter(); + final PrettyPrintWriter prettyPrintWriter = new PrettyPrintWriter(writer); + new TreeMarshaller(prettyPrintWriter, converterLookup, mapper).start(software, null); + prettyPrintWriter.flush(); + assertEquals("" + + "\n" + + " Windows\n" + + " BSD\n" + + "", writer.toString()); + + final HierarchicalStreamReader reader = driver.createReader(new StringReader( + writer.toString())); + Software[] array = (Software[])new TreeUnmarshaller( + null, reader, converterLookup, mapper).start(null); + assertEquals(software[0], array[0]); + assertEquals(software[1], array[1]); + } + + /** + * Tests conversion with null in field value. + */ + public void testWithNullValueDeserializedAsEmptyString() { + converterLookup.registerConverter(new ToAttributedValueConverter( + Software.class, mapper, reflectionProvider, converterLookup, "name"), 0); + + final Software software = new Software(null, null); + final StringWriter writer = new StringWriter(); + final CompactWriter compactWriter = new CompactWriter(writer); + new TreeMarshaller(compactWriter, converterLookup, mapper).start(software, null); + compactWriter.flush(); + assertEquals("", writer.toString()); + + final HierarchicalStreamReader reader = driver.createReader(new StringReader( + writer.toString())); + assertEquals( + "", + ((Software)new TreeUnmarshaller(null, reader, converterLookup, mapper).start(null)).name); + } + + /** + * Tests conversion with null in field value. + */ + public void testWithoutValueField() { + converterLookup.registerConverter(new ToAttributedValueConverter( + Software.class, mapper, reflectionProvider, converterLookup, null), 0); + + final Software software = new Software("Codehaus", "XStream"); + final StringWriter writer = new StringWriter(); + final CompactWriter compactWriter = new CompactWriter(writer); + new TreeMarshaller(compactWriter, converterLookup, mapper).start(software, null); + compactWriter.flush(); + assertEquals("", writer.toString()); + + final HierarchicalStreamReader reader = driver.createReader(new StringReader( + writer.toString())); + assertEquals( + software, new TreeUnmarshaller(null, reader, converterLookup, mapper).start(null)); + } + + /** + * Tests conversion with complex value field. + */ + public void testWithComplexValueField() { + converterLookup.registerConverter(new ToAttributedValueConverter( + X.class, mapper, reflectionProvider, converterLookup, "innerObj"), 0); + + final X x = new X(42); + x.aStr = "xXx"; + x.innerObj = new Y(); + x.innerObj.yField = "inner"; + final StringWriter writer = new StringWriter(); + final CompactWriter compactWriter = new CompactWriter(writer); + new TreeMarshaller(compactWriter, converterLookup, mapper).start(x, null); + compactWriter.flush(); + assertEquals( + "inner", writer.toString()); + + final HierarchicalStreamReader reader = driver.createReader(new StringReader( + writer.toString())); + assertEquals(x, new TreeUnmarshaller(null, reader, converterLookup, mapper).start(null)); + } + + public void testFailsWhenFieldCannotBeWrittenAsAttribute() { + converterLookup.registerConverter(new ToAttributedValueConverter( + X.class, mapper, reflectionProvider, converterLookup, "aStr"), 0); + + final X x = new X(42); + x.aStr = "xXx"; + x.innerObj = new Y(); + x.innerObj.yField = "inner"; + final StringWriter writer = new StringWriter(); + final CompactWriter compactWriter = new CompactWriter(writer); + try { + new TreeMarshaller(compactWriter, converterLookup, mapper).start(x, null); + fail("Thrown " + ConversionException.class.getName() + " expected"); + } catch (final ConversionException e) { + assertTrue(e.getMessage().indexOf("innerObj") >= 0); + } + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/extended/ToStringConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/extended/ToStringConverterTest.java new file mode 100644 index 0000000..fb58482 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/extended/ToStringConverterTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.extended; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.SingleValueConverter; + +import junit.framework.TestCase; + +import java.util.Map; + +/** + * + * @author Paul Hammant + */ +public class ToStringConverterTest extends TestCase { + + public void testClaimsCanConvertRightType() throws NoSuchMethodException { + SingleValueConverter converter = new ToStringConverter(Foo.class); + assertTrue(converter.canConvert(Foo.class)); + } + + public void testClaimsCantConvertWrongType() throws NoSuchMethodException { + SingleValueConverter converter = new ToStringConverter(Foo.class); + assertFalse(converter.canConvert(Map.class)); + } + + public void testClaimsCantConvertWrongType2() { + try { + new ToStringConverter(Map.class); + fail("shoulda barfed"); + } catch (NoSuchMethodException e) { + // expected. + } + } + + public void testCanConvertRightType() throws NoSuchMethodException { + SingleValueConverter converter = new ToStringConverter(Foo.class); + assertTrue(converter.fromString("hello") instanceof Foo); + assertEquals("hello", ((Foo) converter.fromString("hello")).foo); + } + + public void testCanInnocentlyConvertWrongTypeToString() throws NoSuchMethodException { + SingleValueConverter converter = new ToStringConverter(Foo.class); + assertEquals("whoa", converter.toString("whoa")); + } + + public void testCantConvertWrongType() throws NoSuchMethodException { + SingleValueConverter converter = new ToStringConverter(BadFoo1.class); + try { + converter.fromString("whoa"); + fail("shoulda barfed"); + } catch (ConversionException e) { + assertTrue(e.getMessage().startsWith("Unable to target single String param constructor")); + assertTrue(e.getCause() instanceof NullPointerException); + } + } + + + public static class Foo { + final String foo; + + public Foo(String foo) { + this.foo = foo; + } + + public String toString() { + return foo; + } + } + + public static class BadFoo1 { + public BadFoo1(String string) { + throw new NullPointerException("abc"); + } + } + + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/javabean/JavaBeanConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/javabean/JavaBeanConverterTest.java new file mode 100644 index 0000000..6f69c15 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/javabean/JavaBeanConverterTest.java @@ -0,0 +1,449 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2010, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 12. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.javabean; + +import junit.framework.TestCase; + +import java.util.Comparator; + +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.XStream; + + +public class JavaBeanConverterTest extends TestCase { + + // Different JDK versions deliver properties in different order - so sort them! + static class StringComparator implements Comparator { + + public int compare(Object o1, Object o2) { + return ((String)o1).compareToIgnoreCase((String)o2); + } + + } + + public static class World extends StandardObject { + + int anInt = 1; + Integer anInteger = new Integer(2); + char aChar = 'a'; + Character aCharacter = new Character('w'); + boolean aBool = true; + Boolean aBoolean = new Boolean(false); + byte aByte = 4; + Byte aByteClass = new Byte("5"); + short aShort = 6; + Short aShortClass = new Short("7"); + float aFloat = 8f; + Float aFloatClass = new Float("9"); + long aLong = 10; + Long aLongClass = new Long("11"); + String aString = new String("XStream programming!"); + + public byte getAByte() { + return aByte; + } + + public void setAByte(byte byte1) { + aByte = byte1; + } + + public Byte getAByteClass() { + return aByteClass; + } + + public void setAByteClass(Byte byteClass) { + aByteClass = byteClass; + } + + public float getAFloat() { + return aFloat; + } + + public void setAFloat(float float1) { + aFloat = float1; + } + + public Float getAFloatClass() { + return aFloatClass; + } + + public void setAFloatClass(Float floatClass) { + aFloatClass = floatClass; + } + + public long getALong() { + return aLong; + } + + public void setALong(long long1) { + aLong = long1; + } + + public Long getALongClass() { + return aLongClass; + } + + public void setALongClass(Long longClass) { + aLongClass = longClass; + } + + public boolean isABool() { + return aBool; + } + + public void setABool(boolean aBool) { + this.aBool = aBool; + } + + public Boolean getABoolean() { + return aBoolean; + } + + public void setABoolean(Boolean aBoolean) { + this.aBoolean = aBoolean; + } + + public char getAChar() { + return aChar; + } + + public void setAChar(char aChar) { + this.aChar = aChar; + } + + public Character getACharacter() { + return aCharacter; + } + + public void setACharacter(Character aCharacter) { + this.aCharacter = aCharacter; + } + + public int getAnInt() { + return anInt; + } + + public void setAnInt(int anInt) { + this.anInt = anInt; + } + + public Integer getAnInteger() { + return anInteger; + } + + public void setAnInteger(Integer anInteger) { + this.anInteger = anInteger; + } + + public String getAString() { + return aString; + } + + public void setAString(String aString) { + this.aString = aString; + } + + public short getAShort() { + return aShort; + } + + public void setAShort(short short1) { + aShort = short1; + } + + public Short getAShortClass() { + return aShortClass; + } + + public void setAShortClass(Short shortClass) { + aShortClass = shortClass; + } + } + + public void testSerializesAllPrimitiveFieldsInACustomObject() { + World world = new World(); + + XStream xstream = new XStream(); + xstream.registerConverter(new JavaBeanConverter(xstream.getMapper(), new BeanProvider( + new StringComparator())), XStream.PRIORITY_LOW); + xstream.alias("world", World.class); + + String expected = "" + + "\n" + + " true\n" + + " false\n" + + " 4\n" + + " 5\n" + + " a\n" + + " w\n" + + " 8.0\n" + + " 9.0\n" + + " 10\n" + + " 11\n" + + " 1\n" + + " 2\n" + + " 6\n" + + " 7\n" + + " XStream programming!\n" + + ""; + + String result = xstream.toXML(world); + + assertEquals(expected, result); + } + + /** + * Only normal and trans are serializable properties, the field modifiers do not matter + */ + public static class TypesOfFields extends StandardObject { + String normal = "normal"; + + transient String trans = "transient"; + + final String fin = "final"; + + static String stat = "stat"; + + public static String getStat() { + return stat; + } + + public static void setStat(String stat) { + TypesOfFields.stat = stat; + } + + public String getFin() { + return fin; + } + + public String getNormal() { + return normal; + } + + public void setNormal(String normal) { + this.normal = normal; + } + + public String getTrans() { + return trans; + } + + public void setTrans(String trans) { + this.trans = trans; + } + } + + public void testDoesNotSerializeStaticFields() { + TypesOfFields fields = new TypesOfFields(); + String expected = "" + + "\n" + + " normal\n" + + " transient\n" + + ""; + + XStream xstream = new XStream(); + xstream.registerConverter(new JavaBeanConverter(xstream.getMapper(), new BeanProvider( + new StringComparator())), -20); + xstream.alias("types", TypesOfFields.class); + + String xml = xstream.toXML(fields); + assertEquals(expected, xml); + + } + + public static class SimpleBean extends StandardObject { + private Object member; + + public Object getMember() { + return this.member; + } + + public void setMember(Object member) { + this.member = member; + } + } + + public void testSupportsTypeAlias() { + SimpleBean innerBean = new SimpleBean(); + SimpleBean bean = new SimpleBean(); + bean.setMember(innerBean); + innerBean.setMember("foo"); + + String expected = "" + + "\n" + + " \n" + + " foo\n" + + " \n" + + ""; + + XStream xstream = new XStream(); + xstream.registerConverter(new JavaBeanConverter(xstream.getMapper()), XStream.PRIORITY_LOW); + xstream.alias("bean", SimpleBean.class); + + String xml = xstream.toXML(bean); + assertEquals(expected, xml); + } + + public void testDoesNotSerializeOmittedFields() { + TypesOfFields fields = new TypesOfFields(); + String expected = ""; + + XStream xstream = new XStream(); + xstream.registerConverter(new JavaBeanConverter(xstream.getMapper()), XStream.PRIORITY_LOW); + xstream.alias("types", TypesOfFields.class); + xstream.omitField(TypesOfFields.class, "trans"); + xstream.omitField(TypesOfFields.class, "foo"); + xstream.omitField(TypesOfFields.class, "normal"); + + String xml = xstream.toXML(fields); + assertEquals(expected, xml); + } + + public void testDoesNotDeserializeOmittedFields() { + TypesOfFields fields = new TypesOfFields(); + String xml = "" + + "\n" + + " foo\n" + + " bar\n" + + ""; + + XStream xstream = new XStream(); + xstream.registerConverter(new JavaBeanConverter(xstream.getMapper()), XStream.PRIORITY_LOW); + xstream.alias("types", TypesOfFields.class); + xstream.omitField(TypesOfFields.class, "foo"); + xstream.omitField(TypesOfFields.class, "normal"); + + TypesOfFields unmarshalledFields = (TypesOfFields)xstream.fromXML(xml); + assertEquals(fields, unmarshalledFields); + } + + public static class UnsafeBean { + public String getUnsafe() { + throw new RuntimeException("Do not call"); + } + public void setUnsafe(String value) { + // ignore + } + } + + public void testDoesNotGetValueOfOmittedFields() { + UnsafeBean bean = new UnsafeBean(); + String expected = ""; + + XStream xstream = new XStream(); + xstream.registerConverter(new JavaBeanConverter(xstream.getMapper()), XStream.PRIORITY_LOW); + xstream.alias("unsafeBean", UnsafeBean.class); + xstream.omitField(UnsafeBean.class, "unsafe"); + + String xml = xstream.toXML(bean); + assertEquals(expected, xml); + } + + public static class Person { + private String fName; + private String lName; + + public Person() { + // Bean constructor + } + + public Person(String firstName, String lastName) { + this.fName = firstName; + this.lName = lastName; + } + + public String getFirstName() { + return fName; + } + + public void setFirstName(String name) { + fName = name; + } + + public String getLastName() { + return lName; + } + + public void setLastName(String name) { + lName = name; + } + } + + public static class Man extends Person { + + public Man() { + // Bean constructor + super(); + } + + public Man(String firstName, String lastName) { + super(firstName, lastName); + } + + } + + public void testDoesNotSerializeOmittedInheritedFields() { + XStream xstream = new XStream(); + xstream.registerConverter( + new JavaBeanConverter(xstream.getMapper()), XStream.PRIORITY_LOW); + xstream.omitField(Person.class, "lastName"); + xstream.alias("man", Man.class); + + Man man = new Man("John", "Doe"); + String expected = "" + + "\n" + + " John\n" + + ""; + + assertEquals(expected, xstream.toXML(man)); + } + + public void testUseAliasInheritedFields() { + XStream xstream = new XStream(); + xstream.registerConverter( + new JavaBeanConverter(xstream.getMapper(), new BeanProvider( + new StringComparator())), XStream.PRIORITY_LOW); + xstream.aliasField("first-name", Person.class, "firstName"); + xstream.aliasField("last-name", Person.class, "lastName"); + xstream.alias("man", Man.class); + + Man man = new Man("John", "Doe"); + String expected = "" + + "\n" + + " John\n" + + " Doe\n" + + ""; + + assertEquals(expected, xstream.toXML(man)); + } + + public void testFailsFastIfPropertyIsDefinedTwice() { + XStream xstream = new XStream(); + xstream.registerConverter( + new JavaBeanConverter(xstream.getMapper()), XStream.PRIORITY_LOW); + String input = "" + + "\n" + + " foo\n" + + " bar\n" + + ""; + xstream.alias("types", TypesOfFields.class); + + try { + + xstream.fromXML(input); + fail("Expected exception"); + + } catch (JavaBeanConverter.DuplicatePropertyException expected) { + assertEquals("normal", expected.get("property")); + } + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/javabean/PropertyDictionaryTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/javabean/PropertyDictionaryTest.java new file mode 100644 index 0000000..8efe993 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/javabean/PropertyDictionaryTest.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 12. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.javabean; + +import junit.framework.TestCase; + +import java.beans.PropertyDescriptor; +import java.util.Iterator; + +public class PropertyDictionaryTest extends TestCase { + + private PropertyDictionary propertyDictionary; + + protected void setUp() throws Exception { + super.setUp(); + propertyDictionary = new PropertyDictionary(); + } + + /** + * Test class: three serializable properties, one with a all capital name, + * two others non serializable, one readable, one writable, and another and + * a lonely field + */ + class SomeClass { + private String a; + + private String URL; + + private String c; + + private String d; + + private String e; + + private String f; + + public String getA() { + return a; + } + + public void setA(String a) { + this.a = a; + } + + public String getURL() { + return URL; + } + + public void setURL(String url) { + this.URL = url; + } + + public String getC() { + return c; + } + + public void setC(String c) { + this.c = c; + } + + public String getD() { + return d; + } + + public void setE(String e) { + this.e = e; + } + } + + public void testListsFieldsInClassInDefinitionOrder() { + Iterator properties = propertyDictionary.serializablePropertiesFor(SomeClass.class); + assertEquals("URL", ((BeanProperty) properties.next()).getName()); + assertEquals("a", ((BeanProperty) properties.next()).getName()); + assertEquals("c", ((BeanProperty) properties.next()).getName()); + assertFalse("No more fields should be present", properties.hasNext()); + + properties = propertyDictionary.propertiesFor(SomeClass.class); + assertEquals("URL", ((PropertyDescriptor) properties.next()).getName()); + assertEquals("a", ((PropertyDescriptor) properties.next()).getName()); + assertEquals("c", ((PropertyDescriptor) properties.next()).getName()); + assertEquals("d", ((PropertyDescriptor) properties.next()).getName()); + assertEquals("e", ((PropertyDescriptor) properties.next()).getName()); + assertFalse("No more fields should be present", properties.hasNext()); + } + + /** + * Test subclassing and private properties + */ + class SpecialClass extends SomeClass { + private String brilliant; + + public String getBrilliant() { + return brilliant; + } + + public void setBrilliant(String brilliant) { + this.brilliant = brilliant; + } + + public String getPrivate() { + return null; + } + + private void setPrivate(String string) { + + } + } + + public void testIncludesFieldsInSuperClasses() { + Iterator properties = propertyDictionary.serializablePropertiesFor(SpecialClass.class); + assertEquals("URL", ((BeanProperty) properties.next()).getName()); + assertEquals("a", ((BeanProperty) properties.next()).getName()); + assertEquals("brilliant", ((BeanProperty) properties.next()).getName()); + assertEquals("c", ((BeanProperty) properties.next()).getName()); + assertFalse("No more fields should be present", properties.hasNext()); + + properties = propertyDictionary.propertiesFor(SpecialClass.class); + assertEquals("URL", ((PropertyDescriptor) properties.next()).getName()); + assertEquals("a", ((PropertyDescriptor) properties.next()).getName()); + assertEquals("brilliant", ((PropertyDescriptor) properties.next()).getName()); + assertEquals("c", ((PropertyDescriptor) properties.next()).getName()); + assertEquals("d", ((PropertyDescriptor) properties.next()).getName()); + assertEquals("e", ((PropertyDescriptor) properties.next()).getName()); + assertEquals("private", ((PropertyDescriptor) properties.next()).getName()); + assertFalse("No more fields should be present", properties.hasNext()); + } +} \ No newline at end of file diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/reflection/AbstractReflectionProviderTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/AbstractReflectionProviderTest.java new file mode 100644 index 0000000..0ba0599 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/AbstractReflectionProviderTest.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 14. May 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.reflection; + +import org.jmock.Mock; +import org.jmock.MockObjectTestCase; + +public abstract class AbstractReflectionProviderTest extends MockObjectTestCase { + + protected ReflectionProvider reflectionProvider; + + public abstract ReflectionProvider createReflectionProvider(); + + protected void setUp() throws Exception { + super.setUp(); + reflectionProvider = createReflectionProvider(); + } + + public void testConstructsStandardClass() { + assertCanCreate(OuterClass.class); + } + + public void testConstructsStaticInnerClass() { + assertCanCreate(PublicStaticInnerClass.class); + } + + public static class WithFields { + private int a; + private int b = 2; + + public int getParentB() { + return b; + } + } + + public void testVisitsEachFieldInClass() { + // setup + Mock mockBlock = new Mock(ReflectionProvider.Visitor.class); + + // expect + mockBlock.expects(once()) + .method("visit") + .with(eq("a"), eq(int.class), eq(WithFields.class), ANYTHING); + mockBlock.expects(once()) + .method("visit") + .with(eq("b"), eq(int.class), eq(WithFields.class), ANYTHING); + + // execute + reflectionProvider.visitSerializableFields(new WithFields(), (ReflectionProvider.Visitor) mockBlock.proxy()); + + // verify + mockBlock.verify(); + } + + public static class SubClassWithFields extends WithFields { + private int c; + } + + public void testVisitsEachFieldInHeirarchy() { + // setup + Mock mockBlock = new Mock(ReflectionProvider.Visitor.class); + + // expect + mockBlock.expects(once()) + .method("visit") + .with(eq("a"), eq(int.class), eq(WithFields.class), ANYTHING); + mockBlock.expects(once()) + .method("visit") + .with(eq("b"), eq(int.class), eq(WithFields.class), ANYTHING); + mockBlock.expects(once()) + .method("visit") + .with(eq("c"), eq(int.class), eq(SubClassWithFields.class), ANYTHING); + + // execute + reflectionProvider.visitSerializableFields(new SubClassWithFields(), (ReflectionProvider.Visitor) mockBlock.proxy()); + + // verify + mockBlock.verify(); + } + + public static class SubClassWithHiddenFields extends WithFields { + private int b = 3; + + public int getChildB() { + return b; + } + } + + public void testVisitsFieldsHiddenBySubclass() { + // setup + Mock mockBlock = new Mock(ReflectionProvider.Visitor.class); + + // expect + mockBlock.expects(once()) + .method("visit") + .with(eq("b"), eq(int.class), eq(WithFields.class), ANYTHING) + .id("first"); + mockBlock.expects(once()) + .method("visit") + .with(eq("b"), eq(int.class), eq(SubClassWithHiddenFields.class), ANYTHING) + .after("first"); + mockBlock.expects(once()) + .method("visit") + .with(eq("a"), ANYTHING, ANYTHING, ANYTHING); + + // execute + reflectionProvider.visitSerializableFields(new SubClassWithHiddenFields(), (ReflectionProvider.Visitor) mockBlock.proxy()); + + // verify + mockBlock.verify(); + } + + public void testWritesHiddenFields() { + SubClassWithHiddenFields o = new SubClassWithHiddenFields(); + reflectionProvider.writeField(o, "b", new Integer(10), null); + reflectionProvider.writeField(o, "b", new Integer(20), WithFields.class); + assertEquals(10, o.getChildB()); + assertEquals(20, o.getParentB()); + } + + protected void assertCanCreate(Class type) { + Object result = reflectionProvider.newInstance(type); + assertEquals(type, result.getClass()); + } + + protected void assertCannotCreate(Class type) { + try { + reflectionProvider.newInstance(type); + fail("Should not have been able to newInstance " + type); + } catch (ObjectAccessException goodException) { + } + } + + public static class PublicStaticInnerClass { + } + +} + +class OuterClass { +} + diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/reflection/FieldDictionaryTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/FieldDictionaryTest.java new file mode 100644 index 0000000..3243389 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/FieldDictionaryTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 14. July 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.reflection; + +import junit.framework.TestCase; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Iterator; + +public class FieldDictionaryTest extends TestCase { + + private FieldDictionary fieldDictionary; + + protected void setUp() throws Exception { + super.setUp(); + fieldDictionary = new FieldDictionary(); + } + + static class SomeClass { + private String a; + private String c; + private transient String b; + private static String d; + private String e; + } + + public void testListsFieldsInClassInDefinitionOrder() { + Iterator fields = fieldDictionary.fieldsFor(SomeClass.class); + assertEquals("a", getNonStaticFieldName(fields)); + assertEquals("c", getNonStaticFieldName(fields)); + assertEquals("b", getNonStaticFieldName(fields)); + assertEquals("e", getNonStaticFieldName(fields)); + assertFalse("No more fields should be present", fields.hasNext()); + } + + static class SpecialClass extends SomeClass { + private String brilliant; + } + + public void testIncludesFieldsInSuperClasses() { + Iterator fields = fieldDictionary.fieldsFor(SpecialClass.class); + assertEquals("a", getNonStaticFieldName(fields)); + assertEquals("c", getNonStaticFieldName(fields)); + assertEquals("b", getNonStaticFieldName(fields)); + assertEquals("e", getNonStaticFieldName(fields)); + assertEquals("brilliant", getNonStaticFieldName(fields)); + assertFalse("No more fields should be present", fields.hasNext()); + } + + class InnerClass { // note: no static makes this an inner class, not nested class. + private String someThing; + } + + public void testIncludesOuterClassReferenceForInnerClass() { + Iterator fields = fieldDictionary.fieldsFor(InnerClass.class); + assertEquals("someThing", getNonStaticFieldName(fields)); + Field innerField = ((Field)fields.next()); + assertEquals("this$0", innerField.getName()); + assertEquals(FieldDictionaryTest.class, innerField.getType()); + assertFalse("No more fields should be present", fields.hasNext()); + } + + private static String getNonStaticFieldName(Iterator fields) { + final Field field = (Field)fields.next(); + // JRockit declares static fields first, XStream will ignore them anyway + if ((field.getModifiers() & Modifier.STATIC) > 0) { + return getNonStaticFieldName(fields); + } + return field.getName(); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/reflection/NativeFieldKeySorterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/NativeFieldKeySorterTest.java new file mode 100644 index 0000000..7919a8f --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/NativeFieldKeySorterTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 17. May 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.reflection; + +import com.thoughtworks.xstream.core.util.OrderRetainingMap; + +import junit.framework.TestCase; + +import java.lang.reflect.Field; +import java.util.Map; + + +public class NativeFieldKeySorterTest extends TestCase { + + static class Base { + String yyy; + String ccc; + String bbb; + } + + static class First extends Base { + String aaa; + } + + static class Second extends First { + String xxx; + String zzz; + } + + public void testDoesSortInDeclarationOrderWithFieldsOfBaseClassFirst() { + String[] fieldOrder = new String[]{"yyy", "ccc", "bbb", "aaa", "xxx", "zzz"}; + FieldKeySorter sorter = new NativeFieldKeySorter(); + Map originalMap = buildMap(Second.class); + Map map = sorter.sort(Second.class, originalMap); + Field[] fields = (Field[])map.values().toArray(new Field[map.size()]); + assertEquals(fieldOrder.length, fields.length); + for (int i = 0; i < fieldOrder.length; i++) { + assertEquals("Field[" + i + ']', fieldOrder[i], fields[i].getName()); + } + } + + private Map buildMap(Class type) { + Map map = new OrderRetainingMap(); + Class cls = type; + while (!cls.equals(Object.class)) { + Field[] fields = cls.getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + Field field = fields[i]; + map.put(new FieldKey(field.getName(), cls, i), field); + } + cls = cls.getSuperclass(); + } + return map; + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/reflection/PureJavaReflectionProvider15Test.java b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/PureJavaReflectionProvider15Test.java new file mode 100644 index 0000000..80c7a9d --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/PureJavaReflectionProvider15Test.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 08. February 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.reflection; + + +public class PureJavaReflectionProvider15Test extends AbstractReflectionProviderTest { + + // inherits tests from superclass + + public ReflectionProvider createReflectionProvider() { + return new PureJavaReflectionProvider(); + } + + + // --------------------------------------------------------- + + + public static class WithFinalField { + private final String s; + private WithFinalField() { + this.s = ""; + } + String getFinal() { + return s; + } + } + + public void testCanCreateWithFinalField() { + assertCanCreate(WithFinalField.class); + } + + public void testWriteToFinalField() { + Object result = reflectionProvider.newInstance(WithFinalField.class); + reflectionProvider.writeField(result, "s", "foo", WithFinalField.class); + WithFinalField withFinalField = (WithFinalField)result; + assertEquals("foo", withFinalField.getFinal()); + } + +} + diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/reflection/PureJavaReflectionProviderTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/PureJavaReflectionProviderTest.java new file mode 100644 index 0000000..f732850 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/PureJavaReflectionProviderTest.java @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.reflection; + +import java.io.Serializable; + +public class PureJavaReflectionProviderTest extends AbstractReflectionProviderTest { + + // inherits tests from superclass + + public ReflectionProvider createReflectionProvider() { + return new PureJavaReflectionProvider(); + } + + + // --------------------------------------------------------- + + + private static class PrivateStaticInnerClass { + } + + public void testCanCreatePrivateStaticInnerClasses() { + assertCanCreate(PrivateStaticInnerClass.class); + } + + + // --------------------------------------------------------- + + + public class PublicNonStaticInnerClass { + } + + private class PrivateNonStaticInnerClass { + } + + public void testIsNotCapableOfConstructingNonStaticInnerClasses() { + assertCannotCreate(PublicNonStaticInnerClass.class); + assertCannotCreate(PrivateNonStaticInnerClass.class); + } + + + // --------------------------------------------------------- + + + public static class WithConstructorThatDoesStuff { + public WithConstructorThatDoesStuff() { + throw new UnsupportedOperationException("constructor called"); + } + } + + public void testUnfortunatelyExecutesCodeInsideConstructor() { + try { + reflectionProvider.newInstance(WithConstructorThatDoesStuff.class); + fail("Expected code in constructor to be executed and throw an exception"); + } catch (UnsupportedOperationException expectedException) { + // good + } + } + + + // --------------------------------------------------------- + + + public static class WithoutDefaultConstructor { + public WithoutDefaultConstructor(String arg) { + } + } + + public void testIsNotCapableOfConstructingClassesWithoutDefaultConstructor() { + assertCannotCreate(WithoutDefaultConstructor.class); + } + + + // --------------------------------------------------------- + + + public static class WithPrivateDefaultConstructor { + private WithPrivateDefaultConstructor(String thing) { + throw new UnsupportedOperationException("wrong constructor called"); + } + + private WithPrivateDefaultConstructor() { + } + } + + public void testUsesPrivateConstructorIfNecessary() { + assertCanCreate(WithPrivateDefaultConstructor.class); + } + + + // --------------------------------------------------------- + + + private static class SerializableWithoutDefaultConstructor implements Serializable { + private int field1, field2; + public SerializableWithoutDefaultConstructor(String thing) { + throw new UnsupportedOperationException("constructor called"); + } + } + + private class NonStaticSerializableWithoutDefaultConstructor implements Serializable { + public NonStaticSerializableWithoutDefaultConstructor(String thing) { + throw new UnsupportedOperationException("constructor called"); + } + } + + public void testBypassesConstructorForSerializableObjectsWithNoDefaultConstructor() { + assertCanCreate(SerializableWithoutDefaultConstructor.class); + assertCanCreate(NonStaticSerializableWithoutDefaultConstructor.class); + } + + +} + diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/reflection/ReflectionConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/ReflectionConverterTest.java new file mode 100644 index 0000000..5a335e4 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/ReflectionConverterTest.java @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2010, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.converters.reflection; + +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.core.ClassLoaderReference; +import com.thoughtworks.xstream.core.util.CompositeClassLoader; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.mapper.AttributeMapper; +import com.thoughtworks.xstream.mapper.DefaultMapper; +import com.thoughtworks.xstream.mapper.Mapper; + +import junit.framework.TestCase; + +public class ReflectionConverterTest extends TestCase { + + public static class World extends StandardObject { + int anInt = 1; + Integer anInteger = new Integer(2); + char anChar = 'a'; + Character anCharacter = new Character('w'); + boolean anBool = true; + Boolean anBoolean = new Boolean(false); + byte aByte = 4; + Byte aByteClass = new Byte("5"); + short aShort = 6; + Short aShortClass = new Short("7"); + float aFloat = 8f; + Float aFloatClass = new Float("9"); + long aLong = 10; + Long aLongClass = new Long("11"); + String anString = new String("XStream programming!"); + } + + public void testSerializesAllPrimitiveFieldsInACustomObject() { + World world = new World(); + + XStream xstream = new XStream(new XppDriver()); + xstream.alias("world", World.class); + + String expected = + "\n" + + " 1\n" + + " 2\n" + + " a\n" + + " w\n" + + " true\n" + + " false\n" + + " 4\n" + + " 5\n" + + " 6\n" + + " 7\n" + + " 8.0\n" + + " 9.0\n" + + " 10\n" + + " 11\n" + + " XStream programming!\n" + + ""; + + assertEquals(expected, xstream.toXML(world)); + } + + public static class TypesOfFields extends StandardObject { + String normal = "normal"; + transient String trans = "transient"; + static String stat = "stat"; + } + + public void testDoesNotSerializeTransientOrStaticFields() { + TypesOfFields fields = new TypesOfFields(); + String expected = "" + + "\n" + + " normal\n" + + ""; + + XStream xstream = new XStream(new XppDriver()); + xstream.alias("types", TypesOfFields.class); + + String xml = xstream.toXML(fields); + assertEquals(expected, xml); + + } + + public void testCanBeOverloadedToDeserializeTransientFields() { + XStream xstream = new XStream(new XppDriver()); + xstream.alias("types", TypesOfFields.class); + xstream.registerConverter(new ReflectionConverter(xstream.getMapper(), xstream + .getReflectionProvider()) { + + public boolean canConvert(Class type) { + return type == TypesOfFields.class; + } + + protected boolean shouldUnmarshalTransientFields() { + return true; + } + }); + + String xml = "" + + "\n" + + " normal\n" + + " foo\n" + + ""; + + TypesOfFields fields = (TypesOfFields)xstream.fromXML(xml); + assertEquals("foo", fields.trans); + } + + public void testCustomConverterCanBeInstantiatedAndRegisteredWithDesiredPriority() { + XStream xstream = new XStream(new XppDriver()); + // using default mapper instead of XStream#buildMapper() + Mapper mapper = new DefaultMapper(new ClassLoaderReference(new CompositeClassLoader())); + // AttributeMapper required by ReflectionConverter + mapper = new AttributeMapper(mapper, xstream.getConverterLookup(), xstream.getReflectionProvider()); + Converter converter = new CustomReflectionConverter(mapper, new PureJavaReflectionProvider()); + xstream.registerConverter(converter, -20); + xstream.alias("world", World.class); + World world = new World(); + + String expected = + "\n" + + " 1\n" + + " 2\n" + + " a\n" + + " w\n" + + " true\n" + + " false\n" + + " 4\n" + + " 5\n" + + " 6\n" + + " 7\n" + + " 8.0\n" + + " 9.0\n" + + " 10\n" + + " 11\n" + + " XStream programming!\n" + + ""; + assertEquals(expected, xstream.toXML(world)); + + } + + static class CustomReflectionConverter extends ReflectionConverter { + + public CustomReflectionConverter(Mapper mapper, ReflectionProvider reflectionProvider) { + super(mapper, reflectionProvider); + } + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SerializableConverterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SerializableConverterTest.java new file mode 100644 index 0000000..f0c1dec --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SerializableConverterTest.java @@ -0,0 +1,345 @@ +/* + * Copyright (C) 2007, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. July 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.converters.reflection; + +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.XStream; + +import junit.framework.TestCase; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamField; +import java.io.Serializable; + + +/** + * @author Jörg Schaible + */ +public class SerializableConverterTest extends TestCase { + + static class SimpleType extends StandardObject { + private String one; + private String two; + + public String getOne() { + return this.one; + } + + public void setOne(String one) { + this.one = one; + } + + public String getTwo() { + return this.two; + } + + public void setTwo(String two) { + this.two = two; + } + + private void writeObject(final ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + } + + private void readObject(final ObjectInputStream in) + throws IOException, ClassNotFoundException { + in.defaultReadObject(); + } + } + + public void testCanOmitFieldAtSerialization() { + XStream xstream = new XStream(); + xstream.alias("simple", SimpleType.class); + xstream.omitField(SimpleType.class, "two"); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " one\n" + + " \n" + + " \n" + + ""; + + SimpleType simple = new SimpleType(); + simple.setOne("one"); + simple.setTwo("two"); + + String xml = xstream.toXML(simple); + assertEquals(expected, xml); + } + + public void testCanOmitFieldAtDeserialization() { + XStream xstream = new XStream(); + xstream.alias("simple", SimpleType.class); + xstream.omitField(SimpleType.class, "two"); + xstream.omitField(SimpleType.class, "x"); + + String xml = "" + + "\n" + + " \n" + + " \n" + + " one\n" + + " x\n" + + " \n" + + " \n" + + ""; + + SimpleType simple = new SimpleType(); + simple.setOne("one"); + + SimpleType serialized = (SimpleType)xstream.fromXML(xml); + assertEquals(simple, serialized); + } + + static class ExtendedType extends SimpleType { + private String three; + + public String getThree() { + return this.three; + } + + public void setThree(String three) { + this.three = three; + } + + private void writeObject(final ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + } + + private void readObject(final ObjectInputStream in) + throws IOException, ClassNotFoundException { + in.defaultReadObject(); + } + } + + public void testCanOmitInheritedFieldAtSerialization() { + XStream xstream = new XStream(); + xstream.alias("extended", ExtendedType.class); + xstream.alias("simple", SimpleType.class); + xstream.omitField(SimpleType.class, "two"); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " one\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " three\n" + + " \n" + + " \n" + + ""; + + ExtendedType extended = new ExtendedType(); + extended.setOne("one"); + extended.setTwo("two"); + extended.setThree("three"); + + String xml = xstream.toXML(extended); + assertEquals(expected, xml); + } + + public void testCanOmitInheritedFieldAtDeserialization() { + XStream xstream = new XStream(); + xstream.alias("extended", ExtendedType.class); + xstream.alias("simple", SimpleType.class); + xstream.omitField(SimpleType.class, "two"); + xstream.omitField(SimpleType.class, "x"); + + String xml = "" + + "\n" + + " \n" + + " \n" + + " one\n" + + " x\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " three\n" + + " \n" + + " \n" + + ""; + + ExtendedType extended = new ExtendedType(); + extended.setOne("one"); + extended.setThree("three"); + + SimpleType serialized = (SimpleType)xstream.fromXML(xml); + assertEquals(extended, serialized); + } + + public static class SimpleNamedFieldsType extends StandardObject implements Serializable { + + private String one; + private String two; + + public String getOne() { + return this.one; + } + + public void setOne(String one) { + this.one = one; + } + + public String getTwo() { + return this.two; + } + + public void setTwo(String two) { + this.two = two; + } + + private static final ObjectStreamField[] serialPersistentFields = { + new ObjectStreamField("s1", String.class), + new ObjectStreamField("s2", String.class), + }; + + private void writeObject(ObjectOutputStream out) throws IOException { + // don't call defaultWriteObject() + ObjectOutputStream.PutField fields = out.putFields(); + fields.put("s1", one); + fields.put("s2", two); + out.writeFields(); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + // don't call defaultReadObject() + ObjectInputStream.GetField fields = in.readFields(); + one = (String) fields.get("s1", "1"); + two = (String) fields.get("s2", "2"); + } + } + + public void testCanOmitNamedFieldAtSerialization() { + XStream xstream = new XStream(); + xstream.alias("simple", SimpleNamedFieldsType.class); + xstream.omitField(SimpleNamedFieldsType.class, "s2"); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " one\n" + + " \n" + + " \n" + + ""; + + SimpleNamedFieldsType simple = new SimpleNamedFieldsType(); + simple.setOne("one"); + simple.setTwo("two"); + + String xml = xstream.toXML(simple); + assertEquals(expected, xml); + } + + public void testCanOmitNamedFieldAtDeserialization() { + XStream xstream = new XStream(); + xstream.alias("simple", SimpleNamedFieldsType.class); + xstream.omitField(SimpleNamedFieldsType.class, "s2"); + xstream.omitField(SimpleNamedFieldsType.class, "x"); + + String xml = "" + + "\n" + + " \n" + + " \n" + + " one\n" + + " x\n" + + " \n" + + " \n" + + ""; + + SimpleNamedFieldsType simple = new SimpleNamedFieldsType(); + simple.setOne("one"); + simple.setTwo("2"); + + SimpleNamedFieldsType serialized = (SimpleNamedFieldsType)xstream.fromXML(xml); + assertEquals(simple, serialized); + } + + public void testCanAliasField() { + XStream xstream = new XStream(); + xstream.alias("simple", SimpleType.class); + xstream.aliasField("s2", SimpleType.class, "two"); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " one\n" + + " two\n" + + " \n" + + " \n" + + ""; + + SimpleType simple = new SimpleType(); + simple.setOne("one"); + simple.setTwo("two"); + + String xml = xstream.toXML(simple); + assertEquals(expected, xml); + SimpleType serialized = (SimpleType)xstream.fromXML(xml); + assertEquals(simple, serialized); + } + + public void testCanAliasNamedField() { + XStream xstream = new XStream(); + xstream.alias("simple", SimpleNamedFieldsType.class); + xstream.aliasField("two", SimpleNamedFieldsType.class, "s2"); + + String expected = "" + + "\n" + + " \n" + + " \n" + + " one\n" + + " two\n" + + " \n" + + " \n" + + ""; + + SimpleNamedFieldsType simple = new SimpleNamedFieldsType(); + simple.setOne("one"); + simple.setTwo("two"); + + String xml = xstream.toXML(simple); + assertEquals(expected, xml); + SimpleNamedFieldsType serialized = (SimpleNamedFieldsType)xstream.fromXML(xml); + assertEquals(simple, serialized); + } + + public static class SerializableType implements Serializable { + public Serializable serializable; + } + + public void testCanHandleFieldsDeclaredWithSerializableInterface() { + XStream xstream = new XStream(); + xstream.alias("sertype", SerializableType.class); + xstream.useAttributeFor(SerializableType.class, "serializable"); + + String expected = "" + + "\n" + + " String\n" + + ""; + + SerializableType s = new SerializableType(); + s.serializable = "String"; + + String xml = xstream.toXML(s); + assertEquals(expected, xml); + SerializableType serialized = (SerializableType)xstream.fromXML(xml); + assertEquals(s.serializable, serialized.serializable); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SortableFieldKeySorterTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SortableFieldKeySorterTest.java new file mode 100644 index 0000000..a69d226 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SortableFieldKeySorterTest.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 10. April 2007 by Guilherme Silveira + */ +package com.thoughtworks.xstream.converters.reflection; + +import java.lang.reflect.Field; +import java.util.Map; + +import com.thoughtworks.xstream.core.util.OrderRetainingMap; +import com.thoughtworks.xstream.io.StreamException; + +import junit.framework.TestCase; + + +public class SortableFieldKeySorterTest extends TestCase { + + public void testDoesNotAffectUnregisteredTypes() { + SortableFieldKeySorter sorter = new SortableFieldKeySorter(); + sorter.registerFieldOrder(Mother.class, new String[]{"field2", "field1"}); + sorter.registerFieldOrder(Child.class, new String[]{"field2", "field1"}); + Map originalMap = buildMap(Base.class); + Map map = sorter.sort(Base.class, originalMap); + assertEquals(originalMap, map); + } + + public void testIgnoresUnknownFields() { + SortableFieldKeySorter sorter = new SortableFieldKeySorter(); + String[] fieldOrder = new String[]{"whatever", "field2", "field1", "field3"}; + sorter.registerFieldOrder(Child.class, fieldOrder); + Map originalMap = buildMap(Child.class); + Map map = sorter.sort(Child.class, originalMap); + Field[] fields = (Field[])map.values().toArray(new Field[map.size()]); + assertEquals(fieldOrder.length - 1, fields.length); + for (int i = 1; i < fieldOrder.length; i++) { + assertEquals(fieldOrder[i], fields[i - 1].getName()); + } + } + + public void testComplainsIfSomeFieldIsNotSpecified() { + SortableFieldKeySorter sorter = new SortableFieldKeySorter(); + sorter.registerFieldOrder(Base.class, new String[]{"field3"}); + try { + sorter.sort(Base.class, buildMap(Base.class)); + fail(); + } catch (StreamException ex) { + // ok + } + } + + public void testSortsMapAccordingToDefinedFieldOrder() { + SortableFieldKeySorter sorter = new SortableFieldKeySorter(); + String[] fieldOrder = new String[]{"field2", "field1", "field3"}; + sorter.registerFieldOrder(Child.class, fieldOrder); + Map originalMap = buildMap(Child.class); + Map map = sorter.sort(Child.class, originalMap); + Field[] fields = (Field[])map.values().toArray(new Field[map.size()]); + assertEquals(fieldOrder.length, fields.length); + for (int i = 0; i < fieldOrder.length; i++) { + assertEquals(fieldOrder[i], fields[i].getName()); + } + } + + private Map buildMap(Class type) { + Map map = new OrderRetainingMap(); + Class cls = type; + while (!cls.equals(Object.class)) { + Field[] fields = cls.getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + Field field = fields[i]; + map.put(new FieldKey(field.getName(), cls, i), field); + } + cls = cls.getSuperclass(); + } + return map; + } + + static class Base extends Mother { + String field3; + } + + static class Child extends Base { + } + + static class Mother { + String field1, field2; + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProviderTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProviderTest.java new file mode 100644 index 0000000..d6cd286 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProviderTest.java @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2013, 2014 XStream Committers. + * All rights reserved. + * + * Created on 08. January 2014 by Joerg Schaible, factored out from SunUnsafeReflectionProviderTest + */ +package com.thoughtworks.xstream.converters.reflection; + +public class SunLimitedUnsafeReflectionProviderTest extends SunUnsafeReflectionProviderTest { + + // inherits tests from superclass + + public ReflectionProvider createReflectionProvider() { + return new SunLimitedUnsafeReflectionProvider(); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SunUnsafeReflectionProviderTest.java b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SunUnsafeReflectionProviderTest.java new file mode 100644 index 0000000..44d7643 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/converters/reflection/SunUnsafeReflectionProviderTest.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2013, 2014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 08. January 2014 by Joerg Schaible, renamed from Sun14RelfectrionProviderTest. + */ +package com.thoughtworks.xstream.converters.reflection; + +public class SunUnsafeReflectionProviderTest extends AbstractReflectionProviderTest { + + // inherits tests from superclass + + public ReflectionProvider createReflectionProvider() { + return new SunUnsafeReflectionProvider(); + } + + protected static class WithFinalFields { + final String finalField; + final int finalInt; + final long finalLong; + final short finalShort; + final char finalChar; + final byte finalByte; + final float finalFloat; + final double finalDouble; + final boolean finalBoolean; + + private WithFinalFields() { + finalField = null; + finalChar = '\0'; + finalInt = 0; + finalLong = 0; + finalShort = 0; + finalByte = 0; + finalFloat = 0.0f; + finalDouble = 0.0; + finalBoolean = false; + } + + } + + public void testCanWriteFinalFields() { + WithFinalFields thingy = new WithFinalFields(); + reflectionProvider.writeField(thingy, "finalField", "zero", WithFinalFields.class); + assertEquals("zero", thingy.finalField); + + reflectionProvider.writeField(thingy, "finalInt", new Integer(1), WithFinalFields.class); + assertEquals(1, thingy.finalInt); + + reflectionProvider.writeField(thingy, "finalLong", new Long(2), WithFinalFields.class); + assertEquals(2, thingy.finalLong); + + reflectionProvider.writeField(thingy, "finalShort", new Short((short)3), WithFinalFields.class); + assertEquals(3, thingy.finalShort); + + reflectionProvider.writeField(thingy, "finalChar", new Character('4'), WithFinalFields.class); + assertEquals('4', thingy.finalChar); + + reflectionProvider.writeField(thingy, "finalByte", new Byte((byte)5), WithFinalFields.class); + assertEquals(5, thingy.finalByte); + + reflectionProvider.writeField(thingy, "finalFloat", new Float(0.6), WithFinalFields.class); + assertEquals(0.6f, thingy.finalFloat, 0.0); + + reflectionProvider.writeField(thingy, "finalDouble", new Double(0.7), WithFinalFields.class); + assertEquals(0.7, thingy.finalDouble, 0.0); + + reflectionProvider.writeField(thingy, "finalBoolean", new Boolean(true), WithFinalFields.class); + assertEquals(true, thingy.finalBoolean); + + reflectionProvider.writeField(thingy, "finalBoolean", new Boolean(false), null); + assertEquals(false, thingy.finalBoolean); + } + + protected static class Unistantiatable { + { + if (true) { + throw new IllegalStateException(""); + } + } + + public Unistantiatable() { + throw new IllegalStateException("ctor"); + } + + public Unistantiatable(String s) { + throw new IllegalStateException("ctor(String)"); + } + } + + public void testCanInstantiateWithoutInitializer() { + assertCanCreate(Unistantiatable.class); + } +} \ No newline at end of file diff --git a/xstream/src/test/com/thoughtworks/xstream/core/DefaultConverterLookupTest.java b/xstream/src/test/com/thoughtworks/xstream/core/DefaultConverterLookupTest.java new file mode 100644 index 0000000..3890259 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/core/DefaultConverterLookupTest.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. March 2004 by Mauro Talevi + */ +package com.thoughtworks.xstream.core; + +import java.util.BitSet; + +import junit.framework.TestCase; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.SingleValueConverterWrapper; +import com.thoughtworks.xstream.converters.basic.StringConverter; +import com.thoughtworks.xstream.converters.collections.BitSetConverter; + +/** + * @author Guilherme Silveira + */ +public class DefaultConverterLookupTest extends TestCase { + + public void testCanReplaceWithHigherPriority() { + + // this test actually depends on the keyset implementation of the corresponding cache map. + final DefaultConverterLookup lookup = new DefaultConverterLookup(); + Converter currentConverter = new SingleValueConverterWrapper(new StringConverter()); + lookup.registerConverter(new BitSetConverter(), XStream.PRIORITY_VERY_HIGH); + lookup.registerConverter(currentConverter, -100); + lookup.lookupConverterForType(String.class); + lookup.lookupConverterForType(BitSet.class); + assertEquals(lookup.lookupConverterForType(String.class), currentConverter); + Converter newConverter = new SingleValueConverterWrapper(new StringConverter()); + lookup.registerConverter(newConverter, 100); + assertEquals(lookup.lookupConverterForType(String.class), newConverter); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/core/JVMTest.java b/xstream/src/test/com/thoughtworks/xstream/core/JVMTest.java new file mode 100644 index 0000000..1c0dd92 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/core/JVMTest.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2012, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 23. July 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core; + +import junit.framework.TestCase; + +public class JVMTest extends TestCase { + + public void testDoesIgnoreLinkageErrors() { + try { + assertNull(JVM.loadClassForName("com.thoughtworks.xstream.core.EvilClass")); + } catch (LinkageError error) { + fail("Error thrown"); + } + } +} + +class EvilClass { + + static { + evil(); + } + + static void evil() { + throw new RuntimeException("Evil"); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/core/ReferenceByIDMarshallingStrategyTest.java b/xstream/src/test/com/thoughtworks/xstream/core/ReferenceByIDMarshallingStrategyTest.java new file mode 100644 index 0000000..90addea --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/core/ReferenceByIDMarshallingStrategyTest.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2006, 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.acceptance.someobjects.WithNamedList; +import com.thoughtworks.xstream.XStream; + +import java.util.ArrayList; + + +public class ReferenceByIDMarshallingStrategyTest extends AbstractAcceptanceTest { + + protected void setUp() throws Exception { + super.setUp(); + xstream.setMode(XStream.ID_REFERENCES); + } + + public void testIgnoresImplicitCollection() { + xstream.alias("strings", WithNamedList.class); + xstream.addImplicitCollection(WithNamedList.class, "things"); + WithNamedList wl = new WithNamedList("foo"); + wl.things.add("Hello"); + wl.things.add("Daniel"); + + final String expected = "" + + "\n" + + " Hello\n" + + " Daniel\n" + + " foo\n" + + ""; + + assertBothWays(wl, expected); + } + + static class List { + public Object o; + public ArrayList list = new ArrayList(); + } + + public void testIgnoresImplicitCollectionAtAnyFieldPosition() { + final List another = new List(); + another.o = new Object(); + another.list.add(new Object()); + xstream.addImplicitCollection(List.class, "list"); + xstream.alias("list", List.class); + + final String expected = "" + + "\n" + + " \n" + + " \n" + + ""; + + assertBothWays(another, expected); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/core/ReferenceByXPathMarshallingStrategyTest.java b/xstream/src/test/com/thoughtworks/xstream/core/ReferenceByXPathMarshallingStrategyTest.java new file mode 100644 index 0000000..8e42bf1 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/core/ReferenceByXPathMarshallingStrategyTest.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. April 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.XStream; + +import java.util.ArrayList; +import java.util.List; + + +public class ReferenceByXPathMarshallingStrategyTest extends AbstractAcceptanceTest { + + protected void setUp() throws Exception { + super.setUp(); + xstream.alias("thing", Thing.class); + } + + public static class Thing extends StandardObject { + private String name; + + public Thing() { + } + + public Thing(String name) { + this.name = name; + } + } + + public void testStoresReferencesUsingRelativeXPath() { + xstream.setMode(XStream.XPATH_RELATIVE_REFERENCES); + + Thing a = new Thing("a"); + Thing b = new Thing("b"); + Thing c = b; + + List list = new ArrayList(); + list.add(a); + list.add(b); + list.add(c); + + String expected = "" + + "\n" + + " \n" + + " a\n" + + " \n" + + " \n" + + " b\n" + + " \n" + + " \n" + // xpath + ""; + + assertBothWays(list, expected); + } + + public void testStoresReferencesUsingAbsoluteXPath() { + xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES); + + Thing a = new Thing("a"); + Thing b = new Thing("b"); + Thing c = b; + + List list = new ArrayList(); + list.add(a); + list.add(b); + list.add(c); + + String expected = "" + + "\n" + + " \n" + + " a\n" + + " \n" + + " \n" + + " b\n" + + " \n" + + " \n" + // xpath + ""; + + assertBothWays(list, expected); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/core/TreeMarshallerTest.java b/xstream/src/test/com/thoughtworks/xstream/core/TreeMarshallerTest.java new file mode 100644 index 0000000..20fde38 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/core/TreeMarshallerTest.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 25. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.xstream.XStream; + +public class TreeMarshallerTest extends AbstractAcceptanceTest { + + static class Thing { + Thing thing; + } + + protected void setUp() throws Exception { + super.setUp(); + xstream.setMode(XStream.NO_REFERENCES); + } + + public void testThrowsExceptionWhenDetectingCircularReferences() { + Thing a = new Thing(); + Thing b = new Thing(); + a.thing = b; + b.thing = a; + + try { + xstream.toXML(a); + fail("expected exception"); + } catch (TreeMarshaller.CircularReferenceException expected) { + // good + } + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/core/TreeUnmarshallerTest.java b/xstream/src/test/com/thoughtworks/xstream/core/TreeUnmarshallerTest.java new file mode 100644 index 0000000..c1ef1b8 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/core/TreeUnmarshallerTest.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 10. April 2005 by Mauro Talevi + */ +package com.thoughtworks.xstream.core; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; + +import java.util.ArrayList; +import java.util.List; + +public class TreeUnmarshallerTest extends AbstractAcceptanceTest { + + protected void setUp() throws Exception { + super.setUp(); + } + + public void testUnmarshallingOfAliasedInterfaces() { + xstream.alias("addressBookInfo", AddressBookInfo.class, AddressBook.class); + xstream.alias("addressInfo", AddressInfo.class, Address.class); + AddressBookInfo initialObject = new AddressBook(); + String marshalledXML = xstream.toXML(initialObject); + AddressBookInfo unmarshalledObject = (AddressBookInfo) xstream.fromXML(marshalledXML); + assertEquals(marshalledXML, xstream.toXML(unmarshalledObject)); + } + + public interface AddressBookInfo { + public List getAddresses(); + + public void setAddresses(List address); + } + + public static class AddressBook implements AddressBookInfo { + private List addresses; + + public AddressBook() { + addresses = new ArrayList(); + AddressInfo addr = new Address("Home", "Home"); + AddressInfo addr1 = new Address("Office", "Office"); + addresses.add(addr); + addresses.add(addr1); + } + + public List getAddresses() { + return addresses; + } + + public void setAddresses(List addresses) { + this.addresses = addresses; + } + } + + public interface AddressInfo { + public String getAddr1(); + + public String getAddr2(); + + public void setAddr1(String addr1); + + public void setAddr2(String addr2); + } + + public static class Address implements AddressInfo { + private String addr1 = "addr1"; + + private String addr2 = "addr2"; + + private Address() { + } + + public Address(String addr1, String addr2) { + this.addr1 = addr1; + this.addr2 = addr2; + } + + public String getAddr1() { + return addr1; + } + + public String getAddr2() { + return addr2; + } + + public void setAddr1(String addr1) { + this.addr1 = addr1; + } + + public void setAddr2(String addr2) { + this.addr2 = addr2; + } + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/core/util/Base64EncoderTest.java b/xstream/src/test/com/thoughtworks/xstream/core/util/Base64EncoderTest.java new file mode 100644 index 0000000..eff4d8e --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/core/util/Base64EncoderTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. August 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core.util; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; + +public class Base64EncoderTest extends AbstractAcceptanceTest { + + private Base64Encoder encoder = new Base64Encoder(); + + public void testEncodesEntireByteArrayAsString() { + byte input[] = "hello world".getBytes(); + String expected = "aGVsbG8gd29ybGQ="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testWrapsLinesAt76Chars() { + byte input[] = ("hello world. hello world. hello world. hello world. hello world. hello world. hello world. " + + "hello world. hello world. hello world. hello world. hello world. hello world. hello world. ").getBytes(); + String expected = "aGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxv\n" + + "IHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3Js\n" + + "ZC4gaGVsbG8gd29ybGQuIGhlbGxvIHdvcmxkLiBoZWxsbyB3b3JsZC4gaGVsbG8gd29ybGQuIGhl\n" + + "bGxvIHdvcmxkLiA="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testPadsSingleMissingByteWhenNotMultipleOfThree() { + byte input[] = { 1, 2, 3, 4, 5 }; + String expected = "AQIDBAU="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testPadsDoubleMissingByteWhenNotMultipleOfThree() { + byte input[] = { 1, 2, 3, 4 }; + String expected = "AQIDBA=="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testDoesNotPadWhenMultipleOfThree() { + byte input[] = { 1, 2, 3, 4, 5, 6 }; + String expected = "AQIDBAUG"; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testHandlesAllPositiveBytes() { + byte input[] = new byte[127]; + for (int i = 0; i < 126; i++) input[i] = (byte) (i + 1); + String expected = "AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5\n" + + "Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFy\n" + + "c3R1dnd4eXp7fH1+AA=="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testHandlesAllNegativeBytes() { + byte input[] = new byte[128]; + for (int i = 0; i < 127; i++) input[i] = (byte) (-1 - i); + String expected = "//79/Pv6+fj39vX08/Lx8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjH\n" + + "xsXEw8LBwL++vby7urm4t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI+O\n" + + "jYyLiomIh4aFhIOCgQA="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testHandlesZeroByte() { + byte input[] = { 0, 0, 0, 0 }; + String expected = "AAAAAA=="; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + + public void testProducesEmptyStringWhenNoBytesGiven() { + byte input[] = new byte[0]; + String expected = ""; + assertEquals(expected, encoder.encode(input)); + assertByteArrayEquals(input, encoder.decode(expected)); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/core/util/CloneablesTest.java b/xstream/src/test/com/thoughtworks/xstream/core/util/CloneablesTest.java new file mode 100644 index 0000000..5faeedf --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/core/util/CloneablesTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2010 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created 18.11.2010 by Joerg Schaible. + */ +package com.thoughtworks.xstream.core.util; + +import java.util.Arrays; + +import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; + +import junit.framework.TestCase; + + +public class CloneablesTest extends TestCase { + public void testCloneOfCloneable() { + final TypedNull stringNull = new CloneableTypedNull(String.class); + final TypedNull stringNullClone = (TypedNull)Cloneables.clone(stringNull); + assertSame(String.class, stringNullClone.getType()); + } + + public void testCloneOfNotCloneable() { + final TypedNull stringNull = new TypedNull(String.class); + assertNull(Cloneables.clone(stringNull)); + } + + public void testCloneOfUncloneable() { + final TypedNull stringNull = new UncloneableTypedNull(String.class); + try { + Cloneables.clone(stringNull); + fail("Thrown " + ObjectAccessException.class.getName() + " expected"); + } catch (final ObjectAccessException e) { + assertTrue(e.getCause() instanceof NoSuchMethodException); + } + } + + public void testPossibleCloneOfCloneable() { + final TypedNull stringNull = new CloneableTypedNull(String.class); + final TypedNull stringNullClone = (TypedNull)Cloneables.cloneIfPossible(stringNull); + assertSame(String.class, stringNullClone.getType()); + } + + public void testCloneOfStringArray() { + assertEquals( + Arrays.asList(new String[]{"string"}), + Arrays.asList((String[])Cloneables.clone(new String[]{"string"}))); + } + + public void testCloneOfPrimitiveArray() { + int[] clone = (int[])Cloneables.clone(new int[]{1}); + assertEquals(1, clone.length); + assertEquals(1, clone[0]); + } + + public void testPossibleCloneOfNotCloneable() { + final TypedNull stringNull = new TypedNull(String.class); + assertSame(stringNull, Cloneables.cloneIfPossible(stringNull)); + } + + static final class CloneableTypedNull extends TypedNull implements Cloneable { + CloneableTypedNull(final Class type) { + super(type); + } + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + } + + static final class UncloneableTypedNull extends TypedNull implements Cloneable { + UncloneableTypedNull(final Class type) { + super(type); + } + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/core/util/DependencyInjectionFactoryTest.java b/xstream/src/test/com/thoughtworks/xstream/core/util/DependencyInjectionFactoryTest.java new file mode 100644 index 0000000..de7c425 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/core/util/DependencyInjectionFactoryTest.java @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2007, 2009, 2010, 2011, 2012 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. March 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; + +import junit.framework.TestCase; + +import java.util.BitSet; + + +public class DependencyInjectionFactoryTest extends TestCase { + public void testDependencyInjectionWithMatchingParameterSequence() { + final BitSet used = new BitSet(); + final Exception exception = (Exception)DependencyInjectionFactory.newInstance( + ObjectAccessException.class, new Object[]{ + "The message", this, new RuntimeException("JUnit")}, used); + assertTrue(exception instanceof ObjectAccessException); + assertEquals("The message : JUnit", exception.getMessage()); + assertEquals("JUnit", ((ObjectAccessException)exception).getCause().getMessage()); + assertTrue(used.get(0)); + assertFalse(used.get(1)); + assertTrue(used.get(2)); + } + + public void testWillUseDefaultConstructor() { + final BitSet used = new BitSet(); + final String string = (String)DependencyInjectionFactory.newInstance( + String.class, new Object[]{this}, used); + assertEquals("", string); + assertFalse(used.get(0)); + } + + public void testWillMatchNullValue() { + final BitSet used = new BitSet(); + final Exception exception = (Exception)DependencyInjectionFactory.newInstance( + ObjectAccessException.class, new Object[]{ + new TypedNull(String.class), this, new RuntimeException("JUnit")}, used); + assertTrue(exception instanceof ObjectAccessException); + assertEquals("null : JUnit", exception.getMessage()); + assertTrue(used.get(0)); + assertFalse(used.get(1)); + assertTrue(used.get(2)); + } + + public void testWillMatchPrimitives() { + final BitSet used = new BitSet(); + final String string = (String)DependencyInjectionFactory.newInstance( + String.class, + new Object[]{"JUnit".getBytes(), new Integer(1), this, new Integer(4)}, used); + assertEquals("Unit", string); + assertTrue(used.get(0)); + assertTrue(used.get(1)); + assertFalse(used.get(2)); + assertTrue(used.get(3)); + } + + public void testWillUseArbitraryOrder() { + final BitSet used = new BitSet(); + final Exception exception = (Exception)DependencyInjectionFactory.newInstance( + ObjectAccessException.class, new Object[]{ + new RuntimeException("JUnit"), this, "The message"}, used); + assertTrue(exception instanceof ObjectAccessException); + assertEquals("The message : JUnit", exception.getMessage()); + assertTrue(used.get(0)); + assertFalse(used.get(1)); + assertTrue(used.get(2)); + } + + public void testWillMatchMostSpecificDependency() { + final BitSet used = new BitSet(); + final Exception exception = (Exception)DependencyInjectionFactory.newInstance( + ObjectAccessException.class, new Object[]{ + new RuntimeException("JUnit"), new IllegalArgumentException("foo"), this, + "The message"}, used); + assertTrue(exception instanceof ObjectAccessException); + assertEquals("The message : foo", exception.getMessage()); + assertFalse(used.get(0)); + assertTrue(used.get(1)); + assertFalse(used.get(2)); + assertTrue(used.get(3)); + } + + public void testWillMatchFirstMatchingDependency() { + final BitSet used = new BitSet(); + final Exception exception = (Exception)DependencyInjectionFactory.newInstance( + ObjectAccessException.class, new Object[]{ + new RuntimeException("JUnit"), "The message", "bar", + new IllegalArgumentException("foo"), this}, used); + assertTrue(exception instanceof ObjectAccessException); + assertEquals("The message : foo", exception.getMessage()); + assertFalse(used.get(0)); + assertTrue(used.get(1)); + assertFalse(used.get(2)); + assertTrue(used.get(3)); + assertFalse(used.get(4)); + } + + static class Thing { + final TestCase testCase; + final int first; + final int second; + + public Thing() { + this(1, 2, null); + } + + public Thing(Number num) { + this(num.intValue(), 8 * num.intValue(), null); + } + + public Thing(String str, TestCase testCase) { + this(str.length(), 4 * str.length(), testCase); + } + + public Thing(Number num, TestCase testCase) { + this(num.intValue(), 4 * num.intValue(), testCase); + } + + public Thing(int first, int second, TestCase testCase) { + this.first = first; + this.second = second; + this.testCase = testCase; + } + + TestCase getTestCase() { + return testCase; + } + + int getFirst() { + return first; + } + + int getSecond() { + return second; + } + } + + public void testWillMatchArbitraryOrderForOneAvailableConstructorOnly() { + final BitSet used = new BitSet(); + final Thing thing = (Thing)DependencyInjectionFactory.newInstance( + Thing.class, new Object[]{this, new Integer(1), new Integer(2)}, used); + assertSame(this, thing.getTestCase()); + assertEquals(1, thing.getFirst()); + assertEquals(2, thing.getSecond()); + assertTrue(used.get(0)); + assertTrue(used.get(1)); + assertTrue(used.get(2)); + } + + public void testWillSelectMatchingConstructor() { + BitSet used = new BitSet(); + Thing thing = (Thing)DependencyInjectionFactory.newInstance( + Thing.class, new Object[]{this, new Integer(1)}, used); + assertSame(this, thing.getTestCase()); + assertEquals(1, thing.getFirst()); + assertEquals(4, thing.getSecond()); + assertTrue(used.get(0)); + assertTrue(used.get(1)); + + used = new BitSet(); + thing = (Thing)DependencyInjectionFactory.newInstance( + Thing.class, new Object[]{this, "a"}, used); + assertSame(this, thing.getTestCase()); + assertEquals(1, thing.getFirst()); + assertEquals(4, thing.getSecond()); + assertTrue(used.get(0)); + assertTrue(used.get(1)); + } + + public void testWillSelectMatchingConstructorForFirstMatchingArguments() { + BitSet used = new BitSet(); + Thing thing = (Thing)DependencyInjectionFactory.newInstance( + Thing.class, new Object[]{this, new Integer(1), "foo"}, used); + assertSame(this, thing.getTestCase()); + assertEquals(1, thing.getFirst()); + assertEquals(4, thing.getSecond()); + assertTrue(used.get(0)); + assertTrue(used.get(1)); + assertFalse(used.get(2)); + + used = new BitSet(); + thing = (Thing)DependencyInjectionFactory.newInstance( + Thing.class, new Object[]{this, "foo", new Integer(1)}, used); + assertSame(this, thing.getTestCase()); + assertEquals(3, thing.getFirst()); + assertEquals(12, thing.getSecond()); + assertTrue(used.get(0)); + assertTrue(used.get(1)); + assertFalse(used.get(2)); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/core/util/FastStackTest.java b/xstream/src/test/com/thoughtworks/xstream/core/util/FastStackTest.java new file mode 100644 index 0000000..126dba2 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/core/util/FastStackTest.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 02. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core.util; + +import junit.framework.TestCase; + +public class FastStackTest extends TestCase { + + public void test() { + FastStack stack = new FastStack(2); + + stack.push("a"); + stack.push("b"); + stack.push("c"); + stack.push("d"); + + assertEquals("d", stack.peek()); + assertEquals("d", stack.peek()); + assertEquals("d", stack.pop()); + assertEquals("c", stack.pop()); + stack.popSilently(); + assertEquals("a", stack.peek()); + assertEquals("a", stack.pop()); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/core/util/ObjectIdDictionaryTest.java b/xstream/src/test/com/thoughtworks/xstream/core/util/ObjectIdDictionaryTest.java new file mode 100644 index 0000000..a96ce9b --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/core/util/ObjectIdDictionaryTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2010, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. May 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.core.util; + +import junit.framework.TestCase; + +public class ObjectIdDictionaryTest extends TestCase { + + public void testMapsIdsToObjectReferences() { + final ObjectIdDictionary dict = new ObjectIdDictionary(); + final Object a = new Object(); + final Object b = new Object(); + final Object c = new Object(); + dict.associateId(a, "id a"); + dict.associateId(b, "id b"); + dict.associateId(c, "id c"); + assertEquals("id a", dict.lookupId(a)); + assertEquals("id b", dict.lookupId(b)); + assertEquals("id c", dict.lookupId(c)); + } + + public void testTreatsObjectsThatAreEqualButNotSameInstanceAsDifferentReference() { + final ObjectIdDictionary dict = new ObjectIdDictionary(); + final Integer a = new Integer(3); + final Integer b = new Integer(3); + dict.associateId(a, "id a"); + dict.associateId(b, "id b"); + assertEquals("id a", dict.lookupId(a)); + assertEquals("id b", dict.lookupId(b)); + } + + public void testEntriesAreGarbageCollected() throws InterruptedException { + final ObjectIdDictionary dict = new ObjectIdDictionary(); + + int counter = 0; + for (; counter < 1000; ++counter) { + final String s = new String("JUnit " + counter); // enforce new object + assertFalse("Failed in (" + counter + ")", dict.containsId(s)); + dict.associateId(s, "X"); + if (counter % 50 == 49) { + System.gc(); + Thread.sleep(10); + } + } + int size = dict.size(); + assertTrue("Dictionary did not shrink; " + + counter + + " distinct objects; " + + size + + " size", dict.size() < 250); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/core/util/OrderRetainingMapTest.java b/xstream/src/test/com/thoughtworks/xstream/core/util/OrderRetainingMapTest.java new file mode 100644 index 0000000..5e9d40a --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/core/util/OrderRetainingMapTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. February 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.core.util; + +import junit.framework.TestCase; + +import java.util.Iterator; +import java.util.Map; + +public class OrderRetainingMapTest extends TestCase { + private Map map; + + private void assertNextEquals(Object expected, Iterator iterator) { + assertTrue("Expected to pull of another item from iterator : " + expected, iterator.hasNext()); + assertEquals(expected, iterator.next()); + } + + private void assertNextEntryEquals(Object expectedKey, Object expectedValue, Iterator iterator) { + assertTrue("Expected to pull of another item from iterator : " + expectedKey + "=" + expectedValue, iterator.hasNext()); + Map.Entry actual = (Map.Entry) iterator.next(); + assertEquals(expectedKey, actual.getKey()); + assertEquals(expectedValue, actual.getValue()); + } + + private void assertNoMore(Iterator iterator) { + assertFalse("Should be no more items in iterator", iterator.hasNext()); + } + + protected void setUp() throws Exception { + super.setUp(); + map = new OrderRetainingMap(); + map.put("one", "ONE"); + map.put("two", "TWO"); + map.put("three", "THREE"); + map.put("four", "FOUR"); + } + + public void testMaintainsOrderOfKeySet() { + Iterator keySetIterator = map.keySet().iterator(); + assertNextEquals("one", keySetIterator); + assertNextEquals("two", keySetIterator); + assertNextEquals("three", keySetIterator); + assertNextEquals("four", keySetIterator); + assertNoMore(keySetIterator); + } + + public void testMaintainsOrderOfValues() { + Iterator valuesIterator = map.values().iterator(); + assertNextEquals("ONE", valuesIterator); + assertNextEquals("TWO", valuesIterator); + assertNextEquals("THREE", valuesIterator); + assertNextEquals("FOUR", valuesIterator); + assertNoMore(valuesIterator); + } + + public void testMaintainsOrderOfEntries() { + Iterator entrySetIterator = map.entrySet().iterator(); + assertNextEntryEquals("one", "ONE", entrySetIterator); + assertNextEntryEquals("two", "TWO", entrySetIterator); + assertNextEntryEquals("three", "THREE", entrySetIterator); + assertNextEntryEquals("four", "FOUR", entrySetIterator); + assertNoMore(entrySetIterator); + } + + public void testMaintainsOrderOfEntriesAfterCopyCtor() { + Iterator entrySetIterator = new OrderRetainingMap(map).entrySet().iterator(); + assertNextEntryEquals("one", "ONE", entrySetIterator); + assertNextEntryEquals("two", "TWO", entrySetIterator); + assertNextEntryEquals("three", "THREE", entrySetIterator); + assertNextEntryEquals("four", "FOUR", entrySetIterator); + assertNoMore(entrySetIterator); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/core/util/PrioritizedListTest.java b/xstream/src/test/com/thoughtworks/xstream/core/util/PrioritizedListTest.java new file mode 100644 index 0000000..08797fa --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/core/util/PrioritizedListTest.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. February 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.core.util; + +import junit.framework.TestCase; + +import java.util.Iterator; + +public class PrioritizedListTest extends TestCase { + + private void assertNextEquals(Object expected, Iterator iterator) { + assertTrue("Expected to pull of another item from iterator : " + expected, iterator.hasNext()); + assertEquals(expected, iterator.next()); + } + + private void assertNoMore(Iterator iterator) { + assertFalse("Should be no more items in iterator", iterator.hasNext()); + } + + public void testIteratesOverElementsInReverseOrderTheyWereAdded() { + PrioritizedList list = new PrioritizedList(); + list.add("one", 0); + list.add("two", 0); + list.add("three", 0); + + Iterator iterator = list.iterator(); + assertNextEquals("three", iterator); + assertNextEquals("two", iterator); + assertNextEquals("one", iterator); + assertNoMore(iterator); + } + + public void testHandlesMultipleIsolatedIterators() { + PrioritizedList list = new PrioritizedList(); + list.add("one", 0); + list.add("two", 0); + + Iterator iteratorOne = list.iterator(); + assertNextEquals("two", iteratorOne); + + Iterator iteratorTwo = list.iterator(); + assertNextEquals("one", iteratorOne); + + assertNextEquals("two", iteratorTwo); + assertNextEquals("one", iteratorTwo); + + assertNoMore(iteratorTwo); + assertNoMore(iteratorOne); + } + + public void testIteratesOverHighestPriorityItemsFirst() { + PrioritizedList list = new PrioritizedList(); + list.add("medium one", 0); + list.add("high one", 1); + list.add("low one", -1); + list.add("very high", 4); + list.add("low two", -1); + list.add("medium two", 0); + list.add("VERY VERY high", 100); + list.add("high two", 1); + list.add("very low", -4); + list.add("VERY VERY low", -100); + + Iterator iterator = list.iterator(); + assertNextEquals("VERY VERY high", iterator); + assertNextEquals("very high", iterator); + assertNextEquals("high two", iterator); + assertNextEquals("high one", iterator); + assertNextEquals("medium two", iterator); + assertNextEquals("medium one", iterator); + assertNextEquals("low two", iterator); + assertNextEquals("low one", iterator); + assertNextEquals("very low", iterator); + assertNextEquals("VERY VERY low", iterator); + assertNoMore(iterator); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/core/util/QuickWriterTest.java b/xstream/src/test/com/thoughtworks/xstream/core/util/QuickWriterTest.java new file mode 100644 index 0000000..51c06d9 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/core/util/QuickWriterTest.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. September 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +import java.io.StringWriter; + +import junit.framework.TestCase; + + +/** + * @author Jörg Schaible + */ +public class QuickWriterTest extends TestCase { + + public void testUnbuffered() { + StringWriter stringWriter = new StringWriter(); + QuickWriter writer = new QuickWriter(stringWriter, 0); + writer.write("Joe"); + assertEquals(stringWriter.toString(), "Joe"); + writer.write(' '); + assertEquals(stringWriter.toString(), "Joe "); + writer.write("Walnes".toCharArray()); + assertEquals(stringWriter.toString(), "Joe Walnes"); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/core/util/ThreadSafeSimpleDateFormatTest.java b/xstream/src/test/com/thoughtworks/xstream/core/util/ThreadSafeSimpleDateFormatTest.java new file mode 100644 index 0000000..696f367 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/core/util/ThreadSafeSimpleDateFormatTest.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2006, 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 14. October 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +import junit.framework.TestCase; + +import java.text.ParseException; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.TimeZone; + +/** + * @author Jörg Schaible + */ +public class ThreadSafeSimpleDateFormatTest extends TestCase { + public void testConcurrentDateFormatting() throws InterruptedException { + + final ThreadSafeSimpleDateFormat format = new ThreadSafeSimpleDateFormat( + "yyyy-MM-dd HH:mm:ss,S z", TimeZone.getTimeZone("UTC"), 2, 4, false); + final Date now = new Date(); + + final Map exceptions = new HashMap(); + final ThreadGroup tg = new ThreadGroup(getName()) { + public void uncaughtException(Thread t, Throwable e) { + exceptions.put(e, t.getName()); + super.uncaughtException(t, e); + } + }; + + final int[] counter = new int[1]; + counter[0] = 0; + final Thread[] threads = new Thread[10]; + for (int i = 0; i < threads.length; ++i) { + threads[i] = new Thread(tg, "JUnit Thread " + i) { + + public void run() { + int i = 0; + try { + synchronized (this) { + notifyAll(); + wait(); + } + while (i < 1000 && !interrupted()) { + String formatted = format.format(now); + Thread.yield(); + assertEquals(now, format.parse(formatted)); + ++i; + } + } catch (InterruptedException e) { + fail("Unexpected InterruptedException"); + } catch (ParseException e) { + fail("Unexpected ParseException"); + } + synchronized (counter) { + counter[0] += i; + } + } + + }; + } + + for (int i = 0; i < threads.length; ++i) { + synchronized (threads[i]) { + threads[i].start(); + threads[i].wait(); + } + } + + for (int i = 0; i < threads.length; ++i) { + synchronized (threads[i]) { + threads[i].notifyAll(); + } + } + + Thread.sleep(1500); + + for (int i = 0; i < threads.length; ++i) { + threads[i].interrupt(); + } + for (int i = 0; i < threads.length; ++i) { + synchronized (threads[i]) { + threads[i].join(); + } + } + + assertEquals("Exceptions have been thrown: " + exceptions, 0, exceptions.size()); + assertTrue("Each thread should have made at least 1 conversion", counter[0] >= threads.length); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/core/util/WeakCacheTest.java b/xstream/src/test/com/thoughtworks/xstream/core/util/WeakCacheTest.java new file mode 100644 index 0000000..58cac21 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/core/util/WeakCacheTest.java @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. July 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +import java.io.File; +import java.lang.ref.PhantomReference; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import junit.framework.TestCase; + +/** + * @author Jörg Schaible + */ +public class WeakCacheTest extends TestCase { + + public void testIsAMap() { + Map map = new WeakCache(); + assertEquals(0, map.size()); + assertNull(map.put("key", "value")); + assertEquals(1, map.size()); + assertEquals("value", map.get("key")); + assertTrue(map.containsKey(new String("key"))); + assertTrue(map.containsValue(new String("value"))); + assertEquals("value", map.values().iterator().next()); + assertEquals("key", map.keySet().iterator().next()); + assertEquals("value", ((Map.Entry)map.entrySet().iterator().next()).getValue()); + assertEquals("key", ((Map.Entry)map.entrySet().iterator().next()).getKey()); + assertEquals("value", map.put("key", "test")); + Map copy = new HashMap(map); + assertEquals("test", map.remove("key")); + assertEquals(0, map.size()); + map.putAll(copy); + assertEquals(1, map.size()); + assertEquals("test", map.get("key")); + map.clear(); + assertEquals(0, map.size()); + } + + public void testEntriesAreRemovedIfKeyIsGarbageCollected() throws InterruptedException { + String key = new String("key"); + ReferenceQueue refQueue = new ReferenceQueue(); + Reference ref = new PhantomReference(key, refQueue); + + Map map = new WeakCache(); + map.put(key, "value"); + key = null; + + int i = 0; + while (refQueue.poll() == null) { + ref.get(); // always null + assertTrue("Key still alive even after "+i+" forced garbage collections", i++ < 5); + Thread.sleep(10); + System.gc(); + } + assertEquals(0, map.size()); + } + + public void testSelfReferencingEntriesAreRemovedIfKeyIsGarbageCollected() throws InterruptedException { + String key = new String("key"); + ReferenceQueue refQueue = new ReferenceQueue(); + Reference ref = new PhantomReference(key, refQueue); + + Map map = new WeakCache(); + map.put(key, Collections.singleton(key)); + key = null; + + int i = 0; + while (refQueue.poll() == null) { + ref.get(); // always null + assertTrue("Key still alive even after "+i+" forced garbage collections", i++ < 5); + Thread.sleep(10); + System.gc(); + } + assertEquals(0, map.size()); + } + + public void testEntriesAreRemovedIfValueIsGarbageCollected() throws InterruptedException { + String value = new String("value"); + ReferenceQueue refQueue = new ReferenceQueue(); + Reference ref = new PhantomReference(value, refQueue); + + Map map = new WeakCache(); + map.put("key", value); + value = null; + + int i = 0; + while (refQueue.poll() == null) { + ref.get(); // always null + assertTrue("Value still alive even after "+i+" forced garbage collections", i++ < 5); + Thread.sleep(10); + System.gc(); + } + assertEquals(0, map.size()); + } + + public void testSelfReferencingEntriesAreRemovedIfValueIsGarbageCollected() throws InterruptedException { + String key = new String("key"); + Set value = Collections.singleton(key); + ReferenceQueue refQueue = new ReferenceQueue(); + Reference ref = new PhantomReference(value, refQueue); + + Map map = new WeakCache(); + map.put(key, value); + value = null; + + int i = 0; + while (refQueue.poll() == null) { + ref.get(); // always null + assertTrue("Value still alive even after "+i+" forced garbage collections", i++ < 5); + Thread.sleep(10); + System.gc(); + } + assertEquals(0, map.size()); + } + + public void testSelfReferencingEntriesWithObjectsFromPermSpace() throws MalformedURLException, ClassNotFoundException, SecurityException, NoSuchFieldException, InterruptedException { + File proxyToys = new File("target/lib/proxytoys-0.2.1.jar"); + ClassLoader classLoader = new URLClassLoader(new URL[]{proxyToys.toURI().toURL()}, getClass().getClassLoader()); + Class simpleReferenceType = Class.forName("com.thoughtworks.proxy.kit.SimpleReference", true, classLoader); + Field instance = simpleReferenceType.getDeclaredField("instance"); + + ReferenceQueue refQueue = new ReferenceQueue(); + Reference ref = new PhantomReference(instance, refQueue); + + Map map = new WeakCache(); + map.put(simpleReferenceType, instance); + simpleReferenceType = null; + instance = null; + + int i = 0; + while (refQueue.poll() == null) { + ref.get(); // always null + //assertTrue("Value still alive even after "+i+" forced garbage collections", i++ < 5); + if (i++ >= 10) { + // actually never reached - unfortunately + break; + } + Thread.sleep(10); + System.gc(); + } + // wanted is 1 :-/ + //assertEquals(1, map.size()); + assertEquals(0, map.size()); + } + + public void testCanUseDifferentMapImplementation() throws InterruptedException { + String value = new String("value"); + ReferenceQueue refQueue = new ReferenceQueue(); + Reference ref = new PhantomReference(value, refQueue); + + Map map = new WeakCache(new TreeMap()); + map.put("key", value); + value = null; + + int i = 0; + while (refQueue.poll() == null) { + ref.get(); // always null + assertTrue("Value still alive even after "+i+" forced garbage collections", i++ < 5); + Thread.sleep(10); + System.gc(); + } + assertEquals(0, map.size()); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/core/util/XmlHeaderAwareReaderTest.java b/xstream/src/test/com/thoughtworks/xstream/core/util/XmlHeaderAwareReaderTest.java new file mode 100644 index 0000000..a20d415 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/core/util/XmlHeaderAwareReaderTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2007, 2008, 2010 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.core.util; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.io.PushbackInputStream; + +import junit.framework.TestCase; + + +/** + * @author Jörg Schaible + */ +public class XmlHeaderAwareReaderTest extends TestCase { + + public void testKeepsAllBytesInStream() throws IOException { + ByteArrayInputStream in = new ByteArrayInputStream("\n".getBytes("us-ascii")); + LineNumberReader reader = new LineNumberReader(new XmlHeaderAwareReader(in)); + assertEquals("", reader.readLine()); + assertEquals("", reader.readLine()); + } + + public void testDefaultValues() throws IOException { + ByteArrayInputStream in = new ByteArrayInputStream("\n".getBytes("us-ascii")); + XmlHeaderAwareReader reader = new XmlHeaderAwareReader(in); + assertEquals(1.0, reader.getVersion(), 0.001); + assertEquals(new InputStreamReader(in, "utf-8").getEncoding(), reader.getEncoding()); + } + + public void testEvaluatesVersion() throws IOException { + ByteArrayInputStream in = new ByteArrayInputStream("\n".getBytes("us-ascii")); + XmlHeaderAwareReader reader = new XmlHeaderAwareReader(in); + assertEquals(1.1, reader.getVersion(), 0.001); + } + + public void testEvaluatesEncoding() throws IOException { + ByteArrayInputStream in = new ByteArrayInputStream("".getBytes("us-ascii")); + XmlHeaderAwareReader reader = new XmlHeaderAwareReader(in); + assertEquals(new InputStreamReader(in, "iso-8859-15").getEncoding(), reader.getEncoding()); + } + + public void testValueEscaping() throws IOException { + ByteArrayInputStream in = new ByteArrayInputStream("".getBytes("us-ascii")); + XmlHeaderAwareReader reader = new XmlHeaderAwareReader(in); + assertEquals(1.1, reader.getVersion(), 0.001); + } + + public void testCanHandleImproperSizedPushbackInputStream() throws IOException { + InputStream in = new ByteArrayInputStream("".getBytes("us-ascii")); + XmlHeaderAwareReader reader = new XmlHeaderAwareReader(new PushbackInputStream(in, 1)); + assertEquals(1.1, reader.getVersion(), 0.001); + } + + public void testSkipsUtf8BOM() throws IOException { + byte[] bytes = "".getBytes("us-ascii"); + byte[] inBytes = new byte[bytes.length+3]; + inBytes[0] = (byte)0xEF; + inBytes[1] = (byte)0xBB; + inBytes[2] = (byte)0xBF; + System.arraycopy(bytes, 0, inBytes, 3, bytes.length); + ByteArrayInputStream in = new ByteArrayInputStream(bytes); + XmlHeaderAwareReader reader = new XmlHeaderAwareReader(in); + assertEquals(new InputStreamReader(in, "utf-8").getEncoding(), reader.getEncoding()); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/DriverEndToEndTestSuite.java b/xstream/src/test/com/thoughtworks/xstream/io/DriverEndToEndTestSuite.java new file mode 100644 index 0000000..2022d43 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/DriverEndToEndTestSuite.java @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.io; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.util.ArrayList; + +import com.thoughtworks.acceptance.objects.SampleLists; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.converters.collections.CollectionConverter; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.io.binary.BinaryStreamDriver; +import com.thoughtworks.xstream.io.xml.BEAStaxDriver; +import com.thoughtworks.xstream.io.xml.Dom4JDriver; +import com.thoughtworks.xstream.io.xml.DomDriver; +import com.thoughtworks.xstream.io.xml.JDomDriver; +import com.thoughtworks.xstream.io.xml.KXml2DomDriver; +import com.thoughtworks.xstream.io.xml.KXml2Driver; +import com.thoughtworks.xstream.io.xml.StaxDriver; +import com.thoughtworks.xstream.io.xml.WstxDriver; +import com.thoughtworks.xstream.io.xml.XomDriver; +import com.thoughtworks.xstream.io.xml.Xpp3DomDriver; +import com.thoughtworks.xstream.io.xml.Xpp3Driver; +import com.thoughtworks.xstream.io.xml.XppDomDriver; +import com.thoughtworks.xstream.io.xml.XppDriver; + +import junit.framework.Assert; +import junit.framework.AssertionFailedError; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public class DriverEndToEndTestSuite extends TestSuite { + + public static Test suite() { + return new DriverEndToEndTestSuite(); + } + + public DriverEndToEndTestSuite() { + super(DriverEndToEndTestSuite.class.getName()); + addDriverTest(new BEAStaxDriver()); + addDriverTest(new BinaryStreamDriver()); + addDriverTest(new Dom4JDriver()); + addDriverTest(new DomDriver()); + addDriverTest(new JDomDriver()); + if (JVM.is15()) { + Class driverType = JVM.loadClassForName("com.thoughtworks.xstream.io.xml.JDom2Driver"); + try { + addDriverTest((HierarchicalStreamDriver)driverType.newInstance()); + } catch (InstantiationException e) { + throw new AssertionFailedError("Cannot instantiate " + driverType.getName()); + } catch (IllegalAccessException e) { + throw new AssertionFailedError("Cannot access default constructor of " + driverType.getName()); + } + } + addDriverTest(new KXml2DomDriver()); + addDriverTest(new KXml2Driver()); + addDriverTest(new StaxDriver()); + if (JVM.is16()) { + Class driverType = JVM.loadClassForName("com.thoughtworks.xstream.io.xml.StandardStaxDriver"); + try { + addDriverTest((HierarchicalStreamDriver)driverType.newInstance()); + } catch (InstantiationException e) { + throw new AssertionFailedError("Cannot instantiate " + driverType.getName()); + } catch (IllegalAccessException e) { + throw new AssertionFailedError("Cannot access default constructor of " + driverType.getName()); + } + } + addDriverTest(new WstxDriver()); + addDriverTest(new XomDriver()); + addDriverTest(new Xpp3DomDriver()); + addDriverTest(new Xpp3Driver()); + addDriverTest(new XppDomDriver()); + addDriverTest(new XppDriver()); + if (JVM.is14()) { + Class driverType = JVM.loadClassForName("com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver"); + try { + addDriverTest((HierarchicalStreamDriver)driverType.newInstance()); + } catch (InstantiationException e) { + throw new AssertionFailedError("Cannot instantiate " + driverType.getName()); + } catch (IllegalAccessException e) { + throw new AssertionFailedError("Cannot access default constructor of " + driverType.getName()); + } + } + } + + private void test(HierarchicalStreamDriver driver) { + XStream xstream = new XStream(driver); + xstream.registerConverter(new CollectionConverter(xstream.getMapper()) { + + public Object unmarshal(HierarchicalStreamReader reader, + UnmarshallingContext context) { + ExtendedHierarchicalStreamReader exReader = (ExtendedHierarchicalStreamReader)reader; + if (exReader.peekNextChild() == null) { + return new ArrayList(); + } + return super.unmarshal(reader, context); + } + + }); + + SampleLists in = new SampleLists(); + in.good.add("one"); + in.good.add("two"); + in.good.add("three"); + in.bad.add(Boolean.TRUE); + in.bad.add(Boolean.FALSE); + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + xstream.toXML(in, buffer); + Object out = xstream.fromXML(new ByteArrayInputStream(buffer.toByteArray())); + + Assert.assertEquals(in, out); + } + + private void addDriverTest(final HierarchicalStreamDriver driver) { + String testName = getShortName(driver); + addTest(new TestCase(testName) { + protected void runTest() throws Throwable { + test(driver); + } + }); + } + + private String getShortName(HierarchicalStreamDriver driver) { + String result = driver.getClass().getName(); + result = result.substring(result.lastIndexOf('.') + 1); + return result; + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/StatefulWriterTest.java b/xstream/src/test/com/thoughtworks/xstream/io/StatefulWriterTest.java new file mode 100644 index 0000000..716765f --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/StatefulWriterTest.java @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. March 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.io; + +import com.thoughtworks.xstream.io.xml.CompactWriter; + +import junit.framework.TestCase; + +import java.io.IOException; +import java.io.StringWriter; + + +/** + * @author Jörg Schaible + */ +public class StatefulWriterTest extends TestCase { + + private StatefulWriter writer; + private StringWriter stringWriter; + + protected void setUp() throws Exception { + super.setUp(); + stringWriter = new StringWriter(); + writer = new StatefulWriter(new CompactWriter(stringWriter)); + } + + public void testDelegatesAllCalls() { + writer.startNode("junit"); + writer.addAttribute("test", "true"); + writer.setValue("foo"); + writer.endNode(); + writer.close(); + assertEquals("foo", stringWriter.toString()); + } + + public void testKeepsBlance() { + writer.startNode("junit"); + writer.endNode(); + try { + writer.endNode(); + fail("Thrown " + StreamException.class.getName() + " expected"); + } catch (final StreamException e) { + assertTrue(e.getCause() instanceof IllegalStateException); + } + } + + public void testCanOnlyWriteAttributesToOpenNode() { + try { + writer.addAttribute("test", "true"); + fail("Thrown " + StreamException.class.getName() + " expected"); + } catch (final StreamException e) { + assertTrue(e.getCause() instanceof IllegalStateException); + } + writer.startNode("junit"); + writer.setValue("text"); + try { + writer.addAttribute("test", "true"); + fail("Thrown " + StreamException.class.getName() + " expected"); + } catch (final StreamException e) { + assertTrue(e.getCause() instanceof IllegalStateException); + } + writer.endNode(); + try { + writer.addAttribute("test", "true"); + fail("Thrown " + StreamException.class.getName() + " expected"); + } catch (final StreamException e) { + assertTrue(e.getCause() instanceof IllegalStateException); + } + } + + public void testCanWriteAttributesOnlyOnce() { + writer.startNode("junit"); + writer.addAttribute("test", "true"); + try { + writer.addAttribute("test", "true"); + fail("Thrown " + StreamException.class.getName() + " expected"); + } catch (final StreamException e) { + assertTrue(e.getCause() instanceof IllegalStateException); + } + writer.endNode(); + } + + public void testCanWriteValueOnlyToOpenNode() { + try { + writer.setValue("test"); + fail("Thrown " + StreamException.class.getName() + " expected"); + } catch (final StreamException e) { + assertTrue(e.getCause() instanceof IllegalStateException); + } + writer.startNode("junit"); + writer.endNode(); + try { + writer.setValue("test"); + fail("Thrown " + StreamException.class.getName() + " expected"); + } catch (final StreamException e) { + assertTrue(e.getCause() instanceof IllegalStateException); + } + } + + public void testCannotOpenNodeInValue() { + writer.startNode("junit"); + writer.setValue("test"); + try { + writer.startNode("junit"); + fail("Thrown " + StreamException.class.getName() + " expected"); + } catch (final StreamException e) { + assertTrue(e.getCause() instanceof IllegalStateException); + } + } + + public void testCanCloseInFinally() { + try { + writer.endNode(); + fail("Thrown " + StreamException.class.getName() + " expected"); + } catch (final StreamException e) { + writer.close(); + } + } + + public void testCannotWriteAfterClose() { + writer.close(); + try { + writer.startNode("junit"); + fail("Thrown " + StreamException.class.getName() + " expected"); + } catch (final StreamException e) { + assertTrue(e.getCause() instanceof IOException); + } + try { + writer.addAttribute("junit", "test"); + fail("Thrown " + StreamException.class.getName() + " expected"); + } catch (final StreamException e) { + assertTrue(e.getCause() instanceof IOException); + } + try { + writer.setValue("test"); + fail("Thrown " + StreamException.class.getName() + " expected"); + } catch (final StreamException e) { + assertTrue(e.getCause() instanceof IOException); + } + try { + writer.endNode(); + fail("Thrown " + StreamException.class.getName() + " expected"); + } catch (final StreamException e) { + assertTrue(e.getCause() instanceof IOException); + } + try { + writer.flush(); + fail("Thrown " + StreamException.class.getName() + " expected"); + } catch (final StreamException e) { + assertTrue(e.getCause() instanceof IOException); + } + } + + public void testCanCloseTwice() { + writer.close(); + writer.close(); + } + + public void testCaresAboutNestingLevelWritingAttributes() { + writer.startNode("junit"); + writer.addAttribute("test", "true"); + writer.startNode("junit"); + writer.addAttribute("test", "true"); + writer.endNode(); + writer.endNode(); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/binary/BinaryStreamTest.java b/xstream/src/test/com/thoughtworks/xstream/io/binary/BinaryStreamTest.java new file mode 100644 index 0000000..ba347af --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/binary/BinaryStreamTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. June 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.io.binary; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.copy.HierarchicalStreamCopier; +import com.thoughtworks.xstream.io.xml.AbstractXMLReaderTest; +import com.thoughtworks.xstream.io.xml.Xpp3Driver; + +import java.io.ByteArrayOutputStream; +import java.io.StringReader; +import java.io.ByteArrayInputStream; + +public class BinaryStreamTest extends AbstractXMLReaderTest { + + private HierarchicalStreamCopier copier = new HierarchicalStreamCopier(); + + protected void setUp() throws Exception { + super.setUp(); + } + + // factory method + protected HierarchicalStreamReader createReader(String xml) throws Exception { + // Transmogrify XML input into binary format. + HierarchicalStreamReader xmlReader = + new Xpp3Driver().createReader(new StringReader(xml)); + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + HierarchicalStreamWriter binaryWriter = new BinaryStreamWriter(buffer); + copier.copy(xmlReader, binaryWriter); + + return new BinaryStreamReader(new ByteArrayInputStream(buffer.toByteArray())); + } + + public void testHandlesMoreThan256Ids() { + int count = 500; + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + HierarchicalStreamWriter binaryWriter = new BinaryStreamWriter(buffer); + binaryWriter.startNode("root"); + for (int i = 0; i < count; i++) { + binaryWriter.startNode("node" + i); + binaryWriter.endNode(); + } + for (int i = 0; i < count; i++) { + binaryWriter.startNode("node" + i); + binaryWriter.endNode(); + } + binaryWriter.endNode(); + + HierarchicalStreamReader binaryReader + = new BinaryStreamReader(new ByteArrayInputStream(buffer.toByteArray())); + assertEquals("root", binaryReader.getNodeName()); + for (int i = 0; i < count; i++) { + assertTrue("Expected child " + i, binaryReader.hasMoreChildren()); + binaryReader.moveDown(); + assertEquals("node" + i, binaryReader.getNodeName()); + binaryReader.moveUp(); + } + for (int i = 0; i < count; i++) { + assertTrue("Expected child " + i, binaryReader.hasMoreChildren()); + binaryReader.moveDown(); + assertEquals("node" + i, binaryReader.getNodeName()); + binaryReader.moveUp(); + } + + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/binary/TokenTest.java b/xstream/src/test/com/thoughtworks/xstream/io/binary/TokenTest.java new file mode 100644 index 0000000..a47964a --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/binary/TokenTest.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. June 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.io.binary; + +import junit.framework.TestCase; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.IOException; + +public class TokenTest extends TestCase { + + private Token.Formatter tokenFormatter; + private ByteArrayOutputStream buffer; + private DataOutput out; + + protected void setUp() throws Exception { + super.setUp(); + tokenFormatter = new Token.Formatter(); + buffer = new ByteArrayOutputStream(); + out = new DataOutputStream(buffer); + } + + public void testDoesNotSupportNegativeIds() { + Token.StartNode token = new Token.StartNode(-5); + try { + writeOneToken(token); + fail("Expected exception"); + } catch (IOException expectedException) { + // expected exception + } + } + + public void testUsesOneExtraByteForIdsThatCanBeRepresentedAsByte() throws IOException { + Token.StartNode token = new Token.StartNode(255); + writeOneToken(token); + assertEquals(2, buffer.size()); // One byte already written for token type. + assertEquals(token, readOneToken()); + } + + public void testUsesTwoExtraBytesForIdsThatCanBeRepresentedAsShort() throws IOException { + Token.StartNode token = new Token.StartNode(30000); + writeOneToken(token); + assertEquals(3, buffer.size()); // One byte already written for token type. + assertEquals(token, readOneToken()); + } + + public void testUsesFourExtraBytesForIdsThatCanBeRepresentedAsShort() throws IOException { + Token.StartNode token = new Token.StartNode(Integer.MAX_VALUE); + writeOneToken(token); + assertEquals(5, buffer.size()); // One byte already written for token type. + assertEquals(token, readOneToken()); + } + + public void testUsesEightExtraBytesForIdsThatCanBeRepresentedAsLong() throws IOException { + Token.StartNode token = new Token.StartNode(324234325543L); + writeOneToken(token); + assertEquals(9, buffer.size()); // One byte already written for token type. + assertEquals(token, readOneToken()); + } + + public void testUsesOneExtraByteForUtf8StringsWith1ByteCharacters() throws IOException { + Token.Value token = new Token.Value("12345"); + writeOneToken(token); + assertEquals(8, buffer.size()); // One byte already written for token type and two for the length. + assertEquals(token, readOneToken()); + } + + public void testUsesOneExtraByteForUtf8StringsWith2ByteCharacters() throws IOException { + Token.Value token = new Token.Value("\u0391\u03b8\u03ae\u03bd\u03b1"); // Athens + writeOneToken(token); + assertEquals(13, buffer.size()); // One byte already written for token type and two for the length. + assertEquals(token, readOneToken()); + } + + public void testUsesIdForStringsWithMoreThen64KBytes() throws IOException { + StringBuffer builder = new StringBuffer(); + for(int i = 0; i++ < 8000;) { + builder.append("\u0391\u03b8\u03ae\u03bd\u03b1"); // Athens + } + String string = builder.toString(); + assertEquals(40000, string.length()); // 5 chars, but each char 2 bytes in UTF-8 + Token.Value token = new Token.Value(string); + writeOneToken(token); + assertEquals(80014, buffer.size()); // > 65k + assertEquals(token, readOneToken()); + } + + private Token readOneToken() throws IOException { + return tokenFormatter.read(new DataInputStream(new ByteArrayInputStream(buffer.toByteArray()))); + } + + private void writeOneToken(Token token) throws IOException { + tokenFormatter.write(out, token); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/copy/HierarchicalStreamCopierTest.java b/xstream/src/test/com/thoughtworks/xstream/io/copy/HierarchicalStreamCopierTest.java new file mode 100644 index 0000000..e9a88ae --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/copy/HierarchicalStreamCopierTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. June 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.io.copy; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.xml.AbstractXMLReaderTest; +import com.thoughtworks.xstream.io.xml.CompactWriter; +import com.thoughtworks.xstream.io.xml.Xpp3Driver; +import com.thoughtworks.xstream.io.xml.XppReader; +import com.thoughtworks.xstream.io.xml.xppdom.XppFactory; + +import org.xmlpull.v1.XmlPullParserException; + +import java.io.StringReader; +import java.io.StringWriter; + +public class HierarchicalStreamCopierTest extends AbstractXMLReaderTest { + + private HierarchicalStreamCopier copier = new HierarchicalStreamCopier(); + + // This test leverages the existing (comprehensive) tests for the XML readers + // and adds an additional stage of copying in. + + // factory method - overriding base class. + protected HierarchicalStreamReader createReader(String xml) throws Exception { + HierarchicalStreamReader sourceReader = + new Xpp3Driver().createReader(new StringReader(xml)); + + StringWriter buffer = new StringWriter(); + HierarchicalStreamWriter destinationWriter = new CompactWriter(buffer); + + copier.copy(sourceReader, destinationWriter); + + return new XppReader(new StringReader(buffer.toString()), XppFactory.createDefaultParser()); + } + + public void testSkipsValueIfEmpty() throws XmlPullParserException { + String input = "blah"; + String expected = "blah"; + HierarchicalStreamReader sourceReader = new XppReader( + new StringReader(input), XppFactory.createDefaultParser()); + + StringWriter buffer = new StringWriter(); + HierarchicalStreamWriter destinationWriter = new CompactWriter(buffer); + + copier.copy(sourceReader, destinationWriter); + + assertEquals(expected, buffer.toString()); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/json/JettisonMappedXmlDriverTest.java b/xstream/src/test/com/thoughtworks/xstream/io/json/JettisonMappedXmlDriverTest.java new file mode 100644 index 0000000..4fb1008 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/json/JettisonMappedXmlDriverTest.java @@ -0,0 +1,314 @@ +/* + * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. April 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.json; + +import com.thoughtworks.acceptance.objects.Category; +import com.thoughtworks.acceptance.objects.OwnerOfExternalizable; +import com.thoughtworks.acceptance.objects.Product; +import com.thoughtworks.acceptance.objects.SomethingExternalizable; +import com.thoughtworks.acceptance.objects.StandardObject; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.testutil.TimeZoneChanger; + +import junit.framework.TestCase; + +import org.codehaus.jettison.mapped.Configuration; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.StringReader; +import java.io.StringWriter; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Date; + + +/** + * Testing serialization to and from JSON with Jettison driver. + * + * @author Dejan Bosanac + */ +public class JettisonMappedXmlDriverTest extends TestCase { + + private final static String SIMPLE = "{'product':{'name':'Banana','id':123,'price':23}}" + .replace('\'', '"'); + private final static String HIERARCHY = (JVM.is15() + ? "{'category':{'name':'fruit','id':111,'products':[{'product':[{'name':'Banana','id':123,'price':23.01,'tags':[{'string':['yellow','fresh','tasty']}]},{'name':'Mango','id':124,'price':34.01}]}]}}" + : "{'category':{'name':'fruit','id':111,'products':{'product':[{'name':'Banana','id':123,'price':23.01,'tags':{'string':['yellow','fresh','tasty']}},{'name':'Mango','id':124,'price':34.01}]}}}") + .replace('\'', '"'); + + private XStream xstream; + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + TimeZoneChanger.change("UTC"); + xstream = new XStream(new JettisonMappedXmlDriver()); + xstream.alias("category", Category.class); + xstream.alias("product", Product.class); + } + + protected void tearDown() throws Exception { + TimeZoneChanger.reset(); + super.tearDown(); + } + + public void testReadSimple() { + Product product = (Product)xstream.fromXML(SIMPLE); + assertEquals(product.getName(), "Banana"); + assertEquals(product.getId(), "123"); + assertEquals("" + product.getPrice(), "" + 23.00); + } + + public void testWriteSimple() { + Product product = new Product("Banana", "123", 23.00); + String result = xstream.toXML(product); + assertEquals(SIMPLE, result); + } + + public void testJettisonConfigured() + throws ClassNotFoundException, InstantiationException, IllegalAccessException, + NoSuchMethodException, InvocationTargetException { + if (JVM.is15()) { + Object typeConverter = Class.class.forName( + "org.codehaus.jettison.mapped.SimpleConverter").newInstance(); + Method setTypeConverter = Configuration.class.getMethod( + "setTypeConverter", new Class[]{typeConverter.getClass().getInterfaces()[0]}); + Configuration config = new Configuration(); + setTypeConverter.invoke(config, new Object[]{typeConverter}); + xstream = new XStream(new JettisonMappedXmlDriver(config)); + xstream.alias("product", Product.class); + Product product = new Product("Banana", "123", 23.00); + String result = xstream.toXML(product); + assertEquals( + "{'product':{'name':'Banana','id':'123','price':'23.0'}}".replace('\'', '"'), + result); + assertEquals(product, xstream.fromXML(result)); + } + } + + public void testWriteHierarchy() { + Category category = new Category("fruit", "111"); + ArrayList products = new ArrayList(); + Product banana = new Product("Banana", "123", 23.01); + ArrayList bananaTags = new ArrayList(); + bananaTags.add("yellow"); + bananaTags.add("fresh"); + bananaTags.add("tasty"); + banana.setTags(bananaTags); + products.add(banana); + Product mango = new Product("Mango", "124", 34.01); + products.add(mango); + category.setProducts(products); + String result = xstream.toXML(category); + assertEquals(HIERARCHY, result); + } + + public void testHierarchyRead() { + Category parsedCategory = (Category)xstream.fromXML(HIERARCHY); + Product parsedBanana = (Product)parsedCategory.getProducts().get(0); + assertEquals("Banana", parsedBanana.getName()); + assertEquals(3, parsedBanana.getTags().size()); + assertEquals("yellow", parsedBanana.getTags().get(0)); + assertEquals("tasty", parsedBanana.getTags().get(2)); + } + + public void testObjectStream() throws IOException, ClassNotFoundException { + Product product = new Product("Banana", "123", 23.00); + StringWriter writer = new StringWriter(); + ObjectOutputStream oos = xstream.createObjectOutputStream(writer, "oos"); + oos.writeObject(product); + oos.close(); + String json = writer.toString(); + assertEquals("{\"oos\":" + SIMPLE + "}", json); + ObjectInputStream ois = xstream.createObjectInputStream(new StringReader(json)); + Product parsedProduct = (Product)ois.readObject(); + assertEquals(product.toString(), parsedProduct.toString()); + } + + public void testDoesHandleQuotesAndEscapes() { + String[] strings = new String[]{ + "last\"", "\"first", "\"between\"", "around \"\" it", "back\\slash", + "forward/slash"}; + String expected = ("" + + (JVM.is15() ? "{#string-array#:[{#string#:[" : "{#string-array#:{#string#:[") + + "#last\\\"#," + + "#\\\"first#," + + "#\\\"between\\\"#," + + "#around \\\"\\\" it#," + + "#back\\\\slash#," + + "#forward\\/slash#" + (JVM.is15() ? "]}]}" : "]}}")).replace('#', '"'); + assertEquals(expected, xstream.toXML(strings)); + } + + public void testDoesEscapeValuesAccordingRfc4627() { + String expected = "{'string':'\\u0000\\u0001\\u001f \uffee'}".replace('\'', '"'); + assertEquals(expected, xstream.toXML("\u0000\u0001\u001f\u0020\uffee")); + } + + public void testSingletonListWithSimpleObject() { + ArrayList list1 = new ArrayList(); + list1.add("one"); + String json = xstream.toXML(list1); + assertEquals((JVM.is15() + ? "{'list':[{'string':'one'}]}" + : "{'list':{'string':['one']}}").replace('\'', '"'), json); + ArrayList list2 = (ArrayList)xstream.fromXML(json); + assertEquals(json, xstream.toXML(list2)); + } + + public void testListWithSimpleObjects() { + ArrayList list1 = new ArrayList(); + list1.add("one"); + list1.add("two"); + list1.add("three"); + String json = xstream.toXML(list1); + assertEquals((JVM.is15() + ? "{'list':[{'string':['one','two','three']}]}" + : "{'list':{'string':['one','two','three']}}").replace('\'', '"'), json); + ArrayList list2 = (ArrayList)xstream.fromXML(json); + assertEquals(json, xstream.toXML(list2)); + } + + public void testSingletonListWithComplexObject() { + Product product = new Product("Banana", "123", 23.00); + ArrayList list1 = new ArrayList(); + list1.add(product); + String json = xstream.toXML(list1); + assertEquals((JVM.is15() + ? "{'list':[{'product':{'name':'Banana','id':123,'price':23}}]}" + : "{'list':{'product':[{'name':'Banana','id':123,'price':23}]}}") + .replace('\'', '"'), json); + ArrayList list2 = (ArrayList)xstream.fromXML(json); + assertEquals(json, xstream.toXML(list2)); + } + + public void testListWithComplexNestedObjects() { + ArrayList list1 = new ArrayList(); + list1.add(new Product("Banana", "123", 23.00)); + list1.add(new Product("Apple", "47", 11.00)); + list1.add(new Product("Orange", "100", 42.00)); + ArrayList tags = new ArrayList(); + ((Product)list1.get(1)).setTags(tags); + tags.add(new Product("Braeburn", "47.1", 10.00)); + String json = xstream.toXML(list1); + assertEquals( + (JVM.is15() + ? "{'list':[{'product':[{'name':'Banana','id':123,'price':23},{'name':'Apple','id':47,'price':11,'tags':[{'product':{'name':'Braeburn','id':47.1,'price':10}}]},{'name':'Orange','id':100,'price':42}]}]}" + : "{'list':{'product':[{'name':'Banana','id':123,'price':23},{'name':'Apple','id':47,'price':11,'tags':{'product':[{'name':'Braeburn','id':47.1,'price':10}]}},{'name':'Orange','id':100,'price':42}]}}") + .replace('\'', '"'), json); + ArrayList list2 = (ArrayList)xstream.fromXML(json); + assertEquals(json, xstream.toXML(list2)); + } + + public void todoTestEmptyList() { + ArrayList list1 = new ArrayList(); + String json = xstream.toXML(list1); + assertEquals("{'list':[]}".replace('\'', '"'), json); + ArrayList list2 = (ArrayList)xstream.fromXML(json); + assertEquals(json, xstream.toXML(list2)); + } + + public static class Topic extends StandardObject { + long id; + String description; + Date createdOn; + } + + public void testDefaultValue() { + Topic topic1 = new Topic(); + topic1.id = 4711; + topic1.description = "JSON"; + topic1.createdOn = new Timestamp(1000); + xstream.alias("topic", Topic.class); + String json = xstream.toXML(topic1); + assertEquals( + "{'topic':{'id':4711,'description':'JSON','createdOn':{'@class':'sql-timestamp','$':'1970-01-01 00:00:01.0'}}}" + .replace('\'', '"'), json); + Topic topic2 = (Topic)xstream.fromXML(json); + assertEquals(json, xstream.toXML(topic2)); + } + + public void testLongValueWithHighPrecision() { + Topic topic1 = new Topic(); + topic1.id = Long.MAX_VALUE; + topic1.description = "JSON"; + xstream.alias("topic", Topic.class); + String json = xstream.toXML(topic1); + assertEquals( + "{'topic':{'id':9223372036854775807,'description':'JSON'}}" + .replace('\'', '"'), json); + Topic topic2 = (Topic)xstream.fromXML(json); + assertEquals(json, xstream.toXML(topic2)); + } + + public void testEmbeddedXml() { + ArrayList list1 = new ArrayList(); + list1.add("]]>"); + String json = xstream.toXML(list1); + assertEquals( + (JVM.is15() + ? "{\"list\":[{\"string\":\"]]><\\/xml>\"}]}" + : "{\"list\":{\"string\":[\"]]><\\/xml>\"]}}"), + json); + ArrayList list2 = (ArrayList)xstream.fromXML(json); + assertEquals(json, xstream.toXML(list2)); + } + + public void testArrayList() { + if (JVM.is15()) { + ArrayList list1 = new ArrayList(); + list1.clear(); + list1.add(new Integer(12)); + + list1.add("string"); + list1.add(new Integer(13)); + String json = xstream.toXML(list1); + + ArrayList list2 = (ArrayList)xstream.fromXML(json); + assertEquals(json, xstream.toXML(list2)); + } + } + + private static class SpecialCharacters extends StandardObject { + String _foo__$_; + } + + public void testSpecialNames() { + SpecialCharacters sc = new SpecialCharacters(); + sc._foo__$_ = "bar"; + String json = xstream.toXML(sc); + assertEquals( + "{'com.thoughtworks.xstream.io.json.JettisonMappedXmlDriverTest$SpecialCharacters':{'_foo__$_':'bar'}}" + .replace('\'', '"'), json); + SpecialCharacters sc2 = (SpecialCharacters)xstream.fromXML(json); + assertEquals(json, xstream.toXML(sc2)); + } + + public void todoTestCanMarshalEmbeddedExternalizable() { + xstream.alias("owner", OwnerOfExternalizable.class); + + OwnerOfExternalizable in = new OwnerOfExternalizable(); + in.target = new SomethingExternalizable("Joe", "Walnes"); + String json = xstream.toXML(in); + // already wrong, Jettison reorders elements ... + assertEquals("{'owner':{'target':{'int':3,'string':['JoeWalnes','XStream'],'null':''}}}".replace('\'', '"'), json); + OwnerOfExternalizable owner = (OwnerOfExternalizable)xstream.fromXML(json); + assertEquals(json, xstream.toXML(owner)); + assertEquals(in.target, owner.target); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/json/JsonHierarchicalStreamDriverTest.java b/xstream/src/test/com/thoughtworks/xstream/io/json/JsonHierarchicalStreamDriverTest.java new file mode 100644 index 0000000..cb9ba4e --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/json/JsonHierarchicalStreamDriverTest.java @@ -0,0 +1,753 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2012 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. June 2006 by Mauro Talevi + */ +package com.thoughtworks.xstream.io.json; + +import java.awt.Color; +import java.io.InputStream; +import java.io.Reader; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.TimeZone; +import java.util.TreeMap; + +import com.thoughtworks.acceptance.objects.Original; +import com.thoughtworks.acceptance.objects.OwnerOfExternalizable; +import com.thoughtworks.acceptance.objects.Replaced; +import com.thoughtworks.acceptance.objects.SomethingExternalizable; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.core.JVM; + +import junit.framework.TestCase; + + +/** + * Some of these test cases are taken from example JSON listed at + * http://www.json.org/example.html + * + * @author Paul Hammant + * @author Jörg Schaible + */ +public class JsonHierarchicalStreamDriverTest extends TestCase { + protected XStream xstream; + + /** + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + xstream = new XStream(createDriver()); + } + + protected JsonHierarchicalStreamDriver createDriver() { + return new JsonHierarchicalStreamDriver(); + } + + protected String normalizeExpectation(String expected) { + return expected.replace('\'', '"'); + } + + public void testDoesNotSupportReader() { + try { + new JsonHierarchicalStreamDriver().createReader((Reader)null); + fail("should have barfed"); + } catch (UnsupportedOperationException uoe) { + // expected + } + } + + public void testDoesNotSupportInputStream() { + try { + new JsonHierarchicalStreamDriver().createReader((InputStream)null); + fail("should have barfed"); + } catch (UnsupportedOperationException uoe) { + // expected + } + } + + public void testCanMarshalSimpleTypes() { + + String expected = normalizeExpectation("" + + "{'innerMessage': {\n" + + " 'long1': 5,\n" + + " 'long2': 42,\n" + + " 'greeting': 'hello',\n" + + " 'int1': 2,\n" + + " 'int2': 3,\n" + + " 'short1': 6,\n" + + " 'short2': 7,\n" + + " 'byte1': 8,\n" + + " 'byte2': 9,\n" + + " 'bool1': true,\n" + + " 'bool2': false,\n" + + " 'char1': 'A',\n" + + " 'char2': 'B',\n" + + " 'float1': 1.1,\n" + + " 'float2': 1.2,\n" + + " 'double1': 2.1,\n" + + " 'double2': 2.2,\n" + + " 'bigInt': 511,\n" + + " 'bigDec': 3.14,\n" + + " 'innerMessage': {\n" + + " 'long1': 0,\n" + + " 'greeting': 'bonjour',\n" + + " 'int1': 3,\n" + + " 'short1': 0,\n" + + " 'byte1': 0,\n" + + " 'bool1': false,\n" + + " 'char1': '\\u0000',\n" + + " 'float1': 0.0,\n" + + " 'double1': 0.0\n" + + " }\n" + + "}}"); + + xstream.alias("innerMessage", Message.class); + + Message message = new Message("hello"); + message.long1 = 5L; + message.long2 = new Long(42); + message.int1 = 2; + message.int2 = new Integer(3); + message.short1 = (short)6; + message.short2 = new Short((short)7); + message.byte1 = (byte)8; + message.byte2 = new Byte((byte)9); + message.bool1 = true; + message.bool2 = Boolean.FALSE; + message.char1 = 'A'; + message.char2 = new Character('B'); + message.float1 = 1.1f; + message.float2 = new Float(1.2f); + message.double1 = 2.1; + message.double2 = new Double(2.2); + message.bigInt = new BigInteger(new byte[]{(byte)1, (byte)0xFF}); + message.bigDec = new BigDecimal(314).divide( + new BigDecimal(100), 2, BigDecimal.ROUND_FLOOR); + + Message message2 = new Message("bonjour"); + message2.int1 = 3; + + message.innerMessage = message2; + + assertEquals(expected, xstream.toXML(message)); + } + + public static class Message { + long long1; + Long long2; + String greeting; + int int1; + Integer int2; + short short1; + Short short2; + byte byte1; + Byte byte2; + boolean bool1; + Boolean bool2; + char char1; + Character char2; + float float1; + Float float2; + double double1; + Double double2; + BigInteger bigInt; + BigDecimal bigDec; + Message innerMessage; + + public Message(String greeting) { + this.greeting = greeting; + } + } + + protected String expectedMenuStart = "" + + "{'menu': {\n" + + " 'id': 'file',\n" + + " 'value': 'File:',\n" + + " 'popup': {\n" + + " 'menuitem': ["; + protected String expectedNew = "" + + " {\n" + + " 'value': 'New',\n" + + " 'onclick': 'CreateNewDoc()'\n" + + " }"; + protected String expectedOpen = "" + + " {\n" + + " 'value': 'Open',\n" + + " 'onclick': 'OpenDoc()'\n" + + " }"; + protected String expectedClose = "" + + " {\n" + + " 'value': 'Close',\n" + + " 'onclick': 'CloseDoc()'\n" + + " }"; + protected String expectedMenuEnd = "" + " ]\n" + " }\n" + "}}"; + protected String expected = "" // + + expectedMenuStart + + "\n" + + expectedNew + + ",\n" + + expectedOpen + + ",\n" + + expectedClose + + "\n" + expectedMenuEnd; + + public void testCanMarshalLists() { + + // This from http://www.json.org/example.html + + xstream.alias("menu", MenuWithList.class); + xstream.alias("menuitem", MenuItem.class); + + MenuWithList menu = new MenuWithList(); + + assertEquals(normalizeExpectation(expected), xstream.toXML(menu)); + } + + public void testCanMarshalArrays() { + + xstream.alias("menu", MenuWithArray.class); + xstream.alias("menuitem", MenuItem.class); + + MenuWithArray menu = new MenuWithArray(); + + assertEquals(normalizeExpectation(expected), xstream.toXML(menu)); + } + + public void testCanMarshalSets() { + + // This from http://www.json.org/example.html + + xstream.alias("menu", MenuWithSet.class); + xstream.alias("menuitem", MenuItem.class); + + MenuWithSet menu = new MenuWithSet(); + + String json = xstream.toXML(menu); + assertTrue(json.startsWith(normalizeExpectation(expectedMenuStart))); + assertTrue(json.indexOf(expectedNew.replace('\'', '"')) > 0); + assertTrue(json.indexOf(expectedOpen.replace('\'', '"')) > 0); + assertTrue(json.indexOf(expectedClose.replace('\'', '"')) > 0); + assertTrue(json.endsWith(expectedMenuEnd.replace('\'', '"'))); + } + + public static class MenuWithList { + String id = "file"; + String value = "File:"; + PopupWithList popup = new PopupWithList(); + } + + public static class PopupWithList { + List menuitem; + { + menuitem = new ArrayList(); + menuitem.add(new MenuItem("New", "CreateNewDoc()")); + menuitem.add(new MenuItem("Open", "OpenDoc()")); + menuitem.add(new MenuItem("Close", "CloseDoc()")); + } + } + + public static class MenuWithArray { + String id = "file"; + String value = "File:"; + PopupWithArray popup = new PopupWithArray(); + } + + public static class PopupWithArray { + MenuItem[] menuitem = new MenuItem[]{ + new MenuItem("New", "CreateNewDoc()"), new MenuItem("Open", "OpenDoc()"), + new MenuItem("Close", "CloseDoc()")}; + } + + public static class MenuWithSet { + String id = "file"; + String value = "File:"; + PopupWithSet popup = new PopupWithSet(); + } + + public static class PopupWithSet { + Set menuitem; + { + menuitem = new HashSet(); + menuitem.add(new MenuItem("New", "CreateNewDoc()")); + menuitem.add(new MenuItem("Open", "OpenDoc()")); + menuitem.add(new MenuItem("Close", "CloseDoc()")); + } + + } + + public static class MenuItem { + public String value; // assume unique + public String onclick; + + public MenuItem(String value, String onclick) { + this.value = value; + this.onclick = onclick; + } + + public int hashCode() { + return value.hashCode(); + } + + } + + public void testCanMarshalTypesWithPrimitives() { + + // This also from http://www.expected.org/example.html + + String expected = normalizeExpectation("" // + + "{'widget': {\n" + + " 'debug': 'on',\n" + + " 'window': {\n" + + " 'title': 'Sample Konfabulator Widget',\n" + + " 'name': 'main_window',\n" + + " 'width': 500,\n" + + " 'height': 500\n" + + " },\n" + + " 'image': {\n" + + " 'src': 'Images/Sun.png',\n" + + " 'name': 'sun1',\n" + + " 'hOffset': 250,\n" + + " 'vOffset': 250,\n" + + " 'alignment': 'center'\n" + + " },\n" + + " 'text': {\n" + + " 'data': 'Click Here',\n" + + " 'size': 36,\n" + + " 'style': 'bold',\n" + + " 'name': 'text1',\n" + + " 'hOffset': 250,\n" + + " 'vOffset': 100,\n" + + " 'alignment': 'center',\n" + + " 'onMouseUp': 'sun1.opacity = (sun1.opacity / 100) * 90;'\n" + + " }\n" + + "}}"); + + xstream.alias("widget", Widget.class); + xstream.alias("window", Window.class); + xstream.alias("image", Image.class); + xstream.alias("text", Text.class); + + Widget widget = new Widget(); + + assertEquals(expected, xstream.toXML(widget)); + + } + + public static class Widget { + String debug = "on"; + Window window = new Window(); + Image image = new Image(); + Text text = new Text(); + } + + public static class Window { + String title = "Sample Konfabulator Widget"; + String name = "main_window"; + int width = 500; + int height = 500; + } + + public static class Image { + String src = "Images/Sun.png"; + String name = "sun1"; + int hOffset = 250; + int vOffset = 250; + String alignment = "center"; + } + + public static class Text { + String data = "Click Here"; + int size = 36; + String style = "bold"; + String name = "text1"; + int hOffset = 250; + int vOffset = 100; + String alignment = "center"; + String onMouseUp = "sun1.opacity = (sun1.opacity / 100) * 90;"; + } + + public void testColor() { + boolean isHeadless = Boolean.valueOf(System.getProperty("java.awt.headless", "false")).booleanValue(); + if (!isHeadless || JVM.is15()) { + Color color = Color.black; + String expected = normalizeExpectation("" // + + "{'awt-color': {\n" + + " 'red': 0,\n" + + " 'green': 0,\n" + + " 'blue': 0,\n" + + " 'alpha': 255\n" + + "}}"); + assertEquals(expected, xstream.toXML(color)); + } + } + + public void testDoesHandleQuotesAndEscapes() { + String[] strings = new String[]{ + "last\"", "\"first", "\"between\"", "around \"\" it", "back\\slash",}; + String expected = normalizeExpectation("" + + "{'string-array': [\n" + + " 'last\\\"',\n" + + " '\\\"first',\n" + + " '\\\"between\\\"',\n" + + " 'around \\\"\\\" it',\n" + + " 'back\\\\slash'\n" + + "]}"); + assertEquals(expected, xstream.toXML(strings)); + } + + public void testDoesEscapeValuesAccordingRfc4627() { + String expected = normalizeExpectation("{'string': '\\u0000\\u0001\\u001f \uffee'}"); + assertEquals(expected, xstream.toXML("\u0000\u0001\u001f\u0020\uffee")); + } + + public void testSimpleInteger() { + String expected = normalizeExpectation("{'int': 123}"); + assertEquals(expected, xstream.toXML(new Integer(123))); + } + + public void testBracesAndSquareBracketsAreNotEscaped() { + String expected = normalizeExpectation("{'string': '..{}[],,'}"); + assertEquals(expected, xstream.toXML("..{}[],,")); + } + + public void testCanMarshalSimpleTypesWithNullMembers() { + Msg message = new Msg("hello"); + Msg message2 = new Msg(null); + message.innerMessage = message2; + + xstream.alias("innerMessage", Msg.class); + + String expected = normalizeExpectation("" + + "{'innerMessage': {\n" + + " 'greeting': 'hello',\n" + + " 'innerMessage': {}\n" + + "}}"); + assertEquals(expected, xstream.toXML(message)); + } + + public static class Msg { + String greeting; + Msg innerMessage; + + public Msg(String greeting) { + this.greeting = greeting; + } + } + + public void testCanMarshalElementWithEmptyArray() { + xstream.alias("element", ElementWithEmptyArray.class); + + String expected = normalizeExpectation("" // + + "{'element': {\n" + + " 'array': []\n" + + "}}"); + assertEquals(expected, xstream.toXML(new ElementWithEmptyArray())); + } + + public static class ElementWithEmptyArray { + String[] array = new String[0]; + } + + public void testCanMarshalJavaMap() { + String entry1 = "" // entry 1 + + " [\n" + + " 'one',\n" + + " 1\n" + + " ]"; + String entry2 = "" // entry 2 + + " [\n" + + " 'two',\n" + + " 2\n" + + " ]"; + + final Map map = new HashMap(); + map.put("one", new Integer(1)); + map.put("two", new Integer(2)); + String actual = xstream.toXML(map); + int idx1 = actual.indexOf("one"); + int idx2 = actual.indexOf("two"); + + String expected = normalizeExpectation("" + + "{'map': [\n" + + ((idx1 < idx2 ? entry1 : entry2) + ",\n") + + ((idx1 < idx2 ? entry2 : entry1) + "\n") // no comma + + "]}"); + assertEquals(expected, actual); + } + + public void testCanMarshalProperties() { + String entry1 = "" // entry 1 + + " {\n" + + " '@name': 'one',\n" + + " '@value': '1'\n" + + " }"; + String entry2 = "" // entry 2 + + " {\n" + + " '@name': 'two',\n" + + " '@value': '2'\n" + + " }"; + + final Properties properties = new Properties(); + properties.setProperty("one", "1"); + properties.setProperty("two", "2"); + String actual = xstream.toXML(properties); + int idx1 = actual.indexOf("one"); + int idx2 = actual.indexOf("two"); + + String expected = normalizeExpectation("" + + "{'properties': [\n" + + ((idx1 < idx2 ? entry1 : entry2) + ",\n") + + ((idx1 < idx2 ? entry2 : entry1) + "\n") // no comma + + "]}"); + assertEquals(expected, actual); + } + + final static class MapHolder { + private Map map = new HashMap(); + } + + public void testCanMarshalNestedMap() { + xstream.alias("holder", MapHolder.class); + String entry1 = "" // entry 1 + + " [\n" + + " 'one',\n" + + " 1\n" + + " ]"; + String entry2 = "" // entry 2 + + " [\n" + + " 'two',\n" + + " 2\n" + + " ]"; + + final MapHolder holder = new MapHolder(); + holder.map.put("one", new Integer(1)); + holder.map.put("two", new Integer(2)); + String actual = xstream.toXML(holder); + int idx1 = actual.indexOf("one"); + int idx2 = actual.indexOf("two"); + + String expected = normalizeExpectation("" + + "{'holder': {\n" + + " 'map': [\n" + + ((idx1 < idx2 ? entry1 : entry2) + ",\n") + + ((idx1 < idx2 ? entry2 : entry1) + "\n") + + " ]\n" // no comma + + "}}"); + assertEquals(expected, actual); + } + + static class CollectionKeeper { + Collection coll = new ArrayList(); + } + + public void testIgnoresAttributeForCollectionMember() { + xstream.alias("keeper", CollectionKeeper.class); + String expected = normalizeExpectation("" // + + "{'keeper': {\n" + + " 'coll': [\n" + + " 'one',\n" + + " 'two'\n" + + " ]\n" + + "}}"); + + final CollectionKeeper holder = new CollectionKeeper(); + holder.coll.add("one"); + holder.coll.add("two"); + assertEquals(expected, xstream.toXML(holder)); + } + + // Writing attributes, the writer has no clue about their original type. + public void testDoesWriteAttributesAsStringValues() { + xstream.alias("window", Window.class); + xstream.useAttributeFor("width", int.class); + xstream.useAttributeFor("height", int.class); + String expected = normalizeExpectation("" + + "{'window': {\n" + + " '@width': '500',\n" + + " '@height': '500',\n" + + " 'title': 'JUnit'\n" + + "}}"); + + final Window window = new Window(); + window.title = "JUnit"; + window.name = null; + assertEquals(expected, xstream.toXML(window)); + } + + static class Person { + String firstName; + String lastName; + Calendar dateOfBirth; + Map titles = new TreeMap(); + } + + public void testCanWriteEmbeddedCalendar() { + xstream.alias("person", Person.class); + String expected = normalizeExpectation("" + + "{'list': [\n" + + " {\n" + + " 'firstName': 'Joe',\n" + + " 'lastName': 'Walnes',\n" + + " 'dateOfBirth': {\n" + + " 'time': -2177539200000,\n" + + " 'timezone': 'Europe/London'\n" + + " },\n" + + " 'titles': [\n" + + " [\n" + + " '1',\n" + + " 'Mr'\n" + + " ]\n" + + " ]\n" + + " }\n" + + "]}"); + + Person person = new Person(); + person.firstName = "Joe"; + person.lastName = "Walnes"; + person.dateOfBirth = Calendar.getInstance(TimeZone.getTimeZone("Europe/London")); + person.dateOfBirth.clear(); + person.dateOfBirth.set(1900, Calendar.DECEMBER, 31); + person.titles.put("1", "Mr"); + List list = new ArrayList(); + list.add(person); + assertEquals(expected, xstream.toXML(list)); + } + + static class SingleValue { + long l; + URL url; + } + + public void testSupportsAllConvertersWithASingleValue() throws MalformedURLException { + xstream.alias("sv", SingleValue.class); + String expected = normalizeExpectation("" + + "{'sv': {\n" + + " 'l': 4711,\n" + + " 'url': 'http://localhost:8888'\n" + + "}}"); + + SingleValue value = new SingleValue(); + value.l = 4711; + value.url = new URL("http://localhost:8888"); + assertEquals(expected, xstream.toXML(value)); + } + + static class SystemAttributes { + String name; + Object object; + Original original; + } + + public void testWillWriteTagValueAsDefaultValueIfNecessary() { + xstream.alias("sa", SystemAttributes.class); + xstream.alias("original", Original.class); + xstream.alias("replaced", Replaced.class); + + SystemAttributes sa = new SystemAttributes(); + sa.name = "joe"; + sa.object = "walnes"; + sa.original = new Original("hello world"); + + String expected = normalizeExpectation("" + + "{'sa': {\n" + + " 'name': 'joe',\n" + + " 'object': {\n" + + " '@class': 'string',\n" + + " '$': 'walnes'\n" + +" },\n" + + " 'original': {\n" + + " '@resolves-to': 'replaced',\n" + + " 'replacedValue': 'HELLO WORLD'\n" + + " }\n" + + "}}"); + + assertEquals(expected, xstream.toXML(sa)); + } + + public void testRealTypeIsHonoredWhenWritingTheValue() { + xstream.alias("sa", SystemAttributes.class); + + List list = new ArrayList(); + list.add("joe"); + list.add("mauro"); + SystemAttributes[] sa = new SystemAttributes[2]; + sa[0] = new SystemAttributes(); + sa[0].name = "year"; + sa[0].object = new Integer(2000); + sa[1] = new SystemAttributes(); + sa[1].name = "names"; + sa[1].object = list; + + String expected = normalizeExpectation("" + + "{'sa-array': [\n" + + " {\n" + + " 'name': 'year',\n" + + " 'object': {\n" + + " '@class': 'int',\n" + + " '$': 2000\n" + + " }\n" + + " },\n" + + " {\n" + + " 'name': 'names',\n" + + " 'object': [\n" + + " 'joe',\n" + + " 'mauro'\n" + + " ]\n" + + " }\n" + + "]}"); + + assertEquals(expected, xstream.toXML(sa)); + } + + public void testCanMarshalExternalizable() { + xstream.alias("ext", SomethingExternalizable.class); + + SomethingExternalizable in = new SomethingExternalizable("Joe", "Walnes"); + String expected = normalizeExpectation("" + + "{'ext': [\n" + + " 3,\n" + + " 'JoeWalnes',\n" + + " {},\n" + + " 'XStream'\n" + + "]}"); + + assertEquals(expected, xstream.toXML(in)); + } + + public void testCanMarshalEmbeddedExternalizable() { + xstream.alias("owner", OwnerOfExternalizable.class); + + OwnerOfExternalizable in = new OwnerOfExternalizable(); + in.target = new SomethingExternalizable("Joe", "Walnes"); + String expected = normalizeExpectation("" + + "{'owner': {\n" + + " 'target': [\n" + + " 3,\n" + + " 'JoeWalnes',\n" + + " {},\n" + + " 'XStream'\n" + + " ]\n" + + "}}"); + + assertEquals(expected, xstream.toXML(in)); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/json/JsonWriterFormatTest.java b/xstream/src/test/com/thoughtworks/xstream/io/json/JsonWriterFormatTest.java new file mode 100644 index 0000000..f5e6797 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/json/JsonWriterFormatTest.java @@ -0,0 +1,331 @@ +/* + * Copyright (C) 2009, 2010, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 02. September 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.json; + +import java.io.StringWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.Properties; +import java.util.TreeSet; + +import com.thoughtworks.acceptance.objects.OpenSourceSoftware; +import com.thoughtworks.acceptance.objects.SampleLists; +import com.thoughtworks.acceptance.someobjects.Handler; +import com.thoughtworks.acceptance.someobjects.Protocol; +import com.thoughtworks.acceptance.someobjects.X; +import com.thoughtworks.acceptance.someobjects.Y; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.converters.extended.ToStringConverter; +import com.thoughtworks.xstream.core.util.OrderRetainingMap; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.json.JsonWriter.Format; + +import junit.framework.AssertionFailedError; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + + +/** + * Tests the {@link JsonWriter} formats. + * + * @author Jörg Schaible + */ +public class JsonWriterFormatTest extends TestCase { + + private XStream xstream; + private Object target; + private final int mode; + private final Format format; + private final String json; + + public static class YString extends Y { + public YString(String y) { + this.yField = y; + } + public String toString() { + return yField; + } + } + + private final static class HandlerConverter implements Converter { + public boolean canConvert(Class type) { + return type == Handler.class; + } + + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + Handler h = (Handler)source; + writer.startNode("str"); + writer.setValue("test"); + writer.endNode(); + writer.startNode("protocol"); + context.convertAnother(h.getProtocol()); + writer.endNode(); + ExtendedHierarchicalStreamWriterHelper.startNode(writer, "i", int.class); + writer.setValue("42"); + writer.endNode(); + } + + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + reader.moveDown(); + reader.moveUp(); + reader.moveDown(); + Protocol p = (Protocol)context.convertAnother(null, Protocol.class); + reader.moveUp(); + reader.moveDown(); + reader.moveUp(); + return new Handler(p); + } + } + + public JsonWriterFormatTest( + String name, Object target, String json, int writerMode, JsonWriter.Format format) { + super(name); + this.target = target; + this.json = json; + this.mode = writerMode; + this.format = format; + + xstream = new XStream(); + xstream.setMode(name.endsWith("+ID") ? XStream.ID_REFERENCES : XStream.NO_REFERENCES); + xstream.alias("chseq", CharSequence.class); + xstream.alias("oss", OpenSourceSoftware.class); + xstream.alias("collections", SampleLists.class); + xstream.alias("x", X.class); + xstream.alias("ys", YString.class); + xstream.alias("h", Handler.class); + xstream.useAttributeFor(OpenSourceSoftware.class, "license"); + try { + xstream.registerConverter(new ToStringConverter(YString.class)); + } catch (NoSuchMethodException e) { + throw new AssertionFailedError(e.getMessage()); + } + xstream.registerConverter(new HandlerConverter()); + } + + protected void runTest() throws Throwable { + assertEquals(json, toJSON(mode, format)); + } + + private String toJSON(int mode, JsonWriter.Format format) { + final StringWriter writer = new StringWriter(1024); + try { + writeJSON(writer, mode, format); + return writer.toString(); + } finally { + //System.out.println(writer.toString() + " ---> " + getName()); + } + } + + private void writeJSON(Writer writer, int mode, JsonWriter.Format format) { + JsonWriter jsonWriter = new JsonWriter(writer, mode, format, 0); + try { + xstream.marshal(target, jsonWriter); + } finally { + jsonWriter.flush(); + } + } + + public static Test suite() { + final Map modes = new OrderRetainingMap(); + modes.put("optimized", new Integer(0)); + modes.put("noRoot", new Integer(AbstractJsonWriter.DROP_ROOT_MODE)); + modes.put("explicit", new Integer(AbstractJsonWriter.EXPLICIT_MODE)); + + final Map formats = new OrderRetainingMap(); + formats.put("Minimal", new JsonWriter.Format( + new char[0], new char[0], JsonWriter.Format.COMPACT_EMPTY_ELEMENT)); + formats.put("Pretty", new JsonWriter.Format( + " ".toCharArray(), "\n".toCharArray(), JsonWriter.Format.SPACE_AFTER_LABEL)); + formats.put("Compact", new JsonWriter.Format( + " ".toCharArray(), "\n".toCharArray(), JsonWriter.Format.SPACE_AFTER_LABEL + | JsonWriter.Format.COMPACT_EMPTY_ELEMENT)); + + final Properties properties = new Properties(); + properties.put("one", "1"); + final X x = new X(); + x.anInt = 42; + x.aStr = "X"; + x.innerObj = new YString("Y"); + final X emptyX = new X(); + emptyX.innerObj = new Y(); + final SampleLists lists = new SampleLists(); + lists.good = new LinkedList(); + lists.good.add("XStream"); + lists.bad = new TreeSet(); + lists.bad.add(new X()); + final Map targets = new OrderRetainingMap(); + targets.put("String", "text"); + targets.put("CharSequenceArray", new CharSequence[]{"text", new StringBuffer("buffer"), null}); + targets.put("CharSequenceArray+ID", new CharSequence[]{"text", new StringBuffer("buffer"), null}); + targets.put("EmptyStringArray", new String[][]{new String[0]}); + targets.put("EmptyStringArray+ID", new String[][]{new String[0]}); + targets.put("Properties", properties); + targets.put("Object", new OpenSourceSoftware("Codehaus", "XStream", "BSD")); + targets.put("AttributeOnly", new OpenSourceSoftware(null, null, "BSD")); + targets.put("X", x); + targets.put("EmptyX", emptyX); + targets.put("Collections", lists); + targets.put("EmptyList", new ArrayList()); + targets.put("CustomConverter", new Handler(new Protocol("ldap"))); + + final Map results = new HashMap(); + results.put("optimizedMinimalString", "{'string':'text'}"); + results.put("optimizedPrettyString", "{'string': 'text'}"); + results.put("optimizedCompactString", "{'string': 'text'}"); + results.put("noRootMinimalString", "'text'"); + results.put("noRootPrettyString", "'text'"); + results.put("noRootCompactString", "'text'"); + results.put("explicitMinimalString", "{'string':[[],['text']]}"); + results.put("explicitPrettyString", "{'string': [\n [\n ],\n [\n 'text'\n ]\n]}"); + results.put("explicitCompactString", "{'string': [\n [],\n [\n 'text'\n ]\n]}"); + results.put("optimizedMinimalCharSequenceArray", "{'chseq-array':['text','buffer',null]}"); + results.put("optimizedPrettyCharSequenceArray", "{'chseq-array': [\n 'text',\n 'buffer',\n null\n]}"); + results.put("optimizedCompactCharSequenceArray", "{'chseq-array': [\n 'text',\n 'buffer',\n null\n]}"); + results.put("noRootMinimalCharSequenceArray", "['text','buffer',null]"); + results.put("noRootPrettyCharSequenceArray", "[\n 'text',\n 'buffer',\n null\n]"); + results.put("noRootCompactCharSequenceArray", "[\n 'text',\n 'buffer',\n null\n]"); + results.put("explicitMinimalCharSequenceArray", "{'chseq-array':[[],[{'string':[[],['text']]},{'string-buffer':[[],['buffer']]},{'null':[[],[null]]}]]}"); + results.put("explicitPrettyCharSequenceArray", "{'chseq-array': [\n [\n ],\n [\n {\n 'string': [\n [\n ],\n [\n 'text'\n ]\n ]\n },\n {\n 'string-buffer': [\n [\n ],\n [\n 'buffer'\n ]\n ]\n },\n {\n 'null': [\n [\n ],\n [\n null\n ]\n ]\n }\n ]\n]}"); + results.put("explicitCompactCharSequenceArray", "{'chseq-array': [\n [],\n [\n {\n 'string': [\n [],\n [\n 'text'\n ]\n ]\n },\n {\n 'string-buffer': [\n [],\n [\n 'buffer'\n ]\n ]\n },\n {\n 'null': [\n [],\n [\n null\n ]\n ]\n }\n ]\n]}"); + results.put("optimizedMinimalCharSequenceArray+ID", "{'chseq-array':['text',{'@id':'2','$':'buffer'},null]}"); + results.put("optimizedPrettyCharSequenceArray+ID", "{'chseq-array': [\n 'text',\n {\n '@id': '2',\n '$': 'buffer'\n },\n null\n]}"); + results.put("optimizedCompactCharSequenceArray+ID", "{'chseq-array': [\n 'text',\n {\n '@id': '2',\n '$': 'buffer'\n },\n null\n]}"); + results.put("noRootMinimalCharSequenceArray+ID", "['text',{'@id':'2','$':'buffer'},null]"); + results.put("noRootPrettyCharSequenceArray+ID", "[\n 'text',\n {\n '@id': '2',\n '$': 'buffer'\n },\n null\n]"); + results.put("noRootCompactCharSequenceArray+ID", "[\n 'text',\n {\n '@id': '2',\n '$': 'buffer'\n },\n null\n]"); + results.put("explicitMinimalCharSequenceArray+ID", "{'chseq-array':[[{'id':'1'}],[{'string':[[],['text']]},{'string-buffer':[[{'id':'2'}],['buffer']]},{'null':[[],[null]]}]]}"); + results.put("explicitPrettyCharSequenceArray+ID", "{'chseq-array': [\n [\n {\n 'id': '1'\n }\n ],\n [\n {\n 'string': [\n [\n ],\n [\n 'text'\n ]\n ]\n },\n {\n 'string-buffer': [\n [\n {\n 'id': '2'\n }\n ],\n [\n 'buffer'\n ]\n ]\n },\n {\n 'null': [\n [\n ],\n [\n null\n ]\n ]\n }\n ]\n]}"); + results.put("explicitCompactCharSequenceArray+ID", "{'chseq-array': [\n [\n {\n 'id': '1'\n }\n ],\n [\n {\n 'string': [\n [],\n [\n 'text'\n ]\n ]\n },\n {\n 'string-buffer': [\n [\n {\n 'id': '2'\n }\n ],\n [\n 'buffer'\n ]\n ]\n },\n {\n 'null': [\n [],\n [\n null\n ]\n ]\n }\n ]\n]}"); + results.put("optimizedMinimalEmptyStringArray", "{'string-array-array':[[]]}"); + results.put("optimizedPrettyEmptyStringArray", "{'string-array-array': [\n [\n ]\n]}"); + results.put("optimizedCompactEmptyStringArray", "{'string-array-array': [\n []\n]}"); + results.put("noRootMinimalEmptyStringArray", "[[]]"); + results.put("noRootPrettyEmptyStringArray", "[\n [\n ]\n]"); + results.put("noRootCompactEmptyStringArray", "[\n []\n]"); + results.put("explicitMinimalEmptyStringArray", "{'string-array-array':[[],[{'string-array':[[],[]]}]]}"); + results.put("explicitPrettyEmptyStringArray", "{'string-array-array': [\n [\n ],\n [\n {\n 'string-array': [\n [\n ],\n [\n ]\n ]\n }\n ]\n]}"); + results.put("explicitCompactEmptyStringArray", "{'string-array-array': [\n [],\n [\n {\n 'string-array': [\n [],\n []\n ]\n }\n ]\n]}"); + results.put("optimizedMinimalEmptyStringArray+ID", "{'string-array-array':[[]]}"); + results.put("optimizedPrettyEmptyStringArray+ID", "{'string-array-array': [\n [\n ]\n]}"); + results.put("optimizedCompactEmptyStringArray+ID", "{'string-array-array': [\n []\n]}"); + results.put("noRootMinimalEmptyStringArray+ID", "[[]]"); + results.put("noRootPrettyEmptyStringArray+ID", "[\n [\n ]\n]"); + results.put("noRootCompactEmptyStringArray+ID", "[\n []\n]"); + results.put("explicitMinimalEmptyStringArray+ID", "{'string-array-array':[[{'id':'1'}],[{'string-array':[[{'id':'2'}],[]]}]]}"); + results.put("explicitPrettyEmptyStringArray+ID", "{'string-array-array': [\n [\n {\n 'id': '1'\n }\n ],\n [\n {\n 'string-array': [\n [\n {\n 'id': '2'\n }\n ],\n [\n ]\n ]\n }\n ]\n]}"); + results.put("explicitCompactEmptyStringArray+ID", "{'string-array-array': [\n [\n {\n 'id': '1'\n }\n ],\n [\n {\n 'string-array': [\n [\n {\n 'id': '2'\n }\n ],\n []\n ]\n }\n ]\n]}"); + results.put("optimizedMinimalProperties", "{'properties':[{'@name':'one','@value':'1'}]}"); + results.put("optimizedPrettyProperties", "{'properties': [\n {\n '@name': 'one',\n '@value': '1'\n }\n]}"); + results.put("optimizedCompactProperties", "{'properties': [\n {\n '@name': 'one',\n '@value': '1'\n }\n]}"); + results.put("noRootMinimalProperties", "[{'@name':'one','@value':'1'}]"); + results.put("noRootPrettyProperties", "[\n {\n '@name': 'one',\n '@value': '1'\n }\n]"); + results.put("noRootCompactProperties", "[\n {\n '@name': 'one',\n '@value': '1'\n }\n]"); + results.put("explicitMinimalProperties", "{'properties':[[],[{'property':[[{'name':'one','value':'1'}],[]]}]]}"); + results.put("explicitPrettyProperties", "{'properties': [\n [\n ],\n [\n {\n 'property': [\n [\n {\n 'name': 'one',\n 'value': '1'\n }\n ],\n [\n ]\n ]\n }\n ]\n]}"); + results.put("explicitCompactProperties", "{'properties': [\n [],\n [\n {\n 'property': [\n [\n {\n 'name': 'one',\n 'value': '1'\n }\n ],\n []\n ]\n }\n ]\n]}"); + results.put("optimizedMinimalObject", "{'oss':{'@license':'BSD','vendor':'Codehaus','name':'XStream'}}"); + results.put("optimizedPrettyObject", "{'oss': {\n '@license': 'BSD',\n 'vendor': 'Codehaus',\n 'name': 'XStream'\n}}"); + results.put("optimizedCompactObject", "{'oss': {\n '@license': 'BSD',\n 'vendor': 'Codehaus',\n 'name': 'XStream'\n}}"); + results.put("noRootMinimalObject", "{'@license':'BSD','vendor':'Codehaus','name':'XStream'}"); + results.put("noRootPrettyObject", "{\n '@license': 'BSD',\n 'vendor': 'Codehaus',\n 'name': 'XStream'\n}"); + results.put("noRootCompactObject", "{\n '@license': 'BSD',\n 'vendor': 'Codehaus',\n 'name': 'XStream'\n}"); + results.put("explicitMinimalObject", "{'oss':[[{'license':'BSD'}],[{'vendor':[[],['Codehaus']]},{'name':[[],['XStream']]}]]}"); + results.put("explicitPrettyObject", "{'oss': [\n [\n {\n 'license': 'BSD'\n }\n ],\n [\n {\n 'vendor': [\n [\n ],\n [\n 'Codehaus'\n ]\n ]\n },\n {\n 'name': [\n [\n ],\n [\n 'XStream'\n ]\n ]\n }\n ]\n]}"); + results.put("explicitCompactObject", "{'oss': [\n [\n {\n 'license': 'BSD'\n }\n ],\n [\n {\n 'vendor': [\n [],\n [\n 'Codehaus'\n ]\n ]\n },\n {\n 'name': [\n [],\n [\n 'XStream'\n ]\n ]\n }\n ]\n]}"); + results.put("optimizedMinimalAttributeOnly", "{'oss':{'@license':'BSD'}}"); + results.put("optimizedPrettyAttributeOnly", "{'oss': {\n '@license': 'BSD'\n}}"); + results.put("optimizedCompactAttributeOnly", "{'oss': {\n '@license': 'BSD'\n}}"); + results.put("noRootMinimalAttributeOnly", "{'@license':'BSD'}"); + results.put("noRootPrettyAttributeOnly", "{\n '@license': 'BSD'\n}"); + results.put("noRootCompactAttributeOnly", "{\n '@license': 'BSD'\n}"); + results.put("explicitMinimalAttributeOnly", "{'oss':[[{'license':'BSD'}],[]]}"); + results.put("explicitPrettyAttributeOnly", "{'oss': [\n [\n {\n 'license': 'BSD'\n }\n ],\n [\n ]\n]}"); + results.put("explicitCompactAttributeOnly", "{'oss': [\n [\n {\n 'license': 'BSD'\n }\n ],\n []\n]}"); + results.put("optimizedMinimalX", "{'x':{'aStr':'X','anInt':42,'innerObj':{'@class':'ys','$':'Y'}}}"); + results.put("optimizedPrettyX", "{'x': {\n 'aStr': 'X',\n 'anInt': 42,\n 'innerObj': {\n '@class': 'ys',\n '$': 'Y'\n }\n}}"); + results.put("optimizedCompactX", "{'x': {\n 'aStr': 'X',\n 'anInt': 42,\n 'innerObj': {\n '@class': 'ys',\n '$': 'Y'\n }\n}}"); + results.put("noRootMinimalX", "{'aStr':'X','anInt':42,'innerObj':{'@class':'ys','$':'Y'}}"); + results.put("noRootPrettyX", "{\n 'aStr': 'X',\n 'anInt': 42,\n 'innerObj': {\n '@class': 'ys',\n '$': 'Y'\n }\n}"); + results.put("noRootCompactX", "{\n 'aStr': 'X',\n 'anInt': 42,\n 'innerObj': {\n '@class': 'ys',\n '$': 'Y'\n }\n}"); + results.put("explicitMinimalX", "{'x':[[],[{'aStr':[[],['X']]},{'anInt':[[],[42]]},{'innerObj':[[{'class':'ys'}],['Y']]}]]}"); + results.put("explicitPrettyX", "{'x': [\n [\n ],\n [\n {\n 'aStr': [\n [\n ],\n [\n 'X'\n ]\n ]\n },\n {\n 'anInt': [\n [\n ],\n [\n 42\n ]\n ]\n },\n {\n 'innerObj': [\n [\n {\n 'class': 'ys'\n }\n ],\n [\n 'Y'\n ]\n ]\n }\n ]\n]}"); + results.put("explicitCompactX", "{'x': [\n [],\n [\n {\n 'aStr': [\n [],\n [\n 'X'\n ]\n ]\n },\n {\n 'anInt': [\n [],\n [\n 42\n ]\n ]\n },\n {\n 'innerObj': [\n [\n {\n 'class': 'ys'\n }\n ],\n [\n 'Y'\n ]\n ]\n }\n ]\n]}"); + results.put("optimizedMinimalEmptyX", "{'x':{'anInt':0,'innerObj':{}}}"); + results.put("optimizedPrettyEmptyX", "{'x': {\n 'anInt': 0,\n 'innerObj': {\n }\n}}"); + results.put("optimizedCompactEmptyX", "{'x': {\n 'anInt': 0,\n 'innerObj': {}\n}}"); + results.put("noRootMinimalEmptyX", "{'anInt':0,'innerObj':{}}"); + results.put("noRootPrettyEmptyX", "{\n 'anInt': 0,\n 'innerObj': {\n }\n}"); + results.put("noRootCompactEmptyX", "{\n 'anInt': 0,\n 'innerObj': {}\n}"); + results.put("explicitMinimalEmptyX", "{'x':[[],[{'anInt':[[],[0]]},{'innerObj':[[],[]]}]]}"); + results.put("explicitPrettyEmptyX", "{'x': [\n [\n ],\n [\n {\n 'anInt': [\n [\n ],\n [\n 0\n ]\n ]\n },\n {\n 'innerObj': [\n [\n ],\n [\n ]\n ]\n }\n ]\n]}"); + results.put("explicitCompactEmptyX", "{'x': [\n [],\n [\n {\n 'anInt': [\n [],\n [\n 0\n ]\n ]\n },\n {\n 'innerObj': [\n [],\n []\n ]\n }\n ]\n]}"); + results.put("optimizedMinimalCollections", "{'collections':{'good':['XStream'],'bad':[{'anInt':0}]}}"); + results.put("optimizedPrettyCollections", "{'collections': {\n 'good': [\n 'XStream'\n ],\n 'bad': [\n {\n 'anInt': 0\n }\n ]\n}}"); + results.put("optimizedCompactCollections", "{'collections': {\n 'good': [\n 'XStream'\n ],\n 'bad': [\n {\n 'anInt': 0\n }\n ]\n}}"); + results.put("noRootMinimalCollections", "{'good':['XStream'],'bad':[{'anInt':0}]}"); + results.put("noRootPrettyCollections", "{\n 'good': [\n 'XStream'\n ],\n 'bad': [\n {\n 'anInt': 0\n }\n ]\n}"); + results.put("noRootCompactCollections", "{\n 'good': [\n 'XStream'\n ],\n 'bad': [\n {\n 'anInt': 0\n }\n ]\n}"); + results.put("explicitMinimalCollections", "{'collections':[[],[{'good':[[{'class':'linked-list'}],[{'string':[[],['XStream']]}]]},{'bad':[[{'class':'sorted-set'}],[{'x':[[],[{'anInt':[[],[0]]}]]}]]}]]}"); + results.put("explicitPrettyCollections", "{'collections': [\n [\n ],\n [\n {\n 'good': [\n [\n {\n 'class': 'linked-list'\n }\n ],\n [\n {\n 'string': [\n [\n ],\n [\n 'XStream'\n ]\n ]\n }\n ]\n ]\n },\n {\n 'bad': [\n [\n {\n 'class': 'sorted-set'\n }\n ],\n [\n {\n 'x': [\n [\n ],\n [\n {\n 'anInt': [\n [\n ],\n [\n 0\n ]\n ]\n }\n ]\n ]\n }\n ]\n ]\n }\n ]\n]}"); + results.put("explicitCompactCollections", "{'collections': [\n [],\n [\n {\n 'good': [\n [\n {\n 'class': 'linked-list'\n }\n ],\n [\n {\n 'string': [\n [],\n [\n 'XStream'\n ]\n ]\n }\n ]\n ]\n },\n {\n 'bad': [\n [\n {\n 'class': 'sorted-set'\n }\n ],\n [\n {\n 'x': [\n [],\n [\n {\n 'anInt': [\n [],\n [\n 0\n ]\n ]\n }\n ]\n ]\n }\n ]\n ]\n }\n ]\n]}"); + results.put("optimizedMinimalEmptyList", "{'list':[]}"); + results.put("optimizedPrettyEmptyList", "{'list': [\n]}"); + results.put("optimizedCompactEmptyList", "{'list': []}"); + results.put("noRootMinimalEmptyList", "[]"); + results.put("noRootPrettyEmptyList", "[\n]"); + results.put("noRootCompactEmptyList", "[]"); + results.put("explicitMinimalEmptyList", "{'list':[[],[]]}"); + results.put("explicitPrettyEmptyList", "{'list': [\n [\n ],\n [\n ]\n]}"); + results.put("explicitCompactEmptyList", "{'list': [\n [],\n []\n]}"); + results.put("optimizedMinimalCustomConverter", "{'h':{'str':'test','protocol':{'id':'ldap'},'i':42}}"); + results.put("optimizedPrettyCustomConverter", "{'h': {\n 'str': 'test',\n 'protocol': {\n 'id': 'ldap'\n },\n 'i': 42\n}}"); + results.put("optimizedCompactCustomConverter", "{'h': {\n 'str': 'test',\n 'protocol': {\n 'id': 'ldap'\n },\n 'i': 42\n}}"); + results.put("noRootMinimalCustomConverter", "{'str':'test','protocol':{'id':'ldap'},'i':42}"); + results.put("noRootPrettyCustomConverter", "{\n 'str': 'test',\n 'protocol': {\n 'id': 'ldap'\n },\n 'i': 42\n}"); + results.put("noRootCompactCustomConverter", "{\n 'str': 'test',\n 'protocol': {\n 'id': 'ldap'\n },\n 'i': 42\n}"); + results.put("explicitMinimalCustomConverter", "{'h':[[],[{'str':[[],['test']]},{'protocol':[[],[{'id':[[],['ldap']]}]]},{'i':[[],[42]]}]]}"); + results.put("explicitPrettyCustomConverter", "{'h': [\n [\n ],\n [\n {\n 'str': [\n [\n ],\n [\n 'test'\n ]\n ]\n },\n {\n 'protocol': [\n [\n ],\n [\n {\n 'id': [\n [\n ],\n [\n 'ldap'\n ]\n ]\n }\n ]\n ]\n },\n {\n 'i': [\n [\n ],\n [\n 42\n ]\n ]\n }\n ]\n]}"); + results.put("explicitCompactCustomConverter", "{'h': [\n [],\n [\n {\n 'str': [\n [],\n [\n 'test'\n ]\n ]\n },\n {\n 'protocol': [\n [],\n [\n {\n 'id': [\n [],\n [\n 'ldap'\n ]\n ]\n }\n ]\n ]\n },\n {\n 'i': [\n [],\n [\n 42\n ]\n ]\n }\n ]\n]}"); + + TestSuite suite = new TestSuite(JsonWriterFormatTest.class.getName()); + for (final Iterator iterMode = modes.entrySet().iterator(); iterMode.hasNext();) { + final Map.Entry entryMode = (Map.Entry)iterMode.next(); + final String modeName = (String)entryMode.getKey(); + final int mode = ((Integer)entryMode.getValue()).intValue(); + for (final Iterator iterFormat = formats.entrySet().iterator(); iterFormat.hasNext();) { + final Map.Entry entryFormat = (Map.Entry)iterFormat.next(); + final String formatName = (String)entryFormat.getKey(); + final JsonWriter.Format format = (JsonWriter.Format)entryFormat.getValue(); + for (final Iterator iterTarget = targets.entrySet().iterator(); iterTarget.hasNext();) { + final Map.Entry entryTarget = (Map.Entry)iterTarget.next(); + final String targetName = (String)entryTarget.getKey(); + final Object target = entryTarget.getValue(); + final String name = modeName + formatName + targetName; + final String result = ((String)results.get(name)).replace('\'', '"'); + + suite.addTest(new JsonWriterFormatTest(name, target, result, mode, format)); + } + } + } + + return suite; + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/json/JsonWriterModeDroppingRootTest.java b/xstream/src/test/com/thoughtworks/xstream/io/json/JsonWriterModeDroppingRootTest.java new file mode 100644 index 0000000..3f6cc2b --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/json/JsonWriterModeDroppingRootTest.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2008, 2011, 2012 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. November 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.json; + +import com.thoughtworks.acceptance.objects.Original; +import com.thoughtworks.acceptance.objects.Replaced; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.List; + + +/** + * Some of these test cases are taken from example JSON listed at + * http://www.json.org/example.html + * + * @author Paul Hammant + * @author Jörg Schaible + */ +public class JsonWriterModeDroppingRootTest extends JsonHierarchicalStreamDriverTest { + + protected void setUp() throws Exception { + super.setUp(); + xstream.aliasSystemAttribute(null, "class"); + xstream.aliasSystemAttribute(null, "resolves-to"); + xstream.aliasSystemAttribute(null, "defined-in"); + } + + protected JsonHierarchicalStreamDriver createDriver() { + return new JsonHierarchicalStreamDriver() { + + public HierarchicalStreamWriter createWriter(Writer out) { + // no root and allow invalid JSON for single values as root object + return new JsonWriter(out, JsonWriter.DROP_ROOT_MODE); + } + }; + } + + protected String normalizeExpectation(final String expected) { + return super.normalizeExpectation(expected.substring( + expected.indexOf(": ") + 2, expected.length() - 1)); + } + + public void testCanMarshalSets() { + // This from http://www.json.org/example.html + xstream.alias("menu", MenuWithSet.class); + xstream.alias("menuitem", MenuItem.class); + + final MenuWithSet menu = new MenuWithSet(); + + final String json = xstream.toXML(menu); + assertTrue(json.startsWith(normalizeExpectation(expectedMenuStart))); + assertTrue(json.indexOf(expectedNew.replace('\'', '"')) > 0); + assertTrue(json.indexOf(expectedOpen.replace('\'', '"')) > 0); + assertTrue(json.indexOf(expectedClose.replace('\'', '"')) > 0); + assertTrue(json.endsWith(expectedMenuEnd.replace('\'', '"').substring( + 0, expectedMenuEnd.length() - 1))); + } + + public void testBracesAndSquareBracketsAreNotEscaped() { + final String expected = ("" // + + "[\n" + + " '..{}[],,'\n" + + "]").replace('\'', '"'); + assertEquals(expected, xstream.toXML(new String[]{"..{}[],,"})); + } + + public void testWillWriteTagValueAsDefaultValueIfNecessary() { + xstream.alias("sa", SystemAttributes.class); + xstream.alias("original", Original.class); + xstream.alias("replaced", Replaced.class); + + SystemAttributes sa = new SystemAttributes(); + sa.name = "joe"; + sa.object = "walnes"; + sa.original = new Original("hello world"); + + String expected = normalizeExpectation("" + + "{'sa': {\n" + + " 'name': 'joe',\n" + + " 'object': 'walnes',\n" + + " 'original': {\n" + + " 'replacedValue': 'HELLO WORLD'\n" + + " }\n" + + "}}"); + + assertEquals(expected, xstream.toXML(sa)); + } + + public void testRealTypeIsHonoredWhenWritingTheValue() { + xstream.alias("sa", SystemAttributes.class); + + List list = new ArrayList(); + list.add("joe"); + list.add("mauro"); + SystemAttributes[] sa = new SystemAttributes[2]; + sa[0] = new SystemAttributes(); + sa[0].name = "year"; + sa[0].object = new Integer(2000); + sa[1] = new SystemAttributes(); + sa[1].name = "names"; + sa[1].object = list; + + String expected = normalizeExpectation("" + + "{'sa-array': [\n" + + " {\n" + + " 'name': 'year',\n" + + " 'object': 2000\n" + + " },\n" + + " {\n" + + " 'name': 'names',\n" + + " 'object': [\n" + + " 'joe',\n" + + " 'mauro'\n" + + " ]\n" + + " }\n" + + "]}"); + + assertEquals(expected, xstream.toXML(sa)); + } + + public void testStrictJSON() { + xstream = new XStream(new JsonHierarchicalStreamDriver() { + + public HierarchicalStreamWriter createWriter(Writer out) { + // do not allow invalid JSON + return new JsonWriter(out, JsonWriter.DROP_ROOT_MODE | JsonWriter.STRICT_MODE); + } + }); + try { + xstream.toXML(new Integer(123)); + fail("Thrown " + ConversionException.class.getName() + " expected"); + } catch (final ConversionException e) { + // OK + } + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/json/JsonWriterModeTest.java b/xstream/src/test/com/thoughtworks/xstream/io/json/JsonWriterModeTest.java new file mode 100644 index 0000000..aa30ad8 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/json/JsonWriterModeTest.java @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2009, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. September 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.json; + +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; + +import com.thoughtworks.acceptance.someobjects.X; +import com.thoughtworks.acceptance.someobjects.Y; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.json.JsonWriter.Format; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + + +/** + * Tests the {@link JsonWriter} formats. + * + * @author Jörg Schaible + */ +public class JsonWriterModeTest extends TestCase { + + private XStream xstream; + private Object target; + private final int mode; + private final Format format; + + public JsonWriterModeTest( + String name, int xstreamMode, int writerMode, JsonWriter.Format format) { + super(name); + this.mode = writerMode; + this.format = format; + + X x = new X(42); + x.aStr = "Codehaus"; + x.innerObj = new Y(); + x.innerObj.yField = "Y"; + + target = new ArrayList(Arrays + .asList(new Object[]{ + new Object[][]{new Object[0]}, + null, + new Integer(42), + new Long(Long.MAX_VALUE), + new Y(), + x.innerObj, + new ArrayList(), + new CharSequence[]{ + "JUnit", "XStream", new StringBuffer("JSON"), new StringBuffer("JScript")}, + x,})); + + xstream = new XStream(); + xstream.setMode(xstreamMode); + xstream.alias("X", X.class); + xstream.alias("Y", Y.class); + xstream.alias("CharSequence", CharSequence.class); + } + + protected void runTest() throws Throwable { + // toConsole(mode, format); + String json = toJSON(mode, format); + assertValidJSON(json); + } + + private static void assertValidJSON(String json) throws JSONException { + JSONObject jsonObject = new JSONObject(json); + assertTrue(equals(jsonObject, new JSONObject(jsonObject.toString()))); + } + + private static boolean equals(JSONObject object1, JSONObject object2) { + String[] names = JSONObject.getNames(object1); + try { + if (names == null) { + return JSONObject.getNames(object2) == null; + } + if (new HashSet(Arrays.asList(names)).equals(new HashSet(Arrays.asList(JSONObject.getNames(object2))))) { + for (int i = 0; i < names.length; i++) { + if (!equals(object1.get(names[i]), object2.get(names[i]))) { + return false; + } + } + return true; + } + } catch (JSONException e) { + // ignore - return false + } + return false; + } + + private static boolean equals(JSONArray array1, JSONArray array2) { + int length = array1.length(); + if (length == array2.length()) { + try { + while (length-- > 0) { + if (!equals(array1.get(length), array2.get(length))) { + return false; + } + } + return true; + } catch (JSONException e) { + // ignore - return false + } + } + return false; + } + + private static boolean equals(Object o1, Object o2) { + if (o1 == null && o2 == null) { + return true; + } else if ((o1 == null && o2 != null) || (o1 != null && o2 == null)) { + return false; + } + Class type = o1.getClass(); + if (type != o2.getClass()) { + return false; + } + if (type == JSONObject.class) { + return equals((JSONObject)o1, (JSONObject)o2); + } else if (type == JSONArray.class) { + return equals((JSONArray)o1, (JSONArray)o2); + } + return o1.equals(o2); + } + + private String toJSON(int mode, JsonWriter.Format format) { + final StringWriter writer = new StringWriter(1024); + writeJSON(writer, mode, format); + return writer.toString(); + } + + private void toConsole(int mode, JsonWriter.Format format) { + System.out.println(xstream.toXML(target)); + try { + writeJSON(new OutputStreamWriter(System.err, "UTF-8"), mode, format); + System.err.println(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void writeJSON(Writer writer, int mode, JsonWriter.Format format) { + JsonWriter jsonWriter = new JsonWriter(writer, mode, format, 0); + xstream.marshal(target, jsonWriter); + jsonWriter.flush(); + } + + public static Test suite() { + JsonWriter.Format compactFormat = new JsonWriter.Format( + new char[0], new char[0], JsonWriter.Format.COMPACT_EMPTY_ELEMENT); + JsonWriter.Format prettyFormat = new JsonWriter.Format(" ".toCharArray(), "\n" + .toCharArray(), JsonWriter.Format.SPACE_AFTER_LABEL); + + TestSuite suite = new TestSuite(JsonWriterModeTest.class.getName()); + suite.addTest(new JsonWriterModeTest( + "optimizedCompact", XStream.NO_REFERENCES, 0, compactFormat)); + suite.addTest(new JsonWriterModeTest( + "optimizedPretty", XStream.NO_REFERENCES, 0, prettyFormat)); + suite.addTest(new JsonWriterModeTest( + "optimizedCompactIEEE754", XStream.NO_REFERENCES, AbstractJsonWriter.IEEE_754_MODE, + compactFormat)); + suite.addTest(new JsonWriterModeTest( + "explicitCompact", XStream.NO_REFERENCES, AbstractJsonWriter.EXPLICIT_MODE, + compactFormat)); + suite.addTest(new JsonWriterModeTest( + "explicitCompactIEEE754", XStream.NO_REFERENCES, AbstractJsonWriter.EXPLICIT_MODE + | AbstractJsonWriter.IEEE_754_MODE, compactFormat)); + suite.addTest(new JsonWriterModeTest( + "explicitPretty", XStream.NO_REFERENCES, AbstractJsonWriter.EXPLICIT_MODE, + prettyFormat)); + suite.addTest(new JsonWriterModeTest( + "optimizedCompactWithIds", XStream.ID_REFERENCES, 0, compactFormat)); + suite.addTest(new JsonWriterModeTest( + "optimizedPrettyWithIds", XStream.ID_REFERENCES, 0, prettyFormat)); + suite.addTest(new JsonWriterModeTest( + "explicitCompactWithIds", XStream.ID_REFERENCES, AbstractJsonWriter.EXPLICIT_MODE, + compactFormat)); + suite.addTest(new JsonWriterModeTest( + "explicitPrettyWithIds", XStream.ID_REFERENCES, AbstractJsonWriter.EXPLICIT_MODE, + prettyFormat)); + + return suite; + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/path/PathTest.java b/xstream/src/test/com/thoughtworks/xstream/io/path/PathTest.java new file mode 100644 index 0000000..3f4a336 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/path/PathTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 02. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.path; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public class PathTest extends TestCase { + + public static Test suite() { + TestSuite result = new TestSuite(PathTest.class.getName()); + + addTest(result, + "/a/b/c", + "/a/b/c", + ".", + ".", + true); + + addTest(result, + "/a", + "/a/b/c", + "b/c", + "b[1]/c[1]", + true); + + addTest(result, + "/a/b/c", + "/a", + "../..", + "../..", + false); + + addTest(result, + "/a/b/c", + "/a/b/X", + "../X", + "../X[1]", + false); + + addTest(result, + "/a/b/c", + "/a/X/c", + "../../X/c", + "../../X[1]/c[1]", + false); + + addTest(result, + "/a/b/c/d", + "/a/X/c", + "../../../X/c", + "../../../X[1]/c[1]", + false); + + addTest(result, + "/a/b/c", + "/a/X/c/d", + "../../X/c/d", + "../../X[1]/c[1]/d[1]", + false); + + addTest(result, + "/a/b/c[2]", + "/a/b/c[3]", + "../c[3]", + "../c[3]", + false); + + addTest(result, + "/a", + "/a[1]", + ".", + ".", + true); + + return result; + } + + private static void addTest(TestSuite suite, final String from, final String to, final String relative, final String explicit, final boolean isAncestor) { + String testName = from + " - " + to; + suite.addTest(new TestCase(testName) { + protected void runTest() throws Throwable { + assertEquals(new Path(relative), new Path(from).relativeTo(new Path(to))); + assertEquals(new Path(to), new Path(from).apply(new Path(relative))); + assertEquals(isAncestor, new Path(from).isAncestor(new Path(to))); + assertEquals(new Path(relative), new Path(explicit)); + assertEquals(new Path(relative).explicit(), explicit); + assertEquals(relative, new Path(explicit).toString()); + } + }); + } + + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/path/PathTrackerTest.java b/xstream/src/test/com/thoughtworks/xstream/io/path/PathTrackerTest.java new file mode 100644 index 0000000..45f5542 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/path/PathTrackerTest.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.path; + +import junit.framework.TestCase; + +public class PathTrackerTest extends TestCase { + + private PathTracker pathTracker; + + protected void setUp() throws Exception { + super.setUp(); + // small initial capacity to ensure resizing works + pathTracker = new PathTracker(1); + } + + public void testExposesXpathLikeExpressionOfLocationInWriter() { + + assertEquals(new Path(""), pathTracker.getPath()); + assertEquals(0, pathTracker.depth()); + + // + pathTracker.pushElement("root"); + assertEquals(new Path("/root"), pathTracker.getPath()); + assertEquals(1, pathTracker.depth()); + assertEquals("root", pathTracker.peekElement()); + + // + pathTracker.pushElement("childA"); + assertEquals(new Path("/root/childA"), pathTracker.getPath()); + assertEquals(2, pathTracker.depth()); + assertEquals("childA", pathTracker.peekElement()); + // + pathTracker.popElement(); + assertEquals(new Path("/root"), pathTracker.getPath()); + assertEquals(1, pathTracker.depth()); + assertEquals("root", pathTracker.peekElement()); + + // + pathTracker.pushElement("childB"); + assertEquals(new Path("/root/childB"), pathTracker.getPath()); + assertEquals(2, pathTracker.depth()); + assertEquals("childB", pathTracker.peekElement()); + + // + pathTracker.pushElement("grandchild"); + assertEquals(new Path("/root/childB/grandchild"), pathTracker.getPath()); + assertEquals(3, pathTracker.depth()); + assertEquals("grandchild", pathTracker.peekElement(0)); + assertEquals("childB", pathTracker.peekElement(-1)); + assertEquals("root", pathTracker.peekElement(-2)); + // + pathTracker.popElement(); + assertEquals(new Path("/root/childB"), pathTracker.getPath()); + assertEquals(2, pathTracker.depth()); + assertEquals("childB", pathTracker.peekElement()); + + // + pathTracker.popElement(); + assertEquals(new Path("/root"), pathTracker.getPath()); + assertEquals(1, pathTracker.depth()); + assertEquals("root", pathTracker.peekElement()); + + // + pathTracker.popElement(); + assertEquals(new Path(""), pathTracker.getPath()); + assertEquals(0, pathTracker.depth()); + + } + + public void testAddsIndexIfSiblingOfSameTypeAlreadyExists() { + + // + pathTracker.pushElement("root"); + + // + pathTracker.pushElement("child"); + assertEquals(new Path("/root/child"), pathTracker.getPath()); + // + pathTracker.popElement(); + + // + pathTracker.pushElement("child"); + assertEquals(new Path("/root/child[2]"), pathTracker.getPath()); + assertEquals("child[2]", pathTracker.peekElement()); + // + pathTracker.popElement(); + + // + pathTracker.pushElement("another"); + assertEquals(new Path("/root/another"), pathTracker.getPath()); + // + pathTracker.popElement(); + + // + pathTracker.pushElement("child"); + assertEquals(new Path("/root/child[3]"), pathTracker.getPath()); + assertEquals("child[3]", pathTracker.peekElement()); + // + pathTracker.popElement(); + + // ... + } + + public void testAssociatesIndexOnlyWithDirectParent() { + + // + pathTracker.pushElement("root"); + + // + pathTracker.pushElement("child"); + + // + pathTracker.pushElement("child"); + assertEquals(new Path("/root/child/child"), pathTracker.getPath()); + // + pathTracker.popElement(); + + // + pathTracker.pushElement("child"); + assertEquals(new Path("/root/child/child[2]"), pathTracker.getPath()); + // + pathTracker.popElement(); + + // + pathTracker.popElement(); + + // + pathTracker.pushElement("child"); + + // + pathTracker.pushElement("child"); + assertEquals(new Path("/root/child[2]/child"), pathTracker.getPath()); + // + pathTracker.popElement(); + + // + pathTracker.pushElement("child"); + assertEquals(new Path("/root/child[2]/child[2]"), pathTracker.getPath()); + + // ... + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/path/PathTrackingReaderTest.java b/xstream/src/test/com/thoughtworks/xstream/io/path/PathTrackingReaderTest.java new file mode 100644 index 0000000..43deafa --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/path/PathTrackingReaderTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.path; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.xml.XppReader; + +import junit.framework.TestCase; + +import org.xmlpull.mxp1.MXParser; + +import java.io.Reader; +import java.io.StringReader; + +public class PathTrackingReaderTest extends TestCase { + + public void testDecoratesReaderAndTracksPath() { + Reader input = new StringReader("" + + "" + + " " + + " " + + " " + + ""); + HierarchicalStreamReader reader = new XppReader(input, new MXParser()); + PathTracker pathTracker = new PathTracker(); + + reader = new PathTrackingReader(reader, pathTracker); + assertEquals(new Path("/a"), pathTracker.getPath()); + + reader.moveDown(); + assertEquals(new Path("/a/b"), pathTracker.getPath()); + + reader.moveDown(); + assertEquals(new Path("/a/b/c"), pathTracker.getPath()); + + reader.moveUp(); + assertEquals(new Path("/a/b"), pathTracker.getPath()); + + reader.moveUp(); + reader.moveDown(); + assertEquals(new Path("/a/b[2]"), pathTracker.getPath()); + + reader.moveUp(); + reader.moveDown(); + assertEquals(new Path("/a/d"), pathTracker.getPath()); + + reader.moveUp(); + assertEquals(new Path("/a"), pathTracker.getPath()); + } + + public void testPathsAreDecodedInTracker() { + Reader input = new StringReader("" + + "" + + " " + + ""); + HierarchicalStreamReader reader = new XppReader(input, new MXParser()); + PathTracker pathTracker = new PathTracker(); + + reader = new PathTrackingReader(reader, pathTracker); + assertEquals(new Path("/a"), pathTracker.getPath()); + + reader.moveDown(); + assertEquals(new Path("/a/b_1"), pathTracker.getPath()); + assertEquals("b_1", pathTracker.peekElement()); + + reader.moveUp(); + assertEquals(new Path("/a"), pathTracker.getPath()); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/path/PathTrackingWriterTest.java b/xstream/src/test/com/thoughtworks/xstream/io/path/PathTrackingWriterTest.java new file mode 100644 index 0000000..d0cbfc3 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/path/PathTrackingWriterTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.path; + +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.xml.CompactWriter; + +import junit.framework.TestCase; + +import java.io.StringWriter; + +public class PathTrackingWriterTest extends TestCase { + private StringWriter out; + private HierarchicalStreamWriter writer; + private PathTracker pathTracker; + + protected void setUp() throws Exception { + super.setUp(); + pathTracker = new PathTracker(); + out = new StringWriter(); + HierarchicalStreamWriter originalWriter = new CompactWriter(out); + + writer = new PathTrackingWriter(originalWriter, pathTracker); + } + + public void testDecoratesXmlWriterProxyingAllInvocations() { + + writer.startNode("foo"); + writer.addAttribute("att", "something"); + writer.setValue("getValue"); + writer.endNode(); + + assertEquals("getValue", out.toString()); + } + + public void testInterceptsWhenWriterMovesLocationInDocumentAndUpdatesPathTracker() { + + assertEquals(new Path(""), pathTracker.getPath()); + + writer.startNode("foo"); + assertEquals(new Path("/foo"), pathTracker.getPath()); + + writer.startNode("do"); + assertEquals(new Path("/foo/do"), pathTracker.getPath()); + + writer.endNode(); + assertEquals(new Path("/foo"), pathTracker.getPath()); + + writer.endNode(); + assertEquals(new Path(""), pathTracker.getPath()); + } + + public void testEncodesPathInTracker() { + assertEquals(new Path(""), pathTracker.getPath()); + + writer.startNode("foo"); + assertEquals(new Path("/foo"), pathTracker.getPath()); + + writer.startNode("b_1"); + assertEquals(new Path("/foo/b__1"), pathTracker.getPath()); + assertEquals("b__1", pathTracker.peekElement()); + + writer.endNode(); + assertEquals(new Path("/foo"), pathTracker.getPath()); + + writer.endNode(); + assertEquals(new Path(""), pathTracker.getPath()); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/AbstractDocumentWriterTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/AbstractDocumentWriterTest.java new file mode 100644 index 0000000..3987757 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/AbstractDocumentWriterTest.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 19. October 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.copy.HierarchicalStreamCopier; +import com.thoughtworks.xstream.io.xml.xppdom.XppDom; + +import junit.framework.TestCase; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + + +public abstract class AbstractDocumentWriterTest extends TestCase { + + private final HierarchicalStreamCopier copier = new HierarchicalStreamCopier(); + protected DocumentWriter writer; + + protected abstract DocumentReader createDocumentReaderFor(Object node); + + protected void assertDocumentProducedIs(final XppDom expected) { + assertDocumentProducedIs(new XppDom[]{expected}); + } + + protected boolean equals(final XppDom node1, final XppDom node2) { + if (node1.getName().equals(node2.getName())) { + final String value1 = node1.getValue(); + final String value2 = node2.getValue(); + if ((value1 == null && value2 == null) || value1.equals(value2)) { + final Set set1 = new HashSet(Arrays.asList(node1.getAttributeNames())); + final Set set2 = new HashSet(Arrays.asList(node2.getAttributeNames())); + if (set1.equals(set2)) { + final XppDom[] children1 = node1.getChildren(); + final XppDom[] children2 = node2.getChildren(); + if (children1.length == children2.length) { + for (int i = 0; i < children1.length; i++) { + if (!equals(children1[i], children2[i])) { + return false; + } + } + return true; + } + } + } + } + return false; + } + + protected void assertDocumentProducedIs(final XppDom[] expected) { + for (int i = 0; i < expected.length; i++) { + copier.copy(new XppDomReader(expected[i]), writer); + } + final Object[] nodes = writer.getTopLevelNodes().toArray(new Object[0]); + assertEquals(expected.length, nodes.length); + for (int i = 0; i < nodes.length; i++) { + final XppDomWriter xpp3 = new XppDomWriter(); + copier.copy(createDocumentReaderFor(nodes[i]), xpp3); + assertTrue(equals(expected[i], xpp3.getConfiguration())); + } + } + + public void testProducesDomElements() { + final XppDom root = new XppDom("hello"); + root.setValue("world"); + assertDocumentProducedIs(root); + } + + public void testSupportsNestedElements() { + final XppDom a = new XppDom("a"); + + XppDom b = new XppDom("b"); + b.setValue("one"); + a.addChild(b); + + b = new XppDom("b"); + b.setValue("two"); + a.addChild(b); + + final XppDom c = new XppDom("c"); + a.addChild(c); + final XppDom d = new XppDom("d"); + d.setValue("three"); + c.addChild(d); + + assertDocumentProducedIs(a); + } + + public void testSupportsAttributes() { + final XppDom person = new XppDom("person"); + person.setAttribute("firstname", "Joe"); + person.setAttribute("lastname", "Walnes"); + assertDocumentProducedIs(person); + } + + public void testAttributesAreResettedForNewNode() { + final XppDom[] roots = new XppDom[2]; + final XppDom person = roots[0] = new XppDom("person"); + person.setAttribute("firstname", "Joe"); + person.setAttribute("lastname", "Walnes"); + final XppDom project = roots[1] = new XppDom("project"); + project.setAttribute("XStream", "Codehaus"); + + assertDocumentProducedIs(roots); + } + + public void testSupportsEmptyNestedTags() { + final XppDom parent = new XppDom("parent"); + parent.addChild(new XppDom("child")); + + assertDocumentProducedIs(parent); + } + + protected void assertDocumentProducedIs(final XppDom expected, final XppDom tree) + { + copier.copy(new XppDomReader(tree), writer); + + final Object[] nodes = writer.getTopLevelNodes().toArray(new Object[0]); + assertEquals(1, nodes.length); + for (int i = 0; i < nodes.length; i++) { + final XppDomWriter xpp3 = new XppDomWriter(); + copier.copy(createDocumentReaderFor(nodes[i]), xpp3); + assertTrue(equals(expected, xpp3.getConfiguration())); + } + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/AbstractStaxWriterTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/AbstractStaxWriterTest.java new file mode 100644 index 0000000..2f47210 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/AbstractStaxWriterTest.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. November 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.acceptance.someobjects.X; +import com.thoughtworks.acceptance.someobjects.Y; +import com.thoughtworks.xstream.XStream; + +import org.apache.oro.text.perl.Perl5Util; + +import javax.xml.namespace.QName; + +import java.io.StringWriter; + +public abstract class AbstractStaxWriterTest extends AbstractXMLWriterTest { + + protected StringWriter buffer; + protected Perl5Util perlUtil; + protected StaxDriver staxDriver; + private X testInput; + + protected abstract String getXMLHeader(); + + protected abstract StaxDriver getStaxDriver(); + + protected void setUp() throws Exception { + super.setUp(); + staxDriver = getStaxDriver(); + staxDriver.setRepairingNamespace(false); + buffer = new StringWriter(); + writer = staxDriver.createWriter(buffer); + perlUtil = new Perl5Util(); + + testInput = new X(); + testInput.anInt = 9; + testInput.aStr = "zzz"; + testInput.innerObj = new Y(); + testInput.innerObj.yField = "ooo"; + } + + public void testNamespacedXmlWithPrefix() throws Exception { + QNameMap qnameMap = new QNameMap(); + QName qname = new QName("http://foo.com", "alias", "foo"); + qnameMap.registerMapping(qname, X.class); + + String expected = "zzz9ooo"; + marshalWithBothRepairingModes(qnameMap, expected); + } + + public void testNamespacedXmlWithoutPrefix() throws Exception { + QNameMap qnameMap = new QNameMap(); + QName qname = new QName("http://foo.com", "bar"); + qnameMap.registerMapping(qname, X.class); + + String expected = "zzz9ooo"; + marshalWithBothRepairingModes(qnameMap, expected); + } + + public void testNamespacedXmlWithPrefixTwice() throws Exception { + QNameMap qnameMap = new QNameMap(); + QName qname = new QName("http://foo.com", "alias", "foo"); + qnameMap.registerMapping(qname, X.class); + + qname = new QName("http://bar.com", "alias1", "bar"); + qnameMap.registerMapping(qname, "aStr"); + + qname = new QName("http://bar.com", "alias2", "bar"); + qnameMap.registerMapping(qname, "anInt"); + + String expected = "zzz9ooo"; + marshalWithBothRepairingModes(qnameMap, expected); + } + + protected void marshalWithBothRepairingModes(QNameMap qnameMap, String expected) { + marshalNonRepairing(qnameMap, expected); + marshalRepairing(qnameMap, expected); + } + + protected void marshalRepairing(QNameMap qnameMap, String expected) { + marshall(qnameMap, true); + assertXmlProducedIs(expected); + } + + protected void marshalNonRepairing(QNameMap qnameMap, String expected) { + marshall(qnameMap, false); + assertXmlProducedIs(expected); + } + + protected void marshall(QNameMap qnameMap, boolean repairNamespaceMode) { + staxDriver.setRepairingNamespace(repairNamespaceMode); + staxDriver.setQnameMap(qnameMap); + XStream xstream = new XStream(staxDriver); + buffer = new StringWriter(); + xstream.toXML(testInput, buffer); + } + +} \ No newline at end of file diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/AbstractXMLReaderTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/AbstractXMLReaderTest.java new file mode 100644 index 0000000..7f818ef --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/AbstractXMLReaderTest.java @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2011, 2012, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; + +import junit.framework.TestCase; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public abstract class AbstractXMLReaderTest extends TestCase { + + // factory method + protected abstract HierarchicalStreamReader createReader(String xml) throws Exception; + + public void testStartsAtRootTag() throws Exception { + HierarchicalStreamReader xmlReader = createReader(""); + assertEquals("hello", xmlReader.getNodeName()); + } + + public void testCanNavigateDownChildTagsByIndex() throws Exception { + HierarchicalStreamReader xmlReader = createReader(""); + + assertEquals("a", xmlReader.getNodeName()); + + assertTrue(xmlReader.hasMoreChildren()); + + xmlReader.moveDown(); // /a/b + + assertEquals("b", xmlReader.getNodeName()); + + assertTrue(xmlReader.hasMoreChildren()); + + xmlReader.moveDown(); // a/b/ooh + assertEquals("ooh", xmlReader.getNodeName()); + assertFalse(xmlReader.hasMoreChildren()); + xmlReader.moveUp(); // a/b + + assertFalse(xmlReader.hasMoreChildren()); + + xmlReader.moveUp(); // /a + + assertTrue(xmlReader.hasMoreChildren()); + + xmlReader.moveDown(); // /a/b[2] + + assertEquals("b", xmlReader.getNodeName()); + + assertTrue(xmlReader.hasMoreChildren()); + + xmlReader.moveDown(); // a/b[2]/aah + + assertEquals("aah", xmlReader.getNodeName()); + assertFalse(xmlReader.hasMoreChildren()); + + xmlReader.moveUp(); // a/b[2] + + assertFalse(xmlReader.hasMoreChildren()); + + xmlReader.moveUp(); // a + + assertFalse(xmlReader.hasMoreChildren()); + } + + public void testChildTagsCanBeMixedWithOtherNodes() throws Exception { + HierarchicalStreamReader xmlReader = createReader(" getValue "); + + assertTrue(xmlReader.hasMoreChildren()); + xmlReader.moveDown(); + assertEquals("hello", xmlReader.getNodeName()); + xmlReader.moveUp(); + + assertTrue(xmlReader.hasMoreChildren()); + xmlReader.moveDown(); + assertEquals("world", xmlReader.getNodeName()); + xmlReader.moveUp(); + + assertFalse(xmlReader.hasMoreChildren()); + } + + public void testAttributesCanBeFetchedFromTags() throws Exception { + HierarchicalStreamReader xmlReader = createReader("" + + "" + + " " + + ""); // /hello + + assertEquals("1", xmlReader.getAttribute("one")); + assertEquals("2", xmlReader.getAttribute("two")); + assertNull(xmlReader.getAttribute("three")); + + xmlReader.moveDown(); // /hello/child + assertNull(xmlReader.getAttribute("one")); + assertNull(xmlReader.getAttribute("two")); + assertEquals("3", xmlReader.getAttribute("three")); + + } + + public void testTextCanBeExtractedFromTag() throws Exception { + HierarchicalStreamReader xmlReader = createReader( + "some getValue!"); + + xmlReader.moveDown(); + assertEquals("some getValue!", xmlReader.getValue()); + xmlReader.moveUp(); + + xmlReader.moveDown(); + assertEquals("more&&more;", xmlReader.getValue()); + xmlReader.moveUp(); + } + + public void testDoesNotIgnoreWhitespaceAroundText() throws Exception { + HierarchicalStreamReader xmlReader = createReader(" hello world "); + + assertEquals(" hello world ", xmlReader.getValue()); + } + + public void testReturnsEmptyStringForEmptyTags() throws Exception { + HierarchicalStreamReader xmlReader = createReader(""); + + String text = xmlReader.getValue(); + assertNotNull(text); + assertEquals("", text); + } + + public void testReturnsLastResultForHasMoreChildrenIfCalledRepeatedlyWithoutMovingNode() throws Exception { + HierarchicalStreamReader xmlReader = createReader(""); + + assertEquals("row", xmlReader.getNodeName()); + assertTrue(xmlReader.hasMoreChildren()); // this is OK + assertTrue(xmlReader.hasMoreChildren()); // this fails + } + + public void testExposesAttributesKeysAndValuesByIndex() throws Exception { + HierarchicalStreamReader xmlReader = createReader(""); + + assertEquals(3, xmlReader.getAttributeCount()); + + assertEquals("hello", xmlReader.getAttributeName(0)); + assertEquals("a", xmlReader.getAttributeName(1)); + assertEquals("c", xmlReader.getAttributeName(2)); + + assertEquals("world", xmlReader.getAttribute(0)); + assertEquals("b", xmlReader.getAttribute(1)); + assertEquals("d", xmlReader.getAttribute(2)); + + xmlReader.moveDown(); + assertEquals("empty", xmlReader.getNodeName()); + assertEquals(0, xmlReader.getAttributeCount()); + } + + public void testExposesAttributesKeysAsIterator() throws Exception { + HierarchicalStreamReader xmlReader = createReader(""); + + Set expected = new HashSet(); + expected.add("hello"); + expected.add("a"); + expected.add("c"); + + Set actual = new HashSet(); + Iterator iterator; + + iterator = xmlReader.getAttributeNames(); + while(iterator.hasNext()) { + actual.add(iterator.next()); + } + assertEquals(expected, actual); + + // again, to check iteration is repeatable + iterator = xmlReader.getAttributeNames(); + while(iterator.hasNext()) { + actual.add(iterator.next()); + } + assertEquals(expected, actual); + } + + public void testAllowsValueToBeReadWithoutDisturbingChildren() throws Exception { + HierarchicalStreamReader xmlReader + = createReader("text2"); // at: /root + + assertEquals("root", xmlReader.getNodeName()); + assertEquals("", xmlReader.getValue()); + assertTrue(xmlReader.hasMoreChildren()); + + xmlReader.moveDown(); // at: /root/child + assertEquals("child", xmlReader.getNodeName()); + assertEquals(null, xmlReader.getAttribute("something")); + assertEquals("", xmlReader.getValue()); + + assertFalse(xmlReader.hasMoreChildren()); // <--- This is an awkward one for pull parsers + + xmlReader.moveUp(); // at: /root + + assertTrue(xmlReader.hasMoreChildren()); + + xmlReader.moveDown(); // at: /root/sibling + assertEquals("sibling", xmlReader.getNodeName()); + assertEquals("text2", xmlReader.getValue()); + assertFalse(xmlReader.hasMoreChildren()); + xmlReader.moveUp(); // at: /root + + assertFalse(xmlReader.hasMoreChildren()); + } + + public void testExposesTextValueOfCurrentElementButNotChildren() throws Exception { + HierarchicalStreamReader xmlReader + = createReader("helloFNARR"); + + assertEquals("hello", xmlReader.getValue()); + xmlReader.moveDown(); + assertEquals("FNARR", xmlReader.getValue()); + } + + public void testCanReadLineFeedInString() throws Exception { + HierarchicalStreamReader xmlReader = createReader("a\nb"); + assertEquals("a\nb", xmlReader.getValue()); + } + + public void testCanReadEncodedAttribute() throws Exception { + HierarchicalStreamReader xmlReader = createReader(""); + assertEquals("value", xmlReader.getAttribute("_attr")); + } + + public void testCanReadAttributeWithEncodedWhitespace() throws Exception { + HierarchicalStreamReader xmlReader = createReader(""); + assertEquals(" A B C\t\n\r ", xmlReader.getAttribute("attr")); + } + + public void testCanReadCDATAWithEmbeddedTags() throws Exception { + String content = "the content"; + HierarchicalStreamReader xmlReader = createReader(""); + assertEquals(content, xmlReader.getValue()); + } + + // TODO: See XSTR-473 + public void todoTestCanReadNullValueInString() throws Exception { + HierarchicalStreamReader xmlReader = createReader(""); + assertEquals("\u0000", xmlReader.getValue()); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/AbstractXMLWriterTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/AbstractXMLWriterTest.java new file mode 100644 index 0000000..8cad0b9 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/AbstractXMLWriterTest.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 05. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + +import junit.framework.TestCase; + +public abstract class AbstractXMLWriterTest extends TestCase { + + protected HierarchicalStreamWriter writer; + + protected abstract void assertXmlProducedIs(String expected); + + // String.replaceAll is JDK 1.4 + protected String replaceAll(String s, final String occurance, final String replacement) { + final int len = occurance.length(); + final int inc = len - replacement.length(); + int i = -inc; + final StringBuffer buff = new StringBuffer(s); + // StringBuffer has no indexOf in JDK 1.3 + while((i = buff.toString().indexOf(occurance, i + inc)) >= 0) { + buff.replace(i, i + len, replacement); + } + return buff.toString(); + } + + public void testProducesXmlElements() { + writer.startNode("hello"); + writer.setValue("world"); + writer.endNode(); + + assertXmlProducedIs("world"); + } + + public void testSupportsNestedElements() { + + writer.startNode("a"); + + writer.startNode("b"); + writer.setValue("one"); + writer.endNode(); + + writer.startNode("b"); + writer.setValue("two"); + writer.endNode(); + + writer.startNode("c"); + writer.startNode("d"); + writer.setValue("three"); + writer.endNode(); + writer.endNode(); + + writer.endNode(); + + assertXmlProducedIs("onetwothree"); + } + + public void testSupportsEmptyTags() { + writer.startNode("empty"); + writer.endNode(); + + assertXmlProducedIs(""); + } + + public void testSupportsAttributes() { + writer.startNode("person"); + writer.addAttribute("firstname", "Joe"); + writer.addAttribute("lastname", "Walnes"); + writer.endNode(); + + assertXmlProducedIs(""); + } + + public void testAttributesAreResettedForNewNode() { + writer.startNode("work"); + writer.startNode("person"); + writer.addAttribute("firstname", "Joe"); + writer.addAttribute("lastname", "Walnes"); + writer.endNode(); + writer.startNode("project"); + writer.addAttribute("XStream", "Codehaus"); + writer.endNode(); + writer.endNode(); + + assertXmlProducedIs(""); + } + + public void testEscapesXmlUnfriendlyCharacters() { + writer.startNode("evil"); + writer.addAttribute("attr", "w0000 $ &!;"); + writer.setValue("w0000 $ &!;"); + writer.endNode(); + + assertXmlProducedIs("w0000 $ <xx> &!;"); + } + + public void testEscapesWhitespaceCharactersInValue() { + writer.startNode("evil"); + writer.setValue(" one\ntwo\rthree\r\nfour\n\r five\tsix "); + writer.endNode(); + + assertXmlProducedIs(" one\n" + + "two three \n" + + "four\n" + + " five\tsix "); + } + + public void testEscapesWhitespaceCharactersInAttribute() { + writer.startNode("evil"); + writer.addAttribute("attr", " one\ntwo\rthree\r\nfour\n\r five\tsix "); + writer.endNode(); + + assertXmlProducedIs(""); + } + + public void testSupportsEmptyNestedTags() { + writer.startNode("parent"); + writer.startNode("child"); + writer.endNode(); + writer.endNode(); + + assertXmlProducedIs(""); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/BEAStaxReaderTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/BEAStaxReaderTest.java new file mode 100644 index 0000000..cc2a10a --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/BEAStaxReaderTest.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. September 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.HierarchicalStreamDriver; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; + +import java.io.StringReader; + +public class BEAStaxReaderTest extends AbstractXMLReaderTest { + + private HierarchicalStreamDriver driver = new BEAStaxDriver(); + + // factory method + protected HierarchicalStreamReader createReader(String xml) throws Exception { + return driver.createReader(new StringReader(xml)); + } + + // inherits tests from superclass +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/BEAStaxWriterTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/BEAStaxWriterTest.java new file mode 100644 index 0000000..e6d1181 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/BEAStaxWriterTest.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. November 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +public final class BEAStaxWriterTest extends AbstractStaxWriterTest { + protected void assertXmlProducedIs(String expected) { + expected = perlUtil.substitute("s# xmlns=\"\"##g", expected); + expected = perlUtil.substitute("s#<(\\w+)([^>]*)/>#<$1$2>#g", expected); + expected = replaceAll(expected, " ", " "); + expected = replaceAll(expected, " ", " "); + expected = replaceAll(expected, " ", " "); + expected = getXMLHeader() + expected; + assertEquals(expected, buffer.toString()); + } + + protected String getXMLHeader() { + return ""; + } + + protected StaxDriver getStaxDriver() { + return new BEAStaxDriver(); + } + + protected void marshalRepairing(QNameMap qnameMap, String expected) { + // repairing mode fails for BEA's reference implementation in this case + if (!getName().equals("testNamespacedXmlWithPrefixTwice")) + super.marshalRepairing(qnameMap, expected); + } +} \ No newline at end of file diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/CompactWriterTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/CompactWriterTest.java new file mode 100644 index 0000000..5251263 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/CompactWriterTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.core.util.QuickWriter; + +import java.io.StringWriter; +import java.io.Writer; + +public class CompactWriterTest extends AbstractXMLWriterTest { + private Writer buffer; + + protected void setUp() throws Exception { + super.setUp(); + buffer = new StringWriter(); + writer = new CompactWriter(buffer); + } + + protected void assertXmlProducedIs(String expected) { + assertEquals(expected, buffer.toString()); + } + + public void testXmlIsIndented() { + writer.startNode("hello"); + writer.startNode("world"); + + writer.startNode("one"); + writer.setValue("potato"); + writer.endNode(); + + writer.startNode("two"); + writer.setValue("potatae"); + writer.endNode(); + + writer.endNode(); + writer.endNode(); + + String expected = "potatopotatae"; + assertXmlProducedIs(expected); + } + + public void testEncodesFunnyXmlChars() { + writer.startNode("tag"); + writer.setValue("hello & this isn't \"really\" "); + writer.endNode(); + + String expected = "hello & this isn't "really" <good>"; + + assertXmlProducedIs(expected); + } + + public void testWriteTextAsCDATA() { + writer = new CompactWriter(buffer) { + protected void writeText(QuickWriter writer, String text) { + writer.write(""); + } + }; + + writer.startNode("tag"); + writer.setValue("hello & this isn't \"really\" "); + writer.endNode(); + + String expected = "]]>"; + + assertXmlProducedIs(expected); + } + + public void testAttributesCanBeWritten() { + writer.startNode("tag"); + writer.addAttribute("hello", "world"); + writer.startNode("inner"); + writer.addAttribute("foo", "bar"); + writer.addAttribute("poo", "par"); + writer.setValue("hi"); + writer.endNode(); + writer.endNode(); + + String expected = "" + + "" + + "hi" + + ""; + + assertXmlProducedIs(expected); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/Dom4JReaderTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/Dom4JReaderTest.java new file mode 100644 index 0000000..a6a7ad7 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/Dom4JReaderTest.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; + +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.DocumentHelper; +import org.dom4j.Element; + +public class Dom4JReaderTest extends AbstractXMLReaderTest { + + // factory method + protected HierarchicalStreamReader createReader(String xml) throws Exception { + return new Dom4JReader(DocumentHelper.parseText(xml)); + } + + public void testCanReadFromElementOfLargerDocument() throws DocumentException { + Document document = DocumentHelper.parseText("" + + "" + + " " + + " " + + " " + + " " + + " " + + ""); + Element small = document.getRootElement().element("small"); + + HierarchicalStreamReader xmlReader = new Dom4JReader(small); + assertEquals("small", xmlReader.getNodeName()); + xmlReader.moveDown(); + assertEquals("tiny", xmlReader.getNodeName()); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/Dom4JWriterTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/Dom4JWriterTest.java new file mode 100644 index 0000000..f58c043 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/Dom4JWriterTest.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 05. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import org.dom4j.Element; + +public class Dom4JWriterTest extends AbstractDocumentWriterTest { + + protected void setUp() throws Exception { + super.setUp(); + writer = new Dom4JWriter(); + } + + protected DocumentReader createDocumentReaderFor(final Object node) { + return new Dom4JReader((Element)node); + } + + // inherits tests from superclass +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/Dom4JXmlWriterTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/Dom4JXmlWriterTest.java new file mode 100644 index 0000000..243a814 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/Dom4JXmlWriterTest.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 05. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import org.dom4j.io.OutputFormat; + +import java.io.StringWriter; + +public class Dom4JXmlWriterTest extends AbstractXMLWriterTest { + + private StringWriter out; + + protected void setUp() throws Exception { + super.setUp(); + + Dom4JDriver driver = new Dom4JDriver(); + + OutputFormat format = OutputFormat.createCompactFormat(); + format.setTrimText(false); + format.setSuppressDeclaration(true); + driver.setOutputFormat(format); + + out = new StringWriter(); + writer = driver.createWriter(out); + } + + protected void assertXmlProducedIs(String expected) { + writer.close(); + expected = replaceAll(expected, " ", "\r"); + // attributes are not properly escaped + expected = replaceAll(expected, " ", "\n"); + expected = replaceAll(expected, " ", "\t"); + assertEquals(expected, out.toString()); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/DomReaderTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/DomReaderTest.java new file mode 100644 index 0000000..ab94ebe --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/DomReaderTest.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import java.io.ByteArrayInputStream; +import java.util.HashMap; +import java.util.Map; + +public class DomReaderTest extends AbstractXMLReaderTest { + + // factory method + protected HierarchicalStreamReader createReader(String xml) throws Exception { + return new DomReader(buildDocument(xml)); + } + + private Document buildDocument(String xml) throws Exception { + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + ByteArrayInputStream inputStream = new ByteArrayInputStream(xml.getBytes()); + Document document = documentBuilder.parse(inputStream); + return document; + } + + public void testCanReadFromElementOfLargerDocument() throws Exception { + Document document = buildDocument("" + + "" + + " " + + " " + + " " + + " " + + " " + + ""); + Element small = (Element) document.getDocumentElement().getElementsByTagName("small").item(0); + + HierarchicalStreamReader xmlReader = new DomReader(small); + assertEquals("small", xmlReader.getNodeName()); + xmlReader.moveDown(); + assertEquals("tiny", xmlReader.getNodeName()); + } + + public void testExposesAttributesKeysAndValuesByIndex() throws Exception { + + // overrides test in superclass, because DOM does not retain order of actualAttributes. + + HierarchicalStreamReader xmlReader = createReader(""); + + assertEquals(3, xmlReader.getAttributeCount()); + + Map expectedAttributes = new HashMap(); + expectedAttributes.put("hello", "world"); + expectedAttributes.put("a", "b"); + expectedAttributes.put("c", "d"); + + Map actualAttributes = new HashMap(); + for (int i = 0; i < xmlReader.getAttributeCount(); i++) { + String name = xmlReader.getAttributeName(i); + String value = xmlReader.getAttribute(i); + actualAttributes.put(name, value); + } + + assertEquals(expectedAttributes, actualAttributes); + + xmlReader.moveDown(); + assertEquals("empty", xmlReader.getNodeName()); + assertEquals(0, xmlReader.getAttributeCount()); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/DomWriterTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/DomWriterTest.java new file mode 100644 index 0000000..0435fe1 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/DomWriterTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 05. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import com.thoughtworks.xstream.io.copy.HierarchicalStreamCopier; +import com.thoughtworks.xstream.io.xml.xppdom.XppDom; + +public class DomWriterTest extends AbstractDocumentWriterTest { + + private Document document; + + protected void setUp() throws Exception { + super.setUp(); + final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + final DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + document = documentBuilder.newDocument(); + writer = new DomWriter(document); + } + + protected DocumentReader createDocumentReaderFor(final Object node) { + return new DomReader((Element)node); + } + + // inherits tests from superclass + + public void testCanWriteIntoArbitraryNode() { + Element root = document.createElement("root"); + document.appendChild(root); + Element a = document.createElement("a"); + root.appendChild(a); + writer = new DomWriter(a, document, new XmlFriendlyNameCoder()); + + final XppDom xppRoot = new XppDom("root"); + XppDom xppA = new XppDom("a"); + xppRoot.addChild(xppA); + XppDom xppB = new XppDom("b"); + xppA.addChild(xppB); + xppB.setAttribute("attr", "foo"); + + assertDocumentProducedIs(xppA, xppB); + XppDomWriter xppDomWriter = new XppDomWriter(); + new HierarchicalStreamCopier().copy(createDocumentReaderFor(document.getDocumentElement()), xppDomWriter); + assertTrue(equals(xppRoot, xppDomWriter.getConfiguration())); + } + + public void testCanWriteIntoArbitraryNodeAgain() { + Element root = document.createElement("root"); + document.appendChild(root); + Element a = document.createElement("a"); + root.appendChild(a); + writer = new DomWriter(a); + + final XppDom xppRoot = new XppDom("root"); + XppDom xppA = new XppDom("a"); + xppRoot.addChild(xppA); + XppDom xppB = new XppDom("b"); + xppA.addChild(xppB); + xppB.setAttribute("attr", "foo"); + + assertDocumentProducedIs(xppA, xppB); + XppDomWriter xppDomWriter = new XppDomWriter(); + new HierarchicalStreamCopier().copy(createDocumentReaderFor(document.getDocumentElement()), xppDomWriter); + assertTrue(equals(xppRoot, xppDomWriter.getConfiguration())); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/JDom2AcceptanceTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/JDom2AcceptanceTest.java new file mode 100644 index 0000000..24ac7e9 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/JDom2AcceptanceTest.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. June 2012 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import java.io.StringReader; +import java.util.List; + +import junit.framework.TestCase; + +import org.jdom2.Document; +import org.jdom2.input.SAXBuilder; +import org.jdom2.output.Format; +import org.jdom2.output.XMLOutputter; + +import com.thoughtworks.acceptance.someobjects.X; +import com.thoughtworks.acceptance.someobjects.Y; +import com.thoughtworks.xstream.XStream; + +public class JDom2AcceptanceTest extends TestCase { + + private XStream xstream; + + protected void setUp() throws Exception { + super.setUp(); + xstream = new XStream(); + xstream.alias("x", X.class); + } + + public void testUnmarshalsObjectFromJDOM() throws Exception { + String xml = + "" + + " joe" + + " 8" + + " " + + " walnes" + + " " + + ""; + + Document doc = new SAXBuilder().build(new StringReader(xml)); + + X x = (X) xstream.unmarshal(new JDom2Reader(doc)); + + assertEquals("joe", x.aStr); + assertEquals(8, x.anInt); + assertEquals("walnes", x.innerObj.yField); + } + + public void testMarshalsObjectToJDOM() { + X x = new X(); + x.anInt = 9; + x.aStr = "zzz"; + x.innerObj = new Y(); + x.innerObj.yField = "ooo"; + + String expected = + "\n" + + " zzz\n" + + " 9\n" + + " \n" + + " ooo\n" + + " \n" + + ""; + + JDom2Writer writer = new JDom2Writer(); + xstream.marshal(x, writer); + List result = writer.getTopLevelNodes(); + + assertEquals("Result list should contain exactly 1 element", + 1, result.size()); + + XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat().setLineSeparator("\n")); + + assertEquals(expected, outputter.outputString(result)); + } +} + diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/JDom2ReaderTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/JDom2ReaderTest.java new file mode 100644 index 0000000..8d763a4 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/JDom2ReaderTest.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. June 2012 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; + +import org.jdom2.Document; +import org.jdom2.input.SAXBuilder; + +import java.io.StringReader; + +public class JDom2ReaderTest extends AbstractXMLReaderTest { + + // factory method + protected HierarchicalStreamReader createReader(String xml) throws Exception { + Document document = new SAXBuilder().build(new StringReader(xml)); + return new JDom2Reader(document); + } + + // inherits tests from superclass + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/JDom2WriterTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/JDom2WriterTest.java new file mode 100644 index 0000000..066dd9e --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/JDom2WriterTest.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 24. June 2012 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import org.jdom2.Element; + +public class JDom2WriterTest extends AbstractDocumentWriterTest { + + protected void setUp() throws Exception { + super.setUp(); + writer = new JDom2Writer(); + } + + protected DocumentReader createDocumentReaderFor(final Object node) { + return new JDom2Reader((Element)node); + } + + // inherits tests from superclass +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/JDomAcceptanceTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/JDomAcceptanceTest.java new file mode 100644 index 0000000..946ad82 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/JDomAcceptanceTest.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import java.io.StringReader; +import java.util.List; + +import junit.framework.TestCase; + +import org.jdom.Document; +import org.jdom.input.SAXBuilder; +import org.jdom.output.Format; +import org.jdom.output.XMLOutputter; + +import com.thoughtworks.acceptance.someobjects.X; +import com.thoughtworks.acceptance.someobjects.Y; +import com.thoughtworks.xstream.XStream; + +public class JDomAcceptanceTest extends TestCase { + + private XStream xstream; + + protected void setUp() throws Exception { + super.setUp(); + xstream = new XStream(); + xstream.alias("x", X.class); + } + + public void testUnmarshalsObjectFromJDOM() throws Exception { + String xml = + "" + + " joe" + + " 8" + + " " + + " walnes" + + " " + + ""; + + Document doc = new SAXBuilder().build(new StringReader(xml)); + + X x = (X) xstream.unmarshal(new JDomReader(doc)); + + assertEquals("joe", x.aStr); + assertEquals(8, x.anInt); + assertEquals("walnes", x.innerObj.yField); + } + + public void testMarshalsObjectToJDOM() { + X x = new X(); + x.anInt = 9; + x.aStr = "zzz"; + x.innerObj = new Y(); + x.innerObj.yField = "ooo"; + + String expected = + "\n" + + " zzz\n" + + " 9\n" + + " \n" + + " ooo\n" + + " \n" + + ""; + + JDomWriter writer = new JDomWriter(); + xstream.marshal(x, writer); + List result = writer.getTopLevelNodes(); + + assertEquals("Result list should contain exactly 1 element", + 1, result.size()); + + XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat().setLineSeparator("\n")); + + assertEquals(expected, outputter.outputString(result)); + } +} + diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/JDomReaderTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/JDomReaderTest.java new file mode 100644 index 0000000..506cb86 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/JDomReaderTest.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 09. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; + +import org.jdom.Document; +import org.jdom.input.SAXBuilder; + +import java.io.StringReader; + +public class JDomReaderTest extends AbstractXMLReaderTest { + + // factory method + protected HierarchicalStreamReader createReader(String xml) throws Exception { + Document document = new SAXBuilder().build(new StringReader(xml)); + return new JDomReader(document); + } + + // inherits tests from superclass + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/JDomWriterTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/JDomWriterTest.java new file mode 100644 index 0000000..ac31ab2 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/JDomWriterTest.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 09. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import org.jdom.Element; + +public class JDomWriterTest extends AbstractDocumentWriterTest { + + protected void setUp() throws Exception { + super.setUp(); + writer = new JDomWriter(); + } + + protected DocumentReader createDocumentReaderFor(final Object node) { + return new JDomReader((Element)node); + } + + // inherits tests from superclass +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/KXml2ReaderTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/KXml2ReaderTest.java new file mode 100644 index 0000000..8d7f8ae --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/KXml2ReaderTest.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. September 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.HierarchicalStreamDriver; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; + +import java.io.StringReader; + +public class KXml2ReaderTest extends AbstractXMLReaderTest { + + private HierarchicalStreamDriver driver = new KXml2Driver(); + + // factory method + protected HierarchicalStreamReader createReader(String xml) throws Exception { + // fails to replace tab characters in attributes to space as required by XML spec + if(xml.indexOf('\t')>=0) { + xml = xml.replace('\t', ' '); + } + return driver.createReader(new StringReader(xml)); + } + + // inherits tests from superclass +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/PrettyPrintWriterTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/PrettyPrintWriterTest.java new file mode 100644 index 0000000..b5187de --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/PrettyPrintWriterTest.java @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.core.util.QuickWriter; +import com.thoughtworks.xstream.io.StreamException; + +import java.io.StringWriter; + + +public class PrettyPrintWriterTest extends AbstractXMLWriterTest { + private StringWriter buffer; + + protected void setUp() throws Exception { + super.setUp(); + buffer = new StringWriter(); + writer = new PrettyPrintWriter(buffer, " "); + } + + protected void assertXmlProducedIs(String expected) { + assertEquals(expected, buffer.toString()); + } + + public void testSupportsNestedElements() { // Note: This overrides a test in superclass to + // include indentation + + writer.startNode("hello"); + writer.startNode("world"); + writer.addAttribute("id", "one"); + + writer.startNode("one"); + writer.setValue("potato"); + writer.endNode(); + + writer.startNode("two"); + writer.addAttribute("id", "two"); + writer.setValue("potatae"); + writer.endNode(); + + writer.endNode(); + + writer.startNode("empty"); + writer.endNode(); + + writer.endNode(); + + String expected = "" + + "\n" + + " \n" + + " potato\n" + + " potatae\n" + + " \n" + + " \n" + + ""; + + assertXmlProducedIs(expected); + } + + public void testAttributesAreResettedForNewNode() { // Note: This overrides a test in + // superclass to include indentation + writer.startNode("work"); + writer.startNode("person"); + writer.addAttribute("firstname", "Joe"); + writer.addAttribute("lastname", "Walnes"); + writer.endNode(); + writer.startNode("project"); + writer.addAttribute("XStream", "Codehaus"); + writer.endNode(); + writer.endNode(); + + String expected = "" + + "\n" + + " \n" + + " \n" + + ""; + + assertXmlProducedIs(expected); + } + + public void testAllowsUserToOverrideTextAndAttributeEscapingRules() { + writer = new PrettyPrintWriter(buffer, " ") { + protected void writeAttributeValue(QuickWriter writer, String text) { + writer.write(replace(text, '&', "_&_")); + } + + protected void writeText(QuickWriter writer, String text) { + writer.write(replace(text, '&', "AND")); + } + }; + + writer.startNode("evil"); + writer.addAttribute("attr", "hello & stuff"); + writer.setValue("bye & stuff"); + writer.endNode(); + + assertXmlProducedIs("bye AND stuff"); + } + + public void testSupportsUserDefinedEOL() { + writer = new PrettyPrintWriter(buffer, "\t", "\r"); + + writer.startNode("element"); + writer.startNode("empty"); + writer.endNode(); + writer.endNode(); + + assertXmlProducedIs("\r\t\r"); + } + + public void testSupportsEmptyNestedTags() { + writer.startNode("parent"); + writer.startNode("child"); + writer.endNode(); + writer.endNode(); + + assertXmlProducedIs("\n \n"); + } + + public void testSupportsNullInQuirksMode() { + writer = new PrettyPrintWriter(buffer, PrettyPrintWriter.XML_QUIRKS); + writer.startNode("tag"); + writer.setValue("\u0000"); + writer.endNode(); + + assertXmlProducedIs(""); + } + + public void testThrowsForNullInXml1_0Mode() { + writer = new PrettyPrintWriter(buffer, PrettyPrintWriter.XML_1_0); + writer.startNode("tag"); + try { + writer.setValue("\u0000"); + fail("Thrown " + StreamException.class.getName() + " expected"); + } catch (final StreamException e) { + assertTrue(e.getMessage().indexOf('0') > 0); + } + } + + public void testThrowsForNullInXml1_1Mode() { + writer = new PrettyPrintWriter(buffer, PrettyPrintWriter.XML_1_1); + writer.startNode("tag"); + try { + writer.setValue("\u0000"); + fail("Thrown " + StreamException.class.getName() + " expected"); + } catch (final StreamException e) { + assertTrue(e.getMessage().indexOf('0') > 0); + } + } + + public void testSupportsOnlyValidControlCharactersInXml1_0Mode() { + writer = new PrettyPrintWriter(buffer, PrettyPrintWriter.XML_1_0); + writer.startNode("tag"); + String ctrl = "" + + "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007" + + "\u0008\u0009\n\u000b\u000c\r\u000e\u000f" + + "\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017" + + "\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f" + + "\u007f" + + "\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087" + + "\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f" + + "\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097" + + "\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f" + + ""; + for (int i = 0; i < ctrl.length(); i++ ) { + char c = ctrl.charAt(i); + try { + writer.setValue(new Character(c).toString()); + if (c != '\t' && c != '\n' && c != '\r' && c < '\u007f') { + fail("Thrown " + StreamException.class.getName() + " expected"); + } + } catch (final StreamException e) { + assertTrue(e.getMessage().indexOf(Integer.toHexString(c)) > 0); + } + } + writer.endNode(); + assertXmlProducedIs("\t\n " + + "€‚ƒ„…†‡" + + "ˆ‰Š‹ŒŽ" + + "‘’“”•–—" + + "˜™š›œžŸ"); + } + + public void testSupportsOnlyValidControlCharactersInXml1_1Mode() { + writer = new PrettyPrintWriter(buffer, PrettyPrintWriter.XML_1_1); + writer.startNode("tag"); + String ctrl = "" + + "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007" + + "\u0008\u0009\n\u000b\u000c\r\u000e\u000f" + + "\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017" + + "\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f" + + "\u007f" + + "\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087" + + "\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f" + + "\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097" + + "\u0098\u0099\u009a\u009b\u009c\u009d\u009e\u009f" + + ""; + for (int i = 0; i < ctrl.length(); i++ ) { + char c = ctrl.charAt(i); + try { + writer.setValue(new Character(c).toString()); + if (c == 0) { + fail("Thrown " + StreamException.class.getName() + " expected"); + } + } catch (final StreamException e) { + assertTrue(e.getMessage().indexOf(Integer.toHexString(c)) > 0); + } + } + writer.endNode(); + assertXmlProducedIs("" + + "\t\n " + + "" + + "" + + "€‚ƒ„…†‡" + + "ˆ‰Š‹ŒŽ" + + "‘’“”•–—" + + "˜™š›œžŸ"); + } + + public void testSupportsInvalidUnicodeCharacterslInQuirksMode() { + writer = new PrettyPrintWriter(buffer, PrettyPrintWriter.XML_QUIRKS); + writer.startNode("tag"); + String ctrl = "\ud7ff\ud800\udfff\ue000\ufffd\ufffe\uffff"; + for (int i = 0; i < ctrl.length(); i++ ) { + char c = ctrl.charAt(i); + writer.setValue(new Character(c).toString()); + } + writer.endNode(); + assertXmlProducedIs("퟿\ud800\udfff\ue000\ufffd￾￿"); + } + + public void testThrowsForInvalidUnicodeCharacterslInXml1_0Mode() { + writer = new PrettyPrintWriter(buffer, PrettyPrintWriter.XML_1_0); + writer.startNode("tag"); + String ctrl = "\ud7ff\ud800\udfff\ue000\ufffd\ufffe\uffff"; + for (int i = 0; i < ctrl.length(); i++ ) { + char c = ctrl.charAt(i); + try { + writer.setValue(new Character(c).toString()); + if ((c >= '\ud800' && c < '\udfff') || c == '\ufffe' || c == '\uffff') { + fail("Thrown " + + StreamException.class.getName() + + " for character value " + + Integer.toHexString(c) + + " expected"); + } + } catch (final StreamException e) { + assertTrue(e.getMessage().indexOf(Integer.toHexString(c)) > 0); + } + } + writer.endNode(); + assertXmlProducedIs("퟿\ue000\ufffd"); + } + + public void testThrowsForInvalidUnicodeCharacterslInXml1_1Mode() { + writer = new PrettyPrintWriter(buffer, PrettyPrintWriter.XML_1_1); + writer.startNode("tag"); + String ctrl = "\ud7ff\ud800\udfff\ue000\ufffd\ufffe\uffff"; + for (int i = 0; i < ctrl.length(); i++ ) { + char c = ctrl.charAt(i); + try { + writer.setValue(new Character(c).toString()); + if ((c >= '\ud800' && c < '\udfff') || c == '\ufffe' || c == '\uffff') { + fail("Thrown " + + StreamException.class.getName() + + " for character value " + + Integer.toHexString(c) + + " expected"); + } + } catch (final StreamException e) { + assertTrue(e.getMessage().indexOf(Integer.toHexString(c)) > 0); + } + } + writer.endNode(); + assertXmlProducedIs("퟿\ue000\ufffd"); + } + + private String replace(String in, char what, String with) { + int pos = in.indexOf(what); + if (pos == -1) { + return in; + } else { + return in.substring(0, pos) + with + in.substring(pos + 1); + } + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/SaxWriterTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/SaxWriterTest.java new file mode 100644 index 0000000..0651dba --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/SaxWriterTest.java @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 14. August 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.megginson.sax.DataWriter; +import com.thoughtworks.acceptance.someobjects.X; +import com.thoughtworks.acceptance.someobjects.Y; +import com.thoughtworks.xstream.XStream; + +import junit.framework.TestCase; + +import javax.xml.transform.ErrorListener; +import javax.xml.transform.Templates; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/* + * @author Laurent Bihanic + */ +public class SaxWriterTest extends TestCase { + + private final static String IDENTITY_STYLESHEET = + "\n" + + "\n" + + " \n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + private XStream xstream; + private X testInput; + private Templates identityStylesheet; + + protected void setUp() throws Exception { + super.setUp(); + xstream = new XStream(); + xstream.alias("x", X.class); + xstream.alias("y", Y.class); + + testInput = new X(); + testInput.anInt = 9; + testInput.aStr = "zzz"; + testInput.innerObj = new Y(); + testInput.innerObj.yField = "ooo"; + + identityStylesheet = TransformerFactory.newInstance().newTemplates(new StreamSource(new StringReader(IDENTITY_STYLESHEET))); + } + + public void testMarshalsObjectToSAX() { + String expected = + "\n\n" + + "\n" + + " zzz\n" + + " 9\n" + + " \n" + + " ooo\n" + + " \n" + + "\n\n"; + + Writer buffer = new StringWriter(); + SaxWriter writer = new SaxWriter(); + DataWriter outputter = new DataWriter(writer, buffer); + outputter.setIndentStep(2); + + writer.setContentHandler(outputter); + + xstream.marshal(testInput, writer); + + assertEquals(expected, buffer.toString()); + } + + public void testAllowsStartAndEndDocCallbacksToBeSkipped() { + String expected = + "1\n" + + "2\n" + + "3\n"; + + Writer buffer = new StringWriter(); + SaxWriter writer = new SaxWriter(false); + DataWriter outputter = new DataWriter(writer, buffer); + outputter.setIndentStep(2); + + writer.setContentHandler(outputter); + + xstream.marshal(new Integer(1), writer); + xstream.marshal(new Integer(2), writer); + xstream.marshal(new Integer(3), writer); + + assertEquals(expected, buffer.toString()); + } + + public void testMarshalsObjectToTrAX() throws Exception { + String expected = + "zzz9" + + "ooo" + + "" + + "ooo"; + + TraxSource traxSource = new TraxSource(); + traxSource.setXStream(xstream); + traxSource.setSourceAsList(Arrays.asList(new Object[]{testInput, testInput.innerObj})); + + Writer buffer = new StringWriter(); + Transformer transformer = identityStylesheet.newTransformer(); + + transformer.transform(traxSource, new StreamResult(buffer)); + + assertEquals(expected, buffer.toString()); + } + + public void testNullSourceObject() { + TraxSource traxSource = new TraxSource(); + + try { + traxSource.setSource(null); + fail("Null source object not rejected"); + } catch (IllegalArgumentException e) { /* good! */ + } + } + + public void testNullSourceList() { + TraxSource traxSource = new TraxSource(); + + try { + traxSource.setSourceAsList(null); + fail("Null source list not rejected"); + } catch (IllegalArgumentException e) { /* good! */ + } + } + + public void testEmptySourceList() { + TraxSource traxSource = new TraxSource(); + + try { + traxSource.setSourceAsList(Collections.EMPTY_LIST); + fail("Empty source list not rejected"); + } catch (IllegalArgumentException e) { /* good! */ + } + } + + /** + * This method tests a quite insidious side-effect of + * XStreamSource delaying the allocation and configuration of + * the SAXWriter until the XSLT processor requests it. + *

+ * SAXWriter performs a copy of the source list contents upon + * property setting to avoid objects being added or removed from + * the list during the parse.

+ *

+ * To avoid just another list copy, XStreamSource does not + * protect itself against list changes. Hence, it is possible + * for an application to configure the XStreamSource and then + * empty the list prior triggering the XSL transformation.

. + *

+ * This method ensures SAXWriter indeed checks the list content + * prior starting the parse.

+ */ + public void testEmptySourceListAtParse() throws Exception { + TraxSource traxSource = new TraxSource(); + Writer buffer = new StringWriter(); + + List list = new ArrayList(); + list.add(testInput); + + traxSource.setSourceAsList(list); + list.clear(); + + Transformer transformer = identityStylesheet.newTransformer(); + transformer.setErrorListener(new TrAXErrorListener()); + + try { + transformer.transform(traxSource, new StreamResult(buffer)); + + fail("Empty source list not rejected"); + } catch (Exception expectedException) { + if (expectedException.getMessage().endsWith("shall not be an empty list")) { + // Good! + } else { + throw expectedException; + } + } + } + + private static class TrAXErrorListener implements ErrorListener { + public TrAXErrorListener() { + super(); + } + + public void warning(TransformerException e) { + /* Ignore... */ + } + + public void error(TransformerException e) { + /* Ignore... */ + } + + public void fatalError(TransformerException e) + throws TransformerException { + throw e; + } + } +} + diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/SjsxpReaderTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/SjsxpReaderTest.java new file mode 100644 index 0000000..46e0322 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/SjsxpReaderTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. September 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.HierarchicalStreamDriver; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestResult; +import junit.framework.TestSuite; + +import java.io.StringReader; + +public class SjsxpReaderTest extends AbstractXMLReaderTest { + final static String className = "com.sun.xml.internal.stream.XMLInputFactoryImpl"; + + public static Test suite() { + try { + Class.forName(className); + return new TestSuite(SjsxpReaderTest.class); + } catch (ClassNotFoundException e) { + return new TestCase(SjsxpReaderTest.class.getName() + ": not available") { + + public int countTestCases() { + return 1; + } + + public void run(TestResult result) { + } + }; + } + } + + private HierarchicalStreamDriver driver = new SjsxpDriver(); + + // factory method + protected HierarchicalStreamReader createReader(String xml) throws Exception { + return driver.createReader(new StringReader(xml)); + } + + // inherits tests from superclass +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/SjsxpWriterTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/SjsxpWriterTest.java new file mode 100644 index 0000000..783fd17 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/SjsxpWriterTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. September 2011 by Joerg Schaible, renamed from SjsxpStaxWriterTest + */ +package com.thoughtworks.xstream.io.xml; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestResult; +import junit.framework.TestSuite; + +public final class SjsxpWriterTest extends AbstractStaxWriterTest { + final static String className = "com.sun.xml.internal.stream.XMLOutputFactoryImpl"; + + public static Test suite() { + try { + Class.forName(className); + return new TestSuite(SjsxpWriterTest.class); + } catch (ClassNotFoundException e) { + return new TestCase(SjsxpWriterTest.class.getName() + ": not available") { + + public int countTestCases() { + return 1; + } + + public void run(TestResult result) { + } + }; + } + } + + protected void assertXmlProducedIs(String expected) { + if (!staxDriver.isRepairingNamespace()) { + expected = perlUtil.substitute("s# xmlns=\"\"##g", expected); + } + expected = perlUtil.substitute("s#<(\\w+)([^>]*)/>#<$1$2>#g", expected); + expected = replaceAll(expected, " ", "\r"); + // attributes are not properly escaped + expected = replaceAll(expected, " ", "\n"); + expected = replaceAll(expected, " ", "\t"); + expected = getXMLHeader() + expected; + assertEquals(expected, buffer.toString()); + } + + protected String getXMLHeader() { + return ""; + } + + protected StaxDriver getStaxDriver() { + return new SjsxpDriver(); + } +} \ No newline at end of file diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/StaxDriverTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/StaxDriverTest.java new file mode 100644 index 0000000..3b1022b --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/StaxDriverTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. July 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.bea.xml.stream.MXParserFactory; +import com.bea.xml.stream.XMLOutputFactoryBase; +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.StreamException; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + + +/** + * @author Jörg Schaible + */ +public class StaxDriverTest extends AbstractAcceptanceTest { + private static class MyStaxDriver extends StaxDriver { + public boolean createStaxWriterCalled = false; + public boolean createStaxReaderCalled = false; + + public StaxWriter createStaxWriter(XMLStreamWriter out) throws StreamException { + createStaxWriterCalled = true; + try { + return super.createStaxWriter(out); + } catch (XMLStreamException e) { + throw new StreamException(e); + } + } + + public AbstractPullReader createStaxReader(XMLStreamReader in) { + createStaxReaderCalled = true; + return super.createStaxReader(in); + } + } + + public void testCanOverloadStaxReaderAndWriterInstantiation() { + System.setProperty(XMLInputFactory.class.getName(), MXParserFactory.class.getName()); + System.setProperty(XMLOutputFactory.class.getName(), XMLOutputFactoryBase.class.getName()); + final MyStaxDriver driver = new MyStaxDriver(); + xstream = new XStream(driver); + assertBothWays("Hi", "Hi"); + assertTrue(driver.createStaxReaderCalled); + assertTrue(driver.createStaxWriterCalled); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/StaxReaderTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/StaxReaderTest.java new file mode 100644 index 0000000..3fa489d --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/StaxReaderTest.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. September 2004 by James Strachan + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; + +import java.io.StringReader; + +public class StaxReaderTest extends AbstractXMLReaderTest { + protected HierarchicalStreamReader createReader(String xml) throws Exception { + StaxDriver driver = new StaxDriver(); + return driver.createReader(new StringReader(xml)); + } + + // inherits tests from superclass +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/WstxReaderTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/WstxReaderTest.java new file mode 100644 index 0000000..e486d51 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/WstxReaderTest.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. September 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.HierarchicalStreamDriver; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; + +import java.io.StringReader; + +public class WstxReaderTest extends AbstractXMLReaderTest { + + private HierarchicalStreamDriver driver = new WstxDriver(); + + // factory method + protected HierarchicalStreamReader createReader(String xml) throws Exception { + return driver.createReader(new StringReader(xml)); + } + + // inherits tests from superclass +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/WstxWriterTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/WstxWriterTest.java new file mode 100644 index 0000000..3a0b9ee --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/WstxWriterTest.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 29. September 2011 by Joerg Schaible, renamed from WoodstoxStaxWriterTest + */ +package com.thoughtworks.xstream.io.xml; + +import com.ctc.wstx.stax.WstxOutputFactory; + +import javax.xml.stream.XMLOutputFactory; + +public final class WstxWriterTest extends AbstractStaxWriterTest { + protected void assertXmlProducedIs(String expected) { + if (!staxDriver.isRepairingNamespace() || perlUtil.match("#<\\w+:\\w+(>| xmlns:\\w+=)#", expected)) { + expected = perlUtil.substitute("s# xmlns=\"\"##g", expected); + } + expected = perlUtil.substitute("s#<(\\w+)([^>]*)/>#<$1$2 />#g", expected); + expected = replaceAll(expected, " ", " "); + expected = replaceAll(expected, ">", ">"); // Woodstox bug !! + expected = getXMLHeader() + expected; + assertEquals(expected, buffer.toString()); + } + + protected String getXMLHeader() { + return ""; + } + + protected XMLOutputFactory getOutputFactory() { + return new WstxOutputFactory(); + } + + protected StaxDriver getStaxDriver() { + return new WstxDriver(); + } +} \ No newline at end of file diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/XomReaderTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/XomReaderTest.java new file mode 100644 index 0000000..491222f --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/XomReaderTest.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 02. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; + +import nu.xom.Builder; +import nu.xom.Document; + +import java.io.StringReader; + +public class XomReaderTest extends AbstractXMLReaderTest { + + // factory method + protected HierarchicalStreamReader createReader(String xml) throws Exception { + Document document = new Builder().build(new StringReader(xml)); + return new XomReader(document); + } + + // inherits tests from superclass + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/XomWriterTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/XomWriterTest.java new file mode 100644 index 0000000..5ff2349 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/XomWriterTest.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 03. September 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import nu.xom.Element; + +public class XomWriterTest extends AbstractDocumentWriterTest { + + protected void setUp() throws Exception { + super.setUp(); + writer = new XomWriter(); + } + + protected DocumentReader createDocumentReaderFor(final Object node) { + return new XomReader((Element)node); + } + + // inherits tests from superclass +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/Xpp3ReaderTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/Xpp3ReaderTest.java new file mode 100644 index 0000000..1443663 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/Xpp3ReaderTest.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. September 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.HierarchicalStreamDriver; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; + +import java.io.StringReader; + +public class Xpp3ReaderTest extends AbstractXMLReaderTest { + + private HierarchicalStreamDriver driver = new Xpp3Driver(); + + // factory method + protected HierarchicalStreamReader createReader(String xml) throws Exception { + return driver.createReader(new StringReader(xml)); + } + + // inherits tests from superclass +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/XppDomReaderTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/XppDomReaderTest.java new file mode 100644 index 0000000..7ae8d92 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/XppDomReaderTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 07. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.xml.xppdom.XppDom; +import com.thoughtworks.xstream.io.xml.xppdom.XppFactory; + +import java.io.StringReader; +import java.util.HashMap; +import java.util.Map; + +public class XppDomReaderTest extends AbstractXMLReaderTest { + protected HierarchicalStreamReader createReader(String xml) throws Exception { + return new Xpp3DomDriver().createReader(new StringReader(xml)); + } + + public void testCanReadFromElementOfLargerDocument() + throws Exception { + String xml = + "" + + " " + + " " + + " " + + " " + + " " + + ""; + + XppDom document = XppFactory.buildDom(xml); + + XppDom small = document.getChild("small"); + + HierarchicalStreamReader xmlReader = new XppDomReader(small); + + assertEquals("small", xmlReader.getNodeName()); + + xmlReader.moveDown(); + + assertEquals("tiny", xmlReader.getNodeName()); + } + + public void testExposesAttributesKeysAndValuesByIndex() throws Exception { + + // overrides test in superclass, because XppDom does not retain order of actualAttributes. + + HierarchicalStreamReader xmlReader = createReader(""); + + assertEquals(3, xmlReader.getAttributeCount()); + + Map expectedAttributes = new HashMap(); + expectedAttributes.put("hello", "world"); + expectedAttributes.put("a", "b"); + expectedAttributes.put("c", "d"); + + Map actualAttributes = new HashMap(); + for (int i = 0; i < xmlReader.getAttributeCount(); i++) { + String name = xmlReader.getAttributeName(i); + String value = xmlReader.getAttribute(i); + actualAttributes.put(name, value); + } + + assertEquals(expectedAttributes, actualAttributes); + + xmlReader.moveDown(); + assertEquals("empty", xmlReader.getNodeName()); + assertEquals(0, xmlReader.getAttributeCount()); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/XppDomWriterTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/XppDomWriterTest.java new file mode 100644 index 0000000..ca6db81 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/XppDomWriterTest.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2006, 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 19. October 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.xml.xppdom.XppDom; + +/** + * @author Jörg Schaible + */ +public class XppDomWriterTest extends AbstractDocumentWriterTest { + + protected void setUp() throws Exception { + super.setUp(); + writer = new XppDomWriter(); + } + + protected DocumentReader createDocumentReaderFor(Object node) { + return new XppDomReader((XppDom)node); + } + + // inherits tests from superclass +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/XppReaderTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/XppReaderTest.java new file mode 100644 index 0000000..80eeb1f --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/XppReaderTest.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 08. March 2004 by Joe Walnes + */ +package com.thoughtworks.xstream.io.xml; + +import com.thoughtworks.xstream.io.HierarchicalStreamReader; + +import java.io.StringReader; + +public class XppReaderTest extends AbstractXMLReaderTest { + protected HierarchicalStreamReader createReader(String xml) throws Exception { + return new XppReader(new StringReader(xml)); + } + + // inherits tests from superclass +} diff --git a/xstream/src/test/com/thoughtworks/xstream/io/xml/xppdom/XppDomComparatorTest.java b/xstream/src/test/com/thoughtworks/xstream/io/xml/xppdom/XppDomComparatorTest.java new file mode 100644 index 0000000..213fffc --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/io/xml/xppdom/XppDomComparatorTest.java @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 11. August 2011 by Joerg Schaible. + */ + +package com.thoughtworks.xstream.io.xml.xppdom; + +import java.util.Comparator; + +import com.thoughtworks.xstream.io.xml.xppdom.XppDom; +import com.thoughtworks.xstream.io.xml.xppdom.XppFactory; + +import junit.framework.TestCase; + + +/** + * Tests {@link XppDomComparator}. + * + * @author Jörg Schaible + */ +public class XppDomComparatorTest extends TestCase { + // ~ Instance fields -------------------------------------------------------- + + private ThreadLocal xpath; + private XppDomComparator comparator; + + // ~ Methods ---------------------------------------------------------------- + + protected void setUp() throws Exception { + super.setUp(); + xpath = new ThreadLocal(); + comparator = new XppDomComparator(xpath); + } + + private void assertEquals(Comparator comparator, Object o1, Object o2) { + if (comparator.compare(o1, o2) != 0) { + fail("Cpmarator claims '" + o1 + "' to be different from '" + o2 + "'"); + } + } + + /** + * Tests comparison of empty document. + * + * @throws Exception unexpected + */ + public void testEqualsEmptyDocuments() throws Exception { + final String xml = ""; + XppDom dom1 = XppFactory.buildDom(xml); + XppDom dom2 = XppFactory.buildDom(xml); + assertEquals(comparator, dom1, dom2); + assertNull(xpath.get()); + } + + /** + * Tests comparison of different values. + * + * @throws Exception unexpected + */ + public void testSortsElementsWithDifferentValue() throws Exception { + XppDom dom1 = XppFactory.buildDom("value1"); + XppDom dom2 = XppFactory.buildDom("value2"); + assertEquals(-1, comparator.compare(dom1, dom2)); + assertEquals("/dom::text()", xpath.get()); + assertEquals(1, comparator.compare(dom2, dom1)); + assertEquals("/dom::text()", xpath.get()); + } + + /** + * Tests comparison of a value and null. + * + * @throws Exception unexpected + */ + public void testSortsElementsWithValueAndNull() throws Exception { + XppDom dom1 = XppFactory.buildDom(""); + XppDom dom2 = XppFactory.buildDom("value"); + assertEquals(-1, comparator.compare(dom1, dom2)); + assertEquals("/dom::text()", xpath.get()); + assertEquals(1, comparator.compare(dom2, dom1)); + assertEquals("/dom::text()", xpath.get()); + } + + /** + * Tests comparison of attributes. + * + * @throws Exception unexpected + */ + public void testEqualsAttributes() throws Exception { + final String xml = ""; + XppDom dom1 = XppFactory.buildDom(xml); + XppDom dom2 = XppFactory.buildDom(xml); + assertEquals(comparator, dom1, dom2); + assertNull(xpath.get()); + } + + /** + * Tests comparison of attributes in different order. + * + * @throws Exception unexpected + */ + public void testEqualsAttributesInDifferentOrder() throws Exception { + XppDom dom1 = XppFactory.buildDom(""); + XppDom dom2 = XppFactory.buildDom(""); + assertEquals(comparator, dom1, dom2); + assertNull(xpath.get()); + } + + /** + * Tests comparison of same attributes with different values. + * + * @throws Exception unexpected + */ + public void testSortsSameAttributes() throws Exception { + XppDom dom1 = XppFactory.buildDom(""); + XppDom dom2 = XppFactory.buildDom(""); + assertEquals(-1, comparator.compare(dom1, dom2)); + assertEquals("/dom[@a]", xpath.get()); + assertEquals(1, comparator.compare(dom2, dom1)); + assertEquals("/dom[@a]", xpath.get()); + } + + /** + * Tests comparison of different attributes. + * + * @throws Exception unexpected + */ + public void testSortsDifferentAttributes() throws Exception { + XppDom dom1 = XppFactory.buildDom(""); + XppDom dom2 = XppFactory.buildDom(""); + assertEquals(-1, comparator.compare(dom1, dom2)); + assertEquals("/dom[@a?]", xpath.get()); + assertEquals(1, comparator.compare(dom2, dom1)); + assertEquals("/dom[@b?]", xpath.get()); + } + + /** + * Tests comparison of different number of attributes. + * + * @throws Exception unexpected + */ + public void testSortsAccordingNumberOfAttributes() throws Exception { + XppDom dom1 = XppFactory.buildDom(""); + XppDom dom2 = XppFactory.buildDom(""); + assertEquals(-1, comparator.compare(dom1, dom2)); + assertEquals("/dom::count(@*)", xpath.get()); + assertEquals(1, comparator.compare(dom2, dom1)); + assertEquals("/dom::count(@*)", xpath.get()); + } + + /** + * Tests comparison of document with children. + * + * @throws Exception unexpected + */ + public void testEqualsDocumentsWithChildren() throws Exception { + final String xml = ""; + XppDom dom1 = XppFactory.buildDom(xml); + XppDom dom2 = XppFactory.buildDom(xml); + assertEquals(comparator, dom1, dom2); + assertNull(xpath.get()); + } + + /** + * Tests comparison of different number of children. + * + * @throws Exception unexpected + */ + public void testSortsAccordingNumberOfChildren() throws Exception { + XppDom dom1 = XppFactory.buildDom(""); + XppDom dom2 = XppFactory.buildDom(""); + assertEquals(-1, comparator.compare(dom1, dom2)); + assertEquals("/dom::count(*)", xpath.get()); + assertEquals(1, comparator.compare(dom2, dom1)); + assertEquals("/dom::count(*)", xpath.get()); + } + + /** + * Tests comparison of different elements. + * + * @throws Exception unexpected + */ + public void testSortsElementsByName() throws Exception { + XppDom dom1 = XppFactory.buildDom(""); + XppDom dom2 = XppFactory.buildDom(""); + assertEquals(-1, comparator.compare(dom1, dom2)); + assertEquals("/dom/a[0]?", xpath.get()); + assertEquals(1, comparator.compare(dom2, dom1)); + assertEquals("/dom/b[0]?", xpath.get()); + } + + /** + * Tests comparison of different nth elements. + * + * @throws Exception unexpected + */ + public void testSortsElementsByNthName() throws Exception { + XppDom dom1 = XppFactory.buildDom(""); + XppDom dom2 = XppFactory.buildDom(""); + assertEquals(-1, comparator.compare(dom1, dom2)); + assertEquals("/dom/a[1]?", xpath.get()); + assertEquals(1, comparator.compare(dom2, dom1)); + assertEquals("/dom/b[1]?", xpath.get()); + } + + /** + * Tests comparison sorts attributes before elements. + * + * @throws Exception unexpected + */ + public void testSortsAttributesBeforeElements() throws Exception { + XppDom dom1 = XppFactory.buildDom(""); + XppDom dom2 = XppFactory.buildDom(""); + assertEquals(-1, comparator.compare(dom1, dom2)); + assertEquals("/dom[@x]", xpath.get()); + assertEquals(1, comparator.compare(dom2, dom1)); + assertEquals("/dom[@x]", xpath.get()); + } + + /** + * Tests comparison will reset XPath after recursion. + * + * @throws Exception unexpected + */ + public void testWillResetXPathAfterRecursion() throws Exception { + XppDom dom1 = XppFactory.buildDom("foo"); + XppDom dom2 = XppFactory.buildDom("foo"); + assertEquals(-1, comparator.compare(dom1, dom2)); + assertEquals("/dom/c[0][@x]", xpath.get()); + assertEquals(1, comparator.compare(dom2, dom1)); + assertEquals("/dom/c[0][@x]", xpath.get()); + } + + /** + * Tests comparison of empty document. + * + * @throws Exception unexpected + */ + public void testCompareWithoutReference() throws Exception { + comparator = new XppDomComparator(); + final String xml = ""; + XppDom dom1 = XppFactory.buildDom(xml); + XppDom dom2 = XppFactory.buildDom(xml); + assertEquals(comparator, dom1, dom2); + assertNull(xpath.get()); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/mapper/DefaultClassMapperTest.java b/xstream/src/test/com/thoughtworks/xstream/mapper/DefaultClassMapperTest.java new file mode 100644 index 0000000..1182419 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/mapper/DefaultClassMapperTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 23. January 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.mapper; + +import com.thoughtworks.xstream.core.ClassLoaderReference; +import com.thoughtworks.xstream.core.util.CompositeClassLoader; + +import junit.framework.TestCase; + +public class DefaultClassMapperTest extends TestCase { + private Mapper mapper; + + protected void setUp() throws Exception { + super.setUp(); + mapper = new ArrayMapper(new DefaultMapper(new ClassLoaderReference( + new CompositeClassLoader()))); + } + + public void testAppendsArraySuffixOnArrays() { + Class arrayCls = new String[0].getClass(); + assertEquals("java.lang.String-array", mapper.serializedClass(arrayCls)); + } + + public void testAppendsMultipleArraySuffixesOnMultidimensionalArrays() { + Class arrayCls = new String[0][0][0].getClass(); + assertEquals("java.lang.String-array-array-array", mapper.serializedClass(arrayCls)); + } + + public void testCreatesInstancesOfArrays() { + Class arrayType = mapper.realClass("java.lang.String-array"); + assertTrue(arrayType.isArray()); + assertEquals(String.class, arrayType.getComponentType()); + } + + public void testSupportsAllPrimitiveArrayTypes() { + assertEquals(int.class, mapper.realClass("int-array").getComponentType()); + assertEquals(short.class, mapper.realClass("short-array").getComponentType()); + assertEquals(long.class, mapper.realClass("long-array").getComponentType()); + assertEquals(char.class, mapper.realClass("char-array").getComponentType()); + assertEquals(boolean.class, mapper.realClass("boolean-array").getComponentType()); + assertEquals(float.class, mapper.realClass("float-array").getComponentType()); + assertEquals(double.class, mapper.realClass("double-array").getComponentType()); + assertEquals(byte.class, mapper.realClass("byte-array").getComponentType()); + } + + public void testCreatesInstancesOfMultidimensionalArrays() { + Class arrayType = mapper.realClass("java.lang.String-array-array-array"); + assertTrue(arrayType.isArray()); + assertTrue(arrayType.getComponentType().isArray()); + assertTrue(arrayType.getComponentType().getComponentType().isArray()); + + assertFalse(arrayType.getComponentType().getComponentType().getComponentType().isArray()); + assertEquals(String.class, arrayType.getComponentType().getComponentType().getComponentType()); + + Class primitiveArrayType = mapper.realClass("int-array-array-array"); + assertTrue(primitiveArrayType.isArray()); + assertTrue(primitiveArrayType.getComponentType().isArray()); + assertTrue(primitiveArrayType.getComponentType().getComponentType().isArray()); + + assertFalse(primitiveArrayType.getComponentType().getComponentType().getComponentType().isArray()); + assertEquals(int.class, primitiveArrayType.getComponentType().getComponentType().getComponentType()); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/mapper/FieldAliasingMapperTest.java b/xstream/src/test/com/thoughtworks/xstream/mapper/FieldAliasingMapperTest.java new file mode 100644 index 0000000..7a1191e --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/mapper/FieldAliasingMapperTest.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 09. April 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.mapper; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.acceptance.objects.Software; + +public class FieldAliasingMapperTest extends AbstractAcceptanceTest { + + public void testAllowsIndividualFieldsToBeAliased() { + Software in = new Software("ms", "word"); + xstream.alias("software", Software.class); + xstream.aliasField("CUSTOM-VENDOR", Software.class, "vendor"); + xstream.aliasField("CUSTOM-NAME", Software.class, "name"); + + String expectedXml = "" + + "\n" + + " ms\n" + + " word\n" + + ""; + + assertBothWays(in, expectedXml); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/mapper/ImplicitCollectionMapperTest.java b/xstream/src/test/com/thoughtworks/xstream/mapper/ImplicitCollectionMapperTest.java new file mode 100644 index 0000000..3fe59f5 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/mapper/ImplicitCollectionMapperTest.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2011, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 16. February 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.mapper; + +import java.util.Map; + +import com.thoughtworks.acceptance.objects.Hardware; +import com.thoughtworks.acceptance.objects.OpenSourceSoftware; +import com.thoughtworks.acceptance.objects.Product; +import com.thoughtworks.acceptance.objects.SampleLists; +import com.thoughtworks.acceptance.objects.SampleMaps; +import com.thoughtworks.acceptance.objects.Software; +import com.thoughtworks.xstream.core.ClassLoaderReference; + +import junit.framework.TestCase; + +public class ImplicitCollectionMapperTest extends TestCase { + + private ImplicitCollectionMapper implicitCollections = new ImplicitCollectionMapper( + new DefaultMapper(new ClassLoaderReference(null))); + + public void testAllowsFieldsToBeMarkedAsImplicitCollectionsToBeAdded() { + implicitCollections.add(SampleLists.class, "good", null); + assertNotNull(implicitCollections.getImplicitCollectionDefForFieldName(SampleLists.class, "good")); + assertEquals("good", implicitCollections.getFieldNameForItemTypeAndName(SampleLists.class, Object.class, null)); + } + + public void testDoesNotMarkFieldsAsImplicitCollectionByDefault() { + assertNull(implicitCollections.getImplicitCollectionDefForFieldName(SampleLists.class, "good")); + assertEquals(null, implicitCollections.getFieldNameForItemTypeAndName(SampleLists.class, Object.class, null)); + } + + public void testAllowsFieldsToBeMarkedBasedOnItemType() { + implicitCollections.add(SampleLists.class, "good", Software.class); + implicitCollections.add(SampleLists.class, "bad", Hardware.class); + assertNotNull(implicitCollections.getImplicitCollectionDefForFieldName(SampleLists.class, "bad")); + assertNotNull(implicitCollections.getImplicitCollectionDefForFieldName(SampleLists.class, "good")); + assertEquals("good", implicitCollections.getFieldNameForItemTypeAndName(SampleLists.class, Software.class, null)); + assertEquals("bad", implicitCollections.getFieldNameForItemTypeAndName(SampleLists.class, Hardware.class, null)); + } + + public void testIncludesSubClassesWhenCheckingItemType() { + implicitCollections.add(SampleLists.class, "good", Software.class); + assertEquals("good", implicitCollections.getFieldNameForItemTypeAndName(SampleLists.class, OpenSourceSoftware.class, null)); + assertEquals(null, implicitCollections.getFieldNameForItemTypeAndName(SampleLists.class, Hardware.class, null)); + } + + public void testAllowsFieldsToBeMarkedAsNamedImplicitCollectionsToBeAdded() { + implicitCollections.add(SampleLists.class, "good", "good-item", Object.class); + implicitCollections.add(SampleLists.class, "bad", null); + Mapper.ImplicitCollectionMapping mappingGood = implicitCollections.getImplicitCollectionDefForFieldName(SampleLists.class, "good"); + assertNotNull(mappingGood); + assertEquals("good-item", mappingGood.getItemFieldName()); + assertEquals(Object.class, mappingGood.getItemType()); + assertEquals("good", mappingGood.getFieldName()); + + Mapper.ImplicitCollectionMapping mappingBad = implicitCollections.getImplicitCollectionDefForFieldName(SampleLists.class, "bad"); + assertNotNull(mappingBad); + assertNull(mappingBad.getItemFieldName()); + assertNull(mappingBad.getItemType()); + + assertEquals("good", implicitCollections.getFieldNameForItemTypeAndName(SampleLists.class, Object.class, "good-item")); + assertEquals("bad", implicitCollections.getFieldNameForItemTypeAndName(SampleLists.class, Object.class, null)); + } + + public void testAllowsFieldsToBeMarkedBasedOnItemFieldName() { + implicitCollections.add(SampleLists.class, "good", "good-item", Object.class); + implicitCollections.add(SampleLists.class, "bad", "bad-item", Object.class); + Mapper.ImplicitCollectionMapping mappingGood = implicitCollections.getImplicitCollectionDefForFieldName(SampleLists.class, "good"); + assertNotNull(mappingGood); + assertEquals("good-item", mappingGood.getItemFieldName()); + assertEquals(Object.class, mappingGood.getItemType()); + assertEquals("good", mappingGood.getFieldName()); + + Mapper.ImplicitCollectionMapping mappingBad = implicitCollections.getImplicitCollectionDefForFieldName(SampleLists.class, "bad"); + assertNotNull(mappingBad); + assertEquals("bad-item", mappingBad.getItemFieldName()); + assertEquals(Object.class, mappingBad.getItemType()); + assertEquals("bad", mappingBad.getFieldName()); + + assertEquals("good", implicitCollections.getFieldNameForItemTypeAndName(SampleLists.class, Object.class, "good-item")); + assertEquals("bad", implicitCollections.getFieldNameForItemTypeAndName(SampleLists.class, Object.class, "bad-item")); + } + + public void testIncludesSubClassesWhenCheckingItemTypeForNamedImplicitCollections() { + implicitCollections.add(SampleLists.class, "good", "good-item", Software.class); + assertEquals("good", implicitCollections.getFieldNameForItemTypeAndName(SampleLists.class, OpenSourceSoftware.class, "good-item")); + assertEquals(null, implicitCollections.getFieldNameForItemTypeAndName(SampleLists.class, Hardware.class, null)); + } + + public void testGetItemTypeForItemFieldName() { + implicitCollections.add(SampleLists.class, "good", "good-item", Software.class); + implicitCollections.add(SampleLists.class, "bad", "bad-item", Product.class); + + assertEquals(Software.class, implicitCollections.getItemTypeForItemFieldName(SampleLists.class, "good-item")); + assertEquals(Product.class, implicitCollections.getItemTypeForItemFieldName(SampleLists.class, "bad-item")); + } + + public void testAllowsFieldsToBeMarkedAsImplicitMapsToBeAdded() { + implicitCollections.add(SampleMaps.class, "good", null); + assertNotNull(implicitCollections.getImplicitCollectionDefForFieldName(SampleMaps.class, "good")); + assertEquals("good", implicitCollections.getFieldNameForItemTypeAndName(SampleMaps.class, Map.Entry.class, null)); + } + + public void testGetKeyFieldNameForItemFieldName() { + implicitCollections.add(SampleMaps.class, "good", "good-item", Software.class, "name"); + implicitCollections.add(SampleMaps.class, "bad", "bad-item", Software.class, "vendor"); + + assertEquals("name", implicitCollections.getImplicitCollectionDefForFieldName(SampleMaps.class, "good").getKeyFieldName()); + assertEquals("vendor", implicitCollections.getImplicitCollectionDefForFieldName(SampleMaps.class, "bad").getKeyFieldName()); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/mapper/SecurityMapperTest.java b/xstream/src/test/com/thoughtworks/xstream/mapper/SecurityMapperTest.java new file mode 100644 index 0000000..7ac6f3c --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/mapper/SecurityMapperTest.java @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2014 XStream Committers. + * All rights reserved. + * + * Created on 09. January 2014 by Joerg Schaible + */ +package com.thoughtworks.xstream.mapper; + +import java.net.URL; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.core.util.QuickWriter; +import com.thoughtworks.xstream.security.AnyTypePermission; +import com.thoughtworks.xstream.security.ArrayTypePermission; +import com.thoughtworks.xstream.security.ExplicitTypePermission; +import com.thoughtworks.xstream.security.ForbiddenClassException; +import com.thoughtworks.xstream.security.NoTypePermission; +import com.thoughtworks.xstream.security.NullPermission; +import com.thoughtworks.xstream.security.PrimitiveTypePermission; +import com.thoughtworks.xstream.security.RegExpTypePermission; +import com.thoughtworks.xstream.security.TypePermission; +import com.thoughtworks.xstream.security.WildcardTypePermission; + +import junit.framework.TestCase; + + +/** + * Tests the {@link SecurityMapper} and the {@link TypePermission} implementations. + * + * @author Jörg Schaible + */ +public class SecurityMapperTest extends TestCase { + + private SecurityMapper mapper; + private Map classMap; + + protected void setUp() throws Exception { + super.setUp(); + + classMap = new HashMap(); + mapper = new SecurityMapper(new MapperWrapper(null) { + public Class realClass(final String elementName) { + return (Class)classMap.get(elementName); + } + }); + } + + private void register(final Class[] types) { + for (int i = 0; i < types.length; ++i) { + classMap.put(types[i].getName(), types[i]); + } + } + + public void testAnyType() { + register(new Class[]{String.class, URL.class, List.class}); + mapper.addPermission(NoTypePermission.NONE); + mapper.addPermission(AnyTypePermission.ANY); + assertSame(String.class, mapper.realClass(String.class.getName())); + assertSame(List.class, mapper.realClass(List.class.getName())); + assertNull(mapper.realClass(null)); + } + + public void testNoType() { + register(new Class[]{String.class, URL.class, List.class}); + mapper.addPermission(NoTypePermission.NONE); + try { + mapper.realClass(String.class.getName()); + fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); + } catch (final ForbiddenClassException e) { + assertEquals(String.class.getName(), e.getMessage()); + } + try { + mapper.realClass(null); + fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); + } catch (final ForbiddenClassException e) { + assertEquals("null", e.getMessage()); + } + } + + public void testNullType() { + register(new Class[]{String.class, Mapper.Null.class}); + mapper.addPermission(NullPermission.NULL); + assertSame(Mapper.Null.class, mapper.realClass(Mapper.Null.class.getName())); + assertNull(mapper.realClass(null)); + try { + mapper.realClass(String.class.getName()); + fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); + } catch (final ForbiddenClassException e) { + assertEquals(String.class.getName(), e.getMessage()); + } + } + + public void testPrimitiveTypes() { + register(new Class[]{String.class, int.class, Integer.class, char[].class, Character[].class}); + mapper.addPermission(PrimitiveTypePermission.PRIMITIVES); + assertSame(int.class, mapper.realClass(int.class.getName())); + assertSame(Integer.class, mapper.realClass(Integer.class.getName())); + try { + mapper.realClass(String.class.getName()); + fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); + } catch (final ForbiddenClassException e) { + assertEquals(String.class.getName(), e.getMessage()); + } + try { + mapper.realClass(null); + fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); + } catch (final ForbiddenClassException e) { + assertEquals("null", e.getMessage()); + } + try { + mapper.realClass(char[].class.getName()); + fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); + } catch (final ForbiddenClassException e) { + assertEquals(char[].class.getName(), e.getMessage()); + } + } + + public void testArrayTypes() { + register(new Class[]{String.class, int.class, Integer.class, char[].class, Character[].class}); + mapper.addPermission(ArrayTypePermission.ARRAYS); + assertSame(char[].class, mapper.realClass(char[].class.getName())); + assertSame(Character[].class, mapper.realClass(Character[].class.getName())); + try { + mapper.realClass(String.class.getName()); + fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); + } catch (final ForbiddenClassException e) { + assertEquals(String.class.getName(), e.getMessage()); + } + try { + mapper.realClass(null); + fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); + } catch (final ForbiddenClassException e) { + assertEquals("null", e.getMessage()); + } + try { + mapper.realClass(int.class.getName()); + fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); + } catch (final ForbiddenClassException e) { + assertEquals(int.class.getName(), e.getMessage()); + } + } + + public void testExplicitTypes() { + register(new Class[]{String.class, List.class}); + mapper.addPermission(new ExplicitTypePermission(new String[]{String.class.getName(), List.class.getName()})); + assertSame(String.class, mapper.realClass(String.class.getName())); + assertSame(List.class, mapper.realClass(List.class.getName())); + try { + mapper.realClass(null); + fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); + } catch (final ForbiddenClassException e) { + assertEquals("null", e.getMessage()); + } + } + + public void testNamesWithRegExps() { + class Foo$_0 {} + final Class anonymous = new Object() {}.getClass(); + register(new Class[]{ + String.class, JVM.class, QuickWriter.class, Foo$_0.class, anonymous, DefaultClassMapperTest.class}); + mapper.addPermission(new RegExpTypePermission(new String[]{ + ".*Test", ".*\\.core\\..*", ".*SecurityMapperTest\\$.+"})); + assertSame(DefaultClassMapperTest.class, mapper.realClass(DefaultClassMapperTest.class.getName())); + assertSame(JVM.class, mapper.realClass(JVM.class.getName())); + assertSame(QuickWriter.class, mapper.realClass(QuickWriter.class.getName())); + assertSame(Foo$_0.class, mapper.realClass(Foo$_0.class.getName())); + assertSame(anonymous, mapper.realClass(anonymous.getName())); + try { + mapper.realClass(String.class.getName()); + fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); + } catch (final ForbiddenClassException e) { + assertEquals(String.class.getName(), e.getMessage()); + } + } + + public void testNamesWithWildcardPatterns() { + class Foo$_0 {} + class Foo$_1 {} + final Class anonymous = new Object() {}.getClass(); + register(new Class[]{String.class, JVM.class, QuickWriter.class, Foo$_0.class, Foo$_1.class, anonymous}); + mapper + .addPermission(new WildcardTypePermission(new String[]{"**.*_0", "**.core.*", "**.SecurityMapperTest$?"})); + assertSame(JVM.class, mapper.realClass(JVM.class.getName())); + assertSame(Foo$_0.class, mapper.realClass(Foo$_0.class.getName())); + assertSame(anonymous, mapper.realClass(anonymous.getName())); + try { + mapper.realClass(String.class.getName()); + fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); + } catch (final ForbiddenClassException e) { + assertEquals(String.class.getName(), e.getMessage()); + } + try { + mapper.realClass(QuickWriter.class.getName()); + fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); + } catch (final ForbiddenClassException e) { + assertEquals(QuickWriter.class.getName(), e.getMessage()); + } + try { + mapper.realClass(Foo$_1.class.getName()); + fail("Thrown " + ForbiddenClassException.class.getName() + " expected"); + } catch (final ForbiddenClassException e) { + assertEquals(Foo$_1.class.getName(), e.getMessage()); + } + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/mapper/XmlFriendlyMapperTest.java b/xstream/src/test/com/thoughtworks/xstream/mapper/XmlFriendlyMapperTest.java new file mode 100644 index 0000000..8b929ae --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/mapper/XmlFriendlyMapperTest.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. February 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.mapper; + +import com.thoughtworks.xstream.core.util.CompositeClassLoader; + +import junit.framework.TestCase; + +public class XmlFriendlyMapperTest extends TestCase { + + private Mapper mapper; + + public void testPrefixesIllegalXmlElementNamesWithValue() throws ClassNotFoundException { + mapper = new XmlFriendlyMapper(new DefaultMapper(new CompositeClassLoader())); + Class clsInDefaultPackage = Class.forName("$Package"); + String aliasedName = mapper.serializedClass(clsInDefaultPackage); + assertTrue("Does not start with 'default-Package' : <" + aliasedName + ">", + aliasedName.startsWith("default-Package")); + assertEquals(clsInDefaultPackage, mapper.realClass(aliasedName)); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/persistence/FilePersistenceStrategyTest.java b/xstream/src/test/com/thoughtworks/xstream/persistence/FilePersistenceStrategyTest.java new file mode 100644 index 0000000..648b4fe --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/persistence/FilePersistenceStrategyTest.java @@ -0,0 +1,257 @@ +/* + * Copyright (C) 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 21. November 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.persistence; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import junit.framework.TestCase; + + +/** + * @author Jörg Schaible + * @author Guilherme Silveira + */ +public class FilePersistenceStrategyTest extends TestCase { + + private final File baseDir = new File("target/tmp"); + + protected void setUp() throws Exception { + super.setUp(); + if (baseDir.exists()) { + clear(baseDir); + } + baseDir.mkdirs(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + clear(baseDir); + } + + private void clear(File dir) { + File[] files = dir.listFiles(); + for (int i = 0; i < files.length; i++ ) { + if (files[i].isFile()) { + boolean deleted = files[i].delete(); + if (!deleted) { + throw new RuntimeException( + "Unable to continue testing: unable to remove file " + + files[i].getAbsolutePath()); + } + } + } + dir.delete(); + } + + public void testConcatenatesXmlExtensionWhileGettingAFilename() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + assertEquals("string@guilherme.xml", strategy.getName("guilherme")); + } + + public void testConcatenatesXmlExtensionWhileExtractingAKey() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + assertEquals("guilherme", strategy.extractKey("string@guilherme.xml")); + } + + public void testEscapesNonAcceptableCharacterWhileExtractingAKey() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + assertEquals("../guilherme", strategy.extractKey("string@..%2Fguilherme.xml")); + } + + public void testEscapesNonAcceptableCharacterWhileGettingAFilename() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + assertEquals("string@..%2Fguilherme.xml", strategy.getName("../guilherme")); + } + + public void testEscapesUTF8NonAcceptableCharacterWhileGettingAFilename() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + assertEquals("string@\u5377guilherme.xml", strategy.getName("\u5377guilherme")); + } + + public void testEscapesUTF8NonAcceptableCharacterWhileExtractingAKey() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + assertEquals("\u5377guilherme", strategy.extractKey("string@\u5377guilherme.xml")); + } + + public void testEscapesPercentageWhileGettingAFilename() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + assertEquals("string@%25guilherme.xml", strategy.getName("%guilherme")); + } + + public void testEscapesPercentageWhileExtractingAKey() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + assertEquals("%guilherme", strategy.extractKey("string@%25guilherme.xml")); + } + + public void testEscapesNullKeyWhileGettingAFileName() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + assertEquals("null@null.xml", strategy.getName(null)); + } + + public void testRestoresTypeOfKey() throws MalformedURLException { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + assertEquals(new URL("http://xstream.codehaus.org"), strategy + .extractKey("url@http%3A%2F%2Fxstream.codehaus.org.xml")); + } + + public void testEscapesNullKeyWhileExtractingKey() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + assertNull(strategy.extractKey("null@null.xml")); + } + + public void testWritesASingleFile() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + File file = new File(baseDir, "string@guilherme.xml"); + assertTrue(file.isFile()); + } + + public void testWritesTwoFiles() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + strategy.put("silveira", "anotherCuteString"); + assertTrue(new File(baseDir, "string@guilherme.xml").isFile()); + assertTrue(new File(baseDir, "string@silveira.xml").isFile()); + } + + public void testRemovesAWrittenFile() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + assertTrue(new File(baseDir, "string@guilherme.xml").isFile()); + String aCuteString = (String)strategy.remove("guilherme"); + assertEquals("aCuteString", aCuteString); + assertFalse(new File(baseDir, "string@guilherme.xml").exists()); + } + + public void testRemovesAnInvalidFile() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + String aCuteString = (String)strategy.remove("guilherme"); + assertNull(aCuteString); + } + + public void testHasZeroLength() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + assertEquals(0, strategy.size()); + } + + public void testHasOneItem() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + assertEquals(1, strategy.size()); + } + + public void testHasTwoItems() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + strategy.put("silveira", "anotherCuteString"); + assertEquals(2, strategy.size()); + } + + public void testIsNotEmpty() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + assertEquals("Map should not be empty", 1, strategy.size()); + } + + public void testDoesNotContainKey() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + assertFalse(strategy.containsKey("guilherme")); + } + + public void testContainsKey() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + assertTrue(strategy.containsKey("guilherme")); + } + + public void testGetsAFile() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + assertTrue(new File(baseDir, "string@guilherme.xml").isFile()); + String aCuteString = (String)strategy.get("guilherme"); + assertEquals("aCuteString", aCuteString); + } + + public void testGetsAnInvalidFile() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + String aCuteString = (String)strategy.get("guilherme"); + assertNull(aCuteString); + } + + public void testRewritesASingleFile() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + File file = new File(baseDir, "string@guilherme.xml"); + assertTrue(file.isFile()); + strategy.put("guilherme", "anotherCuteString"); + assertEquals("anotherCuteString", strategy.get("guilherme")); + } + + public void testIsEmpty() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + assertEquals("Map should be empty", 0, strategy.size()); + } + + public void testContainsAllItems() { + Map original = new HashMap(); + original.put("guilherme", "aCuteString"); + original.put("silveira", "anotherCuteString"); + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + strategy.put("silveira", "anotherCuteString"); + for (Iterator iter = original.keySet().iterator(); iter.hasNext();) { + assertTrue(strategy.containsKey(iter.next())); + } + } + + public void testIteratesOverEntryAndChecksItsKeyWithAnotherInstance() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + strategy.put("silveira", "anotherCuteString"); + FilePersistenceStrategy built = new FilePersistenceStrategy(baseDir); + for (Iterator iter = strategy.iterator(); iter.hasNext();) { + Map.Entry entry = (Map.Entry)iter.next(); + assertTrue(built.containsKey(entry.getKey())); + } + } + + public void testRemovesAnItemThroughIteration() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + strategy.put("silveira", "anotherCuteString"); + for (Iterator iter = strategy.iterator(); iter.hasNext();) { + Map.Entry entry = (Map.Entry)iter.next(); + if (entry.getKey().equals("guilherme")) { + iter.remove(); + } + } + assertFalse(strategy.containsKey("guilherme")); + } + + public void testRewritesAFile() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + strategy.put("guilherme", "anotherCuteString"); + assertEquals("anotherCuteString", strategy.get("guilherme")); + } + + public void testPutReturnsTheOldValueWhenRewritingAFile() { + FilePersistenceStrategy strategy = new FilePersistenceStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + assertEquals("aCuteString", strategy.put("guilherme", "anotherCuteString")); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/persistence/FileStreamStrategyTest.java b/xstream/src/test/com/thoughtworks/xstream/persistence/FileStreamStrategyTest.java new file mode 100644 index 0000000..9f7f46d --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/persistence/FileStreamStrategyTest.java @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 17. June 2006 by Guilherme Silveira + */ +package com.thoughtworks.xstream.persistence; + +import java.io.File; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import junit.framework.TestCase; + + +/** + * @author Guilherme Silveira + */ +public class FileStreamStrategyTest extends TestCase { + + private final File baseDir = new File("target/tmp"); + + protected void setUp() throws Exception { + super.setUp(); + if (baseDir.exists()) { + clear(baseDir); + } + baseDir.mkdirs(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + clear(baseDir); + } + + private void clear(File dir) { + File[] files = dir.listFiles(); + for (int i = 0; i < files.length; i++ ) { + if (files[i].isFile()) { + boolean deleted = files[i].delete(); + if (!deleted) { + throw new RuntimeException( + "Unable to continue testing: unable to remove file " + + files[i].getAbsolutePath()); + } + } + } + dir.delete(); + } + + public void testConcatenatesXmlExtensionWhileGettingAFilename() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + assertEquals("guilherme.xml", strategy.getName("guilherme")); + } + + public void testConcatenatesXmlExtensionWhileExtractingAKey() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + assertEquals("guilherme", strategy.extractKey("guilherme.xml")); + } + + public void testEscapesNonAcceptableCharacterWhileExtractingAKey() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + assertEquals("../guilherme", strategy.extractKey("_2e__2e__2f_guilherme.xml")); + } + + public void testEscapesNonAcceptableCharacterWhileGettingAFilename() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + assertEquals("_2e__2e__2f_guilherme.xml", strategy.getName("../guilherme")); + } + + public void testEscapesUTF8NonAcceptableCharacterWhileGettingAFilename() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + assertEquals("_5377_guilherme.xml", strategy.getName("\u5377guilherme")); + } + + public void testEscapesUTF8NonAcceptableCharacterWhileExtractingAKey() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + assertEquals("\u5377guilherme", strategy.extractKey("_5377_guilherme.xml")); + } + + public void testEscapesUnderlineWhileGettingAFilename() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + assertEquals("__guilherme.xml", strategy.getName("_guilherme")); + } + + public void testEscapesUnderlineWhileExtractingAKey() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + assertEquals("_guilherme", strategy.extractKey("__guilherme.xml")); + } + + public void testEscapesNullKeyWhileGettingAFileName() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + assertEquals("_0_.xml", strategy.getName(null)); + } + + public void testEscapesNullKeyWhileExtractingKey() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + assertNull(strategy.extractKey("_0_.xml")); + } + + public void testWritesASingleFile() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + File file = new File(baseDir, "guilherme.xml"); + assertTrue(file.exists()); + } + + public void testWritesTwoFiles() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + strategy.put("silveira", "anotherCuteString"); + assertTrue(new File(baseDir, "guilherme.xml").exists()); + assertTrue(new File(baseDir, "silveira.xml").exists()); + } + + public void testRemovesAWrittenFile() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + assertTrue(new File(baseDir, "guilherme.xml").exists()); + String aCuteString = (String)strategy.remove("guilherme"); + assertEquals("aCuteString", aCuteString); + assertFalse(new File(baseDir, "guilherme.xml").exists()); + } + + public void testRemovesAnInvalidFile() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + String aCuteString = (String)strategy.remove("guilherme"); + assertNull(aCuteString); + } + + public void testHasZeroLength() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + assertEquals(0, strategy.size()); + } + + public void testHasOneItem() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + assertEquals(1, strategy.size()); + } + + public void testHasTwoItems() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + strategy.put("silveira", "anotherCuteString"); + assertEquals(2, strategy.size()); + } + + public void testIsNotEmpty() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + assertEquals("Map should not be empty", 1, strategy.size()); + } + + public void testDoesNotContainKey() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + assertFalse(strategy.containsKey("guilherme")); + } + + public void testContainsKey() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + assertTrue(strategy.containsKey("guilherme")); + } + + public void testGetsAFile() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + assertTrue(new File(baseDir, "guilherme.xml").exists()); + String aCuteString = (String)strategy.get("guilherme"); + assertEquals("aCuteString", aCuteString); + } + + public void testGetsAnInvalidFile() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + String aCuteString = (String)strategy.get("guilherme"); + assertNull(aCuteString); + } + + public void testRewritesASingleFile() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + File file = new File(baseDir, "guilherme.xml"); + assertTrue(file.exists()); + strategy.put("guilherme", "anotherCuteString"); + assertEquals("anotherCuteString", strategy.get("guilherme")); + } + + public void testIsEmpty() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + assertEquals("Map should be empty", 0, strategy.size()); + } + + public void testContainsAllItems() { + Map original = new HashMap(); + original.put("guilherme", "aCuteString"); + original.put("silveira", "anotherCuteString"); + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + strategy.put("silveira", "anotherCuteString"); + for (Iterator iter = original.keySet().iterator(); iter.hasNext();) { + assertTrue(strategy.containsKey(iter.next())); + } + } + + // actually an acceptance test? + public void testIteratesOverEntryAndChecksItsKeyWithAnotherInstance() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + strategy.put("silveira", "anotherCuteString"); + FileStreamStrategy built = new FileStreamStrategy(baseDir); + for (Iterator iter = strategy.iterator(); iter.hasNext();) { + Map.Entry entry = (Map.Entry)iter.next(); + assertTrue(built.containsKey(entry.getKey())); + } + } + + public void testRemovesAnItemThroughIteration() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + strategy.put("silveira", "anotherCuteString"); + for (Iterator iter = strategy.iterator(); iter.hasNext();) { + Map.Entry entry = (Map.Entry)iter.next(); + if (entry.getKey().equals("guilherme")) { + iter.remove(); + } + } + assertFalse(strategy.containsKey("guilherme")); + } + + public void testRewritesAFile() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + strategy.put("guilherme", "anotherCuteString"); + assertEquals("anotherCuteString", strategy.get("guilherme")); + } + + public void testPutReturnsTheOldValueWhenRewritingAFile() { + FileStreamStrategy strategy = new FileStreamStrategy(baseDir); + strategy.put("guilherme", "aCuteString"); + assertEquals("aCuteString", strategy.put("guilherme", "anotherCuteString")); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/persistence/XmlArrayListTest.java b/xstream/src/test/com/thoughtworks/xstream/persistence/XmlArrayListTest.java new file mode 100644 index 0000000..1bf5d57 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/persistence/XmlArrayListTest.java @@ -0,0 +1,283 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. July 2006 by Guilherme Silveira + */ +package com.thoughtworks.xstream.persistence; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import junit.framework.TestCase; + +public class XmlArrayListTest extends TestCase { + private MockedStrategy strategy; + + public void setUp() throws Exception { + super.setUp(); + strategy = new MockedStrategy(); + } + + public void testWritesASingleObject() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + assertTrue(strategy.map.containsValue("guilherme")); + } + + public void testWritesASingleObjectInANegativePosition() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + try { + xmlList.add(-1, "guilherme"); + fail(); + } catch (IndexOutOfBoundsException ex) { + // ok + } + } + + public void testWritesASingleObjectInFirstPosition() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + assertTrue(strategy.map.containsKey(new Integer(0))); + } + + public void testWritesTwoObjects() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + xmlList.add("silveira"); + assertTrue(strategy.map.containsValue("guilherme")); + assertTrue(strategy.map.containsValue("silveira")); + assertTrue(strategy.map.containsKey(new Integer(0))); + assertTrue(strategy.map.containsKey(new Integer(1))); + } + + public void testWritesTwoObjectsGuaranteesItsEnumerationOrder() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + xmlList.add("silveira"); + assertEquals("guilherme", strategy.map.get(new Integer(0))); + assertEquals("silveira", strategy.map.get(new Integer(1))); + } + + public void testWritesASecondObjectInAPositionHigherThanTheListsSize() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + try { + xmlList.add("silveira"); + xmlList.add(3, "guilherme"); + fail(); + } catch (IndexOutOfBoundsException ex) { + // ok + } + } + + public void testRemovesAWrittenObject() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + assertTrue(xmlList.remove("guilherme")); + assertFalse(strategy.map.containsValue("guilherme")); + } + + public void testRemovesAWrittenObjectImplyingInAChangeInTheList() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + boolean changed = xmlList.remove("guilherme"); + assertTrue(changed); + } + + public void testRemovesAnInvalidObjectWithoutAffectingTheList() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + boolean removed = xmlList.remove("guilherme"); + assertFalse(removed); + } + + public void testHasZeroLengthWhenInstantiated() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + assertEquals(0, xmlList.size()); + } + + public void testHasOneItem() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + assertEquals(1, xmlList.size()); + } + + public void testHasTwoItems() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + xmlList.add("silveira"); + assertEquals(2, xmlList.size()); + } + + public void testIsNotEmpty() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + assertFalse(xmlList.isEmpty()); + } + + public void testDoesNotContainKey() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + assertFalse(xmlList.contains("guilherme")); + } + + public void testContainsKey() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + assertTrue(xmlList.contains("guilherme")); + } + + public void testGetsAnObject() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + Object onlyValue = xmlList.iterator().next(); + assertEquals("guilherme", onlyValue); + } + + public void testGetsTheFirstObject() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + assertEquals("guilherme", xmlList.get(0)); + } + + public void testGetsTheSecondObject() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + xmlList.add("silveira"); + assertEquals("silveira", xmlList.get(1)); + } + + public void testInsertsAnObjectInTheMiddleOfTheList() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + xmlList.add("silveira"); + xmlList.add(1, "de azevedo"); + assertEquals("guilherme", xmlList.get(0)); + assertEquals("de azevedo", xmlList.get(1)); + assertEquals("silveira", xmlList.get(2)); + } + + public void testIteratingGuaranteesItsEnumeration() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + xmlList.add("silveira"); + Iterator it = xmlList.iterator(); + assertEquals("guilherme", it.next()); + assertEquals("silveira", it.next()); + } + + public void testIsEmpty() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + assertTrue(xmlList.isEmpty()); + } + + public void testClearsItsObjects() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + xmlList.add("silveira"); + xmlList.clear(); + assertEquals(0, xmlList.size()); + } + + public void testPutsAllAddsTwoItems() { + Set original = new HashSet(); + original.add("guilherme"); + original.add("silveira"); + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.addAll(original); + assertEquals(2, xmlList.size()); + } + + public void testContainsASpecificValue() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + assertTrue(xmlList.contains("guilherme")); + } + + public void testDoesNotContainASpecificValue() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + assertFalse(xmlList.contains("zzzz")); + } + + public void testEntrySetContainsAllItems() { + Set original = new HashSet(); + original.add("guilherme"); + original.add("silveira"); + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + xmlList.add("silveira"); + assertTrue(xmlList.containsAll(original)); + } + + // actually an acceptance test? + public void testIteratesOverEntryAndChecksWithAnotherInstance() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + xmlList.add("silveira"); + XmlArrayList built = new XmlArrayList(this.strategy); + for (Iterator iter = xmlList.iterator(); iter.hasNext();) { + Object entry = iter.next(); + assertTrue(built.contains(entry)); + } + } + + public void testIteratesOverEntrySetContainingTwoItems() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + xmlList.add("silveira"); + List built = new ArrayList(); + for (Iterator iter = xmlList.iterator(); iter.hasNext();) { + Object entry = iter.next(); + built.add(entry); + } + assertEquals(xmlList, built); + } + + public void testRemovesAnItemThroughIteration() { + XmlArrayList xmlList = new XmlArrayList(this.strategy); + xmlList.add("guilherme"); + xmlList.add("silveira"); + for (Iterator iter = xmlList.iterator(); iter.hasNext();) { + Object entry = iter.next(); + if (entry.equals("guilherme")) { + iter.remove(); + } + } + assertFalse(xmlList.contains("guilherme")); + } + + private static class MockedStrategy implements PersistenceStrategy { + + private Map map = new HashMap(); + + public Iterator iterator() { + return map.entrySet().iterator(); + } + + public int size() { + return map.size(); + } + + public Object get(Object key) { + return map.get(key); + } + + public Object put(Object key, Object value) { + return map.put(key, value); + } + + public Object remove(Object key) { + return map.remove(key); + } + + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/persistence/XmlMapTest.java b/xstream/src/test/com/thoughtworks/xstream/persistence/XmlMapTest.java new file mode 100644 index 0000000..d9b8f26 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/persistence/XmlMapTest.java @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. June 2006 by Guilherme Silveira + */ +package com.thoughtworks.xstream.persistence; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import junit.framework.TestCase; + +public class XmlMapTest extends TestCase { + + private MockedStrategy strategy; + + public void setUp() throws Exception { + super.setUp(); + strategy = new MockedStrategy(); + } + + public void testWritesASingleObject() { + XmlMap map = new XmlMap(this.strategy); + map.put("guilherme", "aCuteString"); + assertTrue(strategy.map.containsKey("guilherme")); + } + + public void testWritesTwoObjects() { + XmlMap map = new XmlMap(this.strategy); + map.put("guilherme", "aCuteString"); + map.put("silveira", "anotherCuteString"); + assertTrue(strategy.map.containsKey("guilherme")); + assertTrue(strategy.map.containsKey("silveira")); + } + + public void testRemovesAWrittenObject() { + XmlMap map = new XmlMap(this.strategy); + map.put("guilherme", "aCuteString"); + assertTrue(strategy.map.containsKey("guilherme")); + String aCuteString = (String) map.remove("guilherme"); + assertEquals("aCuteString", aCuteString); + assertFalse(strategy.map.containsKey("guilherme")); + } + + public void testRemovesAnInvalidObject() { + XmlMap map = new XmlMap(this.strategy); + String aCuteString = (String) map.remove("guilherme"); + assertNull(aCuteString); + } + + public void testHasZeroLength() { + XmlMap map = new XmlMap(this.strategy); + assertEquals(0, map.size()); + } + + public void testHasOneItem() { + XmlMap map = new XmlMap(this.strategy); + map.put("guilherme", "aCuteString"); + assertEquals(1, map.size()); + } + + public void testHasTwoItems() { + XmlMap map = new XmlMap(this.strategy); + map.put("guilherme", "aCuteString"); + map.put("silveira", "anotherCuteString"); + assertEquals(2, map.size()); + } + + public void testIsNotEmpty() { + XmlMap map = new XmlMap(this.strategy); + map.put("guilherme", "aCuteString"); + assertFalse("Map should not be empty", map.isEmpty()); + } + + public void testDoesNotContainKey() { + XmlMap map = new XmlMap(this.strategy); + assertFalse(map.containsKey("guilherme")); + } + + public void testContainsKey() { + XmlMap map = new XmlMap(this.strategy); + map.put("guilherme", "aCuteString"); + assertTrue(map.containsKey("guilherme")); + } + + public void testGetsAnObject() { + XmlMap map = new XmlMap(this.strategy); + this.strategy.map.put("guilherme", "aCuteString"); + String aCuteString = (String) map.get("guilherme"); + assertEquals("aCuteString", aCuteString); + } + + public void testGetsAnInvalidObject() { + XmlMap map = new XmlMap(this.strategy); + String aCuteString = (String) map.get("guilherme"); + assertNull(aCuteString); + } + + public void testRewritesASingleObject() { + XmlMap map = new XmlMap(this.strategy); + map.put("guilherme", "aCuteString"); + assertEquals("aCuteString", map.get("guilherme")); + map.put("guilherme", "anotherCuteString"); + assertEquals("anotherCuteString", map.get("guilherme")); + } + + public void testIsEmpty() { + XmlMap map = new XmlMap(this.strategy); + assertTrue("Map should be empty", map.isEmpty()); + } + + public void testClearsItsObjects() { + XmlMap map = new XmlMap(this.strategy); + map.put("guilherme", "aCuteString"); + map.put("silveira", "anotherCuteString"); + map.clear(); + assertEquals(0, map.size()); + } + + public void testPutsAllAddsTwoItems() { + Map original = new HashMap(); + original.put("guilherme", "aCuteString"); + original.put("silveira", "anotherCuteString"); + XmlMap map = new XmlMap(this.strategy); + map.putAll(original); + assertEquals(2, map.size()); + } + + public void testContainsASpecificValue() { + XmlMap map = new XmlMap(this.strategy); + String value = "aCuteString"; + map.put("guilherme", value); + assertTrue(map.containsValue(value)); + } + + public void testDoesNotContainASpecificValue() { + XmlMap map = new XmlMap(this.strategy); + assertFalse(map.containsValue("zzzz")); + } + + public void testEntrySetContainsAllItems() { + Map original = new HashMap(); + original.put("guilherme", "aCuteString"); + original.put("silveira", "anotherCuteString"); + Set originalSet = original.entrySet(); + XmlMap map = new XmlMap(this.strategy); + map.put("guilherme", "aCuteString"); + map.put("silveira", "anotherCuteString"); + Set set = map.entrySet(); + assertTrue(set.containsAll(originalSet)); + } + + // actually an acceptance test? + public void testIteratesOverEntryAndChecksItsKeyWithAnotherInstance() { + XmlMap map = new XmlMap(this.strategy); + map.put("guilherme", "aCuteString"); + map.put("silveira", "anotherCuteString"); + XmlMap built = new XmlMap(this.strategy); + for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) { + Map.Entry entry = (Map.Entry) iter.next(); + assertTrue(built.containsKey(entry.getKey())); + } + } + + // actually an acceptance test? + public void testIteratesOverEntryAndChecksItsValueWithAnotherInstance() { + XmlMap map = new XmlMap(this.strategy); + map.put("guilherme", "aCuteString"); + map.put("silveira", "anotherCuteString"); + XmlMap built = new XmlMap(this.strategy); + for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) { + Map.Entry entry = (Map.Entry) iter.next(); + assertTrue(built.containsValue(entry.getValue())); + } + } + + public void testIteratesOverEntrySetContainingTwoItems() { + XmlMap map = new XmlMap(this.strategy); + map.put("guilherme", "aCuteString"); + map.put("silveira", "anotherCuteString"); + Map built = new HashMap(); + for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) { + Map.Entry entry = (Map.Entry) iter.next(); + built.put(entry.getKey(), entry.getValue()); + } + assertEquals(map, built); + } + + public void testRemovesAnItemThroughIteration() { + XmlMap map = new XmlMap(this.strategy); + map.put("guilherme", "aCuteString"); + map.put("silveira", "anotherCuteString"); + for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) { + Map.Entry entry = (Map.Entry) iter.next(); + if (entry.getKey().equals("guilherme")) { + iter.remove(); + } + } + assertFalse(map.containsKey("guilherme")); + } + + public void testRewritesAObject() { + XmlMap map = new XmlMap(this.strategy); + map.put("guilherme", "aCuteString"); + map.put("guilherme", "anotherCuteString"); + assertEquals("anotherCuteString", map.get("guilherme")); + } + + public void testPutReturnsTheOldValueWhenRewritingAObject() { + XmlMap map = new XmlMap(this.strategy); + map.put("guilherme", "aCuteString"); + assertEquals("aCuteString", map.put("guilherme", "anotherCuteString")); + } + + private static class MockedStrategy implements PersistenceStrategy { + + private Map map = new HashMap(); + + public Iterator iterator() { + return map.entrySet().iterator(); + } + + public int size() { + return map.size(); + } + + public Object get(Object key) { + return map.get(key); + } + + public Object put(Object key, Object value) { + return map.put(key, value); + } + + public Object remove(Object key) { + return map.remove(key); + } + + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/persistence/XmlSetTest.java b/xstream/src/test/com/thoughtworks/xstream/persistence/XmlSetTest.java new file mode 100644 index 0000000..817f539 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/persistence/XmlSetTest.java @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 28. June 2006 by Guilherme Silveira + */ +package com.thoughtworks.xstream.persistence; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import junit.framework.TestCase; + +public class XmlSetTest extends TestCase { + private MockedStrategy strategy; + public void setUp() throws Exception { + super.setUp(); + strategy = new MockedStrategy(); + } + + public void testWritesASingleObject() { + XmlSet set = new XmlSet(this.strategy); + set.add("guilherme"); + assertTrue(strategy.map.containsValue("guilherme")); + } + + public void testWritesTwoObjects() { + XmlSet set = new XmlSet(this.strategy); + set.add("guilherme"); + set.add("silveira"); + assertTrue(strategy.map.containsValue("guilherme")); + assertTrue(strategy.map.containsValue("silveira")); + } + + public void testRemovesAWrittenObject() { + XmlSet set = new XmlSet(this.strategy); + set.add("guilherme"); + assertTrue(strategy.map.containsValue("guilherme")); + boolean changed = set.remove("guilherme"); + assertTrue(changed); + assertFalse(strategy.map.containsValue("guilherme")); + } + + public void testRemovesAnInvalidObject() { + XmlSet set = new XmlSet(this.strategy); + boolean removed= set.remove("guilherme"); + assertFalse(removed); + } + + public void testHasZeroLength() { + XmlSet set = new XmlSet(this.strategy); + assertEquals(0, set.size()); + } + + public void testHasOneItem() { + XmlSet set = new XmlSet(this.strategy); + set.add("guilherme"); + assertEquals(1, set.size()); + } + + public void testHasTwoItems() { + XmlSet set = new XmlSet(this.strategy); + set.add("guilherme"); + set.add("silveira"); + assertEquals(2, set.size()); + } + + public void testIsNotEmpty() { + XmlSet set = new XmlSet(this.strategy); + set.add("guilherme"); + assertFalse("set should not be empty", set.isEmpty()); + } + + public void testDoesNotContainKey() { + XmlSet set = new XmlSet(this.strategy); + assertFalse(set.contains("guilherme")); + } + + public void testContainsKey() { + XmlSet set = new XmlSet(this.strategy); + set.add("guilherme"); + assertTrue(set.contains("guilherme")); + } + + public void testGetsAnObject() { + XmlSet set = new XmlSet(this.strategy); + set.add("guilherme"); + Object onlyValue = set.iterator().next(); + assertEquals("guilherme", onlyValue); + } + + public void testIsEmpty() { + XmlSet set = new XmlSet(this.strategy); + assertTrue("set should be empty", set.isEmpty()); + } + + public void testClearsItsObjects() { + XmlSet set = new XmlSet(this.strategy); + set.add("guilherme"); + set.add("silveira"); + set.clear(); + assertEquals(0, set.size()); + } + + public void testPutsAllAddsTwoItems() { + Set original = new HashSet(); + original.add("guilherme"); + original.add("silveira"); + XmlSet set = new XmlSet(this.strategy); + set.addAll(original); + assertEquals(2, set.size()); + } + + public void testContainsASpecificValue() { + XmlSet set = new XmlSet(this.strategy); + set.add("guilherme"); + assertTrue(set.contains("guilherme")); + } + + public void testDoesNotContainASpecificValue() { + XmlSet set = new XmlSet(this.strategy); + assertFalse(set.contains("zzzz")); + } + + public void testEntrySetContainsAllItems() { + Set original = new HashSet(); + original.add("guilherme"); + original.add("silveira"); + XmlSet set = new XmlSet(this.strategy); + set.add("guilherme"); + set.add("silveira"); + assertTrue(set.containsAll(original)); + } + + // actually an acceptance test? + public void testIteratesOverEntryAndChecksWithAnotherInstance() { + XmlSet set = new XmlSet(this.strategy); + set.add("guilherme"); + set.add("silveira"); + XmlSet built = new XmlSet(this.strategy); + for (Iterator iter = set.iterator(); iter.hasNext();) { + Object entry = iter.next(); + assertTrue(built.contains(entry)); + } + } + + public void testIteratesOverEntrySetContainingTwoItems() { + XmlSet set = new XmlSet(this.strategy); + set.add("guilherme"); + set.add("silveira"); + Set built = new HashSet(); + for (Iterator iter = set.iterator(); iter.hasNext();) { + Object entry = iter.next(); + built.add(entry); + } + assertEquals(set, built); + } + + public void testRemovesAnItemThroughIteration() { + XmlSet set = new XmlSet(this.strategy); + set.add("guilherme"); + set.add("silveira"); + for (Iterator iter = set.iterator(); iter.hasNext();) { + Object entry = iter.next(); + if (entry.equals("guilherme")) { + iter.remove(); + } + } + assertFalse(set.contains("guilherme")); + } + + private static class MockedStrategy implements PersistenceStrategy { + + private Map map = new HashMap(); + + public Iterator iterator() { + return map.entrySet().iterator(); + } + + public int size() { + return map.size(); + } + + public Object get(Object key) { + return map.get(key); + } + + public Object put(Object key, Object value) { + return map.put(key, value); + } + + public Object remove(Object key) { + return map.remove(key); + } + + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/testutil/CallLog.java b/xstream/src/test/com/thoughtworks/xstream/testutil/CallLog.java new file mode 100644 index 0000000..7e0cbfd --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/testutil/CallLog.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 02. February 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.testutil; + +import junit.framework.Assert; + +public class CallLog { + + private StringBuffer expected = new StringBuffer(); + private StringBuffer actual = new StringBuffer(); + + public void expect(String message) { + expected.append(message).append('\n'); + } + + public void actual(String message) { + actual.append(message).append('\n'); + } + + public void verify() { + Assert.assertEquals(expected.toString(), actual.toString()); + reset(); + } + + public void reset() { + expected = new StringBuffer(); + actual = new StringBuffer(); + } + +} diff --git a/xstream/src/test/com/thoughtworks/xstream/testutil/DynamicSecurityManager.java b/xstream/src/test/com/thoughtworks/xstream/testutil/DynamicSecurityManager.java new file mode 100644 index 0000000..5c425a6 --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/testutil/DynamicSecurityManager.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2006, 2007, 2009, 2010 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 14. March 2006 by Joerg Schaible + */ +package com.thoughtworks.xstream.testutil; + +import java.io.FilePermission; +import java.security.AccessControlContext; +import java.security.CodeSource; +import java.security.Permission; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.ProtectionDomain; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + + +/** + * @author Jörg Schaible + */ +public class DynamicSecurityManager extends SecurityManager { + + private Map permissions = new HashMap(); + private AccessControlContext acc = null; + private List failedPermissions = new ArrayList(); + + public void addPermission(final CodeSource codeSource, final Permission permission) { + PermissionCollection permissionCollection = (PermissionCollection)permissions + .get(codeSource); + if (permissionCollection == null) { + permissionCollection = new Permissions(); + permissions.put(codeSource, permissionCollection); + } + permissionCollection.add(permission); +// updateACC(); + } + + public void setPermissions( + final CodeSource codeSource, final PermissionCollection permissionCollection) { + if (permissionCollection == null) { + if (permissions.remove(codeSource) != null) { +// updateACC(); + } + } else { + if (permissions.put(codeSource, permissionCollection) != null) { +// updateACC(); + } + } + } + + private void updateACC() { + if (permissions.size() == 0) { + acc = null; + } else { + final ProtectionDomain[] domains = new ProtectionDomain[permissions.size()]; + int i = 0; + for (final Iterator iter = permissions.keySet().iterator(); iter.hasNext();) { + final CodeSource codeSource = (CodeSource)iter.next(); + final PermissionCollection permissionCollection = (PermissionCollection)permissions + .get(codeSource); + domains[i++] = new ProtectionDomain(codeSource, permissionCollection); + } + acc = new AccessControlContext(domains); + } + } + + public void setReadOnly() { + updateACC(); + } + + public void checkPermission(Permission perm) { + if (acc != null) { + // Ughhh. Eclipse class path leak :-/ + if (perm instanceof FilePermission && "read".equals(perm.getActions())) { + String name = perm.getName(); + if (name.indexOf("org.eclipse.osgi") > 0 + && (name.endsWith("javax.xml.parsers.DocumentBuilderFactory") + || name.endsWith("javax.xml.datatype.DatatypeFactory"))) { + return; + } + } + try { + checkPermission(perm, acc); + } catch (final SecurityException e) { + failedPermissions.add(perm); + throw e; + } + } + } + + public List getFailedPermissions() { + return Collections.unmodifiableList(failedPermissions); + } +} diff --git a/xstream/src/test/com/thoughtworks/xstream/testutil/TimeZoneChanger.java b/xstream/src/test/com/thoughtworks/xstream/testutil/TimeZoneChanger.java new file mode 100644 index 0000000..0e21c4e --- /dev/null +++ b/xstream/src/test/com/thoughtworks/xstream/testutil/TimeZoneChanger.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. January 2005 by Joe Walnes + */ +package com.thoughtworks.xstream.testutil; + +import java.util.TimeZone; + +public class TimeZoneChanger { + + private static final TimeZone originalTimeZone = TimeZone.getDefault(); + + public static void change(String timeZone) { + TimeZone.setDefault(TimeZone.getTimeZone(timeZone)); + } + + public static void reset() { + TimeZone.setDefault(originalTimeZone); + } + +} diff --git a/xstream-benchmark/pom.xml b/xstream-benchmark/pom.xml new file mode 100644 index 0000000..d6fb34a --- /dev/null +++ b/xstream-benchmark/pom.xml @@ -0,0 +1,136 @@ + + + 4.0.0 + + com.thoughtworks.xstream + xstream-parent + 1.4.8 + + xstream-benchmark + jar + XStream Benchmark + Benchmark suite of XStream. + + + + jdk18-ge + + [1.8,) + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + com.thoughtworks.xstream.tools.benchmark.model + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${version.plugin.maven.javadoc} + + com.thoughtworks.xstream.tools.benchmark.model + ${javadoc.xdoclint} + false + ${version.java.source} + + ${link.javadoc.javase} + + + + + + + + jdk15-ge + + [1.5,) + + + + + org.apache.maven.plugins + maven-jar-plugin + + + ${project.build.directory}/OSGi/MANIFEST.MF + + + + + org.apache.felix + maven-bundle-plugin + + + !com.thoughtworks.xstream.tools.benchmark.model,com.thoughtworks.xstream.tools.benchmark.*;-noimport:=true + + + + + + + + + + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + + + com.thoughtworks.xstream + xstream + + + net.sf.kxml + kxml2-min + test + + + commons-lang + commons-lang + test + + + commons-cli + commons-cli + test + + + commons-io + commons-io + test + + + junit + junit + + + diff --git a/xstream-benchmark/src/benchmarks/xmlfriendly-joehni.html b/xstream-benchmark/src/benchmarks/xmlfriendly-joehni.html new file mode 100644 index 0000000..68c893b --- /dev/null +++ b/xstream-benchmark/src/benchmarks/xmlfriendly-joehni.html @@ -0,0 +1,652 @@ + + + XmlFriendlyReplacer Benchmark + + + +

XmlFriendlyReplacer Benchmark

+

Size of serialized data

+

Field Target

+ + + + + + + + + + +
Productbytes
353514.0 +
+
+

Field with underscores Target

+ + + + + + + + + + +
Productbytes
353914.0 +
+
+

Field with dollars Target

+ + + + + + + + + + +
Productbytes
353914.0 +
+
+

Character count for '$'

+

Field Target

+ + + + + + + + + + +
Productcharacters
0.0 +
+
+

Field with underscores Target

+ + + + + + + + + + +
Productcharacters
0.0 +
+
+

Field with dollars Target

+ + + + + + + + + + +
Productcharacters
100200.0 +
+
+

Character count for '_'

+

Field Target

+ + + + + + + + + + +
Productcharacters
0.0 +
+
+

Field with underscores Target

+ + + + + + + + + + +
Productcharacters
100200.0 +
+
+

Field with dollars Target

+ + + + + + + + + + +
Productcharacters
0.0 +
+
+

Serialization speed (50 iterations)

+

Field Target

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Productms
XStream 1.2.2 Replacer7788.0 +
+
Combined Lookup Appending9173.0 +
+
Combined Lookup Appending (16)7628.0 +
+
Combined Lookup Replacer7806.0 +
+
Combined Lookup Replacer (16)7817.0 +
+
Iterative Appender7634.0 +
+
Iterative Appender (16)7785.0 +
+
Iterative Replacer7787.0 +
+
Iterative Replacer (16)7937.0 +
+
Separate Lookup Replacer7779.0 +
+
Separate Lookup Replacer (16)7765.0 +
+
+

Field with underscores Target

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Productms
XStream 1.2.2 Replacer7971.0 +
+
Combined Lookup Appending8416.0 +
+
Combined Lookup Appending (16)8197.0 +
+
Combined Lookup Replacer8477.0 +
+
Combined Lookup Replacer (16)8673.0 +
+
Iterative Appender7818.0 +
+
Iterative Appender (16)9497.0 +
+
Iterative Replacer8003.0 +
+
Iterative Replacer (16)8010.0 +
+
Separate Lookup Replacer8422.0 +
+
Separate Lookup Replacer (16)8528.0 +
+
+

Field with dollars Target

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Productms
XStream 1.2.2 Replacer8038.0 +
+
Combined Lookup Appending9266.0 +
+
Combined Lookup Appending (16)9174.0 +
+
Combined Lookup Replacer8888.0 +
+
Combined Lookup Replacer (16)8926.0 +
+
Iterative Appender8337.0 +
+
Iterative Appender (16)8402.0 +
+
Iterative Replacer9186.0 +
+
Iterative Replacer (16)8299.0 +
+
Separate Lookup Replacer8540.0 +
+
Separate Lookup Replacer (16)8617.0 +
+
+

Deserialization speed (50 iterations)

+

Field Target

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Productms
XStream 1.2.2 Replacer15346.0 +
+
Combined Lookup Appending13864.0 +
+
Combined Lookup Appending (16)13438.0 +
+
Combined Lookup Replacer13480.0 +
+
Combined Lookup Replacer (16)13700.0 +
+
Iterative Appender14062.0 +
+
Iterative Appender (16)13926.0 +
+
Iterative Replacer13634.0 +
+
Iterative Replacer (16)13496.0 +
+
Separate Lookup Replacer13630.0 +
+
Separate Lookup Replacer (16)13985.0 +
+
+

Field with underscores Target

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Productms
XStream 1.2.2 Replacer15547.0 +
+
Combined Lookup Appending14747.0 +
+
Combined Lookup Appending (16)14816.0 +
+
Combined Lookup Replacer16730.0 +
+
Combined Lookup Replacer (16)15099.0 +
+
Iterative Appender13857.0 +
+
Iterative Appender (16)13982.0 +
+
Iterative Replacer16226.0 +
+
Iterative Replacer (16)16218.0 +
+
Separate Lookup Replacer15496.0 +
+
Separate Lookup Replacer (16)15151.0 +
+
+

Field with dollars Target

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Productms
XStream 1.2.2 Replacer14163.0 +
+
Combined Lookup Appending14140.0 +
+
Combined Lookup Appending (16)14360.0 +
+
Combined Lookup Replacer14938.0 +
+
Combined Lookup Replacer (16)14771.0 +
+
Iterative Appender13549.0 +
+
Iterative Appender (16)13679.0 +
+
Iterative Replacer14890.0 +
+
Iterative Replacer (16)15030.0 +
+
Separate Lookup Replacer15437.0 +
+
Separate Lookup Replacer (16)17536.0 +
+
+

Fri Sep 14 23:41:12 CEST 2007 - Sun JDK 1.6.0_02/Linux x86 - AMD Athlon XP 2700+ (2.1Ghz)

+ + \ No newline at end of file diff --git a/xstream-benchmark/src/benchmarks/xmlfriendly-joehni.txt b/xstream-benchmark/src/benchmarks/xmlfriendly-joehni.txt new file mode 100644 index 0000000..83a9d23 --- /dev/null +++ b/xstream-benchmark/src/benchmarks/xmlfriendly-joehni.txt @@ -0,0 +1,110 @@ +====================================================================== +Size of serialized data +====================================================================== +* Field Target + - .................................................. 353514.0 bytes +* Field with underscores Target + - .................................................. 353914.0 bytes +* Field with dollars Target + - .................................................. 353914.0 bytes + +====================================================================== +Character count for '$' +====================================================================== +* Field Target + - .................................................. 0.0 characters +* Field with underscores Target + - .................................................. 0.0 characters +* Field with dollars Target + - .................................................. 100200.0 characters + +====================================================================== +Character count for '_' +====================================================================== +* Field Target + - .................................................. 0.0 characters +* Field with underscores Target + - .................................................. 100200.0 characters +* Field with dollars Target + - .................................................. 0.0 characters + +====================================================================== +Serialization speed (50 iterations) +====================================================================== +* Field Target + - XStream 1.2.2 Replacer............................ 7788.0 ms + - Combined Lookup Appending......................... 9173.0 ms + - Combined Lookup Appending (16).................... 7628.0 ms + - Combined Lookup Replacer.......................... 7806.0 ms + - Combined Lookup Replacer (16)..................... 7817.0 ms + - Iterative Appender................................ 7634.0 ms + - Iterative Appender (16)........................... 7785.0 ms + - Iterative Replacer................................ 7787.0 ms + - Iterative Replacer (16)........................... 7937.0 ms + - Separate Lookup Replacer.......................... 7779.0 ms + - Separate Lookup Replacer (16)..................... 7765.0 ms +* Field with underscores Target + - XStream 1.2.2 Replacer............................ 7971.0 ms + - Combined Lookup Appending......................... 8416.0 ms + - Combined Lookup Appending (16).................... 8197.0 ms + - Combined Lookup Replacer.......................... 8477.0 ms + - Combined Lookup Replacer (16)..................... 8673.0 ms + - Iterative Appender................................ 7818.0 ms + - Iterative Appender (16)........................... 9497.0 ms + - Iterative Replacer................................ 8003.0 ms + - Iterative Replacer (16)........................... 8010.0 ms + - Separate Lookup Replacer.......................... 8422.0 ms + - Separate Lookup Replacer (16)..................... 8528.0 ms +* Field with dollars Target + - XStream 1.2.2 Replacer............................ 8038.0 ms + - Combined Lookup Appending......................... 9266.0 ms + - Combined Lookup Appending (16).................... 9174.0 ms + - Combined Lookup Replacer.......................... 8888.0 ms + - Combined Lookup Replacer (16)..................... 8926.0 ms + - Iterative Appender................................ 8337.0 ms + - Iterative Appender (16)........................... 8402.0 ms + - Iterative Replacer................................ 9186.0 ms + - Iterative Replacer (16)........................... 8299.0 ms + - Separate Lookup Replacer.......................... 8540.0 ms + - Separate Lookup Replacer (16)..................... 8617.0 ms + +====================================================================== +Deserialization speed (50 iterations) +====================================================================== +* Field Target + - XStream 1.2.2 Replacer............................ 15346.0 ms + - Combined Lookup Appending......................... 13864.0 ms + - Combined Lookup Appending (16).................... 13438.0 ms + - Combined Lookup Replacer.......................... 13480.0 ms + - Combined Lookup Replacer (16)..................... 13700.0 ms + - Iterative Appender................................ 14062.0 ms + - Iterative Appender (16)........................... 13926.0 ms + - Iterative Replacer................................ 13634.0 ms + - Iterative Replacer (16)........................... 13496.0 ms + - Separate Lookup Replacer.......................... 13630.0 ms + - Separate Lookup Replacer (16)..................... 13985.0 ms +* Field with underscores Target + - XStream 1.2.2 Replacer............................ 15547.0 ms + - Combined Lookup Appending......................... 14747.0 ms + - Combined Lookup Appending (16).................... 14816.0 ms + - Combined Lookup Replacer.......................... 16730.0 ms + - Combined Lookup Replacer (16)..................... 15099.0 ms + - Iterative Appender................................ 13857.0 ms + - Iterative Appender (16)........................... 13982.0 ms + - Iterative Replacer................................ 16226.0 ms + - Iterative Replacer (16)........................... 16218.0 ms + - Separate Lookup Replacer.......................... 15496.0 ms + - Separate Lookup Replacer (16)..................... 15151.0 ms +* Field with dollars Target + - XStream 1.2.2 Replacer............................ 14163.0 ms + - Combined Lookup Appending......................... 14140.0 ms + - Combined Lookup Appending (16).................... 14360.0 ms + - Combined Lookup Replacer.......................... 14938.0 ms + - Combined Lookup Replacer (16)..................... 14771.0 ms + - Iterative Appender................................ 13549.0 ms + - Iterative Appender (16)........................... 13679.0 ms + - Iterative Replacer................................ 14890.0 ms + - Iterative Replacer (16)........................... 15030.0 ms + - Separate Lookup Replacer.......................... 15437.0 ms + - Separate Lookup Replacer (16)..................... 17536.0 ms + diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/Harness.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/Harness.java new file mode 100644 index 0000000..dd1bd74 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/Harness.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark; + +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; + +/** + * A simple harness for running benchmarks over object serialization products. + * + *

+ * There are three dimensions that can be added: + *

+ *
    + *
  • {@link Product} (e.g. DOM, SAX, XPP...)
  • + *
  • {@link Metric} (e.g. time taken, memory usage, output size...)
  • + *
  • {@link Target} (e.g. a small object, large object, list of objects...)
  • + *
+ *

+ * The Harness will then across every permutation of these + * (in order of product, metric, target), and write the results to a {@link Reporter}. + *

+ * + *

Example usage

+ *
+ * Harness harness = new Harness();
+ *
+ * // Compare speed of serialization/deserialization metrics...
+ * harness.addMetric(new SerializationSpeedMetric());
+ * harness.addMetric(new DeserializationSpeedMetric());
+ *
+ * // Using a simple String and a JTree instance...
+ * harness.addTarget(new StringTarget());
+ * harness.addTarget(new JTreeTarget());
+ *
+ * // Across XStream with different XML drivers.
+ * harness.addProduct(new XStreamDom());
+ * harness.addProduct(new XStreamXpp());
+ * harness.addProduct(new XStreamSax());
+ *
+ * // Now do it, and report the results as text to the console.
+ * harness.run(new TextReporter());
+ * 
+ * + * @author Joe Walnes + */ +public class Harness { + + private List products = new ArrayList(); + private List targets = new ArrayList(); + private List metrics = new ArrayList(); + + public synchronized void addProduct(Product product) { + products.add(product); + } + + public synchronized void addTarget(Target target) { + targets.add(target); + } + + public synchronized void addMetric(Metric metric) { + metrics.add(metric); + } + + public synchronized void run(Reporter reporter) { + // Nested loop galore. + reporter.startBenchmark(); + for (Iterator metricsIt = metrics.iterator(); metricsIt.hasNext();) { + Metric metric = (Metric) metricsIt.next(); + reporter.startMetric(metric); + for (Iterator targetIt = targets.iterator(); targetIt.hasNext();) { + Target target = (Target) targetIt.next(); + reporter.startTarget(target); + for (Iterator productsIt = products.iterator(); productsIt.hasNext();) { + Product product = (Product) productsIt.next(); + run(reporter, metric, target, product); + } + reporter.endTarget(target); + } + reporter.endMetric(metric); + } + reporter.endBenchmark(); + } + + private void run(Reporter reporter, Metric metric, Target target, Product product) { + try { + double result = metric.run(product, target); + reporter.metricRecorded(product, result); + } catch (Exception e) { + reporter.metricFailed(product, e); + } + } + +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/Metric.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/Metric.java new file mode 100644 index 0000000..8d68b91 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/Metric.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark; + +/** + * A metric is what's actually recorded. This provides a strategy + * for what to do with an object for a given product and should + * return a measurable result. For example it could serialize an + * object against a product and return how long it took to complete + * the operation. + * + * @author Joe Walnes + * @author Jörg Schaible + * @see Harness + */ +public interface Metric { + + /** + * Run the test and produce a metric. + * + * @param product Product to use in test. + * @param object A object to use against the product. + * @return The resulting metric (e.g. 12.22). + * @throws Exception If this metric could not be obtained. This will + * be reported back to the {@link Reporter}. + * @deprecated since 1.3 + */ + double run(Product product, Object object) throws Exception; + + /** + * Run the test and produce a metric. + * + * @param product Product to use in test. + * @param target A target to use against the product. + * @return The resulting metric (e.g. 12.22). + * @throws Exception If this metric could not be obtained. This will + * be reported back to the {@link Reporter}. + * @since 1.3 + */ + double run(Product product, Target target) throws Exception; + + /** + * The unit the metric is recorded in (for reporting purposes). + * e.g. "ms" or "bytes". + */ + String unit(); + + /** + * Whether a big result is better for this metric. + */ + boolean biggerIsBetter(); + +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/Product.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/Product.java new file mode 100644 index 0000000..308ec39 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/Product.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark; + +import java.io.OutputStream; +import java.io.InputStream; + +/** + * Provides an abstraction above the product used to perform the serialization/deserialization + * in the benchmarks. + * + * @author Joe Walnes + * @see Harness + */ +public interface Product { + + /** + * Serialize an object to a stream. + */ + void serialize(Object object, OutputStream output) throws Exception; + + /** + * Deserialize an object from a stream. + */ + Object deserialize(InputStream input) throws Exception; + +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/Reporter.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/Reporter.java new file mode 100644 index 0000000..67775e3 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/Reporter.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark; + +/** + * A listener to what the {@link Harness} is doing that should report the results. + * + * The sequence of methods is: + *
+ * startBenchmark,
+ * (
+ *   startMetric,
+ *   (
+ *     startTarget,
+ *     ( metricRecorded | metricFailed ),
+ *     endTarget
+ *   ) * ,
+ *   endMetric
+ * ) * ,
+ * endBenchmark
+ * 
+ * + * @author Joe Walnes + * @see Harness + */ +public interface Reporter { + + /** + * Benchmark has started. This will always be called ONCE (and only once) BEFORE everything else. + */ + void startBenchmark(); + + void startMetric(Metric metric); + + void startTarget(Target target); + + void metricRecorded(Product product, double result); + + void metricFailed(Product product, Exception e); + + void endTarget(Target target); + + void endMetric(Metric metric); + + /** + * Benchmark has ended. This will always be called ONCE (and only once) AFTER everything else. + */ + void endBenchmark(); + +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/Target.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/Target.java new file mode 100644 index 0000000..1010f51 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/Target.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark; + +/** + * Provides a target object to use in the metric. This could be a very small object or a large + * complicated graph. + * + * Also used to test if the object is equal to another instance (as some object's don't provide + * sensible equals() methods. + * + * @author Joe Walnes + * @see Harness + */ +public interface Target { + + /** + * The target to use in the metric. + */ + Object target(); + + /** + * Check whether the object for this target is equal to another one. + */ + boolean isEqual(Object other); + +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/metrics/CharacterCountMetric.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/metrics/CharacterCountMetric.java new file mode 100644 index 0000000..297d654 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/metrics/CharacterCountMetric.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2007, 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 14. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.metrics; + +import com.thoughtworks.xstream.tools.benchmark.Metric; +import com.thoughtworks.xstream.tools.benchmark.Product; +import com.thoughtworks.xstream.tools.benchmark.Target; + +import java.io.ByteArrayOutputStream; + +/** + * Determines the amount of a special characters. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class CharacterCountMetric implements Metric { + + private final char ch; + + public CharacterCountMetric(char ch) { + this.ch = ch; + } + + public double run(Product product, Target target) throws Exception { + return run(product, target.target()); + } + + /** + *@deprecated since 1.3 + */ + public double run(Product product, Object object) throws Exception { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + product.serialize(object, buffer); + String s = buffer.toString(); + int counter = 0; + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == ch) { + ++counter; + } + } + return counter; + } + + public String toString() { + return "Character count for '" + ch + "'"; + } + + public String unit() { + return "characters"; + } + + public boolean biggerIsBetter() { + return false; + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/metrics/DeserializationSpeedMetric.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/metrics/DeserializationSpeedMetric.java new file mode 100644 index 0000000..9817575 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/metrics/DeserializationSpeedMetric.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark.metrics; + +import com.thoughtworks.xstream.tools.benchmark.Metric; +import com.thoughtworks.xstream.tools.benchmark.Product; +import com.thoughtworks.xstream.tools.benchmark.Target; + +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; + +/** + * Determines how long it takes to deserialize an object (in ms). + * + * @author Joe Walnes + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Metric + */ +public class DeserializationSpeedMetric implements Metric { + + private final int iterations; + private final boolean validate; + + /** + * Measure deserialization speed. + * + * @param iterations + * @deprecated since 1.3, use {@link #DeserializationSpeedMetric(int, boolean)} + */ + public DeserializationSpeedMetric(int iterations) { + this(iterations, false); + } + + /** + * Measure deserialization speed. + * @param iterations + * @param validate flag to compare result of last iteration with original data + * @since 1.3 + */ + public DeserializationSpeedMetric(int iterations, boolean validate) { + this.iterations = iterations; + this.validate = validate; + } + + public double run(Product product, Target target) throws Exception { + + // Serialize once (because we need something to deserialize). + ByteArrayOutputStream output = new ByteArrayOutputStream(); + product.serialize(target.target(), output); + byte[] data = output.toByteArray(); + + // Deserialize once, to warm up. + product.deserialize(new ByteArrayInputStream(data)); + + // Now lots of times + Object lastResult = null; + long start = System.currentTimeMillis(); + for (int i = 0; i < iterations; i++) { + lastResult = product.deserialize(new ByteArrayInputStream(data)); + } + long end = System.currentTimeMillis(); + if (validate && iterations > 0) { + if (!target.isEqual(lastResult)) { + throw new RuntimeException("Deserialized object is not equal"); + } + } + + return (end - start); + } + + /** + *@deprecated since 1.3 + */ + public double run(Product product, Object object) throws Exception { + + // Serialize once (because we need something to deserialize). + ByteArrayOutputStream output = new ByteArrayOutputStream(); + product.serialize(object, output); + byte[] data = output.toByteArray(); + + // Deserialize once, to warm up. + product.deserialize(new ByteArrayInputStream(data)); + + // Now lots of times + long start = System.currentTimeMillis(); + for (int i = 0; i < iterations; i++) { + product.deserialize(new ByteArrayInputStream(data)); + } + long end = System.currentTimeMillis(); + + return (end - start); + } + + public String unit() { + return "ms"; + } + + public boolean biggerIsBetter() { + return false; + } + + public String toString() { + return "Deserialization speed (" + iterations + " iteration" + (iterations == 1 ? "" : "s") + ")"; + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/metrics/SerializationSpeedMetric.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/metrics/SerializationSpeedMetric.java new file mode 100644 index 0000000..699e611 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/metrics/SerializationSpeedMetric.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark.metrics; + +import com.thoughtworks.xstream.tools.benchmark.Metric; +import com.thoughtworks.xstream.tools.benchmark.Product; +import com.thoughtworks.xstream.tools.benchmark.Target; + +import java.io.ByteArrayOutputStream; + +/** + * Determines how long it takes to serialize an object (in ms). + * + * @author Joe Walnes + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Metric + */ +public class SerializationSpeedMetric implements Metric { + + private int iterations; + + public SerializationSpeedMetric(int iterations) { + this.iterations = iterations; + } + + public double run(Product product, Target target) throws Exception { + return run(product, target.target()); + } + + /** + *@deprecated since 1.3 + */ + public double run(Product product, Object object) throws Exception { + // Do it once to warm up. + product.serialize(object, new ByteArrayOutputStream()); + + // Now lots of times + long start = System.currentTimeMillis(); + for (int i = 0; i < iterations; i++) { + product.serialize(object, new ByteArrayOutputStream()); + } + long end = System.currentTimeMillis(); + + return (end - start); + } + + public String unit() { + return "ms"; + } + + public boolean biggerIsBetter() { + return false; + } + + public String toString() { + return "Serialization speed (" + iterations + " iteration" + (iterations == 1 ? "" : "s") + ")"; + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/metrics/SizeMetric.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/metrics/SizeMetric.java new file mode 100644 index 0000000..a31c9e9 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/metrics/SizeMetric.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark.metrics; + +import com.thoughtworks.xstream.tools.benchmark.Metric; +import com.thoughtworks.xstream.tools.benchmark.Product; +import com.thoughtworks.xstream.tools.benchmark.Target; + +import java.io.ByteArrayOutputStream; + +/** + * Determines the size of the serialized form of an object (in bytes). + * + * @author Joe Walnes + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Metric + */ +public class SizeMetric implements Metric { + + public double run(Product product, Target target) throws Exception { + return run(product, target.target()); + } + + /** + *@deprecated since 1.3 + */ + public double run(Product product, Object object) throws Exception { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + product.serialize(object, buffer); + return buffer.size(); + } + + public String toString() { + return "Size of serialized data"; + } + + public String unit() { + return "bytes"; + } + + public boolean biggerIsBetter() { + return false; + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/A100Fields.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/A100Fields.java new file mode 100644 index 0000000..770ebfe --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/A100Fields.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 25. June 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.model; + +/** + * Class with 100 fields. + * + * @since 1.4 + */ +public class A100Fields { + + String field000; + String field001; + String field002; + String field003; + String field004; + String field005; + String field006; + String field007; + String field008; + String field009; + String field010; + String field011; + String field012; + String field013; + String field014; + String field015; + String field016; + String field017; + String field018; + String field019; + String field020; + String field021; + String field022; + String field023; + String field024; + String field025; + String field026; + String field027; + String field028; + String field029; + String field030; + String field031; + String field032; + String field033; + String field034; + String field035; + String field036; + String field037; + String field038; + String field039; + String field040; + String field041; + String field042; + String field043; + String field044; + String field045; + String field046; + String field047; + String field048; + String field049; + String field050; + String field051; + String field052; + String field053; + String field054; + String field055; + String field056; + String field057; + String field058; + String field059; + String field060; + String field061; + String field062; + String field063; + String field064; + String field065; + String field066; + String field067; + String field068; + String field069; + String field070; + String field071; + String field072; + String field073; + String field074; + String field075; + String field076; + String field077; + String field078; + String field079; + String field080; + String field081; + String field082; + String field083; + String field084; + String field085; + String field086; + String field087; + String field088; + String field089; + String field090; + String field091; + String field092; + String field093; + String field094; + String field095; + String field096; + String field097; + String field098; + String field099; +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/A100Parents.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/A100Parents.java new file mode 100644 index 0000000..a6439ac --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/A100Parents.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 25. June 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.model; + +/** + * Class with 100 parents. + * + * @since 1.4 + */ +public class A100Parents { + + public static class Parent000 { String field000; } + public static class Parent001 extends Parent000 { String field001; } + public static class Parent002 extends Parent001 { String field002; } + public static class Parent003 extends Parent002 { String field003; } + public static class Parent004 extends Parent003 { String field004; } + public static class Parent005 extends Parent004 { String field005; } + public static class Parent006 extends Parent005 { String field006; } + public static class Parent007 extends Parent006 { String field007; } + public static class Parent008 extends Parent007 { String field008; } + public static class Parent009 extends Parent008 { String field009; } + public static class Parent010 extends Parent009 { String field010; } + public static class Parent011 extends Parent010 { String field011; } + public static class Parent012 extends Parent011 { String field012; } + public static class Parent013 extends Parent012 { String field013; } + public static class Parent014 extends Parent013 { String field014; } + public static class Parent015 extends Parent014 { String field015; } + public static class Parent016 extends Parent015 { String field016; } + public static class Parent017 extends Parent016 { String field017; } + public static class Parent018 extends Parent017 { String field018; } + public static class Parent019 extends Parent018 { String field019; } + public static class Parent020 extends Parent019 { String field020; } + public static class Parent021 extends Parent020 { String field021; } + public static class Parent022 extends Parent021 { String field022; } + public static class Parent023 extends Parent022 { String field023; } + public static class Parent024 extends Parent023 { String field024; } + public static class Parent025 extends Parent024 { String field025; } + public static class Parent026 extends Parent025 { String field026; } + public static class Parent027 extends Parent026 { String field027; } + public static class Parent028 extends Parent027 { String field028; } + public static class Parent029 extends Parent028 { String field029; } + public static class Parent030 extends Parent029 { String field030; } + public static class Parent031 extends Parent030 { String field031; } + public static class Parent032 extends Parent031 { String field032; } + public static class Parent033 extends Parent032 { String field033; } + public static class Parent034 extends Parent033 { String field034; } + public static class Parent035 extends Parent034 { String field035; } + public static class Parent036 extends Parent035 { String field036; } + public static class Parent037 extends Parent036 { String field037; } + public static class Parent038 extends Parent037 { String field038; } + public static class Parent039 extends Parent038 { String field039; } + public static class Parent040 extends Parent039 { String field040; } + public static class Parent041 extends Parent040 { String field041; } + public static class Parent042 extends Parent041 { String field042; } + public static class Parent043 extends Parent042 { String field043; } + public static class Parent044 extends Parent043 { String field044; } + public static class Parent045 extends Parent044 { String field045; } + public static class Parent046 extends Parent045 { String field046; } + public static class Parent047 extends Parent046 { String field047; } + public static class Parent048 extends Parent047 { String field048; } + public static class Parent049 extends Parent048 { String field049; } + public static class Parent050 extends Parent049 { String field050; } + public static class Parent051 extends Parent050 { String field051; } + public static class Parent052 extends Parent051 { String field052; } + public static class Parent053 extends Parent052 { String field053; } + public static class Parent054 extends Parent053 { String field054; } + public static class Parent055 extends Parent054 { String field055; } + public static class Parent056 extends Parent055 { String field056; } + public static class Parent057 extends Parent056 { String field057; } + public static class Parent058 extends Parent057 { String field058; } + public static class Parent059 extends Parent058 { String field059; } + public static class Parent060 extends Parent059 { String field060; } + public static class Parent061 extends Parent060 { String field061; } + public static class Parent062 extends Parent061 { String field062; } + public static class Parent063 extends Parent062 { String field063; } + public static class Parent064 extends Parent063 { String field064; } + public static class Parent065 extends Parent064 { String field065; } + public static class Parent066 extends Parent065 { String field066; } + public static class Parent067 extends Parent066 { String field067; } + public static class Parent068 extends Parent067 { String field068; } + public static class Parent069 extends Parent068 { String field069; } + public static class Parent070 extends Parent069 { String field070; } + public static class Parent071 extends Parent070 { String field071; } + public static class Parent072 extends Parent071 { String field072; } + public static class Parent073 extends Parent072 { String field073; } + public static class Parent074 extends Parent073 { String field074; } + public static class Parent075 extends Parent074 { String field075; } + public static class Parent076 extends Parent075 { String field076; } + public static class Parent077 extends Parent076 { String field077; } + public static class Parent078 extends Parent077 { String field078; } + public static class Parent079 extends Parent078 { String field079; } + public static class Parent080 extends Parent079 { String field080; } + public static class Parent081 extends Parent080 { String field081; } + public static class Parent082 extends Parent081 { String field082; } + public static class Parent083 extends Parent082 { String field083; } + public static class Parent084 extends Parent083 { String field084; } + public static class Parent085 extends Parent084 { String field085; } + public static class Parent086 extends Parent085 { String field086; } + public static class Parent087 extends Parent086 { String field087; } + public static class Parent088 extends Parent087 { String field088; } + public static class Parent089 extends Parent088 { String field089; } + public static class Parent090 extends Parent089 { String field090; } + public static class Parent091 extends Parent090 { String field091; } + public static class Parent092 extends Parent091 { String field092; } + public static class Parent093 extends Parent092 { String field093; } + public static class Parent094 extends Parent093 { String field094; } + public static class Parent095 extends Parent094 { String field095; } + public static class Parent096 extends Parent095 { String field096; } + public static class Parent097 extends Parent096 { String field097; } + public static class Parent098 extends Parent097 { String field098; } + public static class Parent099 extends Parent098 { String field099; } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/A50InnerClasses.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/A50InnerClasses.java new file mode 100644 index 0000000..749e3ae --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/A50InnerClasses.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.model; + +/** + * Class with inner classes 50 levels deep. + * + * @since 1.4 + */ +public class A50InnerClasses { + + public class L00 { String field000; + public class L01 { String field001; + public class L02 { String field002; + public class L03 { String field003; + public class L04 { String field004; + public class L05 { String field005; + public class L06 { String field006; + public class L07 { String field007; + public class L08 { String field008; + public class L09 { String field009; + public class L10 { String field010; + public class L11 { String field011; + public class L12 { String field012; + public class L13 { String field013; + public class L14 { String field014; + public class L15 { String field015; + public class L16 { String field016; + public class L17 { String field017; + public class L18 { String field018; + public class L19 { String field019; + public class L20 { String field020; + public class L21 { String field021; + public class L22 { String field022; + public class L23 { String field023; + public class L24 { String field024; + public class L25 { String field025; + public class L26 { String field026; + public class L27 { String field027; + public class L28 { String field028; + public class L29 { String field029; + public class L30 { String field030; + public class L31 { String field031; + public class L32 { String field032; + public class L33 { String field033; + public class L34 { String field034; + public class L35 { String field035; + public class L36 { String field036; + public class L37 { String field037; + public class L38 { String field038; + public class L39 { String field039; + public class L40 { String field040; + public class L41 { String field041; + public class L42 { String field042; + public class L43 { String field043; + public class L44 { String field044; + public class L45 { String field045; + public class L46 { String field046; + public class L47 { String field047; + public class L48 { String field048; + public class L49 { String field049; + }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/A50StaticInnerClasses.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/A50StaticInnerClasses.java new file mode 100644 index 0000000..ae296ce --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/A50StaticInnerClasses.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2007, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. August 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.model; + +/** + * Class with static inner classes 50 levels deep. + * + * @since 1.4 + */ +public class A50StaticInnerClasses { + + public static class L00 { String field000; + public static class L01 { String field001; + public static class L02 { String field002; + public static class L03 { String field003; + public static class L04 { String field004; + public static class L05 { String field005; + public static class L06 { String field006; + public static class L07 { String field007; + public static class L08 { String field008; + public static class L09 { String field009; + public static class L10 { String field010; + public static class L11 { String field011; + public static class L12 { String field012; + public static class L13 { String field013; + public static class L14 { String field014; + public static class L15 { String field015; + public static class L16 { String field016; + public static class L17 { String field017; + public static class L18 { String field018; + public static class L19 { String field019; + public static class L20 { String field020; + public static class L21 { String field021; + public static class L22 { String field022; + public static class L23 { String field023; + public static class L24 { String field024; + public static class L25 { String field025; + public static class L26 { String field026; + public static class L27 { String field027; + public static class L28 { String field028; + public static class L29 { String field029; + public static class L30 { String field030; + public static class L31 { String field031; + public static class L32 { String field032; + public static class L33 { String field033; + public static class L34 { String field034; + public static class L35 { String field035; + public static class L36 { String field036; + public static class L37 { String field037; + public static class L38 { String field038; + public static class L39 { String field039; + public static class L40 { String field040; + public static class L41 { String field041; + public static class L42 { String field042; + public static class L43 { String field043; + public static class L44 { String field044; + public static class L45 { String field045; + public static class L46 { String field046; + public static class L47 { String field047; + public static class L48 { String field048; + public static class L49 { String field049; + }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/Five.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/Five.java new file mode 100644 index 0000000..8daa634 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/Five.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. January 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.model; + + +/** + * Class containing 5 basic types. + * + * @since 1.4 + */ +public class Five extends One { + + private int two; + private boolean three; + private char four; + private StringBuffer five; + + public Five(String one, int two, boolean three, char four, StringBuffer five) { + super(one); + this.two = two; + this.three = three; + this.four = four; + this.five = five; + } + + public boolean equals(Object obj) { + Five five = (Five)obj; + return super.equals(obj) && two == five.two && three == five.three && four == five.four && this.five.toString().equals(five.five.toString()); + } + + public int hashCode() { + return super.hashCode() + two + new Boolean(three).hashCode() + five.toString().hashCode(); + } +} \ No newline at end of file diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/FiveBean.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/FiveBean.java new file mode 100644 index 0000000..21216ab --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/FiveBean.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 05. May 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.model; + + +/** + * JavaBean class containing 5 basic types. + * + * @since 1.4 + */ +public class FiveBean extends OneBean { + + private int two; + private boolean three; + private char four; + private StringBuffer five; + + public int getTwo() { + return this.two; + } + + public void setTwo(int two) { + this.two = two; + } + + public boolean isThree() { + return this.three; + } + + public void setThree(boolean three) { + this.three = three; + } + + public char getFour() { + return this.four; + } + + public void setFour(char four) { + this.four = four; + } + + public StringBuffer getFive() { + return this.five; + } + + public void setFive(StringBuffer five) { + this.five = five; + } + + public boolean equals(Object obj) { + FiveBean five = (FiveBean)obj; + return super.equals(obj) && two == five.two && three == five.three && four == five.four && this.five.toString().equals(five.five.toString()); + } + + public int hashCode() { + return super.hashCode() + two + new Boolean(three).hashCode() + five.toString().hashCode(); + } +} \ No newline at end of file diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/One.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/One.java new file mode 100644 index 0000000..8b40d05 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/One.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. January 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.model; + + +/** + * Class containing one basic type. + * + * @since 1.4 + */ +public class One { + + private String one; + + public One(String one) { + this.one = one; + } + + public boolean equals(Object obj) { + return one.equals(((One)obj).one); + } + + public int hashCode() { + return one.hashCode() >>> 1; + } +} \ No newline at end of file diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/OneBean.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/OneBean.java new file mode 100644 index 0000000..c9ae520 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/OneBean.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 05. May 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.model; + + +/** + * JavaBean class containing one basic type. + * + * @since 1.4 + */ +public class OneBean { + + private String one; + + public String getOne() { + return this.one; + } + + public void setOne(String one) { + this.one = one; + } + + public boolean equals(Object obj) { + return one.equals(((OneBean)obj).one); + } + + public int hashCode() { + return one.hashCode() >>> 1; + } +} \ No newline at end of file diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/SerializableFive.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/SerializableFive.java new file mode 100644 index 0000000..f1d4c2f --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/SerializableFive.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. January 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.model; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +/** + * Serializable class containing 5 basic types. + * + * @since 1.4 + */ +public class SerializableFive extends SerializableOne { + + private static final long serialVersionUID = 1L; + private int two; + private boolean three; + private char four; + private StringBuffer five; + + public SerializableFive(String one, int two, boolean three, char four, StringBuffer five) { + super(one); + this.two = two; + this.three = three; + this.four = four; + this.five = five; + } + + private void writeObject(final ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + } + + private void readObject(final ObjectInputStream in) + throws IOException, ClassNotFoundException { + in.defaultReadObject(); + } + + public boolean equals(Object obj) { + SerializableFive five = (SerializableFive)obj; + return super.equals(obj) && two == five.two && three == five.three && four == five.four && this.five.toString().equals(five.five.toString()); + } + + public int hashCode() { + return super.hashCode() + two + new Boolean(three).hashCode() + five.toString().hashCode(); + } +} \ No newline at end of file diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/SerializableOne.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/SerializableOne.java new file mode 100644 index 0000000..104c301 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/model/SerializableOne.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. January 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.model; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +/** + * Serializable class containing one basic types. + * + * @since 1.4 + */ +public class SerializableOne implements Serializable { + + private static final long serialVersionUID = 1L; + + private String one; + + public SerializableOne(String one) { + this.one = one; + } + + private void writeObject(final ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + } + + private void readObject(final ObjectInputStream in) + throws IOException, ClassNotFoundException { + in.defaultReadObject(); + } + + public boolean equals(Object obj) { + return one.equals(((SerializableOne)obj).one); + } + + public int hashCode() { + return one.hashCode() >>> 1; + } +} \ No newline at end of file diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/package.html b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/package.html new file mode 100644 index 0000000..36e306b --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/package.html @@ -0,0 +1,14 @@ + + +A simple harness for running benchmarks. See Harness + diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/JavaObjectSerialization.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/JavaObjectSerialization.java new file mode 100644 index 0000000..6263761 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/JavaObjectSerialization.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark.products; + +import com.thoughtworks.xstream.tools.benchmark.Product; + +import java.io.OutputStream; +import java.io.InputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectInputStream; + +/** + * Standard Java Object Serialization product. + * + * @author Joe Walnes + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Product + * @see ObjectOutputStream + * @see ObjectInputStream + */ +public class JavaObjectSerialization implements Product { + + public void serialize(Object object, OutputStream output) throws Exception { + ObjectOutputStream objectOutputStream = new ObjectOutputStream(output); + objectOutputStream.writeObject(object); + } + + public Object deserialize(InputStream input) throws Exception { + ObjectInputStream objectInputStream = new ObjectInputStream(input); + return objectInputStream.readObject(); + } + + public String toString() { + return "Java object serialization"; + } + +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamBEAStax.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamBEAStax.java new file mode 100644 index 0000000..373372e --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamBEAStax.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. April 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.products; + +import com.thoughtworks.xstream.io.xml.BEAStaxDriver; + +/** + * Uses XStream with the BEA StAX driver for parsing XML. + * + * @author Joe Walnes + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see com.thoughtworks.xstream.tools.benchmark.Product + * @see com.thoughtworks.xstream.XStream + * @see BEAStaxDriver + */ +public class XStreamBEAStax extends XStreamDriver { + + public XStreamBEAStax() { + super(new BEAStaxDriver(), "XML with BEA StAX parser"); + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamBinary.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamBinary.java new file mode 100644 index 0000000..e66f848 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamBinary.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark.products; + +import com.thoughtworks.xstream.tools.benchmark.Product; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.binary.BinaryStreamWriter; +import com.thoughtworks.xstream.io.binary.BinaryStreamReader; + +import java.io.OutputStream; +import java.io.InputStream; + +/** + * Uses XStream with binary format instead of XML. + * + * @author Joe Walnes + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Product + * @see XStream + * @see BinaryStreamReader + * @see BinaryStreamWriter + */ +public class XStreamBinary implements Product { + + private final XStream xstream; + + public XStreamBinary() { + this.xstream = new XStream(); + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.marshal(object, new BinaryStreamWriter(output)); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.unmarshal(new BinaryStreamReader(input)); + } + + public String toString() { + return "XStream (binary format)"; + } + +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamCompact.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamCompact.java new file mode 100644 index 0000000..7a99d0a --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamCompact.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark.products; + +import com.thoughtworks.xstream.tools.benchmark.Product; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.io.xml.CompactWriter; + +import java.io.OutputStream; +import java.io.InputStream; +import java.io.OutputStreamWriter; + +/** + * Uses XStream with a compact XML output format. + * + * @author Joe Walnes + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Product + * @see XStream + * @see CompactWriter + */ +public class XStreamCompact implements Product { + + private final XStream xstream; + + public XStreamCompact() { + this.xstream = new XStream(new XppDriver()); + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.marshal(object, new CompactWriter(new OutputStreamWriter(output))); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.fromXML(input); + } + + public String toString() { + return "XStream (Compact XML)"; + } + +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamDom.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamDom.java new file mode 100644 index 0000000..d953e46 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamDom.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark.products; + +import com.thoughtworks.xstream.io.xml.DomDriver; + +/** + * Uses XStream with the DOM driver for parsing XML. + * + * @author Joe Walnes + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see com.thoughtworks.xstream.tools.benchmark.Product + * @see com.thoughtworks.xstream.XStream + * @see DomDriver + */ +public class XStreamDom extends XStreamDriver { + + public XStreamDom() { + super(new DomDriver(), "XML with DOM parser"); + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamDom4J.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamDom4J.java new file mode 100644 index 0000000..d1b360c --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamDom4J.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. April 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.products; + +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.xml.Dom4JDriver; +import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; + +import java.io.Writer; + +/** + * Uses XStream with the DOM4J driver for parsing XML. + * + * @author Joe Walnes + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see com.thoughtworks.xstream.tools.benchmark.Product + * @see com.thoughtworks.xstream.XStream + * @see Dom4JDriver + */ +public class XStreamDom4J extends XStreamDriver { + + public XStreamDom4J() { + super(new Dom4JDriver() { + + public HierarchicalStreamWriter createWriter(Writer out) { + return new PrettyPrintWriter(out); + } + + }, "XML with DOM4J parser"); + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamDriver.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamDriver.java new file mode 100644 index 0000000..43b500d --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamDriver.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 19.02.2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.products; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.javabean.JavaBeanConverter; +import com.thoughtworks.xstream.io.HierarchicalStreamDriver; +import com.thoughtworks.xstream.tools.benchmark.Product; +import com.thoughtworks.xstream.tools.benchmark.model.FiveBean; +import com.thoughtworks.xstream.tools.benchmark.model.OneBean; + +import java.io.InputStream; +import java.io.OutputStream; + + +/** + * Generic XStream product based on an arbitrary driver. + * + * @see XStream + * @see Product + * @see HierarchicalStreamDriver + * @author Joe Walnes + * @author Jörg Schaible + * @since 1.4 + */ +public class XStreamDriver implements Product { + + private final XStream xstream; + private final String desc; + + /** + * Create a XStream product based on a driver. + * + * @param driver the driver to use for serialization/deserialization + * @param desc the driver description + * + * @since 1.4 + */ + public XStreamDriver(HierarchicalStreamDriver driver, String desc) { + this.xstream = new XStream(driver); + this.xstream.registerConverter(new JavaBeanConverter(this.xstream.getMapper()) { + + public boolean canConvert(Class type) { + return type == OneBean.class || type == FiveBean.class; + } + + }); + this.desc = desc; + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.toXML(object, output); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.fromXML(input); + } + + public String toString() { + return "XStream (" + desc + ")"; + } + +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamJDom.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamJDom.java new file mode 100644 index 0000000..b374d05 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamJDom.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. April 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.products; + +import com.thoughtworks.xstream.io.xml.JDomDriver; + +/** + * Uses XStream with the JDOM driver for parsing XML. + * + * @author Joe Walnes + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see com.thoughtworks.xstream.tools.benchmark.Product + * @see com.thoughtworks.xstream.XStream + * @see JDomDriver + */ +public class XStreamJDom extends XStreamDriver { + + public XStreamJDom() { + super(new JDomDriver(), "XML with JDOM parser"); + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamKXml2.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamKXml2.java new file mode 100644 index 0000000..5b688cb --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamKXml2.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. April 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.products; + +import com.thoughtworks.xstream.io.xml.KXml2Driver; + +/** + * Uses XStream with the kXML2 driver for parsing XML. + * + * @author Joe Walnes + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see com.thoughtworks.xstream.tools.benchmark.Product + * @see com.thoughtworks.xstream.XStream + * @see KXml2Driver + */ +public class XStreamKXml2 extends XStreamDriver { + + public XStreamKXml2() { + super(new KXml2Driver(), "XML with kXML2 parser"); + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamKXml2DOM.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamKXml2DOM.java new file mode 100644 index 0000000..2b102f8 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamKXml2DOM.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 05. May 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.products; + +import com.thoughtworks.xstream.io.xml.KXml2DomDriver; + +/** + * Uses XStream with the Xpp3 DOM driver for parsing XML. + * + * @author Joe Walnes + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see com.thoughtworks.xstream.tools.benchmark.Product + * @see com.thoughtworks.xstream.XStream + * @see KXml2DomDriver + */ +public class XStreamKXml2DOM extends XStreamDriver { + + public XStreamKXml2DOM() { + super(new KXml2DomDriver(), "XML with kXML2 DOM parser"); + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamSjsxp.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamSjsxp.java new file mode 100644 index 0000000..05676f1 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamSjsxp.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. April 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.products; + +import com.thoughtworks.xstream.io.xml.SjsxpDriver; + +/** + * Uses XStream with the SJSXP StAX driver for parsing XML. + * + * @author Joe Walnes + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see com.thoughtworks.xstream.tools.benchmark.Product + * @see com.thoughtworks.xstream.XStream + * @see SjsxpDriver + */ +public class XStreamSjsxp extends XStreamDriver { + + public XStreamSjsxp() { + super(new SjsxpDriver(), "XML with SJSXP StAX parser"); + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamStax.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamStax.java new file mode 100644 index 0000000..8077f67 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamStax.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark.products; + +import com.thoughtworks.xstream.io.xml.StaxDriver; + +/** + * Uses XStream with the default StAX driver for parsing XML. + * + * @author Joe Walnes + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see com.thoughtworks.xstream.tools.benchmark.Product + * @see com.thoughtworks.xstream.XStream + * @see StaxDriver + */ +public class XStreamStax extends XStreamDriver { + + public XStreamStax() { + super(new StaxDriver(), "XML with default StAX parser"); + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamWoodstox.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamWoodstox.java new file mode 100644 index 0000000..a46df2d --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamWoodstox.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. April 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.products; + +import com.thoughtworks.xstream.io.xml.WstxDriver; + +/** + * Uses XStream with the Woodstox StAX driver for parsing XML. + * + * @author Joe Walnes + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see com.thoughtworks.xstream.tools.benchmark.Product + * @see com.thoughtworks.xstream.XStream + * @see WstxDriver + */ +public class XStreamWoodstox extends XStreamDriver { + + public XStreamWoodstox() { + super(new WstxDriver(), "XML with Woodstox StAX parser"); + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamXom.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamXom.java new file mode 100644 index 0000000..6309ad1 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamXom.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. April 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.products; + +import com.thoughtworks.xstream.io.xml.XomDriver; + +/** + * Uses XStream with the XOM driver for parsing XML. + * + * @author Joe Walnes + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see com.thoughtworks.xstream.tools.benchmark.Product + * @see com.thoughtworks.xstream.XStream + * @see XomDriver + */ +public class XStreamXom extends XStreamDriver { + + public XStreamXom() { + super(new XomDriver(), "XML with XOM parser"); + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamXpp.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamXpp.java new file mode 100644 index 0000000..4ae26e2 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamXpp.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark.products; + +import com.thoughtworks.xstream.io.xml.XppDriver; + + +/** + * Uses XStream with the default XPP driver for parsing XML. + * + * @author Joe Walnes + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see com.thoughtworks.xstream.tools.benchmark.Product + * @see com.thoughtworks.xstream.XStream + * @see XppDriver + */ +public class XStreamXpp extends XStreamDriver { + + public XStreamXpp() { + super(new XppDriver(), "XML with default XPP parser"); + } + +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamXpp3.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamXpp3.java new file mode 100644 index 0000000..567968b --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamXpp3.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 30. April 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.products; + +import com.thoughtworks.xstream.io.xml.Xpp3Driver; + +/** + * Uses XStream with the Xpp3 driver for parsing XML. + * + * @author Joe Walnes + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see com.thoughtworks.xstream.tools.benchmark.Product + * @see com.thoughtworks.xstream.XStream + * @see Xpp3Driver + */ +public class XStreamXpp3 extends XStreamDriver { + + public XStreamXpp3() { + super(new Xpp3Driver(), "XML with Xpp3 parser"); + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamXpp3DOM.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamXpp3DOM.java new file mode 100644 index 0000000..646f1fd --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/products/XStreamXpp3DOM.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 05. May 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.products; + +import com.thoughtworks.xstream.io.xml.Xpp3DomDriver; + +/** + * Uses XStream with the kXML2 DOM driver for parsing XML. + * + * @author Joe Walnes + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see com.thoughtworks.xstream.tools.benchmark.Product + * @see com.thoughtworks.xstream.XStream + * @see Xpp3DomDriver + */ +public class XStreamXpp3DOM extends XStreamDriver { + + public XStreamXpp3DOM() { + super(new Xpp3DomDriver(), "XML with Xpp3 DOM parser"); + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/reporters/HtmlReporter.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/reporters/HtmlReporter.java new file mode 100644 index 0000000..437c4fa --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/reporters/HtmlReporter.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 22. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark.reporters; + +import com.thoughtworks.xstream.tools.benchmark.Reporter; +import com.thoughtworks.xstream.tools.benchmark.Metric; +import com.thoughtworks.xstream.tools.benchmark.Target; +import com.thoughtworks.xstream.tools.benchmark.Product; +import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Date; + +public class HtmlReporter implements Reporter { + + private final PrettyPrintWriter out; + private final String title; + + private Metric currentMetric; + private double largestMetricForTarget; + private List resultsForTarget; + + public HtmlReporter(File htmlFile, String title) throws IOException { + this.title = title; + out = new PrettyPrintWriter(new FileWriter(htmlFile)); + } + + public void startBenchmark() { + out.startNode("html"); + + out.startNode("head"); + writeTag("title", title); + writeTag("style", css(), "type", "text/css"); + out.endNode(); + + out.startNode("body"); + + writeTag("h1", title); + } + + private String css() { + StringBuffer css = new StringBuffer("\n"); + css.append("body, h1, h2, h3, td { font-family: arial; }\n"); + css.append("h1 { text-align: center; }\n"); + css.append("table, h3 { margin-left: 40px; }\n"); + css.append("table, td, th { border: 1px solid #999; border-collapse: collapse; font-size: smaller; }\n"); + css.append(".success { color: #090; }\n"); + css.append(".fail { color: #900; }\n"); + return css.toString(); + } + + public void startMetric(Metric metric) { + writeTag("h2", metric.toString()); + currentMetric = metric; + } + + public void startTarget(Target target) { + writeTag("h3", target.toString()); + out.flush(); // Flush now, so progress can be seen with slow benchmarks. + largestMetricForTarget = 0; + resultsForTarget = new ArrayList(); + } + + public void metricRecorded(Product product, double result) { + // Keep a look out for the largest result. + if (result > largestMetricForTarget) { + largestMetricForTarget = result; + } + resultsForTarget.add(new MetricResult(product, result)); + } + + public void metricFailed(Product product, Exception e) { + resultsForTarget.add(new MetricResult(product, e)); + } + + public void endTarget(Target target) { + out.startNode("table"); + out.startNode("tr"); + + writeTag("th", "Product"); + writeTag("th", currentMetric.unit()); + + out.endNode(); + for (Iterator iterator = resultsForTarget.iterator(); iterator.hasNext();) { + MetricResult metricResult = (MetricResult) iterator.next(); + out.startNode("tr"); + + writeTag("td", metricResult.product.toString()); + + if (metricResult.exception == null) { + writeTag("td", String.valueOf(metricResult.result), "class", "success"); + + long percentage = Math.round(Math.abs(metricResult.result / largestMetricForTarget) * 100.0); + out.startNode("td"); + out.addAttribute("style", "width: 400px;"); + writeTag("div", "", "style", "height: 100%; width: " + percentage + "%; background-color: blue;"); + out.endNode(); + } else { + writeTag("td", "FAIL", "class", "fail"); + writeTag("td", metricResult.exception.toString()); + } + + out.endNode(); + } + out.endNode(); + out.flush(); // Flush now, so progress can be seen with slow benchmarks. + } + + private void writeTag(String tag, String value) { + out.startNode(tag); + out.setValue(value); + out.endNode(); + } + + private void writeTag(String tag, String value, String attributeName, String attributeValue) { + out.startNode(tag); + out.addAttribute(attributeName, attributeValue); + out.setValue(value); + out.endNode(); + } + + public void endMetric(Metric metric) { + } + + public void endBenchmark() { + writeTag("p", new Date().toString()); + out.endNode(); + out.endNode(); + out.close(); + } + + private static class MetricResult { + private final Product product; + private final double result; + private final Exception exception; + + public MetricResult(Product product, double result) { + this.result = result; + this.product = product; + this.exception = null; + } + + public MetricResult(Product product, Exception exception) { + this.product = product; + this.result = 0; + this.exception = exception; + } + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/reporters/MultiReporter.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/reporters/MultiReporter.java new file mode 100644 index 0000000..270157f --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/reporters/MultiReporter.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2007, 2008 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 14. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.reporters; + +import com.thoughtworks.xstream.tools.benchmark.Metric; +import com.thoughtworks.xstream.tools.benchmark.Product; +import com.thoughtworks.xstream.tools.benchmark.Reporter; +import com.thoughtworks.xstream.tools.benchmark.Target; + +/** + * A reporter multiplexing the results to other Reporters. + * + * @author Jörg Schaible + * @since 1.3 + */ +public class MultiReporter implements Reporter { + + private final Reporter[] reporter; + + public MultiReporter(Reporter[] reporter) { + this.reporter = reporter; + } + + public void endBenchmark() { + for (int i = 0; i < reporter.length; i++) { + reporter[i].endBenchmark(); + } + } + + public void endMetric(Metric metric) { + for (int i = 0; i < reporter.length; i++) { + reporter[i].endMetric(metric); + } + } + + public void endTarget(Target target) { + for (int i = 0; i < reporter.length; i++) { + reporter[i].endTarget(target); + } + } + + public void metricFailed(Product product, Exception e) { + for (int i = 0; i < reporter.length; i++) { + reporter[i].metricFailed(product, e); + } + } + + public void metricRecorded(Product product, double result) { + for (int i = 0; i < reporter.length; i++) { + reporter[i].metricRecorded(product, result); + } + } + + public void startBenchmark() { + for (int i = 0; i < reporter.length; i++) { + reporter[i].startBenchmark(); + } + } + + public void startMetric(Metric metric) { + for (int i = 0; i < reporter.length; i++) { + reporter[i].startMetric(metric); + } + } + + public void startTarget(Target target) { + for (int i = 0; i < reporter.length; i++) { + reporter[i].startTarget(target); + } + } + +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/reporters/TextReporter.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/reporters/TextReporter.java new file mode 100644 index 0000000..cdb696a --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/reporters/TextReporter.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark.reporters; + +import com.thoughtworks.xstream.tools.benchmark.Metric; +import com.thoughtworks.xstream.tools.benchmark.Product; +import com.thoughtworks.xstream.tools.benchmark.Reporter; +import com.thoughtworks.xstream.tools.benchmark.Target; + +import java.io.PrintWriter; +import java.io.Writer; + +/** + * Reports results of Harness in text form designed for human reading. + * + * @author Joe Walnes + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Reporter + */ +public class TextReporter implements Reporter { + + private final PrintWriter out; + private Metric currentMetric; + + public TextReporter(PrintWriter out) { + this.out = out; + } + + public TextReporter(Writer out) { + this(new PrintWriter(out)); + } + + /** + * Reports to System.out. + */ + public TextReporter() { + this(new PrintWriter(System.out, true)); + } + + public void startBenchmark() { + } + + public void startMetric(Metric metric) { + currentMetric = metric; + out.println("======================================================================"); + out.println(metric); + out.println("======================================================================"); + } + + public void startTarget(Target target) { + out.println("* " + target + ""); + } + + public void metricRecorded(Product product, double result) { + out.println(" - " + pad(product.toString()) + " " + result + " " + currentMetric.unit()); + } + + public void metricFailed(Product product, Exception e) { + out.println(" - " + pad(product.toString()) + " FAILED (" + e + ")"); + } + + public void endTarget(Target target) { + } + + public void endMetric(Metric metric) { + out.println(); + currentMetric = null; + } + + public void endBenchmark() { + out.flush(); + } + + private String pad(String value) { + StringBuffer result = new StringBuffer(); + result.append(value); + while (result.length() < 50) { + result.append('.'); + } + return result.toString(); + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/BasicTarget.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/BasicTarget.java new file mode 100644 index 0000000..d7f4c90 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/BasicTarget.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. January 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.targets; + +import com.thoughtworks.xstream.tools.benchmark.Target; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +/** + * Target containing basic types. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class BasicTarget implements Target { + + private List list; + + public BasicTarget() { + list = new ArrayList(); + list.add(new Integer(1)); + list.add(new Byte((byte)2)); + list.add(new Short((short)3)); + list.add(new Long(4)); + list.add("Profile"); + list.add(Boolean.TRUE); + list.add(new Float(1.2f)); + list.add(new Double(1.2f)); + list.add(new File("profile.txt")); + list.add(Locale.ENGLISH); + } + + public boolean isEqual(Object other) { + return list.equals(other); + } + + public Object target() { + return list; + } + + public String toString() { + return "SingleValue Converters"; + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/ExtendedTarget.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/ExtendedTarget.java new file mode 100644 index 0000000..2c15837 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/ExtendedTarget.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. January 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.targets; + +import com.thoughtworks.xstream.tools.benchmark.Target; + +import java.awt.Color; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +/** + * Target containing extended types. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class ExtendedTarget implements Target { + + private final static Method EQUALS; + private final static Field LIST; + static { + Method method; + Field field; + try { + method = Object.class.getMethod("equals", new Class[]{Object.class}); + field = ExtendedTarget.class.getDeclaredField("list"); + } catch (NoSuchMethodException e) { + throw new ExceptionInInitializerError(e); + } catch (NoSuchFieldException e) { + throw new ExceptionInInitializerError(e); + } + EQUALS = method; + LIST = field; + } + + private List list; + + public ExtendedTarget() { + list = new ArrayList(); + list.add(new Color(128, 0, 255)); + Object proxy = Proxy + .newProxyInstance( + getClass().getClassLoader(), new Class[]{ + Runnable.class, Cloneable.class, Comparable.class}, + new RunnableInvocationHandler()); + list.add(proxy); + list.add(ExtendedTarget.class); + list.add(EQUALS); + list.add(LIST); + Properties properties = new Properties(); + properties.put("1", "one"); + properties.put("2", "two"); + properties.put("3", "three"); + list.add(properties); + } + + public boolean isEqual(Object other) { + return list.equals(other); + } + + public Object target() { + return list; + } + + public String toString() { + return "Standard Converters"; + } + + static class RunnableInvocationHandler implements InvocationHandler { + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + if (method.equals(EQUALS)) { + return new Boolean(args[0] instanceof Runnable); + } else if (method.getName().equals("hashCode")) { + return new Integer(System.identityHashCode(proxy)); + } else if (method.getName().equals("toString")) { + return "Proxy" + System.identityHashCode(proxy); + } else if (method.getName().equals("getClass")) { + return proxy.getClass(); + } + return null; + } + + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/JTreeTarget.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/JTreeTarget.java new file mode 100644 index 0000000..00ed6cf --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/JTreeTarget.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark.targets; + +import com.thoughtworks.xstream.tools.benchmark.Target; + +import javax.swing.*; + +/** + * A Swing JTree instance, which is a suitably complex object graph. + * + * @author Joe Walnes + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Target + * @see JTree + */ +public class JTreeTarget implements Target { + + private JTree jTree = new JTree(); + + public String toString() { + return "JTree"; + } + + public Object target() { + return jTree; + } + + public boolean isEqual(Object other) { + // TODO: Check if JTrees are equal. -Joe + return true; + } + +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/JavaBeanTarget.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/JavaBeanTarget.java new file mode 100644 index 0000000..dd7240c --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/JavaBeanTarget.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 05. May 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.targets; + +import com.thoughtworks.xstream.tools.benchmark.Target; +import com.thoughtworks.xstream.tools.benchmark.model.FiveBean; +import com.thoughtworks.xstream.tools.benchmark.model.OneBean; + +import java.util.ArrayList; +import java.util.List; + +/** + * Target containing basic types using the JavaBeanConverter. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class JavaBeanTarget implements Target { + + private List list; + + public JavaBeanTarget() { + list = new ArrayList(); + for (int i = 0; i < 5; ++i) { + OneBean one = new OneBean(); + one.setOne(Integer.toString(i)); + list.add(one); + } + FiveBean five = new FiveBean(); + five.setOne("1"); + five.setTwo(2); + five.setThree(true); + five.setFour('4'); + five.setFive(new StringBuffer("5")); + list.add(five); + } + + public boolean isEqual(Object other) { + return list.equals(other); + } + + public Object target() { + return list; + } + + public String toString() { + return "JavaBean Converter"; + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/ListTarget.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/ListTarget.java new file mode 100644 index 0000000..89a5e43 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/ListTarget.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark.targets; + +import com.thoughtworks.xstream.tools.benchmark.Target; + +import java.util.ArrayList; +import java.util.List; + +/** + * An ArrayList of user defined class ({@link Person}) instances to serialize. + * + * @author Joe Walnes + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Target + */ +public class ListTarget implements Target { + + private List list = new ArrayList(); + + public ListTarget(int size) { + for (int i = 0; i < size; i++) { + Person person = new Person(); + person.firstName = "First name " + i; + person.lastName = "Last name " + i; + list.add(person); + } + } + + public String toString() { + return "List of " + list.size() + " user defined objects"; + } + + public Object target() { + return list; + } + + public boolean isEqual(Object other) { + return list.equals(other); + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/Person.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/Person.java new file mode 100644 index 0000000..c347453 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/Person.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark.targets; + +import java.util.Date; +import java.io.Serializable; + +/** + * @see UserDefinedClassTarget + */ +public class Person implements Serializable { + + public String firstName; + public String lastName; + public Date dateOfBirth; + + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + final Person person = (Person) o; + + if (dateOfBirth != null ? !dateOfBirth.equals(person.dateOfBirth) : person.dateOfBirth != null) return false; + if (firstName != null ? !firstName.equals(person.firstName) : person.firstName != null) return false; + return !(lastName != null ? !lastName.equals(person.lastName) : person.lastName != null); + } + + public int hashCode() { + int result; + result = (firstName != null ? firstName.hashCode() : 0); + result = 29 * result + (lastName != null ? lastName.hashCode() : 0); + result = 29 * result + (dateOfBirth != null ? dateOfBirth.hashCode() : 0); + return result; + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/ReflectionTarget.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/ReflectionTarget.java new file mode 100644 index 0000000..1970f87 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/ReflectionTarget.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. January 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.targets; + +import com.thoughtworks.xstream.tools.benchmark.Target; +import com.thoughtworks.xstream.tools.benchmark.model.Five; +import com.thoughtworks.xstream.tools.benchmark.model.One; + +import java.util.ArrayList; +import java.util.List; + +/** + * Target containing basic types using the ReflectionConverter. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class ReflectionTarget implements Target { + + private List list; + + public ReflectionTarget() { + list = new ArrayList(); + for (int i = 0; i < 5; ++i) { + list.add(new One(Integer.toString(i))); + } + list.add(new Five("1", 2, true, '4', new StringBuffer("5"))); + } + + public boolean isEqual(Object other) { + return list.equals(other); + } + + public Object target() { + return list; + } + + public String toString() { + return "Reflection Converter"; + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/SerializableTarget.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/SerializableTarget.java new file mode 100644 index 0000000..537ba81 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/SerializableTarget.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2008, 2009, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. January 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.targets; + +import com.thoughtworks.xstream.tools.benchmark.Target; +import com.thoughtworks.xstream.tools.benchmark.model.SerializableFive; +import com.thoughtworks.xstream.tools.benchmark.model.SerializableOne; + +import java.util.ArrayList; +import java.util.List; + +/** + * Target containing basic types using the SerializableConverter. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class SerializableTarget implements Target { + + private List list; + + public SerializableTarget() { + list = new ArrayList(); + for (int i = 0; i < 5; ++i) { + list.add(new SerializableOne(Integer.toString(i))); + } + list.add(new SerializableFive("1", 2, true, '4', new StringBuffer("5"))); + } + + public boolean isEqual(Object other) { + return list.equals(other); + } + + public Object target() { + return list; + } + + public String toString() { + return "Serializable types"; + } +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/StringTarget.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/StringTarget.java new file mode 100644 index 0000000..0f11266 --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/StringTarget.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark.targets; + +import com.thoughtworks.xstream.tools.benchmark.Target; + +/** + * A small java.lang.String target. + * + * @author Joe Walnes + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Target + */ +public class StringTarget implements Target { + + private final String string = "Hello World!"; + + public String toString() { + return "Simple string"; + } + + public Object target() { + return string; + } + + public boolean isEqual(Object other) { + return string.equals(other); + } + +} diff --git a/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/UserDefinedClassTarget.java b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/UserDefinedClassTarget.java new file mode 100644 index 0000000..f82604b --- /dev/null +++ b/xstream-benchmark/src/java/com/thoughtworks/xstream/tools/benchmark/targets/UserDefinedClassTarget.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2006 Joe Walnes. + * Copyright (C) 2006, 2007 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 15. July 2006 by Joe Walnes + */ +package com.thoughtworks.xstream.tools.benchmark.targets; + +import com.thoughtworks.xstream.tools.benchmark.Target; + +import java.util.Date; + +/** + * A user defined class ({@link Person}) to serialize that contains a few simple fields. + * + * @author Joe Walnes + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Target + */ +public class UserDefinedClassTarget implements Target { + + private final Person person; + + public UserDefinedClassTarget() { + person = new Person(); + person.firstName = "Joe"; + person.lastName = "Walnes"; + person.dateOfBirth = new Date(); + } + + public String toString() { + return "User defined class"; + } + + public Object target() { + return person; + } + + public boolean isEqual(Object other) { + return person.equals(other); + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/CacheBenchmark.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/CacheBenchmark.java new file mode 100644 index 0000000..ae4bf6b --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/CacheBenchmark.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. January 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.cache; + +import com.thoughtworks.xstream.tools.benchmark.Harness; +import com.thoughtworks.xstream.tools.benchmark.Product; +import com.thoughtworks.xstream.tools.benchmark.cache.products.AliasedAttributeCache; +import com.thoughtworks.xstream.tools.benchmark.cache.products.Cache122; +import com.thoughtworks.xstream.tools.benchmark.cache.products.DefaultImplementationCache; +import com.thoughtworks.xstream.tools.benchmark.cache.products.NoCache; +import com.thoughtworks.xstream.tools.benchmark.cache.products.RealClassCache; +import com.thoughtworks.xstream.tools.benchmark.cache.products.SerializedClassCache; +import com.thoughtworks.xstream.tools.benchmark.metrics.DeserializationSpeedMetric; +import com.thoughtworks.xstream.tools.benchmark.metrics.SerializationSpeedMetric; +import com.thoughtworks.xstream.tools.benchmark.reporters.TextReporter; +import com.thoughtworks.xstream.tools.benchmark.targets.BasicTarget; +import com.thoughtworks.xstream.tools.benchmark.targets.ExtendedTarget; +import com.thoughtworks.xstream.tools.benchmark.targets.ReflectionTarget; +import com.thoughtworks.xstream.tools.benchmark.targets.SerializableTarget; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.Parser; +import org.apache.commons.cli.PosixParser; + +import java.io.PrintWriter; + + +/** + * Main application to run harness for Profile benchmark. + * + * @author Jörg Schaible + */ +public class CacheBenchmark { + public static void main(String[] args) { + int counter = 10000; + Product product = null; + + Options options = new Options(); + options.addOption("p", "product", true, "Class name of the product to use for benchmark"); + options.addOption("n", true, "Number of repetitions"); + + Parser parser = new PosixParser(); + try { + CommandLine commandLine = parser.parse(options, args); + if (commandLine.hasOption('p')) { + product = (Product)Class.forName(commandLine.getOptionValue('p')).newInstance(); + } + if (commandLine.hasOption('n')) { + counter = Integer.parseInt(commandLine.getOptionValue('n')); + } + } catch (ParseException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + + Harness harness = new Harness(); + // harness.addMetric(new SerializationSpeedMetric(1) { + // public String toString() { + // return "Initial run serialization"; + // } + // }); + // harness.addMetric(new DeserializationSpeedMetric(1, false) { + // public String toString() { + // return "Initial run deserialization"; + // } + // }); + harness.addMetric(new SerializationSpeedMetric(counter)); + harness.addMetric(new DeserializationSpeedMetric(counter, false)); + if (product == null) { + harness.addProduct(new NoCache()); + harness.addProduct(new Cache122()); + harness.addProduct(new RealClassCache()); + harness.addProduct(new SerializedClassCache()); + harness.addProduct(new AliasedAttributeCache()); + harness.addProduct(new DefaultImplementationCache()); + harness.addProduct(new NoCache()); + } else { + harness.addProduct(product); + } + harness.addTarget(new BasicTarget()); + harness.addTarget(new ExtendedTarget()); + harness.addTarget(new ReflectionTarget()); + harness.addTarget(new SerializableTarget()); + harness.run(new TextReporter(new PrintWriter(System.out, true))); + System.out.println("Done."); + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/AliasedAttributeCache.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/AliasedAttributeCache.java new file mode 100644 index 0000000..03a9e10 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/AliasedAttributeCache.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2008, 2009, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 02. January 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.cache.products; + +import com.thoughtworks.xstream.mapper.Mapper; +import com.thoughtworks.xstream.mapper.MapperWrapper; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * Uses XStream with a CachingMapper caching the aliasForAttribute method. + * + * @author Jörg Schaible + */ +public class AliasedAttributeCache extends XStreamCache { + + protected List getMappers() { + List list = super.getMappers(); + list.add(CachingMapper.class); + return list; + } + + public String toString() { + return "Aliased Attribute Cache"; + } + + public static class CachingMapper extends MapperWrapper { + + private transient Map attributeAliasCache; + + public CachingMapper(Mapper wrapped) { + super(wrapped); + readResolve(); + } + + public String aliasForAttribute(String attribute) { + String alias = (String) attributeAliasCache.get(attribute); + if (alias != null) { + return alias; + } + + String result = super.aliasForAttribute(attribute); + attributeAliasCache.put(attribute, alias); + return result; + } + + private Object readResolve() { + attributeAliasCache = Collections.synchronizedMap(new HashMap(256)); + return this; + } + + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/Cache122.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/Cache122.java new file mode 100644 index 0000000..9523f0b --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/Cache122.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2008, 2009, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. January 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.cache.products; + +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.mapper.ImplicitCollectionMapper; +import com.thoughtworks.xstream.mapper.Mapper; +import com.thoughtworks.xstream.mapper.MapperWrapper; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * Uses XStream with the CachingMapper of 1.2.2. + * + * @author Jörg Schaible + */ +public class Cache122 extends XStreamCache { + + protected List getMappers() { + List list = super.getMappers(); + Object cglibMapper = list.remove(1); + Object dynProxyMapper = null; + if (JVM.loadClassForName("net.sf.cglib.proxy.Enhancer") != null) { + dynProxyMapper = list.remove(1); + } + int idx = list.indexOf(ImplicitCollectionMapper.class); + if (JVM.loadClassForName("net.sf.cglib.proxy.Enhancer") != null) { + list.add(idx+1, dynProxyMapper); + } + list.add(idx+1, cglibMapper); + list.add(CachingMapper.class); + return list; + } + + public String toString() { + return "XStream 1.2.2 Cache"; + } + + public static class CachingMapper extends MapperWrapper { + + private transient Map realClassCache; + + public CachingMapper(Mapper wrapped) { + super(wrapped); + realClassCache = Collections.synchronizedMap(new HashMap()); + } + + public Class realClass(String elementName) { + Class cached = (Class)realClassCache.get(elementName); + if (cached != null) { + return cached; + } + + Class result = super.realClass(elementName); + realClassCache.put(elementName, result); + return result; + } + + private Object readResolve() { + realClassCache = Collections.synchronizedMap(new HashMap()); + return this; + } + + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/DefaultImplementationCache.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/DefaultImplementationCache.java new file mode 100644 index 0000000..fd4ab5a --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/DefaultImplementationCache.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2008, 2009, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. January 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.cache.products; + +import com.thoughtworks.xstream.mapper.Mapper; +import com.thoughtworks.xstream.mapper.MapperWrapper; + +import java.lang.ref.WeakReference; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; + + +/** + * Uses XStream with a CachingMapper caching the aliasForAttribute method. + * + * @author Jörg Schaible + */ +public class DefaultImplementationCache extends XStreamCache { + + protected List getMappers() { + List list = super.getMappers(); + list.add(CachingMapper.class); + return list; + } + + public String toString() { + return "Default Implementation Cache"; + } + + public static class CachingMapper extends MapperWrapper { + + private transient Map defaultImplementationCache; + + public CachingMapper(Mapper wrapped) { + super(wrapped); + readResolve(); + } + + public Class defaultImplementationOf(Class type) { + WeakReference reference = (WeakReference) defaultImplementationCache.get(type); + if (reference != null) { + Class cached = (Class) reference.get(); + if (cached != null) { + return cached; + } + } + + Class result = super.defaultImplementationOf(type); + defaultImplementationCache.put(type, new WeakReference(result)); + return result; + } + + private Object readResolve() { + defaultImplementationCache = Collections.synchronizedMap(new WeakHashMap(128)); + return this; + } + + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/NoCache.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/NoCache.java new file mode 100644 index 0000000..088970a --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/NoCache.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. January 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.cache.products; + + + +/** + * Uses XStream with the CachingMapper of 1.2.2. + * + * @author Jörg Schaible + */ +public class NoCache extends XStreamCache { + + public String toString() { + return "No Cache"; + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/RealClassCache.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/RealClassCache.java new file mode 100644 index 0000000..bd5625a --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/RealClassCache.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2008, 2009, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 02. January 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.cache.products; + +import com.thoughtworks.xstream.mapper.Mapper; +import com.thoughtworks.xstream.mapper.MapperWrapper; + +import java.lang.ref.WeakReference; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * Uses XStream with a CachingMapper caching the realClass method. + * + * @author Jörg Schaible + */ +public class RealClassCache extends XStreamCache { + + protected List getMappers() { + List list = super.getMappers(); + list.add(CachingMapper.class); + return list; + } + + public String toString() { + return "Real Class Cache"; + } + + public static class CachingMapper extends MapperWrapper { + + private transient Map realClassCache; + + public CachingMapper(Mapper wrapped) { + super(wrapped); + readResolve(); + } + + public Class realClass(String elementName) { + WeakReference reference = (WeakReference) realClassCache.get(elementName); + if (reference != null) { + Class cached = (Class) reference.get(); + if (cached != null) { + return cached; + } + } + + Class result = super.realClass(elementName); + realClassCache.put(elementName, new WeakReference(result)); + return result; + } + + private Object readResolve() { + realClassCache = Collections.synchronizedMap(new HashMap(128)); + return this; + } + + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/SerializedClassCache.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/SerializedClassCache.java new file mode 100644 index 0000000..7716107 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/SerializedClassCache.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2008, 2009, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. January 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.cache.products; + +import com.thoughtworks.xstream.mapper.Mapper; +import com.thoughtworks.xstream.mapper.MapperWrapper; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; + + +/** + * Uses XStream with a CachingMapper caching the aliasForAttribute method. + * + * @author Jörg Schaible + */ +public class SerializedClassCache extends XStreamCache { + + protected List getMappers() { + List list = super.getMappers(); + list.add(CachingMapper.class); + return list; + } + + public String toString() { + return "Serialized Class Cache"; + } + + public static class CachingMapper extends MapperWrapper { + + private transient Map serializedClassCache; + + public CachingMapper(Mapper wrapped) { + super(wrapped); + readResolve(); + } + + public String serializedClass(Class type) { + String alias = (String) serializedClassCache.get(type); + if (alias != null) { + return alias; + } + + String result = super.serializedClass(type); + serializedClassCache.put(type, alias); + return result; + } + + private Object readResolve() { + serializedClassCache = Collections.synchronizedMap(new WeakHashMap(128)); + return this; + } + + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/XStreamCache.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/XStreamCache.java new file mode 100644 index 0000000..ca516c3 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/cache/products/XStreamCache.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2008, 2009, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 01. January 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.cache.products; + +import com.thoughtworks.xstream.InitializationException; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.ConverterLookup; +import com.thoughtworks.xstream.core.ClassLoaderReference; +import com.thoughtworks.xstream.core.DefaultConverterLookup; +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.core.util.CompositeClassLoader; +import com.thoughtworks.xstream.core.util.DependencyInjectionFactory; +import com.thoughtworks.xstream.core.util.TypedNull; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.mapper.ArrayMapper; +import com.thoughtworks.xstream.mapper.AttributeAliasingMapper; +import com.thoughtworks.xstream.mapper.AttributeMapper; +import com.thoughtworks.xstream.mapper.ClassAliasingMapper; +import com.thoughtworks.xstream.mapper.DefaultImplementationsMapper; +import com.thoughtworks.xstream.mapper.DefaultMapper; +import com.thoughtworks.xstream.mapper.DynamicProxyMapper; +import com.thoughtworks.xstream.mapper.FieldAliasingMapper; +import com.thoughtworks.xstream.mapper.ImmutableTypesMapper; +import com.thoughtworks.xstream.mapper.ImplicitCollectionMapper; +import com.thoughtworks.xstream.mapper.LocalConversionMapper; +import com.thoughtworks.xstream.mapper.Mapper; +import com.thoughtworks.xstream.mapper.OuterClassMapper; +import com.thoughtworks.xstream.tools.benchmark.Product; +import com.thoughtworks.xstream.tools.benchmark.model.Five; +import com.thoughtworks.xstream.tools.benchmark.model.One; +import com.thoughtworks.xstream.tools.benchmark.model.SerializableFive; +import com.thoughtworks.xstream.tools.benchmark.model.SerializableOne; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + + +/** + * Uses XStream with the XPP driver. + * + * @author Jörg Schaible + */ +public abstract class XStreamCache implements Product { + + private final XStream xstream; + + public XStreamCache() { + ClassLoaderReference classLoaderReference = new ClassLoaderReference( + new CompositeClassLoader()); + DefaultConverterLookup converterLookup = new DefaultConverterLookup(); + xstream = new XStream( + JVM.newReflectionProvider(), new XppDriver(), classLoaderReference, buildMapper( + getMappers(), classLoaderReference, converterLookup), converterLookup, converterLookup); + xstream.alias("one", One.class); + xstream.alias("five", Five.class); + xstream.alias("ser-one", SerializableOne.class); + xstream.alias("ser-five", SerializableFive.class); + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.toXML(object, output); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.fromXML(input); + } + + protected List getMappers() { + List mappers = new ArrayList(); + mappers.add(DefaultMapper.class); + if (JVM.loadClassForName("net.sf.cglib.proxy.Enhancer") != null) { + mappers.add(JVM.loadClassForName("com.thoughtworks.xstream.mapper.CGLIBMapper")); + } + mappers.add(DynamicProxyMapper.class); + mappers.add(ClassAliasingMapper.class); + mappers.add(FieldAliasingMapper.class); + mappers.add(AttributeAliasingMapper.class); + mappers.add(ImplicitCollectionMapper.class); + mappers.add(OuterClassMapper.class); + mappers.add(ArrayMapper.class); + mappers.add(LocalConversionMapper.class); + mappers.add(DefaultImplementationsMapper.class); + if (JVM.is15()) { + mappers.add(JVM.loadClassForName("com.thoughtworks.xstream.mapper.EnumMapper")); + } else { + mappers.add(AttributeMapper.class); + } + mappers.add(ImmutableTypesMapper.class); + if (JVM.is15()) { + mappers.add(JVM.loadClassForName("com.thoughtworks.xstream.mapper.AnnotationMapper")); + } + return mappers; + } + + private Mapper buildMapper(List mappers, ClassLoaderReference classLoaderReference, + ConverterLookup converterLookup) { + final Object[] arguments = new Object[]{ + new TypedNull(Mapper.class), converterLookup, classLoaderReference, + JVM.newReflectionProvider()}; + for (final Iterator iter = mappers.iterator(); iter.hasNext();) { + final Class mapperType = (Class)iter.next(); + try { + arguments[0] = DependencyInjectionFactory.newInstance(mapperType, arguments); + } catch (Exception e) { + throw new InitializationException("Could not instantiate mapper : " + + mapperType.getName(), e); + } + } + return (Mapper)arguments[0]; + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/parsers/ParserBenchmark.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/parsers/ParserBenchmark.java new file mode 100644 index 0000000..57a31ff --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/parsers/ParserBenchmark.java @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 18. February 2009 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.parsers; + +import com.thoughtworks.xstream.core.JVM; +import com.thoughtworks.xstream.tools.benchmark.Harness; +import com.thoughtworks.xstream.tools.benchmark.metrics.DeserializationSpeedMetric; +import com.thoughtworks.xstream.tools.benchmark.products.XStreamDom; +import com.thoughtworks.xstream.tools.benchmark.products.XStreamDom4J; +import com.thoughtworks.xstream.tools.benchmark.products.XStreamBEAStax; +import com.thoughtworks.xstream.tools.benchmark.products.XStreamJDom; +import com.thoughtworks.xstream.tools.benchmark.products.XStreamKXml2; +import com.thoughtworks.xstream.tools.benchmark.products.XStreamKXml2DOM; +import com.thoughtworks.xstream.tools.benchmark.products.XStreamSjsxp; +import com.thoughtworks.xstream.tools.benchmark.products.XStreamWoodstox; +import com.thoughtworks.xstream.tools.benchmark.products.XStreamXom; +import com.thoughtworks.xstream.tools.benchmark.products.XStreamXpp3; +import com.thoughtworks.xstream.tools.benchmark.products.XStreamXpp3DOM; +import com.thoughtworks.xstream.tools.benchmark.reporters.TextReporter; +import com.thoughtworks.xstream.tools.benchmark.targets.BasicTarget; +import com.thoughtworks.xstream.tools.benchmark.targets.ExtendedTarget; +import com.thoughtworks.xstream.tools.benchmark.targets.JavaBeanTarget; +import com.thoughtworks.xstream.tools.benchmark.targets.ReflectionTarget; +import com.thoughtworks.xstream.tools.benchmark.targets.SerializableTarget; +import com.thoughtworks.xstream.tools.model.targets.FieldReflection; +import com.thoughtworks.xstream.tools.model.targets.HierarchyLevelReflection; +import com.thoughtworks.xstream.tools.model.targets.InnerClassesReflection; +import com.thoughtworks.xstream.tools.model.targets.StaticInnerClassesReflection; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.Parser; +import org.apache.commons.cli.PosixParser; + +import java.io.PrintWriter; + + +/** + * Main application to run harness for Profile benchmark. + * + * @author Jörg Schaible + */ +public class ParserBenchmark { + public static void main(String[] args) { + int counter = 1000; + + Options options = new Options(); + options.addOption("p", "product", true, "Class name of the product to use for benchmark"); + options.addOption("n", true, "Number of repetitions"); + + Harness harness = new Harness(); + harness.addMetric(new DeserializationSpeedMetric(0, false) { + public String toString() { + return "Initial run deserialization"; + } + }); + + Parser parser = new PosixParser(); + try { + CommandLine commandLine = parser.parse(options, args); + String name = null; + if (commandLine.hasOption('p')) { + name = commandLine.getOptionValue('p'); + } + if (name == null || name.equals("DOM")) { + harness.addProduct(new XStreamDom()); + } + if (name == null || name.equals("JDOM")) { + harness.addProduct(new XStreamJDom()); + } + if (name == null || name.equals("DOM4J")) { + harness.addProduct(new XStreamDom4J()); + } + if (name == null || name.equals("XOM")) { + harness.addProduct(new XStreamXom()); + } + if (name == null || name.equals("BEAStAX")) { + harness.addProduct(new XStreamBEAStax()); + } + if (name == null || name.equals("Woodstox")) { + harness.addProduct(new XStreamWoodstox()); + } + if (JVM.is16() && (name == null || name.equals("SJSXP"))) { + harness.addProduct(new XStreamSjsxp()); + } + if (name == null || name.equals("Xpp3")) { + harness.addProduct(new XStreamXpp3()); + } + if (name == null || name.equals("kXML2")) { + harness.addProduct(new XStreamKXml2()); + } + if (name == null || name.equals("Xpp3DOM")) { + harness.addProduct(new XStreamXpp3DOM()); + } + if (name == null || name.equals("kXML2DOM")) { + harness.addProduct(new XStreamKXml2DOM()); + } + if (commandLine.hasOption('n')) { + counter = Integer.parseInt(commandLine.getOptionValue('n')); + } + } catch (ParseException e) { + e.printStackTrace(); + } + + harness.addMetric(new DeserializationSpeedMetric(counter, false)); + harness.addTarget(new BasicTarget()); + harness.addTarget(new ExtendedTarget()); + harness.addTarget(new ReflectionTarget()); + harness.addTarget(new SerializableTarget()); + harness.addTarget(new JavaBeanTarget()); + if (false) { + harness.addTarget(new FieldReflection()); + harness.addTarget(new HierarchyLevelReflection()); + harness.addTarget(new InnerClassesReflection()); + harness.addTarget(new StaticInnerClassesReflection()); + } + harness.run(new TextReporter(new PrintWriter(System.out, true))); + System.out.println("Done."); + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/reflection/ReflectionBenchmark.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/reflection/ReflectionBenchmark.java new file mode 100644 index 0000000..eb598c4 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/reflection/ReflectionBenchmark.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. June 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.reflection; + +import com.thoughtworks.xstream.tools.benchmark.Harness; +import com.thoughtworks.xstream.tools.benchmark.metrics.DeserializationSpeedMetric; +import com.thoughtworks.xstream.tools.benchmark.metrics.SerializationSpeedMetric; +import com.thoughtworks.xstream.tools.benchmark.reflection.products.XStreamClassAliases; +import com.thoughtworks.xstream.tools.benchmark.reflection.products.XStreamFieldAliases; +import com.thoughtworks.xstream.tools.benchmark.reflection.products.XStreamLocalAttributeAliases; +import com.thoughtworks.xstream.tools.benchmark.reflection.products.XStreamPlain; +import com.thoughtworks.xstream.tools.benchmark.reporters.TextReporter; +import com.thoughtworks.xstream.tools.model.targets.FieldReflection; +import com.thoughtworks.xstream.tools.model.targets.HierarchyLevelReflection; +import com.thoughtworks.xstream.tools.model.targets.InnerClassesReflection; +import com.thoughtworks.xstream.tools.model.targets.StaticInnerClassesReflection; + + +/** + * Main application to run harness for Reflection benchmark. + * + * @author Jörg Schaible + */ +public class ReflectionBenchmark { + public static void main(String[] args) { + Harness harness = new Harness(); + harness.addMetric(new SerializationSpeedMetric(10)); + harness.addMetric(new DeserializationSpeedMetric(10, true)); + harness.addProduct(new XStreamPlain()); + harness.addProduct(new XStreamClassAliases()); + harness.addProduct(new XStreamFieldAliases()); + harness.addProduct(new XStreamLocalAttributeAliases()); + harness.addTarget(new FieldReflection()); + harness.addTarget(new HierarchyLevelReflection()); + harness.addTarget(new InnerClassesReflection()); + harness.addTarget(new StaticInnerClassesReflection()); + harness.run(new TextReporter()); + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/reflection/products/XStreamClassAliases.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/reflection/products/XStreamClassAliases.java new file mode 100644 index 0000000..359160c --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/reflection/products/XStreamClassAliases.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. June 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.reflection.products; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.tools.benchmark.Product; +import com.thoughtworks.xstream.tools.benchmark.model.A100Parents; + +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Uses XStream with the XPP driver for parsing XML with aliases for field names. + * + * @author Jörg Schaible + * @author Joe Walnes + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Product + * @see XStream#alias(String, Class) + */ +public class XStreamClassAliases implements Product { + + private final XStream xstream; + + public XStreamClassAliases() { + this.xstream = new XStream(new XppDriver()); + for(int i = 0; i < 100; ++i) { + String no = "00" + i; + no = no.substring(no.length() - 3); + try { + Class cls = Class.forName(A100Parents.class.getName() + "$Parent" + no); + xstream.alias("p" + no, cls); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.toXML(object, output); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.fromXML(input); + } + + public String toString() { + return "XStream (class aliases)"; + } + +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/reflection/products/XStreamFieldAliases.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/reflection/products/XStreamFieldAliases.java new file mode 100644 index 0000000..538de03 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/reflection/products/XStreamFieldAliases.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. June 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.reflection.products; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.tools.benchmark.Product; +import com.thoughtworks.xstream.tools.benchmark.model.A100Fields; +import com.thoughtworks.xstream.tools.benchmark.model.A100Parents; + +import java.io.InputStream; +import java.io.OutputStream; + + +/** + * Uses XStream with the XPP driver for parsing XML with aliases for fields. + * + * @author Jörg Schaible + * @author Joe Walnes + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Product + * @see XStream#aliasField(String, Class, String) + */ +public class XStreamFieldAliases implements Product { + + private final XStream xstream; + + public XStreamFieldAliases() { + this.xstream = new XStream(new XppDriver()); + try { + Class clsFields = Class.forName(A100Fields.class.getName()); + for (int i = 0; i < 100; ++i) { + String no = "00" + i; + no = no.substring(no.length() - 3); + xstream.aliasField("f" + no, clsFields, "field" + no); + Class cls = Class.forName(A100Parents.class.getName() + "$Parent" + no); + xstream.aliasField("f" + no, cls, "field" + no); + } + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.toXML(object, output); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.fromXML(input); + } + + public String toString() { + return "XStream (field aliases)"; + } + +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/reflection/products/XStreamLocalAttributeAliases.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/reflection/products/XStreamLocalAttributeAliases.java new file mode 100644 index 0000000..e21a36b --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/reflection/products/XStreamLocalAttributeAliases.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. June 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.reflection.products; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.tools.benchmark.Product; +import com.thoughtworks.xstream.tools.benchmark.model.A100Fields; +import com.thoughtworks.xstream.tools.benchmark.model.A100Parents; + +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Uses XStream with the XPP driver for parsing XML with local attribute aliases for fields. + * + * @author Jörg Schaible + * @author Joe Walnes + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Product + * @see XStream#aliasAttribute(Class, String, String) + */ +public class XStreamLocalAttributeAliases implements Product { + + private final XStream xstream; + + public XStreamLocalAttributeAliases() { + this.xstream = new XStream(new XppDriver()); + try { + Class clsFields = Class.forName(A100Fields.class.getName()); + for (int i = 0; i < 100; ++i) { + String no = "00" + i; + no = no.substring(no.length() - 3); + xstream.useAttributeFor(clsFields, "field" + no); + xstream.aliasAttribute(clsFields, "field" + no, "f" + no); + Class cls = Class.forName(A100Parents.class.getName() + "$Parent" + no); + xstream.useAttributeFor(cls, "field" + no); + xstream.aliasAttribute(cls, "field" + no, "f" + no); + } + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.toXML(object, output); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.fromXML(input); + } + + public String toString() { + return "XStream (local attribute aliases)"; + } + +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/reflection/products/XStreamPlain.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/reflection/products/XStreamPlain.java new file mode 100644 index 0000000..76eff98 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/reflection/products/XStreamPlain.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. June 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.reflection.products; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.tools.benchmark.Product; + +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Uses XStream with the XPP driver for parsing XML and no additional setup. + * + * @author Joe Walnes + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Product + * @see XStream + * @see XppDriver + */ +public class XStreamPlain implements Product { + + private final XStream xstream; + + public XStreamPlain() { + this.xstream = new XStream(new XppDriver()); + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.toXML(object, output); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.fromXML(input); + } + + public String toString() { + return "XStream (plain)"; + } + +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/StringsBenchmark.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/StringsBenchmark.java new file mode 100644 index 0000000..f1208e9 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/StringsBenchmark.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. May 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.strings; + +import com.thoughtworks.xstream.tools.benchmark.Harness; +import com.thoughtworks.xstream.tools.benchmark.metrics.DeserializationSpeedMetric; +import com.thoughtworks.xstream.tools.benchmark.reporters.TextReporter; +import com.thoughtworks.xstream.tools.benchmark.strings.products.StringInternConverter; +import com.thoughtworks.xstream.tools.benchmark.strings.products.StringNonCachingConverter; +import com.thoughtworks.xstream.tools.benchmark.strings.products.StringWithSynchronizedWeakHashMapConverter; +import com.thoughtworks.xstream.tools.benchmark.strings.products.StringWithWeakHashMapConverter; +import com.thoughtworks.xstream.tools.benchmark.strings.targets.BigString; +import com.thoughtworks.xstream.tools.benchmark.strings.targets.StringArray; + + +/** + * Main application to run harness for StringConverter benchmark. + * + * @author Jörg Schaible + */ +public class StringsBenchmark { + public static void main(String[] args) { + Harness harness = new Harness(); + harness.addMetric(new DeserializationSpeedMetric(10, true)); + harness.addProduct(new StringNonCachingConverter()); + harness.addProduct(new StringInternConverter()); + harness.addProduct(new StringWithWeakHashMapConverter()); + harness.addProduct(new StringWithSynchronizedWeakHashMapConverter()); + harness.addTarget(new BigString()); + harness.addTarget(new StringArray(1024, 1024, 128)); + harness.addTarget(new StringArray(64 * 1024, 8, 32)); + harness.run(new TextReporter()); + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/products/StringInternConverter.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/products/StringInternConverter.java new file mode 100644 index 0000000..ca4070c --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/products/StringInternConverter.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. May 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.strings.products; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.tools.benchmark.Product; + +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Uses String.intern() for StringConverter (and allocates PermSpace). + * + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Product + */ +public class StringInternConverter implements Product { + + private final XStream xstream; + + public StringInternConverter() { + xstream = new XStream(new XppDriver()); + xstream.registerConverter(new StringConverter()); + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.toXML(object, output); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.fromXML(input); + } + + public String toString() { + return "StringConverter using intern() allocating perm space"; + } + + /** + * Converts a String to a String ;). Well ok, it doesn't + * actually do any conversion. + *

The converter always calls intern() on the returned + * String to encourage the JVM to reuse instances.

+ * + * @author Joe Walnes + * @see String#intern() + */ + public static class StringConverter extends AbstractSingleValueConverter { + + public boolean canConvert(Class type) { + return type.equals(String.class); + } + + public Object fromString(String str) { + return str.intern(); + } + + } + +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/products/StringNonCachingConverter.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/products/StringNonCachingConverter.java new file mode 100644 index 0000000..5c03bf5 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/products/StringNonCachingConverter.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 18. June 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.strings.products; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.tools.benchmark.Product; + +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Uses no cache at all StringConverter. + * + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Product + */ +public class StringNonCachingConverter implements Product { + + private final XStream xstream; + + public StringNonCachingConverter() { + xstream = new XStream(new XppDriver()); + xstream.registerConverter(new StringConverter()); + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.toXML(object, output); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.fromXML(input); + } + + public String toString() { + return "StringConverter using no cache at all"; + } + + /** + * Converts a String to a String ;). + * + * @author Jörg Schaible + * @see String#intern() + */ + public static class StringConverter extends AbstractSingleValueConverter { + + public boolean canConvert(Class type) { + return type.equals(String.class); + } + + public Object fromString(String str) { + return str; + } + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/products/StringWithSynchronizedWeakHashMapConverter.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/products/StringWithSynchronizedWeakHashMapConverter.java new file mode 100644 index 0000000..9d977f5 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/products/StringWithSynchronizedWeakHashMapConverter.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. May 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.strings.products; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.tools.benchmark.Product; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Collections; +import java.util.WeakHashMap; + + +/** + * Uses WeakHashMap for StringConverter. + * + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Product + */ +public class StringWithSynchronizedWeakHashMapConverter implements Product { + + private final XStream xstream; + + public StringWithSynchronizedWeakHashMapConverter() { + xstream = new XStream(new XppDriver()); + xstream.registerConverter(new StringWithWeakHashMapConverter.StringConverter(Collections.synchronizedMap(new WeakHashMap()))); + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.toXML(object, output); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.fromXML(input); + } + + public String toString() { + return "StringConverter using synchronized WeakHashMap"; + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/products/StringWithWeakHashMapConverter.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/products/StringWithWeakHashMapConverter.java new file mode 100644 index 0000000..012f29f --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/products/StringWithWeakHashMapConverter.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 04. May 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.strings.products; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.tools.benchmark.Product; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; +import java.util.WeakHashMap; +import java.lang.ref.WeakReference; + + +/** + * Uses WeakHashMap for StringConverter. + * + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Product + */ +public class StringWithWeakHashMapConverter implements Product { + + private final XStream xstream; + + public StringWithWeakHashMapConverter() { + xstream = new XStream(new XppDriver()); + xstream.registerConverter(new StringConverter()); + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.toXML(object, output); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.fromXML(input); + } + + public String toString() { + return "StringConverter using WeakHashMap"; + } + + /** + * Converts a String to a String. + *

+ * Well ok, it doesn't actually do any conversion. The converter uses a map to reuse + * instances. This map is by default a {@link WeakHashMap}. + *

+ * + * @author Rene Schwietzke + * @author Jörg Schaible + * @see WeakHashMap + */ + public static class StringConverter extends AbstractSingleValueConverter { + /** + * A Map to store strings as long as needed to map similar strings onto the same + * instance and conserve memory. The map can be set from the outside during + * construction, so it can be a LRU map or a weak map, sychronized or not. + */ + private final Map cache; + + public StringConverter(Map map) { + this.cache = map; + } + + public StringConverter() { + this(new WeakHashMap()); + } + + public boolean canConvert(Class type) { + return type.equals(String.class); + } + + public Object fromString(String str) { + WeakReference ref = (WeakReference)cache.get(str); + String s = (String)(ref == null ? null : ref.get()); + + if (s == null) { + // fill cache + cache.put(str, new WeakReference(str)); + + s = str; + } + + return s; + } + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/targets/BigString.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/targets/BigString.java new file mode 100644 index 0000000..9d98b02 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/targets/BigString.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. June 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.strings.targets; + +import com.thoughtworks.xstream.tools.benchmark.Target; + +import org.apache.commons.io.IOUtils; + +import java.io.IOException; + + +/** + * A small java.lang.String target. + * + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Target + */ +public class BigString implements Target { + + private final String string; + + public BigString() { + try { + string = IOUtils.toString(getClass().getResourceAsStream("eclipse-build-log.txt")); + } catch (IOException e) { + throw new RuntimeException("Cannot create big String target", e); + } + } + + public String toString() { + return "Big string"; + } + + public Object target() { + return string; + } + + public boolean isEqual(Object other) { + return string.equals(other); + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/targets/StringArray.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/targets/StringArray.java new file mode 100644 index 0000000..c521978 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/targets/StringArray.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. June 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.strings.targets; + +import com.thoughtworks.xstream.tools.benchmark.Target; + +import java.util.Arrays; + + +/** + * A target with an array of java.lang.String objects. + * + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Target + */ +public class StringArray implements Target { + + private final String[] strings; + private final int unique; + + public StringArray(int elements, int length, int unique) { + this.unique = unique; + char[] zero = new char[length]; + Arrays.fill(zero, '0'); + + strings = new String[elements]; + for (int i = 0; i < strings.length; i++) { + String hex = Integer.toHexString(i % unique); + strings[i] = new String(zero, 0, zero.length - hex.length()) + hex; + } + } + + public String toString() { + return "String array with " + + strings.length + + " elements of " + + strings[0].length() + + " chars and " + + unique + + " unique entries"; + } + + public Object target() { + return strings; + } + + public boolean isEqual(Object other) { + return Arrays.equals(strings, (Object[])other); + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/targets/eclipse-build-log.txt b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/targets/eclipse-build-log.txt new file mode 100644 index 0000000..6fc7693 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/strings/targets/eclipse-build-log.txt @@ -0,0 +1,9690 @@ + * Checking for at least 768MBytes RAM ... + [ ok ] + * Using: sun-jdk-1.4 +>>> Unpacking source... +>>> Unpacking eclipse-sourceBuild-srcIncluded-3.2.zip to /volatile/portage/eclipse-sdk-3.2/work +>>> Unpacking eclipse-sdk-3.2-patches.tar.bz2 to /volatile/portage/eclipse-sdk-3.2/work + * Enabling embedded Mozilla support + * Enabling CAIRO support + * Enabling OpenGL support + * Applying eclipse-sdk-3.2-build.patch ... + [ ok ] + * Applying eclipse-sdk-3.2-libupdatebuild.patch ... + [ ok ] + * Applying eclipse-sdk-3.2-libupdatebuild2.patch ... + [ ok ] + * Applying eclipse-sdk-3.2-swttools.patch ... + [ ok ] + * Applying eclipse-sdk-3.2-updatehomedir.patch ... + [ ok ] + * Applying eclipse-sdk-3.2-fileinitializer.patch ... + [ ok ] + * Applying eclipse-sdk-3.2-bz162177.patch ... + [ ok ] + * Applying eclipse-sdk-3.2-genjavadocoutput.patch ... + [ ok ] + * Applying eclipse-sdk-3.2-helpindexbuilder.patch ... + [ ok ] + * Applying eclipse-sdk-3.2-usebuiltlauncher.patch ... + [ ok ] + * Applying eclipse-sdk-3.2-launcher-link.patch ... + [ ok ] + * Applying eclipse-sdk-3.2-launcher-link.patch ... + [ ok ] + * Applying eclipse-sdk-3.2-javadoclinks.patch ... + [ ok ] + * Applying eclipse-sdk-3.2-pde.build-add-package-build.patch ... + [ ok ] + * Applying eclipse-sdk-3.2-swt-rm-ON_TOP.patch ... + [ ok ] + * Applying eclipse-sdk-3.2-disable-junit4-apt.patch ... + [ ok ] +>>> Source unpacked. +>>> Compiling source in /volatile/portage/eclipse-sdk-3.2/work ... + * Using bootclasspath /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar:/opt/sun-jdk-1.4.2.12/jre/lib/i18n.jar:/opt/sun-jdk-1.4.2.12/jre/lib/sunrsasign.jar:/opt/sun-jdk-1.4.2.12/jre/lib/jsse.jar:/opt/sun-jdk-1.4.2.12/jre/lib/jce.jar:/opt/sun-jdk-1.4.2.12/jre/lib/charsets.jar + * Using JVM library path /opt/sun-jdk-1.4.2.12/jre/lib/i386 + * Will compile embedded seamonkey support against www-client/seamonkey + * Using /opt/sun-jdk-1.6.0 for java5home + [echo] TARGET: compiler + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/core/JDTCompilerAdapter.java] + [javac] [parsing completed 83ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/core/compiler/CategorizedProblem.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/core/compiler/CharOperation.java] + [javac] [parsing completed 61ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/core/compiler/IProblem.java] + [javac] [parsing completed 37ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/core/compiler/InvalidInputException.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/antadapter/AntAdapterMessages.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ASTVisitor.java] + [javac] [parsing completed 11ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ClassFile.java] + [javac] [parsing completed 219ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ClassFilePool.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/CompilationResult.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/Compiler.java] + [javac] [parsing completed 11ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ConfigurableOption.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/DefaultErrorHandlingPolicies.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ICompilerRequestor.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/IDebugRequestor.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/IErrorHandlingPolicy.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/IProblemFactory.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java] + [javac] [parsing completed 7ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ASTNode.java] + [javac] [parsing completed 6ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java] + [javac] [parsing completed 5ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/AbstractVariableDeclaration.java] + [javac] [parsing completed 6ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/Annotation.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/AnnotationMethodDeclaration.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/Argument.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ArrayAllocationExpression.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.java] + [javac] [parsing completed 7ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ArrayQualifiedTypeReference.java] + [javac] [parsing completed 6ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ArrayReference.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ArrayTypeReference.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java] + [javac] [parsing completed 7ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/Assignment.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.java] + [javac] [parsing completed 202ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/Block.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/CastExpression.java] + [javac] [parsing completed 10ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/CharLiteral.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.java] + [javac] [parsing completed 6ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/Clinit.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.java] + [javac] [parsing completed 8ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java] + [javac] [parsing completed 11ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/DoStatement.java] + [javac] [parsing completed 5ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/DoubleLiteral.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java] + [javac] [parsing completed 10ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/Expression.java] + [javac] [parsing completed 5ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ExtendedStringLiteral.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/FalseLiteral.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java] + [javac] [parsing completed 9ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/FieldReference.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/FloatLiteral.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ForStatement.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java] + [javac] [parsing completed 10ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/IfStatement.java] + [javac] [parsing completed 10ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ImportReference.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/Initializer.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/IntLiteral.java] + [javac] [parsing completed 6ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/IntLiteralMinValue.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/Javadoc.java] + [javac] [parsing completed 6ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/JavadocArgumentExpression.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/JavadocArrayQualifiedTypeReference.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/JavadocArraySingleTypeReference.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/JavadocImplicitTypeReference.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/JavadocImportReference.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/JavadocQualifiedTypeReference.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/JavadocReturnStatement.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/JavadocSingleNameReference.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/JavadocSingleTypeReference.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/Literal.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/LongLiteral.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/LongLiteralMinValue.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/MagicLiteral.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/MarkerAnnotation.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/MessageSend.java] + [javac] [parsing completed 5ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java] + [javac] [parsing completed 6ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/NameReference.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/NormalAnnotation.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/NullLiteral.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/NumberLiteral.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/OperatorExpression.java] + [javac] [parsing completed 16ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/OperatorIds.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.java] + [javac] [parsing completed 9ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/PostfixExpression.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/PrefixExpression.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java] + [javac] [parsing completed 8ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.java] + [javac] [parsing completed 8ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/Reference.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/SingleMemberAnnotation.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java] + [javac] [parsing completed 9ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java] + [javac] [parsing completed 5ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/Statement.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/StringLiteral.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/StringLiteralConcatenation.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/SubRoutineStatement.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/SuperReference.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java] + [javac] [parsing completed 8ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ThisReference.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/TrueLiteral.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/TryStatement.java] + [javac] [parsing completed 8ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java] + [javac] [parsing completed 11ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java] + [javac] [parsing completed 145ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/TypeReference.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java] + [javac] [parsing completed 6ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/ast/Wildcard.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/batch/ClasspathLocation.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/batch/ClasspathSourceJar.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/batch/CompilationUnit.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/batch/FileFinder.java] + [javac] [parsing completed 44ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/batch/FileSystem.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/batch/Main.java] + [javac] [parsing completed 27ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/classfmt/AnnotationInfo.java] + [javac] [parsing completed 6ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/classfmt/AnnotationMethodInfo.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/classfmt/AnnotationMethodInfoWithAnnotations.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/classfmt/ClassFileStruct.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/classfmt/ClassFormatException.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/classfmt/ElementValuePairInfo.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/classfmt/FieldInfo.java] + [javac] [parsing completed 5ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/classfmt/FieldInfoWithAnnotation.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/classfmt/InnerClassInfo.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.java] + [javac] [parsing completed 6ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithAnnotations.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithParameterAnnotations.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/AttributeNamesConstants.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/BranchLabel.java] + [javac] [parsing completed 7ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/CachedIndexEntry.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/CaseLabel.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/CharArrayCache.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java] + [javac] [parsing completed 36ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java] + [javac] [parsing completed 20ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/DoubleCache.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/ExceptionLabel.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/FieldNameAndTypeCache.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/FloatCache.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/IntegerCache.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/Label.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/LongCache.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/MethodNameAndTypeCache.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/ObjectCache.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/Opcodes.java] + [javac] [parsing completed 5ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/StackMapFrame.java] + [javac] [parsing completed 5ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java] + [javac] [parsing completed 19ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/codegen/VerificationTypeInfo.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/AccessRestriction.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/AccessRule.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/AccessRuleSet.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/ClassSignature.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/EnumConstantSignature.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/IBinaryAnnotation.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/IBinaryElementValuePair.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/IBinaryField.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/IBinaryMethod.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/IBinaryNestedType.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/IBinaryType.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/ICompilationUnit.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/IDependent.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/IGenericField.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/IGenericMethod.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/IGenericType.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/INameEnvironment.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/ISourceField.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/ISourceImport.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/ISourceMethod.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/ISourceType.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/env/NameEnvironmentAnswer.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java] + [javac] [parsing completed 6ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/flow/FlowContext.java] + [javac] [parsing completed 5ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/flow/InsideSubRoutineFlowContext.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/flow/LabelFlowContext.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/flow/NullInfoRegistry.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java] + [javac] [parsing completed 17ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/impl/BooleanConstant.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/impl/ByteConstant.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/impl/CharConstant.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java] + [javac] [parsing completed 19ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/impl/Constant.java] + [javac] [parsing completed 209ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/impl/DoubleConstant.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/impl/FloatConstant.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/impl/ITypeRequestor.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/impl/IntConstant.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/impl/LongConstant.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/impl/ShortConstant.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/impl/StringConstant.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/AnnotationHolder.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java] + [javac] [parsing completed 8ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/Binding.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java] + [javac] [parsing completed 9ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java] + [javac] [parsing completed 8ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/ElementValuePair.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/ExtraCompilerModifiers.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/ImportBinding.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/ImportConflictBinding.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/InnerEmulationDependency.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/InvocationSite.java] + [javac] [parsing completed 13ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java] + [javac] [parsing completed 10ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/MemberTypeBinding.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java] + [javac] [parsing completed 6ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.java] + [javac] [parsing completed 17ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/ParameterizedFieldBinding.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java] + [javac] [parsing completed 19ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/ProblemBinding.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/ProblemFieldBinding.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/ProblemMethodBinding.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/ProblemPackageBinding.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/ProblemReasons.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java] + [javac] [parsing completed 9ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/Scope.java] + [javac] [parsing completed 33ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/SignatureWrapper.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java] + [javac] [parsing completed 10ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/Substitution.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/SyntheticArgumentBinding.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/SyntheticFieldBinding.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/TagBits.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java] + [javac] [parsing completed 19ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/TypeIds.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/UnresolvedAnnotationBinding.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/UpdatedMethodBinding.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/VariableBinding.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java] + [javac] [parsing completed 20ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java] + [javac] [parsing completed 5ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/NLSTag.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/Parser.java] + [javac] [parsing completed 80ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java] + [javac] [parsing completed 0ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/RecoveredImport.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/RecoveredInitializer.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/RecoveredLocalVariable.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/RecoveredMethod.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/RecoveredStatement.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/RecoveredUnit.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/RecoveryScannerData.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/Scanner.java] + [javac] [parsing completed 20ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java] + [javac] [parsing completed 3ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser.java] + [javac] [parsing completed 26ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/diagnose/LexStream.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/parser/diagnose/RangeUtil.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/problem/AbortCompilation.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/problem/AbortCompilationUnit.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/problem/AbortMethod.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/problem/AbortType.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/problem/DefaultProblem.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/problem/DefaultProblemFactory.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java] + [javac] [parsing completed 316ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/problem/ProblemSeverities.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/problem/ShouldNotImplement.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/util/CompoundNameVector.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/util/FloatUtil.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/util/HashtableOfInt.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/util/HashtableOfIntValues.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/util/HashtableOfLong.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/util/HashtableOfObject.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/util/HashtableOfObjectToInt.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/util/HashtableOfObjectToIntArray.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/util/HashtableOfPackage.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/util/HashtableOfType.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/util/Messages.java] + [javac] [parsing completed 2ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/util/ObjectVector.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/util/SimpleLookupTable.java] + [javac] [parsing completed 4ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/util/SimpleNameVector.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/util/SimpleSet.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/util/SuffixConstants.java] + [javac] [parsing completed 1ms] + [javac] [parsing started /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/src/org/eclipse/jdt/internal/compiler/util/Util.java] + [javac] [parsing completed 6ms] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/File.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/IOException.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/PrintWriter.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/reflect/Constructor.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/reflect/InvocationTargetException.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/reflect/Method.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/ArrayList.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/Arrays.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/Comparator.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/HashMap.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/List.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/Map.class)] + [javac] [loading /usr/share/ant-core/lib/ant.jar(org/apache/tools/ant/BuildException.class)] + [javac] [loading /usr/share/ant-core/lib/ant.jar(org/apache/tools/ant/Project.class)] + [javac] [loading /usr/share/ant-core/lib/ant.jar(org/apache/tools/ant/taskdefs/Javac.class)] + [javac] [loading /usr/share/ant-core/lib/ant.jar(org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.class)] + [javac] [loading /usr/share/ant-core/lib/ant.jar(org/apache/tools/ant/types/Commandline.class)] + [javac] [loading /usr/share/ant-core/lib/ant.jar(org/apache/tools/ant/types/Path.class)] + [javac] [loading /usr/share/ant-core/lib/ant.jar(org/apache/tools/ant/types/Commandline$Argument.class)] + [javac] [loading /usr/share/ant-core/lib/ant.jar(org/apache/tools/ant/util/JavaEnvUtils.class)] + [javac] [loading /usr/share/ant-core/lib/ant.jar(org/apache/tools/ant/taskdefs/compilers/CompilerAdapter.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/Object.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/String.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/Class.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/Exception.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/Throwable.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/Serializable.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/text/MessageFormat.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/Locale.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/MissingResourceException.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/ResourceBundle.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/StringBuffer.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/CharConversionException.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/StringWriter.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/ByteArrayInputStream.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/InputStreamReader.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/UnsupportedEncodingException.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/Hashtable.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/Iterator.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/Set.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/Cloneable.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/HashSet.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/BufferedOutputStream.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/FileOutputStream.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/StringTokenizer.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/Collections.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/RuntimeException.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/CloneNotSupportedException.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/NoSuchElementException.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/Enumeration.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/zip/ZipEntry.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/zip/ZipFile.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/FileNotFoundException.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/FilenameFilter.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/LineNumberReader.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/StringReader.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/reflect/Field.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/text/DateFormat.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/Date.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/PrintStream.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/Comparable.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/InputStream.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/DataInputStream.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/reflect/Modifier.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/Properties.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/ClassLoader.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/Dictionary.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/FileInputStream.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/Boolean.class)] + [javac] [checking org.eclipse.jdt.core.JDTCompilerAdapter] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/Error.class)] + [javac] [loading /usr/share/ant-core/lib/ant.jar(org/apache/tools/ant/taskdefs/MatchingTask.class)] + [javac] [loading /usr/share/ant-core/lib/ant.jar(org/apache/tools/ant/Task.class)] + [javac] [loading /usr/share/ant-core/lib/ant.jar(org/apache/tools/ant/ProjectComponent.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/System.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/Writer.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/FilterOutputStream.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/OutputStream.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/reflect/AccessibleObject.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/ClassNotFoundException.class)] + [javac] [loading /usr/share/ant-core/lib/ant.jar(org/apache/tools/ant/types/DataType.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/NoSuchMethodException.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/IllegalAccessException.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/Collection.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/Map$Entry.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/net/URI.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/AbstractMap.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/AbstractList.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/AbstractCollection.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/SecurityException.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/InstantiationException.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/IllegalArgumentException.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/NoClassDefFoundError.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/LinkageError.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/core/JDTCompilerAdapter$1.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/core/JDTCompilerAdapter.class] + [javac] [checking org.eclipse.jdt.core.compiler.CategorizedProblem] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/core/compiler/CategorizedProblem.class] + [javac] [checking org.eclipse.jdt.core.compiler.IProblem] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/core/compiler/IProblem.class] + [javac] [checking org.eclipse.jdt.core.compiler.CharOperation] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/Character.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/Math.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/core/compiler/CharOperation.class] + [javac] [checking org.eclipse.jdt.core.compiler.InvalidInputException] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/core/compiler/InvalidInputException.class] + [javac] [checking org.eclipse.jdt.internal.antadapter.AntAdapterMessages] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/text/Format.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/antadapter/AntAdapterMessages.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ASTVisitor] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.AllocationExpression] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/Double.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/Integer.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.Expression] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.Statement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ASTNode] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.TypeConstants] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeConstants.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.TypeIds] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeIds.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.InvocationSite] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/InvocationSite.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.TypeReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/TypeReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.MethodBinding] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/ClassCastException.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.Binding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/Binding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.TypeBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.FieldDeclaration] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractVariableDeclaration.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.BlockScope] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/AbstractSet.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.Scope] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.class] + [javac] [checking org.eclipse.jdt.internal.compiler.flow.FlowContext] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.class] + [javac] [checking org.eclipse.jdt.internal.compiler.flow.FlowInfo] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding$1.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding$2.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding$3.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.IDependent] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/IDependent.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.CodeStream] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/Number.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/Float.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.class] + [javac] [checking org.eclipse.jdt.internal.compiler.impl.Constant] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.OperatorIds] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorIds.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.BranchLabel] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/BranchLabel.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.Label] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/Label.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalVariableBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.VariableBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/VariableBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.ClassScope] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.SwitchStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.FieldBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/FieldBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.Annotation] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding$1.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.PackageBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/PackageBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.ProblemReasons] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReasons.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.class] + [javac] [checking org.eclipse.jdt.internal.compiler.problem.ProblemSeverities] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemSeverities.class] + [javac] [checking org.eclipse.jdt.internal.compiler.impl.ReferenceContext] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/impl/ReferenceContext.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.ElementValuePair] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ElementValuePair.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.UnresolvedReferenceBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedReferenceBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.Javadoc] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.MethodScope] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.CaseStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.TypeDeclaration] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.LocalDeclaration] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.class] + [javac] [checking org.eclipse.jdt.internal.compiler.problem.ProblemReporter] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/IndexOutOfBoundsException.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.class] + [javac] [checking org.eclipse.jdt.internal.compiler.problem.ProblemHandler] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemHandler.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.Substitution] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/Substitution.class] + [javac] [checking org.eclipse.jdt.internal.compiler.impl.CompilerOptions] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/nio/charset/CharsetDecoder.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/nio/charset/Charset.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/Reader.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/NumberFormatException.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.TypeParameter] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.ArrayBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.util.ObjectVector] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/ObjectVector.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration$1.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.class] + [javac] [checking org.eclipse.jdt.internal.compiler.flow.NullInfoRegistry] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/flow/NullInfoRegistry.class] + [javac] [checking org.eclipse.jdt.internal.compiler.flow.UnconditionalFlowInfo] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo$AssertionFailedException.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.Reference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.SubRoutineStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/SubRoutineStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.util.SimpleLookupTable] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/SimpleLookupTable.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.AnnotationHolder] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationHolder$MethodHolder.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationHolder$AnnotationMethodHolder.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationHolder.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticArgumentBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.ExceptionLabel] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/ExceptionLabel.class] + [javac] [checking org.eclipse.jdt.internal.compiler.CompilationResult] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/CompilationResult$1.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ClassFile] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/FileDescriptor.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ClassFile.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.ConstantPool] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.class] + [javac] [checking org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/Long.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.SyntheticMethodBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticMethodBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.CaseLabel] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/CaseLabel.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/LocalTypeBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.NestedTypeBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.AccessRestriction] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/AccessRestriction.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.ImportBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ImportBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.util.HashtableOfObject] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObject.class] + [javac] [checking org.eclipse.jdt.internal.compiler.util.CompoundNameVector] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/CompoundNameVector.class] + [javac] [checking org.eclipse.jdt.internal.compiler.util.SimpleNameVector] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/SimpleNameVector.class] + [javac] [checking org.eclipse.jdt.internal.compiler.util.HashtableOfType] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfType.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.MethodVerifier] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.MemberValuePair] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/MemberValuePair.class] + [javac] [checking org.eclipse.jdt.internal.compiler.util.HashtableOfPackage] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfPackage.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.ProblemPackageBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemPackageBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemReferenceBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.INameEnvironment] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/INameEnvironment.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ClassFilePool] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ClassFilePool.class] + [javac] [checking org.eclipse.jdt.internal.compiler.impl.ITypeRequestor] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/impl/ITypeRequestor.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.IBinaryType] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.IGenericType] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/IGenericType.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/IllegalStateException.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/RawTypeBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedGenericMethodBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.ParameterizedMethodBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding$1.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding$2.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.WildcardBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.SignatureWrapper] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/SignatureWrapper.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.Argument] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/Argument.class] + [javac] [checking org.eclipse.jdt.internal.compiler.flow.InitializationFlowContext] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.class] + [javac] [checking org.eclipse.jdt.internal.compiler.flow.ExceptionHandlingFlowContext] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.Parser] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/ExceptionInInitializerError.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/BufferedWriter.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/FileWriter.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/OutputStreamWriter.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/BufferedInputStream.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/FilterInputStream.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/Parser$1MethodVisitor.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/Parser$1TypeVisitor.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.ParserBasicInformation] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.TerminalTokens] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.JavadocSingleNameReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleNameReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.SingleNameReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.NameReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/NameReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.JavadocSingleTypeReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocSingleTypeReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.SingleTypeReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.JavadocReturnStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocReturnStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ReturnStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.MethodDeclaration] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.MemberTypeBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/MemberTypeBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/IErrorHandlingPolicy.class] + [javac] [checking org.eclipse.jdt.internal.compiler.IProblemFactory] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/IProblemFactory.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/AnnotationMethodDeclaration.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.Assignment] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayAllocationExpression.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.MessageSend] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ImportReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ImportReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.class] + [javac] [checking org.eclipse.jdt.internal.compiler.problem.AbortCompilationUnit] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/problem/AbortCompilationUnit.class] + [javac] [checking org.eclipse.jdt.internal.compiler.problem.AbortCompilation] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/problem/AbortCompilation.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ThrowStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ThrowStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ConditionalExpression] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.OperatorExpression] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorExpression$1Decode.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/OperatorExpression.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.NumberLiteral] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/NumberLiteral.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.Literal] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/Literal.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ThisReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ThisReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.Block] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/Block.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedTypeReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.Initializer] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/Initializer.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.FieldReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.BinaryExpression] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/ArithmeticException.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/BinaryExpression.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.CompoundAssignment] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/CompoundAssignment.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.UnaryExpression] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/UnaryExpression.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.EqualExpression] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ArrayReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.CastExpression] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression$1.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.BranchStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.LabeledStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.TryStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.SyntheticFieldBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/SyntheticFieldBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.NLSTag] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/NLSTag.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.StringLiteral] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/StringLiteral.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.ICompilationUnit] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/ICompilationUnit.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.RecoveryScannerData] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScannerData.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.DoubleCache] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/DoubleCache.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.FloatCache] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/FloatCache.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.IntegerCache] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/IntegerCache.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.LongCache] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/LongCache.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.CharArrayCache] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/CharArrayCache.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.InnerEmulationDependency] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/InnerEmulationDependency.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.AccessRule] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/AccessRule.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/NameEnvironmentAnswer.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.ISourceType] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/ISourceType.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.IBinaryNestedType] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryNestedType.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.IBinaryField] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryField.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.IGenericField] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/IGenericField.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.IBinaryMethod] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryMethod.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.IGenericMethod] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/IGenericMethod.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryAnnotation.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.ObjectCache] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/ObjectCache.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.RecoveredElement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredElement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.RecoveryScanner] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/ArrayIndexOutOfBoundsException.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.Scanner] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.JavadocParser] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.JavadocTagConstants] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedQualifiedTypeReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayQualifiedTypeReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.RecoveredType] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.RecoveredStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ArrayInitializer] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayInitializer.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.CharLiteral] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/CharLiteral.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ExtendedStringLiteral] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ExtendedStringLiteral.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.StringLiteralConcatenation] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/StringLiteralConcatenation.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.ISourceField] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/ISourceField.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.ISourceMethod] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/ISourceMethod.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.IBinaryElementValuePair] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryElementValuePair.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.RecoveredBlock] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredBlock.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.RecoveredInitializer] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredInitializer.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.RecoveredField] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.RecoveredMethod] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredMethod.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.RecoveredLocalVariable] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredLocalVariable.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ArrayTypeReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.AssertStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.BreakStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ClassLiteralAccess.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.Clinit] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ContinueStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.DoStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/DoStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.DoubleLiteral] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/DoubleLiteral.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.EmptyStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.FalseLiteral] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/FalseLiteral.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.MagicLiteral] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/MagicLiteral.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.FloatLiteral] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/FloatLiteral.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ForeachStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ForStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.IfStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.IntLiteral] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/IntLiteral.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.JavadocArgumentExpression] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArgumentExpression.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.JavadocArrayQualifiedTypeReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArrayQualifiedTypeReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.JavadocQualifiedTypeReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocQualifiedTypeReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.JavadocArraySingleTypeReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocArraySingleTypeReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.JavadocFieldReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.LongLiteral] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteral.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/MarkerAnnotation.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.NormalAnnotation] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/NormalAnnotation.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.NullLiteral] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/NullLiteral.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/ParameterizedSingleTypeReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.PostfixExpression] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/PostfixExpression.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.PrefixExpression] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/PrefixExpression.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedSuperReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedThisReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/SingleMemberAnnotation.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.SuperReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/SuperReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.TrueLiteral] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/TrueLiteral.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.WhileStatement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.Wildcard] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/Wildcard.class] + [javac] [checking org.eclipse.jdt.internal.compiler.Compiler] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/Compiler$1.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/Compiler.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ICompilerRequestor] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ICompilerRequestor.class] + [javac] [checking org.eclipse.jdt.internal.compiler.IDebugRequestor] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/IDebugRequestor.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ConfigurableOption] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ConfigurableOption.class] + [javac] [checking org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/DefaultErrorHandlingPolicies$1.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/DefaultErrorHandlingPolicies$2.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/DefaultErrorHandlingPolicies$3.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/DefaultErrorHandlingPolicies$4.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/DefaultErrorHandlingPolicies.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.IntLiteralMinValue] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/IntLiteralMinValue.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.JavadocAllocationExpression] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocAllocationExpression.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.JavadocImplicitTypeReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocImplicitTypeReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.JavadocImportReference] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocImportReference.class] + [javac] [checking org.eclipse.jdt.internal.compiler.ast.LongLiteralMinValue] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/ast/LongLiteralMinValue.class] + [javac] [checking org.eclipse.jdt.internal.compiler.batch.ClasspathDirectory] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/batch/ClasspathDirectory.class] + [javac] [checking org.eclipse.jdt.internal.compiler.batch.ClasspathLocation] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/batch/ClasspathLocation.class] + [javac] [checking org.eclipse.jdt.internal.compiler.batch.FileSystem] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/batch/FileSystem$Classpath.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/batch/FileSystem.class] + [javac] [checking org.eclipse.jdt.internal.compiler.util.SuffixConstants] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/SuffixConstants.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.AccessRuleSet] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/AccessRuleSet.class] + [javac] [checking org.eclipse.jdt.internal.compiler.batch.ClasspathJar] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/util/zip/ZipException.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.class] + [javac] [checking org.eclipse.jdt.internal.compiler.batch.ClasspathSourceJar] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/batch/ClasspathSourceJar.class] + [javac] [checking org.eclipse.jdt.internal.compiler.batch.CompilationUnit] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/batch/CompilationUnit.class] + [javac] [checking org.eclipse.jdt.internal.compiler.batch.FileFinder] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/batch/FileFinder.class] + [javac] [checking org.eclipse.jdt.internal.compiler.batch.Main] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/BufferedReader.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/FileFilter.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/batch/Main$Logger.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/batch/Main$1.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/batch/Main$2.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/batch/Main$3.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/batch/Main.class] + [javac] [checking org.eclipse.jdt.internal.compiler.classfmt.AnnotationInfo] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/io/ByteArrayOutputStream.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationInfo.class] + [javac] [checking org.eclipse.jdt.internal.compiler.classfmt.ClassFileStruct] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileStruct.class] + [javac] [checking org.eclipse.jdt.internal.compiler.classfmt.ElementValuePairInfo] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/classfmt/ElementValuePairInfo.class] + [javac] [checking org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFormatException.class] + [javac] [checking org.eclipse.jdt.internal.compiler.classfmt.AnnotationMethodInfo] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationMethodInfo.class] + [javac] [checking org.eclipse.jdt.internal.compiler.classfmt.MethodInfo] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfo.class] + [javac] [checking org.eclipse.jdt.internal.compiler.classfmt.AnnotationMethodInfoWithAnnotations] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/classfmt/AnnotationMethodInfoWithAnnotations.class] + [javac] [checking org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.class] + [javac] [checking org.eclipse.jdt.internal.compiler.classfmt.FieldInfo] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/Byte.class)] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/Short.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfo.class] + [javac] [checking org.eclipse.jdt.internal.compiler.classfmt.InnerClassInfo] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/classfmt/InnerClassInfo.class] + [javac] [checking org.eclipse.jdt.internal.compiler.classfmt.FieldInfoWithAnnotation] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfoWithAnnotation.class] + [javac] [checking org.eclipse.jdt.internal.compiler.classfmt.MethodInfoWithAnnotations] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithAnnotations.class] + [javac] [checking org.eclipse.jdt.internal.compiler.classfmt.MethodInfoWithParameterAnnotations] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithParameterAnnotations.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/AttributeNamesConstants.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.CachedIndexEntry] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/CachedIndexEntry.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.FieldNameAndTypeCache] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/FieldNameAndTypeCache.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.MethodNameAndTypeCache] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/MethodNameAndTypeCache.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.Opcodes] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/Opcodes.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.StackMapFrame] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrame.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.VerificationTypeInfo] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/VerificationTypeInfo.class] + [javac] [checking org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.ClassSignature] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/ClassSignature.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.EnumConstantSignature] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/EnumConstantSignature.class] + [javac] [checking org.eclipse.jdt.internal.compiler.env.ISourceImport] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/env/ISourceImport.class] + [javac] [checking org.eclipse.jdt.internal.compiler.flow.ConditionalFlowInfo] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.class] + [javac] [checking org.eclipse.jdt.internal.compiler.flow.FinallyFlowContext] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.class] + [javac] [checking org.eclipse.jdt.internal.compiler.flow.InsideSubRoutineFlowContext] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/flow/InsideSubRoutineFlowContext.class] + [javac] [checking org.eclipse.jdt.internal.compiler.flow.LabelFlowContext] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/flow/LabelFlowContext.class] + [javac] [checking org.eclipse.jdt.internal.compiler.flow.SwitchFlowContext] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/flow/SwitchFlowContext.class] + [javac] [checking org.eclipse.jdt.internal.compiler.flow.LoopingFlowContext] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.class] + [javac] [checking org.eclipse.jdt.internal.compiler.impl.BooleanConstant] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/impl/BooleanConstant.class] + [javac] [checking org.eclipse.jdt.internal.compiler.impl.ByteConstant] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/impl/ByteConstant.class] + [javac] [checking org.eclipse.jdt.internal.compiler.impl.CharConstant] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/impl/CharConstant.class] + [javac] [checking org.eclipse.jdt.internal.compiler.impl.DoubleConstant] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/impl/DoubleConstant.class] + [javac] [checking org.eclipse.jdt.internal.compiler.impl.FloatConstant] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/impl/FloatConstant.class] + [javac] [checking org.eclipse.jdt.internal.compiler.impl.IntConstant] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/impl/IntConstant.class] + [javac] [checking org.eclipse.jdt.internal.compiler.impl.LongConstant] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/impl/LongConstant.class] + [javac] [checking org.eclipse.jdt.internal.compiler.impl.ShortConstant] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/impl/ShortConstant.class] + [javac] [checking org.eclipse.jdt.internal.compiler.impl.StringConstant] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/impl/StringConstant.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.CaptureBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/CaptureBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ExtraCompilerModifiers.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.ImportConflictBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ImportConflictBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.MethodVerifier15] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.ParameterizedFieldBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedFieldBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.ProblemBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemFieldBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemMethodBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.TagBits] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.UnresolvedAnnotationBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/UnresolvedAnnotationBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.lookup.UpdatedMethodBinding] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/lookup/UpdatedMethodBinding.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.RecoveredImport] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredImport.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.RecoveredUnit] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredUnit.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.ScannerHelper] + [javac] [loading /opt/sun-jdk-1.4.2.12/jre/lib/rt.jar(java/lang/NullPointerException.class)] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.diagnose.DiagnoseParser] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser$RepairCandidate.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser$PrimaryRepairInfo.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser$SecondaryRepairInfo.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser$StateInfo.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/DiagnoseParser.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.diagnose.LexStream] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/LexStream$Token.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/LexStream.class] + [javac] [checking org.eclipse.jdt.internal.compiler.parser.diagnose.RangeUtil] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/RangeUtil$RangeResult.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/parser/diagnose/RangeUtil.class] + [javac] [checking org.eclipse.jdt.internal.compiler.problem.AbortMethod] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/problem/AbortMethod.class] + [javac] [checking org.eclipse.jdt.internal.compiler.problem.AbortType] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/problem/AbortType.class] + [javac] [checking org.eclipse.jdt.internal.compiler.problem.DefaultProblem] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblem.class] + [javac] [checking org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblemFactory.class] + [javac] [checking org.eclipse.jdt.internal.compiler.util.HashtableOfInt] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfInt.class] + [javac] [checking org.eclipse.jdt.internal.compiler.problem.ShouldNotImplement] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/problem/ShouldNotImplement.class] + [javac] [checking org.eclipse.jdt.internal.compiler.util.FloatUtil] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/FloatUtil.class] + [javac] [checking org.eclipse.jdt.internal.compiler.util.HashtableOfIntValues] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfIntValues.class] + [javac] [checking org.eclipse.jdt.internal.compiler.util.HashtableOfLong] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfLong.class] + [javac] [checking org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObjectToInt.class] + [javac] [checking org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToIntArray] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObjectToIntArray.class] + [javac] [checking org.eclipse.jdt.internal.compiler.util.Messages] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/Messages$MessagesProperties.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/Messages.class] + [javac] [checking org.eclipse.jdt.internal.compiler.util.SimpleSet] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/SimpleSet.class] + [javac] [checking org.eclipse.jdt.internal.compiler.util.Util] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/Util$Displayable.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/Util$1.class] + [javac] [wrote /volatile/portage/eclipse-sdk-3.2/work/jdtcoresrc/compiler/org/eclipse/jdt/internal/compiler/util/Util.class] + [javac] [total 10900ms] + [echo] UPDATE ecj.jar + +BUILD SUCCESSFUL +Total time: 16 seconds + [echo] TARGET: compiler2 + [echo] compilerArg -encoding ISO-8859-1 + [echo] build compiler org.eclipse.jdt.core.JDTCompilerAdapter + [echo] UPDATE ecj.jar + +BUILD SUCCESSFUL +Total time: 13 seconds + [echo] Deleting jars to recompile... + [echo] Compiling... + [echo] Copying source from org.eclipse.swt project to folder /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.gtk.linux.ia64/src folder /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.gtk.linux.ia64/temp.folder. + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.gtk.linux.ia64/src/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java + [javac] (at line 1101) + [javac] Control control = null; + [javac] ^^^^^^^ + [javac] The local variable control is never read + [javac] ---------- + [javac] 1 problem (1 warning) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java + [javac] (at line 1101) + [javac] Control control = null; + [javac] ^^^^^^^ + [javac] The local variable control is never read + [javac] ---------- + [javac] 1 problem (1 warning) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java + [javac] (at line 1101) + [javac] Control control = null; + [javac] ^^^^^^^ + [javac] The local variable control is never read + [javac] ---------- + [javac] 1 problem (1 warning) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java + [javac] (at line 1101) + [javac] Control control = null; + [javac] ^^^^^^^ + [javac] The local variable control is never read + [javac] ---------- + [javac] 1 problem (1 warning) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java + [javac] (at line 1101) + [javac] Control control = null; + [javac] ^^^^^^^ + [javac] The local variable control is never read + [javac] ---------- + [javac] 1 problem (1 warning) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java + [javac] (at line 1449) + [javac] boolean noMoreElements = false; + [javac] ^^^^^^^^^^^^^^ + [javac] The field new Enumeration(){}.noMoreElements is never read locally + [javac] ---------- + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleRepository.java + [javac] (at line 38) + [javac] private PackageAdminImpl packageAdmin; + [javac] ^^^^^^^^^^^^ + [javac] The field BundleRepository.packageAdmin is never read locally + [javac] ---------- + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/FrameworkSecurityManager.java + [javac] (at line 30) + [javac] Class c; + [javac] ^ + [javac] The local variable c is never read + [javac] ---------- + [javac] ---------- + [javac] 4. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/SecurePermissionStorage.java + [javac] (at line 26) + [javac] private String[] infos; + [javac] ^^^^^ + [javac] The field SecurePermissionStorage.infos is never read locally + [javac] ---------- + [javac] ---------- + [javac] 5. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/StartLevelManager.java + [javac] (at line 701) + [javac] int bundlestate = bundle.getState(); + [javac] ^^^^^^^^^^^ + [javac] The local variable bundlestate is never read + [javac] ---------- + [javac] ---------- + [javac] 6. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/launcher/Launcher.java + [javac] (at line 242) + [javac] String cmd = tok.nextToken(); + [javac] ^^^ + [javac] The local variable cmd is never read + [javac] ---------- + [javac] 7. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/launcher/Launcher.java + [javac] (at line 258) + [javac] String cmd = tok.getToken(":"); //$NON-NLS-1$ + [javac] ^^^ + [javac] The local variable cmd is never read + [javac] ---------- + [javac] ---------- + [javac] 8. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/BaseData.java + [javac] (at line 97) + [javac] path = path = '/' + path; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] The assignment to variable path has no effect + [javac] ---------- + [javac] ---------- + [javac] 9. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/loader/ClasspathManager.java + [javac] (at line 42) + [javac] private static final int BUF_SIZE = 8 * 1024; + [javac] ^^^^^^^^ + [javac] The field ClasspathManager.BUF_SIZE is never read locally + [javac] ---------- + [javac] ---------- + [javac] 10. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseStarter.java + [javac] (at line 121) + [javac] private static final String CONTEXTCLASSLOADER_PARENT_CCL = "ccl"; //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] The field EclipseStarter.CONTEXTCLASSLOADER_PARENT_CCL is never read locally + [javac] ---------- + [javac] 11. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseStarter.java + [javac] (at line 124) + [javac] private static final String FILE_PROTOCOL = "file"; //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^ + [javac] The field EclipseStarter.FILE_PROTOCOL is never read locally + [javac] ---------- + [javac] 12. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseStarter.java + [javac] (at line 570) + [javac] URL child = new URL(name); + [javac] ^^^^^ + [javac] The local variable child is never read + [javac] ---------- + [javac] 13. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/adaptor/EclipseStarter.java + [javac] (at line 1305) + [javac] private static String buildCommandLine(String arg, String value) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] The method buildCommandLine(String, String) from the type EclipseStarter is never used locally + [javac] ---------- + [javac] 13 problems (13 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/PlatformConfiguration.java + [javac] (at line 34) + [javac] import org.eclipse.update.configurator.IPlatformConfiguration.ISitePolicy; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] The import org.eclipse.update.configurator.IPlatformConfiguration.ISitePolicy is never used + [javac] ---------- + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/VersionedIdentifier.java + [javac] (at line 16) + [javac] import org.osgi.framework.Version; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] The import org.osgi.framework.Version is never used + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/VersionedIdentifier.java + [javac] (at line 88) + [javac] private void parseVersion(String v) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] The method parseVersion(String) from the type VersionedIdentifier is never used locally + [javac] ---------- + [javac] 3 problems (3 warnings) + [echo] Copying source from org.eclipse.swt project to folder /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.gtk.linux.x86_64/src folder /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.gtk.linux.x86_64/temp.folder. + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.gtk.linux.x86_64/src/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java + [javac] (at line 1101) + [javac] Control control = null; + [javac] ^^^^^^^ + [javac] The local variable control is never read + [javac] ---------- + [javac] 1 problem (1 warning) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/src/org/eclipse/update/internal/core/FeaturePackagedContentProvider.java + [javac] (at line 386) + [javac] private ContentReference continueOrErrorOrRethrow(String archiveID, CoreException coreException) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] The method continueOrErrorOrRethrow(String, CoreException) from the type FeaturePackagedContentProvider is never used locally + [javac] ---------- + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/src/org/eclipse/update/internal/core/InstallConfiguration.java + [javac] (at line 54) + [javac] import org.eclipse.update.internal.configurator.IConfigurationConstants; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] The import org.eclipse.update.internal.configurator.IConfigurationConstants is never used + [javac] ---------- + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/src/org/eclipse/update/internal/core/JarDeltaInstallHandler.java + [javac] (at line 52) + [javac] ContentReference[] oldReferences = oldFeature.getFeatureContentProvider().getPluginEntryContentReferences(oldPlugin, null); + [javac] ^^^^^^^^^^^^^ + [javac] The local variable oldReferences is never read + [javac] ---------- + [javac] 4. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/src/org/eclipse/update/internal/core/JarDeltaInstallHandler.java + [javac] (at line 53) + [javac] ContentReference[] newReferences = feature.getFeatureContentProvider().getPluginEntryContentReferences(newPlugin, null); + [javac] ^^^^^^^^^^^^^ + [javac] The local variable newReferences is never read + [javac] ---------- + [javac] ---------- + [javac] 5. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/src/org/eclipse/update/search/UpdateSearchRequest.java + [javac] (at line 13) + [javac] import java.io.File; + [javac] ^^^^^^^^^^^^ + [javac] The import java.io.File is never used + [javac] ---------- + [javac] 5 problems (5 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/contentDescriber/AntBuildfileContentDescriber.java + [javac] (at line 20) + [javac] import org.eclipse.core.internal.content.XMLContentDescriber; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type XMLContentDescriber is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.core.contenttype/@dot + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/contentDescriber/AntBuildfileContentDescriber.java + [javac] (at line 44) + [javac] public final class AntBuildfileContentDescriber extends XMLContentDescriber implements IExecutableExtension { + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type XMLContentDescriber is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.core.contenttype/@dot + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/contentDescriber/AntBuildfileContentDescriber.java + [javac] (at line 90) + [javac] if (super.describe(contents, description) == INVALID) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method describe(InputStream, IContentDescription) from the type XMLContentDescriber is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.core.contenttype/@dot + [javac] ---------- + [javac] 4. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.core/src/org/eclipse/ant/internal/core/contentDescriber/AntBuildfileContentDescriber.java + [javac] (at line 104) + [javac] if (super.describe(contents, description) == INVALID) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method describe(Reader, IContentDescription) from the type XMLContentDescriber is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.core.contenttype/@dot + [javac] ---------- + [javac] 4 problems (4 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 21) + [javac] import org.eclipse.swt.internal.Callback; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type Callback is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 22) + [javac] import org.eclipse.swt.internal.carbon.HICommand; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type HICommand is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 23) + [javac] import org.eclipse.swt.internal.carbon.OS; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 4. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 150) + [javac] int windowHandle = OS.GetControlOwner(shell.handle); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method GetControlOwner(int) from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 5. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 150) + [javac] int windowHandle = OS.GetControlOwner(shell.handle); + [javac] ^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 6. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 151) + [javac] OS.ChangeWindowAttributes(windowHandle, + [javac] OS.kWindowToolbarButtonAttribute, 0); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method ChangeWindowAttributes(int, int, int) from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 7. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 151) + [javac] OS.ChangeWindowAttributes(windowHandle, + [javac] ^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 8. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 152) + [javac] OS.kWindowToolbarButtonAttribute, 0); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 9. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 152) + [javac] OS.kWindowToolbarButtonAttribute, 0); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field kWindowToolbarButtonAttribute from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 10. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 164) + [javac] int toolbarProc (int nextHandler, int theEvent, int userData) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] The method toolbarProc(int, int, int) from the type new Object(){} is never used locally + [javac] ---------- + [javac] 11. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 165) + [javac] int eventKind = OS.GetEventKind (theEvent); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method GetEventKind(int) from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 12. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 165) + [javac] int eventKind = OS.GetEventKind (theEvent); + [javac] ^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 13. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 166) + [javac] if (eventKind != OS.kEventWindowToolbarSwitchMode) + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 14. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 166) + [javac] if (eventKind != OS.kEventWindowToolbarSwitchMode) + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field kEventWindowToolbarSwitchMode from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 15. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 167) + [javac] return OS.eventNotHandledErr; + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 16. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 167) + [javac] return OS.eventNotHandledErr; + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field eventNotHandledErr from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 17. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 170) + [javac] OS.GetEventParameter (theEvent, OS.kEventParamDirectObject, OS.typeWindowRef, null, 4, null, theWindow); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method GetEventParameter(int, int, int, int[], int, int[], int[]) from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 18. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 170) + [javac] OS.GetEventParameter (theEvent, OS.kEventParamDirectObject, OS.typeWindowRef, null, 4, null, theWindow); + [javac] ^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 19. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 170) + [javac] OS.GetEventParameter (theEvent, OS.kEventParamDirectObject, OS.typeWindowRef, null, 4, null, theWindow); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 20. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 170) + [javac] OS.GetEventParameter (theEvent, OS.kEventParamDirectObject, OS.typeWindowRef, null, 4, null, theWindow); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field kEventParamDirectObject from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 21. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 170) + [javac] OS.GetEventParameter (theEvent, OS.kEventParamDirectObject, OS.typeWindowRef, null, 4, null, theWindow); + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 22. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 170) + [javac] OS.GetEventParameter (theEvent, OS.kEventParamDirectObject, OS.typeWindowRef, null, 4, null, theWindow); + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The field typeWindowRef from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 23. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 173) + [javac] OS.GetRootControl (theWindow [0], theRoot); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method GetRootControl(int, int[]) from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 24. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 173) + [javac] OS.GetRootControl (theWindow [0], theRoot); + [javac] ^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 25. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 177) + [javac] return OS.eventNotHandledErr; + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 26. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 177) + [javac] return OS.eventNotHandledErr; + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field eventNotHandledErr from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 27. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 190) + [javac] return OS.eventNotHandledErr; + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 28. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 190) + [javac] return OS.eventNotHandledErr; + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field eventNotHandledErr from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 29. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 203) + [javac] return OS.noErr; + [javac] ^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 30. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 203) + [javac] return OS.noErr; + [javac] ^^^^^ + [javac] Discouraged access: The field noErr from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 31. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 206) + [javac] return OS.eventNotHandledErr; + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 32. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 206) + [javac] return OS.eventNotHandledErr; + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field eventNotHandledErr from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 33. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 211) + [javac] final Callback commandCallback = new Callback(target, "toolbarProc", 3); //$NON-NLS-1$ + [javac] ^^^^^^^^ + [javac] Discouraged access: The type Callback is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 34. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 211) + [javac] final Callback commandCallback = new Callback(target, "toolbarProc", 3); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor Callback(Object, String, int) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 35. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 211) + [javac] final Callback commandCallback = new Callback(target, "toolbarProc", 3); //$NON-NLS-1$ + [javac] ^^^^^^^^ + [javac] Discouraged access: The type Callback is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 36. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 212) + [javac] int commandProc = commandCallback.getAddress(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getAddress() from the type Callback is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 37. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 214) + [javac] commandCallback.dispose(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method dispose() from the type Callback is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 38. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 218) + [javac] int[] mask = new int[] { OS.kEventClassWindow, OS.kEventWindowToolbarSwitchMode }; + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 39. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 218) + [javac] int[] mask = new int[] { OS.kEventClassWindow, OS.kEventWindowToolbarSwitchMode }; + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field kEventClassWindow from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 40. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 218) + [javac] int[] mask = new int[] { OS.kEventClassWindow, OS.kEventWindowToolbarSwitchMode }; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 41. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 218) + [javac] int[] mask = new int[] { OS.kEventClassWindow, OS.kEventWindowToolbarSwitchMode }; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field kEventWindowToolbarSwitchMode from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 42. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 219) + [javac] OS.InstallEventHandler(OS.GetApplicationEventTarget(), commandProc, + [javac] mask.length / 2, mask, 0, null); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method InstallEventHandler(int, int, int, int[], int, int[]) from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 43. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 219) + [javac] OS.InstallEventHandler(OS.GetApplicationEventTarget(), commandProc, + [javac] ^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 44. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 219) + [javac] OS.InstallEventHandler(OS.GetApplicationEventTarget(), commandProc, + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method GetApplicationEventTarget() from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 45. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 219) + [javac] OS.InstallEventHandler(OS.GetApplicationEventTarget(), commandProc, + [javac] ^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 46. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 231) + [javac] int commandProc(int nextHandler, int theEvent, int userData) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] The method commandProc(int, int, int) from the type new Object(){} is never used locally + [javac] ---------- + [javac] 47. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 232) + [javac] if (OS.GetEventKind(theEvent) == OS.kEventProcessCommand) { + [javac] ^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 48. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 232) + [javac] if (OS.GetEventKind(theEvent) == OS.kEventProcessCommand) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method GetEventKind(int) from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 49. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 232) + [javac] if (OS.GetEventKind(theEvent) == OS.kEventProcessCommand) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 50. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 232) + [javac] if (OS.GetEventKind(theEvent) == OS.kEventProcessCommand) { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field kEventProcessCommand from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 51. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 233) + [javac] HICommand command = new HICommand(); + [javac] ^^^^^^^^^ + [javac] Discouraged access: The type HICommand is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 52. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 233) + [javac] HICommand command = new HICommand(); + [javac] ^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor HICommand() is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 53. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 233) + [javac] HICommand command = new HICommand(); + [javac] ^^^^^^^^^ + [javac] Discouraged access: The type HICommand is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 54. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 234) + [javac] OS.GetEventParameter(theEvent, OS.kEventParamDirectObject, + [javac] OS.typeHICommand, null, HICommand.sizeof, null, command); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method GetEventParameter(int, int, int, int[], int, int[], HICommand) from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 55. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 234) + [javac] OS.GetEventParameter(theEvent, OS.kEventParamDirectObject, + [javac] ^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 56. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 234) + [javac] OS.GetEventParameter(theEvent, OS.kEventParamDirectObject, + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 57. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 234) + [javac] OS.GetEventParameter(theEvent, OS.kEventParamDirectObject, + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field kEventParamDirectObject from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 58. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 235) + [javac] OS.typeHICommand, null, HICommand.sizeof, null, command); + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 59. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 235) + [javac] OS.typeHICommand, null, HICommand.sizeof, null, command); + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The field typeHICommand from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 60. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 235) + [javac] OS.typeHICommand, null, HICommand.sizeof, null, command); + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type HICommand is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 61. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 235) + [javac] OS.typeHICommand, null, HICommand.sizeof, null, command); + [javac] ^^^^^^ + [javac] Discouraged access: The field sizeof from the type HICommand is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 62. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 236) + [javac] switch (command.commandID) { + [javac] ^^^^^^^^^ + [javac] Discouraged access: The field commandID from the type HICommand is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 63. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 245) + [javac] return OS.eventNotHandledErr; + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 64. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 245) + [javac] return OS.eventNotHandledErr; + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field eventNotHandledErr from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 65. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 249) + [javac] final Callback commandCallback = new Callback(target, "commandProc", 3); //$NON-NLS-1$ + [javac] ^^^^^^^^ + [javac] Discouraged access: The type Callback is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 66. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 249) + [javac] final Callback commandCallback = new Callback(target, "commandProc", 3); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor Callback(Object, String, int) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 67. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 249) + [javac] final Callback commandCallback = new Callback(target, "commandProc", 3); //$NON-NLS-1$ + [javac] ^^^^^^^^ + [javac] Discouraged access: The type Callback is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 68. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 250) + [javac] int commandProc = commandCallback.getAddress(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getAddress() from the type Callback is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 69. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 252) + [javac] commandCallback.dispose(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method dispose() from the type Callback is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 70. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 257) + [javac] int[] mask = new int[] { OS.kEventClassCommand, OS.kEventProcessCommand }; + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 71. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 257) + [javac] int[] mask = new int[] { OS.kEventClassCommand, OS.kEventProcessCommand }; + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field kEventClassCommand from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 72. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 257) + [javac] int[] mask = new int[] { OS.kEventClassCommand, OS.kEventProcessCommand }; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 73. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 257) + [javac] int[] mask = new int[] { OS.kEventClassCommand, OS.kEventProcessCommand }; + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field kEventProcessCommand from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 74. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 258) + [javac] OS.InstallEventHandler(OS.GetApplicationEventTarget(), commandProc, + [javac] mask.length / 2, mask, 0, null); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method InstallEventHandler(int, int, int, int[], int, int[]) from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 75. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 258) + [javac] OS.InstallEventHandler(OS.GetApplicationEventTarget(), commandProc, + [javac] ^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 76. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 258) + [javac] OS.InstallEventHandler(OS.GetApplicationEventTarget(), commandProc, + [javac] ^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 77. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 258) + [javac] OS.InstallEventHandler(OS.GetApplicationEventTarget(), commandProc, + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method GetApplicationEventTarget() from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 78. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 264) + [javac] if (OS.GetIndMenuItemWithCommandID(0, kHICommandPreferences, 1, outMenu, outIndex) == OS.noErr + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method GetIndMenuItemWithCommandID(int, int, int, int[], short[]) from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 79. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 264) + [javac] if (OS.GetIndMenuItemWithCommandID(0, kHICommandPreferences, 1, outMenu, outIndex) == OS.noErr + [javac] ^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 80. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 264) + [javac] if (OS.GetIndMenuItemWithCommandID(0, kHICommandPreferences, 1, outMenu, outIndex) == OS.noErr + [javac] ^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 81. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 264) + [javac] if (OS.GetIndMenuItemWithCommandID(0, kHICommandPreferences, 1, outMenu, outIndex) == OS.noErr + [javac] ^^^^^ + [javac] Discouraged access: The field noErr from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 82. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 271) + [javac] int str = OS.CFStringCreateWithCharacters(OS.kCFAllocatorDefault, buffer, l); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method CFStringCreateWithCharacters(int, char[], int) from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 83. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 271) + [javac] int str = OS.CFStringCreateWithCharacters(OS.kCFAllocatorDefault, buffer, l); + [javac] ^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 84. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 271) + [javac] int str = OS.CFStringCreateWithCharacters(OS.kCFAllocatorDefault, buffer, l); + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 85. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 271) + [javac] int str = OS.CFStringCreateWithCharacters(OS.kCFAllocatorDefault, buffer, l); + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field kCFAllocatorDefault from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 86. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 272) + [javac] OS.InsertMenuItemTextWithCFString(menu, str, (short) 0, 0, kHICommandAbout); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method InsertMenuItemTextWithCFString(int, int, short, int, int) from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 87. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 272) + [javac] OS.InsertMenuItemTextWithCFString(menu, str, (short) 0, 0, kHICommandAbout); + [javac] ^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 88. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 273) + [javac] OS.CFRelease(str); + [javac] ^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 89. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 273) + [javac] OS.CFRelease(str); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method CFRelease(int) from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 90. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 276) + [javac] OS.InsertMenuItemTextWithCFString(menu, 0, (short) 1, OS.kMenuItemAttrSeparator, 0); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method InsertMenuItemTextWithCFString(int, int, short, int, int) from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 91. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 276) + [javac] OS.InsertMenuItemTextWithCFString(menu, 0, (short) 1, OS.kMenuItemAttrSeparator, 0); + [javac] ^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 92. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 276) + [javac] OS.InsertMenuItemTextWithCFString(menu, 0, (short) 1, OS.kMenuItemAttrSeparator, 0); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 93. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 276) + [javac] OS.InsertMenuItemTextWithCFString(menu, 0, (short) 1, OS.kMenuItemAttrSeparator, 0); + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field kMenuItemAttrSeparator from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 94. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 279) + [javac] OS.EnableMenuCommand(menu, kHICommandPreferences); + [javac] ^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 95. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 279) + [javac] OS.EnableMenuCommand(menu, kHICommandPreferences); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method EnableMenuCommand(int, int) from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 96. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 282) + [javac] OS.DisableMenuCommand(menu, kHICommandServices); + [javac] ^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 97. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 282) + [javac] OS.DisableMenuCommand(menu, kHICommandServices); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method DisableMenuCommand(int, int) from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 98. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 288) + [javac] commandCallback.dispose(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method dispose() from the type Callback is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 99. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 315) + [javac] return OS.noErr; + [javac] ^^^^^^^^ + [javac] Discouraged access: The type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 100. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.carbon/src/org/eclipse/ui/carbon/CarbonUIEnhancer.java + [javac] (at line 315) + [javac] return OS.noErr; + [javac] ^^^^^ + [javac] Discouraged access: The field noErr from the type OS is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.swt.carbon.macosx/@dot + [javac] ---------- + [javac] 100 problems (100 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ReviewPage.java + [javac] (at line 73) + [javac] import org.eclipse.update.internal.core.ExtendedSite; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] The import org.eclipse.update.internal.core.ExtendedSite is never used + [javac] ---------- + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.ui/src/org/eclipse/update/internal/ui/wizards/ShowActivitiesDialog.java + [javac] (at line 106) + [javac] url.setText(((InstallConfiguration)SiteManager.getLocalSite().getCurrentConfiguration()).getURL().getFile()); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getURL() from the type InstallConfigurationModel is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 2 problems (2 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java + [javac] (at line 154) + [javac] import org.eclipse.ui.internal.EditorPluginAction; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type EditorPluginAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java + [javac] (at line 4080) + [javac] return new EditorPluginAction(element, this, defId, IAction.AS_UNSPECIFIED); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor EditorPluginAction(IConfigurationElement, IEditorPart, String, int) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java + [javac] (at line 4080) + [javac] return new EditorPluginAction(element, this, defId, IAction.AS_UNSPECIFIED); + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type EditorPluginAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 3 problems (3 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/CopyProjectAction.java + [javac] (at line 35) + [javac] import org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/CopyProjectAction.java + [javac] (at line 190) + [javac] new ProgressMonitorJobsDialog(shell).run(true, true, op); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor ProgressMonitorJobsDialog(Shell) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/CopyProjectAction.java + [javac] (at line 190) + [javac] new ProgressMonitorJobsDialog(shell).run(true, true, op); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method run(boolean, boolean, IRunnableWithProgress) from the type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 4. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/CopyProjectAction.java + [javac] (at line 190) + [javac] new ProgressMonitorJobsDialog(shell).run(true, true, op); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] ---------- + [javac] 5. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/CopyProjectOperation.java + [javac] (at line 37) + [javac] import org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 6. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/CopyProjectOperation.java + [javac] (at line 160) + [javac] new ProgressMonitorJobsDialog(parentShell).run(true, true, op); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor ProgressMonitorJobsDialog(Shell) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 7. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/CopyProjectOperation.java + [javac] (at line 160) + [javac] new ProgressMonitorJobsDialog(parentShell).run(true, true, op); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method run(boolean, boolean, IRunnableWithProgress) from the type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 8. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/CopyProjectOperation.java + [javac] (at line 160) + [javac] new ProgressMonitorJobsDialog(parentShell).run(true, true, op); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] ---------- + [javac] 9. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/MoveProjectAction.java + [javac] (at line 34) + [javac] import org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 10. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/MoveProjectAction.java + [javac] (at line 115) + [javac] new ProgressMonitorJobsDialog(shell).run(true, true, op); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor ProgressMonitorJobsDialog(Shell) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 11. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/MoveProjectAction.java + [javac] (at line 115) + [javac] new ProgressMonitorJobsDialog(shell).run(true, true, op); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method run(boolean, boolean, IRunnableWithProgress) from the type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 12. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/MoveProjectAction.java + [javac] (at line 115) + [javac] new ProgressMonitorJobsDialog(shell).run(true, true, op); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] ---------- + [javac] 13. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewExampleAction.java + [javac] (at line 24) + [javac] import org.eclipse.ui.internal.dialogs.NewWizard; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type NewWizard is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 14. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewExampleAction.java + [javac] (at line 28) + [javac] import org.eclipse.ui.internal.registry.WizardsRegistryReader; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type WizardsRegistryReader is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 15. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewExampleAction.java + [javac] (at line 90) + [javac] NewWizard wizard = new NewWizard(); + [javac] ^^^^^^^^^ + [javac] Discouraged access: The type NewWizard is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 16. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewExampleAction.java + [javac] (at line 90) + [javac] NewWizard wizard = new NewWizard(); + [javac] ^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor NewWizard() is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 17. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewExampleAction.java + [javac] (at line 90) + [javac] NewWizard wizard = new NewWizard(); + [javac] ^^^^^^^^^ + [javac] Discouraged access: The type NewWizard is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 18. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewExampleAction.java + [javac] (at line 91) + [javac] wizard + [javac] .setCategoryId(WizardsRegistryReader.FULL_EXAMPLES_WIZARD_CATEGORY); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setCategoryId(String) from the type NewWizard is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 19. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewExampleAction.java + [javac] (at line 92) + [javac] .setCategoryId(WizardsRegistryReader.FULL_EXAMPLES_WIZARD_CATEGORY); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type WizardsRegistryReader is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 20. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewExampleAction.java + [javac] (at line 92) + [javac] .setCategoryId(WizardsRegistryReader.FULL_EXAMPLES_WIZARD_CATEGORY); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field FULL_EXAMPLES_WIZARD_CATEGORY from the type WizardsRegistryReader is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 21. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewExampleAction.java + [javac] (at line 99) + [javac] wizard.init(workbench, selectionToPass); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method init(IWorkbench, IStructuredSelection) from the type NewWizard is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] ---------- + [javac] 22. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewProjectAction.java + [javac] (at line 23) + [javac] import org.eclipse.ui.internal.dialogs.NewWizard; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type NewWizard is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 23. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewProjectAction.java + [javac] (at line 88) + [javac] NewWizard wizard = new NewWizard(); + [javac] ^^^^^^^^^ + [javac] Discouraged access: The type NewWizard is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 24. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewProjectAction.java + [javac] (at line 88) + [javac] NewWizard wizard = new NewWizard(); + [javac] ^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor NewWizard() is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 25. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewProjectAction.java + [javac] (at line 88) + [javac] NewWizard wizard = new NewWizard(); + [javac] ^^^^^^^^^ + [javac] Discouraged access: The type NewWizard is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 26. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewProjectAction.java + [javac] (at line 89) + [javac] wizard.setProjectsOnly(true); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setProjectsOnly(boolean) from the type NewWizard is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 27. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewProjectAction.java + [javac] (at line 95) + [javac] wizard.init(workbench, selectionToPass); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method init(IWorkbench, IStructuredSelection) from the type NewWizard is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] ---------- + [javac] 28. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewWizardMenu.java + [javac] (at line 22) + [javac] import org.eclipse.ui.internal.registry.WizardsRegistryReader; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type WizardsRegistryReader is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 29. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewWizardMenu.java + [javac] (at line 117) + [javac] return registryHasCategory(WizardsRegistryReader.FULL_EXAMPLES_WIZARD_CATEGORY); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type WizardsRegistryReader is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 30. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/NewWizardMenu.java + [javac] (at line 117) + [javac] return registryHasCategory(WizardsRegistryReader.FULL_EXAMPLES_WIZARD_CATEGORY); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field FULL_EXAMPLES_WIZARD_CATEGORY from the type WizardsRegistryReader is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] ---------- + [javac] 31. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/WorkspaceAction.java + [javac] (at line 37) + [javac] import org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 32. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/WorkspaceAction.java + [javac] (at line 298) + [javac] new ProgressMonitorJobsDialog(shell).run(true, true, op); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor ProgressMonitorJobsDialog(Shell) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 33. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/WorkspaceAction.java + [javac] (at line 298) + [javac] new ProgressMonitorJobsDialog(shell).run(true, true, op); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method run(boolean, boolean, IRunnableWithProgress) from the type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 34. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/actions/WorkspaceAction.java + [javac] (at line 298) + [javac] new ProgressMonitorJobsDialog(shell).run(true, true, op); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] ---------- + [javac] 35. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/dialogs/NewFolderDialog.java + [javac] (at line 60) + [javac] import org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 36. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/dialogs/NewFolderDialog.java + [javac] (at line 289) + [javac] new ProgressMonitorJobsDialog(getShell()) + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor ProgressMonitorJobsDialog(Shell) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 37. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/dialogs/NewFolderDialog.java + [javac] (at line 289) + [javac] new ProgressMonitorJobsDialog(getShell()) + [javac] .run(true, true, operation); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method run(boolean, boolean, IRunnableWithProgress) from the type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 38. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/extensions/org/eclipse/ui/dialogs/NewFolderDialog.java + [javac] (at line 289) + [javac] new ProgressMonitorJobsDialog(getShell()) + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] ---------- + [javac] 39. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/ide/IDE.java + [javac] (at line 58) + [javac] import org.eclipse.ui.internal.misc.UIStats; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type UIStats is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 40. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/ide/IDE.java + [javac] (at line 988) + [javac] UIStats.start(UIStats.CONTENT_TYPE_LOOKUP, file.getName()); + [javac] ^^^^^^^ + [javac] Discouraged access: The type UIStats is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 41. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/ide/IDE.java + [javac] (at line 988) + [javac] UIStats.start(UIStats.CONTENT_TYPE_LOOKUP, file.getName()); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method start(int, String) from the type UIStats is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 42. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/ide/IDE.java + [javac] (at line 988) + [javac] UIStats.start(UIStats.CONTENT_TYPE_LOOKUP, file.getName()); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type UIStats is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 43. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/ide/IDE.java + [javac] (at line 988) + [javac] UIStats.start(UIStats.CONTENT_TYPE_LOOKUP, file.getName()); + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field CONTENT_TYPE_LOOKUP from the type UIStats is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 44. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/ide/IDE.java + [javac] (at line 997) + [javac] UIStats.end(UIStats.CONTENT_TYPE_LOOKUP, file, file.getName()); + [javac] ^^^^^^^ + [javac] Discouraged access: The type UIStats is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 45. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/ide/IDE.java + [javac] (at line 997) + [javac] UIStats.end(UIStats.CONTENT_TYPE_LOOKUP, file, file.getName()); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method end(int, Object, String) from the type UIStats is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 46. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/ide/IDE.java + [javac] (at line 997) + [javac] UIStats.end(UIStats.CONTENT_TYPE_LOOKUP, file, file.getName()); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type UIStats is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 47. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/ide/IDE.java + [javac] (at line 997) + [javac] UIStats.end(UIStats.CONTENT_TYPE_LOOKUP, file, file.getName()); + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field CONTENT_TYPE_LOOKUP from the type UIStats is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 48. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/ide/IDE.java + [javac] (at line 1012) + [javac] UIStats.start(UIStats.CONTENT_TYPE_LOOKUP, fileName); + [javac] ^^^^^^^ + [javac] Discouraged access: The type UIStats is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 49. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/ide/IDE.java + [javac] (at line 1012) + [javac] UIStats.start(UIStats.CONTENT_TYPE_LOOKUP, fileName); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method start(int, String) from the type UIStats is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 50. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/ide/IDE.java + [javac] (at line 1012) + [javac] UIStats.start(UIStats.CONTENT_TYPE_LOOKUP, fileName); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type UIStats is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 51. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/ide/IDE.java + [javac] (at line 1012) + [javac] UIStats.start(UIStats.CONTENT_TYPE_LOOKUP, fileName); + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field CONTENT_TYPE_LOOKUP from the type UIStats is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 52. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/ide/IDE.java + [javac] (at line 1018) + [javac] UIStats.end(UIStats.CONTENT_TYPE_LOOKUP, file, fileName); + [javac] ^^^^^^^ + [javac] Discouraged access: The type UIStats is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 53. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/ide/IDE.java + [javac] (at line 1018) + [javac] UIStats.end(UIStats.CONTENT_TYPE_LOOKUP, file, fileName); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method end(int, Object, String) from the type UIStats is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 54. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/ide/IDE.java + [javac] (at line 1018) + [javac] UIStats.end(UIStats.CONTENT_TYPE_LOOKUP, file, fileName); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type UIStats is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 55. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/ide/IDE.java + [javac] (at line 1018) + [javac] UIStats.end(UIStats.CONTENT_TYPE_LOOKUP, file, fileName); + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field CONTENT_TYPE_LOOKUP from the type UIStats is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] ---------- + [javac] 56. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchAdvisor.java + [javac] (at line 59) + [javac] import org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 57. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchAdvisor.java + [javac] (at line 374) + [javac] new ProgressMonitorJobsDialog(null).run(true, false, runnable); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor ProgressMonitorJobsDialog(Shell) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 58. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchAdvisor.java + [javac] (at line 374) + [javac] new ProgressMonitorJobsDialog(null).run(true, false, runnable); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method run(boolean, boolean, IRunnableWithProgress) from the type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 59. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchAdvisor.java + [javac] (at line 374) + [javac] new ProgressMonitorJobsDialog(null).run(true, false, runnable); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] ---------- + [javac] 60. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/WorkbenchActionBuilder.java + [javac] (at line 32) + [javac] import org.eclipse.jface.internal.provisional.action.IToolBarContributionItem; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IToolBarContributionItem is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jface/@dot + [javac] ---------- + [javac] 61. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/WorkbenchActionBuilder.java + [javac] (at line 56) + [javac] import org.eclipse.ui.internal.provisional.application.IActionBarConfigurer2; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IActionBarConfigurer2 is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 62. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/WorkbenchActionBuilder.java + [javac] (at line 362) + [javac] IActionBarConfigurer2 actionBarConfigurer = (IActionBarConfigurer2) getActionBarConfigurer(); + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IActionBarConfigurer2 is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 63. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/WorkbenchActionBuilder.java + [javac] (at line 362) + [javac] IActionBarConfigurer2 actionBarConfigurer = (IActionBarConfigurer2) getActionBarConfigurer(); + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IActionBarConfigurer2 is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 64. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/WorkbenchActionBuilder.java + [javac] (at line 371) + [javac] IToolBarManager fileToolBar = actionBarConfigurer.createToolBarManager(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createToolBarManager() from the type IActionBarConfigurer2 is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 65. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/WorkbenchActionBuilder.java + [javac] (at line 392) + [javac] coolBar.add(actionBarConfigurer.createToolBarContributionItem(fileToolBar, + [javac] IWorkbenchActionConstants.TOOLBAR_FILE)); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createToolBarContributionItem(IToolBarManager, String) from the type IActionBarConfigurer2 is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 66. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/WorkbenchActionBuilder.java + [javac] (at line 400) + [javac] IToolBarManager navToolBar = actionBarConfigurer.createToolBarManager(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createToolBarManager() from the type IActionBarConfigurer2 is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 67. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/WorkbenchActionBuilder.java + [javac] (at line 411) + [javac] coolBar.add(actionBarConfigurer.createToolBarContributionItem(navToolBar, + [javac] IWorkbenchActionConstants.TOOLBAR_NAVIGATE)); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createToolBarContributionItem(IToolBarManager, String) from the type IActionBarConfigurer2 is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 68. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/WorkbenchActionBuilder.java + [javac] (at line 420) + [javac] IToolBarManager helpToolBar = actionBarConfigurer.createToolBarManager(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createToolBarManager() from the type IActionBarConfigurer2 is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 69. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/WorkbenchActionBuilder.java + [javac] (at line 426) + [javac] coolBar.add(actionBarConfigurer.createToolBarContributionItem(helpToolBar, + [javac] IWorkbenchActionConstants.TOOLBAR_HELP)); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createToolBarContributionItem(IToolBarManager, String) from the type IActionBarConfigurer2 is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 70. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/WorkbenchActionBuilder.java + [javac] (at line 1580) + [javac] if (!(cbItem instanceof IToolBarContributionItem)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IToolBarContributionItem is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jface/@dot + [javac] ---------- + [javac] 71. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/WorkbenchActionBuilder.java + [javac] (at line 1585) + [javac] IToolBarContributionItem toolBarItem = (IToolBarContributionItem) cbItem; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IToolBarContributionItem is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jface/@dot + [javac] ---------- + [javac] 72. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/WorkbenchActionBuilder.java + [javac] (at line 1585) + [javac] IToolBarContributionItem toolBarItem = (IToolBarContributionItem) cbItem; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IToolBarContributionItem is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jface/@dot + [javac] ---------- + [javac] 73. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/WorkbenchActionBuilder.java + [javac] (at line 1586) + [javac] IToolBarManager toolBarManager = toolBarItem.getToolBarManager(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getToolBarManager() from the type IToolBarContributionItem is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jface/@dot + [javac] ---------- + [javac] 74. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/WorkbenchActionBuilder.java + [javac] (at line 1628) + [javac] if (!(cbItem instanceof IToolBarContributionItem)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IToolBarContributionItem is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jface/@dot + [javac] ---------- + [javac] 75. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/WorkbenchActionBuilder.java + [javac] (at line 1634) + [javac] IToolBarContributionItem toolBarItem = (IToolBarContributionItem) cbItem; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IToolBarContributionItem is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jface/@dot + [javac] ---------- + [javac] 76. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/WorkbenchActionBuilder.java + [javac] (at line 1634) + [javac] IToolBarContributionItem toolBarItem = (IToolBarContributionItem) cbItem; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IToolBarContributionItem is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jface/@dot + [javac] ---------- + [javac] 77. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/WorkbenchActionBuilder.java + [javac] (at line 1635) + [javac] IToolBarManager toolBarManager = toolBarItem.getToolBarManager(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getToolBarManager() from the type IToolBarContributionItem is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jface/@dot + [javac] ---------- + [javac] ---------- + [javac] 78. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEEditorsPreferencePage.java + [javac] (at line 18) + [javac] import org.eclipse.ui.internal.dialogs.EditorsPreferencePage; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type EditorsPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 79. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEEditorsPreferencePage.java + [javac] (at line 28) + [javac] public class IDEEditorsPreferencePage extends EditorsPreferencePage { + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type EditorsPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 80. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEEditorsPreferencePage.java + [javac] (at line 31) + [javac] Composite composite = createComposite(parent); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createComposite(Composite) from the type EditorsPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 81. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEEditorsPreferencePage.java + [javac] (at line 54) + [javac] createEditorHistoryGroup(composite); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createEditorHistoryGroup(Composite) from the type EditorsPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 82. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEEditorsPreferencePage.java + [javac] (at line 56) + [javac] createSpace(composite); + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createSpace(Composite) from the type EditorsPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 83. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEEditorsPreferencePage.java + [javac] (at line 57) + [javac] createShowMultipleEditorTabsPref(composite); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createShowMultipleEditorTabsPref(Composite) from the type EditorsPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 84. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEEditorsPreferencePage.java + [javac] (at line 58) + [javac] createEditorReuseGroup(composite); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createEditorReuseGroup(Composite) from the type EditorsPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 85. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEEditorsPreferencePage.java + [javac] (at line 62) + [javac] super.setHelpContext(parent); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setHelpContext(Composite) from the type EditorsPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] ---------- + [javac] 86. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEPerspectivesPreferencePage.java + [javac] (at line 20) + [javac] import org.eclipse.ui.internal.dialogs.PerspectivesPreferencePage; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type PerspectivesPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 87. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEPerspectivesPreferencePage.java + [javac] (at line 32) + [javac] public class IDEPerspectivesPreferencePage extends PerspectivesPreferencePage { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type PerspectivesPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 88. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEPerspectivesPreferencePage.java + [javac] (at line 56) + [javac] Composite composite = createComposite(parent); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createComposite(Composite) from the type PerspectivesPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 89. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEPerspectivesPreferencePage.java + [javac] (at line 58) + [javac] createOpenPerspButtonGroup(composite); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createOpenPerspButtonGroup(Composite) from the type PerspectivesPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 90. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEPerspectivesPreferencePage.java + [javac] (at line 59) + [javac] createOpenViewButtonGroup(composite); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createOpenViewButtonGroup(Composite) from the type PerspectivesPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 91. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEPerspectivesPreferencePage.java + [javac] (at line 61) + [javac] createCustomizePerspective(composite); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createCustomizePerspective(Composite) from the type PerspectivesPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 92. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEPerspectivesPreferencePage.java + [javac] (at line 103) + [javac] super.performDefaults(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method performDefaults() from the type PerspectivesPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 93. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEPerspectivesPreferencePage.java + [javac] (at line 114) + [javac] return super.performOk(); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method performOk() from the type PerspectivesPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] ---------- + [javac] 94. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEStartupPreferencePage.java + [javac] (at line 23) + [javac] import org.eclipse.ui.internal.dialogs.StartupPreferencePage; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StartupPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 95. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEStartupPreferencePage.java + [javac] (at line 36) + [javac] public class IDEStartupPreferencePage extends StartupPreferencePage implements + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StartupPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 96. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEStartupPreferencePage.java + [javac] (at line 55) + [javac] Composite composite = createComposite(parent); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createComposite(Composite) from the type StartupPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 97. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEStartupPreferencePage.java + [javac] (at line 64) + [javac] createEarlyStartupSelection(composite); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createEarlyStartupSelection(Composite) from the type StartupPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 98. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEStartupPreferencePage.java + [javac] (at line 84) + [javac] super.performDefaults(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method performDefaults() from the type StartupPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 99. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEStartupPreferencePage.java + [javac] (at line 111) + [javac] return super.performOk(); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method performOk() from the type StartupPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] ---------- + [javac] 100. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEWorkbenchPreferencePage.java + [javac] (at line 19) + [javac] import org.eclipse.ui.internal.dialogs.WorkbenchPreferencePage; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type WorkbenchPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 101. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEWorkbenchPreferencePage.java + [javac] (at line 28) + [javac] public class IDEWorkbenchPreferencePage extends WorkbenchPreferencePage + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type WorkbenchPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 102. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEWorkbenchPreferencePage.java + [javac] (at line 41) + [javac] Composite composite = createComposite(parent); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createComposite(Composite) from the type WorkbenchPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 103. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEWorkbenchPreferencePage.java + [javac] (at line 43) + [javac] createShowUserDialogPref(composite); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createShowUserDialogPref(Composite) from the type WorkbenchPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 104. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEWorkbenchPreferencePage.java + [javac] (at line 44) + [javac] createStickyCyclePref(composite); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createStickyCyclePref(Composite) from the type WorkbenchPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 105. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEWorkbenchPreferencePage.java + [javac] (at line 45) + [javac] createHeapStatusPref(composite); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createHeapStatusPref(Composite) from the type WorkbenchPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 106. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEWorkbenchPreferencePage.java + [javac] (at line 47) + [javac] createOpenModeGroup(composite); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createOpenModeGroup(Composite) from the type WorkbenchPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 107. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEWorkbenchPreferencePage.java + [javac] (at line 66) + [javac] super.performDefaults(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method performDefaults() from the type WorkbenchPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 108. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/IDEWorkbenchPreferencePage.java + [javac] (at line 73) + [javac] return super.performOk(); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method performOk() from the type WorkbenchPreferencePage is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] ---------- + [javac] 109. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/ProjectReferencePage.java + [javac] (at line 47) + [javac] import org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 110. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/ProjectReferencePage.java + [javac] (at line 245) + [javac] new ProgressMonitorJobsDialog(getControl().getShell()).run(true, + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor ProgressMonitorJobsDialog(Shell) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 111. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/ProjectReferencePage.java + [javac] (at line 245) + [javac] new ProgressMonitorJobsDialog(getControl().getShell()).run(true, + [javac] true, runnable); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method run(boolean, boolean, IRunnableWithProgress) from the type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 112. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/dialogs/ProjectReferencePage.java + [javac] (at line 245) + [javac] new ProgressMonitorJobsDialog(getControl().getShell()).run(true, + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] ---------- + [javac] 113. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/wizards/datatransfer/WizardFileSystemResourceImportPage1.java + [javac] (at line 60) + [javac] import org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 114. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/wizards/datatransfer/WizardFileSystemResourceImportPage1.java + [javac] (at line 818) + [javac] ProgressMonitorDialog dialog = new ProgressMonitorJobsDialog( + [javac] getContainer().getShell()); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor ProgressMonitorJobsDialog(Shell) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 115. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/internal/wizards/datatransfer/WizardFileSystemResourceImportPage1.java + [javac] (at line 818) + [javac] ProgressMonitorDialog dialog = new ProgressMonitorJobsDialog( + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ProgressMonitorJobsDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] ---------- + [javac] 116. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/wizards/newresource/BasicNewProjectResourceWizard.java + [javac] (at line 66) + [javac] import org.eclipse.ui.internal.registry.PerspectiveDescriptor; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type PerspectiveDescriptor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 117. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/wizards/newresource/BasicNewProjectResourceWizard.java + [javac] (at line 530) + [javac] PerspectiveDescriptor descriptor = ((PerspectiveDescriptor) perspectives[i]); + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type PerspectiveDescriptor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 118. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/wizards/newresource/BasicNewProjectResourceWizard.java + [javac] (at line 530) + [javac] PerspectiveDescriptor descriptor = ((PerspectiveDescriptor) perspectives[i]); + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type PerspectiveDescriptor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 119. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/wizards/newresource/BasicNewProjectResourceWizard.java + [javac] (at line 531) + [javac] if (descriptor.getOriginalId().equals(id)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getOriginalId() from the type PerspectiveDescriptor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 120. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/src/org/eclipse/ui/wizards/newresource/BasicNewProjectResourceWizard.java + [javac] (at line 532) + [javac] perspectiveIds.add(descriptor.getId()); + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getId() from the type PerspectiveDescriptor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 120 problems (120 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/ResourceMgmtActionProvider.java + [javac] (at line 33) + [javac] import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDEWorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/ResourceMgmtActionProvider.java + [javac] (at line 34) + [javac] import org.eclipse.ui.internal.ide.actions.CloseUnrelatedProjectsAction; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type CloseUnrelatedProjectsAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/ResourceMgmtActionProvider.java + [javac] (at line 51) + [javac] private CloseUnrelatedProjectsAction closeUnrelatedProjectsAction; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type CloseUnrelatedProjectsAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 4. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/ResourceMgmtActionProvider.java + [javac] (at line 188) + [javac] closeUnrelatedProjectsAction = new CloseUnrelatedProjectsAction(shell); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor CloseUnrelatedProjectsAction(Shell) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 5. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/ResourceMgmtActionProvider.java + [javac] (at line 188) + [javac] closeUnrelatedProjectsAction = new CloseUnrelatedProjectsAction(shell); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type CloseUnrelatedProjectsAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 6. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/ResourceMgmtActionProvider.java + [javac] (at line 206) + [javac] return IDEWorkbenchPlugin.getIDEImageDescriptor(relativePath); + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDEWorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 7. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.navigator.resources/src/org/eclipse/ui/internal/navigator/resources/actions/ResourceMgmtActionProvider.java + [javac] (at line 206) + [javac] return IDEWorkbenchPlugin.getIDEImageDescriptor(relativePath); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getIDEImageDescriptor(String) from the type IDEWorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 7 problems (7 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/TeamAction.java + [javac] (at line 38) + [javac] import org.eclipse.ui.internal.LegacyResourceSupport; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type LegacyResourceSupport is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/TeamAction.java + [javac] (at line 190) + [javac] return LegacyResourceSupport.getAdaptedContributorResourceMapping(object); + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type LegacyResourceSupport is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/TeamAction.java + [javac] (at line 190) + [javac] return LegacyResourceSupport.getAdaptedContributorResourceMapping(object); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getAdaptedContributorResourceMapping(Object) from the type LegacyResourceSupport is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] ---------- + [javac] 4. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/PreferencePageContainerDialog.java + [javac] (at line 18) + [javac] import org.eclipse.compare.internal.TabFolderLayout; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type TabFolderLayout is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 5. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/PreferencePageContainerDialog.java + [javac] (at line 158) + [javac] tabFolder.setLayout(new TabFolderLayout()); + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor TabFolderLayout() is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 6. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/PreferencePageContainerDialog.java + [javac] (at line 158) + [javac] tabFolder.setLayout(new TabFolderLayout()); + [javac] ^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type TabFolderLayout is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] ---------- + [javac] 7. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/registry/RegistryReader.java + [javac] (at line 18) + [javac] import org.eclipse.ui.internal.WorkbenchPlugin; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type WorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 8. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/registry/RegistryReader.java + [javac] (at line 36) + [javac] return WorkbenchPlugin.createExtension(element, classAttribute); + [javac] ^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type WorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 9. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/registry/RegistryReader.java + [javac] (at line 36) + [javac] return WorkbenchPlugin.createExtension(element, classAttribute); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createExtension(IConfigurationElement, String) from the type WorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] ---------- + [javac] 10. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/AbstractTreeViewerAdvisor.java + [javac] (at line 13) + [javac] import org.eclipse.compare.internal.INavigatable; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 11. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/AbstractTreeViewerAdvisor.java + [javac] (at line 25) + [javac] private INavigatable nav; + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 12. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/AbstractTreeViewerAdvisor.java + [javac] (at line 170) + [javac] INavigatable nav = (INavigatable)configuration.getProperty(SynchronizePageConfiguration.P_NAVIGATOR); + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 13. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/AbstractTreeViewerAdvisor.java + [javac] (at line 170) + [javac] INavigatable nav = (INavigatable)configuration.getProperty(SynchronizePageConfiguration.P_NAVIGATOR); + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 14. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/AbstractTreeViewerAdvisor.java + [javac] (at line 172) + [javac] configuration.setProperty(SynchronizePageConfiguration.P_NAVIGATOR, getAdapter(INavigatable.class)); + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 15. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/AbstractTreeViewerAdvisor.java + [javac] (at line 194) + [javac] if(adapter == INavigatable.class) { + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 16. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/AbstractTreeViewerAdvisor.java + [javac] (at line 196) + [javac] nav = new INavigatable() { + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] ---------- + [javac] 17. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/LocalResourceTypedElement.java + [javac] (at line 16) + [javac] import org.eclipse.compare.internal.BufferedResourceNode; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type BufferedResourceNode is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 18. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/LocalResourceTypedElement.java + [javac] (at line 92) + [javac] child= new BufferedResourceNode(file); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor BufferedResourceNode(IResource) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 19. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/LocalResourceTypedElement.java + [javac] (at line 92) + [javac] child= new BufferedResourceNode(file); + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type BufferedResourceNode is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] ---------- + [javac] 20. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/NavigationActionGroup.java + [javac] (at line 13) + [javac] import org.eclipse.compare.internal.INavigatable; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 21. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/NavigationActionGroup.java + [javac] (at line 51) + [javac] INavigatable nav = (INavigatable)configuration.getProperty(SynchronizePageConfiguration.P_NAVIGATOR); + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 22. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/NavigationActionGroup.java + [javac] (at line 51) + [javac] INavigatable nav = (INavigatable)configuration.getProperty(SynchronizePageConfiguration.P_NAVIGATOR); + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] ---------- + [javac] 23. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 14) + [javac] import org.eclipse.compare.internal.INavigatable; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 24. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 15) + [javac] import org.eclipse.compare.internal.IOpenable; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IOpenable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 25. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 32) + [javac] public class PartNavigator implements INavigatable { + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 26. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 52) + [javac] INavigatable[] navigators= new INavigatable[4]; + [javac] ^^^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 27. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 52) + [javac] INavigatable[] navigators= new INavigatable[4]; + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 28. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 61) + [javac] if (navigators[n].gotoDifference(next)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method gotoDifference(boolean) from the type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 29. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 70) + [javac] private static INavigatable getNavigator(Object p) { + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 30. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 84) + [javac] Object data = control.getData(INavigatable.NAVIGATOR_PROPERTY); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 31. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 84) + [javac] Object data = control.getData(INavigatable.NAVIGATOR_PROPERTY); + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field NAVIGATOR_PROPERTY from the type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 32. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 85) + [javac] if (data instanceof INavigatable) + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 33. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 86) + [javac] return (INavigatable) data; + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 34. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 88) + [javac] return (INavigatable)((IAdaptable)p).getAdapter(INavigatable.class); + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 35. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 88) + [javac] return (INavigatable)((IAdaptable)p).getAdapter(INavigatable.class); + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 36. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 116) + [javac] IOpenable openable= getOpenable(fPanes[0]); + [javac] ^^^^^^^^^ + [javac] Discouraged access: The type IOpenable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 37. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 118) + [javac] openable.openSelected(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method openSelected() from the type IOpenable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 38. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 125) + [javac] private static IOpenable getOpenable(Object p) { + [javac] ^^^^^^^^^ + [javac] Discouraged access: The type IOpenable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 39. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 138) + [javac] Object data = control.getData(IOpenable.OPENABLE_PROPERTY); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IOpenable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 40. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 138) + [javac] Object data = control.getData(IOpenable.OPENABLE_PROPERTY); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field OPENABLE_PROPERTY from the type IOpenable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 41. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 139) + [javac] if (data instanceof IOpenable) + [javac] ^^^^^^^^^ + [javac] Discouraged access: The type IOpenable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 42. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/PartNavigator.java + [javac] (at line 140) + [javac] return (IOpenable) data; + [javac] ^^^^^^^^^ + [javac] Discouraged access: The type IOpenable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] ---------- + [javac] 43. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/NavigateAction.java + [javac] (at line 15) + [javac] import org.eclipse.compare.internal.INavigatable; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 44. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/NavigateAction.java + [javac] (at line 63) + [javac] INavigatable nav = (INavigatable)configuration.getProperty(SynchronizePageConfiguration.P_NAVIGATOR); + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 45. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/NavigateAction.java + [javac] (at line 63) + [javac] INavigatable nav = (INavigatable)configuration.getProperty(SynchronizePageConfiguration.P_NAVIGATOR); + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 46. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/NavigateAction.java + [javac] (at line 67) + [javac] nav.gotoDifference(next); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method gotoDifference(boolean) from the type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 47. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/NavigateAction.java + [javac] (at line 74) + [javac] private void navigateInView(INavigatable nav) { + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 48. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/NavigateAction.java + [javac] (at line 77) + [javac] if(nav.gotoDifference(next)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method gotoDifference(boolean) from the type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 49. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/NavigateAction.java + [javac] (at line 89) + [javac] if(! nav.gotoDifference(next)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method gotoDifference(boolean) from the type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 50. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/NavigateAction.java + [javac] (at line 105) + [javac] if(! nav.gotoDifference(next)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method gotoDifference(boolean) from the type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 51. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/NavigateAction.java + [javac] (at line 116) + [javac] if(! nav.gotoDifference(next)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method gotoDifference(boolean) from the type INavigatable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] ---------- + [javac] 52. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/ui/PageSaveablePart.java + [javac] (at line 18) + [javac] import org.eclipse.compare.internal.CompareEditor; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type CompareEditor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 53. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/ui/PageSaveablePart.java + [javac] (at line 19) + [javac] import org.eclipse.compare.internal.ISavable; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ISavable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 54. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/ui/PageSaveablePart.java + [javac] (at line 208) + [javac] Object o= cc.getProperty(CompareEditor.CONFIRM_SAVE_PROPERTY); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type CompareEditor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 55. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/ui/PageSaveablePart.java + [javac] (at line 208) + [javac] Object o= cc.getProperty(CompareEditor.CONFIRM_SAVE_PROPERTY); + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field CONFIRM_SAVE_PROPERTY from the type CompareEditor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 56. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/ui/PageSaveablePart.java + [javac] (at line 410) + [javac] if (element instanceof ISavable){ + [javac] ^^^^^^^^ + [javac] Discouraged access: The type ISavable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 57. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/ui/PageSaveablePart.java + [javac] (at line 412) + [javac] ((ISavable)element).save(monitor); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method save(IProgressMonitor) from the type ISavable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 58. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/ui/PageSaveablePart.java + [javac] (at line 412) + [javac] ((ISavable)element).save(monitor); + [javac] ^^^^^^^^ + [javac] Discouraged access: The type ISavable is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] ---------- + [javac] 59. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartDialog.java + [javac] (at line 13) + [javac] import org.eclipse.compare.internal.ResizableDialog; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ResizableDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 60. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartDialog.java + [javac] (at line 29) + [javac] public class SaveablePartDialog extends ResizableDialog { + [javac] ^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ResizableDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 61. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartDialog.java + [javac] (at line 41) + [javac] super(shell, null); + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor ResizableDialog(Shell, ResourceBundle) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 62. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.ui/src/org/eclipse/team/ui/SaveablePartDialog.java + [javac] (at line 70) + [javac] return super.close(); + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The method close() from the type ResizableDialog is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 62 problems (62 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java + [javac] (at line 31) + [javac] import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDEWorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java + [javac] (at line 32) + [javac] import org.eclipse.ui.internal.registry.EditorDescriptor; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type EditorDescriptor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java + [javac] (at line 340) + [javac] part = page.openEditor(new RemoteAnnotationEditorInput(file, contents), IDEWorkbenchPlugin.DEFAULT_TEXT_EDITOR_ID); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDEWorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 4. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java + [javac] (at line 340) + [javac] part = page.openEditor(new RemoteAnnotationEditorInput(file, contents), IDEWorkbenchPlugin.DEFAULT_TEXT_EDITOR_ID); + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field DEFAULT_TEXT_EDITOR_ID from the type IDEWorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 5. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java + [javac] (at line 355) + [javac] if (descriptor == null || !(descriptor instanceof EditorDescriptor) || !(((EditorDescriptor)descriptor).isInternal())) { + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type EditorDescriptor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 6. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java + [javac] (at line 355) + [javac] if (descriptor == null || !(descriptor instanceof EditorDescriptor) || !(((EditorDescriptor)descriptor).isInternal())) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method isInternal() from the type EditorDescriptor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 7. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java + [javac] (at line 355) + [javac] if (descriptor == null || !(descriptor instanceof EditorDescriptor) || !(((EditorDescriptor)descriptor).isInternal())) { + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type EditorDescriptor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 8. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java + [javac] (at line 356) + [javac] id = IDEWorkbenchPlugin.DEFAULT_TEXT_EDITOR_ID; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDEWorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 9. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java + [javac] (at line 356) + [javac] id = IDEWorkbenchPlugin.DEFAULT_TEXT_EDITOR_ID; + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field DEFAULT_TEXT_EDITOR_ID from the type IDEWorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 10. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java + [javac] (at line 359) + [javac] Object obj = IDEWorkbenchPlugin.createExtension(((EditorDescriptor) descriptor).getConfigurationElement(), "class"); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDEWorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 11. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java + [javac] (at line 359) + [javac] Object obj = IDEWorkbenchPlugin.createExtension(((EditorDescriptor) descriptor).getConfigurationElement(), "class"); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createExtension(IConfigurationElement, String) from the type IDEWorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 12. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java + [javac] (at line 359) + [javac] Object obj = IDEWorkbenchPlugin.createExtension(((EditorDescriptor) descriptor).getConfigurationElement(), "class"); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getConfigurationElement() from the type EditorDescriptor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 13. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java + [javac] (at line 359) + [javac] Object obj = IDEWorkbenchPlugin.createExtension(((EditorDescriptor) descriptor).getConfigurationElement(), "class"); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type EditorDescriptor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.workbench/@dot + [javac] ---------- + [javac] 14. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java + [javac] (at line 363) + [javac] id = IDEWorkbenchPlugin.DEFAULT_TEXT_EDITOR_ID; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDEWorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 15. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java + [javac] (at line 363) + [javac] id = IDEWorkbenchPlugin.DEFAULT_TEXT_EDITOR_ID; + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field DEFAULT_TEXT_EDITOR_ID from the type IDEWorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 16. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java + [javac] (at line 366) + [javac] id = IDEWorkbenchPlugin.DEFAULT_TEXT_EDITOR_ID; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDEWorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 17. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/AnnotateView.java + [javac] (at line 366) + [javac] id = IDEWorkbenchPlugin.DEFAULT_TEXT_EDITOR_ID; + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field DEFAULT_TEXT_EDITOR_ID from the type IDEWorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] ---------- + [javac] 18. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSDecoratorPreferencesPage.java + [javac] (at line 21) + [javac] import org.eclipse.compare.internal.TabFolderLayout; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type TabFolderLayout is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 19. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSDecoratorPreferencesPage.java + [javac] (at line 547) + [javac] tabFolder.setLayout(new TabFolderLayout()); + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor TabFolderLayout() is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] 20. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSDecoratorPreferencesPage.java + [javac] (at line 547) + [javac] tabFolder.setLayout(new TabFolderLayout()); + [javac] ^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type TabFolderLayout is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.compare/@dot + [javac] ---------- + [javac] ---------- + [javac] 21. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/ChangeSetContentProvider.java + [javac] (at line 40) + [javac] import org.eclipse.ui.internal.navigator.extensions.CommonExtensionSite; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type CommonExtensionSite is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.navigator/@dot + [javac] ---------- + [javac] 22. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/ChangeSetContentProvider.java + [javac] (at line 640) + [javac] INavigatorContentService contentService = ((CommonExtensionSite)getExtensionSite()).getContentService(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getContentService() from the type CommonExtensionSite is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.navigator/@dot + [javac] ---------- + [javac] 23. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/mappings/ChangeSetContentProvider.java + [javac] (at line 640) + [javac] INavigatorContentService contentService = ((CommonExtensionSite)getExtensionSite()).getContentService(); + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type CommonExtensionSite is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.navigator/@dot + [javac] ---------- + [javac] ---------- + [javac] 24. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ShowAnnotationOperation.java + [javac] (at line 21) + [javac] import org.eclipse.jface.internal.text.revisions.RevisionSelectionProvider; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type RevisionSelectionProvider is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jface.text/@dot + [javac] ---------- + [javac] 25. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ShowAnnotationOperation.java + [javac] (at line 48) + [javac] import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDEWorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 26. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ShowAnnotationOperation.java + [javac] (at line 116) + [javac] final ISelectionProvider provider= (ISelectionProvider) editor.getAdapter(RevisionSelectionProvider.class); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type RevisionSelectionProvider is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jface.text/@dot + [javac] ---------- + [javac] 27. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ShowAnnotationOperation.java + [javac] (at line 241) + [javac] IEditorPart part = getPart().getSite().getPage().openEditor(new FileEditorInput((IFile) resource), IDEWorkbenchPlugin.DEFAULT_TEXT_EDITOR_ID, true, IWorkbenchPage.MATCH_NONE); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDEWorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 28. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ShowAnnotationOperation.java + [javac] (at line 241) + [javac] IEditorPart part = getPart().getSite().getPage().openEditor(new FileEditorInput((IFile) resource), IDEWorkbenchPlugin.DEFAULT_TEXT_EDITOR_ID, true, IWorkbenchPage.MATCH_NONE); + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field DEFAULT_TEXT_EDITOR_ID from the type IDEWorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 29. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ShowAnnotationOperation.java + [javac] (at line 265) + [javac] IEditorPart part = IDE.openEditor(getPart().getSite().getPage(), (IFile) resource, IDEWorkbenchPlugin.DEFAULT_TEXT_EDITOR_ID); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDEWorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 30. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/operations/ShowAnnotationOperation.java + [javac] (at line 265) + [javac] IEditorPart part = IDE.openEditor(getPart().getSite().getPage(), (IFile) resource, IDEWorkbenchPlugin.DEFAULT_TEXT_EDITOR_ID); + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field DEFAULT_TEXT_EDITOR_ID from the type IDEWorkbenchPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 30 problems (30 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParser.java + [javac] (at line 517) + [javac] private boolean jj_semLA; + [javac] ^^^^^^^^ + [javac] The field HTMLParser.jj_semLA is never read locally + [javac] ---------- + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 239) + [javac] private final void jjCheckNAddStates(int start) + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] The method jjCheckNAddStates(int) from the type HTMLParserTokenManager is never used locally + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 252) + [javac] int[] nextStates; + [javac] ^^^^^^^^^^ + [javac] The local variable nextStates is never read + [javac] ---------- + [javac] 4. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 257) + [javac] int j, kind = 0x7fffffff; + [javac] ^ + [javac] The local variable j is never read + [javac] ---------- + [javac] 5. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 265) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 6. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 430) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 7. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 507) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 8. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 558) + [javac] int[] nextStates; + [javac] ^^^^^^^^^^ + [javac] The local variable nextStates is never read + [javac] ---------- + [javac] 9. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 563) + [javac] int j, kind = 0x7fffffff; + [javac] ^ + [javac] The local variable j is never read + [javac] ---------- + [javac] 10. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 571) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 11. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 600) + [javac] long l = 1L << (curChar & 077); + [javac] ^ + [javac] The local variable l is never read + [javac] ---------- + [javac] 12. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 601) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 13. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 621) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 14. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 658) + [javac] private final int jjStartNfa_7(int pos, long active0) + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] The method jjStartNfa_7(int, long) from the type HTMLParserTokenManager is never used locally + [javac] ---------- + [javac] 15. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 662) + [javac] private final int jjStartNfaWithStates_7(int pos, int kind, int state) + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] The method jjStartNfaWithStates_7(int, int, int) from the type HTMLParserTokenManager is never used locally + [javac] ---------- + [javac] 16. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 682) + [javac] int[] nextStates; + [javac] ^^^^^^^^^^ + [javac] The local variable nextStates is never read + [javac] ---------- + [javac] 17. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 687) + [javac] int j, kind = 0x7fffffff; + [javac] ^ + [javac] The local variable j is never read + [javac] ---------- + [javac] 18. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 695) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 19. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 711) + [javac] long l = 1L << (curChar & 077); + [javac] ^ + [javac] The local variable l is never read + [javac] ---------- + [javac] 20. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 712) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 21. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 731) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 22. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 765) + [javac] int[] nextStates; + [javac] ^^^^^^^^^^ + [javac] The local variable nextStates is never read + [javac] ---------- + [javac] 23. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 770) + [javac] int j, kind = 0x7fffffff; + [javac] ^ + [javac] The local variable j is never read + [javac] ---------- + [javac] 24. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 778) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 25. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 807) + [javac] long l = 1L << (curChar & 077); + [javac] ^ + [javac] The local variable l is never read + [javac] ---------- + [javac] 26. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 808) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 27. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 828) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 28. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 865) + [javac] private final int jjStartNfa_3(int pos, long active0) + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] The method jjStartNfa_3(int, long) from the type HTMLParserTokenManager is never used locally + [javac] ---------- + [javac] 29. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 869) + [javac] private final int jjStartNfaWithStates_3(int pos, int kind, int state) + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] The method jjStartNfaWithStates_3(int, int, int) from the type HTMLParserTokenManager is never used locally + [javac] ---------- + [javac] 30. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 891) + [javac] int[] nextStates; + [javac] ^^^^^^^^^^ + [javac] The local variable nextStates is never read + [javac] ---------- + [javac] 31. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 896) + [javac] int j, kind = 0x7fffffff; + [javac] ^ + [javac] The local variable j is never read + [javac] ---------- + [javac] 32. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 904) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 33. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 941) + [javac] long l = 1L << (curChar & 077); + [javac] ^ + [javac] The local variable l is never read + [javac] ---------- + [javac] 34. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 942) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 35. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 963) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 36. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1022) + [javac] private final int jjStartNfaWithStates_6(int pos, int kind, int state) + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] The method jjStartNfaWithStates_6(int, int, int) from the type HTMLParserTokenManager is never used locally + [javac] ---------- + [javac] 37. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1078) + [javac] int[] nextStates; + [javac] ^^^^^^^^^^ + [javac] The local variable nextStates is never read + [javac] ---------- + [javac] 38. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1083) + [javac] int j, kind = 0x7fffffff; + [javac] ^ + [javac] The local variable j is never read + [javac] ---------- + [javac] 39. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1091) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 40. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1120) + [javac] long l = 1L << (curChar & 077); + [javac] ^ + [javac] The local variable l is never read + [javac] ---------- + [javac] 41. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1121) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 42. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1141) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 43. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1176) + [javac] int[] nextStates; + [javac] ^^^^^^^^^^ + [javac] The local variable nextStates is never read + [javac] ---------- + [javac] 44. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1181) + [javac] int j, kind = 0x7fffffff; + [javac] ^ + [javac] The local variable j is never read + [javac] ---------- + [javac] 45. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1189) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 46. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1237) + [javac] long l = 1L << (curChar & 077); + [javac] ^ + [javac] The local variable l is never read + [javac] ---------- + [javac] 47. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1238) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 48. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1286) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 49. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1327) + [javac] private final int jjStartNfa_2(int pos, long active0) + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] The method jjStartNfa_2(int, long) from the type HTMLParserTokenManager is never used locally + [javac] ---------- + [javac] 50. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1355) + [javac] int[] nextStates; + [javac] ^^^^^^^^^^ + [javac] The local variable nextStates is never read + [javac] ---------- + [javac] 51. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1360) + [javac] int j, kind = 0x7fffffff; + [javac] ^ + [javac] The local variable j is never read + [javac] ---------- + [javac] 52. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1368) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 53. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1421) + [javac] long l = 1L << (curChar & 077); + [javac] ^ + [javac] The local variable l is never read + [javac] ---------- + [javac] 54. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1422) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 55. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1443) + [javac] MatchLoop: do + [javac] ^^^^^^^^^ + [javac] The label MatchLoop is never explicitly referenced + [javac] ---------- + [javac] 56. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1576) + [javac] int kind; + [javac] ^^^^ + [javac] The local variable kind is never read + [javac] ---------- + [javac] 57. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.apache.lucene/src/org/apache/lucene/demo/html/HTMLParserTokenManager.java + [javac] (at line 1577) + [javac] Token specialToken = null; + [javac] ^^^^^^^^^^^^ + [javac] The local variable specialToken is never read + [javac] ---------- + [javac] 57 problems (57 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/advanced_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/advanced_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/advanced_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 4. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/askShowAll_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 5. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/askShowAll_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 6. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/askShowAll_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 7. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/askShowAll_jsp.java + [javac] (at line 51) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 8. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/bookmarksToolbar_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 9. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/bookmarksToolbar_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 10. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/bookmarksToolbar_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 11. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/bookmarksToolbar_jsp.java + [javac] (at line 51) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 12. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/bookmarksView_jsp.java + [javac] (at line 29) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 13. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/bookmarksView_jsp.java + [javac] (at line 31) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 14. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/bookmarksView_jsp.java + [javac] (at line 33) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 15. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/confirmShowAll_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 16. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/confirmShowAll_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 17. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/confirmShowAll_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 18. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/confirmShowAll_jsp.java + [javac] (at line 51) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 19. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/confirm_jsp.java + [javac] (at line 29) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 20. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/confirm_jsp.java + [javac] (at line 31) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 21. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/confirm_jsp.java + [javac] (at line 33) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 22. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/contentToolbar_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 23. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/contentToolbar_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 24. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/contentToolbar_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 25. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/contentToolbar_jsp.java + [javac] (at line 51) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 26. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/content_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 27. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/content_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 28. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/content_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 29. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/content_jsp.java + [javac] (at line 51) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 30. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/err_jsp.java + [javac] (at line 23) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 31. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/err_jsp.java + [javac] (at line 25) + [javac] ServletContext application = null; + [javac] ^^^^^^^^^^^ + [javac] The local variable application is never read + [javac] ---------- + [javac] 32. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/err_jsp.java + [javac] (at line 26) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 33. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/err_jsp.java + [javac] (at line 28) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 34. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/fheader_jsp.java + [javac] (at line 23) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 35. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/fheader_jsp.java + [javac] (at line 25) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 36. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/fheader_jsp.java + [javac] (at line 27) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 37. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/fheader_jsp.java + [javac] (at line 45) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 38. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/header_jsp.java + [javac] (at line 23) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 39. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/header_jsp.java + [javac] (at line 25) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 40. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/header_jsp.java + [javac] (at line 27) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 41. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/header_jsp.java + [javac] (at line 45) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 42. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/help_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 43. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/help_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 44. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/help_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 45. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/help_jsp.java + [javac] (at line 51) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 46. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/indexList_jsp.java + [javac] (at line 29) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 47. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/indexList_jsp.java + [javac] (at line 31) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 48. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/indexList_jsp.java + [javac] (at line 33) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 49. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/indexToolbar_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 50. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/indexToolbar_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 51. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/indexToolbar_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 52. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/indexToolbar_jsp.java + [javac] (at line 51) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 53. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/indexTypein_jsp.java + [javac] (at line 29) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 54. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/indexTypein_jsp.java + [javac] (at line 31) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 55. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/indexTypein_jsp.java + [javac] (at line 33) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 56. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/indexView_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 57. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/indexView_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 58. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/indexView_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 59. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/indexView_jsp.java + [javac] (at line 51) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 60. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/index_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 61. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/index_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 62. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/index_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 63. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/index_jsp.java + [javac] (at line 51) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 64. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/linksToolbar_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 65. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/linksToolbar_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 66. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/linksToolbar_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 67. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/linksToolbar_jsp.java + [javac] (at line 51) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 68. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/linksView_jsp.java + [javac] (at line 29) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 69. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/linksView_jsp.java + [javac] (at line 31) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 70. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/linksView_jsp.java + [javac] (at line 33) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 71. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/livehelp_js_jsp.java + [javac] (at line 23) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 72. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/livehelp_js_jsp.java + [javac] (at line 25) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 73. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/livehelp_js_jsp.java + [javac] (at line 27) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 74. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/nav_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 75. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/nav_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 76. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/nav_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 77. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/nav_jsp.java + [javac] (at line 51) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 78. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/searchScoped_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 79. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/searchScoped_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 80. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/searchScoped_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 81. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/searchSimple_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 82. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/searchSimple_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 83. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/searchSimple_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 84. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/searchToolbar_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 85. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/searchToolbar_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 86. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/searchToolbar_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 87. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/searchToolbar_jsp.java + [javac] (at line 51) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 88. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/searchView_jsp.java + [javac] (at line 29) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 89. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/searchView_jsp.java + [javac] (at line 31) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 90. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/searchView_jsp.java + [javac] (at line 33) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 91. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/search_jsp.java + [javac] (at line 23) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 92. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/search_jsp.java + [javac] (at line 25) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 93. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/search_jsp.java + [javac] (at line 27) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 94. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/tabs_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 95. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/tabs_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 96. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/tabs_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 97. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/tocFragment_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 98. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/tocFragment_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 99. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/tocFragment_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 100. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/tocToolbar_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 101. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/tocToolbar_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 102. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/tocToolbar_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 103. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/tocToolbar_jsp.java + [javac] (at line 51) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 104. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/tocView_jsp.java + [javac] (at line 29) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 105. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/tocView_jsp.java + [javac] (at line 31) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 106. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/tocView_jsp.java + [javac] (at line 33) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 107. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/toolbar_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 108. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/toolbar_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 109. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/toolbar_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 110. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/view_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 111. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/view_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 112. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/view_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 113. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/view_jsp.java + [javac] (at line 51) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 114. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/views_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 115. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/views_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 116. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/views_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 117. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/workingSetManager_jsp.java + [javac] (at line 29) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 118. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/workingSetManager_jsp.java + [javac] (at line 31) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 119. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/workingSetManager_jsp.java + [javac] (at line 33) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 120. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/workingSet_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 121. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/workingSet_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 122. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/advanced/workingSet_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 123. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/err_jsp.java + [javac] (at line 23) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 124. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/err_jsp.java + [javac] (at line 25) + [javac] ServletContext application = null; + [javac] ^^^^^^^^^^^ + [javac] The local variable application is never read + [javac] ---------- + [javac] 125. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/err_jsp.java + [javac] (at line 26) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 126. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/err_jsp.java + [javac] (at line 28) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 127. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/header_jsp.java + [javac] (at line 23) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 128. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/header_jsp.java + [javac] (at line 24) + [javac] ServletContext application = null; + [javac] ^^^^^^^^^^^ + [javac] The local variable application is never read + [javac] ---------- + [javac] 129. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/header_jsp.java + [javac] (at line 25) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 130. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/header_jsp.java + [javac] (at line 27) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 131. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/header_jsp.java + [javac] (at line 47) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 132. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/help_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 133. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/help_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 134. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/help_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 135. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/help_jsp.java + [javac] (at line 53) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 136. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/indexToolbar_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 137. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/indexToolbar_jsp.java + [javac] (at line 29) + [javac] ServletContext application = null; + [javac] ^^^^^^^^^^^ + [javac] The local variable application is never read + [javac] ---------- + [javac] 138. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/indexToolbar_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 139. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/indexToolbar_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 140. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/indexToolbar_jsp.java + [javac] (at line 53) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 141. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/indexView_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 142. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/indexView_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 143. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/indexView_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 144. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/index_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 145. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/index_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 146. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/index_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 147. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/index_jsp.java + [javac] (at line 53) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 148. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/linksToolbar_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 149. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/linksToolbar_jsp.java + [javac] (at line 29) + [javac] ServletContext application = null; + [javac] ^^^^^^^^^^^ + [javac] The local variable application is never read + [javac] ---------- + [javac] 150. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/linksToolbar_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 151. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/linksToolbar_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 152. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/linksToolbar_jsp.java + [javac] (at line 53) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 153. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/linksView_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 154. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/linksView_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 155. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/linksView_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 156. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/livehelp_js_jsp.java + [javac] (at line 23) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 157. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/livehelp_js_jsp.java + [javac] (at line 25) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 158. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/livehelp_js_jsp.java + [javac] (at line 27) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 159. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/searchToolbar_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 160. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/searchToolbar_jsp.java + [javac] (at line 29) + [javac] ServletContext application = null; + [javac] ^^^^^^^^^^^ + [javac] The local variable application is never read + [javac] ---------- + [javac] 161. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/searchToolbar_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 162. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/searchToolbar_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 163. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/searchToolbar_jsp.java + [javac] (at line 53) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 164. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/searchView_jsp.java + [javac] (at line 29) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 165. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/searchView_jsp.java + [javac] (at line 31) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 166. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/searchView_jsp.java + [javac] (at line 33) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 167. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/searchView_jsp.java + [javac] (at line 63) + [javac] LayoutData ldata = new LayoutData(application,request, response); + [javac] ^^^^^ + [javac] The local variable ldata is never read + [javac] ---------- + [javac] ---------- + [javac] 168. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/tabs_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 169. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/tabs_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 170. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/tabs_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 171. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/tocToolbar_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 172. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/tocToolbar_jsp.java + [javac] (at line 29) + [javac] ServletContext application = null; + [javac] ^^^^^^^^^^^ + [javac] The local variable application is never read + [javac] ---------- + [javac] 173. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/tocToolbar_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 174. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/tocToolbar_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 175. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/tocToolbar_jsp.java + [javac] (at line 53) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 176. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/tocView_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 177. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/tocView_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 178. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/tocView_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 179. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/toolbar_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 180. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/toolbar_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 181. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/toolbar_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] ---------- + [javac] 182. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/view_jsp.java + [javac] (at line 28) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 183. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/view_jsp.java + [javac] (at line 30) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 184. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/view_jsp.java + [javac] (at line 32) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 185. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/basic/view_jsp.java + [javac] (at line 53) + [javac] String direction = isRTL?"rtl":"ltr"; + [javac] ^^^^^^^^^ + [javac] The local variable direction is never read + [javac] ---------- + [javac] ---------- + [javac] 186. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/index_jsp.java + [javac] (at line 23) + [javac] HttpSession session = null; + [javac] ^^^^^^^ + [javac] The local variable session is never read + [javac] ---------- + [javac] 187. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/index_jsp.java + [javac] (at line 25) + [javac] ServletConfig config = null; + [javac] ^^^^^^ + [javac] The local variable config is never read + [javac] ---------- + [javac] 188. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.help.webapp/temp.folder/jsp.jar.src/index_jsp.java + [javac] (at line 27) + [javac] Object page = this; + [javac] ^^^^ + [javac] The local variable page is never read + [javac] ---------- + [javac] 188 problems (188 warnings) + [zip] Warning: skipping zip archive /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.osgi.services/src.zip because no files were included. + [zip] Warning: skipping zip archive /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.osgi.util/src.zip because no files were included. + [exec] javadoc: Error reading file: /usr/share/javadoc/java/package-list + [exec] javadoc: Error reading file: org.eclipse.ant.core/package-list + [exec] Result: 1 + [echo] Extract .class file and properties for the batch compiler + [echo] Extract .class file and properties for the ant adapter + [echo] UPDATE ecj.jar + [echo] UPDATE ecjsrc.zip + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/JavaHotCodeReplaceManager.java + [javac] (at line 70) + [javac] import org.eclipse.jdt.internal.core.util.Util; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type Util is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.core/@dot + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/JavaHotCodeReplaceManager.java + [javac] (at line 634) + [javac] bytes= Util.getResourceContentsAsByteArray((IFile) resource); + [javac] ^^^^ + [javac] Discouraged access: The type Util is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.core/@dot + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/JavaHotCodeReplaceManager.java + [javac] (at line 634) + [javac] bytes= Util.getResourceContentsAsByteArray((IFile) resource); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getResourceContentsAsByteArray(IFile) from the type Util is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.core/@dot + [javac] ---------- + [javac] ---------- + [javac] 4. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/spy/VerbosePacketStream.java + [javac] (at line 1711) + [javac] String signature= readString(in); + [javac] ^^^^^^^^^ + [javac] The local variable signature is never read + [javac] ---------- + [javac] ---------- + [javac] 5. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/SignatureExt.java + [javac] (at line 17) + [javac] import org.eclipse.jdt.internal.core.util.Util; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type Util is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.core/@dot + [javac] ---------- + [javac] 6. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/SignatureExt.java + [javac] (at line 37) + [javac] i = Util.scanTypeSignature(typeSignature, i); + [javac] ^^^^ + [javac] Discouraged access: The type Util is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.core/@dot + [javac] ---------- + [javac] 7. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/SignatureExt.java + [javac] (at line 37) + [javac] i = Util.scanTypeSignature(typeSignature, i); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method scanTypeSignature(char[], int) from the type Util is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.core/@dot + [javac] ---------- + [javac] 8. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/SignatureExt.java + [javac] (at line 47) + [javac] i= Util.scanTypeSignature(typeSignature, i); + [javac] ^^^^ + [javac] Discouraged access: The type Util is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.core/@dot + [javac] ---------- + [javac] 9. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/SignatureExt.java + [javac] (at line 47) + [javac] i= Util.scanTypeSignature(typeSignature, i); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method scanTypeSignature(char[], int) from the type Util is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.core/@dot + [javac] ---------- + [javac] 9 problems (9 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/sourcelookup/containers/JavaSourceLookupParticipant.java + [javac] (at line 30) + [javac] import org.eclipse.jdt.internal.debug.core.JavaDebugUtils; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaDebugUtils is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug/jdimodel.jar + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/sourcelookup/containers/JavaSourceLookupParticipant.java + [javac] (at line 60) + [javac] return JavaDebugUtils.getSourceName(object); + [javac] ^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaDebugUtils is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug/jdimodel.jar + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/sourcelookup/containers/JavaSourceLookupParticipant.java + [javac] (at line 60) + [javac] return JavaDebugUtils.getSourceName(object); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getSourceName(Object) from the type JavaDebugUtils is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug/jdimodel.jar + [javac] ---------- + [javac] 3 problems (3 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarRefactoringDialog.java + [javac] (at line 40) + [javac] import org.eclipse.ltk.internal.ui.refactoring.history.BrowseRefactoringHistoryControl; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type BrowseRefactoringHistoryControl is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarRefactoringDialog.java + [javac] (at line 69) + [javac] private BrowseRefactoringHistoryControl fHistoryControl= null; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type BrowseRefactoringHistoryControl is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarRefactoringDialog.java + [javac] (at line 102) + [javac] final RefactoringDescriptorProxy[] descriptors= fHistoryControl.getCheckedDescriptors(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getCheckedDescriptors() from the type RefactoringHistoryControl is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] 4. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarRefactoringDialog.java + [javac] (at line 115) + [javac] settings.put(SETTING_SORT, fHistoryControl.isSortByProjects()); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method isSortByProjects() from the type BrowseRefactoringHistoryControl is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] 5. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarRefactoringDialog.java + [javac] (at line 147) + [javac] fHistoryControl= new BrowseRefactoringHistoryControl(composite, configuration); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor BrowseRefactoringHistoryControl(Composite, RefactoringHistoryControlConfiguration) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] 6. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarRefactoringDialog.java + [javac] (at line 147) + [javac] fHistoryControl= new BrowseRefactoringHistoryControl(composite, configuration); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type BrowseRefactoringHistoryControl is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] 7. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarRefactoringDialog.java + [javac] (at line 148) + [javac] fHistoryControl.createControl(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createControl() from the type BrowseRefactoringHistoryControl is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] 8. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarRefactoringDialog.java + [javac] (at line 154) + [javac] fHistoryControl.sortByProjects(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method sortByProjects() from the type BrowseRefactoringHistoryControl is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] 9. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarRefactoringDialog.java + [javac] (at line 156) + [javac] fHistoryControl.sortByDate(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method sortByDate() from the type BrowseRefactoringHistoryControl is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] 10. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarRefactoringDialog.java + [javac] (at line 161) + [javac] fHistoryControl.setInput(fHistory); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setInput(RefactoringHistory) from the type BrowseRefactoringHistoryControl is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] 11. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/jarpackager/JarRefactoringDialog.java + [javac] (at line 162) + [javac] fHistoryControl.setCheckedDescriptors(fData.getRefactoringDescriptors()); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setCheckedDescriptors(RefactoringDescriptorProxy[]) from the type RefactoringHistoryControl is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] ---------- + [javac] 12. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/ProjectActionGroup.java + [javac] (at line 37) + [javac] import org.eclipse.ui.internal.ide.actions.CloseUnrelatedProjectsAction; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type CloseUnrelatedProjectsAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 13. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/ProjectActionGroup.java + [javac] (at line 79) + [javac] fCloseUnrelatedAction= new CloseUnrelatedProjectsAction(shell); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor CloseUnrelatedProjectsAction(Shell) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] 14. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/ProjectActionGroup.java + [javac] (at line 79) + [javac] fCloseUnrelatedAction= new CloseUnrelatedProjectsAction(shell); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type CloseUnrelatedProjectsAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.ide/@dot + [javac] ---------- + [javac] ---------- + [javac] 15. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/RefactoringExecutionHelper.java + [javac] (at line 48) + [javac] import org.eclipse.ltk.internal.ui.refactoring.ChangeExceptionHandler; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ChangeExceptionHandler is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] 16. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/RefactoringExecutionHelper.java + [javac] (at line 143) + [javac] ChangeExceptionHandler handler= new ChangeExceptionHandler(fParent, fRefactoring); + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ChangeExceptionHandler is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] 17. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/RefactoringExecutionHelper.java + [javac] (at line 143) + [javac] ChangeExceptionHandler handler= new ChangeExceptionHandler(fParent, fRefactoring); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor ChangeExceptionHandler(Shell, Refactoring) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] 18. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/RefactoringExecutionHelper.java + [javac] (at line 143) + [javac] ChangeExceptionHandler handler= new ChangeExceptionHandler(fParent, fRefactoring); + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ChangeExceptionHandler is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] 19. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/RefactoringExecutionHelper.java + [javac] (at line 146) + [javac] handler.handle(pco.getChange(), (RuntimeException)inner); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method handle(Change, RuntimeException) from the type ChangeExceptionHandler is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] 20. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/RefactoringExecutionHelper.java + [javac] (at line 148) + [javac] handler.handle(pco.getChange(), (CoreException)inner); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method handle(Change, CoreException) from the type ChangeExceptionHandler is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] ---------- + [javac] 21. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/actions/ApplyRefactoringScriptAction.java + [javac] (at line 48) + [javac] org.eclipse.ltk.internal.ui.refactoring.actions.ApplyRefactoringScriptAction.showApplyScriptWizard(fWindow); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ApplyRefactoringScriptAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] 22. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/actions/ApplyRefactoringScriptAction.java + [javac] (at line 48) + [javac] org.eclipse.ltk.internal.ui.refactoring.actions.ApplyRefactoringScriptAction.showApplyScriptWizard(fWindow); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method showApplyScriptWizard(IWorkbenchWindow) from the type ApplyRefactoringScriptAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] ---------- + [javac] 23. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/actions/CreateRefactoringScriptAction.java + [javac] (at line 48) + [javac] org.eclipse.ltk.internal.ui.refactoring.actions.CreateRefactoringScriptAction.showCreateScriptWizard(fWindow); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type CreateRefactoringScriptAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] 24. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/actions/CreateRefactoringScriptAction.java + [javac] (at line 48) + [javac] org.eclipse.ltk.internal.ui.refactoring.actions.CreateRefactoringScriptAction.showCreateScriptWizard(fWindow); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method showCreateScriptWizard(IWorkbenchWindow) from the type CreateRefactoringScriptAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] ---------- + [javac] 25. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/actions/ShowRefactoringHistoryAction.java + [javac] (at line 48) + [javac] org.eclipse.ltk.internal.ui.refactoring.actions.ShowRefactoringHistoryAction.showRefactoringHistoryWizard(fWindow); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ShowRefactoringHistoryAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] 26. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/actions/ShowRefactoringHistoryAction.java + [javac] (at line 48) + [javac] org.eclipse.ltk.internal.ui.refactoring.actions.ShowRefactoringHistoryAction.showRefactoringHistoryWizard(fWindow); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method showRefactoringHistoryWizard(IWorkbenchWindow) from the type ShowRefactoringHistoryAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ltk.ui.refactoring/@dot + [javac] ---------- + [javac] 26 problems (26 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXDebugVMRunner.java + [javac] (at line 16) + [javac] import org.eclipse.jdt.internal.launching.StandardVMDebugger; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StandardVMDebugger is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXDebugVMRunner.java + [javac] (at line 19) + [javac] public class MacOSXDebugVMRunner extends StandardVMDebugger { + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StandardVMDebugger is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXDebugVMRunner.java + [javac] (at line 22) + [javac] super(vmInstance); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor StandardVMDebugger(IVMInstall) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] ---------- + [javac] 4. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstall.java + [javac] (at line 16) + [javac] import org.eclipse.jdt.internal.launching.StandardVMType; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StandardVMType is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 5. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstall.java + [javac] (at line 40) + [javac] File executable= StandardVMType.findJavaExecutable(installLocation); + [javac] ^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StandardVMType is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 6. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstall.java + [javac] (at line 40) + [javac] File executable= StandardVMType.findJavaExecutable(installLocation); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method findJavaExecutable(File) from the type StandardVMType is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] ---------- + [javac] 7. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstallType.java + [javac] (at line 26) + [javac] import org.eclipse.jdt.internal.launching.LaunchingPlugin; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type LaunchingPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 8. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstallType.java + [javac] (at line 27) + [javac] import org.eclipse.jdt.internal.launching.LibraryInfo; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type LibraryInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 9. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstallType.java + [javac] (at line 28) + [javac] import org.eclipse.jdt.internal.launching.StandardVMType; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StandardVMType is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 10. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstallType.java + [javac] (at line 37) + [javac] public class MacOSXVMInstallType extends StandardVMType { + [javac] ^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StandardVMType is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 11. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstallType.java + [javac] (at line 113) + [javac] vm.setLibraryLocations(getDefaultLibraryLocations(home)); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getDefaultLibraryLocations(File) from the type StandardVMType is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 12. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstallType.java + [javac] (at line 124) + [javac] LaunchingPlugin.log(e); + [javac] ^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type LaunchingPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 13. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstallType.java + [javac] (at line 124) + [javac] LaunchingPlugin.log(e); + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method log(Throwable) from the type LaunchingPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 14. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstallType.java + [javac] (at line 133) + [javac] LaunchingPlugin.log(e); + [javac] ^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type LaunchingPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 15. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstallType.java + [javac] (at line 133) + [javac] LaunchingPlugin.log(e); + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method log(Throwable) from the type LaunchingPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 16. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstallType.java + [javac] (at line 149) + [javac] protected LibraryInfo getDefaultLibraryInfo(File installLocation) { + [javac] ^^^^^^^^^^^ + [javac] Discouraged access: The type LibraryInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 17. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstallType.java + [javac] (at line 172) + [javac] return new LibraryInfo("???", libs, dirs, endDirs); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor LibraryInfo(String, String[], String[], String[]) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 18. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstallType.java + [javac] (at line 172) + [javac] return new LibraryInfo("???", libs, dirs, endDirs); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^ + [javac] Discouraged access: The type LibraryInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 19. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstallType.java + [javac] (at line 181) + [javac] setDefaultRootPath("src");//$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setDefaultRootPath(String) from the type StandardVMType is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 20. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstallType.java + [javac] (at line 186) + [javac] setDefaultRootPath(""); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setDefaultRootPath(String) from the type StandardVMType is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 21. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstallType.java + [javac] (at line 191) + [javac] setDefaultRootPath(""); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setDefaultRootPath(String) from the type StandardVMType is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 22. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstallType.java + [javac] (at line 240) + [javac] return super.getDefaultJavadocLocation(installLocation); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getDefaultJavadocLocation(File) from the type StandardVMType is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 23. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstallType.java + [javac] (at line 247) + [javac] return super.getVMVersion(javaHome, javaExecutable); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getVMVersion(File, File) from the type StandardVMType is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] ---------- + [javac] 24. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMRunner.java + [javac] (at line 16) + [javac] import org.eclipse.jdt.internal.launching.StandardVMRunner; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StandardVMRunner is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 25. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMRunner.java + [javac] (at line 19) + [javac] public class MacOSXVMRunner extends StandardVMRunner { + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StandardVMRunner is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 26. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMRunner.java + [javac] (at line 22) + [javac] super(vmInstance); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor StandardVMRunner(IVMInstall) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 26 problems (26 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DetailFormatterDialog.java + [javac] (at line 36) + [javac] import org.eclipse.jdt.internal.ui.dialogs.StatusInfo; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DetailFormatterDialog.java + [javac] (at line 282) + [javac] StatusInfo status= new StatusInfo(); + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DetailFormatterDialog.java + [javac] (at line 282) + [javac] StatusInfo status= new StatusInfo(); + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor StatusInfo() is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 4. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DetailFormatterDialog.java + [javac] (at line 282) + [javac] StatusInfo status= new StatusInfo(); + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 5. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DetailFormatterDialog.java + [javac] (at line 285) + [javac] status.setError(DebugUIMessages.DetailFormatterDialog_Qualified_type_name_must_not_be_empty__3); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setError(String) from the type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 6. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DetailFormatterDialog.java + [javac] (at line 287) + [javac] status.setError(DebugUIMessages.DetailFormatterDialog_A_detail_formatter_is_already_defined_for_this_type_2); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setError(String) from the type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 7. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DetailFormatterDialog.java + [javac] (at line 289) + [javac] status.setError(DebugUIMessages.DetailFormatterDialog_Associated_code_must_not_be_empty_3); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setError(String) from the type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 8. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DetailFormatterDialog.java + [javac] (at line 291) + [javac] status.setWarning(DebugUIMessages.No_type_with_the_given_name_found_in_the_workspace__1); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setWarning(String) from the type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 9. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EditLogicalStructureDialog.java + [javac] (at line 38) + [javac] import org.eclipse.jdt.internal.ui.dialogs.StatusInfo; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 10. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EditLogicalStructureDialog.java + [javac] (at line 667) + [javac] StatusInfo status= new StatusInfo(); + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 11. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EditLogicalStructureDialog.java + [javac] (at line 667) + [javac] StatusInfo status= new StatusInfo(); + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor StatusInfo() is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 12. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EditLogicalStructureDialog.java + [javac] (at line 667) + [javac] StatusInfo status= new StatusInfo(); + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 13. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EditLogicalStructureDialog.java + [javac] (at line 669) + [javac] status.setError(DebugUIMessages.EditLogicalStructureDialog_16); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setError(String) from the type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 14. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EditLogicalStructureDialog.java + [javac] (at line 671) + [javac] status.setError(DebugUIMessages.EditLogicalStructureDialog_17); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setError(String) from the type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 15. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EditLogicalStructureDialog.java + [javac] (at line 673) + [javac] status.setError(DebugUIMessages.EditLogicalStructureDialog_18); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setError(String) from the type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 16. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EditLogicalStructureDialog.java + [javac] (at line 678) + [javac] status.setError(DebugUIMessages.EditLogicalStructureDialog_19); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setError(String) from the type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 17. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EditLogicalStructureDialog.java + [javac] (at line 680) + [javac] status.setError(DebugUIMessages.EditLogicalStructureDialog_20); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setError(String) from the type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 18. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EditLogicalStructureDialog.java + [javac] (at line 682) + [javac] status.setError(DebugUIMessages.EditLogicalStructureDialog_21); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setError(String) from the type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 19. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EditLogicalStructureDialog.java + [javac] (at line 687) + [javac] status.setError(DebugUIMessages.EditLogicalStructureDialog_22); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setError(String) from the type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 20. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EditLogicalStructureDialog.java + [javac] (at line 692) + [javac] status.setError(MessageFormat.format(DebugUIMessages.EditLogicalStructureDialog_23, new String[] {variable[0]})); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setError(String) from the type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 21. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EditLogicalStructureDialog.java + [javac] (at line 699) + [javac] if (!status.isError()) { + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method isError() from the type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 22. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EditLogicalStructureDialog.java + [javac] (at line 701) + [javac] status.setWarning(DebugUIMessages.EditLogicalStructureDialog_24); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setWarning(String) from the type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 23. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EvaluationContextManager.java + [javac] (at line 19) + [javac] import org.eclipse.debug.internal.ui.contexts.DebugContextManager; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugContextManager is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 24. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EvaluationContextManager.java + [javac] (at line 20) + [javac] import org.eclipse.debug.internal.ui.contexts.provisional.IDebugContextListener; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDebugContextListener is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 25. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EvaluationContextManager.java + [javac] (at line 39) + [javac] public class EvaluationContextManager implements IWindowListener, IDebugContextListener { + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDebugContextListener is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 26. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EvaluationContextManager.java + [javac] (at line 59) + [javac] DebugContextManager.getDefault().addDebugContextListener(this); + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugContextManager is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 27. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EvaluationContextManager.java + [javac] (at line 59) + [javac] DebugContextManager.getDefault().addDebugContextListener(this); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getDefault() from the type DebugContextManager is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 28. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EvaluationContextManager.java + [javac] (at line 59) + [javac] DebugContextManager.getDefault().addDebugContextListener(this); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method addDebugContextListener(IDebugContextListener) from the type IDebugContextManager is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 29. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java + [javac] (at line 73) + [javac] import org.eclipse.jdt.internal.ui.JavaPlugin; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 30. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java + [javac] (at line 74) + [javac] import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type EditorUtility is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 31. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java + [javac] (at line 75) + [javac] import org.eclipse.jdt.internal.ui.viewsupport.ImageDescriptorRegistry; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ImageDescriptorRegistry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 32. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java + [javac] (at line 115) + [javac] private ImageDescriptorRegistry fJavaElementImageRegistry; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ImageDescriptorRegistry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 33. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java + [javac] (at line 861) + [javac] return getJavaElementImageRegistry().get(descriptor); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method get(ImageDescriptor) from the type ImageDescriptorRegistry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 34. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java + [javac] (at line 1062) + [javac] return EditorUtility.getEditorInput(item); + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The type EditorUtility is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 35. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java + [javac] (at line 1062) + [javac] return EditorUtility.getEditorInput(item); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getEditorInput(Object) from the type EditorUtility is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 36. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java + [javac] (at line 1877) + [javac] protected ImageDescriptorRegistry getJavaElementImageRegistry() { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ImageDescriptorRegistry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 37. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java + [javac] (at line 1879) + [javac] fJavaElementImageRegistry = JavaPlugin.getImageDescriptorRegistry(); + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 38. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java + [javac] (at line 1879) + [javac] fJavaElementImageRegistry = JavaPlugin.getImageDescriptorRegistry(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getImageDescriptorRegistry() from the type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 39. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugHover.java + [javac] (at line 38) + [javac] import org.eclipse.jdt.internal.ui.text.HTMLTextPresenter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type HTMLTextPresenter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 40. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugHover.java + [javac] (at line 359) + [javac] new HTMLTextPresenter(true), + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor HTMLTextPresenter(boolean) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 41. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugHover.java + [javac] (at line 359) + [javac] new HTMLTextPresenter(true), + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type HTMLTextPresenter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 42. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaStepFilterPreferencePage.java + [javac] (at line 15) + [javac] import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IInternalDebugUIConstants is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 43. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaStepFilterPreferencePage.java + [javac] (at line 473) + [javac] boolean stepenabled = getPreferenceStore().getDefaultBoolean(IInternalDebugUIConstants.PREF_USE_STEP_FILTERS/*IDebugUIConstants.PREF_USE_STEP_FILTERS*/); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IInternalDebugUIConstants is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 44. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaStepFilterPreferencePage.java + [javac] (at line 473) + [javac] boolean stepenabled = getPreferenceStore().getDefaultBoolean(IInternalDebugUIConstants.PREF_USE_STEP_FILTERS/*IDebugUIConstants.PREF_USE_STEP_FILTERS*/); + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field PREF_USE_STEP_FILTERS from the type IInternalDebugUIConstants is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 45. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/TypeNameResolver.java + [javac] (at line 16) + [javac] import org.eclipse.debug.internal.ui.stringsubstitution.ResourceResolver; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ResourceResolver is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 46. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/TypeNameResolver.java + [javac] (at line 28) + [javac] public class TypeNameResolver extends ResourceResolver { + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ResourceResolver is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 47. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/TypeNameResolver.java + [javac] (at line 33) + [javac] IResource resource = getSelectedResource(variable); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getSelectedResource(IDynamicVariable) from the type ResourceResolver is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 48. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/TypeNameResolver.java + [javac] (at line 41) + [javac] abort(DebugUIMessages.TypeNameResolver_0, null); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method abort(String, Throwable) from the type ResourceResolver is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 49. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JavaObjectValueEditor.java + [javac] (at line 27) + [javac] import org.eclipse.debug.internal.ui.DebugUIPlugin; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugUIPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 50. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JavaObjectValueEditor.java + [javac] (at line 147) + [javac] IStatus status = DebugUIPlugin.newErrorStatus(cause.getMessage(), null); + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugUIPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 51. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JavaObjectValueEditor.java + [javac] (at line 147) + [javac] IStatus status = DebugUIPlugin.newErrorStatus(cause.getMessage(), null); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method newErrorStatus(String, Throwable) from the type DebugUIPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 52. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JavaObjectValueEditor.java + [javac] (at line 150) + [javac] DebugUIPlugin.errorDialog(shell, ActionMessages.JavaObjectValueEditor_0, ActionMessages.JavaObjectValueEditor_1, e); // + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugUIPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 53. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JavaObjectValueEditor.java + [javac] (at line 150) + [javac] DebugUIPlugin.errorDialog(shell, ActionMessages.JavaObjectValueEditor_0, ActionMessages.JavaObjectValueEditor_1, e); // + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method errorDialog(Shell, String, String, Throwable) from the type DebugUIPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 54. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JavaObjectValueEditor.java + [javac] (at line 215) + [javac] DebugUIPlugin.errorDialog(shell, ActionMessages.JavaObjectValueEditor_2, + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugUIPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 55. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JavaObjectValueEditor.java + [javac] (at line 215) + [javac] DebugUIPlugin.errorDialog(shell, ActionMessages.JavaObjectValueEditor_2, + [javac] ActionMessages.JavaObjectValueEditor_3, status); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method errorDialog(Shell, String, String, IStatus) from the type DebugUIPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 56. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JavaPrimitiveValueEditor.java + [javac] (at line 17) + [javac] import org.eclipse.debug.internal.ui.DebugUIPlugin; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugUIPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 57. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JavaPrimitiveValueEditor.java + [javac] (at line 69) + [javac] DebugUIPlugin.errorDialog(shell, ActionMessages.JavaPrimitiveValueEditor_2, ActionMessages.JavaPrimitiveValueEditor_3, e); // + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugUIPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 58. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JavaPrimitiveValueEditor.java + [javac] (at line 69) + [javac] DebugUIPlugin.errorDialog(shell, ActionMessages.JavaPrimitiveValueEditor_2, ActionMessages.JavaPrimitiveValueEditor_3, e); // + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method errorDialog(Shell, String, String, Throwable) from the type DebugUIPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 59. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JavaVariableValueEditor.java + [javac] (at line 15) + [javac] import org.eclipse.debug.internal.ui.DebugUIPlugin; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugUIPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 60. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JavaVariableValueEditor.java + [javac] (at line 34) + [javac] DebugUIPlugin.errorDialog(shell, ActionMessages.JavaVariableValueEditor_0, ActionMessages.JavaVariableValueEditor_1, e); // + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugUIPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 61. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JavaVariableValueEditor.java + [javac] (at line 34) + [javac] DebugUIPlugin.errorDialog(shell, ActionMessages.JavaVariableValueEditor_0, ActionMessages.JavaVariableValueEditor_1, e); // + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method errorDialog(Shell, String, String, Throwable) from the type DebugUIPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 62. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JavaVariableValueEditor.java + [javac] (at line 59) + [javac] DebugUIPlugin.errorDialog(shell, ActionMessages.JavaVariableValueEditor_0, ActionMessages.JavaVariableValueEditor_1, e); // + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugUIPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 63. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JavaVariableValueEditor.java + [javac] (at line 59) + [javac] DebugUIPlugin.errorDialog(shell, ActionMessages.JavaVariableValueEditor_0, ActionMessages.JavaVariableValueEditor_1, e); // + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method errorDialog(Shell, String, String, Throwable) from the type DebugUIPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 64. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/OpenTypeAction.java + [javac] (at line 35) + [javac] import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type EditorUtility is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 65. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/OpenTypeAction.java + [javac] (at line 36) + [javac] import org.eclipse.jdt.internal.ui.util.OpenTypeHierarchyUtil; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OpenTypeHierarchyUtil is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 66. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/OpenTypeAction.java + [javac] (at line 110) + [javac] OpenTypeHierarchyUtil.open((IJavaElement)sourceElement, getWorkbenchWindow()); + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type OpenTypeHierarchyUtil is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 67. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/OpenTypeAction.java + [javac] (at line 110) + [javac] OpenTypeHierarchyUtil.open((IJavaElement)sourceElement, getWorkbenchWindow()); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method open(IJavaElement, IWorkbenchWindow) from the type OpenTypeHierarchyUtil is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 68. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/OpenTypeAction.java + [javac] (at line 115) + [javac] IEditorPart part= EditorUtility.openInEditor(sourceElement); + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The type EditorUtility is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 69. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/OpenTypeAction.java + [javac] (at line 115) + [javac] IEditorPart part= EditorUtility.openInEditor(sourceElement); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method openInEditor(Object) from the type EditorUtility is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 70. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/OpenTypeAction.java + [javac] (at line 117) + [javac] EditorUtility.revealInEditor(part, ((IJavaElement)sourceElement)); + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The type EditorUtility is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 71. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/OpenTypeAction.java + [javac] (at line 117) + [javac] EditorUtility.revealInEditor(part, ((IJavaElement)sourceElement)); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method revealInEditor(IEditorPart, IJavaElement) from the type EditorUtility is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 72. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/PopupDisplayAction.java + [javac] (at line 17) + [javac] import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaEditor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 73. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/PopupDisplayAction.java + [javac] (at line 94) + [javac] if (part instanceof JavaEditor) { + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type JavaEditor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 74. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/PopupDisplayAction.java + [javac] (at line 95) + [javac] viewer = ((JavaEditor)part).getViewer(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getViewer() from the type JavaEditor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 75. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/PopupDisplayAction.java + [javac] (at line 95) + [javac] viewer = ((JavaEditor)part).getViewer(); + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type JavaEditor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 76. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/PopupInspectAction.java + [javac] (at line 18) + [javac] import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaEditor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 77. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/PopupInspectAction.java + [javac] (at line 37) + [javac] if (part instanceof JavaEditor) { + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type JavaEditor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 78. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/PopupInspectAction.java + [javac] (at line 38) + [javac] viewer = ((JavaEditor) part).getViewer(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getViewer() from the type JavaEditor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 79. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/PopupInspectAction.java + [javac] (at line 38) + [javac] viewer = ((JavaEditor) part).getViewer(); + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type JavaEditor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 80. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ShowStratumAction.java + [javac] (at line 17) + [javac] import org.eclipse.debug.internal.ui.sourcelookup.SourceLookupManager; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type SourceLookupManager is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 81. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ShowStratumAction.java + [javac] (at line 136) + [javac] SourceLookupManager.getDefault().displaySource(frame, fPart.getSite().getPage(), true); + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type SourceLookupManager is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 82. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ShowStratumAction.java + [javac] (at line 136) + [javac] SourceLookupManager.getDefault().displaySource(frame, fPart.getSite().getPage(), true); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getDefault() from the type SourceLookupManager is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 83. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ShowStratumAction.java + [javac] (at line 136) + [javac] SourceLookupManager.getDefault().displaySource(frame, fPart.getSite().getPage(), true); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method displaySource(Object, IWorkbenchPage, boolean) from the type SourceLookupManager is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 84. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/breakpoints/ExceptionInspector.java + [javac] (at line 20) + [javac] import org.eclipse.debug.internal.ui.contexts.DebugContextManager; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugContextManager is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 85. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/breakpoints/ExceptionInspector.java + [javac] (at line 21) + [javac] import org.eclipse.debug.internal.ui.contexts.provisional.IDebugContextListener; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDebugContextListener is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 86. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/breakpoints/ExceptionInspector.java + [javac] (at line 22) + [javac] import org.eclipse.debug.internal.ui.contexts.provisional.IDebugContextManager; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDebugContextManager is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 87. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/breakpoints/ExceptionInspector.java + [javac] (at line 43) + [javac] public class ExceptionInspector implements IDebugContextListener, IPropertyChangeListener { + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDebugContextListener is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 88. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/breakpoints/ExceptionInspector.java + [javac] (at line 49) + [javac] DebugContextManager.getDefault().addDebugContextListener(this); + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugContextManager is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 89. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/breakpoints/ExceptionInspector.java + [javac] (at line 49) + [javac] DebugContextManager.getDefault().addDebugContextListener(this); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getDefault() from the type DebugContextManager is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 90. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/breakpoints/ExceptionInspector.java + [javac] (at line 49) + [javac] DebugContextManager.getDefault().addDebugContextListener(this); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method addDebugContextListener(IDebugContextListener) from the type IDebugContextManager is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 91. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/breakpoints/ExceptionInspector.java + [javac] (at line 109) + [javac] IDebugContextManager manager = DebugContextManager.getDefault(); + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDebugContextManager is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 92. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/breakpoints/ExceptionInspector.java + [javac] (at line 109) + [javac] IDebugContextManager manager = DebugContextManager.getDefault(); + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugContextManager is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 93. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/breakpoints/ExceptionInspector.java + [javac] (at line 109) + [javac] IDebugContextManager manager = DebugContextManager.getDefault(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getDefault() from the type DebugContextManager is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 94. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/breakpoints/ExceptionInspector.java + [javac] (at line 111) + [javac] manager.addDebugContextListener(this); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method addDebugContextListener(IDebugContextListener) from the type IDebugContextManager is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 95. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/breakpoints/ExceptionInspector.java + [javac] (at line 113) + [javac] manager.removeDebugContextListener(this); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method removeDebugContextListener(IDebugContextListener) from the type IDebugContextManager is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 96. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaStackTraceConsole.java + [javac] (at line 19) + [javac] import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDebugPreferenceConstants is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 97. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaStackTraceConsole.java + [javac] (at line 41) + [javac] if (property.equals(IDebugPreferenceConstants.CONSOLE_FONT)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDebugPreferenceConstants is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 98. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaStackTraceConsole.java + [javac] (at line 41) + [javac] if (property.equals(IDebugPreferenceConstants.CONSOLE_FONT)) { + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The field CONSOLE_FONT from the type IDebugPreferenceConstants is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 99. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaStackTraceConsole.java + [javac] (at line 42) + [javac] setFont(JFaceResources.getFont(IDebugPreferenceConstants.CONSOLE_FONT)); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDebugPreferenceConstants is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 100. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaStackTraceConsole.java + [javac] (at line 42) + [javac] setFont(JFaceResources.getFont(IDebugPreferenceConstants.CONSOLE_FONT)); + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The field CONSOLE_FONT from the type IDebugPreferenceConstants is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 101. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaStackTraceConsole.java + [javac] (at line 49) + [javac] Font font = JFaceResources.getFont(IDebugPreferenceConstants.CONSOLE_FONT); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDebugPreferenceConstants is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 102. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaStackTraceConsole.java + [javac] (at line 49) + [javac] Font font = JFaceResources.getFont(IDebugPreferenceConstants.CONSOLE_FONT); + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The field CONSOLE_FONT from the type IDebugPreferenceConstants is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 103. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/JavaDebugContentAssistProcessor.java + [javac] (at line 18) + [javac] import org.eclipse.jdt.internal.ui.JavaPlugin; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 104. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/JavaDebugContentAssistProcessor.java + [javac] (at line 19) + [javac] import org.eclipse.jdt.internal.ui.text.java.JavaParameterListValidator; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaParameterListValidator is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 105. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/JavaDebugContentAssistProcessor.java + [javac] (at line 20) + [javac] import org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateEngine; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type TemplateEngine is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 106. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/JavaDebugContentAssistProcessor.java + [javac] (at line 41) + [javac] private TemplateEngine fTemplateEngine; + [javac] ^^^^^^^^^^^^^^ + [javac] Discouraged access: The type TemplateEngine is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 107. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/JavaDebugContentAssistProcessor.java + [javac] (at line 50) + [javac] TemplateContextType contextType= JavaPlugin.getDefault().getTemplateContextRegistry().getContextType("java"); //$NON-NLS-1$ + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 108. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/JavaDebugContentAssistProcessor.java + [javac] (at line 50) + [javac] TemplateContextType contextType= JavaPlugin.getDefault().getTemplateContextRegistry().getContextType("java"); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getDefault() from the type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 109. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/JavaDebugContentAssistProcessor.java + [javac] (at line 50) + [javac] TemplateContextType contextType= JavaPlugin.getDefault().getTemplateContextRegistry().getContextType("java"); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getTemplateContextRegistry() from the type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 110. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/JavaDebugContentAssistProcessor.java + [javac] (at line 52) + [javac] fTemplateEngine= new TemplateEngine(contextType); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor TemplateEngine(TemplateContextType) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 111. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/JavaDebugContentAssistProcessor.java + [javac] (at line 52) + [javac] fTemplateEngine= new TemplateEngine(contextType); + [javac] ^^^^^^^^^^^^^^ + [javac] Discouraged access: The type TemplateEngine is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 112. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/JavaDebugContentAssistProcessor.java + [javac] (at line 88) + [javac] fValidator= new JavaParameterListValidator(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor JavaParameterListValidator() is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 113. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/JavaDebugContentAssistProcessor.java + [javac] (at line 88) + [javac] fValidator= new JavaParameterListValidator(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaParameterListValidator is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 114. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/JavaDebugContentAssistProcessor.java + [javac] (at line 143) + [javac] fTemplateEngine.reset(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method reset() from the type TemplateEngine is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 115. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/JavaDebugContentAssistProcessor.java + [javac] (at line 144) + [javac] fTemplateEngine.complete(viewer, documentOffset, null); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method complete(ITextViewer, int, ICompilationUnit) from the type TemplateEngine is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 116. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/JavaDebugContentAssistProcessor.java + [javac] (at line 145) + [javac] IJavaCompletionProposal[] templateResults= fTemplateEngine.getResults(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getResults() from the type TemplateEngine is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 117. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 27) + [javac] import org.eclipse.jdt.internal.ui.dialogs.StatusInfo; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 118. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 28) + [javac] import org.eclipse.jdt.internal.ui.wizards.dialogfields.ComboDialogField; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ComboDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 119. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 29) + [javac] import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 120. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 30) + [javac] import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDialogFieldListener is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 121. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 31) + [javac] import org.eclipse.jdt.internal.ui.wizards.dialogfields.IStringButtonAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IStringButtonAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 122. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 32) + [javac] import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringButtonDialogField; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StringButtonDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 123. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 33) + [javac] import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringDialogField; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 124. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 64) + [javac] private ComboDialogField fVMTypeCombo; + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ComboDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 125. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 67) + [javac] private StringButtonDialogField fJRERoot; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StringButtonDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 126. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 68) + [javac] private StringDialogField fVMName; + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 127. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 70) + [javac] private StringDialogField fVMArgs; + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 128. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 85) + [javac] fStati[i]= new StatusInfo(); + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor StatusInfo() is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 129. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 85) + [javac] fStati[i]= new StatusInfo(); + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 130. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 106) + [javac] fVMTypeCombo= new ComboDialogField(SWT.READ_ONLY); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor ComboDialogField(int) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 131. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 106) + [javac] fVMTypeCombo= new ComboDialogField(SWT.READ_ONLY); + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ComboDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 132. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 107) + [javac] fVMTypeCombo.setLabelText(JREMessages.addVMDialog_jreType); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setLabelText(String) from the type DialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 133. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 108) + [javac] fVMTypeCombo.setItems(getVMTypeNames()); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setItems(String[]) from the type ComboDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 134. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 110) + [javac] fVMName= new StringDialogField(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor StringDialogField() is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 135. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 110) + [javac] fVMName= new StringDialogField(); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 136. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 111) + [javac] fVMName.setLabelText(JREMessages.addVMDialog_jreName); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setLabelText(String) from the type DialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 137. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 113) + [javac] fJRERoot= new StringButtonDialogField(new IStringButtonAdapter() { + [javac] public void changeControlPressed(DialogField field) { + [javac] browseForInstallDir(); + [javac] } + [javac] }); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor StringButtonDialogField(IStringButtonAdapter) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 138. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 113) + [javac] fJRERoot= new StringButtonDialogField(new IStringButtonAdapter() { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StringButtonDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 139. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 113) + [javac] fJRERoot= new StringButtonDialogField(new IStringButtonAdapter() { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IStringButtonAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 140. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 114) + [javac] public void changeControlPressed(DialogField field) { + [javac] ^^^^^^^^^^^ + [javac] Discouraged access: The type DialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 141. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 118) + [javac] fJRERoot.setLabelText(JREMessages.addVMDialog_jreHome); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setLabelText(String) from the type DialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 142. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 119) + [javac] fJRERoot.setButtonLabel(JREMessages.addVMDialog_browse1); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setButtonLabel(String) from the type StringButtonDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 143. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 121) + [javac] fVMArgs= new StringDialogField(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor StringDialogField() is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 144. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 121) + [javac] fVMArgs= new StringDialogField(); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 145. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 122) + [javac] fVMArgs.setLabelText(JREMessages.AddVMDialog_23); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setLabelText(String) from the type DialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 146. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 126) + [javac] fVMTypeCombo.setDialogFieldListener(new IDialogFieldListener() { + [javac] public void dialogFieldChanged(DialogField field) { + [javac] updateVMType(); + [javac] } + [javac] }); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setDialogFieldListener(IDialogFieldListener) from the type DialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 147. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 126) + [javac] fVMTypeCombo.setDialogFieldListener(new IDialogFieldListener() { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDialogFieldListener is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 148. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 127) + [javac] public void dialogFieldChanged(DialogField field) { + [javac] ^^^^^^^^^^^ + [javac] Discouraged access: The type DialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 149. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 132) + [javac] fVMName.setDialogFieldListener(new IDialogFieldListener() { + [javac] public void dialogFieldChanged(DialogField field) { + [javac] setVMNameStatus(validateVMName()); + [javac] updateStatusLine(); + [javac] } + [javac] }); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setDialogFieldListener(IDialogFieldListener) from the type DialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 150. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 132) + [javac] fVMName.setDialogFieldListener(new IDialogFieldListener() { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDialogFieldListener is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 151. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 133) + [javac] public void dialogFieldChanged(DialogField field) { + [javac] ^^^^^^^^^^^ + [javac] Discouraged access: The type DialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 152. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 139) + [javac] fJRERoot.setDialogFieldListener(new IDialogFieldListener() { + [javac] public void dialogFieldChanged(DialogField field) { + [javac] setJRELocationStatus(validateJRELocation()); + [javac] updateStatusLine(); + [javac] } + [javac] }); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setDialogFieldListener(IDialogFieldListener) from the type DialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 153. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 139) + [javac] fJRERoot.setDialogFieldListener(new IDialogFieldListener() { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IDialogFieldListener is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 154. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 140) + [javac] public void dialogFieldChanged(DialogField field) { + [javac] ^^^^^^^^^^^ + [javac] Discouraged access: The type DialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 155. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 149) + [javac] return fVMName.getText(); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getText() from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 156. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 153) + [javac] return new File(fJRERoot.getText()); + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getText() from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 157. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 161) + [javac] fVMTypeCombo.doFillIntoGrid(parent, 3); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method doFillIntoGrid(Composite, int) from the type ComboDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 158. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 162) + [javac] ((GridData)fVMTypeCombo.getComboControl(null).getLayoutData()).widthHint= convertWidthInCharsToPixels(50); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getComboControl(Composite) from the type ComboDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 159. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 164) + [javac] fVMName.doFillIntoGrid(parent, 3); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method doFillIntoGrid(Composite, int) from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 160. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 166) + [javac] fJRERoot.doFillIntoGrid(parent, 3); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method doFillIntoGrid(Composite, int) from the type StringButtonDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 161. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 168) + [javac] fVMArgs.doFillIntoGrid(parent, 3); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method doFillIntoGrid(Composite, int) from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 162. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 169) + [javac] ((GridData)fVMArgs.getTextControl(null).getLayoutData()).widthHint= convertWidthInCharsToPixels(50); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getTextControl(Composite) from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 163. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 183) + [javac] Text t= fJRERoot.getTextControl(parent); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getTextControl(Composite) from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 164. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 195) + [javac] int selIndex= fVMTypeCombo.getSelectionIndex(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getSelectionIndex() from the type ComboDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 165. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 210) + [javac] fVMName.setFocus(); + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setFocus() from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 166. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 225) + [javac] fVMTypeCombo.selectItem(i); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method selectItem(int) from the type ComboDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 167. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 232) + [javac] fVMTypeCombo.setItems(getVMTypeNames()); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setItems(String[]) from the type ComboDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 168. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 234) + [javac] fVMName.setText(""); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setText(String) from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 169. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 235) + [javac] fJRERoot.setText(""); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setText(String) from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 170. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 237) + [javac] fVMArgs.setText(""); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setText(String) from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 171. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 239) + [javac] fVMTypeCombo.setEnabled(false); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setEnabled(boolean) from the type DialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 172. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 240) + [javac] fVMName.setText(fEditedVM.getName()); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setText(String) from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 173. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 241) + [javac] fJRERoot.setText(fEditedVM.getInstallLocation().getAbsolutePath()); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setText(String) from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 174. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 247) + [javac] fVMArgs.setText(vmArgs); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setText(String) from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 175. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 260) + [javac] fVMArgs.setText(buffer.toString()); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setText(String) from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 176. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 273) + [javac] String locationName= fJRERoot.getText(); + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getText() from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 177. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 277) + [javac] s = new StatusInfo(IStatus.INFO, JREMessages.addVMDialog_enterLocation); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor StatusInfo(int, String) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 178. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 277) + [javac] s = new StatusInfo(IStatus.INFO, JREMessages.addVMDialog_enterLocation); + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 179. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 281) + [javac] s = new StatusInfo(IStatus.ERROR, JREMessages.addVMDialog_locationNotExists); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor StatusInfo(int, String) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 180. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 281) + [javac] s = new StatusInfo(IStatus.ERROR, JREMessages.addVMDialog_locationNotExists); + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 181. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 299) + [javac] String name = fVMName.getText(); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getText() from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 182. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 317) + [javac] fVMName.setText(genName); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setText(String) from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 183. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 344) + [javac] StatusInfo status= new StatusInfo(); + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 184. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 344) + [javac] StatusInfo status= new StatusInfo(); + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor StatusInfo() is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 185. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 344) + [javac] StatusInfo status= new StatusInfo(); + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 186. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 345) + [javac] String name= fVMName.getText(); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getText() from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 187. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 347) + [javac] status.setInfo(JREMessages.addVMDialog_enterName); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setInfo(String) from the type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 188. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 350) + [javac] status.setError(JREMessages.addVMDialog_duplicateName); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setError(String) from the type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 189. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 354) + [javac] status.setError(MessageFormat.format(JREMessages.AddVMDialog_JRE_name_must_be_a_valid_file_name___0__1, new String[]{s.getMessage()})); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setError(String) from the type StatusInfo is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 190. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 378) + [javac] dialog.setFilterPath(fJRERoot.getText()); + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getText() from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 191. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 382) + [javac] fJRERoot.setText(newPath); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setText(String) from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 192. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 414) + [javac] File dir = new File(fJRERoot.getText()); + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getText() from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 193. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 420) + [javac] vm.setName(fVMName.getText()); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getText() from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 194. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/AddVMDialog.java + [javac] (at line 423) + [javac] String argString = fVMArgs.getText().trim(); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getText() from the type StringDialogField is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 195. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/InstalledJREsBlock.java + [javac] (at line 26) + [javac] import org.eclipse.debug.internal.ui.SWTUtil; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type SWTUtil is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 196. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/InstalledJREsBlock.java + [javac] (at line 533) + [javac] return SWTUtil.createPushButton(parent, label, null); + [javac] ^^^^^^^ + [javac] Discouraged access: The type SWTUtil is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 197. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/InstalledJREsBlock.java + [javac] (at line 533) + [javac] return SWTUtil.createPushButton(parent, label, null); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createPushButton(Composite, String, Image) from the type SWTUtil is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 198. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/JREsComboBlock.java + [javac] (at line 25) + [javac] import org.eclipse.debug.internal.ui.SWTUtil; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type SWTUtil is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 199. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/JREsComboBlock.java + [javac] (at line 332) + [javac] return SWTUtil.createPushButton(parent, label, null); + [javac] ^^^^^^^ + [javac] Discouraged access: The type SWTUtil is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 200. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/JREsComboBlock.java + [javac] (at line 332) + [javac] return SWTUtil.createPushButton(parent, label, null); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createPushButton(Composite, String, Image) from the type SWTUtil is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 201. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/LibraryLabelProvider.java + [javac] (at line 21) + [javac] import org.eclipse.jdt.internal.ui.JavaPlugin; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 202. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/LibraryLabelProvider.java + [javac] (at line 22) + [javac] import org.eclipse.jdt.internal.ui.JavaPluginImages; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaPluginImages is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 203. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/LibraryLabelProvider.java + [javac] (at line 23) + [javac] import org.eclipse.jdt.internal.ui.viewsupport.ImageDescriptorRegistry; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ImageDescriptorRegistry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 204. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/LibraryLabelProvider.java + [javac] (at line 37) + [javac] private ImageDescriptorRegistry fRegistry= JavaPlugin.getImageDescriptorRegistry(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ImageDescriptorRegistry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 205. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/LibraryLabelProvider.java + [javac] (at line 37) + [javac] private ImageDescriptorRegistry fRegistry= JavaPlugin.getImageDescriptorRegistry(); + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 206. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/LibraryLabelProvider.java + [javac] (at line 37) + [javac] private ImageDescriptorRegistry fRegistry= JavaPlugin.getImageDescriptorRegistry(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getImageDescriptorRegistry() from the type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 207. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/LibraryLabelProvider.java + [javac] (at line 58) + [javac] return fRegistry.get(JavaPluginImages.DESC_OBJS_SOURCE_ATTACH_ATTRIB); // todo: change image + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method get(ImageDescriptor) from the type ImageDescriptorRegistry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 208. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/LibraryLabelProvider.java + [javac] (at line 58) + [javac] return fRegistry.get(JavaPluginImages.DESC_OBJS_SOURCE_ATTACH_ATTRIB); // todo: change image + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaPluginImages is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 209. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/LibraryLabelProvider.java + [javac] (at line 58) + [javac] return fRegistry.get(JavaPluginImages.DESC_OBJS_SOURCE_ATTACH_ATTRIB); // todo: change image + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field DESC_OBJS_SOURCE_ATTACH_ATTRIB from the type JavaPluginImages is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 210. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/LibraryLabelProvider.java + [javac] (at line 60) + [javac] return fRegistry.get(JavaPluginImages.DESC_OBJS_JAVADOC_LOCATION_ATTRIB); // todo: change image + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method get(ImageDescriptor) from the type ImageDescriptorRegistry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 211. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/LibraryLabelProvider.java + [javac] (at line 60) + [javac] return fRegistry.get(JavaPluginImages.DESC_OBJS_JAVADOC_LOCATION_ATTRIB); // todo: change image + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaPluginImages is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 212. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/LibraryLabelProvider.java + [javac] (at line 60) + [javac] return fRegistry.get(JavaPluginImages.DESC_OBJS_JAVADOC_LOCATION_ATTRIB); // todo: change image + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field DESC_OBJS_JAVADOC_LOCATION_ATTRIB from the type JavaPluginImages is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 213. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncJavaContendedMonitorAdapter.java + [javac] (at line 14) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 214. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncJavaContendedMonitorAdapter.java + [javac] (at line 18) + [javac] protected Object[] getChildren(Object parent, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 215. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncJavaContendedMonitorAdapter.java + [javac] (at line 21) + [javac] return EMPTY; + [javac] ^^^^^ + [javac] Discouraged access: The field EMPTY from the type AsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 216. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncJavaContendedMonitorAdapter.java + [javac] (at line 26) + [javac] protected boolean hasChildren(Object element, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 217. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncJavaOwnedMonitorAdapter.java + [javac] (at line 14) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 218. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncJavaOwnedMonitorAdapter.java + [javac] (at line 18) + [javac] protected Object[] getChildren(Object parent, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 219. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncJavaOwnedMonitorAdapter.java + [javac] (at line 22) + [javac] protected boolean hasChildren(Object element, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 220. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncJavaOwningThreadAdapter.java + [javac] (at line 14) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 221. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncJavaOwningThreadAdapter.java + [javac] (at line 18) + [javac] protected Object[] getChildren(Object parent, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 222. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncJavaOwningThreadAdapter.java + [javac] (at line 21) + [javac] return EMPTY; + [javac] ^^^^^ + [javac] Discouraged access: The field EMPTY from the type AsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 223. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncJavaOwningThreadAdapter.java + [javac] (at line 26) + [javac] protected boolean hasChildren(Object element, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 224. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncJavaThreadAdapter.java + [javac] (at line 17) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 225. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncJavaThreadAdapter.java + [javac] (at line 27) + [javac] protected Object[] getChildren(Object parent, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 226. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncJavaThreadAdapter.java + [javac] (at line 30) + [javac] return EMPTY; + [javac] ^^^^^ + [javac] Discouraged access: The field EMPTY from the type AsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 227. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncJavaThreadAdapter.java + [javac] (at line 66) + [javac] return EMPTY; + [javac] ^^^^^ + [javac] Discouraged access: The field EMPTY from the type AsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 228. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncJavaThreadAdapter.java + [javac] (at line 70) + [javac] protected boolean hasChildren(Object element, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 229. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncJavaWaitingThreadAdapter.java + [javac] (at line 14) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 230. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncJavaWaitingThreadAdapter.java + [javac] (at line 18) + [javac] protected Object[] getChildren(Object parent, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 231. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncJavaWaitingThreadAdapter.java + [javac] (at line 22) + [javac] protected boolean hasChildren(Object element, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 232. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncMonitorAdapter.java + [javac] (at line 13) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousContentAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 233. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/AsyncMonitorAdapter.java + [javac] (at line 21) + [javac] public abstract class AsyncMonitorAdapter extends AsynchronousContentAdapter implements IPropertyChangeListener { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 234. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/JavaDebugElementAdapterFactory.java + [javac] (at line 14) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 235. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/JavaDebugElementAdapterFactory.java + [javac] (at line 23) + [javac] private static IAsynchronousContentAdapter fgThreadAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 236. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/JavaDebugElementAdapterFactory.java + [javac] (at line 24) + [javac] private static IAsynchronousContentAdapter fgContendedMonitorAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 237. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/JavaDebugElementAdapterFactory.java + [javac] (at line 25) + [javac] private static IAsynchronousContentAdapter fgOwnedMonitorAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 238. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/JavaDebugElementAdapterFactory.java + [javac] (at line 26) + [javac] private static IAsynchronousContentAdapter fgOwningThreadAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 239. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/JavaDebugElementAdapterFactory.java + [javac] (at line 27) + [javac] private static IAsynchronousContentAdapter fgWaitingThreadAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 240. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/JavaDebugElementAdapterFactory.java + [javac] (at line 65) + [javac] private IAsynchronousContentAdapter getOwnedMonitorAdapater() { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 241. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/JavaDebugElementAdapterFactory.java + [javac] (at line 72) + [javac] private IAsynchronousContentAdapter getContendedMonitorAdapter() { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 242. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/JavaDebugElementAdapterFactory.java + [javac] (at line 83) + [javac] return new Class[] {IAsynchronousContentAdapter.class}; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 243. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/monitors/JavaDebugElementAdapterFactory.java + [javac] (at line 86) + [javac] private IAsynchronousContentAdapter getThreadAdapter() { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 244. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetCompletionProcessor.java + [javac] (at line 19) + [javac] import org.eclipse.jdt.internal.ui.JavaPlugin; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 245. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetCompletionProcessor.java + [javac] (at line 20) + [javac] import org.eclipse.jdt.internal.ui.text.java.JavaParameterListValidator; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaParameterListValidator is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 246. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetCompletionProcessor.java + [javac] (at line 21) + [javac] import org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateEngine; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type TemplateEngine is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 247. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetCompletionProcessor.java + [javac] (at line 22) + [javac] import org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateProposal; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type TemplateProposal is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 248. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetCompletionProcessor.java + [javac] (at line 43) + [javac] private TemplateEngine fTemplateEngine; + [javac] ^^^^^^^^^^^^^^ + [javac] Discouraged access: The type TemplateEngine is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 249. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetCompletionProcessor.java + [javac] (at line 51) + [javac] TemplateContextType contextType= JavaPlugin.getDefault().getTemplateContextRegistry().getContextType("java"); //$NON-NLS-1$ + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 250. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetCompletionProcessor.java + [javac] (at line 51) + [javac] TemplateContextType contextType= JavaPlugin.getDefault().getTemplateContextRegistry().getContextType("java"); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getDefault() from the type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 251. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetCompletionProcessor.java + [javac] (at line 51) + [javac] TemplateContextType contextType= JavaPlugin.getDefault().getTemplateContextRegistry().getContextType("java"); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getTemplateContextRegistry() from the type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 252. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetCompletionProcessor.java + [javac] (at line 53) + [javac] fTemplateEngine= new TemplateEngine(contextType); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor TemplateEngine(TemplateContextType) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 253. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetCompletionProcessor.java + [javac] (at line 53) + [javac] fTemplateEngine= new TemplateEngine(contextType); + [javac] ^^^^^^^^^^^^^^ + [javac] Discouraged access: The type TemplateEngine is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 254. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetCompletionProcessor.java + [javac] (at line 78) + [javac] fValidator= new JavaParameterListValidator(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor JavaParameterListValidator() is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 255. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetCompletionProcessor.java + [javac] (at line 78) + [javac] fValidator= new JavaParameterListValidator(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaParameterListValidator is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 256. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetCompletionProcessor.java + [javac] (at line 116) + [javac] fTemplateEngine.reset(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method reset() from the type TemplateEngine is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 257. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetCompletionProcessor.java + [javac] (at line 117) + [javac] fTemplateEngine.complete(viewer, position, null); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method complete(ITextViewer, int, ICompilationUnit) from the type TemplateEngine is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 258. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetCompletionProcessor.java + [javac] (at line 119) + [javac] TemplateProposal[] templateResults= fTemplateEngine.getResults(); + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type TemplateProposal is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 259. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetCompletionProcessor.java + [javac] (at line 119) + [javac] TemplateProposal[] templateResults= fTemplateEngine.getResults(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getResults() from the type TemplateEngine is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 260. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/SelectImportsDialog.java + [javac] (at line 29) + [javac] import org.eclipse.jdt.internal.ui.util.SWTUtil; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type SWTUtil is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 261. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/SelectImportsDialog.java + [javac] (at line 203) + [javac] SWTUtil.setButtonDimensionHint(button); + [javac] ^^^^^^^ + [javac] Discouraged access: The type SWTUtil is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 262. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/SelectImportsDialog.java + [javac] (at line 203) + [javac] SWTUtil.setButtonDimensionHint(button); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setButtonDimensionHint(Button) from the type SWTUtil is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 263. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/ShowInPackageViewAction.java + [javac] (at line 15) + [javac] import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IJavaHelpContextIds is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 264. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/ShowInPackageViewAction.java + [javac] (at line 16) + [javac] import org.eclipse.jdt.internal.ui.packageview.PackageExplorerPart; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type PackageExplorerPart is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 265. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/ShowInPackageViewAction.java + [javac] (at line 45) + [javac] PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.SHOW_IN_PACKAGEVIEW_ACTION); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IJavaHelpContextIds is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 266. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/ShowInPackageViewAction.java + [javac] (at line 45) + [javac] PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.SHOW_IN_PACKAGEVIEW_ACTION); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field SHOW_IN_PACKAGEVIEW_ACTION from the type IJavaHelpContextIds is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 267. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/ShowInPackageViewAction.java + [javac] (at line 64) + [javac] PackageExplorerPart view= PackageExplorerPart.openInActivePerspective(); + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type PackageExplorerPart is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 268. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/ShowInPackageViewAction.java + [javac] (at line 64) + [javac] PackageExplorerPart view= PackageExplorerPart.openInActivePerspective(); + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type PackageExplorerPart is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 269. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/ShowInPackageViewAction.java + [javac] (at line 64) + [javac] PackageExplorerPart view= PackageExplorerPart.openInActivePerspective(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method openInActivePerspective() from the type PackageExplorerPart is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 270. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/ShowInPackageViewAction.java + [javac] (at line 70) + [javac] private boolean reveal(PackageExplorerPart view, Object element) { + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type PackageExplorerPart is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 271. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/ShowInPackageViewAction.java + [javac] (at line 74) + [javac] view.selectReveal(new StructuredSelection(element)); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method selectReveal(ISelection) from the type PackageExplorerPart is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 272. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/ShowInPackageViewAction.java + [javac] (at line 75) + [javac] IElementComparer comparer= view.getTreeViewer().getComparer(); + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getTreeViewer() from the type PackageExplorerPart is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 273. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/ShowInPackageViewAction.java + [javac] (at line 83) + [javac] private Object getSelectedElement(PackageExplorerPart view) { + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type PackageExplorerPart is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 274. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/SnippetEditorActionContributor.java + [javac] (at line 15) + [javac] import org.eclipse.jdt.internal.ui.javaeditor.BasicCompilationUnitEditorActionContributor; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type BasicCompilationUnitEditorActionContributor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 275. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/SnippetEditorActionContributor.java + [javac] (at line 25) + [javac] public class SnippetEditorActionContributor extends BasicCompilationUnitEditorActionContributor { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type BasicCompilationUnitEditorActionContributor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 276. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/SnippetEditorActionContributor.java + [javac] (at line 35) + [javac] super(); + [javac] ^^^^^^^ + [javac] Discouraged access: The constructor BasicCompilationUnitEditorActionContributor() is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 277. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/SnippetEditorActionContributor.java + [javac] (at line 59) + [javac] super.contributeToMenu(menu); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method contributeToMenu(IMenuManager) from the type BasicCompilationUnitEditorActionContributor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 278. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/SnippetEditorActionContributor.java + [javac] (at line 74) + [javac] super.setActiveEditor(part); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setActiveEditor(IEditorPart) from the type BasicCompilationUnitEditorActionContributor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 279. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugElementLabelAdapterFactory.java + [javac] (at line 14) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 280. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugElementLabelAdapterFactory.java + [javac] (at line 15) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousLabelAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 281. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugElementLabelAdapterFactory.java + [javac] (at line 16) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxyFactoryAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IModelProxyFactoryAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 282. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugElementLabelAdapterFactory.java + [javac] (at line 26) + [javac] private static IAsynchronousLabelAdapter fgThreadGroupLabelAdapter = new JavaThreadGroupLabelAdapter(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousLabelAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 283. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugElementLabelAdapterFactory.java + [javac] (at line 27) + [javac] private static IAsynchronousContentAdapter fgThreadGroupTreeAdapter = new JavaThreadGroupContentAdapter(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 284. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugElementLabelAdapterFactory.java + [javac] (at line 28) + [javac] private static IAsynchronousContentAdapter fgTargetTreeAdapter = new JavaDebugTargetContentAdapter(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 285. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugElementLabelAdapterFactory.java + [javac] (at line 29) + [javac] private static IModelProxyFactoryAdapter fgJavaModelProxyFactory = new JavaModelProxyFactory(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IModelProxyFactoryAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 286. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugElementLabelAdapterFactory.java + [javac] (at line 35) + [javac] if (adapterType.equals(IAsynchronousLabelAdapter.class)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousLabelAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 287. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugElementLabelAdapterFactory.java + [javac] (at line 40) + [javac] if (adapterType.equals(IAsynchronousContentAdapter.class)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 288. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugElementLabelAdapterFactory.java + [javac] (at line 48) + [javac] if (adapterType.equals(IModelProxyFactoryAdapter.class)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IModelProxyFactoryAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 289. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugElementLabelAdapterFactory.java + [javac] (at line 60) + [javac] return new Class[]{IAsynchronousLabelAdapter.class, IAsynchronousContentAdapter.class, IModelProxyFactoryAdapter.class}; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousLabelAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 290. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugElementLabelAdapterFactory.java + [javac] (at line 60) + [javac] return new Class[]{IAsynchronousLabelAdapter.class, IAsynchronousContentAdapter.class, IModelProxyFactoryAdapter.class}; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 291. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugElementLabelAdapterFactory.java + [javac] (at line 60) + [javac] return new Class[]{IAsynchronousLabelAdapter.class, IAsynchronousContentAdapter.class, IModelProxyFactoryAdapter.class}; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IModelProxyFactoryAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 292. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugTargetContentAdapter.java + [javac] (at line 15) + [javac] import org.eclipse.debug.internal.ui.elements.adapters.DebugTargetContentAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugTargetContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 293. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugTargetContentAdapter.java + [javac] (at line 16) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 294. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugTargetContentAdapter.java + [javac] (at line 27) + [javac] public class JavaDebugTargetContentAdapter extends DebugTargetContentAdapter { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugTargetContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 295. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugTargetContentAdapter.java + [javac] (at line 29) + [javac] protected Object[] getChildren(Object parent, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 296. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugTargetContentAdapter.java + [javac] (at line 30) + [javac] String id = context.getPart().getSite().getId(); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getPart() from the type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 297. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugTargetContentAdapter.java + [javac] (at line 39) + [javac] return super.getChildren(parent, context); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getChildren(Object, IPresentationContext) from the type DebugTargetContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 298. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugTargetProxy.java + [javac] (at line 14) + [javac] import org.eclipse.debug.internal.ui.viewers.update.DebugEventHandler; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugEventHandler is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 299. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugTargetProxy.java + [javac] (at line 15) + [javac] import org.eclipse.debug.internal.ui.viewers.update.DebugTargetEventHandler; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugTargetEventHandler is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 300. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugTargetProxy.java + [javac] (at line 16) + [javac] import org.eclipse.debug.internal.ui.viewers.update.DebugTargetProxy; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugTargetProxy is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 301. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugTargetProxy.java + [javac] (at line 22) + [javac] public class JavaDebugTargetProxy extends DebugTargetProxy { + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugTargetProxy is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 302. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugTargetProxy.java + [javac] (at line 28) + [javac] super(target); + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor DebugTargetProxy(IDebugTarget) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 303. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugTargetProxy.java + [javac] (at line 34) + [javac] protected DebugEventHandler[] createEventHandlers() { + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugEventHandler is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 304. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugTargetProxy.java + [javac] (at line 35) + [javac] return new DebugEventHandler[] { new DebugTargetEventHandler(this), new JavaThreadEventHandler(this) }; + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugEventHandler is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 305. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugTargetProxy.java + [javac] (at line 35) + [javac] return new DebugEventHandler[] { new DebugTargetEventHandler(this), new JavaThreadEventHandler(this) }; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor DebugTargetEventHandler(AbstractModelProxy) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 306. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugTargetProxy.java + [javac] (at line 35) + [javac] return new DebugEventHandler[] { new DebugTargetEventHandler(this), new JavaThreadEventHandler(this) }; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DebugTargetEventHandler is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 307. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaModelProxyFactory.java + [javac] (at line 14) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxy; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IModelProxy is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 308. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaModelProxyFactory.java + [javac] (at line 15) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IModelProxyFactoryAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IModelProxyFactoryAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 309. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaModelProxyFactory.java + [javac] (at line 16) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 310. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaModelProxyFactory.java + [javac] (at line 23) + [javac] public class JavaModelProxyFactory implements IModelProxyFactoryAdapter { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IModelProxyFactoryAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 311. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaModelProxyFactory.java + [javac] (at line 28) + [javac] public IModelProxy createModelProxy(Object element, IPresentationContext context) { + [javac] ^^^^^^^^^^^ + [javac] Discouraged access: The type IModelProxy is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 312. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaModelProxyFactory.java + [javac] (at line 28) + [javac] public IModelProxy createModelProxy(Object element, IPresentationContext context) { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 313. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 21) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AbstractModelProxy is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 314. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 22) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IModelDelta; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IModelDelta is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 315. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 23) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.ModelDelta; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ModelDelta is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 316. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 24) + [javac] import org.eclipse.debug.internal.ui.viewers.update.ThreadEventHandler; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ThreadEventHandler is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 317. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 35) + [javac] public class JavaThreadEventHandler extends ThreadEventHandler { + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ThreadEventHandler is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 318. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 42) + [javac] public JavaThreadEventHandler(AbstractModelProxy proxy) { + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AbstractModelProxy is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 319. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 43) + [javac] super(proxy); + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The constructor ThreadEventHandler(AbstractModelProxy) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 320. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 46) + [javac] protected ModelDelta addPathToThread(ModelDelta delta, IThread thread) { + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type ModelDelta is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 321. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 46) + [javac] protected ModelDelta addPathToThread(ModelDelta delta, IThread thread) { + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type ModelDelta is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 322. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 48) + [javac] delta = delta.addNode(thread.getLaunch(), IModelDelta.NO_CHANGE); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method addNode(Object, int) from the type ModelDelta is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 323. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 48) + [javac] delta = delta.addNode(thread.getLaunch(), IModelDelta.NO_CHANGE); + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IModelDelta is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 324. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 48) + [javac] delta = delta.addNode(thread.getLaunch(), IModelDelta.NO_CHANGE); + [javac] ^^^^^^^^^ + [javac] Discouraged access: The field NO_CHANGE from the type IModelDelta is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 325. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 49) + [javac] delta = delta.addNode(thread.getDebugTarget(), IModelDelta.NO_CHANGE); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method addNode(Object, int) from the type ModelDelta is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 326. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 49) + [javac] delta = delta.addNode(thread.getDebugTarget(), IModelDelta.NO_CHANGE); + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IModelDelta is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 327. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 49) + [javac] delta = delta.addNode(thread.getDebugTarget(), IModelDelta.NO_CHANGE); + [javac] ^^^^^^^^^ + [javac] Discouraged access: The field NO_CHANGE from the type IModelDelta is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 328. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 63) + [javac] delta = delta.addNode(iterator.next(), IModelDelta.NO_CHANGE); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method addNode(Object, int) from the type ModelDelta is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 329. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 63) + [javac] delta = delta.addNode(iterator.next(), IModelDelta.NO_CHANGE); + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IModelDelta is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 330. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 63) + [javac] delta = delta.addNode(iterator.next(), IModelDelta.NO_CHANGE); + [javac] ^^^^^^^^^ + [javac] Discouraged access: The field NO_CHANGE from the type IModelDelta is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 331. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 67) + [javac] return super.addPathToThread(delta, thread); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method addPathToThread(ModelDelta, IThread) from the type ThreadEventHandler is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 332. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadEventHandler.java + [javac] (at line 75) + [javac] if (super.handlesEvent(event)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method handlesEvent(DebugEvent) from the type ThreadEventHandler is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 333. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadGroupContentAdapter.java + [javac] (at line 14) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousContentAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 334. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadGroupContentAdapter.java + [javac] (at line 15) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 335. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadGroupContentAdapter.java + [javac] (at line 25) + [javac] public class JavaThreadGroupContentAdapter extends AsynchronousContentAdapter { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 336. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadGroupContentAdapter.java + [javac] (at line 27) + [javac] protected Object[] getChildren(Object parent, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 337. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadGroupContentAdapter.java + [javac] (at line 44) + [javac] return EMPTY; + [javac] ^^^^^ + [javac] Discouraged access: The field EMPTY from the type AsynchronousContentAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 338. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadGroupContentAdapter.java + [javac] (at line 47) + [javac] protected boolean hasChildren(Object element, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 339. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadGroupLabelAdapter.java + [javac] (at line 16) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.AsynchronousLabelAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AsynchronousLabelAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 340. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadGroupLabelAdapter.java + [javac] (at line 17) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 341. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadGroupLabelAdapter.java + [javac] (at line 29) + [javac] public class JavaThreadGroupLabelAdapter extends AsynchronousLabelAdapter { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AsynchronousLabelAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 342. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadGroupLabelAdapter.java + [javac] (at line 36) + [javac] protected String[] getLabels(Object element, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 343. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadGroupLabelAdapter.java + [javac] (at line 47) + [javac] protected ImageDescriptor[] getImageDescriptors(Object element, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 344. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadGroupLabelAdapter.java + [javac] (at line 54) + [javac] protected FontData[] getFontDatas(Object element, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 345. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadGroupLabelAdapter.java + [javac] (at line 61) + [javac] protected RGB[] getForegrounds(Object element, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 346. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaThreadGroupLabelAdapter.java + [javac] (at line 68) + [javac] protected RGB[] getBackgrounds(Object element, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 347. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/ColumnPresentationAdapterFactory.java + [javac] (at line 14) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousLabelAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousLabelAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 348. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/ColumnPresentationAdapterFactory.java + [javac] (at line 15) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditorFactoryAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IColumnEditorFactoryAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 349. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/ColumnPresentationAdapterFactory.java + [javac] (at line 16) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentationFactoryAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IColumnPresentationFactoryAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 350. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/ColumnPresentationAdapterFactory.java + [javac] (at line 27) + [javac] private static final IAsynchronousLabelAdapter fgLabel = new JavaVariableLabelAdapter(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousLabelAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 351. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/ColumnPresentationAdapterFactory.java + [javac] (at line 28) + [javac] private static final IColumnEditorFactoryAdapter fgColumnEditor = new JavaVariableColumnEditorFactory(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IColumnEditorFactoryAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 352. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/ColumnPresentationAdapterFactory.java + [javac] (at line 29) + [javac] private static final IColumnPresentationFactoryAdapter fgColumnPresentation = new JavaVariableColumnPresentationFactory(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IColumnPresentationFactoryAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 353. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/ColumnPresentationAdapterFactory.java + [javac] (at line 36) + [javac] if (IAsynchronousLabelAdapter.class.equals(adapterType)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousLabelAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 354. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/ColumnPresentationAdapterFactory.java + [javac] (at line 39) + [javac] if (IColumnEditorFactoryAdapter.class.equals(adapterType)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IColumnEditorFactoryAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 355. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/ColumnPresentationAdapterFactory.java + [javac] (at line 44) + [javac] if (IColumnPresentationFactoryAdapter.class.equals(adapterType)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IColumnPresentationFactoryAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 356. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/ColumnPresentationAdapterFactory.java + [javac] (at line 55) + [javac] return new Class[]{IAsynchronousLabelAdapter.class, IColumnEditorFactoryAdapter.class, IColumnPresentationFactoryAdapter.class}; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAsynchronousLabelAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 357. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/ColumnPresentationAdapterFactory.java + [javac] (at line 55) + [javac] return new Class[]{IAsynchronousLabelAdapter.class, IColumnEditorFactoryAdapter.class, IColumnPresentationFactoryAdapter.class}; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IColumnEditorFactoryAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 358. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/ColumnPresentationAdapterFactory.java + [javac] (at line 55) + [javac] return new Class[]{IAsynchronousLabelAdapter.class, IColumnEditorFactoryAdapter.class, IColumnPresentationFactoryAdapter.class}; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IColumnPresentationFactoryAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 359. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableCellModifier.java + [javac] (at line 14) + [javac] import org.eclipse.debug.internal.ui.elements.adapters.DefaultVariableCellModifier; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DefaultVariableCellModifier is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 360. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableCellModifier.java + [javac] (at line 15) + [javac] import org.eclipse.debug.internal.ui.elements.adapters.VariableColumnPresentation; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type VariableColumnPresentation is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 361. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableCellModifier.java + [javac] (at line 16) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 362. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableCellModifier.java + [javac] (at line 24) + [javac] public class JavaVariableCellModifier extends DefaultVariableCellModifier { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type DefaultVariableCellModifier is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 363. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableCellModifier.java + [javac] (at line 31) + [javac] public JavaVariableCellModifier(IPresentationContext context) { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 364. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableCellModifier.java + [javac] (at line 32) + [javac] super(context); + [javac] ^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor DefaultVariableCellModifier(IPresentationContext) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 365. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableCellModifier.java + [javac] (at line 42) + [javac] if (VariableColumnPresentation.COLUMN_VARIABLE_VALUE.equals(property)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type VariableColumnPresentation is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 366. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableCellModifier.java + [javac] (at line 42) + [javac] if (VariableColumnPresentation.COLUMN_VARIABLE_VALUE.equals(property)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field COLUMN_VARIABLE_VALUE from the type VariableColumnPresentation is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 367. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableCellModifier.java + [javac] (at line 66) + [javac] if (VariableColumnPresentation.COLUMN_VARIABLE_VALUE.equals(property)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type VariableColumnPresentation is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 368. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableCellModifier.java + [javac] (at line 66) + [javac] if (VariableColumnPresentation.COLUMN_VARIABLE_VALUE.equals(property)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field COLUMN_VARIABLE_VALUE from the type VariableColumnPresentation is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 369. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableCellModifier.java + [javac] (at line 81) + [javac] return super.getValue(element, property); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getValue(Object, String) from the type DefaultVariableCellModifier is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 370. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableCellModifier.java + [javac] (at line 87) + [javac] if (VariableColumnPresentation.COLUMN_VARIABLE_VALUE.equals(property)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type VariableColumnPresentation is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 371. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableCellModifier.java + [javac] (at line 87) + [javac] if (VariableColumnPresentation.COLUMN_VARIABLE_VALUE.equals(property)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field COLUMN_VARIABLE_VALUE from the type VariableColumnPresentation is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 372. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableCellModifier.java + [javac] (at line 93) + [javac] super.modify(element, property, Boolean.toString(true)); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method modify(Object, String, Object) from the type DefaultVariableCellModifier is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 373. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableCellModifier.java + [javac] (at line 96) + [javac] super.modify(element, property, Boolean.toString(false)); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method modify(Object, String, Object) from the type DefaultVariableCellModifier is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 374. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableCellModifier.java + [javac] (at line 102) + [javac] super.modify(element, property, value); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method modify(Object, String, Object) from the type DefaultVariableCellModifier is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 375. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnEditor.java + [javac] (at line 13) + [javac] import org.eclipse.debug.internal.ui.elements.adapters.VariableColumnEditor; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type VariableColumnEditor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 376. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnEditor.java + [javac] (at line 14) + [javac] import org.eclipse.debug.internal.ui.elements.adapters.VariableColumnPresentation; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type VariableColumnPresentation is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 377. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnEditor.java + [javac] (at line 28) + [javac] public class JavaVariableColumnEditor extends VariableColumnEditor { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type VariableColumnEditor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 378. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnEditor.java + [javac] (at line 39) + [javac] fModifier = new JavaVariableCellModifier(getPresentationContext()); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getPresentationContext() from the type AbstractColumnEditor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 379. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnEditor.java + [javac] (at line 55) + [javac] if (VariableColumnPresentation.COLUMN_VARIABLE_VALUE.equals(id)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type VariableColumnPresentation is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 380. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnEditor.java + [javac] (at line 55) + [javac] if (VariableColumnPresentation.COLUMN_VARIABLE_VALUE.equals(id)) { + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field COLUMN_VARIABLE_VALUE from the type VariableColumnPresentation is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 381. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnEditor.java + [javac] (at line 63) + [javac] return super.getCellEditor(id, element, parent); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getCellEditor(String, Object, Composite) from the type VariableColumnEditor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 382. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnEditorFactory.java + [javac] (at line 13) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditor; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IColumnEditor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 383. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnEditorFactory.java + [javac] (at line 14) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IColumnEditorFactoryAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IColumnEditorFactoryAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 384. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnEditorFactory.java + [javac] (at line 15) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 385. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnEditorFactory.java + [javac] (at line 25) + [javac] IColumnEditorFactoryAdapter { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IColumnEditorFactoryAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 386. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnEditorFactory.java + [javac] (at line 30) + [javac] public IColumnEditor createColumnEditor(IPresentationContext context, Object element) { + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The type IColumnEditor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 387. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnEditorFactory.java + [javac] (at line 30) + [javac] public IColumnEditor createColumnEditor(IPresentationContext context, Object element) { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 388. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnEditorFactory.java + [javac] (at line 31) + [javac] IWorkbenchPart part = context.getPart(); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getPart() from the type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 389. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnEditorFactory.java + [javac] (at line 45) + [javac] public String getColumnEditorId(IPresentationContext context, Object element) { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 390. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnEditorFactory.java + [javac] (at line 46) + [javac] IWorkbenchPart part = context.getPart(); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getPart() from the type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 391. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnPresentation.java + [javac] (at line 13) + [javac] import org.eclipse.debug.internal.ui.elements.adapters.VariableColumnPresentation; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type VariableColumnPresentation is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 392. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnPresentation.java + [javac] (at line 20) + [javac] public class JavaVariableColumnPresentation extends VariableColumnPresentation { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type VariableColumnPresentation is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 393. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnPresentation.java + [javac] (at line 40) + [javac] String[] basic = super.getAvailableColumns(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getAvailableColumns() from the type VariableColumnPresentation is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 394. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnPresentation.java + [javac] (at line 55) + [javac] return super.getHeader(id); + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getHeader(String) from the type VariableColumnPresentation is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 395. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnPresentationFactory.java + [javac] (at line 14) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentation; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IColumnPresentation is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 396. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnPresentationFactory.java + [javac] (at line 15) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IColumnPresentationFactoryAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IColumnPresentationFactoryAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 397. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnPresentationFactory.java + [javac] (at line 16) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 398. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnPresentationFactory.java + [javac] (at line 26) + [javac] public class JavaVariableColumnPresentationFactory implements IColumnPresentationFactoryAdapter { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IColumnPresentationFactoryAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 399. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnPresentationFactory.java + [javac] (at line 31) + [javac] public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) { + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IColumnPresentation is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 400. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnPresentationFactory.java + [javac] (at line 31) + [javac] public IColumnPresentation createColumnPresentation(IPresentationContext context, Object element) { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 401. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnPresentationFactory.java + [javac] (at line 41) + [javac] public String getColumnPresentationId(IPresentationContext context, Object element) { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 402. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnPresentationFactory.java + [javac] (at line 48) + [javac] private boolean isApplicable(IPresentationContext context, Object element) { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 403. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableColumnPresentationFactory.java + [javac] (at line 49) + [javac] IWorkbenchPart part = context.getPart(); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getPart() from the type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 404. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableLabelAdapter.java + [javac] (at line 17) + [javac] import org.eclipse.debug.internal.ui.elements.adapters.VariableLabelAdapter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type VariableLabelAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 405. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableLabelAdapter.java + [javac] (at line 18) + [javac] import org.eclipse.debug.internal.ui.viewers.provisional.IPresentationContext; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 406. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableLabelAdapter.java + [javac] (at line 31) + [javac] public class JavaVariableLabelAdapter extends VariableLabelAdapter { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type VariableLabelAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 407. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableLabelAdapter.java + [javac] (at line 38) + [javac] protected String getValueText(IVariable variable, IValue value, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 408. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableLabelAdapter.java + [javac] (at line 40) + [javac] return escapeSpecialChars(fLabelProvider.getFormattedValueText((IJavaValue) value)); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method escapeSpecialChars(String) from the type VariableLabelAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 409. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableLabelAdapter.java + [javac] (at line 42) + [javac] return super.getValueText(variable, value, context); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getValueText(IVariable, IValue, IPresentationContext) from the type VariableLabelAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 410. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableLabelAdapter.java + [javac] (at line 48) + [javac] protected String getValueTypeName(IVariable variable, IValue value, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 411. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableLabelAdapter.java + [javac] (at line 62) + [javac] protected String getVariableTypeName(IVariable variable, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 412. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableLabelAdapter.java + [javac] (at line 73) + [javac] private boolean isShowQualfiiedNames(IPresentationContext context) { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 413. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableLabelAdapter.java + [javac] (at line 74) + [javac] IWorkbenchPart part = context.getPart(); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getPart() from the type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 414. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableLabelAdapter.java + [javac] (at line 84) + [javac] protected String getColumnText(IVariable variable, IValue value, String columnId, IPresentationContext context) throws CoreException { + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IPresentationContext is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 415. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableLabelAdapter.java + [javac] (at line 95) + [javac] return super.getColumnText(variable, value, columnId, context); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getColumnText(IVariable, IValue, String, IPresentationContext) from the type VariableLabelAdapter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 415 problems (415 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/AntUtil.java + [javac] (at line 601) + [javac] mementos.add(homeEntry.getMemento()); + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getMemento() from the type AbstractRuntimeClasspathEntry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/ExternalHyperlink.java + [javac] (at line 27) + [javac] import org.eclipse.ui.internal.editors.text.JavaFileEditorInput; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaFileEditorInput is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.editors/@dot + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/ExternalHyperlink.java + [javac] (at line 53) + [javac] input = new JavaFileEditorInput(fileStore); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor JavaFileEditorInput(IFileStore) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.editors/@dot + [javac] ---------- + [javac] 4. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/ExternalHyperlink.java + [javac] (at line 53) + [javac] input = new JavaFileEditorInput(fileStore); + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaFileEditorInput is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.editors/@dot + [javac] ---------- + [javac] ---------- + [javac] 5. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/JavacMarkerCreator.java + [javac] (at line 30) + [javac] import org.eclipse.debug.internal.ui.views.console.ProcessConsole; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ProcessConsole is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 6. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/JavacMarkerCreator.java + [javac] (at line 74) + [javac] if (fConsole instanceof ProcessConsole) { + [javac] ^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ProcessConsole is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 7. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/JavacMarkerCreator.java + [javac] (at line 75) + [javac] fProcess= ((ProcessConsole) fConsole).getProcess(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getProcess() from the type ProcessConsole is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] 8. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/console/JavacMarkerCreator.java + [javac] (at line 75) + [javac] fProcess= ((ProcessConsole) fConsole).getProcess(); + [javac] ^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ProcessConsole is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 9. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/debug/model/AntDebugModelPresentation.java + [javac] (at line 37) + [javac] import org.eclipse.ui.internal.editors.text.JavaFileEditorInput; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaFileEditorInput is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.editors/@dot + [javac] ---------- + [javac] 10. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/debug/model/AntDebugModelPresentation.java + [javac] (at line 155) + [javac] return new JavaFileEditorInput(fileStore); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor JavaFileEditorInput(IFileStore) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.editors/@dot + [javac] ---------- + [javac] 11. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/debug/model/AntDebugModelPresentation.java + [javac] (at line 155) + [javac] return new JavaFileEditorInput(fileStore); + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaFileEditorInput is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ui.editors/@dot + [javac] ---------- + [javac] ---------- + [javac] 12. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AddVariableStringAction.java + [javac] (at line 13) + [javac] import org.eclipse.jdt.internal.debug.ui.actions.RuntimeClasspathAction; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type RuntimeClasspathAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 13. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AddVariableStringAction.java + [javac] (at line 14) + [javac] import org.eclipse.jdt.internal.debug.ui.launcher.IClasspathViewer; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IClasspathViewer is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 14. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AddVariableStringAction.java + [javac] (at line 18) + [javac] public class AddVariableStringAction extends RuntimeClasspathAction { + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type RuntimeClasspathAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 15. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AddVariableStringAction.java + [javac] (at line 20) + [javac] public AddVariableStringAction(IClasspathViewer viewer) { + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IClasspathViewer is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 16. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AddVariableStringAction.java + [javac] (at line 21) + [javac] super(AntLaunchConfigurationMessages.AddVariableStringAction_1, viewer); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor RuntimeClasspathAction(String, IClasspathViewer) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 17. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AddVariableStringAction.java + [javac] (at line 28) + [javac] return ADD; + [javac] ^^^ + [javac] Discouraged access: The field ADD from the type RuntimeClasspathAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 18. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AddVariableStringAction.java + [javac] (at line 35) + [javac] VariableInputDialog inputDialog = new VariableInputDialog(getShell()); + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The method getShell() from the type RuntimeClasspathAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 19. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AddVariableStringAction.java + [javac] (at line 40) + [javac] getViewer().addEntries(new IRuntimeClasspathEntry[] {newEntry}); + [javac] ^^^^^^^^^^^ + [javac] Discouraged access: The method getViewer() from the type RuntimeClasspathAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 20. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AddVariableStringAction.java + [javac] (at line 40) + [javac] getViewer().addEntries(new IRuntimeClasspathEntry[] {newEntry}); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method addEntries(IRuntimeClasspathEntry[]) from the type IClasspathViewer is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 21. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 18) + [javac] import org.eclipse.jdt.internal.debug.ui.actions.AddExternalJarAction; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AddExternalJarAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 22. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 19) + [javac] import org.eclipse.jdt.internal.debug.ui.actions.AddFolderAction; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AddFolderAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 23. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 20) + [javac] import org.eclipse.jdt.internal.debug.ui.actions.AddJarAction; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AddJarAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 24. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 21) + [javac] import org.eclipse.jdt.internal.debug.ui.actions.MoveDownAction; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type MoveDownAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 25. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 22) + [javac] import org.eclipse.jdt.internal.debug.ui.actions.MoveUpAction; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type MoveUpAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 26. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 23) + [javac] import org.eclipse.jdt.internal.debug.ui.actions.RemoveAction; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type RemoveAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 27. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 24) + [javac] import org.eclipse.jdt.internal.debug.ui.actions.RestoreDefaultEntriesAction; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type RestoreDefaultEntriesAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 28. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 25) + [javac] import org.eclipse.jdt.internal.debug.ui.actions.RuntimeClasspathAction; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type RuntimeClasspathAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 29. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 26) + [javac] import org.eclipse.jdt.internal.debug.ui.classpath.ClasspathEntry; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ClasspathEntry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 30. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 27) + [javac] import org.eclipse.jdt.internal.debug.ui.classpath.ClasspathModel; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ClasspathModel is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 31. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 28) + [javac] import org.eclipse.jdt.internal.debug.ui.classpath.IClasspathEntry; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IClasspathEntry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 32. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 29) + [javac] import org.eclipse.jdt.internal.debug.ui.launcher.IClasspathViewer; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IClasspathViewer is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 33. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 54) + [javac] createButton(pathButtonComp, new MoveUpAction(fClasspathViewer)); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor MoveUpAction(IClasspathViewer) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 34. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 54) + [javac] createButton(pathButtonComp, new MoveUpAction(fClasspathViewer)); + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type MoveUpAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 35. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 55) + [javac] createButton(pathButtonComp, new MoveDownAction(fClasspathViewer)); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor MoveDownAction(IClasspathViewer) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 36. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 55) + [javac] createButton(pathButtonComp, new MoveDownAction(fClasspathViewer)); + [javac] ^^^^^^^^^^^^^^ + [javac] Discouraged access: The type MoveDownAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 37. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 56) + [javac] createButton(pathButtonComp, new RemoveAction(fClasspathViewer)); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor RemoveAction(IClasspathViewer) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 38. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 56) + [javac] createButton(pathButtonComp, new RemoveAction(fClasspathViewer)); + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type RemoveAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 39. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 57) + [javac] createButton(pathButtonComp, new AddJarAction(fClasspathViewer)); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor AddJarAction(IClasspathViewer) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 40. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 57) + [javac] createButton(pathButtonComp, new AddJarAction(fClasspathViewer)); + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type AddJarAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 41. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 58) + [javac] createButton(pathButtonComp, new AddExternalJarAction(fClasspathViewer, DIALOG_SETTINGS_PREFIX)); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor AddExternalJarAction(IClasspathViewer, String) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 42. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 58) + [javac] createButton(pathButtonComp, new AddExternalJarAction(fClasspathViewer, DIALOG_SETTINGS_PREFIX)); + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AddExternalJarAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 43. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 59) + [javac] Button button = createButton(pathButtonComp, new AddFolderAction(fClasspathViewer)); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor AddFolderAction(IClasspathViewer) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 44. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 59) + [javac] Button button = createButton(pathButtonComp, new AddFolderAction(fClasspathViewer)); + [javac] ^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AddFolderAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 45. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 62) + [javac] RuntimeClasspathAction action= new RestoreDefaultEntriesAction(fClasspathViewer, this); + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type RuntimeClasspathAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 46. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 62) + [javac] RuntimeClasspathAction action= new RestoreDefaultEntriesAction(fClasspathViewer, this); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor RestoreDefaultEntriesAction(IClasspathViewer, JavaClasspathTab) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 47. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 62) + [javac] RuntimeClasspathAction action= new RestoreDefaultEntriesAction(fClasspathViewer, this); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type RestoreDefaultEntriesAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 48. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 64) + [javac] action.setEnabled(true); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setEnabled(boolean) from the type RuntimeClasspathAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 49. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 68) + [javac] action.setEnabled(true); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setEnabled(boolean) from the type RuntimeClasspathAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 50. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 92) + [javac] public void entriesChanged(IClasspathViewer viewer) { + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IClasspathViewer is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 51. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 93) + [javac] super.entriesChanged(viewer); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method entriesChanged(IClasspathViewer) from the type AbstractJavaClasspathTab is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 52. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 117) + [javac] ClasspathModel model= getModel(); + [javac] ^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ClasspathModel is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 53. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 118) + [javac] IClasspathEntry userEntry= model.getUserEntry(); + [javac] ^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IClasspathEntry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 54. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 118) + [javac] IClasspathEntry userEntry= model.getUserEntry(); + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getUserEntry() from the type ClasspathModel is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 55. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 119) + [javac] IClasspathEntry[] entries= userEntry.getEntries(); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IClasspathEntry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 56. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 119) + [javac] IClasspathEntry[] entries= userEntry.getEntries(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getEntries() from the type IClasspathEntry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 57. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 121) + [javac] ClasspathEntry entry = (ClasspathEntry) entries[i]; + [javac] ^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ClasspathEntry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 58. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 121) + [javac] ClasspathEntry entry = (ClasspathEntry) entries[i]; + [javac] ^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ClasspathEntry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 59. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntClasspathTab.java + [javac] (at line 122) + [javac] IRuntimeClasspathEntry runtimeEntry= entry.getDelegate(); + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getDelegate() from the type ClasspathEntry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 60. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntHomeClasspathEntry.java + [javac] (at line 25) + [javac] import org.eclipse.jdt.internal.launching.AbstractRuntimeClasspathEntry; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AbstractRuntimeClasspathEntry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 61. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntHomeClasspathEntry.java + [javac] (at line 37) + [javac] public class AntHomeClasspathEntry extends AbstractRuntimeClasspathEntry { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AbstractRuntimeClasspathEntry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 62. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntHomeClasspathEntry.java + [javac] (at line 128) + [javac] abort(MessageFormat.format(AntLaunchConfigurationMessages.AntHomeClasspathEntry_10, new String[] {antHomeLocation}), null); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method abort(String, Throwable) from the type AbstractRuntimeClasspathEntry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 63. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntHomeClasspathEntry.java + [javac] (at line 131) + [javac] abort(MessageFormat.format(AntLaunchConfigurationMessages.AntHomeClasspathEntry_11, new String[] {antHomeLocation}), null); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method abort(String, Throwable) from the type AbstractRuntimeClasspathEntry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] ---------- + [javac] 64. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 23) + [javac] import org.eclipse.jdt.internal.debug.ui.jres.JREDescriptor; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JREDescriptor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 65. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 24) + [javac] import org.eclipse.jdt.internal.debug.ui.launcher.VMArgumentsBlock; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type VMArgumentsBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 66. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 38) + [javac] private VMArgumentsBlock fVMArgumentsBlock= new VMArgumentsBlock(); + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type VMArgumentsBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 67. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 38) + [javac] private VMArgumentsBlock fVMArgumentsBlock= new VMArgumentsBlock(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor VMArgumentsBlock() is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 68. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 38) + [javac] private VMArgumentsBlock fVMArgumentsBlock= new VMArgumentsBlock(); + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type VMArgumentsBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 69. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 47) + [javac] Composite comp= (Composite)fJREBlock.getControl(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getControl() from the type JREsComboBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 70. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 51) + [javac] fVMArgumentsBlock.createControl(comp); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createControl(Composite) from the type VMArgumentsBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 71. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 54) + [javac] fWorkingDirectoryBlock.createControl(comp); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createControl(Composite) from the type WorkingDirectoryBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 72. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 61) + [javac] protected JREDescriptor getDefaultJREDescriptor() { + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The type JREDescriptor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 73. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 62) + [javac] return new JREDescriptor() { + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The type JREDescriptor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 74. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 75) + [javac] protected JREDescriptor getSpecificJREDescriptor() { + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The type JREDescriptor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 75. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 76) + [javac] return new JREDescriptor() { + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The type JREDescriptor is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 76. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 90) + [javac] boolean isDefaultJRE = fJREBlock.isDefaultJRE(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method isDefaultJRE() from the type JREsComboBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 77. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 92) + [javac] fVMArgumentsBlock.setEnabled(!isDefaultJRE); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setEnabled(boolean) from the type VMArgumentsBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 78. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 110) + [javac] fVMArgumentsBlock.performApply(configuration); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method performApply(ILaunchConfigurationWorkingCopy) from the type VMArgumentsBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 79. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 111) + [javac] fWorkingDirectoryBlock.performApply(configuration); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method performApply(ILaunchConfigurationWorkingCopy) from the type WorkingDirectoryBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 80. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 133) + [javac] IVMInstall vm= fJREBlock.getJRE(); + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getJRE() from the type JREsComboBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 81. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 203) + [javac] fVMArgumentsBlock.initializeFrom(configuration); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method initializeFrom(ILaunchConfiguration) from the type VMArgumentsBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 82. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 205) + [javac] boolean separateVM= !fJREBlock.isDefaultJRE(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method isDefaultJRE() from the type JREsComboBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 83. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 207) + [javac] fVMArgumentsBlock.setEnabled(separateVM); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setEnabled(boolean) from the type VMArgumentsBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 84. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntJRETab.java + [javac] (at line 214) + [javac] return super.isValid(config) && fWorkingDirectoryBlock.isValid(config); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method isValid(ILaunchConfiguration) from the type WorkingDirectoryBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 85. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntWorkingDirectoryBlock.java + [javac] (at line 18) + [javac] import org.eclipse.jdt.internal.debug.ui.launcher.WorkingDirectoryBlock; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type WorkingDirectoryBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 86. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntWorkingDirectoryBlock.java + [javac] (at line 23) + [javac] public class AntWorkingDirectoryBlock extends WorkingDirectoryBlock { + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type WorkingDirectoryBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 87. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntWorkingDirectoryBlock.java + [javac] (at line 40) + [javac] super.setDefaultWorkingDir(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setDefaultWorkingDir() from the type WorkingDirectoryBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 88. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntWorkingDirectoryBlock.java + [javac] (at line 43) + [javac] setDefaultWorkingDirectoryText(fDefaultWorkingDirPath); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setDefaultWorkingDirectoryText(String) from the type WorkingDirectoryBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 89. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntWorkingDirectoryBlock.java + [javac] (at line 50) + [javac] setLaunchConfiguration(configuration); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setLaunchConfiguration(ILaunchConfiguration) from the type WorkingDirectoryBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 90. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntWorkingDirectoryBlock.java + [javac] (at line 59) + [javac] setOtherWorkingDirectoryText(wd); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setOtherWorkingDirectoryText(String) from the type WorkingDirectoryBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 91. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/AntWorkingDirectoryBlock.java + [javac] (at line 75) + [javac] super.setEnabled(enabled); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setEnabled(boolean) from the type WorkingDirectoryBlock is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 92. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/ContributedClasspathEntriesEntry.java + [javac] (at line 33) + [javac] import org.eclipse.jdt.internal.launching.AbstractRuntimeClasspathEntry; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AbstractRuntimeClasspathEntry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] 93. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/ContributedClasspathEntriesEntry.java + [javac] (at line 48) + [javac] public class ContributedClasspathEntriesEntry extends AbstractRuntimeClasspathEntry { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AbstractRuntimeClasspathEntry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.launching/@dot + [javac] ---------- + [javac] ---------- + [javac] 94. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java + [javac] (at line 19) + [javac] import org.eclipse.jdt.internal.debug.ui.actions.RuntimeClasspathAction; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type RuntimeClasspathAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 95. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java + [javac] (at line 20) + [javac] import org.eclipse.jdt.internal.debug.ui.classpath.ClasspathEntry; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ClasspathEntry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 96. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java + [javac] (at line 21) + [javac] import org.eclipse.jdt.internal.debug.ui.launcher.IClasspathViewer; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IClasspathViewer is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 97. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java + [javac] (at line 33) + [javac] public class EditAntHomeEntryAction extends RuntimeClasspathAction { + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type RuntimeClasspathAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 98. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java + [javac] (at line 41) + [javac] public EditAntHomeEntryAction(IClasspathViewer viewer, AntClasspathTab tab) { + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IClasspathViewer is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 99. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java + [javac] (at line 42) + [javac] super(AntLaunchConfigurationMessages.EditAntHomeEntryAction_1, viewer); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor RuntimeClasspathAction(String, IClasspathViewer) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 100. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java + [javac] (at line 56) + [javac] DirectoryDialog dialog = new DirectoryDialog(getShell()); + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The method getShell() from the type RuntimeClasspathAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 101. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java + [javac] (at line 71) + [javac] IRuntimeClasspathEntry[] entries = getViewer().getEntries(); + [javac] ^^^^^^^^^^^ + [javac] Discouraged access: The method getViewer() from the type RuntimeClasspathAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 102. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java + [javac] (at line 71) + [javac] IRuntimeClasspathEntry[] entries = getViewer().getEntries(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getEntries() from the type IClasspathViewer is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 103. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java + [javac] (at line 75) + [javac] IRuntimeClasspathEntry2 entry2 = (IRuntimeClasspathEntry2)((ClasspathEntry)entry).getDelegate(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getDelegate() from the type ClasspathEntry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 104. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java + [javac] (at line 75) + [javac] IRuntimeClasspathEntry2 entry2 = (IRuntimeClasspathEntry2)((ClasspathEntry)entry).getDelegate(); + [javac] ^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ClasspathEntry is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 105. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java + [javac] (at line 78) + [javac] getViewer().refresh(entry); + [javac] ^^^^^^^^^^^ + [javac] Discouraged access: The method getViewer() from the type RuntimeClasspathAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 106. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java + [javac] (at line 78) + [javac] getViewer().refresh(entry); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method refresh(Object) from the type IClasspathViewer is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 107. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java + [javac] (at line 79) + [javac] getViewer().notifyChanged(); + [javac] ^^^^^^^^^^^ + [javac] Discouraged access: The method getViewer() from the type RuntimeClasspathAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 108. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java + [javac] (at line 79) + [javac] getViewer().notifyChanged(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method notifyChanged() from the type IClasspathViewer is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 109. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java + [javac] (at line 85) + [javac] getViewer().addEntries(new IRuntimeClasspathEntry[]{new AntHomeClasspathEntry(path)}); + [javac] ^^^^^^^^^^^ + [javac] Discouraged access: The method getViewer() from the type RuntimeClasspathAction is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 110. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/launchConfigurations/EditAntHomeEntryAction.java + [javac] (at line 85) + [javac] getViewer().addEntries(new IRuntimeClasspathEntry[]{new AntHomeClasspathEntry(path)}); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method addEntries(IRuntimeClasspathEntry[]) from the type IClasspathViewer is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 111. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathBlock.java + [javac] (at line 34) + [javac] import org.eclipse.jdt.internal.debug.ui.actions.ArchiveFilter; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type ArchiveFilter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 112. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathBlock.java + [javac] (at line 289) + [javac] ViewerFilter filter= new ArchiveFilter(allEntries); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor ArchiveFilter(List) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] 113. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntClasspathBlock.java + [javac] (at line 289) + [javac] ViewerFilter filter= new ArchiveFilter(allEntries); + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The type ArchiveFilter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.debug.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 114. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/derived/HTML2TextReader.java + [javac] (at line 30) + [javac] * @see org.eclipse.jdt.internal.ui.text.HTML2TextReader + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type HTML2TextReader is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 115. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/derived/HTMLPrinter.java + [javac] (at line 21) + [javac] * @see org.eclipse.jdt.internal.ui.text.HTMLPrinter + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type HTMLPrinter is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 116. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/derived/LineBreakingReader.java + [javac] (at line 22) + [javac] * @see org.eclipse.jdt.internal.ui.text.LineBreakingReader + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type LineBreakingReader is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 117. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/derived/SingleCharReader.java + [javac] (at line 18) + [javac] * @see org.eclipse.jdt.internal.corext.javadoc.SingleCharReader + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type SingleCharReader is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 118. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/Ant Editor/org/eclipse/ant/internal/ui/editor/derived/SubstitutionTextReader.java + [javac] (at line 24) + [javac] * @see org.eclipse.jdt.internal.ui.text.SubstitutionTextReader + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type SubstitutionTextReader is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 118 problems (118 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/FetchScriptGenerator.java + [javac] (at line 23) + [javac] import org.eclipse.update.internal.core.FeatureExecutableFactory; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type FeatureExecutableFactory is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/FetchScriptGenerator.java + [javac] (at line 415) + [javac] FeatureExecutableFactory factory = new FeatureExecutableFactory(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type FeatureExecutableFactory is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/FetchScriptGenerator.java + [javac] (at line 415) + [javac] FeatureExecutableFactory factory = new FeatureExecutableFactory(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor FeatureExecutableFactory() is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 4. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/FetchScriptGenerator.java + [javac] (at line 415) + [javac] FeatureExecutableFactory factory = new FeatureExecutableFactory(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type FeatureExecutableFactory is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 5. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/FetchScriptGenerator.java + [javac] (at line 419) + [javac] feature = factory.createFeature(featureLocation.toURL(), null, null); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createFeature(URL, ISite, IProgressMonitor) from the type FeatureExecutableFactory is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 6. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/FetchScriptGenerator.java + [javac] (at line 459) + [javac] FeatureExecutableFactory factory = new FeatureExecutableFactory(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type FeatureExecutableFactory is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 7. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/FetchScriptGenerator.java + [javac] (at line 459) + [javac] FeatureExecutableFactory factory = new FeatureExecutableFactory(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor FeatureExecutableFactory() is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 8. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/FetchScriptGenerator.java + [javac] (at line 459) + [javac] FeatureExecutableFactory factory = new FeatureExecutableFactory(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type FeatureExecutableFactory is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 9. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/FetchScriptGenerator.java + [javac] (at line 461) + [javac] feature = factory.createFeature(featureFolder.toURL(), null, null); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createFeature(URL, ISite, IProgressMonitor) from the type FeatureExecutableFactory is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] ---------- + [javac] 10. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ClasspathComputer2_1.java + [javac] (at line 18) + [javac] import org.eclipse.core.internal.runtime.PlatformURLFragmentConnection; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type PlatformURLFragmentConnection is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.equinox.common/@dot + [javac] ---------- + [javac] 11. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ClasspathComputer2_1.java + [javac] (at line 19) + [javac] import org.eclipse.core.internal.runtime.PlatformURLPluginConnection; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type PlatformURLPluginConnection is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.equinox.common/@dot + [javac] ---------- + [javac] 12. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ClasspathComputer2_1.java + [javac] (at line 265) + [javac] if (urlfragments[1].equalsIgnoreCase(PlatformURLPluginConnection.PLUGIN)) + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type PlatformURLPluginConnection is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.equinox.common/@dot + [javac] ---------- + [javac] 13. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ClasspathComputer2_1.java + [javac] (at line 265) + [javac] if (urlfragments[1].equalsIgnoreCase(PlatformURLPluginConnection.PLUGIN)) + [javac] ^^^^^^ + [javac] Discouraged access: The field PLUGIN from the type PlatformURLPluginConnection is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.equinox.common/@dot + [javac] ---------- + [javac] 14. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ClasspathComputer2_1.java + [javac] (at line 268) + [javac] if (urlfragments[1].equalsIgnoreCase(PlatformURLFragmentConnection.FRAGMENT)) + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type PlatformURLFragmentConnection is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.equinox.common/@dot + [javac] ---------- + [javac] 15. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ClasspathComputer2_1.java + [javac] (at line 268) + [javac] if (urlfragments[1].equalsIgnoreCase(PlatformURLFragmentConnection.FRAGMENT)) + [javac] ^^^^^^^^ + [javac] Discouraged access: The field FRAGMENT from the type PlatformURLFragmentConnection is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.equinox.common/@dot + [javac] ---------- + [javac] ---------- + [javac] 16. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ClasspathComputer3_0.java + [javac] (at line 19) + [javac] import org.eclipse.core.internal.runtime.PlatformURLFragmentConnection; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type PlatformURLFragmentConnection is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.equinox.common/@dot + [javac] ---------- + [javac] 17. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ClasspathComputer3_0.java + [javac] (at line 20) + [javac] import org.eclipse.core.internal.runtime.PlatformURLPluginConnection; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type PlatformURLPluginConnection is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.equinox.common/@dot + [javac] ---------- + [javac] 18. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ClasspathComputer3_0.java + [javac] (at line 421) + [javac] if (urlfragments[1].equalsIgnoreCase(PlatformURLPluginConnection.PLUGIN) || urlfragments[1].equalsIgnoreCase(PlatformURLFragmentConnection.FRAGMENT)) + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type PlatformURLPluginConnection is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.equinox.common/@dot + [javac] ---------- + [javac] 19. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ClasspathComputer3_0.java + [javac] (at line 421) + [javac] if (urlfragments[1].equalsIgnoreCase(PlatformURLPluginConnection.PLUGIN) || urlfragments[1].equalsIgnoreCase(PlatformURLFragmentConnection.FRAGMENT)) + [javac] ^^^^^^ + [javac] Discouraged access: The field PLUGIN from the type PlatformURLPluginConnection is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.equinox.common/@dot + [javac] ---------- + [javac] 20. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ClasspathComputer3_0.java + [javac] (at line 421) + [javac] if (urlfragments[1].equalsIgnoreCase(PlatformURLPluginConnection.PLUGIN) || urlfragments[1].equalsIgnoreCase(PlatformURLFragmentConnection.FRAGMENT)) + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type PlatformURLFragmentConnection is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.equinox.common/@dot + [javac] ---------- + [javac] 21. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/builder/ClasspathComputer3_0.java + [javac] (at line 421) + [javac] if (urlfragments[1].equalsIgnoreCase(PlatformURLPluginConnection.PLUGIN) || urlfragments[1].equalsIgnoreCase(PlatformURLFragmentConnection.FRAGMENT)) + [javac] ^^^^^^^^ + [javac] Discouraged access: The field FRAGMENT from the type PlatformURLFragmentConnection is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.equinox.common/@dot + [javac] ---------- + [javac] ---------- + [javac] 22. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/site/BuildTimeFeatureFactory.java + [javac] (at line 21) + [javac] import org.eclipse.update.internal.core.FeatureExecutableContentProvider; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type FeatureExecutableContentProvider is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 23. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/site/BuildTimeFeatureFactory.java + [javac] (at line 22) + [javac] import org.eclipse.update.internal.core.URLEncoder; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type URLEncoder is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 24. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/site/BuildTimeFeatureFactory.java + [javac] (at line 40) + [javac] IFeatureContentProvider contentProvider = new FeatureExecutableContentProvider(url); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor FeatureExecutableContentProvider(URL) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 25. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/site/BuildTimeFeatureFactory.java + [javac] (at line 40) + [javac] IFeatureContentProvider contentProvider = new FeatureExecutableContentProvider(url); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type FeatureExecutableContentProvider is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 26. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/site/BuildTimeFeatureFactory.java + [javac] (at line 43) + [javac] URL resolvedURL = URLEncoder.encode(nonResolvedURL); + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type URLEncoder is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 27. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/site/BuildTimeFeatureFactory.java + [javac] (at line 43) + [javac] URL resolvedURL = URLEncoder.encode(nonResolvedURL); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method encode(URL) from the type URLEncoder is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 28. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/site/BuildTimeFeatureFactory.java + [javac] (at line 88) + [javac] IFeatureContentProvider contentProvider = new FeatureExecutableContentProvider(null); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor FeatureExecutableContentProvider(URL) is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 29. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/site/BuildTimeFeatureFactory.java + [javac] (at line 88) + [javac] IFeatureContentProvider contentProvider = new FeatureExecutableContentProvider(null); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type FeatureExecutableContentProvider is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] ---------- + [javac] 30. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/swt/tools/internal/IconExe.java + [javac] (at line 224) + [javac] int IRDE_StartOffset = imageResourceDirectoryOffset + IMAGE_RESOURCE_DIRECTORY.SIZEOF; + [javac] ^^^^^^^^^^^^^^^^ + [javac] The local variable IRDE_StartOffset is never read + [javac] ---------- + [javac] 31. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/swt/tools/internal/IconExe.java + [javac] (at line 2462) + [javac] TYPE_GENERIC_8 = 0, + [javac] ^^^^^^^^^^^^^^ + [javac] The field IconExe.ImageData.TYPE_GENERIC_8 is never read locally + [javac] ---------- + [javac] 32. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/swt/tools/internal/IconExe.java + [javac] (at line 2463) + [javac] TYPE_GENERIC_16_MSB = 1, + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] The field IconExe.ImageData.TYPE_GENERIC_16_MSB is never read locally + [javac] ---------- + [javac] 33. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/swt/tools/internal/IconExe.java + [javac] (at line 2464) + [javac] TYPE_GENERIC_16_LSB = 2, + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] The field IconExe.ImageData.TYPE_GENERIC_16_LSB is never read locally + [javac] ---------- + [javac] 34. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/swt/tools/internal/IconExe.java + [javac] (at line 2465) + [javac] TYPE_GENERIC_24 = 3, + [javac] ^^^^^^^^^^^^^^^ + [javac] The field IconExe.ImageData.TYPE_GENERIC_24 is never read locally + [javac] ---------- + [javac] 35. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/swt/tools/internal/IconExe.java + [javac] (at line 2466) + [javac] TYPE_GENERIC_32_MSB = 4, + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] The field IconExe.ImageData.TYPE_GENERIC_32_MSB is never read locally + [javac] ---------- + [javac] 36. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/swt/tools/internal/IconExe.java + [javac] (at line 2467) + [javac] TYPE_GENERIC_32_LSB = 5, + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] The field IconExe.ImageData.TYPE_GENERIC_32_LSB is never read locally + [javac] ---------- + [javac] 37. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/swt/tools/internal/IconExe.java + [javac] (at line 2469) + [javac] TYPE_INDEX_8 = 6, + [javac] ^^^^^^^^^^^^ + [javac] The field IconExe.ImageData.TYPE_INDEX_8 is never read locally + [javac] ---------- + [javac] 38. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/swt/tools/internal/IconExe.java + [javac] (at line 2470) + [javac] TYPE_INDEX_4 = 7, + [javac] ^^^^^^^^^^^^ + [javac] The field IconExe.ImageData.TYPE_INDEX_4 is never read locally + [javac] ---------- + [javac] 39. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/swt/tools/internal/IconExe.java + [javac] (at line 2471) + [javac] TYPE_INDEX_2 = 8, + [javac] ^^^^^^^^^^^^ + [javac] The field IconExe.ImageData.TYPE_INDEX_2 is never read locally + [javac] ---------- + [javac] 40. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/swt/tools/internal/IconExe.java + [javac] (at line 2472) + [javac] TYPE_INDEX_1_MSB = 9, + [javac] ^^^^^^^^^^^^^^^^ + [javac] The field IconExe.ImageData.TYPE_INDEX_1_MSB is never read locally + [javac] ---------- + [javac] 41. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/swt/tools/internal/IconExe.java + [javac] (at line 2473) + [javac] TYPE_INDEX_1_LSB = 10; + [javac] ^^^^^^^^^^^^^^^^ + [javac] The field IconExe.ImageData.TYPE_INDEX_1_LSB is never read locally + [javac] ---------- + [javac] 42. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/swt/tools/internal/IconExe.java + [javac] (at line 2984) + [javac] int xPelsPerMeter = (infoHeader[24] & 0xFF) | ((infoHeader[25] & 0xFF) << 8) | ((infoHeader[26] & 0xFF) << 16) | ((infoHeader[27] & 0xFF) << 24); + [javac] ^^^^^^^^^^^^^ + [javac] The local variable xPelsPerMeter is never read + [javac] ---------- + [javac] 43. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src/org/eclipse/swt/tools/internal/IconExe.java + [javac] (at line 2985) + [javac] int yPelsPerMeter = (infoHeader[28] & 0xFF) | ((infoHeader[29] & 0xFF) << 8) | ((infoHeader[30] & 0xFF) << 16) | ((infoHeader[31] & 0xFF) << 24); + [javac] ^^^^^^^^^^^^^ + [javac] The local variable yPelsPerMeter is never read + [javac] ---------- + [javac] 43 problems (43 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src_ant/org/eclipse/pde/internal/build/tasks/BuildManifestTask.java + [javac] (at line 22) + [javac] import org.eclipse.update.internal.core.FeatureExecutableFactory; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type FeatureExecutableFactory is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src_ant/org/eclipse/pde/internal/build/tasks/BuildManifestTask.java + [javac] (at line 192) + [javac] FeatureExecutableFactory factory = new FeatureExecutableFactory(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type FeatureExecutableFactory is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src_ant/org/eclipse/pde/internal/build/tasks/BuildManifestTask.java + [javac] (at line 192) + [javac] FeatureExecutableFactory factory = new FeatureExecutableFactory(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor FeatureExecutableFactory() is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 4. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src_ant/org/eclipse/pde/internal/build/tasks/BuildManifestTask.java + [javac] (at line 192) + [javac] FeatureExecutableFactory factory = new FeatureExecutableFactory(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type FeatureExecutableFactory is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 5. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.build/src_ant/org/eclipse/pde/internal/build/tasks/BuildManifestTask.java + [javac] (at line 193) + [javac] return (Feature) factory.createFeature(root.toFile().toURL(), null, null); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createFeature(URL, ISite, IProgressMonitor) from the type FeatureExecutableFactory is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.update.core/@dot + [javac] ---------- + [javac] 5 problems (5 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.junit.runtime/src/org/eclipse/pde/internal/junit/runtime/RemotePluginTestRunner.java + [javac] (at line 19) + [javac] import org.eclipse.jdt.internal.junit.runner.RemoteTestRunner; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type RemoteTestRunner is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit.runtime/junitruntime.jar + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.junit.runtime/src/org/eclipse/pde/internal/junit/runtime/RemotePluginTestRunner.java + [javac] (at line 25) + [javac] public class RemotePluginTestRunner extends RemoteTestRunner { + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type RemoteTestRunner is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit.runtime/junitruntime.jar + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.junit.runtime/src/org/eclipse/pde/internal/junit/runtime/RemotePluginTestRunner.java + [javac] (at line 52) + [javac] * @see RemoteTestRunner + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type RemoteTestRunner is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit.runtime/junitruntime.jar + [javac] ---------- + [javac] 4. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.junit.runtime/src/org/eclipse/pde/internal/junit/runtime/RemotePluginTestRunner.java + [javac] (at line 58) + [javac] testRunner.run(); + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method run() from the type RemoteTestRunner is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit.runtime/junitruntime.jar + [javac] ---------- + [javac] 5. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.junit.runtime/src/org/eclipse/pde/internal/junit/runtime/RemotePluginTestRunner.java + [javac] (at line 63) + [javac] * @see RemoteTestRunner#getTestClassLoader() + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type RemoteTestRunner is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit.runtime/junitruntime.jar + [javac] ---------- + [javac] 6. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.junit.runtime/src/org/eclipse/pde/internal/junit/runtime/RemotePluginTestRunner.java + [javac] (at line 63) + [javac] * @see RemoteTestRunner#getTestClassLoader() + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getTestClassLoader() from the type RemoteTestRunner is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit.runtime/junitruntime.jar + [javac] ---------- + [javac] 7. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.junit.runtime/src/org/eclipse/pde/internal/junit/runtime/RemotePluginTestRunner.java + [javac] (at line 79) + [javac] defaultInit(args); + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method defaultInit(String[]) from the type RemoteTestRunner is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit.runtime/junitruntime.jar + [javac] ---------- + [javac] 7 problems (7 warnings) + [javac] ---------- + [javac] 1. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/build/BaseBuildAction.java + [javac] (at line 18) + [javac] import org.eclipse.ant.internal.ui.IAntUIConstants; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAntUIConstants is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/@dot + [javac] ---------- + [javac] 2. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/build/BaseBuildAction.java + [javac] (at line 19) + [javac] import org.eclipse.ant.internal.ui.launchConfigurations.AntLaunchShortcut; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AntLaunchShortcut is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/@dot + [javac] ---------- + [javac] 3. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/build/BaseBuildAction.java + [javac] (at line 20) + [javac] import org.eclipse.ant.internal.ui.launchConfigurations.IAntLaunchConfigurationConstants; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAntLaunchConfigurationConstants is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/@dot + [javac] ---------- + [javac] 4. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/build/BaseBuildAction.java + [javac] (at line 176) + [javac] List configs = AntLaunchShortcut + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AntLaunchShortcut is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/@dot + [javac] ---------- + [javac] 5. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/build/BaseBuildAction.java + [javac] (at line 176) + [javac] List configs = AntLaunchShortcut + [javac] .findExistingLaunchConfigurations(generatedFile); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method findExistingLaunchConfigurations(IFile) from the type AntLaunchShortcut is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/@dot + [javac] ---------- + [javac] 6. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/build/BaseBuildAction.java + [javac] (at line 180) + [javac] ILaunchConfiguration config = AntLaunchShortcut + [javac] ^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AntLaunchShortcut is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/@dot + [javac] ---------- + [javac] 7. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/build/BaseBuildAction.java + [javac] (at line 180) + [javac] ILaunchConfiguration config = AntLaunchShortcut + [javac] .createDefaultLaunchConfiguration(generatedFile); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method createDefaultLaunchConfiguration(IFile) from the type AntLaunchShortcut is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/@dot + [javac] ---------- + [javac] 8. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/build/BaseBuildAction.java + [javac] (at line 192) + [javac] IAntLaunchConfigurationConstants.ATTR_ANT_PROPERTIES, + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAntLaunchConfigurationConstants is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/@dot + [javac] ---------- + [javac] 9. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/build/BaseBuildAction.java + [javac] (at line 192) + [javac] IAntLaunchConfigurationConstants.ATTR_ANT_PROPERTIES, + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field ATTR_ANT_PROPERTIES from the type IAntLaunchConfigurationConstants is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/@dot + [javac] ---------- + [javac] 10. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/build/BaseBuildAction.java + [javac] (at line 224) + [javac] IAntLaunchConfigurationConstants.ATTR_ANT_PROPERTIES, + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAntLaunchConfigurationConstants is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/@dot + [javac] ---------- + [javac] 11. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/build/BaseBuildAction.java + [javac] (at line 224) + [javac] IAntLaunchConfigurationConstants.ATTR_ANT_PROPERTIES, + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field ATTR_ANT_PROPERTIES from the type IAntLaunchConfigurationConstants is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/@dot + [javac] ---------- + [javac] 12. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/build/BaseBuildAction.java + [javac] (at line 239) + [javac] IAntUIConstants.ATTR_DEFAULT_VM_INSTALL, + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type IAntUIConstants is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/@dot + [javac] ---------- + [javac] 13. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/build/BaseBuildAction.java + [javac] (at line 239) + [javac] IAntUIConstants.ATTR_DEFAULT_VM_INSTALL, + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field ATTR_DEFAULT_VM_INSTALL from the type IAntUIConstants is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.ant.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 14. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/build/BuildSourcePage.java + [javac] (at line 12) + [javac] import org.eclipse.jdt.internal.ui.JavaPlugin; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 15. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/build/BuildSourcePage.java + [javac] (at line 77) + [javac] IPreferenceStore store = JavaPlugin.getDefault().getCombinedPreferenceStore(); + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 16. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/build/BuildSourcePage.java + [javac] (at line 77) + [javac] IPreferenceStore store = JavaPlugin.getDefault().getCombinedPreferenceStore(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getDefault() from the type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 17. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/build/BuildSourcePage.java + [javac] (at line 77) + [javac] IPreferenceStore store = JavaPlugin.getDefault().getCombinedPreferenceStore(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getCombinedPreferenceStore() from the type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 18. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/text/ColorManager.java + [javac] (at line 17) + [javac] import org.eclipse.jdt.internal.ui.JavaPlugin; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 19. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/text/ColorManager.java + [javac] (at line 73) + [javac] pstore = JavaPlugin.getDefault().getCombinedPreferenceStore(); + [javac] ^^^^^^^^^^ + [javac] Discouraged access: The type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 20. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/text/ColorManager.java + [javac] (at line 73) + [javac] pstore = JavaPlugin.getDefault().getCombinedPreferenceStore(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getDefault() from the type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] 21. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/text/ColorManager.java + [javac] (at line 73) + [javac] pstore = JavaPlugin.getDefault().getCombinedPreferenceStore(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getCombinedPreferenceStore() from the type JavaPlugin is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.ui/@dot + [javac] ---------- + [javac] ---------- + [javac] 22. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 36) + [javac] import org.eclipse.jdt.internal.junit.launcher.JUnitBaseLaunchConfiguration; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JUnitBaseLaunchConfiguration is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 23. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 37) + [javac] import org.eclipse.jdt.internal.junit.launcher.TestSearchResult; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type TestSearchResult is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 24. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 66) + [javac] public class JUnitLaunchConfiguration extends JUnitBaseLaunchConfiguration { + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JUnitBaseLaunchConfiguration is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 25. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 83) + [javac] TestSearchResult testSearchResult = findTestTypes(configuration, monitor); + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type TestSearchResult is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 26. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 83) + [javac] TestSearchResult testSearchResult = findTestTypes(configuration, monitor); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method findTestTypes(ILaunchConfiguration, IProgressMonitor) from the type JUnitBaseLaunchConfiguration is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 27. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 84) + [javac] IType[] testTypes = testSearchResult.getTypes(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getTypes() from the type TestSearchResult is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 28. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 109) + [javac] launch.setAttribute(PORT_ATTR, Integer.toString(port)); + [javac] ^^^^^^^^^ + [javac] Discouraged access: The field PORT_ATTR from the type JUnitBaseLaunchConfiguration is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 29. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 110) + [javac] launch.setAttribute(TESTTYPE_ATTR, testTypes[0].getHandleIdentifier()); + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The field TESTTYPE_ATTR from the type JUnitBaseLaunchConfiguration is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 30. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 133) + [javac] TestSearchResult testTypes, + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type TestSearchResult is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 31. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 179) + [javac] TestSearchResult testSearchResult, + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type TestSearchResult is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 32. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 212) + [javac] programArgs.addAll(getBasicArguments(configuration, port, runMode, testSearchResult)); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getBasicArguments(ILaunchConfiguration, int, String, TestSearchResult) from the type JUnitBaseLaunchConfiguration is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 33. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 295) + [javac] programArgs.add(testSearchResult.getTestKind().getLoaderPluginId()); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getTestKind() from the type TestSearchResult is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 34. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 295) + [javac] programArgs.add(testSearchResult.getTestKind().getLoaderPluginId()); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getLoaderPluginId() from the type ITestKind is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 35. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 297) + [javac] String testFailureNames = configuration.getAttribute(JUnitBaseLaunchConfiguration.FAILURES_FILENAME_ATTR, ""); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JUnitBaseLaunchConfiguration is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 36. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 297) + [javac] String testFailureNames = configuration.getAttribute(JUnitBaseLaunchConfiguration.FAILURES_FILENAME_ATTR, ""); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field FAILURES_FILENAME_ATTR from the type JUnitBaseLaunchConfiguration is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 37. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 304) + [javac] IType[] testTypes = testSearchResult.getTypes(); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getTypes() from the type TestSearchResult is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 38. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 306) + [javac] configuration.getAttribute(JUnitBaseLaunchConfiguration.TESTNAME_ATTR, ""); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JUnitBaseLaunchConfiguration is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 39. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 306) + [javac] configuration.getAttribute(JUnitBaseLaunchConfiguration.TESTNAME_ATTR, ""); //$NON-NLS-1$ + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The field TESTNAME_ATTR from the type JUnitBaseLaunchConfiguration is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 40. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 318) + [javac] protected IPluginModelBase[] addRequiredPlugins(Map pluginMap, TestSearchResult result) + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type TestSearchResult is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 41. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 323) + [javac] addRequiredPlugin(pluginMap, result.getTestKind().getLoaderPluginId()); + [javac] ^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getTestKind() from the type TestSearchResult is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 42. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitLaunchConfiguration.java + [javac] (at line 323) + [javac] addRequiredPlugin(pluginMap, result.getTestKind().getLoaderPluginId()); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method getLoaderPluginId() from the type ITestKind is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] ---------- + [javac] 43. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitTabGroup.java + [javac] (at line 16) + [javac] import org.eclipse.jdt.internal.junit.launcher.AssertionVMArg; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AssertionVMArg is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 44. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitTabGroup.java + [javac] (at line 17) + [javac] import org.eclipse.jdt.internal.junit.launcher.JUnitMainTab; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JUnitMainTab is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 45. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitTabGroup.java + [javac] (at line 32) + [javac] new JUnitMainTab(), + [javac] ^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The constructor JUnitMainTab() is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 46. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitTabGroup.java + [javac] (at line 32) + [javac] new JUnitMainTab(), + [javac] ^^^^^^^^^^^^ + [javac] Discouraged access: The type JUnitMainTab is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 47. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitTabGroup.java + [javac] (at line 55) + [javac] vmArgs = AssertionVMArg.enableAssertInArgString(vmArgs); + [javac] ^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AssertionVMArg is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 48. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitTabGroup.java + [javac] (at line 55) + [javac] vmArgs = AssertionVMArg.enableAssertInArgString(vmArgs); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method enableAssertInArgString(String) from the type AssertionVMArg is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] ---------- + [javac] 49. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitWorkbenchShortcut.java + [javac] (at line 21) + [javac] import org.eclipse.jdt.internal.junit.launcher.AssertionVMArg; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AssertionVMArg is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 50. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitWorkbenchShortcut.java + [javac] (at line 22) + [javac] import org.eclipse.jdt.internal.junit.launcher.JUnitBaseLaunchConfiguration; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JUnitBaseLaunchConfiguration is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 51. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitWorkbenchShortcut.java + [javac] (at line 23) + [javac] import org.eclipse.jdt.internal.junit.launcher.JUnitLaunchShortcut; + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JUnitLaunchShortcut is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 52. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitWorkbenchShortcut.java + [javac] (at line 31) + [javac] public class JUnitWorkbenchShortcut extends JUnitLaunchShortcut { + [javac] ^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JUnitLaunchShortcut is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 53. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitWorkbenchShortcut.java + [javac] (at line 67) + [javac] wc.setAttribute(JUnitBaseLaunchConfiguration.ATTR_KEEPRUNNING, false); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JUnitBaseLaunchConfiguration is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 54. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitWorkbenchShortcut.java + [javac] (at line 67) + [javac] wc.setAttribute(JUnitBaseLaunchConfiguration.ATTR_KEEPRUNNING, false); + [javac] ^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field ATTR_KEEPRUNNING from the type JUnitBaseLaunchConfiguration is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 55. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitWorkbenchShortcut.java + [javac] (at line 68) + [javac] wc.setAttribute(JUnitBaseLaunchConfiguration.LAUNCH_CONTAINER_ATTR, container); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JUnitBaseLaunchConfiguration is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 56. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitWorkbenchShortcut.java + [javac] (at line 68) + [javac] wc.setAttribute(JUnitBaseLaunchConfiguration.LAUNCH_CONTAINER_ATTR, container); + [javac] ^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The field LAUNCH_CONTAINER_ATTR from the type JUnitBaseLaunchConfiguration is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 57. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitWorkbenchShortcut.java + [javac] (at line 70) + [javac] wc.setAttribute(JUnitBaseLaunchConfiguration.TESTNAME_ATTR, testName); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The type JUnitBaseLaunchConfiguration is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 58. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitWorkbenchShortcut.java + [javac] (at line 70) + [javac] wc.setAttribute(JUnitBaseLaunchConfiguration.TESTNAME_ATTR, testName); + [javac] ^^^^^^^^^^^^^ + [javac] Discouraged access: The field TESTNAME_ATTR from the type JUnitBaseLaunchConfiguration is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 59. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitWorkbenchShortcut.java + [javac] (at line 80) + [javac] AssertionVMArg.setArgDefault(wc); + [javac] ^^^^^^^^^^^^^^ + [javac] Discouraged access: The type AssertionVMArg is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 60. WARNING in /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/JUnitWorkbenchShortcut.java + [javac] (at line 80) + [javac] AssertionVMArg.setArgDefault(wc); + [javac] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + [javac] Discouraged access: The method setArgDefault(ILaunchConfigurationWorkingCopy) from the type AssertionVMArg is not accessible due to restriction on classpath entry /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.jdt.junit/junitsupport.jar + [javac] ---------- + [javac] 60 problems (60 warnings) + [echo] Assembling... + [subant] Failure for target 'pre.gather.bin.parts' of: /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.platform.doc.user/customBuildCallbacks.xml + [subant] The following error occurred while executing this line: + [subant] Target `pre.gather.bin.parts' does not exist in this project. + [subant] Failure for target 'pre.gather.bin.parts' of: /volatile/portage/eclipse-sdk-3.2/work/plugins/org.eclipse.platform.doc.isv/customBuildCallbacks.xml + [subant] The following error occurred while executing this line: + [subant] Target `pre.gather.bin.parts' does not exist in this project. + [java] [exec] Result: 1 + [java] [exec] Result: 1 + [java] [exec] Result: 1 + [echo] Done. + +BUILD SUCCESSFUL +Total time: 61 minutes 0 seconds +>>> Source compiled. +>>> Test phase [not enabled]: dev-util/eclipse-sdk-3.2 + +>>> Install eclipse-sdk-3.2 into /volatile/portage/eclipse-sdk-3.2/image/ category dev-util +doexe: warning, skipping directory eclipse +>>> Completed installing eclipse-sdk-3.2 into /volatile/portage/eclipse-sdk-3.2/image/ + +man: + +QA Notice: pre-stripped files found: +/volatile/portage/eclipse-sdk-3.2/image/usr/lib/eclipse-3.2/libcairo-swt.so +strip: i686-pc-linux-gnu-strip --strip-unneeded + usr/lib/eclipse-3.2/eclipse + * Users can now install plugins via Update Manager without any + * tweaking. + + * Eclipse plugin packages (ie eclipse-cdt) will likely go away in + * the near future until they can be properly packaged. Update Manager + * is prefered in the meantime. diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/XmlFriendlyBenchmark.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/XmlFriendlyBenchmark.java new file mode 100644 index 0000000..371c887 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/XmlFriendlyBenchmark.java @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.xmlfriendly; + +import com.thoughtworks.xstream.InitializationException; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.tools.benchmark.Harness; +import com.thoughtworks.xstream.tools.benchmark.Reporter; +import com.thoughtworks.xstream.tools.benchmark.metrics.CharacterCountMetric; +import com.thoughtworks.xstream.tools.benchmark.metrics.DeserializationSpeedMetric; +import com.thoughtworks.xstream.tools.benchmark.metrics.SerializationSpeedMetric; +import com.thoughtworks.xstream.tools.benchmark.metrics.SizeMetric; +import com.thoughtworks.xstream.tools.benchmark.reporters.HtmlReporter; +import com.thoughtworks.xstream.tools.benchmark.reporters.MultiReporter; +import com.thoughtworks.xstream.tools.benchmark.reporters.TextReporter; +import com.thoughtworks.xstream.tools.benchmark.xmlfriendly.products.CachingIterativeAppenderWithShortcut; +import com.thoughtworks.xstream.tools.benchmark.xmlfriendly.products.CombinedLookupAppender; +import com.thoughtworks.xstream.tools.benchmark.xmlfriendly.products.CombinedLookupReplacer; +import com.thoughtworks.xstream.tools.benchmark.xmlfriendly.products.IterativeAppender; +import com.thoughtworks.xstream.tools.benchmark.xmlfriendly.products.IterativeAppenderWithShortcut; +import com.thoughtworks.xstream.tools.benchmark.xmlfriendly.products.IterativeReplacer; +import com.thoughtworks.xstream.tools.benchmark.xmlfriendly.products.NoReplacer; +import com.thoughtworks.xstream.tools.benchmark.xmlfriendly.products.SeparateLookupReplacer; +import com.thoughtworks.xstream.tools.benchmark.xmlfriendly.targets.Field$Reflection; +import com.thoughtworks.xstream.tools.benchmark.xmlfriendly.targets.Field_Reflection; +import com.thoughtworks.xstream.tools.model.targets.FieldReflection; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + + +/** + * Main application to run harness for Reflection benchmark. + * + * @author Jörg Schaible + */ +public class XmlFriendlyBenchmark extends TestSuite { + + public static class __ { + public static class UnfriendlyClass { + String __a__$$a__; + String b__b__; + String __c__c; + + public boolean equals(Object obj) { + UnfriendlyClass other = (UnfriendlyClass)obj; + return __a__$$a__.equals(other.__a__$$a__) + && b__b__.equals(other.b__b__) + && __c__c.equals(other.__c__c); + } + + } + } + + private static Class currentType; + + public static class ReplacerTest extends TestCase { + + private final Class type; + + public ReplacerTest(String name) { + super(name); + type = currentType; + } + + public String getName() { + return type.getName() + ": " + super.getName(); + } + + public void testReplacerWithDefaultReplacements() { + String xml = "" + + "\n" + + " <____a_____-_-a____>a\n" + + " b\n" + + " <____c____c>c\n" + + ""; + performTest("_-", "__", getReference(), xml); + } + + public void testReplacerWithDollarReplacementOnly() { + String xml = "" + + "\n" + + " <__a___-_-a__>a\n" + + " b\n" + + " <__c__c>c\n" + + ""; + performTest("_-", "_", getReference(), xml); + } + + private void performTest(String dollar, String underscore, __.UnfriendlyClass object, + String xml) { + XStream xstream = createXStreamWithReplacer(dollar, underscore); + assertEquals(xml, xstream.toXML(object)); + assertEquals(object, xstream.fromXML(xml)); + } + + private __.UnfriendlyClass getReference() { + __.UnfriendlyClass ref = new __.UnfriendlyClass(); + ref.__a__$$a__ = "a"; + ref.b__b__ = "b"; + ref.__c__c = "c"; + return ref; + } + + private XStream createXStreamWithReplacer(String dollar, String underscore) { + Exception ex; + try { + Constructor constructor = type.getConstructor(new Class[]{ + String.class, String.class, int.class}); + XmlFriendlyReplacer replacer = (XmlFriendlyReplacer)constructor + .newInstance(new Object[]{dollar, underscore, new Integer(0)}); + return new XStream(new XppDriver(replacer)); + } catch (NoSuchMethodException e) { + ex = e; + } catch (InstantiationException e) { + ex = e; + } catch (IllegalAccessException e) { + ex = e; + } catch (InvocationTargetException e) { + ex = e; + } + throw new InitializationException("Cannot initialize XmlFriendlyReplacer", ex); + } + } + + XmlFriendlyBenchmark() { + addTestSuite(CombinedLookupReplacer.XmlFriendlyReplacer.class); + addTestSuite(CombinedLookupAppender.XmlFriendlyReplacer.class); + addTestSuite(SeparateLookupReplacer.XmlFriendlyReplacer.class); + addTestSuite(IterativeReplacer.XmlFriendlyReplacer.class); + addTestSuite(IterativeAppender.XmlFriendlyReplacer.class); + addTestSuite(IterativeAppenderWithShortcut.XmlFriendlyReplacer.class); + addTestSuite(CachingIterativeAppenderWithShortcut.XmlFriendlyReplacer.class); + } + + public void addTestSuite(Class replacerClass) { + currentType = replacerClass; + super.addTestSuite(ReplacerTest.class); + } + + public static Test suite() { + // Ensure the different implementations work + return new XmlFriendlyBenchmark(); + } + + public static void main(String[] args) { + new File("target/benchmarks").mkdirs(); + + Reporter[] reporters; + try { + String basename = "target/benchmarks/xmlfriendly-" + + System.getProperty("user.name"); + reporters = new Reporter[]{ + new TextReporter(), new TextReporter(new FileWriter(basename + ".txt")), + new HtmlReporter(new File(basename + ".html"), "XmlFriendlyReplacer Benchmark")}; + } catch (IOException e) { + throw new RuntimeException(e); + } + + Harness stats = new Harness(); + stats.addMetric(new SizeMetric()); + stats.addMetric(new CharacterCountMetric('$')); + stats.addMetric(new CharacterCountMetric('_')); + stats.addProduct(new NoReplacer()); + stats.addTarget(new FieldReflection()); + stats.addTarget(new Field_Reflection()); + stats.addTarget(new Field$Reflection()); + stats.run(new MultiReporter(reporters) { + + public void endBenchmark() { + // do nothing + } + + }); + + Harness harness = new Harness(); + harness.addMetric(new SerializationSpeedMetric(100)); + harness.addMetric(new DeserializationSpeedMetric(100, false)); + harness.addProduct(new CombinedLookupReplacer(0)); + // harness.addProduct(new CombinedLookupReplacer(32)); + harness.addProduct(new CombinedLookupAppender(0)); + // harness.addProduct(new CombinedLookupAppender(32)); + harness.addProduct(new SeparateLookupReplacer(0)); + // harness.addProduct(new SeparateLookupReplacer(32)); + harness.addProduct(new IterativeReplacer(0)); + // harness.addProduct(new IterativeReplacer(32)); + harness.addProduct(new IterativeAppender(0)); + // harness.addProduct(new IterativeAppender(32)); + harness.addProduct(new IterativeAppenderWithShortcut()); + harness.addProduct(new CachingIterativeAppenderWithShortcut()); + harness.addTarget(new FieldReflection()); + harness.addTarget(new Field_Reflection()); + harness.addTarget(new Field$Reflection()); + harness.run(new MultiReporter(reporters) { + + public void startBenchmark() { + // do nothing + } + + }); + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/model/A100$Fields.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/model/A100$Fields.java new file mode 100644 index 0000000..6ca1f84 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/model/A100$Fields.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 14. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.xmlfriendly.model; + +/** + * Class with 100 fields containing each 5 dollars in the name. + * + * @author Jörg Schaible + */ +public class A100$Fields { + + String $$$$$000; + String $$$$$001; + String $$$$$002; + String $$$$$003; + String $$$$$004; + String $$$$$005; + String $$$$$006; + String $$$$$007; + String $$$$$008; + String $$$$$009; + String $$$$$010; + String $$$$$011; + String $$$$$012; + String $$$$$013; + String $$$$$014; + String $$$$$015; + String $$$$$016; + String $$$$$017; + String $$$$$018; + String $$$$$019; + String $$$$$020; + String $$$$$021; + String $$$$$022; + String $$$$$023; + String $$$$$024; + String $$$$$025; + String $$$$$026; + String $$$$$027; + String $$$$$028; + String $$$$$029; + String $$$$$030; + String $$$$$031; + String $$$$$032; + String $$$$$033; + String $$$$$034; + String $$$$$035; + String $$$$$036; + String $$$$$037; + String $$$$$038; + String $$$$$039; + String $$$$$040; + String $$$$$041; + String $$$$$042; + String $$$$$043; + String $$$$$044; + String $$$$$045; + String $$$$$046; + String $$$$$047; + String $$$$$048; + String $$$$$049; + String $$$$$050; + String $$$$$051; + String $$$$$052; + String $$$$$053; + String $$$$$054; + String $$$$$055; + String $$$$$056; + String $$$$$057; + String $$$$$058; + String $$$$$059; + String $$$$$060; + String $$$$$061; + String $$$$$062; + String $$$$$063; + String $$$$$064; + String $$$$$065; + String $$$$$066; + String $$$$$067; + String $$$$$068; + String $$$$$069; + String $$$$$070; + String $$$$$071; + String $$$$$072; + String $$$$$073; + String $$$$$074; + String $$$$$075; + String $$$$$076; + String $$$$$077; + String $$$$$078; + String $$$$$079; + String $$$$$080; + String $$$$$081; + String $$$$$082; + String $$$$$083; + String $$$$$084; + String $$$$$085; + String $$$$$086; + String $$$$$087; + String $$$$$088; + String $$$$$089; + String $$$$$090; + String $$$$$091; + String $$$$$092; + String $$$$$093; + String $$$$$094; + String $$$$$095; + String $$$$$096; + String $$$$$097; + String $$$$$098; + String $$$$$099; +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/model/A100_Fields.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/model/A100_Fields.java new file mode 100644 index 0000000..1e29858 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/model/A100_Fields.java @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.xmlfriendly.model; + +/** + * Class with 100 fields containing each 5 underscores in the name. + * + * @author Jörg Schaible + */ +public class A100_Fields { + + String _____000; + String _____001; + String _____002; + String _____003; + String _____004; + String _____005; + String _____006; + String _____007; + String _____008; + String _____009; + String _____010; + String _____011; + String _____012; + String _____013; + String _____014; + String _____015; + String _____016; + String _____017; + String _____018; + String _____019; + String _____020; + String _____021; + String _____022; + String _____023; + String _____024; + String _____025; + String _____026; + String _____027; + String _____028; + String _____029; + String _____030; + String _____031; + String _____032; + String _____033; + String _____034; + String _____035; + String _____036; + String _____037; + String _____038; + String _____039; + String _____040; + String _____041; + String _____042; + String _____043; + String _____044; + String _____045; + String _____046; + String _____047; + String _____048; + String _____049; + String _____050; + String _____051; + String _____052; + String _____053; + String _____054; + String _____055; + String _____056; + String _____057; + String _____058; + String _____059; + String _____060; + String _____061; + String _____062; + String _____063; + String _____064; + String _____065; + String _____066; + String _____067; + String _____068; + String _____069; + String _____070; + String _____071; + String _____072; + String _____073; + String _____074; + String _____075; + String _____076; + String _____077; + String _____078; + String _____079; + String _____080; + String _____081; + String _____082; + String _____083; + String _____084; + String _____085; + String _____086; + String _____087; + String _____088; + String _____089; + String _____090; + String _____091; + String _____092; + String _____093; + String _____094; + String _____095; + String _____096; + String _____097; + String _____098; + String _____099; +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/AbstractXmlFriendlyReplacer.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/AbstractXmlFriendlyReplacer.java new file mode 100644 index 0000000..d4f791c --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/AbstractXmlFriendlyReplacer.java @@ -0,0 +1,463 @@ +/* + * Copyright (C) 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.xmlfriendly.products; + +import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer; + +import java.lang.ref.WeakReference; +import java.util.Map; +import java.util.WeakHashMap; + + +/** + * Abstract base class for the XmlFriendlyReplacer with all kind of implementations. + * + * @author Jörg Schaible + * @author Mauro Talevi + * @author Tatu Saloranta + */ +public abstract class AbstractXmlFriendlyReplacer extends XmlFriendlyReplacer { + + private final String dollarReplacement; + private final String underscoreReplacement; + private final int bufferIncrement; + private final Map escapeCache; + private final Map unescapeCache; + + /** + * Creates an XmlFriendlyReplacer with custom replacements + * + * @param dollarReplacement the replacement for '$' + * @param underscoreReplacement the replacement for '_' + * @param bufferIncrement buffer increment for preallocation + */ + public AbstractXmlFriendlyReplacer( + final String dollarReplacement, final String underscoreReplacement, + final int bufferIncrement) { + this.dollarReplacement = dollarReplacement; + this.underscoreReplacement = underscoreReplacement; + this.bufferIncrement = bufferIncrement; + escapeCache = new WeakHashMap(); + unescapeCache = new WeakHashMap(); + } + + /** + * Escapes name substituting '$' and '_' with replacement strings + * + * @param name the name of attribute or node + * @return The String with the escaped name + */ + public abstract String escapeName(String name); + + /** + * Escapes name substituting '$' and '_' with replacement strings + * + * @param name the name of attribute or node + * @return The String with the escaped name + */ + public abstract String unescapeName(String name); + + protected String escapeNoName(final String name) { + return name; + } + + protected String unescapeNoName(final String name) { + return name; + } + + protected String escapeIterativelyAppending(final String name) { + final int length = name.length(); + final StringBuffer result = bufferIncrement == 0 + ? new StringBuffer() + : new StringBuffer(length + bufferIncrement); + for (int i = 0; i < length; i++) { + final char c = name.charAt(i); + if (c == '$') { + result.append(dollarReplacement); + } else if (c == '_') { + result.append(underscoreReplacement); + } else { + result.append(c); + } + } + return result.toString(); + } + + protected String unescapeIterativelyAppending(final String name) { + final int underscoreReplacementInc = underscoreReplacement.length() - 1; + final int dollarReplacementInc = dollarReplacement.length() - 1; + final int length = name.length(); + final StringBuffer result = bufferIncrement == 0 + ? new StringBuffer() + : new StringBuffer(length + bufferIncrement); + for (int i = 0; i < length; i++) { + final char c = name.charAt(i); + if (name.startsWith(dollarReplacement, i)) { + i += dollarReplacementInc; + result.append('$'); + } else if (name.startsWith(underscoreReplacement, i)) { + i += underscoreReplacementInc; + result.append('_'); + } else { + result.append(c); + } + } + return result.toString(); + } + + protected String escapeByCombinedLookupAppending(final String name) { + final int length = name.length(); + final StringBuffer result = bufferIncrement == 0 + ? new StringBuffer() + : new StringBuffer(length + bufferIncrement); + int posDollar = 0; + int posUnderscore = 0; + for (int i = 0; i < length;) { + if (posUnderscore >= 0) { + posUnderscore = name.indexOf('_', i); + } + if (posDollar >= 0) { + posDollar = name.indexOf('$', i); + } + if (posDollar == -1 && posUnderscore == -1) { + if (i < length) { + result.append(name.substring(i)); + } + break; + } else if (posDollar >= 0 && (posUnderscore == -1 || posUnderscore >= posDollar)) { + result.append(name.substring(i, posDollar)); + result.append(dollarReplacement); + i = posDollar + 1; + } else if (posUnderscore >= 0) { + result.append(name.substring(i, posUnderscore)); + result.append(underscoreReplacement); + i = posUnderscore + 1; + } + } + return result.toString(); + } + + protected String unescapeByCombinedLookupAppending(final String name) { + final int underscoreReplacementLength = underscoreReplacement.length(); + final int dollarReplacementLength = dollarReplacement.length(); + final int length = name.length(); + final StringBuffer result = bufferIncrement == 0 + ? new StringBuffer() + : new StringBuffer(length + bufferIncrement); + int posDollar = 0; + int posUnderscore = 0; + for (int i = 0; i < length;) { + if (posUnderscore >= 0) { + posUnderscore = name.indexOf(underscoreReplacement, i); + } + if (posDollar >= 0) { + posDollar = name.indexOf(dollarReplacement, i); + } + if (posDollar == -1 && posUnderscore == -1) { + if (i < length) { + result.append(name.substring(i)); + } + break; + } else if (posDollar >= 0 && (posUnderscore == -1 || posUnderscore >= posDollar)) { + result.append(name.substring(i, posDollar)); + result.append('$'); + i = posDollar + dollarReplacementLength; + } else if (posUnderscore >= 0) { + result.append(name.substring(i, posUnderscore)); + result.append('_'); + i = posUnderscore + underscoreReplacementLength; + } + } + return result.toString(); + } + + protected String escapeByCombinedLookupReplacing(final String name) { + final int underscoreReplacementLength = underscoreReplacement.length(); + final int dollarReplacementLength = dollarReplacement.length(); + final StringBuffer result; + if (bufferIncrement == 0) { + result = new StringBuffer(name); + } else { + result = new StringBuffer(name.length() + bufferIncrement); + result.append(name); + } + int posDollar = 0; + int posUnderscore = 0; + int i = 0; + while (true) { + if (posUnderscore >= 0) { + posUnderscore = result.indexOf("_", i); + } + if (posDollar >= 0) { + posDollar = result.indexOf("$", i); + } + if (posDollar == -1 && posUnderscore == -1) { + break; + } else if (posDollar >= 0 && (posUnderscore == -1 || posUnderscore > posDollar)) { + result.replace(posDollar, posDollar + 1, dollarReplacement); + i = posDollar + dollarReplacementLength; + } else if (posUnderscore >= 0) { + result.replace(posUnderscore, posUnderscore + 1, underscoreReplacement); + i = posUnderscore + underscoreReplacementLength; + } + } + return result.toString(); + } + + protected String unescapeByCombinedLookupReplacing(final String name) { + final int underscoreReplacementLength = underscoreReplacement.length(); + final int dollarReplacementLength = dollarReplacement.length(); + final StringBuffer result; + if (bufferIncrement == 0) { + result = new StringBuffer(name); + } else { + result = new StringBuffer(name.length() + bufferIncrement); + result.append(name); + } + int posDollar = 0; + int posUnderscore = 0; + int i = 0; + while (true) { + if (posUnderscore >= 0) { + posUnderscore = result.indexOf(underscoreReplacement, i); + } + if (posDollar >= 0) { + posDollar = result.indexOf(dollarReplacement, i); + } + if (posDollar == -1 && posUnderscore == -1) { + break; + } else if (posDollar >= 0 && (posUnderscore == -1 || posUnderscore >= posDollar)) { + result.replace(posDollar, posDollar + dollarReplacementLength, "$"); + i = posDollar + 1; + } else if (posUnderscore >= 0) { + result.replace(posUnderscore, posUnderscore + underscoreReplacementLength, "_"); + i = posUnderscore + 1; + } + } + return result.toString(); + } + + protected String escapeBySeparateLookupReplacing(final String name) { + final StringBuffer result; + if (bufferIncrement == 0) { + result = new StringBuffer(name); + } else { + result = new StringBuffer(name.length() + bufferIncrement); + result.append(name); + } + final int underscoreReplacementInc = underscoreReplacement.length(); + final int dollarReplacementInc = dollarReplacement.length(); + int inc = 0; + int pos = 0; + + while ((pos = result.indexOf("_", pos + inc)) != -1) { + result.replace(pos, pos + 1, underscoreReplacement); + inc = underscoreReplacementInc; + } + + inc = 0; + pos = 0; + while ((pos = result.indexOf("$", pos + inc)) != -1) { + result.replace(pos, pos + 1, dollarReplacement); + inc = dollarReplacementInc; + } + return result.toString(); + } + + protected String unescapeBySeparateLookupReplacing(final String name) { + final StringBuffer result; + if (bufferIncrement == 0) { + result = new StringBuffer(name); + } else { + result = new StringBuffer(name.length() + bufferIncrement); + result.append(name); + } + int dollarReplacementLength = dollarReplacement.length(); + int pos = -dollarReplacementLength; + while ((pos = result.indexOf(dollarReplacement, pos + 1)) != -1) { + result.replace(pos, pos + dollarReplacementLength, "$"); + } + + int underscoreReplacementLength = underscoreReplacement.length(); + pos = -underscoreReplacementLength; + + while ((pos = result.indexOf(underscoreReplacement, pos + 1)) != -1) { + result.replace(pos, pos + underscoreReplacementLength, "_"); + } + + return result.toString(); + } + + protected String escapeIterativelyReplacing(final String name) { + int length = name.length(); + final int underscoreReplacementInc = underscoreReplacement.length() - 1; + final int dollarReplacementInc = dollarReplacement.length() - 1; + final StringBuffer result; + if (bufferIncrement == 0) { + result = new StringBuffer(name); + } else { + result = new StringBuffer(length + bufferIncrement); + result.append(name); + } + for (int i = 0; i < length; i++) { + final char c = result.charAt(i); + if (c == '$') { + result.replace(i, i + 1, dollarReplacement); + length += dollarReplacementInc; + i += dollarReplacementInc; + } else if (c == '_') { + result.replace(i, i + 1, underscoreReplacement); + length += underscoreReplacementInc; + i += underscoreReplacementInc; + } + } + return result.toString(); + } + + protected String unescapeIterativelyReplacing(final String name) { + final char dollarChar = dollarReplacement.charAt(0); + final char underscoreChar = underscoreReplacement.charAt(0); + final int underscoreReplacementLength = underscoreReplacement.length(); + final int dollarReplacementLength = dollarReplacement.length(); + int length = name.length(); + final StringBuffer result; + if (bufferIncrement == 0) { + result = new StringBuffer(name); + } else { + result = new StringBuffer(length + bufferIncrement); + result.append(name); + } + for (int i = 0; i < length; ++i) { + final char c = result.charAt(i); + if (c == dollarChar + && i + dollarReplacementLength <= length + && result.substring(i, i + dollarReplacementLength).equals(dollarReplacement)) { + result.replace(i, i + dollarReplacementLength, "$"); + length -= dollarReplacementLength - 1; + } else if (c == underscoreChar + && i + underscoreReplacementLength <= length + && result.substring(i, i + underscoreReplacementLength).equals( + underscoreReplacement)) { + result.replace(i, i + underscoreReplacementLength, "_"); + length -= underscoreReplacementLength - 1; + } + } + return result.toString(); + } + + protected String escapeIterativelyAppendingWithShortcut(String name) { + final int length = name.length(); + + // First, fast (common) case: nothing to escape + int i = 0; + + for (; i < length; i++) { + char c = name.charAt(i); + if (c == '$' || c == '_') { + break; + } + } + + if (i == length) { + return name; + } + + // Otherwise full processing + final StringBuffer result = new StringBuffer(length+8); + + // We know first N chars are safe + if (i > 0) { + result.append(name.substring(0, i)); + } + + for (; i < length; i++) { + char c = name.charAt(i); + if (c == '$' ) { + result.append(dollarReplacement); + } else if (c == '_') { + result.append(underscoreReplacement); + } else { + result.append(c); + } + } + return result.toString(); + } + + protected String unescapeIterativelyAppendingWithShortcut(String name) { + final char dollarReplacementFirstChar = dollarReplacement.charAt(0); + final char underscoreReplacementFirstChar = underscoreReplacement.charAt(0); + final int length = name.length(); + + // First, fast (common) case: nothing to unescape + int i = 0; + + for (; i < length; i++) { + char c = name.charAt(i); + // We'll do a quick check for potential match + if (c == dollarReplacementFirstChar + || c == underscoreReplacementFirstChar) { + // and if it might be a match, just quit, will check later on + break; + } + } + + if (i == length) { + return name; + } + + // Otherwise full processing + final StringBuffer result = new StringBuffer(length+8); + + // We know first N chars are safe + if (i > 0) { + result.append(name.substring(0, i)); + } + + for (; i < length; i++) { + char c = name.charAt(i); + if (c == dollarReplacementFirstChar + && name.startsWith(dollarReplacement, i)) { + i += dollarReplacement.length()-1; + result.append('$'); + } else if (c == underscoreReplacementFirstChar + && name.startsWith(underscoreReplacement, i)) { + i += underscoreReplacement.length()-1; + result.append('_'); + } else { + result.append(c); + } + } + + return result.toString(); + } + + protected String escapeCachingIterativelyAppendingWithShortcut(String name) { + final WeakReference ref = (WeakReference)escapeCache.get(name); + String s = (String)(ref == null ? null : ref.get()); + + if (s == null) { + s = escapeIterativelyAppendingWithShortcut(name); + escapeCache.put(name, new WeakReference(s)); + } + return s; + } + + protected String unescapeCachingIterativelyAppendingWithShortcut(String name) { + final WeakReference ref = (WeakReference)unescapeCache.get(name); + String s = (String)(ref == null ? null : ref.get()); + + if (s == null) { + s = unescapeIterativelyAppendingWithShortcut(name); + unescapeCache.put(name, new WeakReference(s)); + } + return s; + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/CachingIterativeAppenderWithShortcut.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/CachingIterativeAppenderWithShortcut.java new file mode 100644 index 0000000..63dcfac --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/CachingIterativeAppenderWithShortcut.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 20. Oktober 2008 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.xmlfriendly.products; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.tools.benchmark.Product; + +import java.io.InputStream; +import java.io.OutputStream; + + +/** + * Special handling for conforming strings, iterates otherwise through the incoming string, + * appends the characters and caches the result. Used in XStream [1.3.1; ). + * + * @author Jörg Schaible + */ +public class CachingIterativeAppenderWithShortcut implements Product { + + private final XStream xstream; + + public CachingIterativeAppenderWithShortcut() { + this.xstream = new XStream(new XppDriver(new XmlFriendlyReplacer())); + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.toXML(object, output); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.fromXML(input); + } + + public String toString() { + return "Caching Iterative Appender with Shortcut"; + } + + public static class XmlFriendlyReplacer extends AbstractXmlFriendlyReplacer { + + public XmlFriendlyReplacer() { + this("_-", "__", 0); + } + + public XmlFriendlyReplacer(String dollarReplacement, String underscoreReplacement, int bufferIncrement) { + super(dollarReplacement, underscoreReplacement, bufferIncrement); + } + + public String escapeName(String name) { + return super.escapeCachingIterativelyAppendingWithShortcut(name); + } + + public String unescapeName(String name) { + return super.unescapeCachingIterativelyAppendingWithShortcut(name); + } + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/CombinedLookupAppender.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/CombinedLookupAppender.java new file mode 100644 index 0000000..cd0f4a2 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/CombinedLookupAppender.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.xmlfriendly.products; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.tools.benchmark.Product; + +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Uses a combined lookup and appends characters. + * + * @author Jörg Schaible + */ +public class CombinedLookupAppender implements Product { + + private final XStream xstream; + private final int bufferIncrement; + + public CombinedLookupAppender(int bufferIncrement) { + this.bufferIncrement = bufferIncrement; + this.xstream = new XStream(new XppDriver(new XmlFriendlyReplacer(bufferIncrement))); + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.toXML(object, output); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.fromXML(input); + } + + public String toString() { + return "Combined Lookup Appending" + (bufferIncrement == 0 ? "" : (" (" + bufferIncrement + ")")); + } + + public static class XmlFriendlyReplacer extends AbstractXmlFriendlyReplacer { + + public XmlFriendlyReplacer(int bufferIncrement) { + super("_-", "__", bufferIncrement); + } + + public XmlFriendlyReplacer(String dollarReplacement, String underscoreReplacement, int bufferIncrement) { + super(dollarReplacement, underscoreReplacement, bufferIncrement); + } + + public String escapeName(String name) { + return super.escapeByCombinedLookupAppending(name); + } + + public String unescapeName(String name) { + return super.unescapeByCombinedLookupAppending(name); + } + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/CombinedLookupReplacer.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/CombinedLookupReplacer.java new file mode 100644 index 0000000..46e8778 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/CombinedLookupReplacer.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.xmlfriendly.products; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.tools.benchmark.Product; + +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Uses a combined lookup and replaces characters. + * + * @author Jörg Schaible + */ +public class CombinedLookupReplacer implements Product { + + private final XStream xstream; + private final int bufferIncrement; + + public CombinedLookupReplacer(int bufferIncrement) { + this.bufferIncrement = bufferIncrement; + this.xstream = new XStream(new XppDriver(new XmlFriendlyReplacer(bufferIncrement))); + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.toXML(object, output); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.fromXML(input); + } + + public String toString() { + return "Combined Lookup Replacer" + (bufferIncrement == 0 ? "" : (" (" + bufferIncrement + ")")); + } + + public static class XmlFriendlyReplacer extends AbstractXmlFriendlyReplacer { + + public XmlFriendlyReplacer(int bufferIncrement) { + super("_-", "__", bufferIncrement); + } + + public XmlFriendlyReplacer(String dollarReplacement, String underscoreReplacement, int bufferIncrement) { + super(dollarReplacement, underscoreReplacement, bufferIncrement); + } + + public String escapeName(String name) { + return super.escapeByCombinedLookupReplacing(name); + } + + public String unescapeName(String name) { + return super.unescapeByCombinedLookupReplacing(name); + } + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/IterativeAppender.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/IterativeAppender.java new file mode 100644 index 0000000..5e77d7b --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/IterativeAppender.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.xmlfriendly.products; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.tools.benchmark.Product; + +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Iterates through the incoming string and appends the characters. + * Used in XStream [1.3; 1.2.2]. + * + * @author Jörg Schaible + */ +public class IterativeAppender implements Product { + + private final XStream xstream; + private final int bufferIncrement; + + public IterativeAppender(int bufferIncrement) { + this.bufferIncrement = bufferIncrement; + this.xstream = new XStream(new XppDriver(new XmlFriendlyReplacer(bufferIncrement))); + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.toXML(object, output); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.fromXML(input); + } + + public String toString() { + return "Iterative Appender" + (bufferIncrement == 0 ? "" : (" (" + bufferIncrement + ")")); + } + + public static class XmlFriendlyReplacer extends AbstractXmlFriendlyReplacer { + + public XmlFriendlyReplacer(int bufferIncrement) { + super("_-", "__", bufferIncrement); + } + + public XmlFriendlyReplacer(String dollarReplacement, String underscoreReplacement, int bufferIncrement) { + super(dollarReplacement, underscoreReplacement, bufferIncrement); + } + + public String escapeName(String name) { + return super.escapeIterativelyAppending(name); + } + + public String unescapeName(String name) { + return super.unescapeIterativelyAppending(name); + } + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/IterativeAppenderWithShortcut.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/IterativeAppenderWithShortcut.java new file mode 100644 index 0000000..22d5925 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/IterativeAppenderWithShortcut.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 02. September 2008 by Tatu Saloranta + */ +package com.thoughtworks.xstream.tools.benchmark.xmlfriendly.products; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.tools.benchmark.Product; + +import java.io.InputStream; +import java.io.OutputStream; + + +/** + * Special handling for conforming strings, iterates otherwise through the incoming string and + * appends the character. + * + * @author Jörg Schaible + * @author Tatu Saloranta + */ +public class IterativeAppenderWithShortcut implements Product { + + private final XStream xstream; + + public IterativeAppenderWithShortcut() { + this.xstream = new XStream(new XppDriver(new XmlFriendlyReplacer())); + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.toXML(object, output); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.fromXML(input); + } + + public String toString() { + return "Iterative Appender with Shortcut"; + } + + public static class XmlFriendlyReplacer extends AbstractXmlFriendlyReplacer { + + public XmlFriendlyReplacer() { + this("_-", "__", 0); + } + + public XmlFriendlyReplacer(String dollarReplacement, String underscoreReplacement, int bufferIncrement) { + super(dollarReplacement, underscoreReplacement, bufferIncrement); + } + + public String escapeName(String name) { + return super.escapeIterativelyAppendingWithShortcut(name); + } + + public String unescapeName(String name) { + return super.unescapeIterativelyAppendingWithShortcut(name); + } + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/IterativeReplacer.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/IterativeReplacer.java new file mode 100644 index 0000000..f9265f7 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/IterativeReplacer.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2007, 2008, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.xmlfriendly.products; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.tools.benchmark.Product; + +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Iterates through the string and replaces characters. + * + * @author Jörg Schaible + */ +public class IterativeReplacer implements Product { + + private final XStream xstream; + private final int bufferIncrement; + + public IterativeReplacer(int bufferIncrement) { + this.bufferIncrement = bufferIncrement; + this.xstream = new XStream(new XppDriver(new XmlFriendlyReplacer(bufferIncrement))); + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.toXML(object, output); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.fromXML(input); + } + + public String toString() { + return "Iterative Replacer" + (bufferIncrement == 0 ? "" : (" (" + bufferIncrement + ")")); + } + + public static class XmlFriendlyReplacer extends AbstractXmlFriendlyReplacer { + + public XmlFriendlyReplacer(int bufferIncrement) { + super("_-", "__", bufferIncrement); + } + + public XmlFriendlyReplacer(String dollarReplacement, String underscoreReplacement, int bufferIncrement) { + super(dollarReplacement, underscoreReplacement, bufferIncrement); + } + + public String escapeName(String name) { + return super.escapeIterativelyReplacing(name); + } + + public String unescapeName(String name) { + return super.unescapeIterativelyReplacing(name); + } + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/NoReplacer.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/NoReplacer.java new file mode 100644 index 0000000..ed66435 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/NoReplacer.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.xmlfriendly.products; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.tools.benchmark.Product; + +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Uses XmlFriendlyReplacer dummy. + * + * @author Jörg Schaible + */ +public class NoReplacer implements Product { + + private final XStream xstream; + + public NoReplacer() { + this.xstream = new XStream(new XppDriver(new XmlFriendlyReplacer())); + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.toXML(object, output); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.fromXML(input); + } + + public String toString() { + return ""; + } + + public static class XmlFriendlyReplacer extends AbstractXmlFriendlyReplacer { + + public XmlFriendlyReplacer() { + super("_-", "__", 0); + } + + public String escapeName(String name) { + return name; + } + + public String unescapeName(String name) { + return name; + } + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/SeparateLookupReplacer.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/SeparateLookupReplacer.java new file mode 100644 index 0000000..714944d --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/products/SeparateLookupReplacer.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.xmlfriendly.products; + +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.tools.benchmark.Product; + +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Uses a combined lookup and replaces characters. + * + * @author Jörg Schaible + */ +public class SeparateLookupReplacer implements Product { + + private final XStream xstream; + private final int bufferIncrement; + + public SeparateLookupReplacer(int bufferIncrement) { + this.bufferIncrement = bufferIncrement; + this.xstream = new XStream(new XppDriver(new XmlFriendlyReplacer(bufferIncrement))); + } + + public void serialize(Object object, OutputStream output) throws Exception { + xstream.toXML(object, output); + } + + public Object deserialize(InputStream input) throws Exception { + return xstream.fromXML(input); + } + + public String toString() { + return "Separate Lookup Replacer" + (bufferIncrement == 0 ? "" : (" (" + bufferIncrement + ")")); + } + + public static class XmlFriendlyReplacer extends AbstractXmlFriendlyReplacer { + + public XmlFriendlyReplacer(int bufferIncrement) { + super("_-", "__", bufferIncrement); + } + + public XmlFriendlyReplacer(String dollarReplacement, String underscoreReplacement, int bufferIncrement) { + super(dollarReplacement, underscoreReplacement, bufferIncrement); + } + + public String escapeName(String name) { + return super.escapeBySeparateLookupReplacing(name); + } + + public String unescapeName(String name) { + return super.unescapeBySeparateLookupReplacing(name); + } + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/targets/Field$Reflection.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/targets/Field$Reflection.java new file mode 100644 index 0000000..7791e7a --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/targets/Field$Reflection.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.xmlfriendly.targets; + +import com.thoughtworks.xstream.tools.benchmark.Target; +import com.thoughtworks.xstream.tools.benchmark.xmlfriendly.model.A100$Fields; +import com.thoughtworks.xstream.tools.model.targets.AbstractReflectionTarget; + +import java.util.ArrayList; +import java.util.List; + +/** + * A Target for a 100 fields class with each field name containing 5 dollars. + * + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Target + */ +public class Field$Reflection extends AbstractReflectionTarget { + + public Field$Reflection() { + super(new ArrayList()); + List list = (List)target(); + for(int i = 0; i < 100; ++i) { + Object o = new A100$Fields(); + fill(o); + list.add(o); + } + } + + public String toString() { + return "Field with dollars Target"; + } + +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/targets/Field_Reflection.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/targets/Field_Reflection.java new file mode 100644 index 0000000..d40d7c1 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/benchmark/xmlfriendly/targets/Field_Reflection.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 13. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.benchmark.xmlfriendly.targets; + +import com.thoughtworks.xstream.tools.benchmark.Target; +import com.thoughtworks.xstream.tools.benchmark.xmlfriendly.model.A100_Fields; +import com.thoughtworks.xstream.tools.model.targets.AbstractReflectionTarget; + +import java.util.ArrayList; +import java.util.List; + +/** + * A Target for a 100 fields class with each field name containing 5 underscores. + * + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Target + */ +public class Field_Reflection extends AbstractReflectionTarget { + + public Field_Reflection() { + super(new ArrayList()); + List list = (List)target(); + for(int i = 0; i < 100; ++i) { + Object o = new A100_Fields(); + fill(o); + list.add(o); + } + } + + public String toString() { + return "Field with underscores Target"; + } + +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/model/targets/AbstractReflectionTarget.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/model/targets/AbstractReflectionTarget.java new file mode 100644 index 0000000..982f48f --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/model/targets/AbstractReflectionTarget.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. June 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.model.targets; + +import com.thoughtworks.xstream.tools.benchmark.Target; + +import org.apache.commons.lang.builder.EqualsBuilder; + +import java.lang.reflect.Field; +import java.util.Arrays; + + +/** + * An abstract Target that fills the fields by reflection. + * + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Target + */ +public abstract class AbstractReflectionTarget implements Target { + + private final Object target; + + public AbstractReflectionTarget(final Object target) { + this.target = target; + } + + public abstract String toString(); + + protected void fill(final Object o) { + final char[] zero = new char[8]; + Arrays.fill(zero, '0'); + for (Class cls = o.getClass(); cls != Object.class; cls = cls.getSuperclass()) { + final Field[] fields = cls.getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + final Field field = fields[i]; + field.setAccessible(true); + if (field.getType() == String.class) { + final String hex = Integer.toHexString(i); + try { + field.set(o, new String(zero, 0, zero.length - hex.length()) + hex); + } catch (final IllegalAccessException e) { + throw new RuntimeException(e); + } + } + } + } + } + + public Object target() { + return target; + } + + public boolean isEqual(final Object other) { + return EqualsBuilder.reflectionEquals(target, other); + } +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/model/targets/FieldReflection.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/model/targets/FieldReflection.java new file mode 100644 index 0000000..d7c9748 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/model/targets/FieldReflection.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. June 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.model.targets; + +import com.thoughtworks.xstream.tools.benchmark.Target; +import com.thoughtworks.xstream.tools.benchmark.model.A100Fields; + +import java.util.ArrayList; +import java.util.List; + +/** + * A Target for a 100 fields class. + * + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Target + */ +public class FieldReflection extends AbstractReflectionTarget { + + public FieldReflection() { + super(new ArrayList()); + List list = (List)target(); + for(int i = 0; i < 100; ++i) { + Object o = new A100Fields(); + fill(o); + list.add(o); + } + } + + public String toString() { + return "Field Target"; + } + +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/model/targets/HierarchyLevelReflection.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/model/targets/HierarchyLevelReflection.java new file mode 100644 index 0000000..320537a --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/model/targets/HierarchyLevelReflection.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 26. June 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.model.targets; + +import com.thoughtworks.xstream.tools.benchmark.Target; +import com.thoughtworks.xstream.tools.benchmark.model.A100Parents; + +import java.util.ArrayList; +import java.util.List; + +/** + * A Target for multiple hierarchy level classes. + * + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Target + */ +public class HierarchyLevelReflection extends AbstractReflectionTarget { + + public HierarchyLevelReflection() { + super(new ArrayList()); + List list = (List)target(); + for(int i = 0; i < 100; ++i) { + String no = "00" + i; + try { + Class cls = Class.forName(A100Parents.class.getName() + "$Parent" + no.substring(no.length() - 3)); + Object o = cls.newInstance(); + fill(o); + list.add(o); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + } + + public String toString() { + return "HierarchyLevel Target"; + } + +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/model/targets/InnerClassesReflection.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/model/targets/InnerClassesReflection.java new file mode 100644 index 0000000..7831cf5 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/model/targets/InnerClassesReflection.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.model.targets; + +import com.thoughtworks.xstream.tools.benchmark.Target; +import com.thoughtworks.xstream.tools.benchmark.model.A50InnerClasses; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; + + +/** + * A Target for multiple hierarchy level classes. + * + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Target + */ +public class InnerClassesReflection extends AbstractReflectionTarget { + + public InnerClassesReflection() { + super(new ArrayList()); + for (int i = 0; i < 10; ++i) { + List list = new ArrayList(); + list.add(new A50InnerClasses()); + StringBuffer name = new StringBuffer(A50InnerClasses.class.getName()); + for (int j = 0; j < 50; ++j) { + String no = "0" + j; + Object parent = list.get(j); + name.append("$L"); + name.append(no.substring(no.length() - 2)); + try { + Class cls = Class.forName(name.toString()); + Constructor ctor = cls + .getDeclaredConstructor(new Class[]{parent.getClass()}); + Object o = ctor.newInstance(new Object[]{parent}); + fill(o); + list.add(o); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + list.remove(0); + ((List)target()).addAll(list); + } + } + + public String toString() { + return "InnerClasses Target"; + } + +} diff --git a/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/model/targets/StaticInnerClassesReflection.java b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/model/targets/StaticInnerClassesReflection.java new file mode 100644 index 0000000..4bfa632 --- /dev/null +++ b/xstream-benchmark/src/test/com/thoughtworks/xstream/tools/model/targets/StaticInnerClassesReflection.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2007, 2009 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 06. September 2007 by Joerg Schaible + */ +package com.thoughtworks.xstream.tools.model.targets; + +import com.thoughtworks.xstream.tools.benchmark.Target; +import com.thoughtworks.xstream.tools.benchmark.model.A50StaticInnerClasses; + +import java.util.ArrayList; +import java.util.List; + + +/** + * A Target for multiple hierarchy level classes. + * + * @author Jörg Schaible + * @see com.thoughtworks.xstream.tools.benchmark.Harness + * @see Target + */ +public class StaticInnerClassesReflection extends AbstractReflectionTarget { + + public StaticInnerClassesReflection() { + super(new ArrayList()); + List list = (List)target(); + for (int i = 0; i < 10; ++i) { + StringBuffer name = new StringBuffer(A50StaticInnerClasses.class.getName()); + for (int j = 0; j < 50; ++j) { + String no = "0" + j; + try { + name.append("$L"); + name.append(no.substring(no.length() - 2)); + Class cls = Class.forName(name.toString()); + Object o = cls.newInstance(); + fill(o); + list.add(o); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + } + } + + public String toString() { + return "StaticInnerClasses Target"; + } + +} diff --git a/xstream-distribution/README.txt b/xstream-distribution/README.txt new file mode 100644 index 0000000..84de809 --- /dev/null +++ b/xstream-distribution/README.txt @@ -0,0 +1,74 @@ +========================================== +Copyright (C) 2005, 2006 Joe Walnes. +Copyright (C) 2006, 2007 XStream committers. +All rights reserved. + +The software in this package is published under the terms of the BSD +style license a copy of which has been included with this distribution in +the LICENSE.txt file. + +Created on 29. January 2005 by Joe Walnes +========================================== + +(The XStream website is build using XSite - http://xsite.codehaus.org) + +STRUCTURE + +The directories should be self explanatory: + ./src/templates: contains the skin HTML and style sheet. Other templates might go here. + ./src/content: contains the content in simple HTML. + +BUILDING SITE + +Run the XSite builder using the Maven 2 plugin associated to the install goal: + +mvn install + +The new site will be deployed in target/xsite + +Alternatively, download the standalone xsite distribution from http://xsite.codehaus.org/download + +$XSITE_HOME/bin/xsite src/content/website.xml src/template/skin.html target/xsite + +EDITING THE CONTENT OF THE SITE + +1) Edit the files in ./src/content. These are plain HTML files and can be edited using any old HTML editor + (including Mozilla Composer or Word). + + Supporting resources that are relevant to the content (such as images) can be placed in this directory. + +2) If the structure of the navigation requires a change (necessary if adding a new page), update ./src/content/website.xml. + + +EDITING THE LOOK AND FEEL OF THE SITE + +1) Edit the file ./src/templates/skin.html. This is a FreeMarker template that is applied to each page using SiteMesh. + + Supporting resources that are relevant to the look and feel (such as images or CSS) can be placed in this directory. + + +DESIGN PRINCIPLES + +The ideas behind site design are as follows: + +1) It implements the design that resulted from the analysis of stereotypical users + +The menu is designed to put what our users most want right up front. Other, less +important information can be linked from subpages. + +2) It completely separates content, navigation and style + +This makes it easy to change the "skin" of the site or the style of that skin. + +3) The navigation "skin" is designed to be convenient in browsers that do not + process CSS. + +The banner appears first, then the main page content, followed by any side panels on +the page. Thus, users of less capable browsers get the most important information +first and less important information later. + +4) All content is simple HTML. + +No styles required, although any styles and other media used by the content pages +get merged into the final site by the templater. This makes it easy to create +content in WYSIWYG editors. diff --git a/xstream-distribution/pom.xml b/xstream-distribution/pom.xml new file mode 100644 index 0000000..cd64e6b --- /dev/null +++ b/xstream-distribution/pom.xml @@ -0,0 +1,225 @@ + + + 4.0.0 + + com.thoughtworks.xstream + xstream-parent + 1.4.8 + + xstream-distribution + pom + XStream Distribution + + Distribution project for XStream to build distributables and documentation. + + + + + com.thoughtworks.xstream + xstream + runtime + + + com.thoughtworks.xstream + xstream-hibernate + runtime + + + com.thoughtworks.xstream + xstream-benchmark + runtime + + + + + + jdk18-ge + + [1.8,) + + + + + org.codehaus.xsite + xsite-maven-plugin + + ${basedir}/src + content/website.xml + templates/skin.html + xsite/xsite.xml + resources + ${project.build.directory}/xsite + + + + package + + run + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + package + + run + + + + + + + + + + + + + + + + + + + + + + + + + + + com.thoughtworks.xstream + xstream + javadoc + + + com.thoughtworks.xstream + xstream-hibernate + javadoc + + + com.thoughtworks.xstream + xstream-benchmark + javadoc + + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + collect-xstream-artifacts + package + + copy-dependencies + + + target/libs + runtime + true + + + + unpack-core + package + + unpack-dependencies + + + ${project.build.directory}/xsite/javadoc + false + true + xstream + javadoc + provided + + + + unpack-hibernate + package + + unpack-dependencies + + + ${project.build.directory}/xsite/hibernate-javadoc + false + true + xstream-hibernate + javadoc + provided + + + + unpack-benchmark + package + + unpack-dependencies + + + ${project.build.directory}/xsite/benchmark-javadoc + false + true + xstream-benchmark + javadoc + provided + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + bin + package + + attached + + + + ${basedir}/src/assembly/assembly-bin.xml + + xstream-${project.version} + ${project.build.directory}/assembly/bin + + + + src + package + + attached + + + + ${basedir}/src/assembly/assembly-src.xml + + xstream-${project.version} + ${project.build.directory}/assembly/src + + + + + + + diff --git a/xstream-distribution/src/assembly/assembly-bin.xml b/xstream-distribution/src/assembly/assembly-bin.xml new file mode 100644 index 0000000..61c67e8 --- /dev/null +++ b/xstream-distribution/src/assembly/assembly-bin.xml @@ -0,0 +1,43 @@ + + + bin + + zip + + + + .. + / + + LICENSE.txt + README.txt + + + + target/docs + docs + + + target/libs + lib + + + ../xstream/target/dependencies + lib/xstream + + + ../xstream-hibernate/target/dependencies + lib/xstream-hibernate + + + \ No newline at end of file diff --git a/xstream-distribution/src/assembly/assembly-src.xml b/xstream-distribution/src/assembly/assembly-src.xml new file mode 100644 index 0000000..b843d6f --- /dev/null +++ b/xstream-distribution/src/assembly/assembly-src.xml @@ -0,0 +1,38 @@ + + + src + + zip + + + + .. + / + + xstream-builder/** + **/build/** + **/target/** + **/.*/** + **/.* + **/cobertura.ser + **/release.properties + **/surefire*.properties + **/*~ + **/*.bak + **/*.classpath + **/*.jps + **/*.releaseBackup + + + + diff --git a/xstream-distribution/src/content/alias-tutorial.html b/xstream-distribution/src/content/alias-tutorial.html new file mode 100644 index 0000000..0bc9440 --- /dev/null +++ b/xstream-distribution/src/content/alias-tutorial.html @@ -0,0 +1,343 @@ + + + + Alias Tutorial + + +

The problem

+

Suppose that our client has defined a base XML file that we should make XStream read/write:

+
<blog author="Guilherme Silveira">
+  <entry>
+    <title>first</title>
+    <description>My first blog entry.</description>
+  </entry>
+  <entry>
+    <title>tutorial</title>
+    <description>
+        Today we have developed a nice alias tutorial. Tell your friends! NOW!
+    </description>
+  </entry>
+</blog>
+ +

Based on the XML file above we shall create some model classes and configure XStream to write/read from this format.

+
+

The model

+

First things first, the classes which shall represent our xml files are shown next, beginning with a simple Blog:

+
package com.thoughtworks.xstream;
+
+public class Blog {
+        private Author writer;
+        private List entries = new ArrayList();
+
+        public Blog(Author writer) {
+                this.writer = writer;
+        }
+
+        public void add(Entry entry) {
+                entries.add(entry);
+        }
+
+        public List getContent() {
+                return entries;
+        }
+}
+

A basic author with name:

+
package com.thoughtworks.xstream;
+
+public class Author {
+        private String name;
+        public Author(String name) {
+                this.name = name;
+        }
+        public String getName() {
+                return name;
+        }
+}
+

A blog entry contains a title and description:

+
package com.thoughtworks.xstream;
+
+public class Entry {
+        private String title, description;
+        public Entry(String title, String description) {
+                this.title = title;
+                this.description = description;
+        }
+}
+

Although we did not create many getters/setters its up to you to create those you wish or those which make sense.

+
+

A simple test

+

We can easily instantiate a new blog and use it with xstream:

+
public static void main(String[] args) {
+
+        Blog teamBlog = new Blog(new Author("Guilherme Silveira"));
+        teamBlog.add(new Entry("first","My first blog entry."));
+        teamBlog.add(new Entry("tutorial",
+                "Today we have developed a nice alias tutorial. Tell your friends! NOW!"));
+
+        XStream xstream = new XStream();
+        System.out.println(xstream.toXML(teamBlog));
+
+}
+

And the resulting XML is not so nice as we would want it to be:

+
<com.thoughtworks.xstream.Blog>
+  <writer>
+    <name>Guilherme Silveira</name>
+  </writer>
+  <entries>
+    <com.thoughtworks.xstream.Entry>
+      <title>first</title>
+      <description>My first blog entry.</description>
+    </com.thoughtworks.xstream.Entry>
+    <com.thoughtworks.xstream.Entry>
+      <title>tutorial</title>
+      <description>
+        Today we have developed a nice alias tutorial. Tell your friends! NOW!
+      </description>
+    </com.thoughtworks.xstream.Entry>
+  </entries>
+</com.thoughtworks.xstream.Blog>
+
+

Class aliasing

+

The first thing we shall change is how XStream refers to the com.thoughtworks.xstream.Blog class. +We shall name it simply blog: let's create an alias called blog to the desired class:

+
xstream.alias("blog", Blog.class);
+

Using the same idea, we can alias the 'Entry' class to 'entry':

+
xstream.alias("entry", Entry.class);
+

The result now becomes:

+
<blog>
+  <writer>
+    <name>Guilherme Silveira</name>
+  </writer>
+  <entries>
+    <entry>
+      <title>first</title>
+      <description>My first blog entry.</description>
+    </entry>
+    <entry>
+      <title>tutorial</title>
+      <description>
+        Today we have developed a nice alias tutorial. Tell your friends! NOW!
+      </description>
+    </entry>
+  </entries>
+</blog>
+
+

Field aliasing

+

Next we will change the name of the writer tag, but this time we have to use a field alias:

+
xstream.aliasField("author", Blog.class, "writer");
+

The result now becomes:

+
<blog>
+  <author>
+    <name>Guilherme Silveira</name>
+  </author>
+  <entries>
+    <entry>
+      <title>first</title>
+      <description>My first blog entry.</description>
+    </entry>
+    <entry>
+      <title>tutorial</title>
+      <description>
+        Today we have developed a nice alias tutorial. Tell your friends! NOW!
+      </description>
+    </entry>
+  </entries>
+</blog>
+
+

Implicit Collections

+

Now let's implement what was called an implicit collection: whenever you have a collection which doesn't need +to display it's root tag, you can map it as an implicit collection.

+

In our example, we do not want to display the entries tag, but simply show the entry tags one after +another.

+

A simple call to the addImplicitCollection method shall configure XStream and let it know that we do not want to +write the entries tag as described above:

+
package com.thoughtworks.xstream;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Test {
+
+        public static void main(String[] args) {
+
+                Blog teamBlog = new Blog(new Author("Guilherme Silveira"));
+                teamBlog.add(new Entry("first","My first blog entry."));
+                teamBlog.add(new Entry("tutorial",
+                        "Today we have developed a nice alias tutorial. Tell your friends! NOW!"));
+
+                XStream xstream = new XStream();
+                xstream.alias("blog", Blog.class);
+                xstream.alias("entry", Entry.class);
+
+                xstream.addImplicitCollection(Blog.class, "entries");
+
+                System.out.println(xstream.toXML(teamBlog));
+
+        }
+}
+

Pay attention to the addImplicitCollection method call: it describes which class and which member variable +shall assume the behaviour we described.

+

The result is almost what we wanted:

+
<blog>
+  <author>
+    <name>Guilherme Silveira</name>
+  </author>
+  <entry>
+    <title>first</title>
+    <description>My first blog entry.</description>
+  </entry>
+  <entry>
+    <title>tutorial</title>
+    <description>
+        Today we have developed a nice alias tutorial. Tell your friends! NOW!
+    </description>
+  </entry>
+</blog>
+

Just as a side note: An array or a map can also be declared as implicit.

+
+

Attribute aliasing

+

The next step is to set the writer member variable as an XML attribute. In order to do this, we shall tell +XStream to alias the writer field of the Blog class as an "author" attribute:

+
                xstream.useAttributeFor(Blog.class, "writer");
+                xstream.aliasField("author", Blog.class, "writer");
+

And now it leaves us with one problem: how does XStream converts an Author in a String so it can be written as a +XML tag attribute?

+

Attributes cannot be written for types that are handled by Converter implementations, we have to use a +SingleValueConverter and implement our own converter for the Author:

+
class AuthorConverter implements SingleValueConverter {
+}
+

The first method to implement tells XStream which types it can deal with:

+
        public boolean canConvert(Class type) {
+                return type.equals(Author.class);
+        }
+

The second one is used to extract a String from an Author:

+
        public String toString(Object obj) {
+                return ((Author) obj).getName();
+        }
+

And the third one does the opposite job: takes a String and returns an Author:

+
        public Object fromString(String name) {
+                return new Author(name);
+        }
+

Finally, the entire single value converter, responsible for converting Strings to Objects (Authors in this case) is:

+
class AuthorConverter implements SingleValueConverter {
+
+        public String toString(Object obj) {
+                return ((Author) obj).getName();
+        }
+
+        public Object fromString(String name) {
+                return new Author(name);
+        }
+
+        public boolean canConvert(Class type) {
+                return type.equals(Author.class);
+        }
+
+}
+

And let's register this converter:

+
public class Test {
+
+        public static void main(String[] args) {
+
+                Blog teamBlog = new Blog(new Author("Guilherme Silveira"));
+                teamBlog.add(new Entry("first","My first blog entry."));
+                teamBlog.add(new Entry("tutorial",
+                        "Today we have developed a nice alias tutorial. Tell your friends! NOW!"));
+
+                XStream xstream = new XStream();
+                xstream.alias("blog", Blog.class);
+                xstream.alias("entry", Entry.class);
+
+                xstream.addImplicitCollection(Blog.class, "entries");
+
+                xstream.useAttributeFor(Blog.class, "author");
+                xstream.registerConverter(new AuthorConverter());
+
+                System.out.println(xstream.toXML(teamBlog));
+
+        }
+}
+

The result?

+
<blog author="Guilherme Silveira">
+  <entry>
+    <title>first</title>
+    <description>My first blog entry.</description>
+  </entry>
+  <entry>
+    <title>tutorial</title>
+    <description>
+        Today we have developed a nice alias tutorial. Tell your friends! NOW!
+    </description>
+  </entry>
+</blog>
+
+ +

You have to be aware, that attribute values normally have to be normalized by the XML parser as +required by the W3C spec. Leading and trailing whitespaces +are normally removed as well as sequential ones! Therefore a deserialized string might differ from the value visible in +the XML representation.

+ +
+

Package aliasing

+ +

In the example above we have so far always used class aliases for the Blog and Entry type. Sometimes it is necessary to +map existing class types to others simply by changing the package name. Let us go back to the first attempt of our tutorial, +but this time we alias the package name instead of the individual classes:

+
public static void main(String[] args) {
+
+        Blog teamBlog = new Blog(new Author("Guilherme Silveira"));
+        teamBlog.add(new Entry("first","My first blog entry."));
+        teamBlog.add(new Entry("tutorial",
+                "Today we have developed a nice alias tutorial. Tell your friends! NOW!"));
+
+        XStream xstream = new XStream();
+        xstream.aliasPackage("my.company", "org.thoughtworks");
+        System.out.println(xstream.toXML(teamBlog));
+
+}
+

And the resulting XML contains now the classes with the aliased package names:

+
<my.company.xstream.Blog>
+  <author>
+    <name>Guilherme Silveira</name>
+  </author>
+  <entries>
+    <my.company.xstream.Entry>
+      <title>first</title>
+      <description>My first blog entry.</description>
+    </my.company.xstream.Entry>
+    <my.company.xstream.Entry>
+      <title>tutorial</title>
+      <description>
+        Today we have developed a nice alias tutorial. Tell your friends! NOW!
+      </description>
+    </my.company.xstream.Entry>
+  </entries>
+</my.company.xstream.Blog>
+

Please recognize that the package name alias works also for sub packages in this example.

+
+ +
+

Summing up

+

To recap:

+
    +
  • You can use class aliases to change tag names
  • +
  • You can use field aliases to change tag names
  • +
  • You can use package aliases to change tag names
  • +
  • Fields can be written as attributes if the field type is handled by a SingleValueConverter
  • +
+

Don't forget to read the converter tutorial to see other type of converters that you can create using XStream. +Or look into the condensed overview how to configure XStream to tweak the output.

+
+ + + diff --git a/xstream-distribution/src/content/annotations-tutorial.html b/xstream-distribution/src/content/annotations-tutorial.html new file mode 100644 index 0000000..e71cc46 --- /dev/null +++ b/xstream-distribution/src/content/annotations-tutorial.html @@ -0,0 +1,532 @@ + + + + Annotations Tutorial + + + + +

Motivation

+

Sometimes it can get tedious to call all those XStream aliases/register converter methods or you might simply like +the new trend on configuring POJOs: Java annotations.

+

This tutorial will show you how to use some of the annotations provided by XStream in order to make configuration +easier. Let's start with a custom Message class:

+
package com.thoughtworks.xstream;
+package com.thoughtworks.xstream;
+public class RendezvousMessage {
+
+	private int messageType;
+	
+	public RendezvousMessage(int messageType) {
+		this.messageType = messageType;
+	}
+	
+}
+

Let's code the XStream calls which generate the XML file:

+
+package com.thoughtworks.xstream;
+public class Tutorial {
+
+	public static void main(String[] args) {
+		XStream stream = new XStream();
+		RendezvousMessage msg = new RendezvousMessage(15);
+		System.out.println(stream.toXML(msg));
+	}
+
+}
+
+

Results in the following XML:

+
+<com.thoughtworks.xstream.RendezvousMessage>
+  <messageType>15</messageType>
+</com.thoughtworks.xstream.RendezvousMessage>
+
+ + +

Aliasing Annotation

+

The most basic annotation is the one responsible for type and field aliasing: @XStreamAlias. Let's annotate both +our type and field and run the tutorial method again:

+
+@XStreamAlias("message")
+class RendezvousMessage {
+
+	@XStreamAlias("type")
+	private int messageType;
+	
+	public RendezvousMessage(int messageType) {
+		this.messageType = messageType;
+	}
+	
+}
+
+

In some strange way, the result is the same. What happened here? XStream does not read this annotation by default +as it would be impossible to deserialize the XML code. Therefore we need to tell XStream to read the annotations from +this type:

+
+	public static void main(String[] args) {
+		XStream stream = new XStream();
+		xstream.processAnnotations(RendezvousMessage.class);
+		RendezvousMessage msg = new RendezvousMessage(15);
+		System.out.println(stream.toXML(msg));
+	}
+
+

Note that we have called the processAnnotations method of XStream. This method registers all aliases annotations in +the XStream instance passed as first argument. You may also use the overloaded version of this method taking an array +of types. The resulting XML is now what we have expected:

+
+<message>
+  <type>15</type>
+</message>
+
+

If you let XStream process the annotations of a type, it will also process all annotations of the related types i.e. +all super types, implemented interfaces, the class types of the members and all their generic types.

+ + +

Implicit Collections

+

Let's add a List of content to our RendezvousMessage. We desire the same functionality obtained with implicit +collections:

+
+@XStreamAlias("message")
+class RendezvousMessage {
+
+	@XStreamAlias("type")
+	private int messageType;        
+	
+	private List<String> content;
+	
+	public RendezvousMessage(int messageType, String ... content) {
+		this.messageType = messageType;
+		this.content = Arrays.asList(content);
+	}
+	
+}
+
+
+	public static void main(String[] args) {
+		XStream stream = new XStream();
+		xstream.processAnnotations(RendezvousMessage.class);
+		RendezvousMessage msg = new RendezvousMessage(15, "firstPart","secondPart");
+		System.out.println(stream.toXML(msg));
+	}
+
+

The resulting XML shows the collection name before its elements:

+
+<message>
+  <type>15</type>
+  <content class="java.util.Arrays$ArrayList">
+    <a class="string-array">
+      <string>firstPart</string>
+      <string>secondPart</string>
+    </a>
+  </content>
+</message>
+
+

This is not what we desire therefore we will annotate the content list to be recognized as an implicit collection:

+
+@XStreamAlias("message")
+class RendezvousMessage {
+
+	@XStreamAlias("type")
+	private int messageType;
+
+	@XStreamImplicit
+	private List<String> content;
+
+	public RendezvousMessage(int messageType, String... content) {
+		this.messageType = messageType;
+		this.content = Arrays.asList(content);
+	}
+
+}
+
+

Resulting in an XML which ignores the field name (content) of the list:

+
+<message>
+  <type>15</type>
+  <a class="string-array">
+    <string>firstPart</string>
+    <string>secondPart</string>
+  </a>
+</message>
+
+

We are almost there... we still want to remove the 'a' tag, and define each content part with the tag 'part'. In +order to do so, let's add another attribute to our implicit collection annotation. The attribute field defines the +name of the tag used for data contained inside this collection:

+
+@XStreamAlias("message")
+class RendezvousMessage {
+
+	@XStreamAlias("type")
+	private int messageType;
+
+	@XStreamImplicit(itemFieldName="part")
+	private List<String> content;
+
+	public RendezvousMessage(int messageType, String... content) {
+		this.messageType = messageType;
+		this.content = Arrays.asList(content);
+	}
+
+}
+
+

Resulting in a cleaner XML:

+
+<message>
+  <type>15</type>
+  <part>firstPart</part>
+  <part>secondPart</part>
+</message>
+
+ +

The implicit annotation can also be used for arrays and maps. In the latter case you should provide the field name +of the values that are used as key of the map.

+ + +

Local Converters

+

Let's create another attribute which defines the timestamp when the message was created and one to flag special +importance of the message:

+
+@XStreamAlias("message")
+class RendezvousMessage {
+
+	@XStreamAlias("type")
+	private int messageType;
+
+	@XStreamImplicit(itemFieldName="part")
+	private List<String> content;
+	
+	private boolean important;
+	
+	private Calendar created = new GregorianCalendar();
+
+	public RendezvousMessage(int messageType, boolean important, String... content) {
+		this.messageType = messageType;
+		this.important = important;
+		this.content = Arrays.asList(content);
+	}
+
+}
+
+

Resulting in the following xml:

+
+<message>
+  <type>15</type>
+  <part>firstPart</part>
+  <part>secondPart</part>
+  <important>false</important>
+  <created>
+    <time>1154097812245</time>
+    <timezone>America/Sao_Paulo</timezone>
+  </created>
+</message>
+
+

Now we face the following problem: We want to use a custom converter locally for this Calendar, but only for this +Calendar, this exact field in this exact type. Easy... let's annotate it with the custom converter annotation:

+
+@XStreamAlias("message")
+class RendezvousMessage {
+
+	@XStreamAlias("type")
+	private int messageType;
+
+	@XStreamImplicit(itemFieldName="part")
+	private List<String> content;
+	
+	private boolean important;
+
+	@XStreamConverter(SingleValueCalendarConverter.class)
+	private Calendar created = new GregorianCalendar();
+
+	public RendezvousMessage(int messageType, String... content) {
+		this.messageType = messageType;
+		this.content = Arrays.asList(content);
+	}
+
+}
+
+

Let's create the custom converter:

+
+public class SingleValueCalendarConverter implements Converter {
+
+    public void marshal(Object source, HierarchicalStreamWriter writer,
+            MarshallingContext context) {
+        Calendar calendar = (Calendar) source;
+        writer.setValue(String.valueOf(calendar.getTime().getTime()));
+    }
+
+    public Object unmarshal(HierarchicalStreamReader reader,
+            UnmarshallingContext context) {
+        GregorianCalendar calendar = new GregorianCalendar();
+        calendar.setTime(new Date(Long.parseLong(reader.getValue())));
+        return calendar;
+    }
+
+    public boolean canConvert(Class type) {
+        return type.equals(GregorianCalendar.class);
+    }
+}
+
+

And we end up with the converter being used and generating the following XML:

+
+<message>
+  <type>15</type>
+  <part>firstPart</part>
+  <part>secondPart</part>
+  <important>false</important>
+  <created>1154097812245</created>
+</message>
+
+ +

Additionally we want to format the importance flag not with a technical true or false, but with a +natural yes or no. Fortunately the BooleanConverter supports alternate format styles, but how can we +use an annotation to register a new instance locally? The XStreamConverter annotation uses some lightweight dependency +injection mechanism to match given arguments with the parameters of available constructors. That way we can write now:

+
+@XStreamAlias("message")
+class RendezvousMessage {
+
+	@XStreamAlias("type")
+	private int messageType;
+
+	@XStreamImplicit(itemFieldName="part")
+	private List<String> content;
+	
+	@XStreamConverter(value=BooleanConverter.class, booleans={false}, strings={"yes", "no"})
+	private boolean important;
+	
+	@XStreamConverter(SingleValueCalendarConverter.class)
+	private Calendar created = new GregorianCalendar();
+
+	public RendezvousMessage(int messageType, boolean important, String... content) {
+		this.messageType = messageType;
+		this.important = important;
+		this.content = Arrays.asList(content);
+	}
+
+}
+
+ +

The BooleanConverter has an additional constructor with two string values expressing true and +false and a third argument to ignore case of these values. Therefore we have added all 3 arguments to the +annotation. The sequence of the arguments is only important for same types. As result we have now:

+
+<message>
+  <type>15</type>
+  <part>firstPart</part>
+  <part>secondPart</part>
+  <important>no</important>
+  <created>1154097812245</created>
+</message>
+
+ +

See the Javadoc of the XStreamConverter annotation what more arguments are provided implicitly.

+ + +

Attributes

+

The client may asks for the type tag and the importance flag to be an attribute inside the message tag, as follows:

+
+<message type="15" important="no">
+  <part>firstPart</part>
+  <part>secondPart</part>
+  <created>1154097812245</created>
+</message>
+
+

All you need to do is add the @XStreamAsAttribute annotation:

+
+@XStreamAlias("message")
+class RendezvousMessage {
+
+	@XStreamAlias("type")
+   	@XStreamAsAttribute
+	private int messageType;
+
+	@XStreamImplicit(itemFieldName="part")
+	private List<String> content;
+	
+   	@XStreamAsAttribute
+	@XStreamConverter(value=BooleanConverter.class, booleans={false}, strings={"yes", "no"})
+	private boolean important;
+
+	@XStreamConverter(SingleValueCalendarConverter.class)
+	private Calendar created = new GregorianCalendar();
+
+	public RendezvousMessage(int messageType, boolean important, String... content) {
+		this.messageType = messageType;
+		this.important = important;
+		this.content = Arrays.asList(content);
+	}
+}
+
+ + +

Field as Text Value

+ +

Sometimes it is desirable to use a single field as text value for a XML element and all other fields should be +written as attributes. XStream delivers the ToAttributedValueConverter, that will write a type with this form:

+
+@XStreamAlias("message")
+@XStreamConverter(value=ToAttributedValueConverter.class, strings={"content"})
+class RendezvousMessage {
+
+	@XStreamAlias("type")
+	private int messageType;
+
+	private List<String> content;
+	
+	@XStreamConverter(value=BooleanConverter.class, booleans={false}, strings={"yes", "no"})
+	private boolean important;
+
+	@XStreamConverter(SingleValueCalendarConverter.class)
+	private Calendar created = new GregorianCalendar();
+
+	public RendezvousMessage(int messageType, boolean important, String... content) {
+		this.messageType = messageType;
+		this.important = important;
+		this.content = Arrays.asList(content);
+	}
+}
+
+ +

Unfortunately our little example does not work! Although we register the converter with the +XStreamConverter annotation and provide with its arguments the field name, the conversion will fail later on. To use +this converter you have to respect the implicit requirement: Any field (derived or not) has to be expressed as a +single string i.e. technically XStream has to use a SingleValueConverter. In our case we have a list of strings that +prevent the conversion. Therefore we have to use either a custom converter that transforms this list into a single +string or we use for simplicity a simple string here:

+
+@XStreamAlias("message")
+@XStreamConverter(value=ToAttributedValueConverter.class, strings={"content"})
+class RendezvousMessage {
+
+	@XStreamAlias("type")
+	private int messageType;
+
+	private String content;
+	
+	@XStreamConverter(value=BooleanConverter.class, booleans={false}, strings={"yes", "no"})
+	private boolean important;
+
+	@XStreamConverter(SingleValueCalendarConverter.class)
+	private Calendar created = new GregorianCalendar();
+
+	public RendezvousMessage(int messageType, boolean important, String content) {
+		this.messageType = messageType;
+		this.important = important;
+		this.content = content;
+	}
+}
+
+ +

Now it is possible to generate this XML:

+
+<message type="15" important="no" created="1154097812245">This is the message content.</message>
+
+ +

Note, that no XStreamAsAttribute annotations were necessary. The converter assumes it implicitly.

+ + +

Omitting Fields

+

Sometimes a class may contain elements that should not be part of the resulting XML. In our case we may now drop +the 'messageType', since we are only interested at the content. This is easy using the @XStreamOmitField annotation:

+
+@XStreamAlias("message")
+class RendezvousMessage {
+
+   	@XStreamOmitField
+	private int messageType;
+
+	@XStreamImplicit(itemFieldName="part")
+	private List<String> content;
+
+	@XStreamConverter(value=BooleanConverter.class, booleans={false}, strings={"yes", "no"})
+	private boolean important;
+
+	@XStreamConverter(SingleValueCalendarConverter.class)
+	private Calendar created = new GregorianCalendar();
+
+	public RendezvousMessage(int messageType, boolean important, String... content) {
+		this.messageType = messageType;
+		this.important = important;
+		this.content = Arrays.asList(content);
+	}
+}
+
+

The resulting XML does not contain the type of the message anymore:

+
+<message>
+  <part>firstPart</part>
+  <part>secondPart</part>
+  <important>no</important>
+  <created>1154097812245</created>
+</message>
+
+ + +

Auto-detect Annotations

+

Until now we have always told you, that you have to call processAnnotation to configure the XStream instance with +the present annotations in the different classes. However, this is only half the truth. You can run XStream also in a +lazy mode, where it auto-detects the annotations while processing the object graph and configure the XStream instance +on-the-fly:

+
+package com.thoughtworks.xstream;
+public class Tutorial {
+
+	public static void main(String[] args) {
+		XStream stream = new XStream();
+		xstream.autodetectAnnotations(true);
+		RendezvousMessage msg = new RendezvousMessage(15);
+		System.out.println(stream.toXML(msg));
+	}
+
+}
+
+

The resulting XML will look as expected! Nevertheless you have to understand the implications, therefore some words +of warning:

+
    +
  1. Chicken-and-egg problem +

    An XStream instance caches all class types processed for annotations. Every time XStream converts an object it will +in auto-detection mode first process the object's type and all the types related (as explained +above). Therefore it is no problem to serialize an object graph into XML, since XStream will +know of all types in advance. This is no longer true at deserialization time. XStream has to know the alias to turn +it into the proper type, but it can find the annotation for the alias only if it has processed the type in advance. +Therefore deserialization will fail if the type has not already been processed either by having called XStream's +processAnnotations method or by already having serialized this type. However, @XStreamAlias is the only annotation +that may fail in this case.

  2. +
  3. Concurrency +

    XStream is not thread-safe while it is configured, thread-safety is only guaranteed during marshalling and +unmarshalling. Unfortunately an annotation is defining a change in configuration that is now applied while object +marshalling is processed. Therefore will the auto-detection mode turn XStream's marshalling process in a thread-unsafe +operation. While XStream synchronizes the configuration modification, it cannot guard concurrent reads and you may run +under certain circumstances into concurrency problems. If you abolutely have to rely on annotation processing on the +fly, you will have to use separate XStream instances for each thread - either by using everytime a new instance or by a +shared pool.

  4. +
  5. Exceptions +

    XStream uses a well-defined exception hierarchy. Normally an InitializationException is only thrown while XStream +is configured. If annotations are processed on the fly they can be thrown obviously also in a marshalling process.

  6. +
  7. Performance +

    In auto-detection mode XStream will have to examine any unknown class type for annotations. This will slow down the +marshalling process until all processed types have been examined once.

  8. +
+

Please note, that any call to XStream.processAnnotations will turn off the auto-detection mode.

+ + +

Summing up

+

The XStream annotations support might help you configuring your class mappings in some ways, as the custom +configuration will appear in your types, but might not be the solution for other problems, i.e. when you need to map +the same type to two different XML 'standards'. Others might claim that the configuration should be clearly stated in +a Java class and not mixed with your model, its up to you to pick the best approach in your case: Annotations or +direct method calls to the XStream instance. Annotations do not provide more functionality, but may improve +convenience.

+ + + diff --git a/xstream-distribution/src/content/architecture.html b/xstream-distribution/src/content/architecture.html new file mode 100644 index 0000000..bdf8b68 --- /dev/null +++ b/xstream-distribution/src/content/architecture.html @@ -0,0 +1,136 @@ + + + + Architecture Overview + + + +

The architecture of XStream consists of the four main components:

+ +
    +
  • Converters
  • + +
  • Drivers (Writer and Reader)
  • +
  • Context
  • +
  • Facade
  • +
+ + + +

Converters

+ +

Whenever XStream encounters an object that needs to be converted to/from XML, it delegates to a suitable + Converter implementation associated + with the class of that Object.

+ +

XStream comes bundled with many converters for common types, including primitives, + String, Collections, arrays, null, Date, etc.

+ +

XStream also has a default Converter, that is used when no other Converters match a type. This uses + reflection to automatically generate the XML for all the fields in an object.

+ +

If an object is composed of other objects, the Converter may delegate to other Converters.

+ +

To customize the XML for particular object type a new Converter should be implemented.

+ + + + +

Drivers (Writer and Reader)

+ +

XStream is abstracted from the underlying XML data using the + HierarchicalStreamWriter + and HierarchicalStreamReader + interfaces for serializing and deserializing respectively.

+ +

This abstraction allows XStream to read XML from direct streams using an XML parser or directly manipulate + existing structures (such as DOM). This prevents the overhead of having to reparse if XStream is working from + XML that has been partially processed by other libraries (for instance a SOAP library). It also avoids tying XStream + to a particular library.

+ +

XStream comes bundled with + reader and writer implementations for + most major XML libraries.

+ +

Writer and Readers can be implemented allowing XStream to serialize to most XML APIs. + Writers and Readers can also be created around tree based non XML structures.

+ + + + + +

Context

+ +

When XStream serializes or deserializes some objects, it creates a + MarshallingContext or + UnmarshallingContext, + which handle the traversing of the data and delegation to the necessary Converters.

+ +

The MarshallingContext/UnmarshallingContext is made available to converters allowing them + to tell XStream to process objects contained within other objects.

+ +

XStream provides three pairs of context implementations that traverse the object graph with slightly + different behaviors. The default can be changed using + XStream.setMode(), passing in one of + the following parameters:

+ +
    +
  • + XStream.XPATH_RELATIVE_REFERENCES
    + (Default) Uses relative XPath references to signify duplicate references. This produces XML with + the least clutter. +
  • +
  • + XStream.XPATH_ABSOLUTE_REFERENCES
    + Uses absolute XPath references to signify duplicate references. This might produce for some situations + better readable XML. Note, that XStream will read XML with relative paths as well as with absolute + paths independent of the XPATH mode. +
  • +
  • + XStream.ID_REFERENCES
    + Uses ID references to signify duplicate references. In some scenarios, such as when using hand-written + XML, this is easier to work with. +
  • +
  • + XStream.NO_REFERENCES
    + This disables object graph support and treats the object structure like a tree. Duplicate references are + treated as two separate objects and circular references cause an exception. This is slightly faster and + uses less memory than the other two modes. +
  • +
+ +

A new context is created for each object graph that is serialized. Both the + MarshallingContext and + UnmarshallingContext + implement DataHolder, + a hash table passed around whilst processing the object graph that can be used as the user sees fit (in a similar + way that the HttpServletRequest attributes are used in a web-application).

+ + + + +

XStream facade

+ +

The main XStream class is typically used as the + entry point. This assembles the necessary components of XStream (as described above; Context, Converter, + Writer/Reader and ClassMapper) and provides a simple to use API for common operations.

+ +

Remember, the XStream class is just a facade - it can always be bypassed for more advanced + operations.

+ + + + \ No newline at end of file diff --git a/xstream-distribution/src/content/changes.html b/xstream-distribution/src/content/changes.html new file mode 100644 index 0000000..a45992c --- /dev/null +++ b/xstream-distribution/src/content/changes.html @@ -0,0 +1,1323 @@ + + + + Change History + + + +

Changes are split into three categories:

+ +
    +
  • Major changes: The major new features that all users should know about.
  • +
  • Minor changes: Any smaller changes, including bugfixes.
  • +
  • API changes: Any changes to the API that could impact existing users.
  • +
+ +

Full details can be found in Jira's + Roadmap and + Change Log. +

+ +

1.4.8

+ +

Released February 18, 2015.

+ +

Major changes

+ +
    +
  • Support for serializable lambda expressions and handling of non-serializable ones.
  • +
+ +

Minor changes

+ +
    +
  • Detect Java 9 runtime.
  • +
  • XSTR-767: Deserialization of referenced lambda expressions fail.
  • +
  • XSTR-762: Private method readResolve() called on base classes.
  • +
  • XSTR-761: Support ignored serialPersistentField at deserialization time.
  • +
  • XSTR-755: ExternalizableConverter does not respect writeReplace and readResolve.
  • +
  • XSTR-757: Deserialized TreeSet does not honor remove(Object) return value contract.
  • +
  • XSTR-759: Support deserialization of W3C datetime format + in DateConverter with Java 7 runtime.
  • +
  • Fix: DateConverter ignores provided locale.
  • +
  • XSTR-768: ISO8601GregorianCalendarConverter may set invalid time zone for Joda-Time.
  • +
  • Fix: WeakCache.entrySet().iterator().next.setValue(value) returns the reference instead of the old value.
  • +
  • Fix: SqlTimestampConverter throws IllegalArgumentException instead of ConversionException on fromString().
  • +
  • Fix: CGLIBEnhancedConverter does not initialize transient members of parent after deserialization.
  • +
  • XSTR-763: Set scope of org.json:json to test instead declaring the dependency as optional.
  • +
+ +

API changes

+ +
    +
  • Added c.t.x.util.JVM.is19().
  • +
  • Added c.t.x.converter.reflection.LambdaConverter and c.t.x.mapper.LambdaMapper.
  • +
  • Declare c.t.x.XStream.ignoreUnknownElements(Pattern) as public.
  • +
  • c.t.x.converters.reflection.AbstractReflectionConverter.readResolve() is protected now.
  • +
  • c.t.x.mapper.AbstractAttributeAliasingMapper.readResolve() is protected now.
  • +
  • Deprecated c.t.x.converters.extended.StackTraceElementFactory, it is an internal helper class.
  • +
  • Deprecated c.t.x.converters.reflection.SerializationMethodInvoker, it is an internal helper class.
  • +
  • Deprecated c.t.x.io.AttributeNameIterator, it is an internal helper class.
  • +
  • Deprecated c.t.x.XStream.useXStream11XmlFriendlyMapper(), corresponding + c.t.x.mapper.XStream11XmlFriendlyMapper has been deprecated long ago.
  • +
  • Deprecated c.t.x.converter.basic.BooleanConverter.shouldConvert(Class,Object), undetected remainder of + ancient XStream version.
  • +
+ +

1.4.7

+ +

Released February 8, 2014.

+ +

This maintenance release addresses mainly the security vulnerability CVE-2013-7285, an + arbitrary execution of commands when unmarshalling.

+ +

Major changes

+ +
    +
  • Add security framework to limit handled types while unmarshalling.
  • +
  • java.bean.EventHandler no longer handled automatically because of severe security vulnerability.
  • +
  • JIRA:XSTR-751: New SunLimitedUnsafeReflectionProvider that uses undocumented features only to allocate new + instances as required on Dalvik.
  • +
  • Fix instantiation of AnnotationMapper that requires ConverterLookup and ConverterRegistry to be the same + instance.
  • +
+ +

Minor changes

+ +
    +
  • XSTR-749: NPE if ReflectionConverter.canConvert(type) is called with null as argument.
  • +
  • XSTR-753: NPE if SerializationConverter.canConvert(type) is called with an interface type as argument that + extends Serializable.
  • +
  • Add constructor to ReflectionConverter taking an additional type to create an instance that is + dedicated to a specific type only.
  • +
  • The ConverterLookup used by default cannot be casted to a ConverterRegistry anymore.
  • +
+ +

API changes

+ +
    +
  • Added package c.t.x.security with interface TypePermission, all its implementations and + ForbiddenClassException.
  • +
  • Added c.t.x.mapper.SecurityMapper handling the new type permissions.
  • +
  • Added methods addPermission, denyPermission, allowTypesXXX and denyTypesXXX to c.t.x.XStream to setup + security at unmarshalling time.
  • +
  • Added c.t.x.converters.reflection.SunLimitedUnsafeReflectionProvider.
  • +
  • Deprecated c.t.x.converters.reflection.Sun14ReflectionProvider in favor of new + c.t.x.converters.reflection.SunUnsafeReflectionProvider.
  • +
  • Added c.t.x.converters.reflection.ReflectionConverter(Mapper,ReflectionProvider,Class).
  • +
+ +

1.4.6

+ +

Released December 12, 2013.

+ +

Major changes

+ +
    +
  • JIRA:XSTR-566 and JIRA:XSTR-200: Better compatibility with GAE and environments with active SecurityManager (i.e. in an + Applet). XStream converters try now to ensure already in the canConvert methods that they can handle the requested type in + practice and not only theoretically. Additionally the implementations even better take care, that the initialization of a + converter will not break the setup of XStream itself. Following modifications have been done for these topics: +
      +
    • ReflectionConverter, SerializationConverter and LookAndFieldConverter will check if they can access the fields by + reflection for a requested type.
    • +
    • SerializationConverter and ExternalizableConverter will check if they can create an instance of a derived + OutputObjectStream first.
    • +
    • BeanProvider does no longer use reflection to locate default constructor.
    • +
    • AbstractAttributedCharacterIteratorAttributeConverter (and therefore TextAttributeConverter) will check first if it + can access the possible constants of the type by reflection.
    • +
    • NoClassDefFoundError raised in GAE accessing the fields of restricted types by reflection will be handled.
    • +
    • StackTraceElementConverter uses constructor for StackTraceElement instances in Java 5 and GEA.
    • +
    +
  • +
  • JIRA:XSTR-739 and JIRA:XSTR-746: OrderRetainingMap fails if HashMap.putAll(Map) of Java Runtime is not + implemented calling put for every element within the map.
  • +
  • New NamedArrayConverter to define names of inner elements.
  • +
+ +

Minor changes

+ +
    +
  • JIRA:XSTR-747: All constructors of StaxDriver derived classes take erroneously a XmlFriendlyNameCoder + instead of a plain NameCoder.
  • +
+ +

API changes

+ +
    +
  • Added c.t.x.converters.extended.NamedArrayConverter for free element names in arrays.
  • +
  • Added constructors to c.t.x.io.xml.StandardStaxDriver taking NameCoder instead of XmlFriendlyNameCoder.
  • +
  • Deprecated constructors of c.t.x.io.xml.StandardStaxDriver taking a XmlFriendlyNameCoder.
  • +
  • Added constructors to c.t.x.io.xml.BEAStaxDriver taking NameCoder instead of XmlFriendlyNameCoder.
  • +
  • Deprecated constructors of c.t.x.io.xml.BEAStaxDriver taking a XmlFriendlyNameCoder.
  • +
  • Added constructors to c.t.x.io.xml.WstxDriver taking NameCoder instead of XmlFriendlyNameCoder.
  • +
  • Deprecated constructors of c.t.x.io.xml.WstxDriver taking a XmlFriendlyNameCoder.
  • +
  • Added method canAccess to c.t.x.converter.reflection.AbstractReflectionConverter.
  • +
  • Added static method canCreateDerivedObjectOutputStream to c.t.x.core.JVM.
  • +
  • Deprecated unused member c.t.x.converter.javabean.BeanProvider.NO_PARAMS.
  • +
  • Deprecated unused method c.t.x.converter.javabean.BeanProvider.getDefaultConstrutor(Class).
  • +
+ + +

1.4.5

+ +

Released September 18, 2013.

+ +

Major changes

+ +
    +
  • JIRA:XSTR-732: Use a referencing implementation for the ClassLoader to support environments where no new + ClassLoader can be instantiated due to security restrictions.
  • +
  • JIRA:XSTR-691: Allow unknown XML elements to be ignored using new method XStream.ignoreUnknownElements.
  • +
  • JIRA:XSTR-728: XStream creates invalid JSON with JsonHierarchicalStreamDriver for custom converters since + XStream 1.4.
  • +
  • JIRA:XSTR-300: New EnumToStringConverter to support custom string representations of Enum values.
  • +
  • JIRA:XSTR-292 and JIRA:XSTR-405: New NamedMapConverter and NamedCollectionConverter to define names of + inner elements.
  • +
  • JIRA:XSTR-726: New annotation XStreamAliasType to support declarative definition of XStream.aliasType().
  • +
  • JIRA:XSTR-735: Support for JDOM2 with JDom2Driver, JDom2Reader and JDom2Writer.
  • +
  • Optimized XML structure for java.awt.Font.
  • +
  • Fix: ToAttributedValueConverter silently appends fields without attribute support to the value producing mixed-mode XML.
  • +
  • JIRA:XSTR-566 and JIRA:XSTR-249: Better compatibility with Google AppEngine and J2ME, setup no longer fails for unavailable converters.
  • +
+ +

Minor changes

+ +
    +
  • Fix missing manifest information.
  • +
  • JIRA:XSTR-729: Add OSGi information to manifests.
  • +
  • JIRA:XSTR-723: XStream will now detect a working enhanced mode dynamically instead using lists of known + vendors. This allows enhanced support for JamVM if it is bundled with OpenJDK. It will currently fail on a + runtime based on GNU Classpath (at least up to version 0.98).
  • +
  • JIRA:XSTR-541: JavaScript compatibility problem with 64-bit integers in JSON.
  • +
  • JIRA:XSTR-719: Support replacement of default converter in any case.
  • +
  • JIRA:XSTR-725: processAnnotation performance improvement in concurrent situation.
  • +
  • JIRA:XSTR-721: EnumConverter is more lenient while parsing constants.
  • +
  • New constructors for CollectionConverter and MapConverter to allow registration for an individual type.
  • +
  • JIRA:XSTR-724: Cache class name lookup failures.
  • +
  • Current IBM JDK for Java 1.4.2 no longer has a reverse field ordering.
  • +
  • LongConverter supports now positive hex and octal numbers over Long.MAX_VALUE within 64 bit.
  • +
  • Fix: Sun14RefectionProvider ignores a provided FieldDictionary.
  • +
  • JIRA:XSTR-457: Do not write 'defined-in' attribute it not needed.
  • +
  • JettisonMappedXmlDriver provides better support to overwrite its create methods.
  • +
  • JIRA:XSTR-685: StAX based drivers (StaxDriver and JettisonMappedXmlDriver) are not closing internal input + stream reading from file or URL.
  • +
  • JIRA:XSTR-736: XStream.unmarshal may throw NPE if version info of manifest is missing.
  • +
  • JIRA:XSTR-733: Implicit elements that match multiple defined implicit collections will be assigned to the + map with the nearest matching element type.
  • +
  • JIRA:XSTR-740: ISO8601GregorianCalendarConverter creates Calendar instance with wrong Locale in Java 7 if + the Locale for the LocaleCategory.FORMAT is different to the global default Locale.
  • +
  • JIRA:XSTR-578: Implement support for aliasing in JavaClasConverter, JavaFieldConverter and + JavaMethodConverter. While it is not possible to enable this in general, new constructors have been added to + these converters and an example in the acceptance tests (AliasTest).
  • +
  • JIRA:XSTR-742: Register CompositeClassLoader in Java 7 as parallel capable.
  • +
  • JIRA:XSTR-743: Support proxy collections of Hibernate Envers.
  • +
  • Fix NPE in AttributeMapper.shouldLookForSingleValueConverter if parameters fieldName and definedIn are null.
  • +
  • Implicit type argument can be omitted when registering converters with @XStreamConverter annotation.
  • +
+ +

API changes

+ +
    +
  • Added c.t.x.converters.extended.NamedCollectionConverter for free element names in collections.
  • +
  • Added c.t.x.converters.extended.NamedMapConverter for free element names in maps.
  • +
  • Added c.t.x.io.xml.StandardStaxDriver to use the StAX implementation delivered with the Java 6 runtime.
  • +
  • Deprecated c.t.x.io.xml.SjsxpStaxDriver to select the internal StAX implementation of Oracle.
  • +
  • Added static methods getStaxInputFactory and getStaxOutputFactory to c.t.x.core.JVM as returning the + implementations of javax.xml.stream.XMLInputFactory (resp. javax.xml.stream.XMLOutputFactory) delivered with + the Java Runtime since Java 6.
  • +
  • Added c.t.x.core.ClassLoaderReference.
  • +
  • Added constructors taking an additional Class argument for c.t.x.converters.collections.CollectionConverter + and c.t.x.converters.collections.MapConverter.
  • +
  • Added constructors taking a ClassLoaderReference instead of a ClassLoader and deprecated the ones taking the ClassLoader: +
      +
    • c.t.x.XStream
    • +
    • c.t.x.converters.extended.DynamicProxyConverter
    • +
    • c.t.x.converters.extended.JavaClassConverter
    • +
    • c.t.x.converters.extended.JavaFieldConverter
    • +
    • c.t.x.converters.extended.JavaMethodConverter
    • +
    • c.t.x.converters.reflection.CGLIBEnhancedConverter
    • +
    • c.t.x.converters.reflection.ExternalizableConverter
    • +
    • c.t.x.converters.reflection.SerializableConverter
    • +
    • c.t.x.mapper.AnnotationMapper
    • +
    • c.t.x.mapper.DefaultMapper
    • +
    +
  • +
  • Added static methods newReflectionProvider, isAWTAvailable, isSQLAvailable and isSwingAvailable to + c.t.x.core.JVM as replacement for the deprecated non-static methods.
  • +
  • Deprecated c.t.x.core.JVM() and all non-static methods.
  • +
  • Added method useImplicitType to c.t.x.annotations.XStreamConverter.
  • +
  • JIRA:XSTR-722: Added + c.t.x.converters.reflection.ReflectionProvider.getFieldOrNull(Class, String).
  • +
  • Deprecated + c.t.x.converters.reflection.ReflectionProvider.fieldDefinedInClass(Class, String) in + favor of new c.t.x.converters.reflection.ReflectionProvider.getFieldOrNull(Class, + String).
  • +
  • Deprecated constructor c.t.x.converters.extended.RegexPatternConverter(Converter) + in favor of c.t.x.converters.extended.RegexPatternConverter().
  • +
  • Deprecated default constructor of c.t.x.converters.extended.FontConverter in favor of + c.t.x.converters.extended.FontConverter(Mapper).
  • +
  • Deprecated constructor c.t.x.converters.extended.ThrowableConverter(Converter) + in favor of c.t.x.converters.extended.ThrowableConverter(ConverterLookup).
  • +
  • Deprecated class c.t.x.converters.reflection.SelfStreamingInstanceChecker and moved + original implementation into c.t.x.core.util, since it is internal.
  • +
  • Deprecated interface c.t.x.mapper.AnnotationConfiguration.
  • +
+ +

1.4.4

+ +

Released January 19, 2013.

+ +

Minor changes

+ +
    +
  • JIRA:XSTR-709: Locks up on Mac with Apple JVM due to unwanted initialization of AWT.
  • +
  • JIRA:XSTR-711: DateConverter cannot handle dates in different era.
  • +
  • JIRA:XSTR-741: ToAttributedValueConverter fails to write enums as attributes.
  • +
  • JIRA:XSTR-712: HibernateMapper throws NPE if a collection contains null.
  • +
  • DateConverter supports now localized formats.
  • +
  • JIRA:XSTR-710: JsonWriter does not write BigInteger and BigDecimal as number values.
  • +
  • JIRA:XSTR-708: SqlTimestampConverter does not ignore timezone.
  • +
  • JIRA:XSTR-707: Creation of XmllPullParser with the XmlPullParserFactory may fail in OSGi environment.
  • +
  • JIRA:XSTR-705: Unnecessary synchronization accessing the field cache decreases performance.
  • +
  • JIRA:XSTR-714: Fields not found when XStream12FieldKeySorter used.
  • +
+ +

API changes

+ +
    +
  • Deprecated method c.t.x.core.util.JVM.is14(), c.t.x.core.util.JVM.is15() and c.t.x.core.util.JVM.is16().
  • +
+ +

1.4.3

+ +

Released July 17, 2012.

+ +

Major changes

+ +
    +
  • Support java.util.concurrent.ConcurrentHashMap with the MapConverter. This will also avoid a bug in JRockit + JDK reported in JIRA:XSTR-608.
  • +
  • JIRA:XSTR-699: Support for Hibernate 4 with XStream's Hibernate module as default for Java 6 or higher.
  • +
+ +

Minor changes

+ +
    +
  • JVM.loadClass will now also initialize the loaded class and ignore any occurring LinkageError.
  • +
  • JIRA:XSTR-596: SubjectConverter will be no longer registered if initialization of javax.security.auth.Subject fails.
  • +
  • JIRA:XSTR-683: Inheritance of implicit collections, arrays or maps is dependent on declaration sequence.
  • +
  • Inherited implicit collections, arrays or maps can be overwritten with own definition in subtype.
  • +
  • JIRA:XSTR-688: Cannot omit XML elements from derived fields.
  • +
  • JIRA:XSTR-696: Ill-formed JSON generated, because JSON writer is fed with type of declaring field instead of + the real object's type.
  • +
  • JIRA:XSTR-685: Deserialization from file or URL keeps stream open.
  • +
  • JIRA:XSTR-684: XML 1.0 character validation fails for characters from 0x10 to 0x1f.
  • +
  • JavaBeanConverter supports now instantiation for a specific type and can therefore be used in + @XStreamConverter annotation.
  • +
  • SerializableConverter is broken if the serialized type is the default implementation.
  • +
  • Method marshalUnserializableParent of SerializableConverter is protected now to skip the default mechanism + in a derived converter that uses the default constructor to create the original type (as an alternative for + JIRA:XSTR-695).
  • +
  • FieldDictionary may call sort of FieldKeySorter implementation with wrong type as key.
  • +
  • Sometimes DependencyInjectionFactory tries to instantiate objects with mismatching constructor arguments.
  • +
  • HSQLDB has to be a test dependency only for XStream's Hibernate module.
  • +
+ +

1.4.2

+ +

Released November 3, 2011.

+ +

Major changes

+ +
    +
  • XStream libraries can be used now directly in Android, therefore support of Java 1.4.2 has been stopped with the delivery. + Anyone who needs a version for Java 1.4.2 can build it easily from source, this build is still supported and part of CI.
  • +
  • JIRA:XSTR-675: New extended HierarchicalStreamReader interface with peekNextChild method. All XStream + readers implement the new interface (by Nikita Levyankov).
  • +
  • JIRA:XSTR-673: Collections.EMPTY_LIST, Collections.EMPTY_SET and Collections.EMPTY_MAP supported with own + alias and defined as immutable.
  • +
  • JIRA:XSTR-631: Collections.singletonList(), Collections.singletonSet() and Collections.singletonMap() + supported with own alias and own converters.
  • +
  • JIRA:XSTR-406 + JIRA:XSTR-663: Support additional parameters for XStreamConverter annotation (e.g. to declare a + ToAttributedValueConverter).
  • +
+ +

Minor changes

+ +
    +
  • WstxDriver did not trigger Woodstox, but BEA StAX implementation.
  • +
  • JIRA:XSTR-260: PrettyPrintWriter does not handle tab and new line characters in attributes.
  • +
  • JIRA:XSTR-667: Cannot serialize empty list with JsonHierarchicalStreamDriver.
  • +
  • JIRA:XSTR-661: TreeMarshaller.CircularReference is not a ConversionException.
  • +
  • JIRA:XSTR-562: StAX: Namespace attribute is not written in non-repairing mode for second sibling.
  • +
  • JIRA:XSTR-664: ClassCastException in HibernatePersistentSortedSetConverter and + HibernatePersistentSortedMapConverter.
  • +
  • JIRA:XSTR-674: Recreate binary compatibility with 1.3.x series for method + CustomObjectInputStream.getInstance(...).
  • +
  • JIRA:XSTR-671: CannotResolveClassException should accept cause.
  • +
  • JIRA:XSTR-672: Collections.EMPTY_LIST, Collections.EMPTY_SET and Collections.EMPTY_MAP used for in implicit + collection should not throw ReferencedImplicitElementException.
  • +
  • JIRA:XSTR-676: Introduce MissingFieldException thrown at deserialization time indicating a missing field or + property (by Nikita Levyankov).
  • +
  • Add length limit for cached strings in StringConverter, 38 characters by default.
  • +
  • The JsonHierarchicalStreamDriver and the JsonWriter did not support the inherited NameCoder instance.
  • +
  • Add BinaryStreamDriver.
  • +
  • NPE in XppDomComparator.
  • +
  • Dom4JXmlWriter fails to flush the underlying writer.
  • +
  • Known control characters are not encoded with JsonWriter as proposed at json.org.
  • +
  • Detect duplicate property processing in JavaBeanConverter and throw DuplicatePropertyException instead of + clobbering silently.
  • +
  • Allow access to Mapper and JavaBeanProvider in derived instances of JavaBeanConverter.
  • +
  • DependencyInjectionFactory failed to create instance when a matching constructor was found, but a default + constructor was also present.
  • +
+ +

API changes

+ +
    +
  • Added interface c.t.x.io.ExtendedHierarchicalStreamReader extending c.t.x.io.HierarchicalStreamReader. All + implementations of c.t.x.io.HierarchicalStreamReader will implement also the extended interface.
  • +
  • Added c.t.x.converters.reflection.MissingFieldException derived from + c.t.x.converters.reflection.ObjectAccessException and used instead when the unmarshalling process should write + a field or property that is missing and does not exist.
  • +
  • Added methods c.t.x.io.path.PathTracker.peekElement(), c.t.x.io.path.PathTracker.peekElement(int), and + c.t.x.io.path.PathTracker.depth().
  • +
  • Deprecated method c.t.x.core.ReferencingMarshallingContext.currentPath(). Wrong approach.
  • +
+ +

1.4.1

+ +

Released August 11, 2011.

+ +

Major changes

+ +
    +
  • JIRA:XSTR-659: Use again Xpp3 as default parser, now with additional XmlPullParser API as regular + dependency for the XPP factory. Only standard kXML2 package contains the XPP factory, but not the minimal kXML2 + version.
  • +
+ +

Minor changes

+ +
    +
  • Add utility class c.t.x.io.xml.xppdom.XppFactory and a path tracking comparator for XppDom.
  • +
+ +

1.4

+ +

Released August 6, 2011.

+ +

Major changes

+ +
    +
  • Java 7 is detected and supported.
  • +
  • JIRA:XSTR-542: The XppDriver uses now the official XmlPullParser API to locate an available parser using + the XmlPullParserFactory. This allows the usage of XPP technology with XStream in Android.
  • +
  • Additional explicit XPP drivers for the Xpp3 and kXML2 implementations.
  • +
  • Additional explicit XPP DOM drivers for the Xpp3 and kXML2 implementations.
  • +
  • kXML2 is now the preferred parser implementation, Xpp3 is optional.
  • +
  • Additional explicit StAX drivers for Woodstox, BEA StAX and SJSXP of the JDK 6 implementations.
  • +
  • JDK 1.3 is no longer officially supported.
  • +
  • JIRA:XSTR-377+JIRA:XSTR-226: New artifact xstream-hibernate with converters and mapper to process Hibernate + object graphs (by Costin Leau, Konstantin Pribluda and in special Jaime Metcher).
  • +
  • New NameCoder interface and implementations to support a generic name translation between names from the + object graph and a target format. The new XmlFriendlyNameCoder replaces the XmlFriendlyReplacer used for XML + only.
  • +
  • JIRA:XSTR-553: Support annotations in Android.
  • +
  • JIRA:XSTR-556: DateConverter uses format with 3-letter time zones that are ambiguous. Therefore it will now + always use UTC to write dates. Unmarshalled dates are not affected as long as they contain a time zone.
  • +
  • The type java.lang.reflect.Field is now handled by an own converter, that can still read the old format.
  • +
  • JIRA:XSTR-490: Provide path in Converter for contexts that track the path.
  • +
  • JIRA:XSTR-592+JIRA:XSTR-579: OmitField respected at deserialization time even for existing fields.
  • +
  • JIRA:XSTR-593: Direct support for java.net.URI instances (by Carlos Roman).
  • +
  • JIRA:XSTR-615+JIRA:XSTR-580: Dynamic proxies cannot be referenced recursively.
  • +
  • JIRA:XSTR-547: Wrong class loader used for Serializable types deserialized with an ObjectInputStream.
  • +
  • JIRA:XSTR-341: Support of implicit arrays.
  • +
  • JIRA:XSTR-306+JIRA:XSTR-406: Support of implicit maps.
  • +
  • JIRA:XSTR-344: New ToAttributedValueConverter to allow conversion of an element with string body and + attributes.
  • +
  • JIRA:XSTR-573: SortedSet added with TreeSet as the default implementation.
  • +
  • JIRA:XSTR-576: TreeMap and TreeSet no longer add an element without comparator (by Jason Greanya), + solves also invalid format with JSON for such objects (JIRA:XSTR-640).
  • +
+ +

Minor changes

+ +
    +
  • JIRA:XSTR-612: Improve extensibility of c.t.x.javabean.* package by reintroducing a PropertyDictionary with + the additional interface PropertySorter.
  • +
  • JIRA:XSTR-591: EnumSingleValueConverter did use toString() instead of name() to create the String + representation of an enum value.
  • +
  • JIRA:XSTR-618: Add Oracle as vendor used for recent JRockit versions and former Sun JDK.
  • +
  • JIRA:XSTR-656: DomReader and Dom4JReader do not escape attribute names retrieving their values.
  • +
  • JIRA:XSTR-604: StringConverter's cache may cause an OutOfMemoryException.
  • +
  • JIRA:XSTR-577: Skip UTF-8 BOM in XmlHeaderAwareReader.
  • +
  • The XppReader no longer uses a BufferedReader.
  • +
  • JIRA:XSTR-543: Better deserialization support of the defined-in system attribute in combination with field + aliases.
  • +
  • JIRA:XSTR-551: Deprecated XStream.InitializationException still thrown instead of InitializationException.
  • +
  • JIRA:XSTR-655: JsonWriter generates invalid JSON for Externalizable types.
  • +
  • JIRA:XSTR-540: Support Jettison-based configuration of JettisonMappedXmlDriver (by Doug Daniels).
  • +
  • JIRA:XSTR-633: JettisonMappedXmlDriver escaped property names according escape rules for XML tag names.
  • +
  • JIRA:XSTR-625: Optionally ignore XStream's hints for Jettison to generate JSON arrays (by Dejan Bosanac).
  • +
  • JIRA:XSTR-605: Upgrade to Jettison 1.2 (for Java 5 or higher).
  • +
  • New JsonWriter.EXPLICIT_MODE generating JSON that enforces property sequence.
  • +
  • JIRA:XSTR-552: Improve performance of ReflectionProvider (by Keith Kowalczykowski).
  • +
  • JIRA:XSTR-559: Improve performance of Sun14ReflectionProvider (by Keith Kowalczykowski).
  • +
  • JIRA:XSTR-564: Improve performance of AnnotationMapper (by Keith Kowalczykowski).
  • +
  • JIRA:XSTR-563: Use ReferenceQueue for cleaning-up WeakReferences in ObjectIdDictionary (by Keith + Kowalczykowski).
  • +
  • JIRA:XSTR-646: Cache of Sun14ReflectionProvider consumes more PermGen space than necessary.
  • +
  • JIRA:XSTR-636: Ineffective cache in FieldDictionary using WeakHashMap with WeakReference values.
  • +
  • Ineffective cache for SerializationMethodInvoker (related to JIRA:XSTR-636).
  • +
  • Introduction of Caching interface implemented by all types in XStream that create local caches that may + have to be flushed manually.
  • +
  • Avoid excessive creation of AbstractPullReader.Event objects by using a pool.
  • +
  • Possibility to generate XPath expressions that select always a single node instead of a node list.
  • +
  • Cannot reference replaced object using ID references.
  • +
  • Implicit collection functionality will no longer use custom collection converters that may write tags that are not + recognized at deserialization time again.
  • +
  • JIRA:XSTR-654: Unmarshal fails when an implicit collection is defined and an element is named equal to the field.
  • +
  • JIRA:XSTR-574: AbstractReferenceUnmarshaller cannot handle null values for references.
  • +
  • Improve exception output in case of a missing field.
  • +
  • JIRA:XSTR-555: StAX driver tests do not honor repairing mode.
  • +
  • JIRA:XSTR-570: The @XStreamConverter provides now also the current type as possible constructor argument.
  • +
  • JIRA:XSTR-629: Deserialization of Externalizable with non-accessible default constructor fails.
  • +
  • JIRA:XSTR-571: Cannot serialize synchronized RandomAccessList types.
  • +
  • JIRA:XSTR-583: BinaryDriver fails to handle Strings with more than 64K bytes.
  • +
  • JIRA:XSTR-639: Cannot omit field at deserialization if the field has a class attribute.
  • +
  • JIRA:XSTR-599: EncodedByteArrayConverter should implement SingleValueConverter.
  • +
  • JIRA:XSTR-584: Race condition in XmlFriendlyReplacer.
  • +
  • JIRA:XSTR-623: XmlFriendlyReplacer may write illegal name characters (by Michael Schnell).
  • +
  • The ConversionException hides information if its ErrorWriter contains the added key already.
  • +
  • JIRA:XSTR-598: Attribute "defined-in" was wrongly evaluated for other attributes.
  • +
  • JIRA:XSTR-650: Possible NullPointerException at initialization on platforms like Android that do not + support all types of the JDK.
  • +
  • JIRA:XSTR-652: Initialization of XStream fails if DurationConverter constructor throws a + javax.xml.datatype.DatatypeConfigurationException. Converter will no longer handle Duration types if no + instance of the internal DatatypeFactory can be created.
  • +
  • Constructor DocumentWriter(Element) forgets the provided element.
  • +
  • JIRA:XSTR-597: Optimize AbstractReflectionConverter.
  • +
  • Introduce Caching interface to flush the internal cache of specific components.
  • +
  • Support JIRA:XSTR-407 also for IBM JRE 1.6 and greater.
  • +
  • java.nio.charset.Charset's converter was added as immutable type instead of the type itself.
  • +
  • java.util.Currency added as immutable type.
  • +
  • Fix selection of same parameter types in DependencyInjectionFactory.
  • +
  • Deprecation of c.t.x.javabean.PropertyDictionary has been countermanded.
  • +
+ +

API changes

+ +
    +
  • Any deprecated stuff of the 1.2.x releases has been removed.
  • +
  • Deprecated constructors of c.t.x.converters.reflection.SerializableConverter, c.t.x.converters.reflection.ExternalizableConverter + and c.t.x.converters.reflection.CGLIBEnhancedConverter; new versions take an additional argument for class loader (as a result + for JIRA:XSTR-547).
  • +
  • Deprecated constructors of c.t.x.io.xml.XppReader, new versions take an additional argument for the XmlPullParser.
  • +
  • Deprecated c.t.x.io.xml.XppReader.createParser(), the XPP parser is now created by the driver.
  • +
  • Package c.t.x.io.xml.xppdom is now part of the official API.
  • +
  • c.t.x.io.xml.xppdom.Xpp3Dom and c.t.x.io.xmlxpp.dom.Xpp3DomBuilder have been deprecated. Functionality is + merged in c.t.x.io.xml.xppdom.XppDom.
  • +
  • Deprecated c.t.x.mapper.XStream11XmlFriendlyMapper and c.t.x.mapper.AbstractXmlFriendlyMapper.
  • +
  • Added interface c.t.x.core.ReferencingMarshallingContext which is implemented by all referencing marshallers.
  • +
  • Added interface c.t.x.io.naming.NameCoder and implementations.
  • +
  • Deprecated c.t.x.io.xml.XmlFriendlyReplacer, c.t.x.io.xml.XmlFriendlyReader and c.t.x.io.xml.XmlFriendlyWriter.
  • +
  • Deprecated c.t.x.io.xml.AbstractXmlDriver, c.t.x.io.xml.AbstractXmlReader and c.t.x.io.xml.AbstractXmlWriter, added + c.t.x.io.AbstractDriver, c.t.x.io.AbstractReader and c.t.x.io.AbstractWriter instead.
  • +
  • Deprecated all constructors of Driver, Reader and Writer implementations that take a XmlFriendlyReplacer as argument, + added constructors taking a NameCoder instead.
  • +
  • Added interface com.thoughtworks.xstream.converters.ErrorReporter to allow other types to report + also errors (apart from a HierarchicalStreamReader). Any converter and the parent object of the currently deserialized + element may provide additional error information now.
  • +
+ +

1.3.1

+ +

Released December 6, 2008.

+ +

CGLIB support must be explicitly activated now. The decision has been made due to possible problems using an own + classloader and because of ongoing complaints about occurring exceptions in the CGLIBEnhancedConverter at XStream initialization although + they are caused by incompatible ASM versions on the user's classpath (JIRA:XSTR-469, JIRA:XSTR-513 and JIRA:XSTR-518).

+ +

XStream uses some attributes on its own. Until now it was possible to use XStream.aliasAttribute to define a different + name. This does still work but is deprecated for system attributes. Use the new call XStream.aliasSystemAttribute for such an alias.

+ +

Major changes

+ +
    +
  • JIRA:XSTR-515: CGLIB support is no longer activated automatically and has to be + explicitly turned on.
  • +
  • JIRA:XSTR-448: Separated system attributes and user defined attributes for aliases.
  • +
  • JIRA:XSTR-55: Ability to alias a package name.
  • +
  • JIRA:XSTR-434: New JsonWriter instead of JsonHierarchicalStreamWriter with mode to strip root node of generated JSON (by Paul Hammant).
  • +
  • Support for Diablo JDK on FreeBSD (by Reto Bachmann-Gmür).
  • +
  • JIRA:XSTR-495: New PersistenceStrategy instead of StreamStrategy (based on the code and comments by Alexander Radzin).
  • +
+ +

Minor changes

+ +
    +
  • Support special Jettison functionality for JSON to detect collections or arrays with one element introduced with Jettison 1.0.
  • +
  • JIRA:XSTR-493: Using attributes for fields with XML-unfriendly names results in NPE at deserialization.
  • +
  • JIRA:XSTR-497: Unsafe operation with WeakHashMap can raise a NPE in Sun14ReflectionProvider.
  • +
  • JIRA:XSTR-423: Support of CGLIB enhanced proxies with multiple callbacks if the proxy uses a factory (CGLIB default).
  • +
  • JIRA:XSTR-536: XStream silently ignores unknown elements.
  • +
  • JIRA:XSTR-503: Omitted properties in JavaBeans are requested at serialization (by Kevin Conaway).
  • +
  • Fix possible memory leak in ObjectIdMap for JVMs that provide real distinct identity hash codes (happened on amd64 system).
  • +
  • JIRA:XSTR-480: Aliasing of array types.
  • +
  • JIRA:XSTR-515: The SubjectConverter and DurationConverter are only registered if the converted class is part of the JDK, + otherwise they must be registered now explicitly.
  • +
  • JIRA:XSTR-504: XmlHeaderAwareReader fails with improper sized PushbackInputStream.
  • +
  • JIRA:XSTR-489: @XStreamConverter supports now also SingleValueConverter implementations.
  • +
  • JIRA:XSTR-481: @XStreamConverter and @XStreamAsAttribute can be used together (as a result of JIRA:XSTR-489).
  • +
  • JIRA:XSTR-519: New annotation @XStreamInclude to force annotation detection of included types (by Seven Sparling).
  • +
  • JIRA:XSTR-469: Support custom converters for enum types.
  • +
  • JIRA:XSTR-502: ClassNotFoundException even if writeReplace returns proper object.
  • +
  • JIRA:XSTR-529: NullPointerException for null elements in implicit lists.
  • +
  • JIRA:XSTR-517: Miscellaneous performance improvements (by Tatu Saloranta).
  • +
  • JIRA:XSTR-525: JsonHierarchicalStreamDriver writes invalid JSON in case of system attribute.
  • +
  • JIRA:XSTR-535: Mode to allow plain values as result for JSON without root node.
  • +
  • JIRA:XSTR-531: Possibility to omit system attributes.
  • +
  • JIRA:XSTR-508: Fix marshalling error for nested serializable objects with own writeReplace/readResolve methods.
  • +
  • JIRA:XSTR-507: Advanced ReferenceByIdMarshaller uses id of the current object if available.
  • +
  • JIRA:XSTR-485: Check reference for valid object when deserializing.
  • +
  • Fix classloader problem, Xpp3 parser cannot be loaded within a web application.
  • +
  • Dependencies have been updated to latest versions of JDOM, Jettison, Joda Time, and Woodstox. Note for Maven + builds that the groupId of JDOM has changed.
  • +
  • Fix possible IndexOutOfBoundsException creating returning the message for a ConversionException.
  • +
  • JIRA:XSTR-495: StreamStrategy cannot handle key with value null.
  • +
+ +

API changes

+ +
    +
  • Deprecated c.t.x.io.json.JsonHierarchicalStreamWriter in favour of c.t.x.io.json.JsonWriter.
  • +
  • c.t.x.mapper.EnumMapper no longer derives from the c.t.x.mapper.AttributeMapper as it has been before version 1.3. Therefore the new + constructor has been deprecated in favour of the old one.
  • +
  • c.t.x.mapper.Mapper.getConverterFromAttribute(Class, String) has been deprecated in favour of + c.t.x.mapper.Mapper.getConverterFromAttribute(Class, String, Class) taking the type as third argument that should be handled by the + converter.
  • +
  • c.t.x.core.ReferenceByIdMarshaller.IdGenerator.next() has now the current object as argument.
  • +
  • New c.t.x.persistence.PersistenceStrategy and c.t.x.persistence.FilePersistenceStrategy.
  • +
  • Deprecated c.t.x.persistence.StreamStrategy and c.t.x.persistence.FileStreamStrategy.
  • +
+ +

1.3

+ +

Released February 27, 2008.

+ +

Major changes

+ +
    +
  • ReflectionConverter writes now the fields of the parent classes first.
  • +
  • Support for Converter definition at field level.
  • +
  • Refactoring of Annotation support, invent auto-detection mode.
  • +
  • Annotated converters are no longer detected automatically, all annotations are now handled in the same way.
  • +
  • JIRA:XSTR-334: XStream will deserialize directly from a file or URL. Some parser take advantage of these objects to + define a SystemId used to resolve further references in XML, schema or DTD. Appropriate createReader methods have been + added to c.t.x.io.HierarchicalStreamDriver.
  • +
  • JIRA:XSTR-261: All c.t.x.io.HierarchicalStreamDriver implementations respect now the encoding of an XML header + if read from an InputStream.
  • +
  • DomDriver does no longer use explicitly UTF-8 by default, DomReader will therefore respect the encoding defined + in the XML header or use native encoding
  • +
  • JIRA:XSTR-415: JavaBeanConverter uses now BeanIntrospection (by Hinse ter Schuur).
  • +
  • JIRA:XSTR-424: DateConverter uses now by default SimpleDateFormat instances in non-lenient mode.
  • +
  • JIRA:XSTR-386: SingleValueConverter that utilizes PropertyEditor implementations (by Jukka Lindström).
  • +
  • JIRA:XSTR-427: Converter for javax.xml.datatype.Duration (by John Kristian).
  • +
  • JIRA:XSTR-305: Field alias inheritance (by David Blevins).
  • +
  • XStream failed to initialize in environments without AWT or SQL classes.
  • +
  • JIRA:XSTR-420: XPath of references are not XmlFriendly encoded.
  • +
  • JIRA:XSTR-473: String "\0" serialized as invalid XML, support compliant behaviour according XML version.
  • +
  • JIRA:XSTR-431: Direct support of enhanced mode for SAP JVM (thanks to Norbert Kuck by SAP).
  • +
  • JIRA:XSTR-437: Static cache in annotation processing causes failing OSGi bundles.
  • +
  • JIRA:XSTR-279+JIRA:XSTR-335: Annotations are not inherited from parent class.
  • +
  • Fix StringConverter using a WeakHashMap with strong references in its value.
  • +
  • JIRA:XSTR-403: Attributes are no longer written with JSONHierarchicalStreamDriver if current object is a collection.
  • +
  • JIRA:XSTR-456: New LookAndFeelConverter handling LookAndFeel implementations with reflection.
  • +
  • JIRA:XSTR-462: CachingMapper keeps direct class references.
  • +
  • JIRA:XSTR-411: JsonHierarchicalStreamDriver does not escape characters according RFC 4627.
  • +
  • JsonHierarchicalStreamDriver writes wrong brackets around complex Java types with a single value.
  • +
  • JsonHierarchicalStreamDriver writes attribute names with a leading '@'.
  • +
  • JsonHierarchicalStreamDriver supports Map implementations.
  • +
+ +

Minor changes

+ +
    +
  • Added converter for java.lang.StringBuilder instances.
  • +
  • Added converter for java.util.UUID instances.
  • +
  • JIRA:XSTR-430: Fields written as attributes could not be omitted.
  • +
  • JIRA:XSTR-407: Comparator might access uninitialized elements for TreeSet and TreeMap. A deserialized + Comparator is no longer called, the converters expect the elements now in a sorted order.
  • +
  • JIRA:XSTR-404, @XStreamImplicit() for ArrayList<ArrayList<Type>> throws ClassCastException.
  • +
  • @XStreamContainedType() for ArrayList<ArrayList<Type>> throws ClassCastException.
  • +
  • XStreamer did not persist a FieldKeySorter instance.
  • +
  • JIRA:XSTR-241: JavaBeanConverter now supports customized BeanProvider.
  • +
  • JIRA:XSTR-280: JavaBeanConverter now supports aliasField and omitField (by Hinse ter Schuur).
  • +
  • JIRA:XSTR-280: SerializationConverter now supports aliasField and omitField.
  • +
  • JIRA:XSTR-429: XmlFriendlyReplacer support for SaxWriter and TraxSource (by Adrian Wilkens).
  • +
  • JIRA:XSTR-421: Characters cannot be written as attribute.
  • +
  • JIRA:XSTR-426: java.swt.KeyStroke not properly serialized because of a character undefined in unicode.
  • +
  • JIRA:XSTR-352: Strings with arbitrary ISO control characters are not properly serialized.
  • +
  • JIRA:XSTR-428: An attribute named like a transient field did abort deserialization of following fields.
  • +
  • JIRA:XSTR-443: XStream.createObjectOutputStream does not use the given driver to create the HierarchicalStreamWriter.
  • +
  • JIRA:XSTR-440: Implicit collections can be declared for fields that are not of Collection type.
  • +
  • JIRA:XSTR-446: Handle all primitives and their boxed counterpart for JsonHierarchicalStreamDriver.
  • +
  • JIRA:XSTR-447: Fix deserialization of Array class types in JDK 6 (see JDK bug 6500212).
  • +
  • JIRA:XSTR-450: @XStreamAlias is ignored if attributes should be used for the field type.
  • +
  • JIRA:XSTR-418: Inherited @XStreamAlias is ignored if field should be rendered as attribute.
  • +
  • JIRA:XSTR-393: Annotation processing is not consistent.
  • +
  • JIRA:XSTR-412: @XStreamImplicit throws NPE for untyped collections.
  • +
  • JIRA:XSTR-463: Cannot provide own default Mapper chain.
  • +
  • JIRA:XSTR-464: Cannot provide a ClassLoader that is used in all cases.
  • +
  • JIRA:XSTR-394: Allow enums as attributes.
  • +
  • JIRA:XSTR-413: Support @XStreamAsAttribute for enums.
  • +
  • JIRA:XSTR-478: Cannot specify default implementation for polymorphic enum.
  • +
  • JIRA:XSTR-419: Treat enums as immutable types.
  • +
  • Update annotation tutorial, explain limitations of auto-detection mode.
  • +
  • Added copyright notices to all files.
  • +
  • StaxWriter.flush did close Stax' XMLStreamWriter instead of flushing it.
  • +
  • JIRA:XSTR-471: XStream POMs do no longer declare a repository at all.
  • +
  • Calendar object could not be rendered with JSONHierarchicalStreamDriver.
  • +
  • JIRA:XSTR-476: Properties can be sorted by key.
  • +
  • XStream.createObjectInputStream and XStream.createObjectOutputStream + overloaded to support a binary InputStream or OutputStream.
  • +
  • JIRA:XSTR-470: Allow transient fields to be optionally deserialized.
  • +
+ +

API changes

+ +
    +
  • c.t.x.annotation.Annotations, c.t.x.annotation.AnnotationReflectionConverter and c.t.x.annotation.AnnotationProvider deprecated. + Functionality is integrated in new c.t.x.mapper.AnnotationMapper and accessible with new methods c.t.x.XStream.processAnnotations().
  • +
  • New auto-detection mode for annotations, that can be turned on with c.t.x.XStream.autodetectAnnotations()
  • +
  • c.t.x.annotation.@XStreamContainedType deprecated, the behaviour is now always active and the annotation therefore superfluous.
  • +
  • Due to JIRA:XSTR-421 null characters are no longer written as tag with an attribute (<char null="true"/>), + but as empty tag. The old representation is still supported at deserialization.
  • +
  • Characters that are not defined in unicode or ISO control characters (expect TAB and LF) are written as numerical entity now.
  • +
  • XPath references are now also XML-friendly encoded to match the path exactly. Unencoded references will normally work anyway, + but in special cases the exact behaviour of XStream 1.2.x might be necessary. See acceptance tests for XStream 1.2.x compatibility.
  • +
  • c.t.x.core.BaseException deprecated in favour of c.t.x.XStreamException as base exception for all exceptions XStream throws.
  • +
  • c.t.x.XStream.InitializerException deprecated in favour of c.t.x.InitializerException.
  • +
  • New methods get() and keys() in interface c.t.x.converter.ErrorWriter.
  • +
  • c.t.x.mapper.XmlFriendlyMapper deprecated, technology is replaced since version 1.2 by c.t.x.io.xml.XmlFriendlyReplacer as part of the + different XmlWriter implementations.
  • +
  • c.t.x.mapper.Mapper.aliasForAttribute() and c.t.x.mapper.Mapper.attributeForAlias() deprecated, since it provided in reality the combined + functionality of c.t.x.mapper.Mapper.serializedMember()/realMember() and c.t.x.mapper.Mapper.getConverterFromItemType().
  • +
  • c.t.x.XStream(ReflectionProvider, Mapper, HierarchicalStreamDriver) deprecated, in favour of + c.t.x.XStream(ReflectionProvider, HierarchicalStreamDriver, Mapper, ClassLoader).
  • +
  • New interface c.t.x.converter.ConverterRegistry to express explicit functionality managing the converters.
  • +
  • c.t.x.core.DefaultConverterLookup no longer uses a c.t.x.mapper.Mapper. Therefore the old constructor has been deprecated in favour + of a default constructor.
  • +
  • Overloaded methods of c.t.x.mapper.Mapper.getConverterFromItemType and c.t.x.mapper.Mapper.getConverterFromAttribute have been + deprecated. Only one version has been kept, the implementation can handle all cases now at once and therefore multiple calls to the mapper chain + are avoided.
  • +
  • c.t.x.mapper.EnumMapper derives now from the c.t.x.mapper.AttributeMapper to support enums as attributes. Therefore the old constructor + has been deprecated in favour of one taking an additional c.t.x.converters.ConverterLookup that has to be passed to the new parent.
  • +
+ +

Note, to support a representation of null values in some way, it is absolutely necessary that each converter can handle a null + value in its marshalling methods. If you have implemented your own custom converters, try to handle such a case also to prevent incompatibilities + in case XStream will provide such values with its next major version.

+ +

Version 1.2.2

+ +

Released May 24, 2007.

+ +

Note, that next version of XStream will behave slightly different by default. XStream emits + all fields in declaration order like Java serialization. But in contrast to Java it will omit the fields of parent + classes last while Java serialization emits them first. This makes it difficult to match a given XML schema that + defined inherited types or leads sometimes to obscure initialization problems. However, XStream itself will not be + affected by the changed order of elements in the XML, any deserialization of current XML representations will work + fine. Anyway we will provide with XStream 1.3 a FieldKeySorter implementation that mimics the old behaviour. In + the meanwhile you can enforce the new field sorting by installing the NaturalFieldKeySorter.

+ +

Major changes

+ +
    +
  • JIRA:XSTR-391, Support for writing (and reading) JSON by the new JettisonMappedXmlDriver (by Dejan Bosanac).
  • +
  • New FieldKeySorter interface allows a custom sort order of the XML elements.
  • +
  • JIRA:XSTR-68 and JIRA:XSTR-210, OmitField is now respected at deserialization to ignore removed fields.
  • +
+ +

Minor changes

+ +
    +
  • JIRA:XSTR-387, Fix aliasing of inherited fields.
  • +
  • JIRA:XSTR-395, Fix StringConverter allocating PermGen space.
  • +
  • JIRA:XSTR-368, @XStreamConverter converters should be cached inside the AnnotationReflectionConverter.
  • +
  • JIRA:XSTR-392, @XStreamOmitField can be used to omit fields from the resulting XML (contributed by Chung-Onn Cheong).
  • +
  • JIRA:XSTR-371, Fix JSONWriter that omits a closing bracket for for fields with null value.
  • +
  • JIRA:XSTR-398, DomDriver ignores given XmlFriendlyReplacer.
  • +
  • JIRA:XSTR-370, Buildable with JDK 6, fix FontConverter for JDK 6.
  • +
  • JIRA:XSTR-382, Support hex and octal number values.
  • +
  • DateConverter did not respect change in TimeZone after first usage.
  • +
  • JIRA:XSTR-375, Support for aliasing native types.
  • +
  • JIRA:XSTR-243 again, XML elements for transient fields are now ignored completely at deserialization.
  • +
  • Release unused object references to keep memory print low.
  • +
  • Support for AWT and SQL is now optional: XStream now works on embedded virtual machines lacking such APIs (by Nicolas Gros d'Aillon).
  • +
  • Support raw bytes read from the ObjectInputStream.
  • +
  • JIRA:XSTR-373, Support for Hitachi JVM (tested by Yuji Yamano).
  • +
  • JIRA:XSTR-378 and JIRA:XSTR-379, Fix TextAttributeConverter and EnumSetConverter failing on Apache Harmony.
  • +
  • JIRA:XSTR-363, Support of native field order i.e. fields are processed in declaration order base classes first.
  • +
  • JIRA:XSTR-320, Static field in child may hide non-static field in parent.
  • +
+ +

API changes

+ +
    +
  • JIRA:XSTR-365, Multiple implicit collections with annotations. Deprecated @XStreamImclicitCollection in favour of @XStreamImplicit + declared at field level.
  • +
+ +

Version 1.2.1

+ +

Released November 11, 2006.

+ +

Major changes

+ +
    +
  • Introduced DocumentWriter interface and generalized functionality for all writer implementations + creating a DOM structure (DOM4J, DOM, JDom, Xom, Xpp3Dom).
  • +
  • Refactored build system to use Maven 2. Ant still supported on XStream Core.
  • +
  • Created separate XStream Benchmark module
  • +
+ +

Minor changes

+ +
    +
  • JIRA:XSTR-346, XStream.getClassMapper() does not return a ClassMapper for the current Mapper.
  • +
  • Fix problem with fields containing a double underscore.
  • +
  • JIRA:XSTR-345, Dom4JWriter adds up attributes.
  • +
  • JIRA:XSTR-336, XStream fails to reference an implicit element.
  • +
  • JIRA:XSTR-337, Annotation cycle bug.
  • +
  • Fix packaging error for the resulting jar building with Maven2.
  • +
  • JIRA:XSTR-339, NPE for attribute null values.
  • +
  • JIRA:XSTR-338, NPE in JSON writer for converters using non-extended HierarchicalStreamWriter.
  • +
  • JIRA:XSTR-357, Fix escaping of values in JSON writer.
  • +
  • JIRA:XSTR-356, Fix unmarshaling error for fields containing proxies.
  • +
  • JIRA:XSTR-349, Fix backward compatibility of Dom4jWriter.
  • +
  • JIRA:XSTR-309, More versatile boolean conversion options (contributed by David Blevins).
  • +
  • Add XStream.getReflectionProvider() to retrieve ReflectionProvider in use.
  • +
  • JIRA:XSTR-358, @XStreamConverter annotation does not call converter constructor.
  • +
  • Website generated using XSite
  • +
+ +

API changes

+ +
    +
  • Deprecate JDomWriter.getResult() in favour of DocumentWriter.getTopLevelNodes().
  • +
  • Deprecate ThreadSafeSimpleDateFormat, since this is an internal helper and not part of XStream API.
  • +
+ +

Version 1.2

+ +

Released August 18, 2006.

+ +

Major changes

+ +
    +
  • JIRA:XSTR-269, Using attributes for fields (contributed by Paul Hammant and Ian Cartwright).
  • +
  • Aliasing of arbitrary attributes.
  • +
  • JIRA:XSTR-50, XStream can now serialize another XStream instance.
  • +
  • JIRA:XSTR-227, XStream has now the XStreamer, that serializes an object together with its XStream instance.
  • +
  • JIRA:XSTR-278, AnnotationConverter for fields (contributed by Guilherme Silveira).
  • +
  • JIRA:XSTR-256, PureJavaReflectionProvider supports now final fields starting with JDK 1.5
  • +
  • JIRA:XSTR-258, Any Collection type can now be declared implicit, the default implementation will be respected for unmarshaling.
  • +
  • JIRA:XSTR-88, XStream can now write all references as absolute XPath expression.
  • +
  • JIRA:XSTR-62 and JIRA:XSTR-211, New SingeValueConverter allows light weight converters if the value can be represented by a unique string.
  • +
  • Aliasing of classes of a specific type.
  • +
  • JIRA:XSTR-239, Support for certain types of proxies generated with the CGLIB Enhancer.
  • +
  • JIRA:XSTR-90 and JIRA:XSTR-311, Support for BEA JRockit starting with R25.1.0 (contributed by Henrik Ståhl of BEA).
  • +
+ +

Technology preview

+ +
    +
  • Experimental binary reader and writer.
  • +
  • Experimental HierarichicalStreamCopier allows streams to be copied from one format to another without the overhead of serialization.
  • +
  • Experimental JSON support allows streams to be copied from one format to another without the overhead of serialization (contributed by Paul Hammant).
  • +
+ +

Minor changes

+ +
    +
  • JIRA:XSTR-266, XStream fails to serialize elements of a unserializable class, that is a base class of a derived class
  • +
  • JIRA:XSTR-236, Priority constants for converter registration are now public
  • +
  • JIRA:XSTR-215, XStream writes now fields in declaration order even for JVMs reporting them in reverse order like IBM JDK.
  • +
  • JIRA:XSTR-276 and JIRA:XSTR-283, XStream does no longer attempt to create references to implicit element.
  • +
  • JIRA:XSTR-244, Closing a Writer can now be done twice, but any write attempt will later on fail.
  • +
  • JIRA:XSTR-243, Transient fields were unmarshalled from XML.
  • +
  • JIRA:XSTR-250, Providing a mapper to the XStream constructor will no longer result in a NPE.
  • +
  • JIRA:XSTR-281, After registering a new converter, the internal converter cache is now cleared.
  • +
  • JIRA:XSTR-284, XStream checks the object returned by a converter for compatibility.
  • +
  • XStream no longer fails serializing a Throwable without cause when no references shall be written.
  • +
  • Converter for java.awt.font.TextAttribute.
  • +
  • Converter for java.nio.charset.Charset.
  • +
  • JIRA:XSTR-286, XStream detects impossible self serialization and throws now an appropriate ConversionException.
  • +
  • JIRA:XSTR-291, XomDriver implementation added.
  • +
  • JIRA:XSTR-299, Fix for implicit collections with items using the same name as the field name of the underlying collection.
  • +
  • JIRA:XSTR-245, Broken XML with custom serialization in certain cases (patch contributed by Cyrille Le Clerc).
  • +
  • JIRA:XSTR-304, Bad handling of repairing namespace flag for StaxDriver (patch contributed by John Kristian).
  • +
+ +

API changes

+ +
    +
  • JIRA:XSTR-252, Refactored support for XML friendly character mapping.
  • +
  • JIRA:XSTR-69, Refactored ReflectionConverter allows simpler subclassing.
  • +
  • Unmarshalling context has now an overloaded version of the method convertAnother to provide the Converter directly.
  • +
  • Deprecate ClassMapper for Mapper. All methods with a ClassMapper parameter have now a duplicate taking only a Mapper. The variant with the ClassMapper is deprecated.
  • +
  • Deprecate c.t.x.alias.CannotResolveClassException for c.t.x.mapper.CannotResolveClassException.
  • +
  • Deprecate NameMapper (was not used within XStream anymore anyway).
  • +
  • Deprecate constructor of DefaultMapper taking an alternative name for the class attribute. Use the aliasAttribute method.
  • +
  • Deprecate attributeForImplementationClass, attributeForClassDefiningField, attributeForReadResolveField, and attributeForEnumType in favour of the generalized aliasForAttribute in the Mapper interface.
  • +
  • Removed all deprecated stuff from 1.1.x and 1.0.x
  • +
  • JIRA:XSTR-211, A lot of existing (basic) Converters have been refactored to use the new SingleValueConverter interface.
  • +
  • Dom4JWriter uses now a DocumentFactory and a XMLWriter as constructor arguments.
  • +
+ +

Version 1.1.3

+ +

Released January 13, 2006.

+ +

Major changes

+ +
    +
  • Added XStream.toXML(OutputStream) and XStream.fromXML(InputStream).
  • +
  • Ability to prevent fields from being serialized by calling XStream.omitField() or by implementing Mapper.shouldSerializeMember().
  • +
  • Added Converter for Enum, EnumMap and EnumSet
  • +
  • JIRA:XSTR-186, Added BeanConverter (contributed by Andrea Aime)
  • +
  • JIRA:XSTR-246, Added ISO8601SqlTimestampConverter (contributed by Cheong, Chung-Onn)
  • +
  • Added ISO8601GregorianCaledarConverter
  • +
  • JIRA:XSTR-215, Fixed support for IBM JVM (contributed by Gabor Liptak)
  • +
  • Enhanced mode support for Blackdown JDK
  • +
  • JIRA:XSTR-265, support for javax.security.auth.Subject
  • +
  • JIRA:XSTR-233, support for Integer[] arrays
  • +
+ +

Minor changes

+ +
    +
  • Remove unnecessary PrintWriter wrapper in default writers (pointed out by Mathieu Champlon)
  • +
  • Bugfix: EnumSet converter can now deal with empty sets (contributed by Baba Buehler)
  • +
  • Update ISO8601DateConverter to use Joda 1.0
  • +
  • JIRA:XSTR-242, GregorianCalenderConverter saves now the timezone
  • +
  • JIRA:XSTR-247, ISO8601DateConverter now independent on timezone
  • +
  • JIRA:XSTR-263, Circular references with Externalizable objects fail
  • +
+ +

API changes

+ +
    +
  • None.
  • +
+ +

Version 1.1.2

+ +

Released April 30, 2005. Most popular feature requests implemented. Java 5 Enum support. Serialization of JavaBeans + using accessors. Aliasing of fields. StAX integration, with namespaces. Improved support on JDK 1.3 and IBM JDK.

+ +

Major changes

+ +
    +
  • JIRA:XSTR-186, Option to serialize JavaBeans using public accessors, rather than private fields (contributed by Andrea Aime).
  • +
  • Ability to alias fields as well as classes, using XStream.addFieldAlias().
  • +
  • JIRA:XSTR-70, JIRA:XSTR-204 Support for JDK 5 enums (contributed by Eric Snell and Bryan Coleman).
  • +
  • JIRA:XSTR-206 Clean representation of JDK 5 EnumMap and EnumSet.
  • +
  • XStream can now be built using JDK 1.3 (previously it required JDK 1.4 to compile, but 1.3 to run).
  • +
  • JIRA:XSTR-215, Enhanced mode is now supported on the IBM 1.4 JDK.
  • +
  • The default HierarchicalStreamWriter implementation is supplied by the HierarichicalStreamDriver (as well as the reader).
  • +
+ +

Minor changes

+ +
    +
  • JIRA:XSTR-104 HierarchicalStreamReader now exposes all available attributes to the Converter implementations (contributed by Trygve Laugstol).
  • +
  • Bugfix: Externalizable deserialization supported for objects not at the root of tree.
  • +
  • JavaMethodConverter handles non public methods/constructors (contributed by Kevin Ring).
  • +
  • PropertiesConverter also serializes default properties, if present (contributed by Kevin Ring).
  • +
  • Bugfix: In some cases, XppReader and StaxReader would get confused when calling hasMoreChildren() and getValue() on the same node.
  • +
  • JIRA:XSTR-217, ISO8601DateConverter now requires joda-time-1.2.1
  • +
  • PrettyPrintWriter and CompactWriter may have their text/attribute escaping rules customized by overriding writeText() and writeAttributeValue().
  • +
+ +

API changes

+ +
    +
  • HierarchicalStreamDriver implementations now require a createWriter() method. The simplest implementation is to return a new PrettyPrintWriter.
  • +
  • Introduced ReaderWrapper/WriterWrapper classes to make it easier to wrap (decorate) HierarchicalStreamReader/Writer instances.
  • +
+ +

Version 1.1.1

+ +

Released March 7, 2005. Mostly bugfixes and minor feature enhancements.

+ +

Major changes

+ +
    +
  • Converters can be registered with a priority, allowing more generic filters to handle classes that don't have more specific converters.
  • +
  • Converters can now access underlying HierarchicalStreamReader/Writer implementations to make implementation specific calls.
  • +
  • Improved support for classes using ObjectInputFields to follow the serialization specification.
  • +
  • JIRA:XSTR-179 Support for ObjectInputStream.registerValidation(ObjectInputValidation).
  • +
  • JIRA:XSTR-178 Serialized inner class now maintains reference to outer class.
  • +
  • JIRA:XSTR-199 Default ClassLoader may be changed using XStream.setClassLoader().
  • +
+ +

Minor changes

+ +
    +
  • Bugfix: Thread context classloader is loaded by the correct thread. (Thanks to Padraic Renaghan for pointing this out).
  • +
  • Bugfix: Default implementations of aliased classes were not being deserialized by SerializableConverter.
  • +
  • Bugfix: JIRA:XSTR-180 Serializable objects support defaultReadObject() even when no default fields available.
  • +
  • Bugfix: For serialized objects class hierarchy is serialized starting with superclass (as per Java Object Serialization).
  • +
  • Bugfix: readObject() is now called for classes containing only transient fields.
  • +
  • Bugfix: Order of fields are maintained when calling ObjectOutputStream.putFields().
  • +
  • Bugfix: FontConverter extended to support FontUIResource which does some awkward native calls.
  • +
  • Bugfix: Deserialization of very complicated graphs (such as Swing components) sometimes resulted in broken object references. Now fixed.
  • +
  • Bugfix: JIRA:XSTR-188 Classes that use readResolve()/writeReplace() can now return different types.
  • +
  • Bugfix: JIRA:XSTR-185, JIRA:XSTR-195 Support for loading of array classes for classes that have not yet been loaded. (Thanks to Henri Tremblay and Simon Daniel)
  • +
  • Bugfix: JIRA:XSTR-190 PrettyPrintWriter and CompactWriter escape characters in XML attributes.
  • +
  • Bugfix: JIRA:XSTR-176, JIRA:XSTR-196 The XStream ObjectInputStream and ObjectOutputStream implementations now propegate the flush() and close() events to the underlying streams.
  • +
  • Bugfix: JIRA:XSTR-192 Implicit collection mappings are now supported in inheritance hierarchies.
  • +
+ +

API changes

+ +
    +
  • ClassMapper is now deprecated. Replaced with MapperWrapper.
  • +
  • HierarchicalStreamWriter implementations must now implement close(), flush() and underlyingWriter().
  • +
  • HierarchicalStreamReader implementations must now implement close() and underlyingReader().
  • +
+ +

Version 1.1

+ +

Released January 15, 2005. Focus on support for objects defining custom serialization using the standard + Java serialization mechanism.

+ +

Major changes

+ +
    +
  • Provides drop in replacement for ObjectInputStream and ObjectOutputStream, using XStream.createObjectInputStream() and + XStream.createObjectOutputStream() and XStream.createObjectInputStream(). This provides support for streaming objects.
  • +
  • Support for objects that specify their own serialization schemes by implementing readObject() and writeObject() + (as in Java serialization spec). This includes support for ObjectInputStream.getFields() and ObjectOuputStream.putFields().
  • +
  • Support for objects to serialize other objects to the stream by implementing writeReplace() (as in Java serialization spec).
  • +
  • Support for any object that performs custom serialization by implementing java.io.Externalizable (as in Java serialization spec).
  • +
  • Implicit collections can be specified for classes, allowing the element wrapping the collection to be skipped.
  • +
  • New writer implementations to allow XStream to serialize directly to a SAX stream or TrAX pipeline.
  • +
  • The MarshallingContext and UnmarshallingContext interfaces now extend DataHolder, allowing arbitrary data to be stored + by the user whilst walking the object graph and passed around to Converters. DataHolders can also be passed into + XStream from the outside.
  • +
  • Includes new DomWriter implementation to serialize directly to a W3C DOM tree (to complement the existing DomReader).
  • +
  • Better support for instantiating objects on non Sun 1.4+ JVMs, including non-public constructors, private static inner classes and + ANY class that implements java.io.Serializable.
  • +
  • DOM, DOM4J, JDOM, XOM, Electric-XML, SAX, STAX
  • +
  • Specific ClassLoaders can be passed into XStream, to allow for greater compatibility in J2EE containers.
  • +
  • Ability to change the default converter
  • +
  • Added optional ISO8601DateConverter for full ISO8601 date format support. The converter is not registered by default + as it requires the joda-time dependency (http://joda-time.sf.net). To use, ensure joda-time is in classpath and register explicitly.
  • +
  • Enhanced mode is now supported on the Apple 1.4 JDK.
  • +
+ +

Minor changes

+ +
    +
  • PrettyPrintWriter only flushes stream when necessary - large performance improvement for serialization.
  • +
  • Added XStream.fromXml(xml, root) convenience methods for deserializing into an existing root object.
  • +
  • JDK 1.3 compatibility: Added mechanism for accessing nested exception.
  • +
  • JDK 1.3 compatibility: GregorianCalendarConverter only calls Calendar.getTimeInMillis() the JDK supports it.
  • +
  • Bugfix: All caches are now synchronized - there were some thread safety issues.
  • +
  • Bugfix: Only immutable basic types will have references ignored in XML (for clarity).
  • +
  • Bugfix: Class names can contain underscores.
  • +
  • Bugfix: Support for '\0' char.
  • +
  • Bugfix: PropertyConverter no longer attempts to serialize subclasses of Properties.
  • +
  • Bugfix: JVM detection uses system properties, which is more accurate than searching the classpath.
  • +
+ +

API changes

+ +
    +
  • XStream.addDefaultCollection() has been deprecated. Use XStream.addImplicitCollection() instead.
  • +
+ +

Version 1.0.2

+ +

Released August 7, 2004. Focus on improving the converters bundled with XStream to support a wider range of types.

+ +

Major changes

+ +
    +
  • XML elements are written in order they are defined in class, rather than alphabetical.
  • +
  • Converters for java.io.File, java.sql.Timestamp, java.awt.Color, and dynamic proxies are now + registered by default.
  • +
  • EncodedByteArrayConverter is now registered by default and uses a single Base64 string to store the contents + of a byte[]. This now works on all JVMs as it no longer relies on Sun specific classes. This converter will also + unmarshal byte[] that have been serialized without it, for backwards compatability.
  • +
  • New converters for java.sql.Time, java.sql.Date, java.util.Locale, java.util.Currency, java.util.Calendar + and java.awt.Font.
  • +
  • All caching is done in XStream instance instead of statics, allowing applications that use hot redeployment + of classes to use XStream in a parent classloader.
  • +
  • XStream will fail fast if a field value is defined more than once in XML when deserializing.
  • +
+ +

Minor changes

+ +
    +
  • The <entry> element used in Maps can now be specified by creating an alias for java.util.Map.Entry.
  • +
  • Bugfix: Fields with characters that generate invalid XML (such as $ signs) are now escaped.
  • +
  • Bugfix: Pre-instantiated objects can be unmarshalled through multiple levels.
  • +
+ +

API changes

+ +
    +
  • None.
  • +
+ +

Version 1.0.1

+ +

Released May 30, 2004. Misc features and bugfixes.

+ +

Major changes

+ +
    +
  • Support for multidimensional arrays.
  • +
  • Object with readResolve() method will be treated the same way native serialization treats them.
  • +
+ +

Minor changes

+ +
    +
  • New converters for Throwable and StackTraceElement that retain stack trace (JDK 1.4 only)
  • +
  • Bugfix: System.identityHashCode() is not guaranteed to be unique. Ensure reference checking is used as well.
  • +
  • Bugfix: Allows user classes to be defined in WEB-INF/classes in Servlet environments. Tries to use context classloader if available.
  • +
  • Support for java.util.Currency (through readResolve()).
  • +
  • Instances of Jakarta Commons Lang Enum are now reused (through readResolve()).
  • +
  • Bugfix: JavaClassConverter handles primitive type classes (contributed by Matthew Sandoz).
  • +
+ +

API changes

+ +
    +
  • Additional method: ConverterLookup.defaultConverter(). Custom implementations of this class should implement + this new method.
  • +
+ +

Version 1.0

+ +

Released May 14, 2004. Focusses on finalizing the API for 1.0 release.

+ +

Major changes

+ +
    +
  • Supports fields of same name, hidden by inheritance.
  • +
+ +

Minor changes

+ +
    +
  • JavaDoc for most important parts of API.
  • +
+ +

API changes

+ +
    +
  • The ReflectionConverter and ReflectionProviders have had an overhaul to support + hidden fields. Most methods now take an extra argument to specify which class a field + is declared in.
  • +
+ +

Version 1.0 (release candidate 1)

+ +

Released May 9, 2004. Focusses on finalizing the API for 1.0 release.

+ +

Major changes

+ +
    +
  • JDK 1.3 compatibility.
  • +
  • Informative error messages.
  • +
  • Defaults to using faster XPP based parser.
  • +
  • Serializes final field under JDK 1.4.
  • +
  • Fail fast when trying to serialize final field if not Sun 1.4 JRE.
  • +
+ +

Minor changes

+ +
    +
  • Misc performance improvements.
  • +
  • Converters for TreeMap and TreeSet that store the Comparator.
  • +
+ +

API changes

+ +
    +
  • Default constructor for XStream class uses XppDriver instead of DomDriver. + To use DomDriver, explicitly pass it in to the constructor.
  • +
  • Exception is thrown if trying to serialize an object that contains a + final field if not Sun 1.4 JRE.
  • +
+ +

About XStream version numbers...

+ +

Version 0.6

+ +

Released May 7, 2004. Focusses on providing full object graph support.

+ +

Major changes

+ +
    +
  • None.
  • +
+ +

Minor changes

+ +
    +
  • Bugfix: Objects that had no children could not be derefenced properly (thanks to Brian Slesinsky and Nick Pomfret).
  • +
  • Bugfix: DateConverter is now thread safe.
  • +
  • Optimization: String instances are reused as much as possible.
  • +
  • Converters for BigInteger and BigDecimal.
  • +
  • IntConverter now recognises hexadecimal and octal notations (thanks to Konstantin Pribluda).
  • +
+ +

API changes

+ +
    +
  • None.
  • +
+ +

Version 0.6 (release candidate 1)

+ +

Released April 19, 2004. Focusses on providing full object graph support.

+ +

Major changes

+ +
    +
  • Full support for object graphs, including duplicate references of same object and + circular references.
  • +
  • References can be identified using XPath (default), unique-IDs or disabled.
  • +
+ +

Minor changes

+ +
    +
  • Release includes Ant build file.
  • +
  • Converters for non standard collections such as Collections.EMPTY_LIST, syncronizedList(), unmodifiableMap(), etc.
  • +
  • Converter for nulls.
  • +
  • Converter for dynamic proxies.
  • +
  • Converter for java.net.URL.
  • +
  • Converters for java.util.LinkedHashMap and java.util.LinkedHashSet.
  • +
  • Converters for java.lang.reflect.Method and java.lang.reflect.Constructor.
  • +
  • If duplicate reference support is disabled and a circular reference is encountered, an exception will be thrown.
  • +
+ +

API changes

+ +
    +
  • None.
  • +
+ +

Version 0.5

+ +

Released March 8, 2004. Focussed on performance.

+ +

Major changes

+ +
    +
  • Massive performance improvements. Up to 3 times faster for serialization and 22 + times faster for deserialization!
  • +
  • Non-DOM building pull parser based reader. Results in much smaller memory footprint, + particularly when deserializing large object models.
  • +
+ +

Minor changes

+ +
    +
  • Misc performance improvements.
  • +
  • Misc bugfixes.
  • +
  • Alternate encodings can be used with DomDriver.
  • +
+ +

API changes

+ +
    +
  • Renamed XMLReader/Writer to HierarchicalStreamReader/Writer as XStream is not + actually coupled to serializing just to XML.
  • +
  • Cleaned up the public API.
  • +
  • Moved internal XStream implementation classes to core package.
  • +
  • Misc package/class renames to make more sense. Dumped lots of dead code.
  • +
+ +

Version 0.4

+ +

This version was never publicly released. All changes were made available in 0.5. Focussed on making it easier to create custom converters.

+ +

Major changes

+ +
    +
  • Overhaul of interface for Converters. Makes Converters much cleaner to write.
  • +
+ +

Minor changes

+ +
    +
  • Added custom converters for java.io.File, java.util.Properties, java.util.Vector, java.util.Hashtable, java.util.BitSet + byte[] (Base64 encoded), char[].
  • +
  • Misc bugfixes.
  • +
+ +

API changes

+ +
    +
  • New interface to be implemented by custom converters.
  • +
+ +

Version 0.3

+ +

Released January 1, 2004.

+ +

Major changes

+ +
    +
  • Added ElementMapper interface and default implementations to allow fine + grained control over element name to class mapper operations.
  • +
  • Added an XPP based reader and writer that uses a pull-parser to create a lightweight DOM tree.
  • +
+ +

Minor changes

+ +
    +
  • Added XStream.fromXML(XMLReader xmlReader,Object root) method to + allow the population of an object graph starting with a live object root.
  • +
  • Added XMLReader.peek() method to allow access to the underlying hierarchical + object being unmarshalled.
  • +
+ +

API changes

+ +
    +
  • Aligned the the methods in XStream to use the specified ObjectFactory in the constructor + instead of creating a SunReflectionObjectFactory.
  • +
+ +

Older versions

+ +

Changes in XStream prior to version 0.3 were not logged.

+ + + diff --git a/xstream-distribution/src/content/converter-tutorial.html b/xstream-distribution/src/content/converter-tutorial.html new file mode 100644 index 0000000..28a2709 --- /dev/null +++ b/xstream-distribution/src/content/converter-tutorial.html @@ -0,0 +1,600 @@ + + + + Converter Tutorial + + + +

Simple Converter

+

Setting up a simple example

+ +

This is the most basic converter... let's start with a simple Person:

+
package com.thoughtworks.xstream.examples;
+
+public class Person {
+
+        private String name;
+
+        public String getName() {
+                return name;
+        }
+
+        public void setName(String name) {
+                this.name = name;
+        }
+
+}

So let's create a person and convert it to +XML...

package com.thoughtworks.xstream.examples;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.DomDriver;
+
+public class PersonTest {
+
+        public static void main(String[] args) {
+                Person person = new Person();
+                person.setName("Guilherme");
+
+                XStream xStream = new XStream(new DomDriver());
+                System.out.println(xStream.toXML(person));
+        }
+
+}

This results in a really ugly XML code which contains the full +class name (including +package)...

<com.thoughtworks.xstream.examples.Person>
+  <name>Guilherme</name>
+</com.thoughtworks.xstream.examples.Person>

So we make use +of an 'alias' to change this full class name to something more 'human', for +example +'person'.

XStream xStream = new XStream(new DomDriver());
+xStream.alias("person", Person.class);
+System.out.println(xStream.toXML(person));

And the outcome is +much easier to read (and +smaller):

<person>
+  <name>Guilherme</name>
+</person>

Now that we have configured a simple class to +play with, let's see what XStream converters can do for us...

+ +

Creating a PersonConverter

+

Let's create a simple converter capable +of:

    +
  1. telling its capable of converting Person's
  2. +
  3. translating a Person instance in XML
  4. +
  5. translate XML into a new Person
  6. +

We begin creating the PersonConverter class and implementing the +Converter +interface:

package com.thoughtworks.xstream.examples;
+
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+
+public class PersonConverter implements Converter {
+
+        public boolean canConvert(Class clazz) {
+                return false;
+        }
+
+        public void marshal(Object value, HierarchicalStreamWriter writer,
+                        MarshallingContext context) {
+        }
+
+        public Object unmarshal(HierarchicalStreamReader reader,
+                        UnmarshallingContext context) {
+                return null;
+        }
+
+}

Now we tell whoever calls us that we can handle only Person's +(and nothing else, including those classes which extends +Person).

public boolean canConvert(Class clazz) {
+        return clazz.equals(Person.class);
+}

The second step is usually quite clean, unless you are dealing +with generic converters.

The marshal method is responsible for +translating an object to XML. It receives three +arguments:

    +
  1. the object we are trying to convert
  2. +
  3. the writer were we should output the data
  4. +
  5. the current marshalling context
  6. +

We start casting the object to +person:

Person person = (Person) value;

Now +we can output the data... let's start creating a node called fullname +and adding the person's name to +it:

writer.startNode("fullname");
+writer.setValue(person.getName());
+writer.endNode();

Quite simple +huh?

public void marshal(Object value, HierarchicalStreamWriter writer,
+                MarshallingContext context) {
+        Person person = (Person) value;
+        writer.startNode("fullname");
+        writer.setValue(person.getName());
+        writer.endNode();
+}

We could have called start/end node as many times as we would +like (but remember to close everything you open)... and conversion usually +takes place when calling the setValue method.

And now let's go to +the unmarshal. We use the moveDown and moveUp methods to move +in the tree hierarchy, so we can simply moveDown, read the value and +moveUp.

                Person person = new Person();
+                reader.moveDown();
+                person.setName(reader.getValue());
+                reader.moveUp();

Which gives us the following +converter:

package com.thoughtworks.xstream.examples;
+
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+
+public class PersonConverter implements Converter {
+
+        public boolean canConvert(Class clazz) {
+                return clazz.equals(Person.class);
+        }
+
+        public void marshal(Object value, HierarchicalStreamWriter writer,
+                        MarshallingContext context) {
+                Person person = (Person) value;
+                writer.startNode("fullname");
+                writer.setValue(person.getName());
+                writer.endNode();
+        }
+
+        public Object unmarshal(HierarchicalStreamReader reader,
+                        UnmarshallingContext context) {
+                Person person = new Person();
+                reader.moveDown();
+                person.setName(reader.getValue());
+                reader.moveUp();
+                return person;
+        }
+
+}

Now let's register our converter and see how our application +main method looks +like:

package com.thoughtworks.xstream.examples;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.DomDriver;
+
+public class PersonTest {
+
+        public static void main(String[] args) {
+                Person person = new Person();
+                person.setName("Guilherme");
+
+                XStream xStream = new XStream(new DomDriver());
+                xStream.registerConverter(new PersonConverter());
+                xStream.alias("person", Person.class);
+                System.out.println(xStream.toXML(person));
+        }
+
+}

Did you notice how we registered our converter? It's a simple +call to +registerConverter:

xStream.registerConverter(new PersonConverter());

The +final result +is:

<person>
+  <fullname>Guilherme</fullname>
+</person>

So you might say... that only changed my tree, I +want to convert data!

Try using an attribute called fullname in +the person tag instead of creating a new child node.

+ +

An alternative for types with String representation

+ +

Let's enhance the Person with a String representation, that contains all necessary +text to recreate the instance:

+
package com.thoughtworks.xstream.examples;
+
+public class Person {
+
+        private String name;
+
+        public String getName() {
+                return name;
+        }
+
+        public void setName(String name) {
+                this.name = name;
+        }
+
+        public String toString() {
+                return getName();
+        }
+}

In this case we can simplify our Converter to

+
package com.thoughtworks.xstream.examples;
+
+import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter;
+
+public class PersonConverter extends AbstractSingleValueConverter {
+
+        public boolean canConvert(Class clazz) {
+                return clazz.equals(Person.class);
+        }
+
+        public Object fromString(String str) {
+                Person person = new Person();
+                person.setName(string);
+                return person;
+        }
+
+}

But even nicer, our XML is also simplified (using the alias for the +Person class). Since the String representation is complete, a nested element is not +necessary anymore:

+
<person>Guilherme</person>
+ +

Note, that in implementation of a SingleValueConverter is required for +attributes, since these objects have to be represented by a single string only.

+ +

Date Converter

+

Now that we know how the Converter interface works, let's create a +simple calendar converter which uses the locale to convert the +information.

Our converter will receive the Locale in its constructor +and we will keep a reference to it in a member +variable:

package com.thoughtworks.xstream.examples;
+
+import java.util.Locale;
+
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+
+public class DateConverter implements Converter {
+
+        private Locale locale;
+
+        public DateConverter(Locale locale) {
+                super();
+                this.locale = locale;
+        }
+
+        public boolean canConvert(Class clazz) {
+                return false;
+        }
+
+        public void marshal(Object value, HierarchicalStreamWriter writer,
+                        MarshallingContext context) {
+        }
+
+        public Object unmarshal(HierarchicalStreamReader reader,
+                        UnmarshallingContext context) {
+                return null;
+        }
+
+}

Now let's convert anything which extends Calendar: +means if instances of class clazz can be assigned to the +Calendar class, they extends the abstract class +Calendar:

public boolean canConvert(Class clazz) {
+        return Calendar.class.isAssignableFrom(clazz);
+}

Let's go for converting a Calendar in a localized +string... we first cast the object to Calendar, extract its Date +and then use a DateFormat factory method to get a date converter to our +localized +string.

public void marshal(Object value, HierarchicalStreamWriter writer,
+                MarshallingContext context) {
+
+        Calendar calendar = (Calendar) value;
+
+        // grabs the date
+        Date date = calendar.getTime();
+
+        // grabs the formatter
+        DateFormat formatter = DateFormat.getDateInstance(DateFormat.FULL,
+                        this.locale);
+
+        // formats and sets the value
+        writer.setValue(formatter.format(date));
+
+}

And the other way around... in order to unmarshall, we create +a GregorianCalendar, retrieves the localized DateFormat +instance, parses the string into a Date and puts this date in the +original +GregorianCalendar:

public Object unmarshal(HierarchicalStreamReader reader,
+                UnmarshallingContext context) {
+
+        // creates the calendar
+        GregorianCalendar calendar = new GregorianCalendar();
+
+        // grabs the converter
+        DateFormat formatter = DateFormat.getDateInstance(DateFormat.FULL,
+                        this.locale);
+
+        // parses the string and sets the time
+        try {
+                calendar.setTime(formatter.parse(reader.getValue()));
+        } catch (ParseException e) {
+                throw new ConversionException(e.getMessage(), e);
+        }
+
+        // returns the new object
+        return calendar;
+
+}

Note 1: remember that some DateFormat implementations +are not thread-safe, therefore don't put your formatter as a member of your +converter.

Note 2: this implementation will convert other types +of Calendar's to GregorianCalendar after save/load. If this is not what you +want, change your canConvert method to return true only if +class equals GregorianCalendar.

So we get the following +converter:

package com.thoughtworks.xstream.examples;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+
+import com.thoughtworks.xstream.converters.ConversionException;
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+
+public class DateConverter implements Converter {
+
+        private Locale locale;
+
+        public DateConverter(Locale locale) {
+                super();
+                this.locale = locale;
+        }
+
+        public boolean canConvert(Class clazz) {
+                return Calendar.class.isAssignableFrom(clazz);
+        }
+
+        public void marshal(Object value, HierarchicalStreamWriter writer,
+                        MarshallingContext context) {
+                Calendar calendar = (Calendar) value;
+                Date date = calendar.getTime();
+                DateFormat formatter = DateFormat.getDateInstance(DateFormat.FULL,
+                                this.locale);
+                writer.setValue(formatter.format(date));
+        }
+
+        public Object unmarshal(HierarchicalStreamReader reader,
+                        UnmarshallingContext context) {
+                GregorianCalendar calendar = new GregorianCalendar();
+                DateFormat formatter = DateFormat.getDateInstance(DateFormat.FULL,
+                                this.locale);
+                try {
+                        calendar.setTime(formatter.parse(reader.getValue()));
+                } catch (ParseException e) {
+                        throw new ConversionException(e.getMessage(), e);
+                }
+                return calendar;
+        }
+
+}

And let's try it out. We create a DateTest class with a +main method:

    +
  1. creates a calendar (current date)
  2. +
  3. creates the XStream object
  4. +
  5. registers the converter with a Brazilian Portuguese locale
  6. +
  7. translates the object in XML
  8. +
+

Well, we already know how to do all those steps... so let's go:

+
package com.thoughtworks.xstream.examples;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.DomDriver;
+
+public class DateTest {
+
+        public static void main(String[] args) {
+
+                // grabs the current date from the virtual machine
+                Calendar calendar = new GregorianCalendar();
+
+                // creates the xstream
+                XStream xStream = new XStream(new DomDriver());
+
+                // brazilian portuguese locale
+                xStream.registerConverter(new DateConverter(new Locale("pt", "br")));
+
+                // prints the result
+                System.out.println(xStream.toXML(calendar));
+
+        }
+
+}

The result? Well... it depends, but it will be something +like:

<gregorian-calendar>Sexta-feira, 10 de Fevereiro de 2006</gregorian-calendar>

Note: +we did not put any alias as gregorian-calendar is the default alias for +GregorianCalendar.

And now let's try to unmarshal the result +shown +above:

// loads the calendar from the string
+Calendar loaded = (Calendar) xStream
+                .fromXML("<gregorian-calendar>Sexta-feira, 10 de Fevereiro de 2006</gregorian-calendar>");

And +print it using the system locale, short date +format:

// prints using the system defined locale
+System.out.println(DateFormat.getDateInstance(DateFormat.SHORT).format(
+                loaded.getTime()));

The result might be +something like (if your system locale is American +English):

2/10/06
+ +

Complex Converter

+

Setting up another example

+ +

We already defined some classes, so let them glue together:

+
package com.thoughtworks.xstream.examples;
+
+public class Birthday {
+
+        private Person person;
+        private Calendar date;
+        private char gender;
+
+        public Person getPerson() {
+                return person;
+        }
+
+        public void setPerson(Person person) {
+                this.person = person;
+        }
+
+        public Calendar getDate() {
+                return date;
+        }
+
+        public void setDate(Calendar date) {
+                this.date = date;
+        }
+        
+        public char getGender() {
+                return gender;
+        }
+
+        public void setGenderMale() {
+                this.gender = 'm';
+        }
+
+        public void setGenderFemale() {
+                this.gender = 'f';
+        }
+
+}

While XStream is capable of converting this class without any problem, we write our own custom converter +just for demonstration. This time we want to reuse our already written converters for the Person and the Calendar and add an +own attribute for the gender. The canConvert method is plain simple. We convert no derived classes this time, +since they might have additional fields. But we reuse the converters registered in XStream for our member fields and handle +null values: +

package com.thoughtworks.xstream.examples;
+
+import java.util.Calendar;
+
+import com.thoughtworks.xstream.converters.ConversionException;
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+
+public class BirthdayConverter implements Converter {
+
+        public boolean canConvert(Class clazz) {
+                return Birthday.class == clazz;
+        }
+
+        public void marshal(Object value, HierarchicalStreamWriter writer,
+                        MarshallingContext context) {
+                Birthday birthday = (Birthday)value;
+                if (birthday.getGender() != '\0') {
+                        writer.addAttribute("gender", Character.toString(birthday.getGender()));
+                }
+                if (birthday.getPerson() != null) {
+                        writer.startNode("person");
+                        context.convertAnother(birthday.getPerson());
+                        writer.endNode();
+                }
+                if (birthday.getDate() != null) {
+                        writer.startNode("birth");
+                        context.convertAnother(birthday.getDate());
+                        writer.endNode();
+                }
+        }
+
+        public Object unmarshal(HierarchicalStreamReader reader,
+                        UnmarshallingContext context) {
+                Birthday birthday = new Birthday();
+                String gender = reader.getAttribute("gender");
+                if (gender != null) {
+                        if (gender.length() > 0) {              
+                                if (gender.char(0) == 'f') {
+                                        birthday.setGenderFemale();
+                                } else if (gender.char(0) == 'm') {
+                                        birthday.setFemale();
+                                } else {
+                                        throw new ConversionException("Invalid gender value: " + gender);
+                                }
+                        } else {
+                                throw new ConversionException("Empty string is invalid gender value");
+                        }
+                }
+                while (reader.hasMoreChildren()) {
+                        reader.moveDown();
+                        if ("person".equals(reader.getNodeName())) {
+                                Person person = (Person)context.convertAnother(birthday, Person.class);
+                                birthday.setPerson(person);
+                        } else if ("birth".equals(reader.getNodeName())) {
+                                Calendar date = (Calendar)context.convertAnother(birthday, Calendar.class);
+                                birthday.setDate(date);
+                        }
+                        reader.moveUp();
+                }
+                return birthday;
+        }
+
+}

The unmarshal method ensures the valid value for the gender by throwing a +ConversionException for invalid entries.

+ +

Note, that attributes will always have to be written and read first. You work on a stream and +accessing the value of a tag or its members will close the surrounding tag (that is still active when the method is +called).

+ +

If the implementation of Birthday ensures, that none of its fields +could hold a null value and gender contains a valid value, then we could drop the +null condition in the marshal method and in unmarshal +we could omit the loop as well as the comparison of the tag names:

package com.thoughtworks.xstream.examples;
+
+import java.util.Calendar;
+
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+
+public class BirthdayConverter implements Converter {
+
+        public boolean canConvert(Class clazz) {
+                return Birthday.class == clazz;
+        }
+
+        public void marshal(Object value, HierarchicalStreamWriter writer,
+                        MarshallingContext context) {
+                Birthday birthday = (Birthday)value;
+                writer.addAttribute("gender", Character.toString(birthday.getGender()));
+                writer.startNode("person");
+                context.convertAnother(birthday.getPerson());
+                writer.endNode();
+                writer.startNode("birth");
+                context.convertAnother(birthday.getDate());
+                writer.endNode();
+        }
+
+        public Object unmarshal(HierarchicalStreamReader reader,
+                        UnmarshallingContext context) {
+                Birthday birthday = new Birthday();
+                if (reader.getAttribute("gender").charAt(0) == 'm') {
+                        birthday.setGenderMale();
+                } else {
+                        birthday.setGenderFemale();
+                }
+                reader.moveDown();
+                Person person = (Person)context.convertAnother(birthday, Person.class);
+                birthday.setPerson(person);
+                reader.moveUp();
+                reader.moveDown();
+                Calendar date = (Calendar)context.convertAnother(birthday, Calendar.class);
+                birthday.setDate(date);
+                reader.moveUp();
+                return birthday;
+        }
+
+}
+ + \ No newline at end of file diff --git a/xstream-distribution/src/content/converters.html b/xstream-distribution/src/content/converters.html new file mode 100644 index 0000000..a7aab01 --- /dev/null +++ b/xstream-distribution/src/content/converters.html @@ -0,0 +1,957 @@ + + + + Converters + + + + +

The core of XStream consists of a registry of + Converters. The responsibility + of a Converter is to provide a strategy for converting particular types of objects found in the object graph, + to and from XML.

+ +

XStream is provided with Converters for common types such as primitives, String, File, Collections, arrays, + and Dates. The following table lists any converter delivered with XStream and documents, if they are + registered by default with which priority.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

java.lang (and core special types)

ConverterSupported typesExampleNotesPrio
NullConverternull values<null/>Usually, null fields are left out of the XML, however when used in arrays or the root object they + have to be explicitly marked.very high
ArrayConverterany kind of array + <string-array>
+   <string>apple</string>
+   <string>banana</string>
+   <string>cabbage</string>
+ <string-array> +
This supports arrays of primitives as well as objects. It also supports multi-dimensional arrays, even if + they are non-rectangular.normal
BooleanConverterboolean
java.lang.Boolean
<boolean>true</boolean>Can also be registered locally using different values.normal
ByteConverterbyte
java.lang.Byte
<byte>22</byte>The byte is represented as an integer.normal
EncodedByteArrayConverterbyte[]<byte-array>AHiEFiEABQ==</byte-array>Uses Base64 encoding to store binary data in XML. Converter can be registered globally or locally.normal
CharConverterchar
java.lang.Character
<char>X</char>
<char null="true"/>
The '\0' character is invalid in XML.normal
CharArrayConverterchar[]<char-array>hello<char-array>Joins all characters into a single String.normal
DoubleConverterdouble
java.lang.Double
<double>456774543443.4553435</double> normal
FloatConverterfloat
java.lang.Float
<float>4563443.435</float> normal
IntConverterint
java.lang.Integer
<int>12345678</int> normal
LongConverterlong
java.lang.Long
<long>2344556678888786</long> normal
NamedArrayConverterany kind of array + <string-array>
+   <product>apple</product>
+   <product>banana</product>
+   <product>cabbage</product>
+ <string-array> +
This supports arrays of primitives as well as objects. It also supports multi-dimensional arrays, even if + they are non-rectangular. Should be registered locally or for an individual array type. 
ShortConvertershort
java.lang.Short
<short>1445</short> normal
StringConverterjava.lang.String<string>hello world</string>This converter can be registered with different caching strategies.normal
StringBufferConverterjava.lang.StringBuffer<string-buffer>hello world</string-buffer> normal
StringBuilderConverterjava.lang.StringBuilder<string-builder>hello world</string-builder>Available under Java 1.5 or greater.normal
ThrowableConverterjava.lang.Throwable
java.lang.Exception
java.lang.RuntimeException
java.lang.Error
...and all subclasses + of these.
+ <java.io.IOException>
+   <detailMessage>No file</detailMessage>
+   <stack-trace>
+     <trace>com.x.Foo.stuff(Foo.java:22)</trace>
+     <trace>com.x.Foo.blah(Foo.java:31)</trace>
+     <trace>com.x.Foo.main(Foo.java:43)</trace>
+   </stack-trace>
+ </java.io.IOException> +
This is only available under Java 1.4 or greater. It retains the full stack trace, including that of any + nested exceptions. The stack trace elements are handled by the + StackTraceElementConverter.normal
EnumConverterjava.lang.Enum<java.lang.annotation.RetentionPolicy>
CLASS
</java.lang.annotation.RetentionPolicy>
Available under Java 1.5 or greater.normal
EnumToStringConverterjava.lang.EnumThe Converter must be initialized with an Enum type and an optional mapping between strings and enum values. By default + it will use the Enum's string representation as value.Available under Java 1.5 or greater. Must be registered explicitly for the Enum type or locally. 

java.util

ConverterSupported typesExampleNotesPrio
CollectionConverterjava.util.ArrayList
java.util.LinkedList
java.util.HashSet
java.util.Vector
java.util.LinkedHashSet
+ <linked-list>
+   <string>apple</string>
+   <string>banana</string>
+   <big-decimal>12345.4555</big-decimal>
+ </linked-list> +
The objects inside the collection can be any type of objects, including nested collections. Can be + registered for an individual Collection type or locally, suppression of implicit type might be + necessary.normal
MapConverterjava.util.HashMap
java.util.Hashtable
java.util.LinkedHashMap
java.util.concurrent.ConcurrentHashMap
+ <map>
+   <entry>
+     <string>apple</string>
+     <float>123.553</float>
+   </entry>
+   <entry>
+     <string>orange</string>
+     <float>55.4</float>
+   </entry>
+ </map> +
Both key and values can be any type of objects. Can be registered for an individual Map type or + locally, suppression of implicit type might be necessary.normal
NamedCollectionConverterjava.util.ArrayList
java.util.LinkedList
java.util.HashSet
java.util.Vector
java.util.LinkedHashSet
+ <linked-list>
+   <string>apple</string>
+   <string>banana</string>
+   <big-decimal>12345.4555</big-decimal>
+ </linked-list> +
The objects inside the collection can be any type of objects, including nested collections. Should + be registered locally or for an individual Collection type. 
NamedMapConverterjava.util.HashMap
java.util.Hashtable
java.util.LinkedHashMap
java.util.concurrent.ConcurrentHashMap
+ <map>
+   <fruit>
+     <name>apple</name>
+     <price>123.553</price>
+   </fruit>
+   <fruit>
+     <name>orange</name>
+     <price>55.4</price>
+   </fruit>
+ </map> +
Both key and values can be any type of objects. If key or value are written as attributes or if + the value is written as text of the entry element, those types must be handled by a + SingleValueConverter. Should be registered locally or for an individual Map type. 
PropertiesConverterjava.util.Properties + <properties>
+   <property name="host" value="localhost"/>
+   <property name="port" value="888"/>
+ </properties> +
Because the Properties class only accepts Strings for keys and values, the XML can be more concise. + If the Properties instance includes a set of default Properties, these are serialized in a nested <defaults> element.normal
SingletonCollectionConverterjava.util.Collections.singletonList().getClass()
java.util.Collections.singleton().getClass()
+ <singleton-set>
+   <string>apple</string>
+ </singleton-set> +
The objects inside the singleton collection can be any type of objects, including nested collections.normal
SingletonMapConverterjava.util.Collections.singletonMap().getClass() + <singleton-map>
+   <entry>
+     <string>apple</string>
+     <float>123.553</float>
+   </entry>
+ </singleton-map> +
The objects inside the singleton collection can be any type of objects, including nested collections.normal
TreeMapConverterjava.util.TreeMap + <tree-map>
+   <comparator class="com.blah.MyComparator"/>
+   <entry>
+     <string>apple</string>
+     <float>123.553</float>
+   </entry>
+   <entry>
+     <string>orange</string>
+     <float>55.4</float>
+   </entry>
+ </tree-map> +
This is similar to MapConverter with an additional field for storing the java.util.Comparator associated with the TreeMap.normal
TreeSetConverterjava.util.TreeSet + <tree-set>
+   <comparator class="com.blah.MyComparator"/>
+   <string>apple</string>
+   <string>banana</string>
+   <string>cabbage</string>
+ </tree-set> +
This is similar to CollectionConverter with an additional field for storing the java.util.Comparator associated with the TreeSet.normal
BitSetConverterjava.util.BitSet + <bit-set>0,1,3,5,6,8,10</bit-set> + Stores a comma separated list of which bits are set. Designed to be readable without taking up too much space.normal
DateConverterjava.util.Date<date>2004-02-22 15:16:04.0 UTC</date>Can be registered with different formats, locales or time zone globally or locally.normal
GregorianCalendarConverterjava.util.Calendar
java.util.GregorianCalendar
+ <gregorian-calendar>
+   <time>555454646</time>
+ </gregorian-calendar> +
 normal
ISO8601DateConverterjava.util.Date<date>2006-07-28T12:06:17.654-03:00</date>Not automatically registered, can be used globally or locally. Implementation needs joda-time. 
ISO8601GregorianCalendarConverterjava.util.GregorianCalendar + <gregorian-calendar>
+ 2006-07-28T12:07:02.788-03:00
+ </gregorian-calendar> +
Not automatically registered, can be used globally or locally. Implementation needs joda-time. 
LocaleConverterjava.util.Locale<locale>en_GB</locale> normal
CurrencyConverterjava.util.Currency<currency>USD</currency>Available under Java 1.4 or greater.normal
UUIDConverterjava.util.UUID<uuid>ca05f023-e07f-4956-a6ef-14ddd23df47b</uuid>Available under Java 1.5 or greater.normal
EnumMapConverterjava.util.EnumMap + <enum-map enum-type="simple">
+   <entry>
+     <simple>GREEN</simple>
+     <string>grass</string>
+   </entry>
+   <entry>
+     <simple>BLUE</simple>
+     <string>sky</string>
+   </entry>
+ </enum-map>
Available under Java 1.5 or greater.normal
EnumSetConverterjava.util.EnumSet + <enum-set enum-type="simple">
+   GREEN,BLUE
+ </enum-set>
Available under Java 1.5 or greater.normal
RegexPatternConverterjava.util.regex.Pattern + <java.util.regex.Pattern>
+   <pattern>.*</pattern>
+   <flags>0</flags>
+ </java.util.regex.Pattern> +
Available under Java 1.4 or greater.normal

java.sql

ConverterSupported typesExampleNotesPrio
SqlDateConverterjava.sql.Date<sql-date>1978-08-25</sql-date>Only automatically registered if runtime has JDBC support.normal
SqlTimeConverterjava.sql.Time<sql-time>14:07:33</sql-time>Only automatically registered if runtime has JDBC support.normal
SqlTimestampConverterjava.sql.Timestamp<sql-timestamp>1970-01-01 00:00:01.234</sql-timestamp>Only automatically registered if runtime has JDBC support.normal
ISO8601SqlTimestampConverterjava.sql.Timestamp<sql-timestamp>2006-07-28T12:06:17.654000000-03:00</sql-timestamp>Not automatically registered, can be used globally or locally. Implementation needs joda-time. 

java.math

ConverterSupported typesExampleNotesPrio
BigDecimalConverterjava.math.BigDecimal<big-decimal>342346.445332</big-decimal> normal
BigIntegerConverterjava.math.BigInteger<big-int>23434224556</big-int> normal

java.net

ConverterSupported typesExampleNotesPrio
URIConverterjava.net.URI<uri>mailto:xstream-user.codehaus.org</uri> normal
URLConverterjava.net.URL<url>http://codehaus.org/blah</url> normal

java.io

ConverterSupported typesExampleNotesPrio
FileConverterjava.io.File<file>/stuff/hello.txt</file> normal
SerializableConverterjava.io.Serializable See description at Generalized Converters.low
ExternalizableConverterjava.io.Externalizable + <externalizable-type>
+   <string>apple</string>
+   <int>42</int>
+   <big-decimal>12345.4555</big-decimal>
+ </externalizable-type> +
See description at Generalized Converters.low

java.nio

ConverterSupported typesExampleNotesPrio
CharsetConverterjava.nio.charset.Charset<charset>US-ASCII</charset>Available under Java 1.4 or greater.normal

java.lang.reflect

ConverterSupported typesExampleNotesPrio
JavaClassConverterjava.lang.Class<class>com.foo.MyThing</class>This converter uses the ClassLoaderReference of the XStream insatance. Can be regisreted with + Mapper globally or locally to respect type aliases.normal
JavaFieldConverterjava.lang.reflect.Field + <field>
+   <name>myField</name>
+   <class>com.foo.MyThing</class>
+ </field> +
This converter uses the ClassLoaderReference of the XStream insatance. Can be regisreted with + Mapper globally or locally to respect type aliases.normal
JavaMethodConverterjava.lang.reflect.Method
java.lang.reflect.Constructor
+ <method>
+   <class>com.foo.MyThing</class>
+   <name>doStuff</name>
+   <parameter-types>
+     <class>java.lang.String</class>
+     <class>java.util.Iterator</class>
+   </parameter-types>
+ </method> +
The enclosing element for this tag will either by <method> or <constructor>. This converter uses the ClassLoaderReference of the XStream insatance. Can be regisreted with + Mapper globally or locally to respect type aliases.normal
DynamicProxyConverterAny dynamic proxy generated by java.lang.reflect.Proxy + <dynamic-proxy>
+   <interface>com.foo.Blah</interface>
+   <interface>com.foo.Woo</interface>
+   <handler class="com.foo.MyHandler">
+     <something>blah</something>
+   </handler>
+ </dynamic-proxy> +
The dynamic proxy itself is not serialized, however the interfaces it implements and the actual InvocationHandler + instance are serialized. This allows the proxy to be reconstructed after deserialization.normal

java.awt

ConverterSupported typesExampleNotesPrio
ColorConverterjava.awt.Color + <awt-color>
+   <red>255</red>
+   <green>255</green>
+   <blue>255</blue>
+   <alpha>255</alpha>
+ </awt-color> +
Only automatically registered if runtime has AWT support.
+ Warning: The AWT toolkit is definitely initialized when a Color is deserialized.
normal
FontConverterjava.awt.Font
+ javax.swing.plaf.FontUIResource
+ <awt-font>
+   <family class="string">Arial</family>
+   <size class="float">20.0</size>
+   <width class="null"/>
+   <posture class="null"/>
+   <weight class="float">2.0</weight>
+   <superscript class="null"/>
+ </awt-font> +
Only automatically registered if runtime has AWT support.
+ Warning: The AWT toolkit is definitely initialized when a Font is deserialized.
normal

java.awt.font

ConverterSupported typesExampleNotesPrio
TextAttributeConverterjava.awt.font.TextAttribute + <awt-text-attribute>family</awt-text-attribute> + Only automatically registered if runtime has AWT support.
+ Warning: The AWT toolkit is definitely initialized when a TextAttribute is deserialized.
normal

javax.swing

ConverterSupported typesExampleNotesPrio
LookAndFeelConverterjavax.swing.LookAndFeel implementations Only automatically registered if runtime has Swing support.normal

javax.security.auth

ConverterSupported typesExampleNotesPrio
SubjectConverterjavax.security.auth.Subject + <auth-subject>
+   <principals>
+     <com.thoughtworks.xstream.Admin/>
+   </principals>
+   <readOnly>false</readOnly>
+ </auth-subject>
+
Available under Java 1.4 or greater. This converter does not serialize any credentials but only the principals.normal

javax.xml.datatype

ConverterSupported typesExampleNotesPrio
DurationConverterjavax.xml.datatype.Duration<duration>PT1H2M</duration>Available under Java 1.5 or greater.normal

Generalized Converters

ConverterSupported typesExplanationNotesPrio
ReflectionConverterAny typeThe Converter is used as fallback. It uses reflection to examine the class and will serialize its fields. very low
AnnotationReflectionConverterAny typeThe Converter is used as fallback. It uses reflection to examine the class and will serialize its fields and supports annotations for + local converters.Needs JDK 1.5, default for JDK 1.5. Deprecated since XStream 1.3 and must be registered now explicitly. 
SerializableConverterjava.io.Serializable or types with one of the serializable methods readObject or writeObjectThe Converter is used for any JDK-serializable types, if not handled by a specialized Converter. low
ExternalizableConverterjava.io.ExternalizableThe Converter is used for any JDK-externalizable types, if not handled by a specialized Converter. low
LambdaConverterFor serializable and non-serializable lambda types. Noon-serialzable lambda instances will be mapped to null, since they + contain no information for recreation. Serializable lambda types have such info, but it is specific to compiler vendor and + occurrence in the code. Never assume that you can deserialize such an element when you use a different version of your code + or a different compiler. Only automatically registered for Java 8.normal
ToAttributedValueConverterAny type with all fields to be represented by a single string but one.The Converter is used to write all but one fields of the type as attributes. The left over field is then used as current value.Must be registered globally or locally for the appropriate type. 
ToStringConverterAny type with natural String representationThe Converter must be initialized with a type, that provides a complete String representation with its toString() method + and is able to be recreated by a constructor taking a single String argument.Must be registered globally or locally for the appropriate type. 
JavaBeanConverterJava beansThe Converter handles any type as Java bean. It expects the type to convert to have a public default constructor and + appropriate getter and setters.Must be registered globally or locally. Can be used as fallback with priority very low. 
PropertyEditorCapableConverterAny type with a PropertyEditor implementationThe Converter can handles any type that provides a PropertyEditor implementation. The PropertyEditor's methods getAsText() and + setAsText() are used to convert between object and string representation.Must be registered globally or locally for the appropriate type. 

Converters for 3rd party classes

ConverterSupported typesExplanationNotesAdd-On
CGLIBEnhancedConverterProxies generated by the CGLIB EnhancerThe Converter handles proxies generated by the CGLIB Enhancer, if there were not multiple callbacks registered. + A proxy with multiple callbacks can currently not be handled at all.Must be registered globally and in combination with the CGLIBMapper. See FAQ.xstream
HibernatePersistentCollectionConverterorg.hibernate.collection.internal.PersistentBag
+ org.hibernate.collection.internal.PersistentList
+ org.hibernate.collection.internal.PersistentSet
+ org.hibernate.envers.entities.mapper.relation.lazy.proxy.ListProxy
+ org.hibernate.envers.entities.mapper.relation.lazy.proxy.SetProxy
The Converter handles Hibernate 4 (or 3) standard collections and Envers proxies. It will handle any element of the collection.Must be registered explicitly in combination with the HibernateMapper and all the other Hibernate converters. See package description.xstream-hibernate
HibernatePersistentMapConverterorg.hibernate.collection.internal.PersistentMap
+ org.hibernate.envers.entities.mapper.relation.lazy.proxy.MapProxy
The Converter handles unsorted Hibernate 4 (or 3) maps or Envers proxy. It will handle any key and value of the map.Must be registered explicitly in combination with the HibernateMapper and all the other Hibernate converters. See package description.xstream-hibernate
HibernatePersistentSortedMapConverterorg.hibernate.collection.internal.PersistentSortedMap
+ org.hibernate.envers.entities.mapper.relation.lazy.proxy.SortedMapProxy
The Converter handles sorted Hibernate 4 (or 3) maps or Envers proxy. It will handle any key and value of the map.Must be registered explicitly in combination with the HibernateMapper and all the other Hibernate converters. See package description.xstream-hibernate
HibernatePersistentSortedSetConverterorg.hibernate.collection.intrernal.PersistentSortedSet
+ org.hibernate.envers.entities.mapper.relation.lazy.proxy.SortedSetProxy
The Converter handles sorted Hibernate 4 (or 3) sets or Envers proxy. It will handle any element of the set.Must be registered explicitly in combination with the HibernateMapper and all the other Hibernate converters. See package description.xstream-hibernate
HibernateProxyConverterorg.hibernate.proxy.HibernateProxyThe Converter handle any element that is wrapped by a Hibernate proxy.Must be registered explicitly in combination with the HibernateMapper and all the other Hibernate converters. See package description.xstream-hibernate
+ + + \ No newline at end of file diff --git a/xstream-distribution/src/content/download.html b/xstream-distribution/src/content/download.html new file mode 100644 index 0000000..0a52b3b --- /dev/null +++ b/xstream-distribution/src/content/download.html @@ -0,0 +1,112 @@ + + + + Download + + + + +

About XStream version numbers...

+ +

Stable Version: 1.4.8

+ +
    +
  • Binary distribution: + Contains the XStream jar files, the Hibernate and Benchmark modules and all the dependencies.
  • +
  • Source distribution: + Contains the complete XStream project as if checked out from the Subversion version tag.
  • +
  • XStream Core only: + The xstream.jar only as it is downloaded automatically when it is referenced as Maven dependency.
  • +
  • XStream Hibernate module: + The xstream-hibernate.jar as it is downloaded automatically when it is referenced as Maven dependency.
  • +
  • XStream Benchmark module: + The xstream-benchmark.jar as it is downloaded automatically when it is referenced as Maven dependency.
  • +
+ +

Latest Snapshot HEAD revision

+ +

Below are builds of the latest HEAD version of XStream from the repository.

+ + + +

Latest Snapshot 1.4.x BRANCH revision

+ +

Below are builds of the latest 1.4.x branch version of XStream from the repository.

+ + + +

Previous Releases

+ +

Previous releases of XStream are also available. However, use of the latest stable version is recommended.

+ + + +

Optional Dependencies

+ +
    +
  • Supported XML parsers and packages: +
      +
    • XmlPull, the XML pull parser API and factory to detect available implementations.
    • +
    • Xpp3, an XML pull parser (recommended).
    • +
    • kXML2 or kXML2-min, an XML pull parser.
    • +
    • DOM4J, easy XML representation and manipulation framework.
    • +
    • JDOM, easy XML representation and manipulation (requires Java 1.2, superseded by JDOM2).
    • +
    • JDOM2, easy XML representation and manipulation, successor of JDOM (requires Java 5).
    • +
    • StaX, the reference implementation of the Streaming API for XML.
    • +
    • Woodstox, an alternate open source StaX implementation.
    • +
    • XOM, another alternative XML API.
    • +
    +
  • +
  • Other optional 3rd party dependencies: +
      +
    • Joda Time for optional ISO8601 date/time formats.
    • +
    • CGLIB for optional support of some proxies generated with the CGLIB Enhancer.
    • +
    • Jettison for serialization and deserialization support with JSON. Note, that newer versions 1.3.x are no longer compatible with XStream.
    • +
    • Jettison 1.0.1 for serialization and deserialization support with JSON in JDK 1.4. Note, that newer version 1.1 is not compatible with XStream.
    • +
    +
  • +
+ +

Dependencies Hibernate Module

+ + + + + diff --git a/xstream-distribution/src/content/faq.html b/xstream-distribution/src/content/faq.html new file mode 100644 index 0000000..4ede3ca --- /dev/null +++ b/xstream-distribution/src/content/faq.html @@ -0,0 +1,767 @@ + + + + Frequently Asked Questions + + + + +
    +
  1. Compatibility
  2. +
  3. Serialization
  4. +
  5. XML specifics
  6. +
  7. JSON specifics
  8. +
  9. Security aspects
  10. +
  11. Comparison to other products
  12. +
  13. Scalability
  14. +
  15. Uses of XStream
  16. +
+ + +

Compatibility

+ + +

Which JDK is required to use XStream?

+

1.4 or later.

+ + +

Which dependencies are required to run XStream?

+

All dependencies are optional, XStream uses since version 1.4.1 by default xpp3:xpp3_min and xmlpull:xmlpull. + However it depends on the use case. XStream will run without dependencies using the DOM driver on all Java runtimes + or the StAX driver in combination with Java 6 or greater. See the list of optional dependencies.

+ + +

Does XStream behave differently across different JVMs?

+ +

XStream has two modes of operation: Pure Java and Enhanced. In pure Java mode, + XStream behaves in the same way across different JVMs, however its features are limited to what + reflection allows, meaning it cannot serialize certain classes or fields. In enhanced mode, + XStream does not have these limitations, however this mode of operation is not available to all JVMs.

+ + +

Which JVMs allow XStream to operate in enhanced mode?

+ +

XStream will check since version 1.4.5 a working enhanced mode dynamically if it is available based on + undocumented internal Java runtime classes. This enhanced mode is known to be working on the Oracle/Sun, Apple, HP, + IBM and Blackdown 1.4 JVMs and onwards, for IcedTea 6 and onwards, for Hitachi, SAP and Diablo from 1.5 and + onwards, for BEA JRockit starting with R25.1.0. Generally it works for all modern Java runtimes based on OpenJDK. + Android basically supports the enhanced mode as well as the Google ApplicationEngine, but the latter's security + model limits the types that can be handled. Note, that an active SecurityManager might prevent the usage of the + enhanced mode also.

+ + +

What are the advantages of using enhanced mode over pure Java mode?

+ +

Currently it is not possible to recreate every instance of a type using the official Java API only. The enhanced mode uses some undocumented, but wide-spread + available functionality to recreate such instances nevertheless. However, in a secured secured environment, older Java run times or a limited Java environment might + prevent the usage of the enhanced mode and XStream uses the plain Java API as fallback. This mode has some restrictions though:

+ + + + + + + + + + + + +
FeaturePure JavaEnhanced Mode
Public classesYesYes
Non public classesNoYes
Static inner classesYesYes
Non-static inner classesNoYes
Anonymous inner classesNoYes
With default constructorYesYes
Without default constructorNoYes
Private fieldsYesYes
Final fieldsYes >= JDK 1.5Yes
+ + +

Why is my application not able to create a XmlPullParser with the XppDriver since XStream 1.4?

+ +

The XML Pull Parser API defines an own mechanism to load the factory for + the available XPP implementation. XStream's XppDriver never used this lookup mechanism automatically before version + 1.4, now it will. Therefore you will have to add a dependency to xmlpull + if the XPP implementation does not deliver the classes on its own. This dependency is necessary for Xpp3 in + contrast to kXML2 that contains the classes. Use the Xpp3Driver or the KXml2Driver if you want to select one of the + directly supported XPP implementation on your own without using the XPP factory. Note, that the minimal version of + kXML2 does not support the XPP factory, but can be used by the KXml2Driver.

+ + +

Can I use XStream in an Android application?

+ +

XStream does work in Android 1.0, but is reported to have limited capabilities. Since XStream 1.4 Android is + treated at least as JDK 5 platform, but it e.g. does not include the java.beans package. Therefore you cannot use + the JavaBeanConverter. Note, that Android provides an XML Pull Parser, therefore XStream can work without + additional dependencies.

+ + +

Which limits exists for XStream in Google's Application Engine (GAE)?

+ +

Starting with XStream 1.4.6 it is possible to instantiate an XStream instance in a GAE environment. Nevertheless + does GAE set some severe restrictions for XStream and therefore XStream will behave differently. Actually a + reflection-based converter cannot handle any type from the JDK itself. Nor is it possible to create an + ObjectInputStream or an ObjectOutputStream. It is not possible to define a field alias for any type within the JDK. + XStream will typically work as general rule, if you process your own objects.

+ + +

Why does XStream fail on Apache Harmony?

+ +

Since JDK 5 it is possible according the Java specification to write into final fields using reflection. This is not yet + supported by Harmony and therefore the PureJavaReflectionProvider fails. We have also already investigated into + enhanced mode in Harmony, but the Harmony JVM crashed running the unit tests. However, Harmony has been retired, + we will no longer make any efforts in this direction.

+ + +

Are there plans to provide enhanced mode support to other JVMs?

+

Yes. Let us know which JVM you would like supported.

+ + +

When should I use XStream not in enhanced mode?

+ +

Running XStream in a secured environment can prevent XStream from running in enhanced mode. This is + especially true when running XStream in an applet. You may also try to use the JavaBeanConverter as alternative to + the ReflectionConverter running in enhanced or pure Java mode.

+ + +

Which permissions does XStream need when running with an active SecurityManager?

+ +

This depends on the mode XStream is running in. Refer to the + SecurityManagerTest + for details. Actually XStream's converters try to check since version 1.4.6 any critical operation, before they + claim to be able to handle a type. As consequence XStream can behave differently running under a SecurityManager. + E.g. if the SecurityManager does not permit to create an instance for a derived class of ObjectOutputStream, the + SerializationConverter will not handle any type and the ReflecitonConverter will take over (as long it has proper + rights for its own reflection-based operations).

+ + +

Why does XStream 1.2 no longer read XML generated with XStream 1.1.x?

+ +

The architecture in XStream has slightly changed. Starting with XStream 1.2 the + HierarchicalStreamDriver + implementation is responsible to ensure that XML tags and attributes are valid names in XML, in XStream 1.1.x + this responsibility was part of the ClassMapper implementations. Under some rare circumstances this will result in + an unreadable XML due to the different processing order in the workflow of such problematic tag names.

+ +

You can run XStream in 1.1 compatibility mode though:

+ +
XStream xstream = new XStream(new XppDriver(new XStream11XmlFriendlyReplacer())) {
+    protected boolean useXStream11XmlFriendlyMapper() {
+        return true;
+    }
+};
+ + +

XStream 1.3 ignores suddenly annotated converters (@XStreamConverter and @XStreamConverters)?

+ +

XStream treats now all annotations the same and therefore it no longer auto-detects any annotation by + default. You can configure XStream to run in auto-detection mode, but be aware if the + implications. As alternative you might register the + deprecated AnnotationReflectionConverter, that was used for XStream pre 1.3.x, but as drawback the functionality + to register a local converter with XStream.registerLocalConverter will no longer work.

+ + +

XStream 1.3 suddenly has a different field order?

+ +

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 + XStream12FieldKeySorter that can be used to + sort the fields according XStream 1.2.2.

+ + + +

Serialization

+ + +

Which class types can be serialized by XStream?

+ +

In contrast to the JDK XStream is not tied to a marker interface to serialize a class. XStream ships with some specialized converters, + but will use reflection by default for "unknown" classes to examine, read and write the class' data. Therefore XStream can handle quite any class, especially + the ones referred as POJO (Plain Old Java Object).

+ +

However, some types of classes exist with typical characteristics, that cannot be handled - at least not out of the box:

+ +
    +
  1. Objects that are based on threads or thread local data: Thread, Timer, ThreadLocal and so on. These classes keep different data for different threads and there's + no possibility to recreate a thread in a generic way nor recreating thread specific data. There might be special use cases, but this will always involve a custom converter + where threads can be recreated in a specific way tied to that use case.
  2. +
  3. Class types that are based on generated classes. Such types have often names that are unique to the current process and will have no meaning + in a different process. A custom converter might help to write the appropriate data into the serializing stream to be able to recreate a equivalent class at deserialization + time.
  4. +
  5. Types that keep and use system resources like file handles, sockets, pipes and so on. ClassLoader, FileInputStream, FileOutputStream, Socket and so on. To + deserialize such a class the converter must be able to claim the appropriate resource from the system again. With the help of a custom converter this might be + possible, but with the reflection converter the deserialized class might refer a system resource that is no longer valid or belongs to somebody else. Behavior is + undefined then.
  6. +
  7. A very special case of such allocated system resources are those classes that keep handles to system memory directly, because they are partly implemented native. + It is known to be true for the Linux version of Sun's JDK that the BufferedImage references some system specific types of the JDK that themselves have member fields + with such memory handles. While it is possible at first sight to serialize and deserialize a BufferedImage, the reflection converter will also duplicate the memory handle. + As a result the JVM might crash easily because of freeing unallocated memory or freeing the same memory twice. It might be possible to create a custom converter, + but the data structure is really complex in this area and nobody has been investigating so far to such an extent. However, do not use the reflection converter + for these types! You have been warned!
  8. +
  9. Inner class types of the JDK can often vary in implementation details between JDK versions and vendors and are therefore only compatible for the same JDK. This + includes collection types returned by the methods of the Collections class that wrap another one (like unmodifiableList) or the collections that are returned by the + different Map implementations for the keySet(), entrySet() and values() methods.
  10. +
  11. Non-serializable lambda expressions cannot be deserialized at all and serializable + lambda expression contain compiler and vendor specific information that might cause deserialization to fail.
  12. +
+ + +

How do I specify that a field should not be serialized?

+

Make it transient, specify it with XStream.omitField() or + annotate it with @XStreamOmitField

+ + +

How do I initialize a transient field at deserialization?

+ +

XStream uses the same mechanism as the JDK serialization. Example:

+ +
class ThreadAwareComponent {
+  private transient ThreadLocal component;
+  // ...
+  private Object readResolve() {
+    component = new ThreadLocal();
+    return this;
+  }
+}
+

or

+
class ThreadAwareComponent {
+  private transient ThreadLocal component;
+  // ...
+  private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+    in.defaultReadObject();
+    component = new ThreadLocal();
+  }
+}
+

Use the latter in class hierarchies, readResolve is not called for base classes.

+ + +

XStream is not calling the default constructor during deserialization.

+ +

This is, in fact, the same case as above. XStream uses the same mechanism as the JDK serialization. When using + the enhanced mode with the optimized reflection API, it does not invoke the default constructor. The solution is to + implement the readResolve or readObject as demonstrated with the last question.

+ + +

What do serialized collections look like?

+ +

See example for the CollectionConverter.

+

Note, that it is possible to configure XStream to omit the container element toys using implicit collections.

+ + +

Why do serialized types, fields or methods do not use aliasing for the names?

+ +

XStream normally has no to separate between a primitive and its boxed type. The complete reflection API works + always with the boxed types and converts to primitives types on the fly. However, for method and field type + signatures the difference is essential. Nevertheless it is possible to register derived versions of the converters + that are able to respect the aliasing with some minor effort. Following lines are taken from the AliasTest in the + acceptence tests:

+
XStream xstream = new XStream();
+Mapper mapper = new MapperWrapper(xstream.getMapper().lookupMapperOfType(ArrayMapper.class)) {
+  public Class realClass(String elementName) {
+    Class primitiveType = Primitives.primitiveType(elementName);
+    return primitiveType != null ? primitiveType : super.realClass(elementName);
+  }
+};
+SingleValueConverter javaClassConverter = new JavaClassConverter(mapper) {};
+xstream.registerConverter(javaClassConverter);
+xstream.registerConverter(new JavaMethodConverter(javaClassConverter){});
+xstream.registerConverter(new JavaFieldConverter(javaClassConverter, mapper){});
+ + +

My implicit collection is suddenly null after deserialization instead of empty!

+ +

By declaring a collection as implicit, the result will have no direct representation of the collection container + itself anymore. Therefore, if the collection was empty at serialization time, the serialized result does not + contain a trace of the collection anymore. At deserialization time it will therefore not know anything about the + collection and will not initialize it. XStream cannot decide anyway at deserialization time, if the collection was + empty or null.

+ + +

The type of my implicit collection is different after deserialization.

+ +

By declaring a collection as implicit, the result will have no direct representation of the collection container + itself anymore. Therefore XStream cannot track the original type of the collection. At deserialization time it will + therefore look at the declaration type of the field that holds the collection and use this type's default + implementation, e.g. for a List this is by default an ArrayList.

+ +

Beware, that this also means that collections with additional information (e.g. a TreeSet with a Comparator) + cannot be restored, since the comparator was already omitted at serialization time.

+ + +

Do my classes have to implement Serializable if XStream is to serialize them?

+

No (except for lambda expressions), but XStream respects the Java serialization methods even for types not declared as Serializable.

+ + +

Can dynamic proxies be serialized?

+

Yes.

+ + +

My lambda expression is serialized to null!

+

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 + objects and as such XStream has no other possibility as to serialize null instead.

+ + +

Suddenly the deserialization of my (serializable) lambda expression fails!

+

Serializable lambda expressions contain information that is specific for compiler and vendor. Even worse, the compiler is free to add information related to the location + of the lambda expression in the source i.e. you may not be able to deserialize a lambda expression after source code changes. XStream has no control over this information + and how it is used by native functionality in the JDK. Therefore Oracle strongly discourages the usage of serializable lambda expressions in the JDK documentation.

+ + +

Can CGLIB proxies be serialized?

+

Only limitedly. A proxy generated with the CGLIB Enhancer is supported, if the proxy uses either a factory or + only one callback. Then it is possible to recreate the proxy instance at unmarshalling time. Starting with XStream 1.3.1 + CGLIB support is no longer automatically installed because of possible classloader problems and side-effects, + because of incompatible ASM versions. You can enable CGLIB support with:

+
XStream xstream = new XStream() {
+    protected MapperWrapper wrapMapper(MapperWrapper next) {
+        return new CGLIBMapper(next);
+    }
+};
+xstream.registerConverter(new CGLIBEnhancedConverter(xstream.getMapper(), xstream.getReflectionProvider()));
+
+ + +

CGLIBEnhancedConverter fails at initialization with ExceptionInInitializerError

+

This is not a problem of XStream. You have incompatible ASM versions in your classpath. CGLIB 2.1.x and below is based on + ASM 1.5.x which is incompatible to newer versions that are used by common packages like Hibernate, Groovy or Guice. Check + your dependencies and ensure that you are using either using cglib-nodep-2.x.jar instead of cglib-2.x.jar or update to + cglib-2.2.x that depends on ASM 3.1. However, the nodep version contains a copy of the ASM classes with private + packages and will therefore not raise class incompatibilities at all.

+ + +

Serialization fails with NoSuchMethodError: net.sf.cglib.proxy.Enhancer.isEnhanced(Ljava/lang/Class;)Z

+

XStream uses this method to detect a CGLIB-enhanced proxy. Unfortunately the method is not available in the + cglib-2.0 version. Since this version is many years old and the method is available starting with cglib-2.0.1, please + consider an upgrade of the dependency, it works usually smoothly.

+ + +

How do I use XStream's Hibernate package to serialize my objects?

+

Support of Hibernate enhanced collections and proxied types. To drop the internals of Hibernate when marshalling + such objects to XStream, all converters and the mapper has to be registered for the XStream instance:

+
final XStream xstream = new XStream() {
+  protected MapperWrapper wrapMapper(final MapperWrapper next) {
+    return new HibernateMapper(next);
+  }
+};
+xstream.registerConverter(new HibernateProxyConverter());
+xstream.registerConverter(new HibernatePersistentCollectionConverter(xstream.getMapper()));
+xstream.registerConverter(new HibernatePersistentMapConverter(xstream.getMapper()));
+xstream.registerConverter(new HibernatePersistentSortedMapConverter(xstream.getMapper()));
+xstream.registerConverter(new HibernatePersistentSortedSetConverter(xstream.getMapper()));
+
+ + +

Does XStream's Hibernate package support Envers?

+

Yes. Hibernate Envers is an optional dependency for XStream and it is automatically supported by XStream's + Hibernate package when the proxy collection types of Envers are available on the classpath.

+ + +

My attributes are interpreted by XStream itself and cause unexpected behavior

+

XStream's generic converters and the marshalling strategies use a number of attributes on their own. Especially the attributes named + id, class and reference are likely to cause such collisions. Main reason is XStream's history, because + originally user defined attributes were not supported and all attribute were system generated. Starting with XStream 1.3.1 you can redefine + those attributes to allow the names to be used for your own ones. The following snippet defines XStream to use different system attributes + for id and class while the field id of YourClass is written into the attribute class:

+
XStream xstream = new XStream() {
+xstream.useAttributeFor(YourClass.class, "id");
+xstream.aliasAttribute("class", "id");
+xstream.aliasSystemAttribute("type", "class");
+xstream.aliasSystemAttribute("refid", "id");
+
+ + +

Can I select the field order in which XStream serializes objects?

+

Yes. XStream's ReflectionConverter uses the defined field order by default. You can override it by using an specific FieldKeySorter:

+
SortableFieldKeySorter sorter = new SortableFieldKeySorter();
+sorter.registerFieldOrder(MyType.class, new String[] { "firstToSerialize", "secondToSerialize", "thirdToSerialize" });
+xstream = new XStream(new Sun14ReflectionProvider(new FieldDictionary(sorter)));
+
+ + +

How does XStream deal with newer versions of classes?

+ +
    +
  • If a new field is added to the class, deserializing an old version will leave the field uninitialized.
  • +
  • If a field is removed from the class, deserializing an old version that contains the field will cause an exception. + Leaving the field in place but declaring it as transient will avoid the exception, but XStream will not try to deserialize it.
  • +
  • If a class is renamed, aliases can be used to create an abstraction between the name used in XML and the real class name.
  • +
  • If a field is renamed, this should be treated as adding a field and removing a field.
  • +
+ +

For more advanced class migrations, you may

+
    +
  • have to do custom pre-processing of the XML before sending it to XStream (for example, with XSLT or DOM manipulations)
  • +
  • declare new fields as transient
  • +
  • implement your own converter, that can handle the situation
  • +
  • add a readResolve() method to your class, that initializes the object accordingly
  • +
  • implement a custom mapper to ignore unknown fields automatically + (see acceptance test CustomMapperTest.testCanBeUsedToOmitUnexpectedElements())
  • +
+ +

Future versions of XStream will include features to make these type of migrations easier.

+ + +

How does XStream cope with isolated class loaders?

+ +

Serializing an object graph is never a problem, even if the classes of those objects have been loaded by + a different class loader. The situation changes completely at deserialization time. In this case you must set the + class loader to use with:

+ +
xstream.setClassLoader(yourClassLoader);
+ +

Although XStream caches a lot of type related information to gain speed, it keeps those information in + tables with weak references that should be cleaned by the garbage collector when the class loader is freed.

+ +

Note, that this call should be made quite immediately after creating the XStream and before any other + configuration is done. Otherwise configuration based on special types might refer classes loaded with the wrong + classloader.

+ + +

XML specifics

+ + +

Why does XStream not respect the encoding in the XML declaration?

+ +

XStream architecture is based on IO Readers and Writers, while the XML declaration is the responsibility of XML + parsers. All HierarchicalStreamDriver + implementations respect the encoding since version 1.3, but only if you provide an + InputStream. If XStream consumes a + Reader you have to initialize the reader with + the appropriate encoding yourself, since it is now the reader's task to perform the encoding and no XML parser can + change the encoding of a Reader and any encoding definition in the XML header will be ignored.

+ + +

Why does XStream not write an XML declaration?

+ +

XStream is designed to write XML snippets, so you can embed its output into an existing stream or string. + You can write the XML declaration yourself into the Writer before using it to call XStream.toXML(writer).

+ + +

Why does XStream not write XML in UTF-8?

+ +

XStream does no character encoding by itself, it relies on the configuration of the underlying XML writer. + By default it uses its own PrettyPrintWriter which writes into the default encoding of the current locale. To write + UTF-8 you have to provide a Writer + with the appropriate encoding yourself.

+ + +

Why do field names suddenly have double underscores in the generated XML?

+ +

XStream maps Java class names and field names to XML tags or attributes. Unfortunately this mapping cannot + be 1:1, since some characters used for + identifiers in Java are invalid in XML names. Therefore + XStream uses an XmlFriendlyNameCoder + to replace these characters with a replacement. By default this + NameCoder uses an underscore as escape + character and has therefore to escape the underscore itself also. You may provide a different configured instance + of the XmlFriendlyNameCoder or a complete different implementation like the + NoNameCoder to prevent name coding + at all. However it is your responsibility then to ensure, that the resulting names are valid for XML.

+ + +

XStream fails to unmarshal my given XML and I do not know why?

+ +

By default XStream is written for persistence i.e. it will read the XML it can write. If you have to transform + a given XML into an object graph, you should go the other way round. Use XStream to transfer your objects into XML. + If the written XML matches your schema, XStream is also able to read it. This way is much easier, since you can + spot the differences in the XML much more easy than to interpret the exceptions XStream will throw if it cannot + match the XML into your objects.

+ + +

My parser claims the &#x0; character to be invalid, but it was written with XStream!

+ +

Your parser is basically right! A character of value 0 is not valid as part of XML according the XML specification (see + version 1.0 or + 1.1), neither directly nor as character + entity nor within CDATA. But not every parser respects this part of the specification (e.g. Xpp3 will ignore it and read + character entities). If you expect such characters in your strings and you do not use the Xpp3 parser, you should consider + to use a converter that writes the string as byte array in Base64 code. As alternative you may force the + PrettyPrintWriter or derived writers + to be XML 1.0 or 1.1. compliant, i.e. in this mode a StreamException is thrown.

+ + +

My parser claims a control character to be invalid, but it was written with XStream!

+ +

Your parser is probably right! Control characters are only valid as part of XML 1.1. You should add an XML header + declaring this version or use a parser that does not care about this part of the specification (e.g. Xpp3 parser).

+ + +

Why is my element not written as XML attribute although I have configured it?

+ +

You can only write types as attributes that are represented as a single String value and are handled therefore + by SingleValueConverter implementations. If your type is handled by a Converter implementation, the configuration + of XStream to write an attribute (using XStream.useAttributeFor() or @XStreamAsAttribute) is simply ignored.

+ + +

Why are whitespace characters wrong in my attribute values after deserialization?

+ +

This is part of the XML specification and a required functionality for any XML parser called + attribute value normalization. It cannot + be influenced by XStream. A compliant XML parser will replace by default real tab, carriage return and line feed + characters with normal spaces. If you want to keep these characters you will have to encode them with entities.

+ + +

Why does XStream not have any namespace support?

+ +

Not every XML parser supports namespaces and not every XML parser that supports namespaces can be configured + within XStream to use those. Basically namespaces must be supported individually for the different XML parsers and the + only support for namespaces that has currently been implemented in XStream is for the StAX paser. Therefore use and + configure the StaxDriver of XStream to use namespaces.

+ + +

My XML contains XPath expressions in the references, but they seem not to work?

+ +

XStream generates only XPath compliant expressions. These have a very limited syntax and they are the only ones + that can be interpreted at deserialization again, since XStream does not use an XPath interpreter. Therefore there + is no support for attribute selectors, qualified element access with axis names or functions. For real XPath + support you will have to implement your own MarshallingStrategy.

+ + +

The XPath expressions in the references do select a list, but not a single node!

+ +

Yes, this is right. However, the result type of an + XPath expression + evaluation can be defined. A node result from a node list is the lists first node, therefore the XPath of XStream + is compliant. Since XStream does not use a real XPath engine, you do not have to worry about memory consumption or + wasted evaluation time, XStream will always operate on a single node anyway. Since XStream 1.4 you can force + XStream to write XPath expressions that select explicit the single node by using the new modes + XStream.SINGLE_NODE_XPATH_ABSOLUTE_REFERENCES or SINGLE_NODE_XPATH_RELATIVE_REFERENCES. Instead of generating a + path like "/doc/list/elem/field" XStream will then generate "/doc[1]/list[1]/elem[1]/field[1]". The two notations + are transparent at deserialization time.

+ + + +

JSON specifics

+ + +

Why are there two JSON driver implementations?

+ +

As always, first for historical reasons! Main difference is that the + JettisonMappedXmlDriver is a + thin wrapper around Jettison in combination with the + StaxDriver, while the + JsonHierarchicalStreamDriver + uses an own more flexible implementation, but can only be used to generate JSON, deserialization is not implemented.

+ + +

Which versions of Jettison are supported?

+ +

Users of Java 5 or higher can use Jettison 1.2, users of Java 1.4.2 have to use Jettison 1.0.1. Jettison 1.1 + nor Jettison 1.3 or higher is supported.

+ + +

Why is it not possible to deserialize a JSON string starting with an array?

+ +

XStream's implementation to deserialize JSON is based on Jettison and StAX. Jettison implements a XMLStreamReader + of StaX and transforms the processed JSON virtually into XML first. However, if the JSON string starts with an array it is not + possible for Jettison to create a valid root element, since it has no name.

+ + +

XStream fails to unmarshal my JSON string and I do not know why?

+ +

Deserialization of JSON is currently done by Jettison, that transforms the JSON string into a StAX stream. + XStream itself does nothing know about the JSON format here. If your JSON string reaches some kind of + complexity and you do not know how to design your Java objects and configure XStream to match those, + you should have a look at the intermediate XML that is processed by XStream in the end. This might help to + identify the problematic spots. Also consider then marshalling your Java + objects into XML first. You can use following code to generate the XML:

+ +
String json = "{\"string\": \"foo\"}";
+HierarchicalStreamDriver driver = new JettisonMappedXmlDriver();
+StringReader reader = new StringReader(json);
+HierarchicalStreamReader hsr = driver.createReader(reader);
+StringWriter writer = new StringWriter();
+new HierarchicalStreamCopier().copy(hsr, new PrettyPrintWriter(writer));
+writer.close();
+System.out.println(writer.toString());
+
+ + +

What limitations has XStream's JSON support?

+ +

JSON represents a very simple data model for easy data transfer. Especially it has no equivalent for XML + attributes. Those are written with a leading "@" character, but this is not always possible without + violating the syntax (e.g. for array types). Those may silently dropped (and makes it therefore difficult to + implement deserialization). References are another issue in the serialized object graph, since JSON has no + possibility to express such a construct. You should therefore always set the NO_REFERENCES mode of XStream. + Additionally you cannot use implicit collections, since the properties in a JSON object must have unique names.

+ + +

Why are my Long values incorrect in JavaScript?

+ +

JavaScript does not know about integer values. All numbers are represented with double precition floats using + 64 bits (IEEE 754). These types cannot represent technically the complete value range of 64-bit integers like + Java's Long. With the JsonWriter you have the possibility since XStream 1.4.5 to set + IEEE_754_MODE to force + any long value that is not representable as JavaScript number to be written as string value in JSON. With the + Jettison-based JettisonMappedXmlDriver you may either set a different TypeConverter or force the default converter + to write integer values out of the range of 32-bit always as string setting the system property + jettison.mapped.typeconverter.enforce_32bit_integer to true (not available for + Jettison 1.0.1 and Java 1.4).

+ + +

Why are there invalid characters in my JSON representation?

+ +

The JSON spec requires any JSON string to be in UTF-8 encoding. However, XStream ensures this only if you + provide an InputStream or an OutputStream. If you provide a Reader or Writer you have to ensure this requirement + on your own.

+ + +

The generated JSON is invalid, it contains a dash in the label!

+ +

Well, no, the JSON is valid! Please check yourself with the JSON syntax checker. + However, some JavaScript libraries silently assume that the JSON labels are valid JavaScript identifiers, because JavaScript + supports a convenient way to address an element, if the label is a valid JavaScript identifier:

+ +
var json = {"label": "foo", "label-with-dash": "bar"};
+var fooVar = json.label; // works for labels that are JavaScript identifiers
+var barVar = json["label-with-dash"]; // using an array index works always
+
+ +

As alternative you may wrap the JsonWriter and replace any dash with an underscore:

+ +
HierarchicalStreamDriver driver = new JsonHierarchicalStreamDriver() {
+    public HierarchicalStreamWriter createWriter(Writer out) {
+        return new WriterWrapper(super.createWriter(out)) {
+            public void startNode(String name) {
+                startNode(name, null);
+            }
+            public void startNode(String name, Class clazz) {
+                wrapped.startNode(name.replace('-', '_'), clazz);
+            }
+        }
+    }
+};
+XStream xstream = new XStream(driver);
+
+ + +

Security Aspects

+ + +

Why does XStream not convert an java.beans.EventHandler?

+ +

Since XStream verison 1.4.7 it does no longer handle an + EventHandler automatically. + Such an instance can be used to initiate calls on arbitray instances at deserialization time e.g. + ProcessBuilder.start() + You can register a ReflectionConverter instance explicitly for the EventHandler if you need support for such + instances.

+ + +

XStream deserializes arbitrary objects!

+ +

Yes, XStream is designed to convert any object form Java to XML and back out of the box. In consequence it is + possible to adjust the processed XML manually to inject arbitrary objects into the deserialized object graph. To + avoid such a behavior, you have several options:

+ +
    +
  • Prevent the usage of the reflection-based converters. Register an own converter with priority LOW that claims + to handle any type and throw a ConversionException in the marshal and unmarshal methods.
  • +
  • Overload XStream.setupConverters() and register only converters for the types that are allowd in your object + graph.
  • +
  • Provide own implementations for ConverterLookup and ConverterRegistry constructing the XStream. Your + implementation can then select the appropriate converter at lookup time on its own or prevent the registration of + specific converters.
  • +
+ + +

Comparison to other products

+ + +

How does XStream compare to java.beans.XMLEncoder?

+ +

XStream is designed for serializing objects using internal fields, whereas + XMLEncoder is designed for + serializing JavaBeans using public API methods (typically in the form + of getXXX(), setXXX(), addXXX() and removeXXX() methods.

+ +

How does XStream compare to JAXB (Java API for XML Binding)?

+ +

JAXB is a Java binding tool. It generates Java code from a schema and you are able to transform from those classes into + XML matching the processed schema and back. Note, that you cannot use your own objects, you have to use what is + generated.

+ + +

Scalability

+ + +

Is XStream thread safe?

+ +

Yes. Once the XStream instance has been created and configured, it may be shared across multiple threads + allowing objects to be serialized/deserialized concurrently (unless you enable the + auto-detection to process annotations on-the-fly). Actually the + creation and initialization of XStream is quite expensive, therefore it is recommended to keep the XStream instance + itself. If you abolutely have to rely on annotation processing on the fly, you will have to use separate XStream + instances for each thread - either by using everytime a new instance or by a shared pool.

+ + +

How much memory does XStream consume?

+ +

This cannot be answered in general, but following topics have impact on the memory:

+ +
    +
  1. XML parser technology in use: You should use a streaming parser like Xpp3 or StAX. DOM-based + parsers process the complete XML and create their document model in memory before the first converter of XStream + is called.
  2. +
  3. Your object model: Is it necessary to keep the complete object graph in memory at once? As alternative you might + use object streams or write custom converters that can load and save objects of your + object model on the fly without adding them to the object graph physically. As example see the implementation of the + XmlArrayList in combination with the + FileStreamStrategy from + XStream's persistence package to keep parts of the object graph separate.
  4. +
  5. References: By default XStream supports references to the same object in an object graph. This implies that XStream + keeps track of all serialized and deserialized objects internally. These references are kept with WeakReferences, so that the + memory can be freed as soon as nobody references these objects anymore.
  6. +
  7. XML values: Any tag and attribute value that is converted into a Java String in the object graph will use by default the + same String instance unless it exceeds 38 characters (length of a UUID string representation).
  8. +
  9. XStream caches: To increase performance XStream caches quite a lot like classes, converters to use, aliasing, tag names. + All those caches make usage of WeakReferences or will exist only while marshalling one object graph resp. unmarshalling one + input stream.
  10. +
+ + +

Can the performance of XStream be increased?

+ +

XStream is a generalizing library, it inspects and handles your types on the fly. Therefore it will normally be slower than + a piece of optimized Java code generated out of a schema. However, it is possible to increase the performance anyway:

+ +
    +
  • Write custom converters for those of your types that occur very often in your XML.
  • +
  • Keep a configured XStream instance for multiple usage. Creation and initialization is quite expensive compared to the + overhead of XStream when calling marshall or unmarshal.
  • +
  • Use Xpp3 or StAX parsers.
  • +
+ +

Note, you should never try to optimize code for performance simply because you believe that you + have detected a bottle neck. Always use proper tools like a profiler to verify where your hotspots are and whether your + optimization was really successful or not.

+ + + +

Uses of XStream

+ + +

Is XStream a data binding tool?

+ +

No. It is a serialization tool.

+ + +

Can XStream generate classes from XSD?

+ +

No. For this kind of work a data binding tool such as XMLBeans is appropriate.

+ + +

Why is there no SaxReader?

+ +

XStream works on a stream-based parser model, while SAX is event-based. The stream based model implies, that the + caller consumes the individual tokens from the XML parser on demand, while in an event-based model the parser + controls the application flow on its own and will use callbacks to support client processing. The different + architecture makes it therefore impossible for XStream to use an event-driven XML parser.

+ + + + diff --git a/xstream-distribution/src/content/graphs.html b/xstream-distribution/src/content/graphs.html new file mode 100644 index 0000000..4a2e7de --- /dev/null +++ b/xstream-distribution/src/content/graphs.html @@ -0,0 +1,232 @@ + + + + Object references + + + + + +

How does XStream deals with duplicate and circular references?

+

It depends on XStream's mode, the default is uses XPath to allow serialized objects to be treated as graphs instead of simple trees (typical XML usage).

+ +

Sometimes it's not desirable to work this way, let's take a look in a simple example in order to switch between XStream's modes and see what its capable of.

+

We start with a simple compact-disc class, with id and a bonus cd fields:

+ +
package com.thoughtworks.xstream;
+public class Cd {
+	private String id;
+
+	private Cd bonusCd;
+
+	Cd(String id, Cd bonusCd) {
+		this.id = id;
+		this.bonusCd = bonusCd;
+	}
+
+	Cd(String id) {
+		this.id = id;
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public Cd getBonusCd() {
+		return bonusCd;
+	}
+}
+ +

And let's create an order with the same cd twice and the order itself, so we can simulate + two references to the same object and a back-reference.

+ +
Cd bj = new Cd("basement_jaxx_singles");
+		
+List order = new ArrayList();
+// adds the same cd twice (two references to the same object)
+order.add(bj);
+order.add(bj);
+
+// adds itself (cycle)
+order.add(order);
+
+XStream xstream = new XStream();
+xstream.alias("cd", Cd.class);
+System.out.println(xstream.toXML(order));
+
+ +

If we execute the above code, XStream's uses its default mode called XPATH_RELATIVE_REFERENCES + based on the W3C XPath specification. Cross and back references are treated in a way that it's (almost) human +readable:

+ +
+<list>
+  <cd>
+    <id>maria rita</id>
+  </cd>
+  <cd>
+    <id>basement_jaxx_singles</id>
+  </cd>
+  <cd reference="../cd[2]"/>
+  <list reference=".."/>
+</list>
+
+ +

The second reference to the Basement Jaxx cd was serialized as "../cd[2]" while the order inside +itself used the ".." path. The XPath Relative mode allows any type of graphs to be used as both cross and +back-references are supported.

+ +

In order to make use of the XPath Relative mode one can implicitly call:

+ +
+xstream.setMode(XStream.XPATH_RELATIVE_REFERENCES);
+
+ + +

Relative x Absolute

+ +

There is an absolute mode which is easy to use and understand. It works +using the same XPath specification and also supports all types of graphs.

+ +
+xstream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
+
+ +

The changes in the resulting xml is a little more 'clutter':

+ +
+<list>
+  <cd>
+    <id>maria rita</id>
+  </cd>
+  <cd>
+    <id>basement_jaxx_singles</id>
+  </cd>
+  <cd reference="/list/cd[2]"/>
+  <list reference="/list"/>
+</list>
+
+ + + +

Single Node Selectors

+ +

In some cases where the XML is used later on or is generated by someone else, the + XPath selectors can be forced to select always a single node instead of a node list where + the first element is taken. Therefore two more modes exist:

+ +
+xstream.setMode(XStream.SINGLE_NODE_XPATH_ABSOLUTE_REFERENCES);
+xstream.setMode(XStream.SINGLE_NODE_XPATH_RELATIVE_REFERENCES);
+
+ +

The changes in the resulting xml is even more 'clutter':

+ +
+<list>
+  <cd>
+    <id>maria rita</id>
+  </cd>
+  <cd>
+    <id>basement_jaxx_singles</id>
+  </cd>
+  <cd reference="/list[1]/cd[2]"/>
+  <list reference="/list[1]"/>
+</list>
+
+ +

For XStream is the notation with the single node selectors absolutely equivalent to the + one without. These two notations are completely transparent at deserialization time.

+ + +

Id mode

+ +

Both modes displayed until now are not so easy to write by hand. XStream has another + mode which makes it is easier to read/write by a human being:

+ +
+xstream.setMode(XStream.ID_REFERENCES);
+
+ +

The result is a XML which generates an "id" attribute for each new object marshaled, + and whenever it finds back or cross-references, it uses a "reference" attribute to so + it doesn't copy the entire object.

+ +

In our example, the list has id 1, the Maria Rita cd 2, and the Basement Jaxx 3. Therefore + the cross-reference to our cd should contain a reference attribute to object number 2 and + the back-reference to our order a reference to object 1. The result is:

+ +
+<list id="1">
+  <cd id="2">
+    <id>maria rita</id>
+  </cd>
+  <cd id="3">
+    <id>basement_jaxx_singles</id>
+  </cd>
+  <cd reference="3"/>
+  <list reference="1"/>
+</list>
+
+ + +

No references

+ +

For some uses of XStream we do not desire any kind of back or cross references like a graph, but a simple + tree. The most famous example is when using XStream to generate XML for B2B services.

+ +

In such scenarios it's impossible to represent a graph cycle (remember: no tree contains such structure), therefore + we have to remove the last add call from our example:

+ +
Cd bj = new Cd("basement_jaxx_singles");
+		
+List order = new ArrayList();
+// adds the same cd twice (two references to the same object)
+order.add(bj);
+order.add(bj);
+
+XStream xstream = new XStream();
+xstream.alias("cd", Cd.class);
+System.out.println(xstream.toXML(order));
+
+ +

Now if we add the NO_REFERENCES option, every reference shall be completed serialized.

+ +
+xstream.setMode(XStream.NO_REFERENCES);
+
+ +

The result are three references:

+ +
+<list>
+  <cd>
+    <id>maria rita</id>
+  </cd>
+  <cd>
+    <id>basement_jaxx_singles</id>
+  </cd>
+  <cd>
+    <id>basement_jaxx_singles</id>
+  </cd>
+</list>
+
+ +

After reading from the above XML, you will get three different Cd instances.

+ +

Remember: it's impossible to support back-references (cycles) with NO_REFERENCES mode activated therefore + a CircularReferenceException is thrown if you ever try to do so.

+ + + + diff --git a/xstream-distribution/src/content/how-to-contribute.html b/xstream-distribution/src/content/how-to-contribute.html new file mode 100644 index 0000000..f98124a --- /dev/null +++ b/xstream-distribution/src/content/how-to-contribute.html @@ -0,0 +1,76 @@ + + + + How to Contribute + + + + +

XStream is nothing without contributions from the user community. There are many ways to + contribute. We are constantly working on the software and documentation, so it's a good + idea to contact the team. For normal question about usage or possible misbehavior, please contact + us on the user mailing list. To discuss further development of XStream, + you may contact us on development mailing lists to avoid duplicating effort.

+ +

Help

+

The correct place if you are looking for help is the user mailing list. You + get there a much wider audience from other users and also the developers are reading and answering there + your questions.

+ +

Documentation

+

One of the traditional weak points of open source software is the documentation. Any + help with this aspect of the project will be welcomed with open arms, or at the very least + with open email clients!

+ +

Examples

+

We are working on one or two examples of using XStream, but we can always do with more.

+ +

Feature Requests

+

We eat our own dogfood, but we're also happy to feed other people's dogs (if you'll excuse + a stretched dachshund metaphor!). If you want to + request a new feature you can either make a request through the issue tracker + or by sending a message to the development mailing list. The benefit of any + new features will be discussed on the mailing list, so its a good idea to sign up so that you can stick your + oar in.

+ +

Bug Reports

+

You can report bugs through the issue tracker interface or in case you are + in doubt whether it is really a bug or just a wrong usage, you may ask first posting to the + user mailing list. Additional brownie points are awarded for bug reports that + include a failing unit test.

+ +

Bug Fixes

+

If you want lots of brownie points, send a fix along with your bug report + and failing unit test. Bug fixes are best sent as patches that we can apply to the + codebase. Remember to tell us which version the patch should be applied against, or + we'll get very confused. To be accepted into the codebase, patches must be released + under the same license as XStream itself.

+ +

New Code

+

If you have a new feature request, then we'll listen extra hard if you show us how it + works. A new feature might be best implemented as a patch to an existing class + or as a new class. The XStream API contains many extension points that allow new functionality + to be integrated into the framework. We are rather anal about testing, so if you send us + some code without any tests we will probably ask you to write the tests tests as well + before we add it to the codebase.

+ +

Write Your Own XStream Extension

+

If you have a project that builds upon XStream we will be happy to announce your + project on the XStream site.

+ +

Become a Committer

+

We follow the Codehaus manifesto + when it comes to expanding the core team.

+ + + diff --git a/xstream-distribution/src/content/index.html b/xstream-distribution/src/content/index.html new file mode 100644 index 0000000..9f4da0e --- /dev/null +++ b/xstream-distribution/src/content/index.html @@ -0,0 +1,89 @@ + + + + Java to XML serialization, and back again + + + + + +

XStream is a simple library to serialize objects to XML and back again.

+ +

Features

+ +
    +
  • Ease of use. A high level facade is supplied that simplifies common use cases.
  • +
  • No mappings required. Most objects can be serialized without need for specifying mappings.
  • +
  • Performance. Speed and low memory footprint are a crucial part of the design, making it suitable for + large object graphs or systems with high message throughput.
  • +
  • Clean XML. No information is duplicated that can be obtained via reflection. This results + in XML that is easier to read for humans and more compact than native Java serialization.
  • +
  • Requires no modifications to objects. Serializes internal fields, including private and + final. Supports non-public and inner classes. Classes are not required to have default constructor.
  • +
  • Full object graph support. Duplicate references encountered in the object-model will + be maintained. Supports circular references.
  • +
  • Integrates with other XML APIs. By implementing an interface, XStream can serialize + directly to/from any tree structure (not just XML).
  • +
  • Customizable conversion strategies. Strategies can be registered allowing customization of how + particular types are represented as XML.
  • +
  • Security framework. Fine-control about the unmarshalled types to prevent security issues with + manipulated input.
  • +
  • Error messages. When an exception occurs due to malformed XML, detailed diagnostics are provided + to help isolate and fix the problem.
  • +
  • Alternative output format. The modular design allows other output formats. XStream ships currently + with JSON support and morphing.
  • +
+ +

Typical Uses

+ +
    +
  • Transport
  • +
  • Persistence
  • +
  • Configuration
  • +
  • Unit Tests
  • +
+ +

Known Limitations

+ +

If using the enhanced mode, XStream can re-instantiate classes that do not have a default constructor. + However, if using a different JVM like an old JRockit version, a JDK 1.4 or you have restrictions because of a + SecurityManager, a default constructor is required.

+ +

The enhanced mode is also necessary to restore final fields for any JDK < 1.5. This implies deserialization of + instances of an inner class.

+ +

Auto-detection of annotations may cause race conditions. Preprocessing annotations is safe though.

+ +

Getting Started

+ + + +

Latest News

+ +

February 18, 2015 XStream 1.4.8 released

+ +

Maintenance release 1.4.8 of XStream with bug fixes and improvements running with Java 8.

+ +

XStream supports now serializable lambda types for a Java 9 runtime.

+ +

View the complete change log and download.

+ +

Note, the next major release 1.5 will require Java 6.

+ +

Thanks to this impressive list of contributors.

+ + + diff --git a/xstream-distribution/src/content/issues.html b/xstream-distribution/src/content/issues.html new file mode 100644 index 0000000..ddda3ee --- /dev/null +++ b/xstream-distribution/src/content/issues.html @@ -0,0 +1,41 @@ + + + + Reporting Issues + + + +

XStream tracks and manages its issues in JIRA of Atlassian, + that is supported by the Codehaus infrastructure and is free for open source development.

+ +

JIRA Account

+ +

Before you can report, comment or vote for an issue you need an account for the Codehaus. This account is then also used for + Codehaus' JIRA installation. Simply sign up at xircles and on top you're able to manage all + the mailing list subscriptions at Codehaus inclusive XStream's lists also. This is necessary to reduce spam in the system and as benefit + you can be notified if work is done on your reported issues.

+ +

Policy

+ +

Please, before opening a new issue look through the open or resolved ones, you may already find your problem. Also do not + use the system to ask questions, for that purpose we have a user list. We read the list continuously. + 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, + 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.

+ +

If you like to contribute code, we prefer a patch/diff in contrast to the complete modified file - unless the file itself is new. Please + provide also unit tests, XStream has a high test coverage and we like to keep this. Additionally, if you provide new files, please also add + 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 + we might not be able to add any code of you.

+ +

Browse XStream in JIRA now.

+ + diff --git a/xstream-distribution/src/content/json-tutorial.html b/xstream-distribution/src/content/json-tutorial.html new file mode 100644 index 0000000..07111e3 --- /dev/null +++ b/xstream-distribution/src/content/json-tutorial.html @@ -0,0 +1,162 @@ + + + + JSON Tutorial + + + +

Due to XStream's flexible architecture, handling of JSON mappings is as easy as handling of XML documents. All you +have to do is to initialize XStream object with an appropriate driver and you are ready to serialize your objects to +(and from) JSON.

+ +

XStream currently delivers two drivers for JSON: The +JsonHierarchicalStreamDriver +and the JettisonMappedXmlDriver. +The first one does not have an additional dependency, but can only be used to write XML, while the second one is based +on Jettison and can also deserialize JSON to Java objects again. However, since the JettisonMappedXmlDriver transforms +plain XML into JSON, you might get better JSON strings with the JsonHierarchicalStreamDriver, because this driver knows +often about the type of the written data and can act properly.

+ +

One word of warning. JSON is made for an easy data transfer between systems and languages. It's +syntax offers much less possibilities to express certain data structures. It supports name/value pairs of primitive +data types, arrays and lists and allows to nest them - but that's it! No references, no possibility for meta data +(attributes), no properties with same names (as generated for implicit collections), etc. Therefore do not expect +wonders. XStream (and Jettison) try their best, but the procedure to convert any kind of object into JSON is a lossy +transformation and especially deserialization will not be possible for any construct. See also +FAQ for JSON limitations. Also note that any number value in JavaScript is a +64-bit double precision float value according IEEE 754 standard. In consequence it is not possible to represent all +values of a Java long type without loss of precision. See again FAQ for JSON +and JavaScript.

+ +

Since JSON has no possibility to express references, you should always set the NO_REFERENCES mode writing JSON.

+ +

Jettison driver

+ +

Jettison driver uses Jettison StAX parser to read and write data in JSON +format. It is available in XStream since version 1.2.2 and is implemented in +com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver class. To successfully use this driver you need +to have the Jettison project and StAX API in your classpath (see reference for +optional dependencies).

+ +

Alternatively you can download JARs manually.

+ +

Here are a few simple examples:

+ +

Write to JSON with the Jettison-based implementation

+ +

The following example:

+ +
package com.thoughtworks.xstream.json.test;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
+
+public class WriteTest {
+
+	public static void main(String[] args) {
+
+        Product product = new Product("Banana", "123", 23.00);
+        XStream xstream = new XStream(new JettisonMappedXmlDriver());
+        xstream.setMode(XStream.NO_REFERENCES);
+        xstream.alias("product", Product.class);
+
+        System.out.println(xstream.toXML(product));		
+		
+	}
+
+}
+ +

produces the following JSON document:

+ +
{"product":{"name":"Banana","id":123,"price":23.0}}
+ +

As you can see, all standard XStream features (such as aliases) can be used with this driver.

+ +

Note that Jettison will try to detect numerical values and omit the quotes. Since Jettison +cannot know about the original data type, it has to guess. Hence it will therefore also write the value of the id +field as numeric value in future.

+ +

Write to JSON with the self-contained JSON driver

+ +

The only difference to the example above is the line with the initialization:

+ +
XStream xstream = new XStream(new JsonHierarchicalStreamDriver());
+ +

The output is as follows:

+ +
{"product": {
+  "name": "Banana",
+  "id": "123",
+  "price": 23.0
+}}
+ +

While the difference because of line feeds is immediately obvious, you have to note also the value of the +id element. This time the driver knew about the string value and therefore quotes were generated.

+ +

Write to JSON with the self-contained JSON driver dropping the root

+ +

Sometimes the root node in the generated JSON is superfluous, since its name is caused by the Java type +of the written object that has no meaning in JSON and increases only the nesting level of the structure. Therefore +it is possible to drop this root by initializing the internally used +JsonWriter in a different mode. +Again, the only difference to the example above is the line with the initialization:

+ +
XStream xstream = new XStream(new JsonHierarchicalStreamDriver() {
+    public HierarchicalStreamWriter createWriter(Writer writer) {
+        return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE);
+    }
+});
+ +

The output is as follows:

+ +
{
+  "name": "Banana",
+  "id": "123",
+  "price": 23.0
+}
+ +

Note, that it is now possible to create invalid JSON if XStream should marshal a single object +with a single value to JSON (like String, int, URL, ...). JSON requires that the root is actually an object, but by +dropping the root all that is generated is a single value. You can force the JsonWriter to throw a ConversionException +in this case, see Javadoc of the JsonWriter.

+ +

Read from JSON

+ +

The following code:

+ +
package com.thoughtworks.xstream.json.test;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
+
+public class ReadTest {
+
+	public static void main(String[] args) {
+		String json = "{\"product\":{\"name\":\"Banana\",\"id\":123"
+		    + ",\"price\":23.0}}";
+		    
+		XStream xstream = new XStream(new JettisonMappedXmlDriver());
+		xstream.alias("product", Product.class);
+		Product product = (Product)xstream.fromXML(json);
+		System.out.println(product.getName());
+	}
+
+}
+ +

serializes JSON document created with preceding example back to Java object. It prints:

+ +
Banana
+ +

as a result.

+ + + diff --git a/xstream-distribution/src/content/license.html b/xstream-distribution/src/content/license.html new file mode 100644 index 0000000..092580e --- /dev/null +++ b/xstream-distribution/src/content/license.html @@ -0,0 +1,51 @@ + + + + License + + + +

XStream is open source software, made available under a BSD license.

+ +
Copyright (c) 2003-2006, Joe Walnes
+Copyright (c) 2006-2009, 2011 XStream Committers
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this list of
+conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other materials provided
+with the distribution.
+
+3. Neither the name of XStream nor the names of its contributors may be used to endorse
+or promote products derived from this software without specific prior written
+permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+ + + diff --git a/xstream-distribution/src/content/list-dev.html b/xstream-distribution/src/content/list-dev.html new file mode 100644 index 0000000..e2ac46c --- /dev/null +++ b/xstream-distribution/src/content/list-dev.html @@ -0,0 +1,43 @@ + + + + Developers' Mailing List + + + +

General discussion and support for anyone who wants to get involved in the development of XStream.

+ +

Note, if you just have questions about using XStream, you should use the user's mailing list.

+ + + + + + + + + + +
Post(Un-)Subscribe
dev@xstream.codehaus.orgManage Email
+ +

Due to massive abuse by spammers the subscriptions is centralized for email lists of all projects hosted on Codehaus. + After following the link above just register with your email address and you can manage all subscriptions at once.

+ +

Archives

+ + + + + diff --git a/xstream-distribution/src/content/list-user.html b/xstream-distribution/src/content/list-user.html new file mode 100644 index 0000000..1a98c38 --- /dev/null +++ b/xstream-distribution/src/content/list-user.html @@ -0,0 +1,41 @@ + + + + Users' Mailing List + + + +

General discussion and support for anyone using or evaluating XStream.

+ + + + + + + + + + +
Post(Un-)Subscribe
user@xstream.codehaus.orgManage Email
+ +

Due to massive abuse by spammers the subscriptions is centralized for email lists of all projects hosted on Codehaus. + After following the link above just register with your email address and you can manage all subscriptions at once.

+ +

Archives

+ + + + + diff --git a/xstream-distribution/src/content/manual-tweaking-output.html b/xstream-distribution/src/content/manual-tweaking-output.html new file mode 100644 index 0000000..d9a7b9a --- /dev/null +++ b/xstream-distribution/src/content/manual-tweaking-output.html @@ -0,0 +1,286 @@ + + + + Tweaking the Output + + + +

Out of the box, XStream is able to serialize most objects without the need for custom mappings to be setup. + The XML produced is clean, however sometimes it's desirable to make tweaks to it. The most common use for this is + when using XStream to read configuration files and some more human-friendly XML is needed.

+ + + +

Modification by configuration

+ +

A big part of the standard output of XStream can be configured. It is possible to set aliases for class types + and field names that are mapped to XML tag or attribute names. Objects that can be represented as simple string + value can be written as attributes. It is possible to omit fields or to flatten the structure for collections.

+ + + +

Aliases

+ +

Aliases offer a simple way to use different tag or attribute names in the XML. The simplest and most commonly + used tweak in XStream is to alias a fully qualified class to a shorter name. Another use case is a different field name + for a class member. Aliases can be set for following elements:

+ +
    +
  • Class types mapped to XML tags
  • +
  • Package names mapped to XML tags
  • +
  • Field names mapped to XML tags
  • +
  • Internal attributes names of XStream
  • +
+ +

The bold elements in the following example are affected:

+ +
<cat>
+  <age>4</age>
+  <name>Garfield</name>
+  <owner type="StandardPerson">
+    <name>Jon Arbuckle</name>
+  </owner>
+</cat>
+ +

Have a look at the Alias Tutorial for examples.

+ + + +

Attributes

+ +

XML is quite clumsy to read for fields in separate tags that can represent their content in a short single + string value. In such a case attributes can help to shorten the XML and increase readability:

+ +
<cat age="4" name="Garfield">
+  <owner class="StandardPerson" name="Jon Arbuckle"/>
+</cat>
+ +

Attributes are also presented in the Alias Tutorial.

+ + + +

Omitted Fields

+ +

For a proper deserialization XStream has to write the complete object graph into XML that is referenced by a + single object. Therefore XStream has to find a representation that contains all aspects to recreate the + objects.

+ +

However, some parts might be superfluous e.g. if a member field is lazy initialized and its content + can be easily recreated. In such a case a field can be omitted using + XStream.omitField(Class, String).

+ + + +

Implicit Collections, Arrays and Maps

+ +

Another use case are collections, arrays and maps. If a class has a field that is a one of those types, by + default all of its elements are embedded in an element that represents the container object itself. By + configuring the XStream with the + XStream.addImplicitCollection(), + XStream.addImplicitArray(), and + XStream.addImplicitMap() methods it + is possible to keep the elements directly as child of the class and the surrounding tag for the container object + is omitted. It is even possible to declare more than one implicit collection, array or map for a class, but + the elements must then be distinguishable to populate the different containers correctly at deserialization.

+ +

In the following example the Java type representing the farm may have two containers, one for cats and one + for dogs:

+ +
<farm>
+  <cat>Garfield</cat>
+  <cat>Arlene</cat>
+  <cat>Nermal</cat>
+  <dog>Odie</dog>
+</farm>
+ +

The container might be a Collection, Array, or even a Map. In the latter case a member field of the value + must have been defined, that is used as key in the deserialized map.

+ + + +

Field order

+ +

XStream is delivered with a lot of converters for standard types. + Nevertheless most objects are processed by converters based on reflection. They will write the fields of a + class in the sequence they are defined. It is possible to implement an algorithm for a different sequence or + use an implementation that allows to define the sequence for each type separately using a + FieldKeySorter. + Similar functionality exists for Java Beans with the + PropertySorter.

+ + + +

Output Format

+ +

XStream writes and reads XML by default. However, the I/O layer is separated from the model and you can + use implementations for other formats as well. A reader/writer pair is typically managed by a HierarchicalStreamDriver. XStream + is delivering additional drivers for JSON and a compact binary format (see BinaryStreamDriver). There are + also drivers to write an object graph into a DOM structure instead of a text based stream (available for W3C + DOM, DOM4J, JDOM, XOM, and XPP DOM).

+ + + +

Enhancing XStream

+ +

Sometimes customization is simply not enough to tweak the output. Depending on the use case it is fortunate to + use specialized converters for own types, mapper implementations that control naming of things more globally or + use specialized writers to influence the complete output.

+ + + +

Specialized Converters

+ +

Not all converters that are part of the XStream package are automatically registered. Some will only make + sense for special types, others have parameters to tweak the behaviour and are often most effective if + registered as local converter only. Most useful in the table of converters are + the JavaBeanConverter, NamedArrayConverter, NamedCollectionConverter, NamedMapConverter, ToStringConverter, and + ToAttributedValueConverter. Not to mention the separate Hibernate package of XStream.

+ +

As example can the ToAttributedValueConverter be used to define the owner's name directly as text value:

+ +
<cat age="4" name="Garfield">
+  <owner class="StandardPerson">Jon Arbuckle</>
+</cat>
+ +

Attributes are also presented in the Alias Tutorial.

+ + + +

Custom Converters

+ +

Sometimes the object to serialize contains fields or elements, that have no friendly representation for + human beings e.g. if a long value represents in reality a time stamp. In such cases XStream supports custom + converters for arbitrary types. Have a look at the Converter Tutorial + for advanced possibilities. Note, that a custom converter is not different to one that is delivered by + XStream. It's simply your code.

+ + + +

Custom Mappers

+ +

In case of global adjustments it can be helpful to implement an own mapper. A mapper is used to name things + and map between the name in the Java world to the name used in the XML representation. The alias mechanism + described above is implemented as such a mapper that can be configured. A typical use case is dropping all + prefixes for field names like underscores in the resulting XML or omitting the package part of class names.

+ +

However, keep in mind that the algorithm must work in both directions to support deserialization.

+ + + +

Custom Name Coders

+ +

Names used e.g. in XML for attributes and element tags might contain characters or character sequences that + violate the syntax of the output format. Instead of using different aliases for such names that depend on the + output format, you may use a NameCoder implementation that transforms an internally used name to an external + form. For XML we use e.g. a NameCoder that encodes '$' characters, while the one used in JSON performs no + operation at all.

+ +

Again, keep in mind that the algorithm of the name coder must support encoding and + decoding of the names.

+ + + +

Custom Writer

+ +

A custom writer can be used to affect the output completely. XStream itself delivers solutions for different + use cases like the CompactWriter + that does not insert any white spaces between the XML tags.

+ +

Another use case for such a writer is a wrapper to drop unwanted XML elements that XStream omits on its own. + Especially if the written XML is not used for deserialization it can be useful to ignore internal attributes by + a custom writer

+ + + +

Tweaking the own implementation

+ +

As shown, XStream can be configured and enhanced in multiple way, but sometimes it is easier to tweak the + implementation of the serialized classes:

+ +
    +
  • Declaring a field transparent will omit it automatically from the processing
  • +
  • Implementing a readResolve method that can be used to initialize additional fields
  • +
  • Usage of annotations
  • +
+ + + +

Preprocessing or postprocessing

+ +

XML Transformations

+ +

Never forget, you're dealing with XML! It is easy to transform XML with an XSLT. XStream is delivered with a SAXSource + implementation, that allows an XStream instance to be the source of a XML transformer.

+ +

Example

+

Look at the following stylesheet:

+ +
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+  <xsl:output method="xml" omit-xml-declaration="yes" indent="no"/>
+  <xsl:template match="/cat">
+    <xsl:copy>
+      <xsl:apply-templates select="mName"/>
+    </xsl:copy>
+  </xsl:template>
+</xsl:stylesheet>
+ +

It is used here to remove the age of the cat on the fly (assuming XSLT is a string with the stylesheet above):

+ +
+XStream xstream = new XStream();
+xstream.alias("cat", Cat.class);
+
+TraxSource traxSource = new TraxSource(new Cat(4, "Garfield"), xstream);
+Writer buffer = new StringWriter();
+Transformer transformer = TransformerFactory.newInstance().newTransformer(
+    new StreamSource(new StringReader(XSLT)));
+transformer.transform(traxSource, new StreamResult(buffer));
+ +

The result in the buffer:

+ +
<cat>
+  <mName>Garfield</mName>
+</cat>
+ +

Format Conversion

+ +

XStream is designed to transform Java objects into a specific format and recreate these objects again. + However, XStream's readers and writers are based on an event model that can be used easily to convert the pure + data between formats. XStream contains the HierarchicalStreamCopier + tool that utilizes a reader and a writer of XStream to perform the conversion:

+ +
+HierarchicalStreamCopier copier = new HierarchicalStreramCopier();
+HierarchicalStreamDriver binaryDriver = new BinaryDriver();
+HierarchicalStreamDriver jsonDriver = new JettisonMappedXmlDriver();
+
+// transform a org.dom4j.Document into a binary stream of XStream
+ByteArrayOutputStream baos = new ByteArrayOutputStream();
+copier.copy(new Dom4JDriver.createReader(dom4JDocument), binaryDriver.createWriter(baos));
+byte[] data = baos.getBytes();
+
+// transform binary XStream data into JSON
+StringWriter strWriter = new StringWriter();
+copier.copy(binaryDriver.createReader(data), jsonDriver.createWriter(strWriter));
+String json = strWriter.toString();
+
+// transform JSON into XML:
+strWriter = new StringWriter();
+copier.copy(jsonDriver.createReader(new StringReader(json)), new PrettyPrintWriter(strWriter));
+String xml = strWriter.toString();
+ + + \ No newline at end of file diff --git a/xstream-distribution/src/content/manual.html b/xstream-distribution/src/content/manual.html new file mode 100644 index 0000000..a10c23f --- /dev/null +++ b/xstream-distribution/src/content/manual.html @@ -0,0 +1,56 @@ + + + + Documentation + + + +

Essentials

+ +
    +
  • Uses of XStream
  • +
  • Architecture Overview
  • +
+ + + + \ No newline at end of file diff --git a/xstream-distribution/src/content/news.html b/xstream-distribution/src/content/news.html new file mode 100644 index 0000000..9731b1d --- /dev/null +++ b/xstream-distribution/src/content/news.html @@ -0,0 +1,321 @@ + + + + News + + + + +

February 18, 2015 XStream 1.4.8 released

+ +

Maintenance release 1.4.8 of XStream with bug fixes and improvements running with Java 8.

+ +

XStream supports now serializable lambda types for a Java 8 runtime.

+ +

View the complete change log and download.

+ +

Note, the next major release 1.5 will require Java 6.

+ +

February 8, 2014 XStream 1.4.7 released

+ +

This maintenance release addresses mainly the security vulnerability CVE-2013-7285, an + arbitrary execution of commands when unmarshalling. All previous versions are affected running at least Java 5.

+ +

XStream contains now a security framework to fine-control the unmarshalled types.

+ +

View the complete change log and download.

+ +

December 12, 2013 XStream 1.4.6 released

+ +

Maintenance release 1.4.6 of XStream with bug fixes and improvements running with Java 8, in a GAE runtime + environment and under an active SecurityManager.

+ +

View the complete change log and download.

+ +

September 28, 2013 XStream 1.4.5 released

+ +

Maintenance release 1.4.5 of XStream with bug fixes and small improvements.

+ +
    +
  • Allow unknown XML elements to be ignored using new method XStream.ignoreUnknownElements.
  • +
  • Support for JDOM2 with JDom2Driver, JDom2Reader and JDom2Writer.
  • +
  • Optimized XML structure for java.awt.Font.
  • +
  • Referencing implementation for the ClassLoader to support environments where no new ClassLoader can be + instantiated due to security restrictions.
  • +
+ +

View the complete change log and download.

+ +

September 26, 2013 A Decade of XStream

+ +

Joe Walnes made his initial commit to the XStream project at Codehaus in 26th September 2003. + 10 years passed by and XStream celebrates its 10th birthday!

+ +

January 19, 2013 XStream 1.4.4 released

+ +

Maintenance release 1.4.4 of XStream with bug fixes and small improvements.

+ +
    +
  • DateConverter supports now localized formats.
  • +
+ +

View the complete change log and download.

+ +

July 17, 2012 XStream 1.4.3 released

+ +

Maintenance release 1.4.3 of XStream with bug fixes and small improvements. Main changes:

+ +
    +
  • Support java.util.concurrent.ConcurrentHashMap with the MapConverter.
  • +
  • Support for Hibernate 4 with XStream's Hibernate module as default for Java 6 or higher.
  • +
+ +

View the complete change log and download.

+ + +

November 3, 2011 XStream 1.4.2 released

+ +

Maintenance release 1.4.2 of XStream with bug fixes and small improvements. Main changes:

+ +
    +
  • XStream libraries can be used now directly in Android, therefore support of Java 1.4.2 has been stopped with the delivery. + Anyone who needs a version for Java 1.4.2 can build it easily from source, this build is still supported and part of CI.
  • +
  • New extended HierarchicalStreamReader interface with peekNextChild method. All XStream readers implement the new + interface (by Nikita Levyankov).
  • +
  • Special support for Collections.EMPTY_LIST, Collections.EMPTY_SET and Collections.EMPTY_MAP and collections created + with Collections.singletonList(), Collections.singletonSet() and Collections.singletonMap().
  • +
  • Support additional parameters for XStreamConverter annotation (e.g. to declare a ToAttributedValueConverter).
  • +
+ +

View the complete change log and download.

+ +

August 11, 2011 XStream 1.4.1 released

+ +

Maintenance release 1.4.1 of XStream after turning out that it did not work in 1.4 with the new default + dependencies. Therefore XStream is back with Xpp3 as default parser and refers additionally the XmlPullParser + API to enable the XppDriver that is used by default.

+ +

View the complete change log and download.

+ +

August 6, 2011 XStream 1.4 released

+ +

Finally - XStream 1.4 is ready for delivery. A lot of things have changed and improved, new features added. + Nevertheless we have maintain compatibility to the old versions:

+ +
    +
  • Detection of Java 7 and Android i.e. enabled enhanced mode and annotations for both environments out of the box
  • +
  • Direct support of XmlPullParser factory and alternate kXML2 implementation
  • +
  • Explicit drivers to select the StAX implementation
  • +
  • New separate Hibernate module to support those managed instances (special thanks to Jaime Metcher)
  • +
  • Support of implicit arrays and maps additionally to already existing implicit collection support
  • +
  • Performance improvements (special thanks to Keith Kowalczykowski)
  • +
  • Some new converters (for URI and one to write all fields but one as attributes)
  • +
  • A lot of other enhancements and bug fixes
  • +
+ +

View the complete change log and download.

+ +

Thanks to this impressive list of contributors.

+ +

Note, that with version 1.4 the default parser has been changed from + Xpp3 to kXML2.

+ +

Note, that JDK 1.3 support has been officially dropped. Nothing special has been done to + enforce this, but there is no longer any support.

+ +

Note, to support a representation of null values in some way, it is absolutely necessary that each converter can handle a null + value in its marshalling methods. If you have implemented your own custom converters, try to handle such a case also to prevent incompatibilities + in case XStream will provide such values with its next major version.

+ +

December 6, 2008 XStream 1.3.1 released

+ +

A new XStream maintenance version has been released. The release contains some + bug fixes, some minor enhancements and support of new JDKs:

+ +
    +
  • Ability to alias package names
  • +
  • Converters are only registered by default for types delivered with the JDK in use preventing + unexpected incompatibilities
  • +
  • Separation between user defined attributes and XStream attributes
  • +
  • New mode for JSONWriter to drop JSON root node
  • +
  • Support for FreeBSD's Diablo JDK.
  • +
  • Enhanced persistence package and extended tutorial.
  • +
+ +

View the complete change log and download.

+ +

Note, that XStream really supports by default now only types of the JDK in use. Especially for + CGLIB this means that support of those proxies will have to be explicitly activated + first. However, support for CGLIB proxies has been enhanced.

+ +

Note, to support a representation of null values in some way, it is absolutely necessary that each converter can handle a null + value in its marshalling methods. If you have implemented your own custom converters, try to handle such a case also to prevent incompatibilities + in case XStream will provide such values with its next major version.

+ +

February 27, 2008 XStream 1.3 released

+ +

The XStream committers proudly present XStream 1.3. This release contains some major + refactorings concerning Java annotations, improved XML support regarding encoding and + character sets, some minor new features, deprecations and a lot of bug fixes:

+ +
    +
  • Annotation support is now implemented as Mapper and Annotations can either be processed + in advance or on-the-fly (see Annotations tutorial + for limitations).
  • +
  • Improved encoding support for JSON and XML (including automated support for XML headers). + Enforceable check for valid XML characters in the written stream.
  • +
  • Dedicated converters can now be configured for individual fields also using the XStream facade.
  • +
  • New converters for java.lang.StringBuilder, java.util.UUID, javax.xml.datatype.Duration, + and javax.swing.LookAndFeel. New generic converter for types using a java.beans.PropertyEditor. + Auto-instantiated SingleValueConverter for Java enums to support enum values as attributes.
  • +
  • XML elements are now sorted by default according their declaration with the fields defined in parent + classes first to improve support for type hierarchies in XML schemata.
  • +
  • A lot of bug fixes to improve JSON support for arbitrary types. Added section in + FAQ for limitations and operation modes.
  • +
  • Native support for SAP VM.
  • +
  • All text-based files are now shipped with an appropriate license header to clean-up legal issues.
  • +
+ +

View the complete change log and download.

+ +

Note, to support a representation of null values in some way, it is absolutely necessary that each converter can handle a null + value in its marshalling methods. If you have implemented your own custom converters, try to handle such a case also to prevent incompatibilities + in case XStream will provide such values with its next major version.

+ +

May 24, 2007 XStream 1.2.2 released

+ +

A maintenance release of XStream that contains a lot of bug fixes and has some minor highlights: + +

    +
  • JSON serialization and deserialization support with the help of the new JettisonMappedXmlDriver
  • +
  • Supports customized field sorting
  • +
  • Omitting fields at deserialization time
  • +
+

View the complete change log and download.

+ +

Note, that next version of XStream will behave slightly different by default. XStream emits + all fields in declaration order like Java serialization. But in contrast to Java it will omit the fields of parent + classes last while Java serialization emits them first. This makes it difficult to match a given XML schema that + defined inherited types or leads sometimes to obscure initialization problems. However, XStream itself will not be + affected by the changed order of elements in the XML, any deserialization of current XML representations will work + fine. Anyway we will provide with XStream 1.3 a FieldKeySorter implementation that mimics the old behaviour. In + the meanwhile you can enforce the new field sorting by installing the NaturalFieldKeySorter.

+ +

November 11, 2006 XStream 1.2.1 released

+
    +
  • Introduced DocumentWriter interface and generalized functionality for all writer implementations + creating a DOM structure (DOM4J, DOM, JDom, Xom, Xpp3Dom).
  • +
  • Refactor of build system to use Maven 2. Ant still supported on XStream Core.
  • +
  • Created separate XStream Benchmark module
  • +
+

View the complete change log and download.

+ +

Oct 10, 2006Joe Walness announcing new XStream Project Lead

+

I have been the XStream project lead, since it was open sourced 3 years ago. In that time, it has attracted some + excellent developers who have formed the foundations of the user community, made all kinds of significant improvements + and pushed out new releases. It's now approaching its 1000th commit.

+ +

The development community that has formed around XStream has been outstanding - more than I could ever have + imagined. In particular, the following people have invested a lot of time into XStream, both from a technical and social point of + view:

+
    +
  • Jörg Schaible
  • +
  • Mauro Talevi
  • +
  • Guilherme Silveira
  • +
  • Jason van Zyl
  • +
  • Me (well I have!)
  • +
+ +

Recently I have been turning my attention to other things and XStream has been very much a self sustaining project. I've + decided that the project would benefit from have a project lead who can invest a lot more time than I can currently offer.

+ +

So, the new XStream project lead will be Jörg Schaible, who along with Mauro Talevi and Guilherme Silveira will carry + XStream forward. This has been happening for a long while anyway, it's just none of us ever realised or acknowledged it.

+ +

Of course, I'll still be lurking around, helping the transition, having loud mouth opinions and generally annoying people in any + way I can... you haven't got rid of me that easily. ;)

+ +

I know Jörg, Mauro and Guilherme will be able carry XStream into the next generation (we have a lot of ambitious plans + for XStream 2).

+ +

I'd also like to thank the 45(!) other contributers to the XStream project, who have all helped + make it what it is today. Finally, thanks to Graham Glass, who's Electric XML library formed a lot of the inspiration for XStream.

+ +

August 18, 2006 XStream 1.2 released

+
    +
  • Using attributes for fields (contributed by Paul Hammant and Ian Cartwright).
  • +
  • Aliasing of arbitrary attributes.
  • +
  • XStream can now serialize another XStream instance.
  • +
  • XStream has now the XStreamer, that serializes an object together with its XStream instance.
  • +
  • AnnotationConverter for fields (contributed by Guilherme Silveira).
  • +
  • PureJavaReflectionProvider supports now final fields starting with JDK 1.5
  • +
  • Any Collection type can now be declared implicit, the default implementation will be respected for unmarshalling.
  • +
  • XStream can now write all references as absolute XPath expression.
  • +
  • New SingeValueConverter allows light weight converters if the value can be represented by a unique string.
  • +
  • Aliasing of classes of a specific type.
  • +
  • Support for certain types of proxies generated with the CGLIB Enhancer.
  • +
  • Support for BEA JRockit starting with R25.1.0 (contributed by Henrik Ståhl of BEA).
  • +
  • Experimental binary reader and writer.
  • +
  • Experimental HierarichicalStreamCopier allows streams to be copied from one format to another without the overhead of serialization.
  • +
  • Experimental JSON support allows streams to be copied from one format to another without the overhead of serialization (contributed by Paul Hammant).
  • +
+

View the complete change log and download.

+ +

January 13, 2006 XStream 1.1.3 released

+
    +
  • Added XStream.toXML(OutputStream) and XStream.fromXML(InputStream).
  • +
  • Ability to prevent fields from being serialized by calling XStream.omitField() or by implementing Mapper.shouldSerializeMember().
  • +
  • Added Converter for Enum, EnumMap and EnumSet
  • +
  • Added BeanConverter and ISO8601SqlTimestampConverter
  • +
  • Fixed support for IBM JVM (contributed by Gabor Liptak)
  • +
  • Enhanced mode support for Blackdown JDK.
  • +
+

View the complete change log and download.

+ +

April 30, 2005 XStream 1.1.2 released

+

Most popular feature requests implemented.

+
    +
  • Java 5 Enum support.
  • +
  • JavaBeanConverter for serialization using getters and setters.
  • +
  • Aliasing of fields.
  • +
  • StAX integration, with namespaces.
  • +
  • Improved support on JDK 1.3 and IBM JDK.
  • +
+

View the complete change log and download.

+ +

March 7, 2005 XStream 1.1.1 released

+
    +
  • Converters can be registered with a priority, allowing more generic filters to handle classes that don't have more specific converters.
  • +
  • Converters can now access underlying HierarchicalStreamReader/Writer implementations to make implementation specific calls.
  • +
  • Improved support for classes using ObjectInputFields and ObjectInputValidation to follow the serialization specification.
  • +
  • Default ClassLoader may be changed using XStream.setClassLoader().
  • +
  • Many bugfixes and performance enhancements.
  • +
+

View the complete change log and download.

+ +

January 15, 2005 XStream 1.1 released

+
    +
  • Improved support for serializing objects as per the Java Serialization Specification: +
      +
    • Calls custom serialization methods, readObject(), writeObject(), readResolve() and writeReplace() in class, if defined.
    • +
    • Supports ObjectInputStream.getFields() and ObjectOutputStream.putFields() in custom serialization.
    • +
  • +
  • Provides implementations of ObjectInputStream and ObjectOutputStream, allowing drop in replacements for standard serialization, + including support for streams of objects. [More...]
  • +
  • Reads and writes directly to most XML Java APIs: DOM, DOM4J, JDOM, XOM, Electric XML, StAX, Trax (write only), SAX (write only). + [More...]
  • +
+

View the complete change log and download.

+ + + diff --git a/xstream-distribution/src/content/objectstream.html b/xstream-distribution/src/content/objectstream.html new file mode 100644 index 0000000..c791955 --- /dev/null +++ b/xstream-distribution/src/content/objectstream.html @@ -0,0 +1,103 @@ + + + + Object Streams Tutorial + + + + +

XStream provides alternative implementations of java.io.ObjectInputStream and + java.io.ObjectOutputStream, + allowing streams of objects to be serialized or deserialized from XML.

+

This is useful when processing large sets of objects, as only one needs to be in memory + at a time.

+

Obviously you should use also a stream-based XML parser reading the XML. A DOM-based XML parser + will process the complete XML and build the object model before XStream is able to to handle the first + element.

+ + + +

Using the Object Streams

+ +

The interface to the object streaming capabilities of XStream is through the standard + java.io.ObjectOutputStream and java.io.ObjectInputStream objects.

+ +

Example

+ +

To serialize a stream of objects to XML:

+ +
ObjectOutputStream out = xstream.createObjectOutputStream(someWriter);
+
+out.writeObject(new Person("Joe", "Walnes"));
+out.writeObject(new Person("Someone", "Else"));
+out.writeObject("hello");
+out.writeInt(12345);
+
+out.close();
+ +

The resulting XML:

+ +
<object-stream>
+  <com.blah.Person>
+    <firstname>Joe</firstname>
+    <lastname>Walnes</lastname>
+  </com.blah.Person>
+  <com.blah.Person>
+    <firstname>Someone</firstname>
+    <lastname>Else</lastname>
+  </com.blah.Person>
+  <string>hello</string>
+  <int>123</int>
+</object-stream>
+ +

To deserialze the stream of objects from the XML:

+ +
ObjectInputStream in = xstream.createObjectInputStream(someReader);
+
+Person a = (Person)in.readObject();
+Person b = (Person)in.readObject();
+String c = (String)in.readObject();
+int    d = in.readInt();
+ + + +

Considerations

+ +

Root node

+ +

Because an XML document can only have a single root node, all the serialized elements must be wrapped in an + additional root node. This root node defaults to <object-stream>, as shown in the example above.

+ +

This can be changed by using the overloaded method: + xstream.createObjectOutputStream(Writer writer, String rootNodeName);

+ +

Close the ObjectOutputStream

+ +

Remember to call ObjectOutputStream.close(), otherwise the stream will contain incomplete XML.

+ +

Detecting the end of the ObjectInputStream

+ +

When there are no more objects left to read in the stream, ObjectInputStream.readObject() (or primitive + equivalent) will throw java.io.EOFException.

+ +

References

+ +

Normally XStream will not know about references between the different objects that are written individually in the ObjectStream. + Nevertheless there is an example in the acceptance tests (MultipleObjectsInOneStreamTest) where such a functionality is realized with + the help of a custom MarshallingStrategy. Note, that this implementation is not for general use, since it will ignore some parameters at + second invocation, but they do not matter in the demonstrated use case. Additionally those references prevent the objects from being + garbage collected, which is a bit counter-productive for the use case of ObjectStreams as described above. So you have to know what + you do!

+ + + \ No newline at end of file diff --git a/xstream-distribution/src/content/parser-benchmarks.html b/xstream-distribution/src/content/parser-benchmarks.html new file mode 100644 index 0000000..98e9b53 --- /dev/null +++ b/xstream-distribution/src/content/parser-benchmarks.html @@ -0,0 +1,145 @@ + + + + Parser Benchmarks + + + + +

Benchmark results are always dependent on a very individual setup. Normally it is not useful to generalize such results + for every use case, but it can give you a hint. However, if you're really in the need of maximum performance, you should + probably create an own benchmark with your objects or even use a profiler to detect the real hot spots in your application.

+ +

Benchmark Values

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParserSingle Value ConvertersStandard ConvertersReflection ConverterSerializable Converter
W3C DOM1823.01495.01437.01758.0
JDOM2620.01796.01776.02030.0
DOM4J1824.01811.02636.02177.0
XOM571.0716.0995.0958.0
StAX (BEA)430.0359.0531.0737.0
StAX (Woodstox)357.0344.0535.0725.0
StAX (SJSXP)332.0445.0491.0667.0
XPP (Xpp3)351.0395.0544.0743.0
XPP (kXML2)299.0353.0517.0761.0
XppDom (Xpp3)351.0395.0544.0743.0
XppDom (kXML2)299.0353.0517.0761.0
+ +

Setup

+ +

The values have been generated running the ParserBenchmark harness of the XStream benchmark module's test code.

+ +
+
Single Value Converters
+
A list with a set of 10 objects of different types (like String, int, File, Locale, Double, ...) that will + be all handled by a SingleValueConverter.
+
Standard Converters
+
A list with a set of 6 objects of different types (like Properties, Color, Class, Method, ...) that will + be all handled by a specialized converter processing nested XML elements.
+
Reflection Converter
+
A list with a set of 6 objects of different types (One, Five of the XStream benchmark package) that will be + all handled by the ReflectionConverter.
+
Serializable Converter
+
A list with a set of 6 objects of different types (SerializableOne, SerializableFive of the XStream + benchmark package) that will be all handled by the SerializableConverter.
+
JavaBean Converter
+
A list with a set of 6 objects of different types (OneBean, FiveBean of the XStream benchmark package) that + will be all handled by the JavaBeanConverter. This converter has been registered especially for this two types.
+
+ +

Environment

+ +

The values above's unit is ms measured after 1000 unmarshalling operations with the object graphs described in + 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 + (32-bit) in Gentoo Linux. Note again, that these values are no replacement for real profiler results and they may + vary from run to run for ~100ms due to this machine's background processes on a single CPU. However, it can give + you some idea of what you can expect using different parser technologies.

+ + + \ No newline at end of file diff --git a/xstream-distribution/src/content/persistence-tutorial.html b/xstream-distribution/src/content/persistence-tutorial.html new file mode 100644 index 0000000..3519df9 --- /dev/null +++ b/xstream-distribution/src/content/persistence-tutorial.html @@ -0,0 +1,185 @@ + + + + Persistence API Tutorial + + +

Challenge

+

Suppose that you need a easy way to persist some objects in the file system. Not just one, but a whole collection. +The real problem arrives when you start using java.io API in order to create one output stream for each object, showing +itself to be really painful - although simple.

+

Imagine that you have the following Java class, a basic Author class (stolen from some other tutorial):

+
package com.thoughtworks.xstream;
+
+public class Author {
+        private String name;
+        public Author(String name) {
+                this.name = name;
+        }
+        public String getName() {
+                return name;
+        }
+}
+

By using the XmlArrayList implementation of java.util.List you get an easy way to write all authors to disk

+

The XmlArrayList (and related collections) receives a PersistenceStrategy during its construction. This Strategy decides +what to do with each of its elements. The basic implementation - our need - is the FilePersistenceStrategy, capable of +writing different files to a base directory.

+
+// prepares the file strategy to directory /tmp
+PersistenceStrategy strategy = new FilePersistenceStrategy(new File("/tmp"));
+
+

We can easily create an XmlArrayList from that strategy:

+
+// prepares the file strategy to directory /tmp
+PersistenceStrategy strategy = new FilePersistenceStrategy(new File("/tmp"));
+// creates the list:
+List list = new XmlArrayList(strategy);
+
+

Adding elements

+

Now that we have an XmlArrayList object in our hands, we are able to add, remove and search for objects as usual. +Let's add five authors and play around with our list:

+
package org.codehaus.xstream.examples;
+
+public class AddAuthors {
+
+	public static void main(String[] args) {
+	
+		// prepares the file strategy to directory /tmp
+		PersistenceStrategy strategy = new FilePersistenceStrategy(new File("/tmp"));
+		// creates the list:
+		List list = new XmlArrayList(strategy);
+		
+		// adds four authors
+		list.add(new Author("joe walnes"));
+		list.add(new Author("joerg schaible"));
+		list.add(new Author("mauro talevi"));
+		list.add(new Author("guilherme silveira"));
+		
+		// adding an extra author
+		Author mistake = new Author("mama");
+		list.add(mistake);
+	
+	}
+}
+
+

If we check the /tmp directory, there are five files: int@1.xml, int@2.xml, int@3.xml, int@4.xml, int@5.xml, each +one containing the XML serialized form of our authors.

+

Playing around

+

Let's remove mama from the list and iterate over all authors:

+
package org.codehaus.xstream.examples;
+
+public class RemoveMama {
+
+	public static void main(String[] args) {
+	
+		// prepares the file strategy to directory /tmp
+		PersistenceStrategy strategy = new FilePersistenceStrategy(new File("/tmp"));
+		// looks up the list:
+		List list = new XmlArrayList(strategy);
+		
+		// remember the list is still there! the files int@[1-5].xml are still in /tmp!
+		// the list was persisted!
+		
+		for(Iterator it = list.iterator(); it.hasNext(); ) {
+			Author author = (Author) it.next();
+			if(author.getName().equals("mama")) {
+				System.out.println("Removing mama...");
+				it.remove();
+			} else {
+				System.out.println("Keeping " + author.getName());
+			}
+		}
+	
+	}
+}
+
+

The result?

+
Keeping joe walnes
+Keeping joerg schaible
+Keeping mauro talevi
+Keeping guilherme silveira
+Removing mama...
+
+

Local Converter

+

Another use case is to split the XML into master/detail documents by declaring a local converter for a collection +(or map) based on the collection types in XStream's persistence package. Think about a volume grouping different type of documents:

+
public abstract class AbstractDocument {
+	String title;
+} 
+public class TextDocument extends AbstractDocument {
+	List chapters = new ArrayList();
+} 
+public class ScannedDocument {
+	List images = new ArrayList();
+} 
+public Volume {
+	List documents = new ArrayList();
+}
+
+

The documents might be big (especially the ones with the scanned pages), therefore it might be nice to separate each +document into an own file. With the help of a local converter utilizing an XmlArrayList this is straight forward:

+
public final class PersistenceArrayListConverter implements Converter {
+	private XStream xstream;
+	
+	public PersistenceArrayListConverter(XStream xstream) {
+		this.xstream = xstream;
+	}
+
+	public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
+		File dir = new File(System.getProperty("user.home"), "documents");
+		XmlArrayList list = new XmlArrayList(new FilePersistenceStrategy(dir, xstream));
+		context.convertAnother(dir);
+		list.addAll((Collection)source); // generate the external files
+	}
+
+	public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
+		File directory = (File)context.convertAnother(null, File.class);
+		XmlArrayList persistentList = new XmlArrayList(new FilePersistenceStrategy(directory, xstream));
+		ArrayList list = new ArrayList(persistentList); // read all files
+		persistentList.clear(); // remove files
+		return list;
+	}
+
+	public boolean canConvert(Class type) {
+		return type == ArrayList.class;
+	}
+}
+
+

This converter will use a given XStream to store each element of an ArrayList into an own file located in the user's home +directory in the folder documents. The master XML will now contain the name of the target folder +instead of the marshalled documents. In our case those documents are destroyed if the volume is unmarshalled again. See the +initialization of the XStream:

+
XStream = new XStream();
+xstream.alias("volume", Volume.class);
+xstream.registerLocalConverter(Volume.class, "documents", new PersistenceArrayListConverter(xstream));
+
+Volume volume = new Volume();
+volume.documents.addAll(...); // add a lot of documents
+String xml = xstream.toXML(volume);
+
+

The resulting XML will be very simple:

+
<volume>~/documents</volume>
+
+

The documents can be found in individual files in the target folder with names like int@<index>.xml.

+ +

Going further

+

From this point on, you can implement different PersistentStrategy algorithms in order to generate other behaviour (e.g. +persisting the objects in a database) using your XmlArrayList collection, or try the other implementations: XmlSet and XmlMap +and you may create your own local converters. As an alternative to a converter you might use the persistent collection type +directly as member instance, the effect is similar - give it a try!

+ +

See also XBird that makes usage of this XStream API to support object +persistence.

+ + + diff --git a/xstream-distribution/src/content/references.html b/xstream-distribution/src/content/references.html new file mode 100644 index 0000000..d50ffc7 --- /dev/null +++ b/xstream-distribution/src/content/references.html @@ -0,0 +1,165 @@ + + + + References + + + +

XStream is used in a lot of commercial and open source projects and is used in production since years.

+ + + +

XStream used for Core Technology

+ +

Atlassian Bamboo

+ +

Bamboo is build server for continuous integration + and release management. Note, XStream itself uses Bamboo + at Codehaus for continuous integration.

+ +

Atlassian Confluence

+ +

Confluence is an enterprise wiki that makes it + easy for your team to collaborate and share knowledge.

+ +

Oracle Hudson CI

+ +

Hudson CI is also a build server for continuous + integration and release management.

+ +

Apache Muse

+ +

The Apache Muse Project is a Java-based implementation of the + WS-ResourceFramework (WSRF), + WS-BaseNotification (WSN), and + WS-DistributedManagement (WSDM) specifications. + It is a framework upon which users can build web service interfaces for manageable resources without having to + implement all of the "plumbing" described by the aforementioned standards. Applications built with Muse can be + deployed in both Apache Axis2 and OSGi environments, and the project includes a set of command line tools that + can generate the proper artifacts for your deployment scenario.

+ +

NanoContainer

+ +

The scope of the NanoContainer project is to complement the + PicoContainer project, providing it with additional functionality. The + project comprises of several components which can either be adoptions in various guises of PicoContainer (e.g. + composition by-class-name rather than by-class), or adaptations to external components bringing them closer to the + Dependency Injection ideal - particularly + Constructor Injection.

+ +

Murq

+ +

Murq is a persistence framework with an emphasis on simplicity. + It is also capable of storing binary data and meta data, supports search functionality and makes internationalization + seamless.

+ +

XBird

+ +

XBird is a light-weight XQuery processor and database system + written in Java. The light-weight means reasonably fast and embeddable. It uses the + XStream persistence API for + object persistence

+ +

EJOE

+ +

EJOE is a lightweight Java remoting framework built to send + and receive objects through pluggable (de)serialization mechanisms. XStream provides the + default (de)serialization mechanism.

+ +

OpenCraft

+ +

OpenCraft is an alternative/custom Minecraft server, written + in Java, compatible with the original protocol. XStream provides the persistence layer.

+ +

XStream Support

+ +

jBoss ESB

+ +

jBossESB is the next generation of EAI - better and without the + vendor-lockin characteristics of old. It uses a flexible architecture based on SOA principles such as loose-coupling + and asynchronous message passing, emphasizing an incremental approach to adopting and deploying an SOI. XStream + can be used as one possibility for the messaging part.

+ +

Restlet

+ +

Restlet is a lightweight REST framework for Java that lets you embrace + the architecture of the Web and benefit from its simplicity and scalability. By leveraging our innovative REST engine, + you can start blending your Web Sites and Web Services into uniform Web Applications!

+ +

The framework uses XStream as + extension for a representation of objects in XML or JSON and a ConverterService based on this functionality.

+ +

ActiveSOAP

+ +

ActiveSOAP is a lightweight & easily embeddable + REST and SOAP stack based on + StAX with support for + WS-Addressing and + WSIF. ActiveSOAP uses StAX (the Standard API for pull parsing) + to implement the SOAP protocols and then it delegates to plugin + Handler objects + for the heavy duty processing of the XML payloads. This means that you only need to pay for what you need; use fast + pull based event parsing or full data binding mechanisms like JAXB or XStream or DOMish APIs like XMLBeans when they + make sense.

+ +

Mule

+ +

Mule is the leading open source ESB (Enterprise Service Bus) and integration + platform. It is a scalable, highly distributable object broker that can seamlessly handle interactions with services and + applications using disparate transport and messaging technologies. Transformers are used to convert inbound data to an + object type required by the UMO Component or outbound to an object type required by the transport such as a JmsMessage. + Mule uses Transformers to convert event data between + the different endpoints. They can be configured on endpoints that receive data to ensure that the expected object type is + always received by a Mule Component. XStream is used for standard XML to Java object transformation.

+ +

Blojsom

+ +

Blojsom is Java-based, full-featured, multi-blog, multi-user software package + that was inspired by blosxom. blojsom aims to retain a simplicity in design while adding flexibility in areas such as the flavors, + templating, plugins, and the ability to run multiple blogs with a single blojsom installation. XStream is used for export.

+ +

FlatTree

+ +

FlatTree is a Java library for reading and + writing of flat files: CSV, FLR (fixed length record) or mixed structures. It features a tree-style processing API, adapters + for SAX, Stax and XStream for transformation, + data binding or serialization.

+ +

Blogs and Articles

+ + + + + diff --git a/xstream-distribution/src/content/repository.html b/xstream-distribution/src/content/repository.html new file mode 100644 index 0000000..f9a6f32 --- /dev/null +++ b/xstream-distribution/src/content/repository.html @@ -0,0 +1,63 @@ + + + + Source Repository + + + +

Modules

+ + XStream project consists of several modules: +
    +
  1. xstream - the core module
  2. +
  3. xstream-benchmark - the benchmark tool
  4. +
  5. xstream-distribution - the module contains the documentation and assembles the src and bin distributions
  6. +
+ 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. +
svn co http://svn.codehaus.org/xstream/trunk/[module]
+ to checkout out the single module separately. + +

Browser

+ +

You can use the browser to navigate within the sources online + with the help of the FishEye installation on Codehaus.

+ +

Subversion

+ + XStream uses Subversion as the SCM. See Subversion website for details and documentation on IDE integration. + +

WebDav Access

+ + WebDav is an access protocol supported by SVN and being http-based is often allowed by corporate firewalls. + +

Anonymous Access

+ +
svn co http://svn.codehaus.org/xstream/trunk
+ +

+ You might also use this URL to browse the repository in a simple manner. +

+ +

Committer Access

+ +
svn co https://svn.codehaus.org/xstream/trunk
+ +

+ This access protocol is available to all, but only developers can commit changes. +

+

+ Developers require a LDAP password for Codehaus username (contact Bob at the Haus to get assigned a password if you don't have one). +

+ + + diff --git a/xstream-distribution/src/content/security.html b/xstream-distribution/src/content/security.html new file mode 100644 index 0000000..16bcfdd --- /dev/null +++ b/xstream-distribution/src/content/security.html @@ -0,0 +1,255 @@ + + + + Security Aspects + + + +

XStream is designed to be an easy to use library. It takes its main task seriously: converting Java objects to + XML, and XML to Java objects. As a result, it is possible to create an instance of XStream with the default + constructor, call a method to convert an object into XML, then call another method to turn the XML back into an + equivalent Java object. By design, there are few limits to the type of objects XStream can handle.

+ +

This flexibility comes at a price. XStream applies various techniques under the hood to ensure it is able to + handle all types of objects. This includes using undocumented Java features and reflection. The XML generated by + XStream includes all information required to build objects of almost any type. This introduces a potential + security problem.

+ +

The XML provided to XStream for conversion to a Java object can be manipulated to inject objects into the + unmarshalled object graph, which were not present at marshalling time. An attacker could exploit this to execute + arbitrary code or shell commands in the context of the server running the XStream process. This issue is + identified by CVE-2013-7285.

+ +

Note that the XML data could be manipulated on different levels. For example, manipulating values on existing + objects (such as a price value), or breaking the format and causing the XML parser to fail. The latter case will + raise an exception, but the former case must be handled by validity checks in any application which processes + user-supplied XML. The worst case scenario is injection of arbitrary code or shell commands, as noted above.

+ +

External Security

+ +

An active Java Security Manager can prevent actions required by XStream components or converters. The same + applies to environments such as Google Application Engine. XStream tries to some extent to check the functionality + of a converter before it claims to handle a type.

+          +

Therefore it is possible that XStream behaves differently in such an environment, because a converter suddenly + no longer handles a special type or any type at all. It is essential that an application that will have to run in + such an environment is tested at an early stage to prevent nasty surprises.

+ +

Implicit Security

+ +

As explained above, it is possible to inject other object instances if an attacker is able to define the data + used to deserialize the Java objects (typically XML, but XStream supports other formats like JSON). A known + exploit can be created with the help of the Java runtime library using the Java Bean + EventHandler. As an instance + for the InvocationHandler + of a dynamic proxy, it can be used to install a redirect for an arbitrary call to the original object to the method + of a completely different instance of an embedded object of the EventHandler itself.

+          +

This scenario can be used perfectly to replace/inject a dynamic proxy with such an EventHandler at any location + in the XML where its parent expects an object of such an interface's type or a simple object instance (any list + element will suffice). The usage of a ProcessBuilder as an embedded element, coupled with the redirection of any + call to the ProcessBuilder's start() + method allows an attacker to call shell commands. Knowing how to define such an attack is the only prerequisite.

+          +

Starting with XStream 1.4.7, an instance of the EventHandler is no longer handled by default. You have to + explicitly register a ReflectionConverter for the EventHandler type, if your application has the requirement to + persist such an object. However, you still have to take special care regarding the location of the persisted data, + and how your application can ensure its integrity.

+          +

Note: this vulnerability is not even a special problem of XStream. XML being deserialized by + XStream acts here like a script, and the scenario above can be created with any script that is executed within a + Java runtime (e.g. using its JavaScript interpreter) if someone is able to manipulate it externally. The key + message for application developers is that deserializing arbitrary user-supplied content is a dangerous proposition + in all cases.

+ +

Explicit Security

+ +

While XStream implicitly avoids the vulnerability scenario with the EventHandler class, there might be other + combinations with types from well-known and commonly-used Java libraries such as ASM, CGLIB, Groovy, or even in + the Java runtime, that are currently simply unknown.

+      +

Starting with XStream 1.4.7, it is possible to define permissions for types, to check + the type of an object that should be unmarshalled. Those permissions can be used to allow or deny types explicitly. + With these permissions it is at least not possible to inject unexpected types into an object graph. Any application + that deserializes data from an external source should at least use this feature to limit the danger of arbitrary + command execution.

+          +

Apart from value manipulations, this implementation still allows the injection of allowed + objects at wrong locations, e.g. inserting an integer into a list of strings.

+          +

Separate to the XStream security framework, it has always been possible to overwrite the setupConverter method + of XStream to register only the required converters.

+ +

XML Validation

+ +

XML itself supports input validation using a schema and a validating parser. With XStream, you can use e.g. a + StAX parser for validation, but it will take some effort to ensure that the XML read and written by XStream matches + the schema in first place. Typically you will have to write some custom converters, but it can be worth the effort + depending on the use case.

+ +

Security Framework

+ +

Noted above, it might be possible that other combinations are found with the Java runtime itself, or other + commonly-used Java libraries that allow a similar vulnerability like the known case using the Java Beans + EventHandler. To prevent such a possibility at all, XStream version 1.4.7 and above contains a security framework, + allowing application developers to define which types are allowed to be unmarshalled with XStream.

+          +

The core interface is TypePermission. + The SecurityMapper will evaluate a list + of registered instances for every type that will be required while unmarshalling input data. The interface has one + simple method:

boolean allow(Class<?>);
+          +

The XStream facade provides the following methods to + register such type permissions within the SecurityMapper:

+
XStream.addPermission(TypePermission);
+XStream.allowTypes(Class[]);
+XStream.allowTypes(String[]);
+XStream.allowTypesByRegExp(String[]);
+XStream.allowTypesByRegExp(Pattern[]);
+XStream.allowTypesByWildcard(String[]);
+XStream.allowTypeHierary(Class);
+XStream.denyPermission(TypePermission);
+XStream.denyTypes(Class[]);
+XStream.denyTypes(String[]);
+XStream.denyTypesByRegExp(String[]);
+XStream.denyTypesByRegExp(Pattern[]);
+XStream.denyTypesByWildcard(String[]);
+XStream.denyTypeHierary(Class);
+ +

The sequence of registration is essential. The most recently registered permission will be evaluated first.

+          +

Every TypePermission has three options to implement the allow method and make decisions on the provided type:

+

    +
  • if the method returns true, the type is accepted and no other permissions are evaluated
  • +
  • if the method returns false, the implementation cannot judge over the type and the SecurityMapper will + continue with the next permission instance in its registration list
  • +
  • the method throws a ForbiddenClassException + to stop the unmarshalling process
  • +
+          +

Predefined Permission Types

+ +

XStream provides some TypePermission implementations to allow any or no type at all, to allow primitive types + and their counterpart, null, array types, implementations match the name of the type by regular or wildcard + expression and one to invert a permission.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PermissionDescriptionExampleDefault
AnyTypePermissionAllow any type. You may use the ANY instance directly. A registration of this permission will wipe any + prior one. yes
ArrayTypePermissionAllow any array type. You may use the ARRAYS instance directly. no
CGLIBProxyTypePermissionAllow any CGLIB proxy type. You may use the PROXIES instance directly. no
ExplicitTypePermissionAllow types explicitly by name. 
InterfaceTypePermissionAllow any interface type. You may use the INTERFACES instance directly. no
NoPermissionInvert any other permission. Instances of this type are used by XStream in the deny methods. no
NoTypePermissionAllow no type. You may use the NONE instance directly. A registration of this permission will wipe any + prior one. 
NullPermissionAllow null as type. You may use the NULL instance directly. no
PrimitiveTypePermissionAllow any primitive type and its boxed counterpart (incl void). You may use the PROXIES instance directly. no
ProxyTypePermissionAllow any Java proxy type. You may use the PROXIES instance directly. no
RegExpTypePermissionAllow any type that matches with its name a regular expression..*\\.core\\..*
[^$]+
TypeHierarchyPermissionAllow types of a hierarchy. 
WildcardTypePermissionAllow any type that matches with its name a wildcard expression.java.lang.*
java.util.**
+ +

Example Code

+ +

XStream uses the AnyTypePermission by default, i.e. any type is accepted. You have to clear out this default + and register your own permissions to activate the security framework (the Blog type is from the + Alias Tutorial):

+
XStream xstream = new XStream();
+// clear out existing permissions and set own ones
+xstream.addPermission(NoPermissionType.NONE);
+// allow some basics
+xstream.addPermission(NullPermission.NULL);
+xstream.addPermission(PrimitiveTypePermission.PRIMITIVES);
+xstream.allowTypeHierarchy(Collection.class);
+// allow any type from the same package
+xstream.allowTypesByWildcard(new String[] {
+    Blog.class.getPackage().getName()+".*"
+});
+
+ +

You may have a further look at XStream's acceptance tests, the security framework is enabled there in general.

+ + diff --git a/xstream-distribution/src/content/team.html b/xstream-distribution/src/content/team.html new file mode 100644 index 0000000..24d8643 --- /dev/null +++ b/xstream-distribution/src/content/team.html @@ -0,0 +1,128 @@ + + + + Development Team + + + +

Project Founder

+ +
    +
  • Joe Walnes
  • +
+ +

Project Lead

+ +
    +
  • Jörg Schaible
  • +
+ +

Active Committers

+ +
    +
  • Joe Walnes
  • +
  • Mauro Talevi
  • +
  • Jörg Schaible
  • +
  • Guilherme Silveira
  • +
+ +

Hibernating Committers

+ +
    +
  • Jason van Zyl
  • +
  • Nat Pryce
  • +
  • Dan North
  • +
+ +

Contributors

+ +

List in sequence of first contribution to XStream.

+ +
    +
  • Tim Mackinnon
  • +
  • James Strachan
  • +
  • Jon Tirsén
  • +
  • Marcos Tarruella
  • +
  • Khurram Chaudhary
  • +
  • Brock Bulger
  • +
  • Paul Hammant
  • +
  • Nicky Sandhu
  • +
  • J. Matthew Pryor
  • +
  • Aslak Hellesøy
  • +
  • Nick Pomfret
  • +
  • Brian Slesinsky
  • +
  • Konstantin Pribluda
  • +
  • Ben Smith
  • +
  • Brian Oxley
  • +
  • Chris Kelly
  • +
  • Matthew Sandoz
  • +
  • Veaceslav Chicu
  • +
  • Jose A. Illescas
  • +
  • Laurent Bihanic
  • +
  • Martin Weindel
  • +
  • Michael Kopp
  • +
  • Brian Selinsky
  • +
  • Daniel Sheppard
  • +
  • Chris Nokleberg
  • +
  • Henri Tremblay
  • +
  • Simon Daniel
  • +
  • Eric Snell
  • +
  • Andrea Aime
  • +
  • Bryan Coleman
  • +
  • Kevin Ring
  • +
  • Trygve Laugstøl
  • +
  • Hannes Havel
  • +
  • Gábor Lipták
  • +
  • Baba Buehler
  • +
  • Emil Kirschner
  • +
  • Chung-Onn Cheong
  • +
  • Ian Cartwright
  • +
  • Costin Leau
  • +
  • Stefano Girotti
  • +
  • David Blevins
  • +
  • Henrik Ståhl of BEA
  • +
  • Cyrille Le Clerc
  • +
  • John Kristian
  • +
  • Chris Winters
  • +
  • Lucio Benfante
  • +
  • Nicolas Gros d'Aillon
  • +
  • Dejan Bosanac
  • +
  • Rene Schwietzke
  • +
  • Hinse ter Schuur
  • +
  • Adrian Wilkens
  • +
  • Jukka Lindström
  • +
  • Kevin Conaway
  • +
  • Kevin Bowman
  • +
  • Tatu Saloranta
  • +
  • Jerome Lacoste
  • +
  • Reto Bachmann-Gmür
  • +
  • Steven Sparling
  • +
  • Alexander Radzin
  • +
  • Doug Daniels
  • +
  • Jason Greanya
  • +
  • Carlos Roman
  • +
  • Jaime Metcher
  • +
  • Michael Schnell
  • +
  • Nikita Levyankov
  • +
  • Kohsuke Kawaguchi
  • +
  • Peter Abeles
  • +
  • Edison Guo
  • +
  • Rico Neubauer
  • +
  • David Jorm
  • +
+ +

Please direct all correspondence about XStream to the users' mailing lists + rather than directly to one of the team.

+ + + diff --git a/xstream-distribution/src/content/tutorial.html b/xstream-distribution/src/content/tutorial.html new file mode 100644 index 0000000..82f69e2 --- /dev/null +++ b/xstream-distribution/src/content/tutorial.html @@ -0,0 +1,122 @@ + + + + Two Minute Tutorial + + + +

This is a very quick introduction to XStream. + Skim read it to get an idea of how simple it is to convert objects to XML and back again. + I'm sure you'll have questions afterwards.

+ +

Create classes to be serialized

+ +

Here's a couple of simple classes. XStream can convert instances of these to XML and back again.

+ +
public class Person {
+  private String firstname;
+  private String lastname;
+  private PhoneNumber phone;
+  private PhoneNumber fax;
+  // ... constructors and methods
+}
+
+public class PhoneNumber {
+  private int code;
+  private String number;
+  // ... constructors and methods
+}
+ +

Note: Notice that the fields are private. XStream doesn't care about the + visibility of the fields. No getters or setters are needed. Also, XStream + does not limit you to having a default constructor.

+ +

Initializing XStream

+ +

To use XStream, simply instantiate the XStream class:

+ +
XStream xstream = new XStream();
+ +

You require xstream-[version].jar, xpp3-[version].jar and + xmlpull-[version].jar in the classpath. Xpp3 + is a very fast XML pull-parser implementation. If you do not want to include these dependencies, you can use a standard + JAXP DOM parser or since Java 6 the integrated StAX parser instead:

+ +
XStream xstream = new XStream(new DomDriver()); // does not require XPP3 library
+
XStream xstream = new XStream(new StaxDriver()); // does not require XPP3 library starting with Java 6
+ +

Note: This class is a simple facade designed for common operations. For more flexibility you + may choose to create your own facade that behaves differently.

+ +

Now, to make the XML outputted by XStream more concise, you can create aliases for your custom class names + to XML element names. This is the only type of mapping required to use XStream and even this is optional.

+ +
xstream.alias("person", Person.class);
+xstream.alias("phonenumber", PhoneNumber.class);
+ +

Note: This is an optional step. Without it XStream would work fine, but the XML element names would + contain the fully qualified name of each class (including package) which would bulk up the XML a bit. See the + Alias Tutorial a more complete introduction.

+ +

Serializing an object to XML

+ +

Let's create an instance of Person and populate its fields:

+ +
Person joe = new Person("Joe", "Walnes");
+joe.setPhone(new PhoneNumber(123, "1234-456"));
+joe.setFax(new PhoneNumber(123, "9999-999"));
+ +

Now, to convert it to XML, all you have to do is make a simple call to XStream:

+ +
String xml = xstream.toXML(joe);
+ +

The resulting XML looks like this:

+ +
<person>
+  <firstname>Joe</firstname>
+  <lastname>Walnes</lastname>
+  <phone>
+    <code>123</code>
+    <number>1234-456</number>
+  </phone>
+  <fax>
+    <code>123</code>
+    <number>9999-999</number>
+  </fax>
+</person>
+ +

It's that simple. Look at how clean the XML is.

+ +

Deserializing an object back from XML

+ +

To reconstruct an object, purely from the XML:

+ +
Person newJoe = (Person)xstream.fromXML(xml);
+ +

And that's how simple XStream is!

+ +

Summary

+ +

To recap:

+ +
    +
  • Create element name to class name aliases for any custom classes using xstream.alias(String elementName, Class cls);
  • +
  • Convert an object to XML using xstream.toXML(Object obj);
  • +
  • Convert XML back to an object using xstream.fromXML(String xml);
  • +
+ +

maybe you like to read the alias tutorial to see more possibilities how you can rename things using XStream. +Or look into the condensed overview how to configure XStream to tweak the output.

+ + + diff --git a/xstream-distribution/src/content/versioning.html b/xstream-distribution/src/content/versioning.html new file mode 100644 index 0000000..5feab90 --- /dev/null +++ b/xstream-distribution/src/content/versioning.html @@ -0,0 +1,103 @@ + + + + About Versioning + + + +

The XStream project follows strict rules that govern its use of version + numbers. The version number of a release indicates how that release + is compatible with previous and future releases.

+ +

Version numbers have the form + major.minor.patch. A major + version identifies the product stage of the project. Two libraries with + different major version are designed to work together in the same + application. This implies a major change in the API - either by not + sharing the same types or using a different package name.

+ +

The minor version number identifies the API version. A release that + changes the API in a way that breaks backwards compatibility will increment + the minor version number and reset the patch version to zero. The patch + version number identifies the backwards compatible revision of the API. A + change in the minor version will still be mostly backward compatible, but + may need some compatibility settings or slight migration adjustments. The + patch version number identifies revisions that do not change the API + although new API elements may occur or existing API may be deprecated to + prepare users for the next release with a change in the minor version. A + release that fixes bugs or refactors implementation details without changing + the API will have the same minor and major versions as the previous release + and increment the patch number.

+ +

A hypothetical example:

+ + + + + + + + + + + +
1.0.0First release
1.0.1Improves Javadoc comments, fixes bug
1.1.0Adds new API elements, may cause some migration
1.1.1Adds new API elements, deprecates some API elements
1.1.2Fixes bugs
1.2.0Adds new API, needs some migration effort and removes deprecated elements
2.0.0Complete API redesign, can be used simultanly with 1.x series.
2.0.1Deprecates API, fixes bugs
2.1.0Adds new API elements
etc.etc.
+ +

Release Candidates

+ +

Before a new major or minor release, XStream will make release + candidate (RC) packages available so that users can test them against + their own code. There will be one or more release candidates given the + version major.minor.0 RCn, where the + major and minor version numbers identify the upcoming release and RC1 + identifies the first candidate release, RC2 the second, and so on.

+ +

A release candidate does not guarantee backward compatibility with + new API features introduced by any previous RC of the same upcoming + version. + A major version RC can change/remove API features introduced in a + previous RC for the same major version; a minor version RC can change + API features introduced by any previous RC of the same upcoming minor + version but guarantees backward compatibility with the previous minor + version.

+ +

Development Snapshots

+ +

During development, the the developers may publish snapshot packages + from time to time. These are not guaranteed to be complete: + Although the unit tests will all pass the snapshot will probably contain + failing acceptance tests that describe planned or requested features that + have not yet been implemented. Snapshots are identified by the UTC time + at which the package was built. The timestamp has the form + VERSION-YYYYMMDD.hhmmss-n, where VERSION is the upcoming + version, YYYY is the (four-digit) year, MM the month, DD the day, hh the + hour, mm the minute, ss the second and n a sequential number.

+ +

Internal Classes

+ +

Many classes are for internal use only and not designed to be used by + end users. These are exempt from the versioning rules above.

+ +

Such classes are clearly marked as internal in the source code + headers and are excluded from the published JavaDoc.

+ +

Versioning and Deprecation

+ +

A patch release might deprecate some API features. Deprecated features + will not actually be removed until the next minor release. + A release will never remove API features that have not been deprecated in + a previous release. +

+ + + \ No newline at end of file diff --git a/xstream-distribution/src/content/website.xml b/xstream-distribution/src/content/website.xml new file mode 100644 index 0000000..f304e03 --- /dev/null +++ b/xstream-distribution/src/content/website.xml @@ -0,0 +1,65 @@ + + +
+ Software + index.html + news.html + changes.html + versioning.html +
+
+ Evaluating XStream + tutorial.html + graphs.html + manual-tweaking-output.html + license.html + download.html + references.html + parser-benchmarks.html + https://www.openhub.net/p/xstream +
+
+ Using XStream + architecture.html + converters.html + security.html + faq.html + list-user.html + issues.html +
+
+ Javadoc + javadoc/index.html + hibernate-javadoc/index.html + benchmark-javadoc/index.html +
+
+ Tutorials + tutorial.html + alias-tutorial.html + annotations-tutorial.html + converter-tutorial.html + objectstream.html + persistence-tutorial.html + json-tutorial.html + http://www.studytrails.com/java/xml/xstream/xstream-introduction.jsp +
+
+ Developing XStream + how-to-contribute.html + list-dev.html + team.html + repository.html + http://bamboo.ci.codehaus.org/browse/XSTREAM +
+
diff --git a/xstream-distribution/src/resources/logo-small.gif b/xstream-distribution/src/resources/logo-small.gif new file mode 100644 index 0000000..28b0184 Binary files /dev/null and b/xstream-distribution/src/resources/logo-small.gif differ diff --git a/xstream-distribution/src/resources/logo.gif b/xstream-distribution/src/resources/logo.gif new file mode 100644 index 0000000..21da75e Binary files /dev/null and b/xstream-distribution/src/resources/logo.gif differ diff --git a/xstream-distribution/src/resources/style.css b/xstream-distribution/src/resources/style.css new file mode 100644 index 0000000..7d6e7fd --- /dev/null +++ b/xstream-distribution/src/resources/style.css @@ -0,0 +1,412 @@ +/* + Copyright (C) 2005, 2006 Joe Walnes. + Copyright (C) 2006, 2007 XStream committers. + All rights reserved. + + The software in this package is published under the terms of the BSD + style license a copy of which has been included with this distribution in + the LICENSE.txt file. + + Created on 29. January 2005 by Joe Walnes +*/ + +/*--------------------------------------------------------------------------- + * Two- and three-column layout + */ + +#banner { + top: 0px; + left: 0px; + right: 0px; + height: 116px; +} + +#left { + position: absolute; + z-index: 2; + left: 8px; + width: 184px; + top: 125px; + bottom: 8px; + margin: 0px; + padding: 0px; +} + +#right { + position: absolute; + z-index: 1; + right: 8px; + width: 184px; + top: 125px; + bottom: 8px; + margin: 0px; + padding: 0px; +} + +.Content3Column { + position: absolute; + top: 125px; + bottom: 8px; + left: 208px; + right: 216px; +} + +.Content2Column { + position: absolute; + top: 125px; + bottom: 8px; + left: 208px; + right: 16px; +} + +#center { + z-index: 3; + margin: 0px; + border: none; + padding-bottom: 8px; +} + + +/*--------------------------------------------------------------------------- + * Default element styles + */ + +body { + padding: 0px; + margin: 0px; + border: 0px; + + font-family: helvetica, arial, sans-serif; + font-size: 12px; + + background-color: white; + color: black; +} + +h1, h2, h3, h4, h5, h6 { + margin: 0px; + border: 0px; + padding: 0px; + font-weight: normal; +} + +a:link { color: #0a0; } +a:active { color: red; } +a:hover { color: red; } +a:visited { color: black; } + +iframe { + width:100%; + height: 800px; + border: 0px; +} + +img { + border: 0px; + padding: 0px; + margin: 0px; +} + +p { + border: 0px; + padding: 0px; + margin: 0px; + margin-bottom: 10px; +} + +blockquote { + margin-bottom: 10px; +} + +td { + font-size: 12px; + padding: 2px; +} + +th { + font-size: 12px; + font-weight: bold; + white-space: nowrap; + padding: 2px; +} + +th.Row { + text-align: left; + vertical-align: top; +} + +ul, ol { + border: 0px; + padding: 0px; + margin-top: 0px; + margin-bottom: 12px; + margin-left: 20px; +} + + +/*--------------------------------------------------------------------------- + * Page banner + */ + +#banner { + margin: 0px; + border: 0px; + border-bottom: 1px solid #afa; + padding: 0px; + background-color: #e0f0e0; + color: #060; + vertical-align: bottom; +} + +#banner a { text-decoration: none; } +#banner a:visited { color: #0a0; } +#banner a:hover { color: red; } +#banner a:active { color: red; } + +#logo { + position: absolute; + top: 5px; + left: 8px; +} + +#versions { + position: absolute; + width: auto; + right: 0px; + top: 0px; + margin: 8px; + font-weight: normal; +} + +/*--------------------------------------------------------------------------- + * Page content + */ + +#content { + margin: 0px; + background-color: white; + color: black; + height: 100%; +} + +#content h1 { + width: 100%; + font-size: 18px; + background-color: #060; + color: white; + padding: 2px; + padding-left: 6px; + margin-top: 24px; + margin-bottom: 12px; +} + +#content .FirstChild { /* IE doesn't understand first-child pseudoelement */ + margin-top: 0px; +} + +#content a { text-decoration: underline; } +#content a:link { color: #060; } +#content a:visited { color: #060; } +#content a:active { color: red; } +#content a:hover { color: red; } + +#content h2 { + margin-top: 24px; + border-top: 1px solid #060; + margin-bottom: 16px; + font-size: 15px; + font-weight: bold; + background-color: #e0f0e0; + padding: 2px; +} + +#content li { + margin-bottom: 6px; +} + +#content th { + background-color: #afa; +} + +#content td { + background-color: #dfd; +} + +.Source pre { + padding: 4px; + font-family: courier new, monospace; + font-size: 11px; + border: 1px solid #080; + background-color: #cfc; + color: black; +} + +.Source:before { + margin: 0px; + padding: 0px; + border: 0px; + font-size: inherit; + line-spacing: 100%; +} + +.highlight { + background-color: #e0f0e0; + border: 1px dotted #060; + padding: 5px; +} + +/* The following are for images, but can also apply to div's containing images. */ + +#content .Float { + float: right; + margin-left: 8px; + margin-right: 0px; + margin-top: 8px; + margin-bottom: 8px; +} + +#content .Diagram { + display: block; + margin-left: auto; + margin-right: auto; + margin-top: 8px; + margin-bottom: 8px; +} + + +#content .Inline { + display: inline; +} + +.RuleOfThumb { + font-weight: bold; +} + +#content h1[id]:hover:after, #content h2[id]:hover:after { + content: " #" attr(id) " "; + font-size: 90%; + color: #aaa; + text-decoration: none; +} + +/*--------------------------------------------------------------------------- + * Side panels + */ + +.SidePanel { + background-color: white; + padding: 0px; + font-size: 11px; +} + +.SidePanel h1 { + margin: 0px; + border: 0px; + padding: 4px; + + color: #060; + + font-size: 12px; + font-weight: bold; +} + + +.SidePanel a { text-decoration: none; } +.SidePanel a:link { color: #060; } +.SidePanel a:visited { color: #060; } +.SidePanel a:active { color: red; } +.SidePanel a:hover { color: red; } + +/*--------------------------------------------------------------------------- + * Menus + */ + +.MenuGroup { + border-left: 1px solid #afa; + border-top: 1px solid #afa; + border-bottom: 1px solid white; /* IE work-around */ + + margin-bottom: 8px; + background-color: white; + color: #060; +} + +.MenuGroup ul { + margin: 0px; + padding-left: 4px; + list-style-type: none; +} + +.MenuGroup li { + padding: 2px; +} + +.MenuGroup .currentLink { +/* background-color: #060;*/ + background-color: #e0f0e0; + color: #000; +} + + +/*--------------------------------------------------------------------------- + * News panel + */ + +.NewsGroup { + border-left: 1px solid #afa; + border-top: 1px solid #afa; + border-bottom: 1px solid white; /* IE workaround */ + margin-bottom: 8px; + + color: #060; +} + +.NewsItem { + margin: 4px; +} + +.NewsDate { + font-weight: bold; + margin: 0px; + padding: 0px; +} + +.NewsText { + padding: 0px; + margin: 0px; + margin-bottom: 8px; +} + +.NewsText a { text-decoration: underline; } +.NewsText a:link { color: #060; } +.NewsText a:visited { color: #060; } +.NewsText a:active { color: red; } +.NewsText a:hover { color: red; } + +.NewsMore { + font-size: smaller; + margin: 4px; + margin-top: 8px; + text-align: left; +} + +.NewsGroup td { + font-size: 12px; +} + +/*--------------------------------------------------------------------------- + * Document meta-information + */ + +.Meta { + margin-top: 64px; + font-size: smaller; + color: #C0C0C0; + text-align: right; +} + +.Meta a { text-decoration: underline; } +.Meta a:link { color: #C0C0C0; } +.Meta a:visited { color: #C0C0C0; } +.Meta a:active { color: red; } +.Meta a:hover { color: red; } \ No newline at end of file diff --git a/xstream-distribution/src/templates/skin.html b/xstream-distribution/src/templates/skin.html new file mode 100644 index 0000000..d2dc8e2 --- /dev/null +++ b/xstream-distribution/src/templates/skin.html @@ -0,0 +1,63 @@ + + + + + XStream - ${title} + + ${head} + + + + + + + + + + +
+
+

${title}

+ + ${body} + +
+ +
+
+ +
+ <#list sitemap.sections as section> + + +
+ + + diff --git a/xstream-distribution/src/xsite/xsite.xml b/xstream-distribution/src/xsite/xsite.xml new file mode 100644 index 0000000..bb9b81e --- /dev/null +++ b/xstream-distribution/src/xsite/xsite.xml @@ -0,0 +1,54 @@ + + + + + true + + + + + + + + + + + + JIRA:([A-Z]+)-([0-9]+) + $1-$2]]> + + + mailto: + + + javascript: + + + http:// + + + https:// + + + nntp:// + + + hibernate-javadoc/ + + + javadoc/ + + + code-coverage/ + + \ No newline at end of file diff --git a/xstream-hibernate/pom.xml b/xstream-hibernate/pom.xml new file mode 100644 index 0000000..3cbf9f8 --- /dev/null +++ b/xstream-hibernate/pom.xml @@ -0,0 +1,178 @@ + + + 4.0.0 + + com.thoughtworks.xstream + xstream-parent + 1.4.8 + + xstream-hibernate + jar + XStream Hibernate Extension + + XStream extension for Hibernate 3/4 to untie Java objects from Hibernate. + + + + + jdk18-ge + + [1.8,) + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${version.plugin.maven.javadoc} + + ${javadoc.xdoclint} + false + ${version.java.source} + + ${link.javadoc.javase} + + + + + + + + jdk16-ge + + [1.6,) + + + + + org.apache.maven.plugins + maven-jar-plugin + + + ${project.build.directory}/OSGi/MANIFEST.MF + + + + + org.apache.felix + maven-bundle-plugin + + + !com.thoughtworks.xstream.hibernate.util,com.thoughtworks.xstream.hibernate.*;-noimport:=true + + + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-dependency-plugin + + + collect-dependencies + package + + copy-dependencies + + + target/dependencies + runtime + xstream,xpp3_min,xmlpull + + + + + + + + + + + org.apache.maven.plugins + maven-surefire-report-plugin + ${version.plugin.maven.surefire} + + + org.codehaus.mojo + cobertura-maven-plugin + ${version.plugin.mojo.cobertura} + + + + + + + com.thoughtworks.xstream + xstream + tests + test-jar + + + com.thoughtworks.xstream + xstream + + + org.hibernate + hibernate-core + + + org.hibernate + hibernate-envers + true + + + org.hsqldb + hsqldb + test + + + org.slf4j + slf4j-simple + provided + + + javassist + javassist + provided + + + cglib + cglib-nodep + provided + + + junit + junit + + + diff --git a/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/converter/HibernatePersistentCollectionConverter.java b/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/converter/HibernatePersistentCollectionConverter.java new file mode 100644 index 0000000..5ded8cb --- /dev/null +++ b/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/converter/HibernatePersistentCollectionConverter.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2011, 2012, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 19. April 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.hibernate.converter; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.converters.collections.CollectionConverter; +import com.thoughtworks.xstream.hibernate.util.Hibernate; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.mapper.Mapper; + + +/** + * A converter for Hibernate's PersistentBag, PersistentList and PersistentSet and for ListProxy + * and SetProxy from Hibernate's Envers add-on. The converter will drop any reference to the + * Hibernate collection and emit at serialization time an equivalent JDK collection instead. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class HibernatePersistentCollectionConverter extends CollectionConverter { + + /** + * Construct a HibernatePersistentCollectionConverter. + * + * @param mapper + * @since 1.4 + */ + public HibernatePersistentCollectionConverter(final Mapper mapper) { + super(mapper); + } + + public boolean canConvert(final Class type) { + return type != null + && ( + type == Hibernate.PersistentBag + || type == Hibernate.PersistentList + || type == Hibernate.PersistentSet + || type == Hibernate.EnversList + || type == Hibernate.EnversSet + ); + } + + public Object unmarshal(final HierarchicalStreamReader reader, + final UnmarshallingContext context) { + throw new ConversionException("Cannot deserialize Hibernate collection"); + } +} diff --git a/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/converter/HibernatePersistentMapConverter.java b/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/converter/HibernatePersistentMapConverter.java new file mode 100644 index 0000000..70447fe --- /dev/null +++ b/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/converter/HibernatePersistentMapConverter.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2011, 2012, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 19. April 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.hibernate.converter; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.converters.collections.MapConverter; +import com.thoughtworks.xstream.hibernate.util.Hibernate; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.mapper.Mapper; + + +/** + * A converter for Hibernate's PersistentMap and for the MapProxy from Hibernate's Envers + * add-on. The converter will drop any reference to the Hibernate collection and emit at + * serialization time an equivalent JDK collection instead. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class HibernatePersistentMapConverter extends MapConverter { + + /** + * Construct a HibernatePersistentMapConverter. + * + * @param mapper + * @since 1.4 + */ + public HibernatePersistentMapConverter(final Mapper mapper) { + super(mapper); + } + + public boolean canConvert(final Class type) { + return type != null && (type == Hibernate.PersistentMap || type == Hibernate.EnversMap); + } + + public Object unmarshal(final HierarchicalStreamReader reader, + final UnmarshallingContext context) { + throw new ConversionException("Cannot deserialize Hibernate collection"); + } +} diff --git a/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/converter/HibernatePersistentSortedMapConverter.java b/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/converter/HibernatePersistentSortedMapConverter.java new file mode 100644 index 0000000..48f80eb --- /dev/null +++ b/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/converter/HibernatePersistentSortedMapConverter.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2011, 2012, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 19. April 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.hibernate.converter; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.converters.collections.TreeMapConverter; +import com.thoughtworks.xstream.hibernate.util.Hibernate; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.mapper.Mapper; + + +/** + * A converter for Hibernate's PersistentSortedMap and for the SortedMapProxy from Hibernate's + * Envers add-on. The converter will drop any reference to the Hibernate collection and emit at + * serialization time an equivalent JDK collection instead. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class HibernatePersistentSortedMapConverter extends TreeMapConverter { + + /** + * Construct a HibernatePersistentSortedMapConverter. + * + * @param mapper + * @since 1.4 + */ + public HibernatePersistentSortedMapConverter(final Mapper mapper) { + super(mapper); + } + + public boolean canConvert(final Class type) { + return type != null && (type == Hibernate.PersistentSortedMap || type == Hibernate.EnversSortedMap); + } + + public Object unmarshal(final HierarchicalStreamReader reader, + final UnmarshallingContext context) { + throw new ConversionException("Cannot deserialize Hibernate collection"); + } +} diff --git a/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/converter/HibernatePersistentSortedSetConverter.java b/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/converter/HibernatePersistentSortedSetConverter.java new file mode 100644 index 0000000..53da6ae --- /dev/null +++ b/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/converter/HibernatePersistentSortedSetConverter.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2011, 2012, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 19. April 2011 by Joerg Schaible + */ +package com.thoughtworks.xstream.hibernate.converter; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.converters.collections.TreeSetConverter; +import com.thoughtworks.xstream.hibernate.util.Hibernate; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.mapper.Mapper; + + +/** + * A converter for Hibernate's PersistentSortedSet and for the SortedSetProxy from Hibernate's + * Envers add-on. The converter will drop any reference to the Hibernate collection and emit at + * serialization time an equivalent JDK collection instead. + * + * @author Jörg Schaible + * @since 1.4 + */ +public class HibernatePersistentSortedSetConverter extends TreeSetConverter { + + /** + * Construct a HibernatePersistentSortedSetConverter. + * + * @param mapper + * @since 1.4 + */ + public HibernatePersistentSortedSetConverter(final Mapper mapper) { + super(mapper); + } + + public boolean canConvert(final Class type) { + return type != null && (type == Hibernate.PersistentSortedSet || type == Hibernate.EnversSortedSet); + } + + public Object unmarshal(final HierarchicalStreamReader reader, + final UnmarshallingContext context) { + throw new ConversionException("Cannot deserialize Hibernate collection"); + } +} diff --git a/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/converter/HibernateProxyConverter.java b/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/converter/HibernateProxyConverter.java new file mode 100644 index 0000000..fe0da85 --- /dev/null +++ b/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/converter/HibernateProxyConverter.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2007, 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 11. January 2007 by Konstantin Pribluda + */ +package com.thoughtworks.xstream.hibernate.converter; + +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + +import org.hibernate.proxy.HibernateProxy; + + +/** + * Converter for Hibernate proxy instances. The converter will effectively remove any trace of + * the proxy. + * + * @author Konstantin Pribluda + * @author Jörg Schaible + */ +public class HibernateProxyConverter implements Converter { + public boolean canConvert(final Class clazz) { + // be responsible for Hibernate proxy. + return HibernateProxy.class.isAssignableFrom(clazz); + } + + public void marshal(final Object object, final HierarchicalStreamWriter writer, + final MarshallingContext context) { + final Object item = ((HibernateProxy)object) + .getHibernateLazyInitializer() + .getImplementation(); + context.convertAnother(item); + } + + public Object unmarshal(final HierarchicalStreamReader reader, + final UnmarshallingContext context) { + throw new ConversionException("Cannot deserialize Hibernate proxy"); + } +} diff --git a/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/mapper/HibernateMapper.java b/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/mapper/HibernateMapper.java new file mode 100644 index 0000000..98a4d4b --- /dev/null +++ b/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/mapper/HibernateMapper.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2007, 2011, 2012, 2013 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 11. January 2007 by Konstantin Pribluda + */ +package com.thoughtworks.xstream.hibernate.mapper; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.TreeMap; +import java.util.TreeSet; + +import com.thoughtworks.xstream.hibernate.util.Hibernate; +import com.thoughtworks.xstream.mapper.MapperWrapper; + +import org.hibernate.proxy.HibernateProxy; + + +/** + * Mapper for Hibernate types. It will map the class names of the Hibernate collections and + * Envers collection proxies with equivalents of the JDK at serialization time. It will also map + * the names of the proxy types to the names of the proxies element's type. + * + * @author Konstantin Pribluda + * @author Jörg Schaible + * @since 1.4 + */ +public class HibernateMapper extends MapperWrapper { + + final private Map collectionMap = new HashMap(); + + public HibernateMapper(final MapperWrapper mapper) { + super(mapper); + collectionMap.put(Hibernate.PersistentBag, ArrayList.class); + collectionMap.put(Hibernate.PersistentList, ArrayList.class); + collectionMap.put(Hibernate.PersistentMap, HashMap.class); + collectionMap.put(Hibernate.PersistentSet, HashSet.class); + collectionMap.put(Hibernate.PersistentSortedMap, TreeMap.class); + collectionMap.put(Hibernate.PersistentSortedSet, TreeSet.class); + collectionMap.put(Hibernate.EnversList, ArrayList.class); + collectionMap.put(Hibernate.EnversMap, HashMap.class); + collectionMap.put(Hibernate.EnversSet, HashSet.class); + collectionMap.put(Hibernate.EnversSortedMap, TreeMap.class); + collectionMap.put(Hibernate.EnversSortedSet, TreeSet.class); + collectionMap.remove(null); + } + + public Class defaultImplementationOf(final Class clazz) { + if (collectionMap.containsKey(clazz)) { + return super.defaultImplementationOf((Class)collectionMap.get(clazz)); + } + + return super.defaultImplementationOf(clazz); + } + + public String serializedClass(final Class clazz) { + if (clazz != null) { + if (collectionMap.containsKey(clazz)) { + // Pretend this is the underlying collection class and map that instead + return super.serializedClass((Class)collectionMap.get(clazz)); + } + // check whether we are Hibernate proxy and substitute real name + if (HibernateProxy.class.isAssignableFrom(clazz)) { + return super.serializedClass(clazz.getSuperclass()); + } + } + return super.serializedClass(clazz); + } +} diff --git a/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/package.html b/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/package.html new file mode 100644 index 0000000..d774283 --- /dev/null +++ b/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/package.html @@ -0,0 +1,27 @@ + + +

Support of Hibernate enhanced collections and proxied types and Hibernate's +collection proxies from the Envers add-on. To drop the internals of Hibernate +when marshalling such objects to XStream, all converters and the mapper have to +be registered for the XStream instance:

+

final XStream xstream = new XStream() {
+  protected MapperWrapper wrapMapper(final MapperWrapper next) {
+    return new HibernateMapper(next);
+  }
+};
+xstream.registerConverter(new HibernateProxyConverter());
+xstream.registerConverter(new HibernatePersistentCollectionConverter(xstream.getMapper()));
+xstream.registerConverter(new HibernatePersistentMapConverter(xstream.getMapper()));
+xstream.registerConverter(new HibernatePersistentSortedMapConverter(xstream.getMapper()));
+xstream.registerConverter(new HibernatePersistentSortedSetConverter(xstream.getMapper()));
+

+ \ No newline at end of file diff --git a/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/util/Hibernate.java b/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/util/Hibernate.java new file mode 100644 index 0000000..03723ba --- /dev/null +++ b/xstream-hibernate/src/java/com/thoughtworks/xstream/hibernate/util/Hibernate.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2012, 2013 Joerg Schaible. + * All rights reserved. + * + * Created on 08.06.2012 by Joerg Schaible + */ +package com.thoughtworks.xstream.hibernate.util; + +import com.thoughtworks.xstream.core.JVM; + +import org.hibernate.proxy.HibernateProxy; + + +/** + * Utility class for Hibernate support. + * + * @author Jörg Schaible + * @since 1.4.3 + */ +public class Hibernate { + public final static Class PersistentBag = loadHibernateType("org.hibernate.collection.internal.PersistentBag"); + public final static Class PersistentList = loadHibernateType("org.hibernate.collection.internal.PersistentList"); + public final static Class PersistentMap = loadHibernateType("org.hibernate.collection.internal.PersistentMap"); + public final static Class PersistentSet = loadHibernateType("org.hibernate.collection.internal.PersistentSet"); + public final static Class PersistentSortedMap = loadHibernateType("org.hibernate.collection.internal.PersistentSortedMap"); + public final static Class PersistentSortedSet = loadHibernateType("org.hibernate.collection.internal.PersistentSortedSet"); + public final static Class EnversList = loadHibernateEnversType("org.hibernate.envers.entities.mapper.relation.lazy.proxy.ListProxy"); + public final static Class EnversMap = loadHibernateEnversType("org.hibernate.envers.entities.mapper.relation.lazy.proxy.MapProxy"); + public final static Class EnversSet = loadHibernateEnversType("org.hibernate.envers.entities.mapper.relation.lazy.proxy.SetProxy"); + public final static Class EnversSortedMap = loadHibernateEnversType("org.hibernate.envers.entities.mapper.relation.lazy.proxy.SortedMapProxy"); + public final static Class EnversSortedSet = loadHibernateEnversType("org.hibernate.envers.entities.mapper.relation.lazy.proxy.SortedSetProxy"); + + private static Class loadHibernateType(String name) { + Class type = null; + try { + try { + type = HibernateProxy.class.getClassLoader().loadClass(name); + } catch (ClassNotFoundException e) { + type = HibernateProxy.class.getClassLoader().loadClass( + name.replaceFirst("\\.internal\\.", ".")); + } + } catch (ClassNotFoundException e) { + // not available + } + return type; + } + + private static Class loadHibernateEnversType(String name) { + Class type = null; + if (JVM.is15()) { + try { + type = HibernateProxy.class.getClassLoader().loadClass(name); + } catch (ClassNotFoundException e) { + // not available + } + } + return type; + } +} diff --git a/xstream-hibernate/src/test/acceptance/hibernate/AbstractHibernateAcceptanceTest.java b/xstream-hibernate/src/test/acceptance/hibernate/AbstractHibernateAcceptanceTest.java new file mode 100644 index 0000000..136d2ec --- /dev/null +++ b/xstream-hibernate/src/test/acceptance/hibernate/AbstractHibernateAcceptanceTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 21. April 2011 by Joerg Schaible + */ +package acceptance.hibernate; + +import com.thoughtworks.acceptance.AbstractAcceptanceTest; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.hibernate.converter.HibernatePersistentCollectionConverter; +import com.thoughtworks.xstream.hibernate.converter.HibernatePersistentMapConverter; +import com.thoughtworks.xstream.hibernate.converter.HibernatePersistentSortedMapConverter; +import com.thoughtworks.xstream.hibernate.converter.HibernatePersistentSortedSetConverter; +import com.thoughtworks.xstream.hibernate.converter.HibernateProxyConverter; +import com.thoughtworks.xstream.hibernate.mapper.HibernateMapper; +import com.thoughtworks.xstream.mapper.MapperWrapper; + +import org.hibernate.SessionFactory; +import org.hibernate.cfg.Configuration; + + +/** + * @author Jörg Schaible + * @author Jaime Metcher + */ +public abstract class AbstractHibernateAcceptanceTest extends AbstractAcceptanceTest { + + private static final SessionFactory sessionFactory; + static { + try { + // Create the SessionFactory from hibernate.cfg.xml + sessionFactory = new Configuration().configure().buildSessionFactory(); + } catch (final Throwable ex) { + // Make sure you log the exception, as it might be swallowed + System.err.println("Initial SessionFactory creation failed." + ex); + throw new ExceptionInInitializerError(ex); + } + } + + /** + * Construct a AbstractHibernateAcceptanceTest. + */ + public AbstractHibernateAcceptanceTest() { + super(); + } + + protected XStream createXStream() { + final XStream xstream = new XStream() { + + protected MapperWrapper wrapMapper(final MapperWrapper next) { + return new HibernateMapper(next); + } + + }; + xstream.registerConverter(new HibernateProxyConverter()); + xstream.registerConverter(new HibernatePersistentCollectionConverter(xstream + .getMapper())); + xstream.registerConverter(new HibernatePersistentMapConverter(xstream.getMapper())); + xstream + .registerConverter(new HibernatePersistentSortedMapConverter(xstream.getMapper())); + xstream + .registerConverter(new HibernatePersistentSortedSetConverter(xstream.getMapper())); + + return xstream; + } + + public static SessionFactory getSessionFactory() { + return sessionFactory; + } +} diff --git a/xstream-hibernate/src/test/acceptance/hibernate/HibernateCollectionsTypeCompatibilityTest.java b/xstream-hibernate/src/test/acceptance/hibernate/HibernateCollectionsTypeCompatibilityTest.java new file mode 100644 index 0000000..bcd6ae8 --- /dev/null +++ b/xstream-hibernate/src/test/acceptance/hibernate/HibernateCollectionsTypeCompatibilityTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2011, 2012 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 11. October 2011 by Joerg Schaible + */ + +package acceptance.hibernate; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.TreeMap; +import java.util.TreeSet; + +import com.thoughtworks.xstream.hibernate.util.Hibernate; + + +/** + * @author Jörg Schaible + */ +public class HibernateCollectionsTypeCompatibilityTest extends AbstractHibernateAcceptanceTest { + + public void testPersistentBag() { + assertXmlEquals(new ArrayList(), newHibernateCollection(Hibernate.PersistentBag, Collections.EMPTY_LIST)); + } + + public void testPersistentList() { + assertXmlEquals(new ArrayList(), newHibernateCollection(Hibernate.PersistentList, Collections.EMPTY_LIST)); + } + + public void testPersistentMap() { + assertXmlEquals(new HashMap(), newHibernateCollection(Hibernate.PersistentMap, Collections.EMPTY_MAP)); + } + + public void testPersistentSet() { + assertXmlEquals(new HashSet(), newHibernateCollection(Hibernate.PersistentSet, Collections.EMPTY_SET)); + } + + public void testPersistentSortedMap() { + assertXmlEquals(new TreeMap(), newHibernateCollection(Hibernate.PersistentSortedMap, new TreeMap())); + } + + public void testPersistentSortedSet() { + assertXmlEquals(new TreeSet(), newHibernateCollection(Hibernate.PersistentSortedSet, new TreeSet())); + } + + private Object newHibernateCollection(Class type, Object secondArg) { + Object instance = null; + Constructor[] ctors = type.getConstructors(); + for(int i = 0; i < ctors.length; ++i) { + if (ctors[i].getParameterTypes().length == 2) { + try { + instance = ctors[i].newInstance(new Object[]{null, secondArg}); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + break; + } + } + assertNotNull(instance); + return instance; + } + + private void assertXmlEquals(Object reference, Object hibernateCollection) { + final String expectedXml = xstream.toXML(reference); + final String loadedXml = xstream.toXML(hibernateCollection); + assertEquals(expectedXml, loadedXml); + } +} diff --git a/xstream-hibernate/src/test/acceptance/hibernate/HibernateReferenceTest.java b/xstream-hibernate/src/test/acceptance/hibernate/HibernateReferenceTest.java new file mode 100644 index 0000000..41a31ad --- /dev/null +++ b/xstream-hibernate/src/test/acceptance/hibernate/HibernateReferenceTest.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2011, 2012 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 25. March 2011 by Jaime Metcher + */ + +package acceptance.hibernate; + +import acceptance.hibernate.reference.BaseDomainObject; +import acceptance.hibernate.reference.Department; +import acceptance.hibernate.reference.Division; +import acceptance.hibernate.reference.Person; +import acceptance.hibernate.reference.Site; + +import org.hibernate.Session; +import org.hibernate.proxy.HibernateProxy; + + +/** + * @author Jaime Metcher + * @author Jörg Schaible + */ +public class HibernateReferenceTest extends AbstractHibernateAcceptanceTest { + + protected void setUp() throws Exception { + super.setUp(); + // don't write the primary keys in this test + xstream.omitField(BaseDomainObject.class, "id"); + xstream.alias("department", Department.class); + xstream.alias("division", Division.class); + xstream.alias("person", Person.class); + xstream.alias("site", Site.class); + } + + protected void tearDown() { + try { + final Session session = getSessionFactory().getCurrentSession(); + session.beginTransaction(); + final Division div = (Division)session.createQuery("from Division").uniqueResult(); + session.delete(div); + session.getTransaction().commit(); + } catch (RuntimeException e) { + e.printStackTrace(); + } + } + + public void testObjectGraphWithReferences() { + final Division memory = setupNonpersistentDivision(); + final Division persisted = setupPersistentDivision(); + + final String expectedXml = xstream.toXML(memory); + final String persistedXml = xstream.toXML(persisted); + + final Session session = getSessionFactory().getCurrentSession(); + session.beginTransaction(); + final Division loaded = (Division)session.createQuery("from Division").uniqueResult(); + final String loadedXml = xstream.toXML(loaded); + session.flush(); + session.getTransaction().commit(); + assertEquals(expectedXml, persistedXml); + assertEquals(expectedXml, loadedXml); + } + + public void testLazyProxyWithReferences() { + setupPersistentDivision(); + + final Session session = getSessionFactory().getCurrentSession(); + session.beginTransaction(); + final Division loaded = (Division)session.createQuery("from Division").uniqueResult(); + final Department dept = (Department)loaded.getDepartments().iterator().next(); + final Person person = (Person)dept.getPeople().iterator().next(); + final Site site = person.getSite(); + assertTrue(HibernateProxy.class.isAssignableFrom(site.getClass())); + final String loadedXml = xstream.toXML(site); + session.flush(); + session.getTransaction().commit(); + + final String expectedXml = "" + + "\n" + + " Site1\n" + + " \n" + + " \n" + + " Tom\n" + + " \n" + + " Dep1\n" + + " \n" + + " Div1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + assertEquals(expectedXml, loadedXml); + } + + /** + * Create the object within a Hibernate session and persist it. + */ + private Division setupPersistentDivision() { + final Session session = getSessionFactory().getCurrentSession(); + session.beginTransaction(); + final Division div = new Division("Div1"); + final Department dep = new Department("Dep1", div); + final Site site = new Site("Site1"); + /* + * This save is necessitated by the fact that Hibernate's transitive persistence is + * depth-first and does not do a full graph analysis. Therefore it would be possible for + * Hibernate to try to save the person record before the site record, which would throw + * an error if the person.site FK is non-nullable. + */ + session.save(site); + new Person("Tom", dep, site); + session.save(div); + session.flush(); + session.getTransaction().commit(); + return div; + } + + /** + * Create the object graph in-memory without Hibernate. + */ + private Division setupNonpersistentDivision() { + final Division div = new Division("Div1"); + final Department dep = new Department("Dep1", div); + final Site site = new Site("Site1"); + new Person("Tom", dep, site); + return div; + } + + /** + * Load object graph with Hibernate from the database. + */ + private Division getPersistentDivision() { + final Session session = getSessionFactory().getCurrentSession(); + session.beginTransaction(); + final Division div = (Division)session.createQuery("from Division").uniqueResult(); + session.getTransaction().commit(); + return div; + } +} diff --git a/xstream-hibernate/src/test/acceptance/hibernate/reference/BaseDomainObject.java b/xstream-hibernate/src/test/acceptance/hibernate/reference/BaseDomainObject.java new file mode 100644 index 0000000..ba667a6 --- /dev/null +++ b/xstream-hibernate/src/test/acceptance/hibernate/reference/BaseDomainObject.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 25. March 2011 by Jaime Metcher + */ + +package acceptance.hibernate.reference; + +/** + * @author Jaime Metcher + */ +public class BaseDomainObject { + + protected Integer id; + protected String name; + + public String getName() { + return name; + } + + public BaseDomainObject() { + super(); + } + +} diff --git a/xstream-hibernate/src/test/acceptance/hibernate/reference/Department.hbm.xml b/xstream-hibernate/src/test/acceptance/hibernate/reference/Department.hbm.xml new file mode 100644 index 0000000..cee1a5e --- /dev/null +++ b/xstream-hibernate/src/test/acceptance/hibernate/reference/Department.hbm.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/xstream-hibernate/src/test/acceptance/hibernate/reference/Department.java b/xstream-hibernate/src/test/acceptance/hibernate/reference/Department.java new file mode 100644 index 0000000..673190e --- /dev/null +++ b/xstream-hibernate/src/test/acceptance/hibernate/reference/Department.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 25. March 2011 by Jaime Metcher + */ +package acceptance.hibernate.reference; + +import java.util.HashSet; +import java.util.Set; + + +/** + * @author Jaime Metcher + */ +public class Department extends BaseDomainObject { + + private Division division; + + private Set people = new HashSet(0); + + protected Department() { + } + + public Department(final String name, final Division division) { + this.name = name; + this.division = division; + division.getDepartments().add(this); + } + + public Set getPeople() { + return people; + } +} diff --git a/xstream-hibernate/src/test/acceptance/hibernate/reference/Division.hbm.xml b/xstream-hibernate/src/test/acceptance/hibernate/reference/Division.hbm.xml new file mode 100644 index 0000000..74c8b5e --- /dev/null +++ b/xstream-hibernate/src/test/acceptance/hibernate/reference/Division.hbm.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/xstream-hibernate/src/test/acceptance/hibernate/reference/Division.java b/xstream-hibernate/src/test/acceptance/hibernate/reference/Division.java new file mode 100644 index 0000000..6a15699 --- /dev/null +++ b/xstream-hibernate/src/test/acceptance/hibernate/reference/Division.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 25. March 2011 by Jaime Metcher + */ +package acceptance.hibernate.reference; + +import java.util.HashSet; +import java.util.Set; + + +/** + * @author Jaime Metcher + */ +public class Division extends BaseDomainObject { + + private Set departments = new HashSet(0); + + protected Division() { + } + + public Division(final String name) { + this.name = name; + } + + public Set getDepartments() { + return departments; + } + +} diff --git a/xstream-hibernate/src/test/acceptance/hibernate/reference/Person.hbm.xml b/xstream-hibernate/src/test/acceptance/hibernate/reference/Person.hbm.xml new file mode 100644 index 0000000..cf5ca98 --- /dev/null +++ b/xstream-hibernate/src/test/acceptance/hibernate/reference/Person.hbm.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/xstream-hibernate/src/test/acceptance/hibernate/reference/Person.java b/xstream-hibernate/src/test/acceptance/hibernate/reference/Person.java new file mode 100644 index 0000000..2740909 --- /dev/null +++ b/xstream-hibernate/src/test/acceptance/hibernate/reference/Person.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 25. March 2011 by Jaime Metcher + */ +package acceptance.hibernate.reference; + +/** + * @author Jaime Metcher + */ +public class Person extends BaseDomainObject { + + private Department department; + private Site site; + + protected Person() { + } + + public Person(final String name, final Department department, final Site site) { + this.name = name; + this.department = department; + this.site = site; + + department.getPeople().add(this); + site.getPeople().add(this); + } + + public Site getSite() { + return site; + } + + public Department getDepartment() { + return department; + } + +} diff --git a/xstream-hibernate/src/test/acceptance/hibernate/reference/Site.hbm.xml b/xstream-hibernate/src/test/acceptance/hibernate/reference/Site.hbm.xml new file mode 100644 index 0000000..53ecc0c --- /dev/null +++ b/xstream-hibernate/src/test/acceptance/hibernate/reference/Site.hbm.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/xstream-hibernate/src/test/acceptance/hibernate/reference/Site.java b/xstream-hibernate/src/test/acceptance/hibernate/reference/Site.java new file mode 100644 index 0000000..6a09b8b --- /dev/null +++ b/xstream-hibernate/src/test/acceptance/hibernate/reference/Site.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2011 XStream Committers. + * All rights reserved. + * + * The software in this package is published under the terms of the BSD + * style license a copy of which has been included with this distribution in + * the LICENSE.txt file. + * + * Created on 25. March 2011 by Jaime Metcher + */ +package acceptance.hibernate.reference; + +import java.util.HashSet; +import java.util.Set; + + +/** + * @author Jaime Metcher + */ +public class Site extends BaseDomainObject { + + private Set people = new HashSet(0); + + protected Site() { + } + + public Site(final String name) { + this.name = name; + } + + public Set getPeople() { + return people; + } + +} diff --git a/xstream-hibernate/src/test/hibernate.cfg.xml b/xstream-hibernate/src/test/hibernate.cfg.xml new file mode 100644 index 0000000..77d4984 --- /dev/null +++ b/xstream-hibernate/src/test/hibernate.cfg.xml @@ -0,0 +1,47 @@ + + + + + + + org.hsqldb.jdbcDriver + jdbc:hsqldb:mem:testdb + sa + + + + 1 + + + org.hibernate.dialect.HSQLDialect + + + thread + + + org.hibernate.cache.NoCacheProvider + + + false + + + update + + + + + + + +