Index: 3rdParty_sources/versions.txt =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/versions.txt,v diff -u -r1.11.2.9 -r1.11.2.10 --- 3rdParty_sources/versions.txt 28 Aug 2014 11:39:39 -0000 1.11.2.9 +++ 3rdParty_sources/versions.txt 10 Nov 2014 12:07:42 -0000 1.11.2.10 @@ -48,4 +48,4 @@ xmltooling 1.4.0 -XStream 1.1.3 \ No newline at end of file +XStream 1.5.0 \ No newline at end of file Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/InitializationException.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/MarshallingStrategy.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/MarshallingStrategy.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/MarshallingStrategy.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/MarshallingStrategy.java 10 Nov 2014 12:07:41 -0000 1.1.2.1 @@ -1,15 +1,54 @@ +/* + * Copyright (C) 2004, 2006 Joe Walnes. + * Copyright (C) 2007, 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 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.core.DefaultConverterLookup; -import com.thoughtworks.xstream.alias.ClassMapper; -import com.thoughtworks.xstream.converters.DataHolder; +import com.thoughtworks.xstream.mapper.Mapper; + +/** + * Core interface for a marshalling strategy. + *

+ * An implementation dictates how an object graph is marshalled and unmarshalled. It is the implementation's + * responsibility to deal with references between the objects. + *

+ */ public interface MarshallingStrategy { - Object unmarshal(Object root, HierarchicalStreamReader reader, DataHolder dataHolder, DefaultConverterLookup converterLookup, ClassMapper classMapper); + /** + * Marshal an object graph. + * + * @param writer the target for the marshalled data + * @param obj the object to marshal + * @param converterLookup the converter store + * @param mapper the mapper chain + * @param dataHolder the holder for additional data and state while marshalling + */ + void marshal(HierarchicalStreamWriter writer, Object obj, ConverterLookup converterLookup, Mapper mapper, + DataHolder dataHolder); - void marshal(HierarchicalStreamWriter writer, Object obj, DefaultConverterLookup converterLookup, ClassMapper classMapper, DataHolder dataHolder); - + /** + * Unmarshal an object graph. + * + * @param root a possible root object (should be {@code null} in normal cases) + * @param reader the source for the unmarshalled object data + * @param dataHolder the holder for additional data and state while marshalling + * @param converterLookup the converter store + * @param mapper the mapper chain + * @return the unmarshalled object + */ + Object unmarshal(Object root, HierarchicalStreamReader reader, DataHolder dataHolder, ConverterLookup converterLookup, + Mapper mapper); } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/XStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/XStream.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/XStream.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/XStream.java 10 Nov 2014 12:07:41 -0000 1.1.2.1 @@ -1,242 +1,663 @@ +/* + * Copyright (C) 2003, 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 26. September 2003 by Joe Walnes + */ package com.thoughtworks.xstream; -import com.thoughtworks.xstream.alias.ClassMapper; +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.Member; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.URI; +import java.net.URL; +import java.nio.charset.Charset; +import java.text.DecimalFormatSymbols; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.Currency; +import java.util.Date; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +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.TimeZone; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.UUID; +import java.util.Vector; +import java.util.concurrent.ConcurrentHashMap; +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.basic.*; -import com.thoughtworks.xstream.converters.collections.*; -import com.thoughtworks.xstream.converters.extended.*; +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.StringBuilderConverter; +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.basic.UUIDConverter; +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.enums.EnumConverter; +import com.thoughtworks.xstream.converters.enums.EnumMapConverter; +import com.thoughtworks.xstream.converters.enums.EnumSetConverter; +import com.thoughtworks.xstream.converters.extended.CharsetConverter; +import com.thoughtworks.xstream.converters.extended.ColorConverter; +import com.thoughtworks.xstream.converters.extended.CurrencyConverter; +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.RegexPatternConverter; +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.StackTraceElementConverter; +import com.thoughtworks.xstream.converters.extended.TextAttributeConverter; +import com.thoughtworks.xstream.converters.extended.ThrowableConverter; 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.*; -import com.thoughtworks.xstream.core.util.ClassLoaderReference; +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.xml.PrettyPrintWriter; +import com.thoughtworks.xstream.io.StatefulWriter; import com.thoughtworks.xstream.io.xml.XppDriver; -import com.thoughtworks.xstream.mapper.*; +import com.thoughtworks.xstream.mapper.AnnotationMapper; +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.EnumMapper; +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.ArrayTypePermission; +import com.thoughtworks.xstream.security.ExplicitTypePermission; +import com.thoughtworks.xstream.security.InterfaceTypePermission; +import com.thoughtworks.xstream.security.NoPermission; +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.TypeHierarchyPermission; +import com.thoughtworks.xstream.security.TypePermission; +import com.thoughtworks.xstream.security.WildcardTypePermission; -import java.io.*; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.net.URL; -import java.sql.Time; -import java.sql.Timestamp; -import java.util.*; /** * Simple facade to XStream library, a Java-XML serialization tool. - *

- *


Example
+ * 

+ *


+ * 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 occurences of element - * <com.blah.MyThing> to - * <my-thing> by registering an alias for the class. - *


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

- *

+ *

+ * 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 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 default converter, ie the converter which will be used if no other registered - * converter is suitable, can be configured by either one of the constructors - * or can be changed using the changeDefaultConverter() method. - * If not set, XStream uses {@link com.thoughtworks.xstream.converters.reflection.ReflectionConverter} - * as the initial default converter. + *

+ * + *
+ *
+ *

+ * 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.changeDefaultConverter(new ACustomDefaultConverter());
- * 

- *

+ *

+ *


+ * 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 XPath or IDs. The - * mode can be changed using setMode():

- *

- * + *

+ * 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_REFERENCES);(Default) Uses XPath references to signify duplicate - * references. This produces XML with the least clutter.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.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 seperate objects and circular references cause an - * exception. This is slightly faster and uses less memory - * than the other two modes.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. - * + *

+ * 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.

- * + *

+ * 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 final ReflectionProvider reflectionProvider; + private final HierarchicalStreamDriver hierarchicalStreamDriver; + private final ClassLoaderReference classLoaderReference; + private MarshallingStrategy marshallingStrategy; + private final ConverterLookup converterLookup; + private final ConverterRegistry converterRegistry; + private final 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 AnnotationMapper annotationMapper; - private ReflectionProvider reflectionProvider; - private HierarchicalStreamDriver hierarchicalStreamDriver; - private MarshallingStrategy marshallingStrategy; - private ClassLoaderReference classLoaderReference; // TODO: Should be changeable - - private ClassMapper classMapper; - private DefaultConverterLookup converterLookup; - private JVM jvm = new JVM(); - public static final int NO_REFERENCES = 1001; public static final int ID_REFERENCES = 1002; - public static final int XPATH_REFERENCES = 1003; + 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; - private static final int PRIORITY_NORMAL = 0; - private static final int PRIORITY_LOW = -10; - private static final int PRIORITY_VERY_LOW = -20; + 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 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, null, new XppDriver()); + this(new XppDriver()); } /** - * @deprecated As of XStream 1.1.1, a default Converter is unnecessary as you can register a Converter with an - * associated priority. Use an alternate constructor. + * 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(Converter defaultConverter) { - this(null, null, new XppDriver(), null); - registerConverter(defaultConverter, PRIORITY_VERY_LOW); + public XStream(final ReflectionProvider reflectionProvider) { + this(reflectionProvider, new XppDriver()); } - public XStream(HierarchicalStreamDriver hierarchicalStreamDriver) { - this(null, null, hierarchicalStreamDriver); + /** + * 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(final HierarchicalStreamDriver hierarchicalStreamDriver) { + this(null, hierarchicalStreamDriver); } - public XStream(ReflectionProvider reflectionProvider) { - this(reflectionProvider, null, new XppDriver()); + /** + * 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(final ReflectionProvider reflectionProvider, final HierarchicalStreamDriver hierarchicalStreamDriver) { + this(reflectionProvider, hierarchicalStreamDriver, new ClassLoaderReference(new CompositeClassLoader())); } - public XStream(ReflectionProvider reflectionProvider, HierarchicalStreamDriver hierarchicalStreamDriver) { - this(reflectionProvider, null, hierarchicalStreamDriver); + /** + * 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( + final ReflectionProvider reflectionProvider, final HierarchicalStreamDriver driver, + final ClassLoaderReference classLoaderReference) { + this(reflectionProvider, driver, classLoaderReference, null); } - public XStream(ReflectionProvider reflectionProvider, ClassMapper classMapper, HierarchicalStreamDriver driver) { - this(reflectionProvider, classMapper, driver, 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)} + */ + @Deprecated + public XStream( + final ReflectionProvider reflectionProvider, final HierarchicalStreamDriver driver, + final ClassLoader classLoader) { + this(reflectionProvider, driver, classLoader, null); } - public XStream(ReflectionProvider reflectionProvider, ClassMapper classMapper, HierarchicalStreamDriver driver, String classAttributeIdentifier) { - jvm = new JVM(); + /** + * 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)} + */ + @Deprecated + public XStream( + final ReflectionProvider reflectionProvider, final HierarchicalStreamDriver driver, + final ClassLoader classLoader, final 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( + final ReflectionProvider reflectionProvider, final HierarchicalStreamDriver driver, + final ClassLoaderReference classLoaderReference, final Mapper mapper) { + this(reflectionProvider, driver, classLoaderReference, mapper, new DefaultConverterLookup()); + } + + private XStream( + final ReflectionProvider reflectionProvider, final HierarchicalStreamDriver driver, + final ClassLoaderReference classLoader, final Mapper mapper, + final DefaultConverterLookup defaultConverterLookup) { + this(reflectionProvider, driver, classLoader, mapper, new ConverterLookup() { + @Override + public Converter lookupConverterForType(final Class type) { + return defaultConverterLookup.lookupConverterForType(type); + } + }, new ConverterRegistry() { + @Override + public void registerConverter(final Converter converter, final 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)} + */ + @Deprecated + public XStream( + final ReflectionProvider reflectionProvider, final HierarchicalStreamDriver driver, + final ClassLoader classLoader, final Mapper mapper, final ConverterLookup converterLookup, + final 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, final HierarchicalStreamDriver driver, + final ClassLoaderReference classLoaderReference, final Mapper mapper, + final ConverterLookup converterLookup, final ConverterRegistry converterRegistry) { if (reflectionProvider == null) { - reflectionProvider = jvm.bestReflectionProvider(); + reflectionProvider = JVM.newReflectionProvider(); } this.reflectionProvider = reflectionProvider; - this.hierarchicalStreamDriver = driver; - this.classLoaderReference = new ClassLoaderReference(new CompositeClassLoader()); - this.classMapper = classMapper == null ? buildMapper(classAttributeIdentifier) : classMapper; - converterLookup = new DefaultConverterLookup(this.classMapper); + 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_REFERENCES); + setMode(XPATH_RELATIVE_REFERENCES); } - /** - * @deprecated As of XStream 1.1.1, a default Converter is unnecessary as you can register a Converter with an - * associated priority. Use an alternate constructor. - */ - public XStream(ReflectionProvider reflectionProvider, ClassMapper classMapper, HierarchicalStreamDriver driver, String classAttributeIdentifier, Converter defaultConverter) { - this(reflectionProvider, classMapper, driver, classAttributeIdentifier); - registerConverter(defaultConverter, PRIORITY_VERY_LOW); - } - - private ClassMapper buildMapper(String classAttributeIdentifier) { - MapperWrapper mapper = new DefaultMapper(classLoaderReference, classAttributeIdentifier); - mapper = new XmlFriendlyMapper(mapper); + 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); - classAliasingMapper = (ClassAliasingMapper) mapper; // need a reference to that one mapper = new FieldAliasingMapper(mapper); - fieldAliasingMapper = (FieldAliasingMapper) mapper; // need a reference to that one + mapper = new AttributeAliasingMapper(mapper); + mapper = new SystemAttributeAliasingMapper(mapper); mapper = new ImplicitCollectionMapper(mapper); - implicitCollectionMapper = (ImplicitCollectionMapper)mapper; // need a reference to this one - mapper = new DynamicProxyMapper(mapper); - if (JVM.is15()) { - mapper = new EnumMapper(mapper); - } mapper = new OuterClassMapper(mapper); mapper = new ArrayMapper(mapper); mapper = new DefaultImplementationsMapper(mapper); - defaultImplementationsMapper = (DefaultImplementationsMapper) mapper; // and that one + mapper = new AttributeMapper(mapper, converterLookup, reflectionProvider); + mapper = new EnumMapper(mapper); + mapper = new LocalConversionMapper(mapper); mapper = new ImmutableTypesMapper(mapper); - immutableTypesMapper = (ImmutableTypesMapper)mapper; // that one too - mapper = wrapMapper(mapper); + mapper = new SecurityMapper(mapper); + mapper = new AnnotationMapper(mapper, converterRegistry, converterLookup, classLoaderReference, + reflectionProvider); + mapper = wrapMapper((MapperWrapper)mapper); mapper = new CachingMapper(mapper); return mapper; } - protected MapperWrapper wrapMapper(MapperWrapper next) { + @SuppressWarnings("unused") + private Mapper buildMapperDynamically(final String className, final Class[] constructorParamTypes, + final Object[] constructorParamValues) { + try { + final Class type = Class.forName(className, false, classLoaderReference.getReference()); + final Constructor constructor = type.getConstructor(constructorParamTypes); + return (Mapper)constructor.newInstance(constructorParamValues); + } catch (final Exception e) { + throw new InitializationException("Could not instantiate mapper : " + className, e); + } catch (final LinkageError e) { + throw new InitializationException("Could not instantiate mapper : " + className, e); + } + } + + protected MapperWrapper wrapMapper(final MapperWrapper next) { return next; } + /** + * @deprecated As of upcoming + */ + @Deprecated + protected boolean useXStream11XmlFriendlyMapper() { + return false; + } + + private void setupMappers() { + packageAliasingMapper = mapper.lookupMapperOfType(PackageAliasingMapper.class); + classAliasingMapper = mapper.lookupMapperOfType(ClassAliasingMapper.class); + fieldAliasingMapper = mapper.lookupMapperOfType(FieldAliasingMapper.class); + attributeMapper = mapper.lookupMapperOfType(AttributeMapper.class); + attributeAliasingMapper = mapper.lookupMapperOfType(AttributeAliasingMapper.class); + systemAttributeAliasingMapper = mapper.lookupMapperOfType(SystemAttributeAliasingMapper.class); + implicitCollectionMapper = mapper.lookupMapperOfType(ImplicitCollectionMapper.class); + defaultImplementationsMapper = mapper.lookupMapperOfType(DefaultImplementationsMapper.class); + immutableTypesMapper = mapper.lookupMapperOfType(ImmutableTypesMapper.class); + localConversionMapper = mapper.lookupMapperOfType(LocalConversionMapper.class); + securityMapper = mapper.lookupMapperOfType(SecurityMapper.class); + annotationMapper = mapper.lookupMapperOfType(AnnotationMapper.class); + } + + protected void setupSecurity() { + if (securityMapper == null) { + return; + } + + addPermission(NullPermission.NULL); + addPermission(PrimitiveTypePermission.PRIMITIVES); + addPermission(ArrayTypePermission.ARRAYS); + addPermission(InterfaceTypePermission.INTERFACES); + allowTypeHierarchy(Calendar.class); + allowTypeHierarchy(Collection.class); + allowTypeHierarchy(Enum.class); + allowTypeHierarchy(Map.class); + allowTypeHierarchy(Map.Entry.class); + allowTypeHierarchy(Member.class); + allowTypeHierarchy(Number.class); + allowTypeHierarchy(Throwable.class); + allowTypeHierarchy(TimeZone.class); + + final Set> types = new HashSet>(); + types.addAll(Arrays.>asList(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, StringBuilder.class, URL.class, URI.class, UUID.class)); + if (JVM.isSQLAvailable()) { + types.add(JVM.loadClassForName("java.sql.Timestamp")); + types.add(JVM.loadClassForName("java.sql.Time")); + types.add(JVM.loadClassForName("java.sql.Date")); + } + types.remove(null); + allowTypes(types.toArray(new Class[types.size()])); + } + protected void setupAliases() { - alias("null", ClassMapper.Null.class); + if (classAliasingMapper == null) { + return; + } + + alias("null", Mapper.Null.class); alias("int", Integer.class); alias("float", Float.class); alias("double", Double.class); @@ -250,153 +671,194 @@ alias("big-int", BigInteger.class); alias("big-decimal", BigDecimal.class); - alias("string-buffer", StringBuffer.class); alias("string", String.class); + alias("string-buffer", StringBuffer.class); + alias("string-builder", StringBuilder.class); + alias("uuid", UUID.class); alias("java-class", Class.class); alias("method", Method.class); alias("constructor", Constructor.class); + alias("field", Field.class); alias("date", Date.class); + alias("gregorian-calendar", Calendar.class); + alias("uri", URI.class); alias("url", URL.class); + alias("file", File.class); + alias("locale", Locale.class); alias("bit-set", BitSet.class); + alias("trace", StackTraceElement.class); + alias("currency", Currency.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("linked-hash-map", LinkedHashMap.class); + alias("linked-hash-set", LinkedHashSet.class); + alias("concurrent-hash-map", ConcurrentHashMap.class); - // 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.loadClass("java.awt.Color")); - alias("awt-font", jvm.loadClass("java.awt.Font")); + alias("enum-set", EnumSet.class); + alias("enum-map", EnumMap.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()); - alias("sql-timestamp", Timestamp.class); - alias("sql-time", Time.class); - alias("sql-date", java.sql.Date.class); - alias("file", File.class); - alias("locale", Locale.class); - alias("gregorian-calendar", Calendar.class); + 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.is14()) { - alias("linked-hash-map", jvm.loadClass("java.util.LinkedHashMap")); - alias("linked-hash-set", jvm.loadClass("java.util.LinkedHashSet")); - alias("trace", jvm.loadClass("java.lang.StackTraceElement")); - alias("currency", jvm.loadClass("java.util.Currency")); - // since jdk 1.4 included, but previously available as separate package ... - alias("auth-subject", jvm.loadClass("javax.security.auth.Subject")); + 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")); } - if (JVM.is15()) { - alias("enum-set", jvm.loadClass("java.util.EnumSet")); - alias("enum-map", jvm.loadClass("java.util.EnumMap")); + aliasType("charset", Charset.class); + + if (JVM.loadClassForName("javax.security.auth.Subject") != null) { + aliasDynamically("auth-subject", "javax.security.auth.Subject"); } + if (JVM.loadClassForName("javax.xml.datatype.Duration") != null) { + aliasDynamically("duration", "javax.xml.datatype.Duration"); + } } + private void aliasDynamically(final String alias, final String className) { + final 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() { - ReflectionConverter reflectionConverter = new ReflectionConverter(classMapper, reflectionProvider); - registerConverter(reflectionConverter, PRIORITY_VERY_LOW); + registerConverter(new ReflectionConverter(mapper, reflectionProvider), PRIORITY_VERY_LOW); - registerConverter(new SerializableConverter(classMapper, reflectionProvider), PRIORITY_LOW); - registerConverter(new ExternalizableConverter(classMapper), PRIORITY_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(new CharConverter(), 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 StringBuilderConverter(), PRIORITY_NORMAL); + registerConverter(new ThrowableConverter(converterLookup), PRIORITY_NORMAL); + registerConverter(new StackTraceElementConverter(), PRIORITY_NORMAL); registerConverter(new DateConverter(), PRIORITY_NORMAL); + registerConverter(new GregorianCalendarConverter(), PRIORITY_NORMAL); + registerConverter(new RegexPatternConverter(), PRIORITY_NORMAL); + registerConverter(new CurrencyConverter(), PRIORITY_NORMAL); + registerConverter(new CharsetConverter(), PRIORITY_NORMAL); + registerConverter(new LocaleConverter(), PRIORITY_NORMAL); registerConverter(new BitSetConverter(), PRIORITY_NORMAL); + registerConverter(new UUIDConverter(), 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(classMapper), PRIORITY_NORMAL); + registerConverter(new ArrayConverter(mapper), PRIORITY_NORMAL); registerConverter(new CharArrayConverter(), PRIORITY_NORMAL); - registerConverter(new CollectionConverter(classMapper), PRIORITY_NORMAL); - registerConverter(new MapConverter(classMapper), PRIORITY_NORMAL); - registerConverter(new TreeMapConverter(classMapper), PRIORITY_NORMAL); - registerConverter(new TreeSetConverter(classMapper), 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(new EncodedByteArrayConverter(), PRIORITY_NORMAL); + registerConverter((Converter)new EncodedByteArrayConverter(), PRIORITY_NORMAL); + registerConverter(new EnumConverter(), PRIORITY_NORMAL); + registerConverter(new EnumSetConverter(mapper), PRIORITY_NORMAL); + registerConverter(new EnumMapConverter(mapper), PRIORITY_NORMAL); registerConverter(new FileConverter(), PRIORITY_NORMAL); - registerConverter(new SqlTimestampConverter(), PRIORITY_NORMAL); - registerConverter(new SqlTimeConverter(), PRIORITY_NORMAL); - registerConverter(new SqlDateConverter(), PRIORITY_NORMAL); - registerConverter(new DynamicProxyConverter(classMapper, classLoaderReference), 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(), PRIORITY_NORMAL); - registerConverter(new FontConverter(), PRIORITY_NORMAL); - registerConverter(new ColorConverter(), 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 - dynamicallyRegisterConverter( - "com.thoughtworks.xstream.converters.extended.ThrowableConverter", PRIORITY_NORMAL, - new Class[] {Converter.class} , new Object[] { reflectionConverter} ); - dynamicallyRegisterConverter( - "com.thoughtworks.xstream.converters.extended.StackTraceElementConverter", PRIORITY_NORMAL, - null, null); - dynamicallyRegisterConverter( - "com.thoughtworks.xstream.converters.extended.CurrencyConverter", PRIORITY_NORMAL, - null, null); - dynamicallyRegisterConverter( - "com.thoughtworks.xstream.converters.extended.RegexPatternConverter", PRIORITY_NORMAL, - new Class[] {Converter.class} , new Object[] { reflectionConverter} ); - dynamicallyRegisterConverter( - "com.thoughtworks.xstream.converters.extended.SubjectConverter", PRIORITY_NORMAL, - new Class[] {Mapper.class}, new Object[] {classMapper}); + 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); + } - if (JVM.is15()) { - // late bound converters - allows XStream to be compiled on earlier JDKs - dynamicallyRegisterConverter( - "com.thoughtworks.xstream.converters.enums.EnumConverter", PRIORITY_NORMAL, - null, null); - dynamicallyRegisterConverter( - "com.thoughtworks.xstream.converters.enums.EnumSetConverter", PRIORITY_NORMAL, - new Class[] {Mapper.class}, new Object[] {classMapper}); - dynamicallyRegisterConverter( - "com.thoughtworks.xstream.converters.enums.EnumMapConverter", PRIORITY_NORMAL, - new Class[] {Mapper.class}, new Object[] {classMapper}); + if (JVM.loadClassForName("javax.security.auth.Subject") != null) { + registerConverterDynamically("com.thoughtworks.xstream.converters.extended.SubjectConverter", + PRIORITY_NORMAL, new Class[]{Mapper.class}, new Object[]{mapper}); } + if (JVM.loadClassForName("javax.xml.datatype.Duration") != null) { + registerConverterDynamically("com.thoughtworks.xstream.converters.extended.DurationConverter", + PRIORITY_NORMAL, null, null); + } + + registerConverter(new SelfStreamingInstanceChecker(converterLookup, this), PRIORITY_NORMAL); } - private void dynamicallyRegisterConverter(String className, int priority, - Class[] constructorParamTypes, Object[] constructorParamValues) { + private void registerConverterDynamically(final String className, final int priority, + final Class[] constructorParamTypes, final Object[] constructorParamValues) { try { - Class type = Class.forName(className, false, classLoaderReference.getReference()); - Constructor constructor = type.getConstructor(constructorParamTypes); - Converter converter = (Converter) constructor.newInstance(constructorParamValues); - registerConverter(converter, priority); - } catch (Exception e) { - throw new InitializationException("Could not instatiate converter : " + className, e); + final Class type = Class.forName(className, false, classLoaderReference.getReference()); + final Constructor constructor = type.getConstructor(constructorParamTypes); + final Object instance = constructor.newInstance(constructorParamValues); + if (instance instanceof Converter) { + registerConverter((Converter)instance, priority); + } else if (instance instanceof SingleValueConverter) { + registerConverter((SingleValueConverter)instance, priority); + } + } catch (final Exception e) { + throw new InitializationException("Could not instantiate converter : " + className, e); + } catch (final LinkageError e) { + throw new InitializationException("Could not instantiate converter : " + className, e); } } protected void setupImmutableTypes() { + if (immutableTypesMapper == null) { + return; + } + // primitives are always immutable addImmutableType(boolean.class); addImmutableType(Boolean.class); @@ -416,446 +878,1180 @@ addImmutableType(Short.class); // additional types - addImmutableType(ClassMapper.Null.class); + addImmutableType(Mapper.Null.class); addImmutableType(BigDecimal.class); addImmutableType(BigInteger.class); addImmutableType(String.class); + addImmutableType(Charset.class); + addImmutableType(Currency.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"); + } } - public void setMarshallingStrategy(MarshallingStrategy marshallingStrategy) { + private void addImmutableTypeDynamically(final String className) { + final Class type = JVM.loadClassForName(className); + if (type != null) { + addImmutableType(type); + } + } + + /** + * Setter for an arbitrary marshalling strategy. + * + * @param marshallingStrategy the implementation to use + * @see #setMode(int) + */ + public void setMarshallingStrategy(final 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 stringWriter = new StringWriter(); - HierarchicalStreamWriter writer = hierarchicalStreamDriver.createWriter(stringWriter); - marshal(obj, writer); - writer.flush(); - writer.close(); - return stringWriter.toString(); + public String toXML(final Object obj) { + final Writer writer = new StringWriter(); + toXML(obj, writer); + return writer.toString(); } /** - * Serialize an object to the given Writer as pretty-printed XML. + * 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); - marshal(obj, writer); - writer.flush(); + public void toXML(final Object obj, final Writer out) { + @SuppressWarnings("resource") + final HierarchicalStreamWriter writer = hierarchicalStreamDriver.createWriter(out); + try { + marshal(obj, writer); + } finally { + writer.flush(); + } } /** - * Serialize an object to the given OutputStream as pretty-printed XML. + * 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); - marshal(obj, writer); - writer.flush(); + public void toXML(final Object obj, final OutputStream out) { + @SuppressWarnings("resource") + final 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) { + public void marshal(final Object obj, final 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. + * + * @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, classMapper, dataHolder); + public void marshal(final Object obj, final HierarchicalStreamWriter writer, final 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) { + public T fromXML(final 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 xml) { - return unmarshal(hierarchicalStreamDriver.createReader(xml), null); + public T fromXML(final 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) { + public T fromXML(final InputStream input) { return unmarshal(hierarchicalStreamDriver.createReader(input), null); } /** - * Deserialize an object from an XML String, - * populating the fields of the given root object instead of instantiating - * a new one. + * 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(String xml, Object root) { + public T fromXML(final 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 T fromXML(final 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 T fromXML(final String xml, final T 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. + * 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) { + public T fromXML(final Reader xml, final T root) { return unmarshal(hierarchicalStreamDriver.createReader(xml), root); } /** - * Deserialize an object from an XML InputStream, - * populating the fields of the given root object instead of instantiating - * a new one. + * 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(InputStream xml, Object root) { - return unmarshal(hierarchicalStreamDriver.createReader(xml), root); + public T fromXML(final URL url, final T 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 T fromXML(final File file, final T root) { + final 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 T fromXML(final InputStream input, final T 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) { + public T unmarshal(final 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. + * 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) { + public T unmarshal(final HierarchicalStreamReader reader, final T 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. - * @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. + * + * @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) { - return marshallingStrategy.unmarshal(root, reader, dataHolder, converterLookup, classMapper); + public T unmarshal(final HierarchicalStreamReader reader, final T root, final DataHolder dataHolder) { + try { + @SuppressWarnings("unchecked") + final T t = (T)marshallingStrategy.unmarshal(root, reader, dataHolder, converterLookup, mapper); + return t; + + } catch (final ConversionException e) { + final Package pkg = getClass().getPackage(); + final 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 + * @param type Type to be aliased + * @throws InitializationException if no {@link ClassAliasingMapper} is available */ - public void alias(String name, Class type) { + public void alias(final String name, final Class type) { + if (classAliasingMapper == null) { + throw new 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(final String name, final Class type) { + if (classAliasingMapper == null) { + throw new 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 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) { + public void alias(final String name, final Class type, final Class defaultImplementation) { alias(name, type); addDefaultImplementation(defaultImplementation, type); } - public void aliasField(String alias, Class type, String fieldName) { - fieldAliasingMapper.addFieldAlias(alias, type, fieldName); + /** + * 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(final String name, final String pkgName) { + if (packageAliasingMapper == null) { + throw new 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(final String alias, final Class definedIn, final String fieldName) { + if (fieldAliasingMapper == null) { + throw new 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(final String alias, final String attributeName) { + if (attributeAliasingMapper == null) { + throw new 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(final String alias, final String systemAttributeName) { + if (systemAttributeAliasingMapper == null) { + throw new 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(final Class definedIn, final String attributeName, final 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(final String fieldName, final Class type) { + if (attributeMapper == null) { + throw new 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(final Class definedIn, final String fieldName) { + if (attributeMapper == null) { + throw new 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(final Class type) { + if (attributeMapper == null) { + throw new 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. + * 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) { + public void addDefaultImplementation(final Class defaultImplementation, final Class ofType) { + if (defaultImplementationsMapper == null) { + throw new InitializationException("No " + DefaultImplementationsMapper.class.getName() + " available"); + } defaultImplementationsMapper.addDefaultImplementation(defaultImplementation, ofType); } - public void addImmutableType(Class type) { + /** + * 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(final Class type) { + if (immutableTypesMapper == null) { + throw new InitializationException("No " + ImmutableTypesMapper.class.getName() + " available"); + } immutableTypesMapper.addImmutableType(type); } /** - * @deprecated As of 1.1.1 you should register a converter with the appropriate priority. + * Register a converter with normal priority. + * + * @param converter the converter instance */ - public void changeDefaultConverter(Converter defaultConverter) { - registerConverter(defaultConverter, PRIORITY_VERY_LOW); + public void registerConverter(final Converter converter) { + registerConverter(converter, PRIORITY_NORMAL); } - public void registerConverter(Converter converter) { + /** + * Register a converter with chosen priority. + * + * @param converter the converter instance + * @param priority the converter priority + */ + public void registerConverter(final Converter converter, final int priority) { + if (converterRegistry != null) { + converterRegistry.registerConverter(converter, priority); + } + } + + /** + * Register a single value converter with normal priority. + * + * @param converter the single value converter instance + */ + public void registerConverter(final SingleValueConverter converter) { registerConverter(converter, PRIORITY_NORMAL); } - public void registerConverter(Converter converter, int priority) { - converterLookup.registerConverter(converter, priority); + /** + * Register a single converter with chosen priority. + * + * @param converter the single converter instance + * @param priority the converter priority + */ + public void registerConverter(final SingleValueConverter converter, final int priority) { + if (converterRegistry != null) { + converterRegistry.registerConverter(new SingleValueConverterWrapper(converter), priority); + } } - public ClassMapper getClassMapper() { - return classMapper; + /** + * 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(final Class definedIn, final String fieldName, final Converter converter) { + if (localConversionMapper == null) { + throw new 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(final Class definedIn, final String fieldName, + final SingleValueConverter converter) { + final Converter wrapper = new SingleValueConverterWrapper(converter); + registerLocalConverter(definedIn, fieldName, wrapper); + } + + /** + * 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 valuse are XStream.XPATH_REFERENCES, - * XStream.ID_REFERENCES and XStream.NO_REFERENCES. - * - * @see #XPATH_REFERENCES + * 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 #setMarshallingStrategy(MarshallingStrategy) + * @see #XPATH_ABSOLUTE_REFERENCES + * @see #XPATH_RELATIVE_REFERENCES * @see #ID_REFERENCES * @see #NO_REFERENCES */ - public void setMode(int mode) { + public void setMode(final int mode) { switch (mode) { - case NO_REFERENCES: - setMarshallingStrategy(new TreeMarshallingStrategy()); - break; - case ID_REFERENCES: - setMarshallingStrategy(new ReferenceByIdMarshallingStrategy()); - break; - case XPATH_REFERENCES: - setMarshallingStrategy(new ReferenceByXPathMarshallingStrategy()); - break; - default: - throw new IllegalArgumentException("Unknown mode : " + 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); } } /** - * @deprecated Use addImplicitCollection() instead. - */ - public void addDefaultCollection(Class ownerType, String fieldName) { - addImplicitCollection(ownerType, fieldName); - } - - /** - * Adds a default implicit collection which is used for any unmapped xml tag. - * + * 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 an java.util.ArrayList. + * @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) { - implicitCollectionMapper.add(ownerType, fieldName, null, Object.class); + public void addImplicitCollection(final Class ownerType, final 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 an java.util.ArrayList. - * @param itemType type of the items to be part of this 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) { - implicitCollectionMapper.add(ownerType, fieldName, null, itemType); + public void addImplicitCollection(final Class ownerType, final String fieldName, final 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 an java.util.ArrayList. - * @param itemFieldName element name of 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) { - implicitCollectionMapper.add(ownerType, fieldName, itemFieldName, itemType); + public void addImplicitCollection(final Class ownerType, final String fieldName, final String itemFieldName, + final 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(final Class ownerType, final 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(final Class ownerType, final String fieldName, final 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(final Class ownerType, final String fieldName, final 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(final Class ownerType, final String fieldName, final Class itemType, + final 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(final Class ownerType, final String fieldName, final String itemName, + final Class itemType, final String keyFieldName) { + if (implicitCollectionMapper == null) { + throw new 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)}.

- * + *

+ * 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(new PrettyPrintWriter(writer), "object-stream"); + public ObjectOutputStream createObjectOutputStream(final 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)}.

- * + *

+ * 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 { + public ObjectOutputStream createObjectOutputStream(final 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(new PrettyPrintWriter(writer), rootNodeName); + public ObjectOutputStream createObjectOutputStream(final Writer writer, final 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(final 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(final OutputStream out, final 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.

- * + *

+ * 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();
- * + * + *
+     *  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 { - writer.startNode(rootNodeName); + @SuppressWarnings("resource") + public ObjectOutputStream createObjectOutputStream(final HierarchicalStreamWriter writer, final 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, writer); + @Override + public void writeToStream(final Object object) { + marshal(object, statefulWriter); } - public void writeFieldsToStream(Map fields) throws NotActiveException { + @Override + public void writeFieldsToStream(final Map fields) throws NotActiveException { throw new NotActiveException("not in call to writeObject"); } + @Override public void defaultWriteObject() throws NotActiveException { throw new NotActiveException("not in call to writeObject"); } + @Override public void flush() { - writer.flush(); + statefulWriter.flush(); } + @Override public void close() { - writer.endNode(); - writer.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 { + public ObjectInputStream createObjectInputStream(final Reader xmlReader) throws IOException { return createObjectInputStream(hierarchicalStreamDriver.createReader(xmlReader)); } /** - * Creates an ObjectInputStream that deserializes a stream of objects from a reader using XStream. - * - *

Example

- *
ObjectInputStream in = xstream.createObjectOutputStream(aReader);
+     * 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(final 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();
- * + * 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() { + @Override public Object readFromStream() throws EOFException { if (!reader.hasMoreChildren()) { throw new EOFException(); } reader.moveDown(); - Object result = unmarshal(reader); + final Object result = unmarshal(reader); reader.moveUp(); return result; } - public Map readFieldsFromStream() throws IOException { + @Override + public Map readFieldsFromStream() throws IOException { throw new NotActiveException("not in call to readObject"); } + @Override public void defaultReadObject() throws NotActiveException { throw new NotActiveException("not in call to readObject"); } - public void registerValidation(ObjectInputValidation validation, int priority) throws NotActiveException { + @Override + public void registerValidation(final ObjectInputValidation validation, final int priority) + throws NotActiveException { throw new NotActiveException("stream inactive"); } + @Override public void close() { reader.close(); } - }); + }, classLoaderReference); } /** - * Change the ClassLoader XStream uses to load classes. - * + * 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) { + public void setClassLoader(final ClassLoader classLoader) { classLoaderReference.setReference(classLoader); } /** - * Change the ClassLoader XStream uses to load classes. - * + * Retrieve the ClassLoader XStream uses to load classes. + * * @since 1.1.1 */ public ClassLoader getClassLoader() { return classLoaderReference.getReference(); } /** - * Prevents a field from being serialized. - * - * @since 1.2 + * 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 void omitField(Class type, String fieldName) { - fieldAliasingMapper.omitField(type, fieldName); + public ClassLoaderReference getClassLoaderReference() { + return classLoaderReference; } - public static class InitializationException extends BaseException { - public InitializationException(String message, Throwable cause) { - super(message, cause); + /** + * 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(final Class definedIn, final String fieldName) { + if (fieldAliasingMapper == null) { + throw new 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(final 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 + */ + private void ignoreUnknownElements(final Pattern pattern) { + if (fieldAliasingMapper == null) { + throw new 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 (annotationMapper == null) { + throw new InitializationException("No " + AnnotationMapper.class.getName() + " available"); + } + annotationMapper.processAnnotations(types); + } + + /** + * 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(final boolean mode) { + if (annotationMapper != null) { + annotationMapper.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(final 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(final 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(final 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(final 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(final 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(final 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: + *

+ *
    + *
  • ?: 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.**'
  • + *
+ * + * @param patterns the patterns to allow type names + * @since 1.4.7 + */ + public void allowTypesByWildcard(final 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(final 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(final 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(final 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(final 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(final 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(final 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: + *

+ *
    + *
  • ?: 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.**'
  • + *
+ * + * @param patterns the patterns to forbid names + * @since 1.4.7 + */ + public void denyTypesByWildcard(final String... patterns) { + denyPermission(new WildcardTypePermission(patterns)); + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/XStreamException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/XStreamer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/alias/CannotResolveClassException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/alias/ClassMapper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/alias/NameMapper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/Annotations.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/XStreamAlias.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/XStreamAlias.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/XStreamAlias.java 10 Sep 2012 19:03:06 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/XStreamAlias.java 10 Nov 2014 12:07:41 -0000 1.1.2.1 @@ -1,19 +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 value. This annotation should only be used with classes and fields + * 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 value of the class or field value + * 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 } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/XStreamAliasType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/XStreamAsAttribute.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/XStreamContainedType.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/XStreamConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/XStreamConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/XStreamConverter.java 10 Sep 2012 19:03:06 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/XStreamConverter.java 10 Nov 2014 12:07:41 -0000 1.1.2.1 @@ -1,18 +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; -import com.thoughtworks.xstream.converters.Converter; /** + * 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) +@Target({ElementType.TYPE, ElementType.FIELD}) +@Documented public @interface XStreamConverter { - Class value(); + 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 {}; } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/XStreamConverters.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/XStreamConverters.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/XStreamConverters.java 10 Sep 2012 19:03:06 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/XStreamConverters.java 10 Nov 2014 12:07:41 -0000 1.1.2.1 @@ -1,3 +1,14 @@ +/* + * 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; Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/XStreamImplicit.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/XStreamImplicitCollection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/XStreamInclude.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/annotations/XStreamOmitField.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/ConversionException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/ConversionException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/ConversionException.java 10 Sep 2012 19:02:59 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/ConversionException.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,87 +1,115 @@ +/* + * Copyright (C) 2003, 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 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.converters; -import com.thoughtworks.xstream.core.BaseException; - -import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.Map; +import com.thoughtworks.xstream.XStreamException; + + /** - * 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. - * + * 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 BaseException implements ErrorWriter { +public class ConversionException extends XStreamException implements ErrorWriter { - private Map stuff = new HashMap(); + private static final String SEPARATOR = "\n-------------------------------"; + private final Map stuff = new LinkedHashMap(); - /** - * Plays nice with JDK1.3 and JDK1.4 - */ - protected Exception cause; - - public ConversionException(String msg, Exception cause) { - super(msg); + public ConversionException(final String msg, final Throwable cause) { + super(msg, cause); if (msg != null) { add("message", msg); } if (cause != null) { add("cause-exception", cause.getClass().getName()); - add("cause-message", cause.getMessage()); - this.cause = cause; + add("cause-message", cause instanceof ConversionException + ? ((ConversionException)cause).getShortMessage() + : cause.getMessage()); } } - public ConversionException(String msg) { + public ConversionException(final String msg) { super(msg); } - public ConversionException(Exception cause) { + public ConversionException(final Throwable cause) { this(cause.getMessage(), cause); } - public String get(String errorKey) { - return (String) stuff.get(errorKey); + @Override + public String get(final String errorKey) { + return stuff.get(errorKey); } - public void add(String name, String information) { - stuff.put(name, information); + @Override + public void add(final String name, final String information) { + String key = name; + int i = 0; + while (stuff.containsKey(key)) { + final String value = stuff.get(key); + if (information.equals(value)) { + return; + } + key = name + "[" + ++i + "]"; + } + stuff.put(key, information); } - public Iterator keys() { + @Override + public void set(final String name, final 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 + "]"; + } + } + + @Override + public Iterator keys() { return stuff.keySet().iterator(); } + @Override public String getMessage() { - StringBuffer result = new StringBuffer(); + final StringBuilder result = new StringBuilder(); if (super.getMessage() != null) { result.append(super.getMessage()); } - result.append("\n---- Debugging information ----"); - for (Iterator iterator = keys(); iterator.hasNext();) { - String k = (String) iterator.next(); - String v = get(k); + if (!result.toString().endsWith(SEPARATOR)) { + result.append("\n---- Debugging information ----"); + } + for (final Iterator iterator = keys(); iterator.hasNext();) { + final String k = iterator.next(); + final String v = get(k); result.append('\n').append(k); - int padding = 20 - k.length(); - for (int i = 0; i < padding; i++) { - result.append(' '); - } - result.append(": ").append(v).append(' '); + result.append(" ".substring(Math.min(20, k.length()))); + result.append(": ").append(v); } - result.append("\n-------------------------------"); + result.append(SEPARATOR); return result.toString(); } - public Throwable getCause() { - return cause; - } - public String getShortMessage() { return super.getMessage(); } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/Converter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/Converter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/Converter.java 10 Sep 2012 19:02:59 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/Converter.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,59 +1,66 @@ +/* + * Copyright (C) 2003, 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 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.

- *

- *

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

- *

- *

{@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).

- * + * 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.AbstractBasicConverter + * @see com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter * @see com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter */ -public interface Converter { +public interface Converter extends ConverterMatcher { /** - * Called by XStream to determine whether to use this converter - * instance to marshall a particular type. - */ - boolean canConvert(Class type); - - /** * 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. + * + * @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. + * + * @param reader the stream to read the text from. + * @param context a context that allows nested objects to be processed by XStream. + * @return the resulting object. */ Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context); Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/ConverterLookup.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/ConverterLookup.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/ConverterLookup.java 10 Sep 2012 19:02:59 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/ConverterLookup.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,24 +1,30 @@ +/* + * Copyright (C) 2003, 2004, 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 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. + *

+ * 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); - - /** - * @deprecated As of 1.1.1 you can register Converters with priorities, making the need for a default converter redundant. - */ - Converter defaultConverter(); - + Converter lookupConverterForType(Class type); } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/ConverterMatcher.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/ConverterRegistry.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/DataHolder.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/DataHolder.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/DataHolder.java 10 Sep 2012 19:02:59 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/DataHolder.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,16 +1,29 @@ +/* + * 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 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(); + Iterator keys(); } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/ErrorReporter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/ErrorWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/ErrorWriter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/ErrorWriter.java 10 Sep 2012 19:02:59 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/ErrorWriter.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,20 +1,61 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 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 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. - * + * 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. - * - * @param name Something to identify the type of information (e.g. 'XPath'). - * @param information Detail of the message (e.g. '/blah/moo[3]' + * 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(); } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/MarshallingContext.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/MarshallingContext.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/MarshallingContext.java 10 Sep 2012 19:02:59 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/MarshallingContext.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,8 +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); } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/SingleValueConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/SingleValueConverterWrapper.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/UnmarshallingContext.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/UnmarshallingContext.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/UnmarshallingContext.java 10 Sep 2012 19:02:59 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/UnmarshallingContext.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,13 +1,55 @@ +/* + * Copyright (C) 2004, 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 06. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters; public interface UnmarshallingContext extends DataHolder { - Object convertAnother(Object current, Class type); + /** + * Convert a nested object of given type. + * + * @param current the current instance (can be {@code null}) + * @param type the expected type of the nested object + * @return the unmarshalled object + */ + Object convertAnother(Object current, Class type); + /** + * Convert a nested object of given type with a specified converter. + * + * @param current the current instance (can be {@code null}) + * @param type the expected type of the nested object + * @param converter the converter to use (special cases only) + * @return the unmarshalled object + * @since 1.2 + */ + Object convertAnother(Object current, Class type, Converter converter); + + /** + * Retrieve the given root object. + * + *

This method will return only an object, if the parent object is root and the root was provided.

+ * + * @return the root object or {@code null} + * @see com.thoughtworks.xstream.XStream#unmarshal(com.thoughtworks.xstream.io.HierarchicalStreamReader, Object, DataHolder) + */ Object currentObject(); - Class getRequiredType(); + /** + * Retrieve the required type for the current conversion. + * + * @return the class type + */ + Class getRequiredType(); void addCompletionCallback(Runnable work, int priority); - + } Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/AbstractBasicConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/AbstractSingleValueConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/BigDecimalConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/BigDecimalConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/BigDecimalConverter.java 10 Sep 2012 19:02:56 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/BigDecimalConverter.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,20 +1,33 @@ +/* + * 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 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. - * + * Converts a {@link BigDecimal} to a string, retaining its precision. + * * @author Joe Walnes */ -public class BigDecimalConverter extends AbstractBasicConverter { +public class BigDecimalConverter extends AbstractSingleValueConverter { - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.equals(BigDecimal.class); } - protected Object fromString(String str) { + @Override + public Object fromString(final String str) { return new BigDecimal(str); } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/BigIntegerConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/BigIntegerConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/BigIntegerConverter.java 10 Sep 2012 19:02:56 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/BigIntegerConverter.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,19 +1,33 @@ +/* + * 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 07. May 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.basic; import java.math.BigInteger; + /** - * Converts a java.math.BigInteger to a String. - * + * Converts a {@link BigInteger} to a string. + * * @author Joe Walnes */ -public class BigIntegerConverter extends AbstractBasicConverter { +public class BigIntegerConverter extends AbstractSingleValueConverter { - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.equals(BigInteger.class); } - protected Object fromString(String str) { + @Override + public Object fromString(final String str) { return new BigInteger(str); } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/BooleanConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/BooleanConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/BooleanConverter.java 10 Sep 2012 19:02:56 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/BooleanConverter.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,19 +1,69 @@ +/* + * 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. - * + * Converts a boolean primitive or {@link Boolean} wrapper to a string. + * * @author Joe Walnes + * @author David Blevins */ -public class BooleanConverter extends AbstractBasicConverter { +public class BooleanConverter extends AbstractSingleValueConverter { - public boolean canConvert(Class type) { + 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 upcoming use {@link #canConvert(Class)} + */ + @Deprecated + public boolean shouldConvert(final Class type, final Object value) { + return true; + } + + @Override + public boolean canConvert(final Class type) { return type.equals(boolean.class) || type.equals(Boolean.class); } - protected Object fromString(String str) { - return str.equals("true") ? Boolean.TRUE : Boolean.FALSE; + @Override + 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; + } } + @Override + public String toString(final Object obj) { + final Boolean value = (Boolean)obj; + return obj == null ? null : value.booleanValue() ? positive : negative; + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/ByteConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/ByteConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/ByteConverter.java 10 Sep 2012 19:02:56 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/ByteConverter.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,19 +1,36 @@ +/* + * Copyright (C) 2003, 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 26. September 2003 by Joe Walnes + */ package com.thoughtworks.xstream.converters.basic; /** - * Converts a byte primitive or java.lang.Byte wrapper to - * a String. + * Converts a byte primitive or {@link Byte} wrapper to + * a string. * * @author Joe Walnes */ -public class ByteConverter extends AbstractBasicConverter { +public class ByteConverter extends AbstractSingleValueConverter { - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.equals(byte.class) || type.equals(Byte.class); } - protected Object fromString(String str) { - return new Byte((byte) Integer.parseInt(str)); + @Override + public Object fromString(final String str) { + final 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); } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/CharConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/CharConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/CharConverter.java 10 Sep 2012 19:02:56 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/CharConverter.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,39 +1,66 @@ +/* + * 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; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; -import com.thoughtworks.xstream.io.HierarchicalStreamReader; +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.Converter; +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, this will be marked as an attribute as - * XML does not allow this. + * Converts a char primitive or {@link 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 { +public class CharConverter implements Converter, SingleValueConverter { - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.equals(char.class) || type.equals(Character.class); } - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - if (source.toString().equals("\0")) { - writer.addAttribute("null", "true"); + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final Character ch = (Character)source; + writer.setValue(toString(ch)); + } + + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + final String nullAttribute = reader.getAttribute("null"); + if (nullAttribute != null && nullAttribute.equals("true")) { + return new Character('\0'); } else { - writer.setValue(source.toString()); + return fromString(reader.getValue()); } } - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - String nullAttribute = reader.getAttribute("null"); - if (nullAttribute != null && nullAttribute.equals("true")) { + @Override + public Object fromString(final String str) { + if (str.length() == 0) { return new Character('\0'); } else { - return new Character(reader.getValue().charAt(0)); + return new Character(str.charAt(0)); } } + @Override + public String toString(final Object obj) { + final char ch = ((Character)obj).charValue(); + return ch == '\0' ? "" : obj.toString(); + } + } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/DateConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/DateConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/DateConverter.java 10 Sep 2012 19:02:56 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/DateConverter.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,59 +1,242 @@ +/* + * Copyright (C) 2003, 2004 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 26. September 2003 by Joe Walnes + */ package com.thoughtworks.xstream.converters.basic; -import com.thoughtworks.xstream.converters.ConversionException; - 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 java.util.Date to a String as a date format, - * retaining precision down to milliseconds. - * + * 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. + *

+ *

+ * 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 AbstractBasicConverter { +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"); + // TODO: 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'"); + } + // backwards compatibility + acceptablePatterns.add("yyyy-MM-dd HH:mm:ssa"); + DEFAULT_ACCEPTABLE_FORMATS = 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.getTimeInMillis(); + } 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("yyyy-MM-dd HH:mm:ss.S z", - new String[] { - "yyyy-MM-dd HH:mm:ss.S a", - "yyyy-MM-dd HH:mm:ssz", "yyyy-MM-dd HH:mm:ss z", // JDK 1.3 needs both versions - "yyyy-MM-dd HH:mm:ssa" }); // backwards compatability - } + this(false); + } - public DateConverter(String defaultFormat, String[] acceptableFormats) { - this.defaultFormat = new ThreadSafeSimpleDateFormat(defaultFormat, 4, 20); - this.acceptableFormats = new ThreadSafeSimpleDateFormat[acceptableFormats.length]; - for (int i = 0; i < acceptableFormats.length; i++) { - this.acceptableFormats[i] = new ThreadSafeSimpleDateFormat(acceptableFormats[i], 1, 20); + /** + * 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) { + @Override + public boolean canConvert(final Class type) { return type.equals(Date.class); } - protected Object fromString(String str) { - try { - return defaultFormat.parse(str); - } catch (ParseException e) { - for (int i = 0; i < acceptableFormats.length; i++) { - try { - return acceptableFormats[i].parse(str); - } catch (ParseException e2) { - // no worries, let's try the next format. - } + @Override + public Object fromString(final String str) { + if (defaultEraFormat != null) { + try { + return defaultEraFormat.parse(str); + } catch (final ParseException e) { + // try next ... } - // no dateFormats left to try - throw new ConversionException("Cannot parse date " + str); } + if (defaultEraFormat != defaultFormat) { + try { + return defaultFormat.parse(str); + } catch (final ParseException e) { + // try next ... + } + } + for (final ThreadSafeSimpleDateFormat acceptableFormat : acceptableFormats) { + try { + return acceptableFormat.parse(str); + } catch (final ParseException e3) { + // no worries, let's try the next format. + } + } + // no dateFormats left to try + throw new ConversionException("Cannot parse date " + str); } - protected String toString(Object obj) { - return defaultFormat.format((Date) obj); + @Override + public String toString(final Object obj) { + final Date date = (Date)obj; + if (date.getTime() < ERA_START && defaultEraFormat != null) { + return defaultEraFormat.format(date); + } else { + return defaultFormat.format(date); + } } + @Override + public void appendErrors(final ErrorWriter errorWriter) { + errorWriter.add("Default date pattern", defaultFormat.toString()); + if (defaultEraFormat != null) { + errorWriter.add("Default era date pattern", defaultEraFormat.toString()); + } + for (final ThreadSafeSimpleDateFormat acceptableFormat : acceptableFormats) { + errorWriter.add("Alternative date pattern", acceptableFormat.toString()); + } + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/DoubleConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/DoubleConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/DoubleConverter.java 10 Sep 2012 19:02:56 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/DoubleConverter.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,18 +1,30 @@ +/* + * 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 double primitive or java.lang.Double wrapper to - * a String. - * + * Converts a double primitive or {@link Double} wrapper to a string. + * * @author Joe Walnes */ -public class DoubleConverter extends AbstractBasicConverter { +public class DoubleConverter extends AbstractSingleValueConverter { - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.equals(double.class) || type.equals(Double.class); } - protected Object fromString(String str) { + @Override + public Object fromString(final String str) { return Double.valueOf(str); } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/FloatConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/FloatConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/FloatConverter.java 10 Sep 2012 19:02:56 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/FloatConverter.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,18 +1,30 @@ +/* + * 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 float primitive or java.lang.Float wrapper to - * a String. - * + * Converts a float primitive or {@link Float} wrapper to a string. + * * @author Joe Walnes */ -public class FloatConverter extends AbstractBasicConverter { +public class FloatConverter extends AbstractSingleValueConverter { - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.equals(float.class) || type.equals(Float.class); } - protected Object fromString(String str) { + @Override + public Object fromString(final String str) { return Float.valueOf(str); } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/IntConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/IntConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/IntConverter.java 10 Sep 2012 19:02:56 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/IntConverter.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,19 +1,35 @@ +/* + * 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. - * + * Converts an int primitive or {@link Integer} wrapper to a string. + * * @author Joe Walnes */ -public class IntConverter extends AbstractBasicConverter { +public class IntConverter extends AbstractSingleValueConverter { - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.equals(int.class) || type.equals(Integer.class); } - protected Object fromString(String str) { - return Integer.decode(str); + @Override + public Object fromString(final String str) { + final 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); } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/LongConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/LongConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/LongConverter.java 10 Sep 2012 19:02:56 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/LongConverter.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,19 +1,58 @@ +/* + * Copyright (C) 2003, 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 26. September 2003 by Joe Walnes + */ package com.thoughtworks.xstream.converters.basic; /** - * Converts a long primitive or java.lang.Long wrapper to - * a String. - * + * Converts a long primitive or {@link Long} wrapper to a string. + * * @author Joe Walnes */ -public class LongConverter extends AbstractBasicConverter { +public class LongConverter extends AbstractSingleValueConverter { - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.equals(long.class) || type.equals(Long.class); } - protected Object fromString(String str) { - return Long.valueOf(str); + @Override + public Object fromString(final String str) { + final int len = str.length(); + if (len == 0) { + throw new NumberFormatException("For input string: \"\""); + } + if (len < 17) { + return Long.decode(str); + } + final char c0 = str.charAt(0); + if (c0 != '0' && c0 != '#') { + return Long.decode(str); + } + final 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); } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/NullConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/NullConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/NullConverter.java 10 Sep 2012 19:02:56 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/NullConverter.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,28 +1,45 @@ +/* + * 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 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.ExtendedHierarchicalStreamWriterHelper; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + /** - * Special converter to signify nulls at the root level. - * + * Special converter to signify nulls at the root level or in collection types. + * * @author Joe Walnes */ public class NullConverter implements Converter { - public boolean canConvert(Class type) { - return type == null; + @Override + public boolean canConvert(final Class type) { + return type == null || Mapper.Null.class.isAssignableFrom(type); } - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - writer.startNode("null"); + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + ExtendedHierarchicalStreamWriterHelper.startNode(writer, "null", Mapper.Null.class); writer.endNode(); } - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { return null; } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/ShortConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/ShortConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/ShortConverter.java 10 Sep 2012 19:02:56 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/ShortConverter.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,19 +1,35 @@ +/* + * 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 short primitive or java.lang.Short wrapper to - * a String. - * + * Converts a short primitive or {@link Short} wrapper to a string. + * * @author Joe Walnes */ -public class ShortConverter extends AbstractBasicConverter { +public class ShortConverter extends AbstractSingleValueConverter { - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.equals(short.class) || type.equals(Short.class); } - protected Object fromString(String str) { - return Short.valueOf(str); + @Override + public Object fromString(final String str) { + final 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); } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/StringBufferConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/StringBufferConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/StringBufferConverter.java 10 Sep 2012 19:02:56 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/StringBufferConverter.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,17 +1,30 @@ +/* + * 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 29. September 2003 by Joe Walnes + */ package com.thoughtworks.xstream.converters.basic; /** - * Converts the contents of a StringBuffer to XML. - * + * Converts the contents of a {@link StringBuffer} to a string. + * * @author Joe Walnes */ -public class StringBufferConverter extends AbstractBasicConverter { +public class StringBufferConverter extends AbstractSingleValueConverter { - protected Object fromString(String str) { - return new StringBuffer(str); + @Override + public boolean canConvert(final Class type) { + return type.equals(StringBuffer.class); } - public boolean canConvert(Class type) { - return type.equals(StringBuffer.class); + @Override + public Object fromString(final String str) { + return new StringBuffer(str); } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/StringBuilderConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/StringConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/StringConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/StringConverter.java 10 Sep 2012 19:02:56 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/StringConverter.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,22 +1,103 @@ +/* + * Copyright (C) 2003, 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 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 always calls intern() on the returned - * String to encourage the JVM to reuse instances.

- * + * Converts a {@link 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 - * @see String#intern() + * @author Rene Schwietzke + * @author Jörg Schaible */ -public class StringConverter extends AbstractBasicConverter { +public class StringConverter extends AbstractSingleValueConverter { - public boolean canConvert(Class type) { - return type.equals(String.class); + 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, synchronized 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, final int lengthLimit) { + cache = map; + this.lengthLimit = lengthLimit; } - protected Object fromString(String str) { - return str.intern(); + /** + * 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(final 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); + } + + @Override + public boolean canConvert(final Class type) { + return type.equals(String.class); + } + + @Override + public Object fromString(final String str) { + if (cache != null && str != null && (lengthLimit < 0 || str.length() <= lengthLimit)) { + String s = cache.get(str); + + if (s == null) { + // fill cache + cache.put(str, str); + + s = str; + } + + return s; + } else { + return str; + } + } } Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/ThreadSafeSimpleDateFormat.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/URIConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/URLConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/URLConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/URLConverter.java 10 Sep 2012 19:02:56 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/URLConverter.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,25 +1,39 @@ +/* + * 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 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; +import com.thoughtworks.xstream.converters.ConversionException; + + /** - * Converts a java.net.URL to a string. - * + * Converts a {@link URL} to a string. + * * @author J. Matthew Pryor */ -public class URLConverter extends AbstractBasicConverter { +public class URLConverter extends AbstractSingleValueConverter { - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.equals(URL.class); } - protected Object fromString(String str) { + @Override + public Object fromString(final String str) { try { return new URL(str); - } catch (MalformedURLException e) { + } catch (final MalformedURLException e) { throw new ConversionException(e); } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/UUIDConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/package.html,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/package.html 10 Sep 2012 19:02:56 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/basic/package.html 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,3 +1,15 @@ + +

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, @@ -7,3 +19,4 @@

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

+ \ No newline at end of file Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/AbstractCollectionConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/AbstractCollectionConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/AbstractCollectionConverter.java 10 Sep 2012 19:02:59 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/AbstractCollectionConverter.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,94 +1,85 @@ +/* + * Copyright (C) 2003, 2004, 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 26. September 2003 by Joe Walnes + */ package com.thoughtworks.xstream.converters.collections; -import com.thoughtworks.xstream.alias.ClassMapper; 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.ExtendedHierarchicalStreamWriterHelper; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; 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.

- * + * 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; - /** - * @deprecated As of 1.1.1, use {@link #mapper()} - */ - protected ClassMapper classMapper; + @Override + public abstract boolean canConvert(Class type); - /** - * @deprecated As of 1.1.1, use {@link #mapper()} - */ - protected String classAttributeIdentifier; - - public abstract boolean canConvert(Class type); - - /** - * @deprecated As of 1.1.1, use other constructor. - */ - public AbstractCollectionConverter(ClassMapper classMapper, String classAttributeIdentifier) { - // TODO: this classAttributeIdentifer should be optional - most uses of XStream don't need it. - this.classMapper = classMapper; - this.classAttributeIdentifier = classAttributeIdentifier; - this.mapper = classMapper; - } - - public AbstractCollectionConverter(Mapper mapper) { + public AbstractCollectionConverter(final Mapper mapper) { this.mapper = mapper; } protected Mapper mapper() { return mapper; } + @Override public abstract void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context); + @Override 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 compatability. + protected void writeItem(final Object item, final MarshallingContext context, final HierarchicalStreamWriter writer) { + // PUBLISHED API METHOD! If changing signature, ensure backwards compatibility. if (item == null) { // todo: this is duplicated in TreeMarshaller.start() - writer.startNode(mapper().serializedClass(ClassMapper.Null.class)); + final String name = mapper().serializedClass(null); + ExtendedHierarchicalStreamWriterHelper.startNode(writer, name, Mapper.Null.class); writer.endNode(); } else { - writer.startNode(mapper().serializedClass(item.getClass())); + final 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) { - // PUBLISHED API METHOD! If changing signature, ensure backwards compatability. - String classAttribute = reader.getAttribute(mapper().attributeForImplementationClass()); - Class type; - if (classAttribute == null) { - type = mapper().realClass(reader.getNodeName()); - } else { - type = mapper().realClass(classAttribute); - } + protected Object readItem(final HierarchicalStreamReader reader, final UnmarshallingContext context, + final Object current) { + final Class type = HierarchicalStreams.readClassType(reader, mapper()); return context.convertAnother(current, type); } - protected Object createCollection(Class type) { - Class defaultType = mapper().defaultImplementationOf(type); + protected Object createCollection(final Class type) { + final Class defaultType = mapper().defaultImplementationOf(type); try { return defaultType.newInstance(); - } catch (InstantiationException e) { + } catch (final InstantiationException e) { throw new ConversionException("Cannot instantiate " + defaultType.getName(), e); - } catch (IllegalAccessException e) { + } catch (final IllegalAccessException e) { throw new ConversionException("Cannot instantiate " + defaultType.getName(), e); } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/ArrayConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/ArrayConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/ArrayConverter.java 10 Sep 2012 19:02:59 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/ArrayConverter.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,64 +1,69 @@ +/* + * Copyright (C) 2003, 2004, 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 03. October 2003 by Joe Walnes + */ package com.thoughtworks.xstream.converters.collections; -import com.thoughtworks.xstream.alias.ClassMapper; +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.List; + 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. - * + * Converts an array of objects or primitives, using a nested child element for each item. + * * @author Joe Walnes + * @see com.thoughtworks.xstream.converters.extended.NamedArrayConverter */ public class ArrayConverter extends AbstractCollectionConverter { - /** - * @deprecated As of 1.1.1, use other constructor. - */ - public ArrayConverter(ClassMapper classMapper, String classAttributeIdentifier) { - super(classMapper, classAttributeIdentifier); - } - - public ArrayConverter(Mapper mapper) { + public ArrayConverter(final Mapper mapper) { super(mapper); } - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.isArray(); } - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - int length = Array.getLength(source); + @Override + 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++) { - Object item = Array.get(source, i); + final 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(); + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + // read the items from xml into a list (the array size is not known until all items have been read) + final List items = new ArrayList(); while (reader.hasMoreChildren()) { reader.moveDown(); - Object item = readItem(reader, context, null); // TODO: arg, what should replace null? + final 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()); + final 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()); + for (final Object item : items) { + Array.set(array, i++, item); } return array; } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/BitSetConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/BitSetConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/BitSetConverter.java 10 Sep 2012 19:02:59 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/BitSetConverter.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,29 +1,42 @@ +/* + * 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 07. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.collections; +import java.util.BitSet; +import java.util.StringTokenizer; + 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. - * + * Converts a {@link BitSet}, as a compact comma delimited list of ones and zeros. + * * @author Joe Walnes */ public class BitSetConverter implements Converter { - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.equals(BitSet.class); } - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - BitSet bitSet = (BitSet) source; - StringBuffer buffer = new StringBuffer(); + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final BitSet bitSet = (BitSet)source; + final StringBuilder buffer = new StringBuilder(); boolean seenFirst = false; for (int i = 0; i < bitSet.length(); i++) { if (bitSet.get(i)) { @@ -38,11 +51,12 @@ writer.setValue(buffer.toString()); } - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - BitSet result = new BitSet(); - StringTokenizer tokenizer = new StringTokenizer(reader.getValue(), ",", false); + @Override + public BitSet unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + final BitSet result = new BitSet(); + final StringTokenizer tokenizer = new StringTokenizer(reader.getValue(), ",", false); while (tokenizer.hasMoreTokens()) { - int index = Integer.parseInt(tokenizer.nextToken()); + final int index = Integer.parseInt(tokenizer.nextToken()); result.set(index); } return result; Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/CharArrayConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/CharArrayConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/CharArrayConverter.java 10 Sep 2012 19:02:59 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/CharArrayConverter.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,3 +1,14 @@ +/* + * 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 06. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.collections; import com.thoughtworks.xstream.converters.Converter; @@ -6,24 +17,27 @@ import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; + /** - * Converts a char[] to XML, storing the contents as a single - * String. - * + * Converts a char[] as a single string. + * * @author Joe Walnes */ public class CharArrayConverter implements Converter { - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.isArray() && type.getComponentType().equals(char.class); } - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - char[] chars = (char[]) source; + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + char[] chars = (char[])source; writer.setValue(new String(chars)); } - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + @Override + public char[] unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { return reader.getValue().toCharArray(); } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/CollectionConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/CollectionConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/CollectionConverter.java 10 Sep 2012 19:02:59 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/CollectionConverter.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,66 +1,116 @@ +/* + * Copyright (C) 2003, 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 01. October 2003 by Joe Walnes + */ package com.thoughtworks.xstream.converters.collections; -import com.thoughtworks.xstream.alias.ClassMapper; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.Vector; + 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.*; /** - * 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.

- * + * Converts most common Collections (Lists and Sets), specifying a nested element for each item. + *

+ * Supports {@link ArrayList}, {@link HashSet}, {@link LinkedList}, {@link Vector} and {@link LinkedHashSet}. + *

+ * * @author Joe Walnes + * @see com.thoughtworks.xstream.converters.extended.NamedCollectionConverter */ public class CollectionConverter extends AbstractCollectionConverter { - /** - * @deprecated As of 1.1.1, use other constructor. - */ - public CollectionConverter(ClassMapper classMapper, String classAttributeIdentifier) { - super(classMapper, classAttributeIdentifier); + private final Class> type; + + public CollectionConverter(final Mapper mapper) { + this(mapper, null); } - public CollectionConverter(Mapper mapper) { + /** + * 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(final Mapper mapper, @SuppressWarnings("rawtypes") final Class type) { super(mapper); + @SuppressWarnings("unchecked") + final Class> checkedType = (Class>)type; + this.type = checkedType; + if (type != null && !Collection.class.isAssignableFrom(type)) { + throw new IllegalArgumentException(type + " not of type " + Collection.class); + } } - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final 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")); + || type.equals(HashSet.class) + || type.equals(LinkedList.class) + || type.equals(Vector.class) + || type.equals(LinkedHashSet.class); } - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - Collection collection = (Collection) source; - for (Iterator iterator = collection.iterator(); iterator.hasNext();) { - Object item = iterator.next(); + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final Collection collection = (Collection)source; + for (final Object item : collection) { writeItem(item, context, writer); } } - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - Collection collection = (Collection) createCollection(context.getRequiredType()); + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + final Class collectionType = context.getRequiredType(); + final Collection collection = createCollection(collectionType); populateCollection(reader, context, collection); return collection; } - protected void populateCollection(HierarchicalStreamReader reader, UnmarshallingContext context, Collection collection) { + protected void populateCollection(final HierarchicalStreamReader reader, final UnmarshallingContext context, + final Collection collection) { + populateCollection(reader, context, collection, collection); + } + + protected void populateCollection(final HierarchicalStreamReader reader, final UnmarshallingContext context, + final Collection collection, final Collection target) { while (reader.hasMoreChildren()) { reader.moveDown(); - Object item = readItem(reader, context, collection); - collection.add(item); + addCurrentElementToCollection(reader, context, collection, target); reader.moveUp(); } } + protected void addCurrentElementToCollection(final HierarchicalStreamReader reader, + final UnmarshallingContext context, final Collection collection, final Collection target) { + final Object item = readItem(reader, context, collection); + @SuppressWarnings("unchecked") + final Collection targetCollection = (Collection)target; + targetCollection.add(item); + } + + @Override + protected Collection createCollection(final Class type) { + return (Collection)super.createCollection(this.type != null ? this.type : type); + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/MapConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/MapConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/MapConverter.java 10 Sep 2012 19:02:59 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/MapConverter.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,51 +1,88 @@ +/* + * Copyright (C) 2003, 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 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 26. September 2003 by Joe Walnes + */ package com.thoughtworks.xstream.converters.collections; -import com.thoughtworks.xstream.alias.ClassMapper; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + import com.thoughtworks.xstream.converters.MarshallingContext; 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 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. - *

- *

Supports java.util.HashMap, java.util.Hashtable and - * java.util.LinkedHashMap.

- * + * Converts a {@link Map}, 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 {@link HashMap}, {@link Hashtable}, {@link LinkedHashMap}, {@link ConcurrentHashMap} and + * sun.font.AttributeMap. + *

+ * + * @see com.thoughtworks.xstream.converters.extended.NamedMapConverter * @author Joe Walnes */ public class MapConverter extends AbstractCollectionConverter { - /** - * @deprecated As of 1.1.1, use other constructor. - */ - public MapConverter(ClassMapper classMapper, String classAttributeIdentifier) { - super(classMapper, classAttributeIdentifier); + private final Class> type; + + public MapConverter(final Mapper mapper) { + this(mapper, null); } - public MapConverter(Mapper mapper) { + /** + * Construct a MapConverter for a special Map type. + * + * @param mapper the mapper + * @param type the type to handle + * @since 1.4.5 + */ + public MapConverter(final Mapper mapper, @SuppressWarnings("rawtypes") final Class type) { super(mapper); + @SuppressWarnings("unchecked") + final Class> checkedType = (Class>)type; + this.type = checkedType; + if (type != null && !Map.class.isAssignableFrom(type)) { + throw new IllegalArgumentException(type + " not of type " + Map.class); + } } - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { + if (this.type != null) { + return type.equals(this.type); + } return type.equals(HashMap.class) - || type.equals(Hashtable.class) - || (JVM.is14() && type.getName().equals("java.util.LinkedHashMap")); + || type.equals(Hashtable.class) + || type.equals(LinkedHashMap.class) + || type.equals(ConcurrentHashMap.class) + || type.getName().equals("sun.font.AttributeMap") // Used by java.awt.Font since JDK 6 + ; } - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - Map map = (Map) source; - for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) { - Map.Entry entry = (Map.Entry) iterator.next(); - writer.startNode(mapper().serializedClass(Map.Entry.class)); + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final Map map = (Map)source; + final String entryName = mapper().serializedClass(Map.Entry.class); + for (final Map.Entry entry : map.entrySet()) { + ExtendedHierarchicalStreamWriterHelper.startNode(writer, entryName, entry.getClass()); writeItem(entry.getKey(), context, writer); writeItem(entry.getValue(), context, writer); @@ -54,28 +91,45 @@ } } - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - Map map = (Map) createCollection(context.getRequiredType()); + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + final Class requiredType = context.getRequiredType(); + final Map map = createCollection(requiredType); populateMap(reader, context, map); return map; } - protected void populateMap(HierarchicalStreamReader reader, UnmarshallingContext context, Map map) { + protected void populateMap(final HierarchicalStreamReader reader, final UnmarshallingContext context, + final Map map) { + populateMap(reader, context, map, map); + } + + protected void populateMap(final HierarchicalStreamReader reader, final UnmarshallingContext context, + final Map map, final Map target) { while (reader.hasMoreChildren()) { reader.moveDown(); - - reader.moveDown(); - Object key = readItem(reader, context, map); + putCurrentEntryIntoMap(reader, context, map, target); reader.moveUp(); + } + } - reader.moveDown(); - Object value = readItem(reader, context, map); - reader.moveUp(); + protected void putCurrentEntryIntoMap(final HierarchicalStreamReader reader, final UnmarshallingContext context, + final Map map, final Map target) { + reader.moveDown(); + final Object key = readItem(reader, context, map); + reader.moveUp(); - map.put(key, value); + reader.moveDown(); + final Object value = readItem(reader, context, map); + reader.moveUp(); - reader.moveUp(); - } + @SuppressWarnings("unchecked") + final Map targetMap = (Map)target; + targetMap.put(key, value); } + @Override + protected Map createCollection(final Class type) { + return (Map)super.createCollection(this.type != null ? this.type : type); + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/PropertiesConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/PropertiesConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/PropertiesConverter.java 10 Sep 2012 19:02:59 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/PropertiesConverter.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,70 +1,104 @@ +/* + * Copyright (C) 2004, 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 23. February 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.collections; +import java.lang.reflect.Field; +import java.util.Map; +import java.util.Properties; +import java.util.TreeMap; + import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.MarshallingContext; import com.thoughtworks.xstream.converters.UnmarshallingContext; -import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.core.util.Fields; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; -import com.thoughtworks.xstream.core.util.Fields; -import java.util.Iterator; -import java.util.Map; -import java.util.Properties; -import java.lang.reflect.Field; /** - * 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.

- * + * Special converter for {@link 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 Field defaultsField = Fields.find(Properties.class, "defaults"); + private final static Field defaultsField = Fields.locate(Properties.class, Properties.class, false); + private final boolean sort; - public boolean canConvert(Class type) { + public PropertiesConverter() { + this(false); + } + + public PropertiesConverter(final boolean sort) { + this.sort = sort; + } + + @Override + public boolean canConvert(final Class type) { return Properties.class == type; } - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - Properties properties = (Properties) source; - for (Iterator iterator = properties.entrySet().iterator(); iterator.hasNext();) { - Map.Entry entry = (Map.Entry) iterator.next(); + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final Properties properties = (Properties)source; + final Map map = sort ? new TreeMap(properties) : properties; + for (final Map.Entry entry : map.entrySet()) { writer.startNode("property"); writer.addAttribute("name", entry.getKey().toString()); writer.addAttribute("value", entry.getValue().toString()); writer.endNode(); } - Properties defaults = (Properties) Fields.read(defaultsField, properties); - if (defaults != null) { - writer.startNode("defaults"); - marshal(defaults, writer, context); - writer.endNode(); + if (defaultsField != null) { + final 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(); + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + final Properties properties = new Properties(); + Properties defaults = null; while (reader.hasMoreChildren()) { reader.moveDown(); if (reader.getNodeName().equals("defaults")) { - Properties defaults = (Properties) unmarshal(reader, context); - Fields.write(defaultsField, properties, defaults); + defaults = (Properties)unmarshal(reader, context); } else { - String name = reader.getAttribute("name"); - String value = reader.getAttribute("value"); + final String name = reader.getAttribute("name"); + final String value = reader.getAttribute("value"); properties.setProperty(name, value); } reader.moveUp(); } - return properties; + if (defaults == null) { + return properties; + } else { + final Properties propertiesWithDefaults = new Properties(defaults); + propertiesWithDefaults.putAll(properties); + return propertiesWithDefaults; + } } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/SingletonCollectionConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/SingletonMapConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/TreeMapConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/TreeMapConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/TreeMapConverter.java 10 Sep 2012 19:02:59 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/TreeMapConverter.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,69 +1,143 @@ +/* + * 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.alias.ClassMapper; +import java.lang.reflect.Field; +import java.util.Comparator; +import java.util.SortedMap; +import java.util.TreeMap; + 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.util.Comparator; -import java.util.TreeMap; /** - * Converts a java.util.TreeMap to XML, and serializes - * the associated java.util.Comparator. - * + * Converts a {@link TreeMap} to XML, and serializes the associated {@link 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 { - /** - * @deprecated As of 1.1.1, use other constructor. - */ - public TreeMapConverter(ClassMapper classMapper, String classAttributeIdentifier) { - super(classMapper, classAttributeIdentifier); + private static final class NullComparator extends Mapper.Null implements Comparator> { + @Override + @SuppressWarnings({"unchecked", "rawtypes"}) + public int compare(final Comparable o1, final Comparable o2) { + return o1.compareTo(o2); + } } - public TreeMapConverter(Mapper mapper) { - super(mapper); + @SuppressWarnings("rawtypes") + private final static Comparator NULL_MARKER = new NullComparator(); + private final static Field comparatorField = Fields.locate(TreeMap.class, Comparator.class, false); + + public TreeMapConverter(final Mapper mapper) { + super(mapper, TreeMap.class); } - public boolean canConvert(Class type) { - return type.equals(TreeMap.class); + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final SortedMap sortedMap = (SortedMap)source; + marshalComparator(sortedMap.comparator(), writer, context); + super.marshal(source, writer, context); } - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - TreeMap treeMap = (TreeMap) source; - Comparator comparator = treeMap.comparator(); - if (comparator == null) { - writer.startNode("no-comparator"); - writer.endNode(); - } else { + protected void marshalComparator(final Comparator comparator, final HierarchicalStreamWriter writer, + final MarshallingContext context) { + if (comparator != null) { writer.startNode("comparator"); - writer.addAttribute("class", mapper().serializedClass(comparator.getClass())); + writer.addAttribute(mapper().aliasForSystemAttribute("class"), mapper().serializedClass( + comparator.getClass())); context.convertAnother(comparator); writer.endNode(); } - super.marshal(source, writer, context); } - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - reader.moveDown(); - TreeMap result; - if (reader.getNodeName().equals("comparator")) { - String comparatorClass = reader.getAttribute("class"); - Comparator comparator = (Comparator) context.convertAnother(null, mapper().realClass(comparatorClass)); - result = new TreeMap(comparator); - } else if (reader.getNodeName().equals("no-comparator")) { - result = new TreeMap(); - } else { - throw new ConversionException("TreeMap does not contain element"); + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + TreeMap result = comparatorField != null ? new TreeMap() : null; + @SuppressWarnings("unchecked") + final Comparator comparator = (Comparator)unmarshalComparator(reader, context, result); + if (result == null) { + result = comparator == null ? new TreeMap() : new TreeMap(comparator); } - reader.moveUp(); - super.populateMap(reader, context, result); + populateTreeMap(reader, context, result, comparator); return result; } + protected Comparator unmarshalComparator(final HierarchicalStreamReader reader, + final UnmarshallingContext context, final TreeMap result) { + final Comparator comparator; + if (reader.hasMoreChildren()) { + reader.moveDown(); + if (reader.getNodeName().equals("comparator")) { + final 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(final HierarchicalStreamReader reader, final UnmarshallingContext context, + final TreeMap result, Comparator comparator) { + final boolean inFirstElement = comparator == NULL_MARKER; + if (inFirstElement) { + comparator = null; + } + @SuppressWarnings("unchecked") + final SortedMap sortedMap = new PresortedMap( + (Comparator)(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); + @SuppressWarnings("unchecked") + final TreeMap typedResult = (TreeMap)result; + try { + if (JVM.hasOptimizedTreeMapPutAll()) { + if (comparator != null && comparatorField != null) { + comparatorField.set(result, comparator); + } + typedResult.putAll(sortedMap); // internal optimization will not call comparator + } else if (comparatorField != null) { + comparatorField.set(result, sortedMap.comparator()); + typedResult.putAll(sortedMap); // "sort" by index + comparatorField.set(result, comparator); + } else { + typedResult.putAll(sortedMap); // will use comparator for already sorted map + } + } catch (final IllegalAccessException e) { + throw new ConversionException("Cannot set comparator of TreeMap", e); + } + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java 10 Sep 2012 19:02:59 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/TreeSetConverter.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,69 +1,141 @@ +/* + * 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.alias.ClassMapper; +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; + 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.util.Comparator; -import java.util.TreeSet; /** - * Converts a java.util.TreeSet to XML, and serializes - * the associated java.util.Comparator. - * + * Converts a {@link TreeSet} to XML, and serializes the associated {@link 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 = JVM.hasOptimizedTreeSetAddAll() ? Fields.locate(TreeSet.class, + SortedMap.class, false) : null; - /** - * @deprecated As of 1.1.1, use other constructor. - */ - public TreeSetConverter(ClassMapper classMapper, String classAttributeIdentifier) { - super(classMapper, classAttributeIdentifier); + public TreeSetConverter(final Mapper mapper) { + super(mapper, TreeSet.class); + readResolve(); } - public TreeSetConverter(Mapper mapper) { - super(mapper); + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final SortedSet sortedSet = (SortedSet)source; + treeMapConverter.marshalComparator(sortedSet.comparator(), writer, context); + super.marshal(source, writer, context); } - public boolean canConvert(Class type) { - return type.equals(TreeSet.class); - } - - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - TreeSet treeSet = (TreeSet) source; - Comparator comparator = treeSet.comparator(); - if (comparator == null) { - writer.startNode("no-comparator"); - writer.endNode(); + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + TreeSet result = null; + final TreeMap treeMap; + final Comparator unmarshalledComparator = treeMapConverter.unmarshalComparator(reader, context, null); + final boolean inFirstElement = unmarshalledComparator instanceof Mapper.Null; + @SuppressWarnings("unchecked") + final Comparator comparator = inFirstElement ? null : (Comparator)unmarshalledComparator; + if (sortedMapField != null) { + final TreeSet possibleResult = comparator == null ? new TreeSet() : new TreeSet( + comparator); + Object backingMap = null; + try { + backingMap = sortedMapField.get(possibleResult); + } catch (final 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 { - writer.startNode("comparator"); - writer.addAttribute("class", mapper().serializedClass(comparator.getClass())); - context.convertAnother(comparator); - writer.endNode(); + treeMap = null; } - super.marshal(source, writer, context); - } - - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - reader.moveDown(); - TreeSet result; - if (reader.getNodeName().equals("comparator")) { - String comparatorClass = reader.getAttribute("class"); - Comparator comparator = (Comparator) context.convertAnother(null, mapper().realClass(comparatorClass)); - result = new TreeSet(comparator); - } else if (reader.getNodeName().equals("no-comparator")) { - result = new TreeSet(); + 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 { - throw new ConversionException("TreeSet does not contain element"); + treeMapConverter.populateTreeMap(reader, context, treeMap, unmarshalledComparator); } - reader.moveUp(); - super.populateCollection(reader, context, result); return result; } + private Object readResolve() { + treeMapConverter = new TreeMapConverter(mapper()) { + + @Override + protected void populateMap(final HierarchicalStreamReader reader, final UnmarshallingContext context, + final Map map, final Map target) { + populateCollection(reader, context, new AbstractList() { + @Override + public boolean add(final Object object) { + @SuppressWarnings("unchecked") + final Map collectionTarget = (Map)target; + return collectionTarget.put(object, object) != null; + } + + @Override + public Object get(final int location) { + return null; + } + + @Override + public int size() { + return target.size(); + } + }); + } + + @Override + protected void putCurrentEntryIntoMap(final HierarchicalStreamReader reader, + final UnmarshallingContext context, final Map map, final Map target) { + final Object key = readItem(reader, context, map); + @SuppressWarnings("unchecked") + final Map checkedTarget = (Map)target; + checkedTarget.put(key, key); + } + }; + return this; + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/package.html,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/package.html 10 Sep 2012 19:02:59 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/collections/package.html 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,4 +1,17 @@ -

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

+ + +

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.

\ No newline at end of file +

All the converters in this package are enabled by default.

+ Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/enums/EnumConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/enums/EnumConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/enums/EnumConverter.java 10 Sep 2012 19:03:00 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/enums/EnumConverter.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,3 +1,15 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 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 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. @@ -7,31 +19,55 @@ 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; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.EnumMapper; + /** - * Converter for JDK 1.5 enums. Combined with EnumMapper this also deals with polymorphic enums. - * - * @author Eric Snell + * Converter for {@link Enum} types. + *

+ * Combined with {@link EnumMapper} this also deals with polymorphic enums. + *

+ * + * @author Eric Snell * @author Bryan Coleman */ public class EnumConverter implements Converter { - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.isEnum() || Enum.class.isAssignableFrom(type); } - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - writer.setValue(((Enum) source).name()); + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + writer.setValue(((Enum)source).name()); } - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - Class type = context.getRequiredType(); + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + Class type = context.getRequiredType(); if (type.getSuperclass() != Enum.class) { type = type.getSuperclass(); // polymorphic enums } - return Enum.valueOf(type, reader.getValue()); + final String name = reader.getValue(); + try { + @SuppressWarnings("rawtypes") + final Class rawType = type; + @SuppressWarnings("unchecked") + final Enum enumValue = Enum.valueOf(rawType, name); + return enumValue; + } catch (final IllegalArgumentException e) { + // failed to find it, do a case insensitive match + for (final Enum c : (Enum[])type.getEnumConstants()) { + if (c.name().equalsIgnoreCase(name)) { + return c; + } + } + // all else failed + throw e; + } } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/enums/EnumMapConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/enums/EnumMapConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/enums/EnumMapConverter.java 10 Sep 2012 19:03:00 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/enums/EnumMapConverter.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,47 +1,71 @@ -// ***** 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. +/* + * 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. April 2005 by Joe Walnes + */ package com.thoughtworks.xstream.converters.enums; -import com.thoughtworks.xstream.converters.collections.MapConverter; +import java.lang.reflect.Field; +import java.util.EnumMap; + +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.converters.collections.MapConverter; import com.thoughtworks.xstream.core.util.Fields; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; -import java.util.EnumMap; -import java.lang.reflect.Field; /** - * Serializes an Java 5 EnumMap, including the type of Enum it's for. - * + * Converts an {@link EnumMap}, including the type of Enum it's for. + *

+ * If a {@link 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 Field typeField; + private final static Field typeField = Fields.locate(EnumMap.class, Class.class, false); - public EnumMapConverter(Mapper mapper) { + public EnumMapConverter(final Mapper mapper) { super(mapper); - typeField = Fields.find(EnumMap.class, "keyType"); } - public boolean canConvert(Class type) { - return type == EnumMap.class; + @Override + public boolean canConvert(final Class type) { + return typeField != null && type == EnumMap.class; } - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - Class type = (Class) Fields.read(typeField, source); - writer.addAttribute(mapper().attributeForEnumType(), mapper().serializedClass(type)); + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final Class type = (Class)Fields.read(typeField, source); + final String attributeName = mapper().aliasForSystemAttribute("enum-type"); + if (attributeName != null) { + writer.addAttribute(attributeName, mapper().serializedClass(type)); + } super.marshal(source, writer, context); } - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - Class type = mapper().realClass(reader.getAttribute(mapper().attributeForEnumType())); - EnumMap map = new EnumMap(type); + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + final String attributeName = mapper().aliasForSystemAttribute("enum-type"); + if (attributeName == null) { + throw new ConversionException("No EnumType specified for EnumMap"); + } + final Class type = mapper().realClass(reader.getAttribute(attributeName)); + @SuppressWarnings({"rawtypes", "unchecked"}) + final EnumMap map = new EnumMap(type); populateMap(reader, context, map); return map; } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/enums/EnumSetConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/enums/EnumSetConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/enums/EnumSetConverter.java 10 Sep 2012 19:03:00 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/enums/EnumSetConverter.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,52 +1,69 @@ -// ***** 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. +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 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 06. April 2005 by Joe Walnes + */ package com.thoughtworks.xstream.converters.enums; +import java.lang.reflect.Field; +import java.util.EnumSet; + +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.Fields; 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. - * + * Converts an {@link 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 Field typeField; + private final static Field typeField = Fields.locate(EnumSet.class, Class.class, false); private final Mapper mapper; - public EnumSetConverter(Mapper mapper) { + public EnumSetConverter(final Mapper mapper) { this.mapper = mapper; - typeField = Fields.find(EnumSet.class, "elementType"); } - public boolean canConvert(Class type) { - return EnumSet.class.isAssignableFrom(type); + @Override + public boolean canConvert(final 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); - writer.addAttribute(mapper.attributeForEnumType(), mapper.serializedClass(enumTypeForSet)); + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final EnumSet set = (EnumSet)source; + final Class enumTypeForSet = (Class)Fields.read(typeField, set); + final String attributeName = mapper.aliasForSystemAttribute("enum-type"); + if (attributeName != null) { + writer.addAttribute(attributeName, mapper.serializedClass(enumTypeForSet)); + } writer.setValue(joinEnumValues(set)); } - private String joinEnumValues(EnumSet set) { + private String joinEnumValues(final EnumSet set) { boolean seenFirst = false; - StringBuffer result = new StringBuffer(); - for (Iterator iterator = set.iterator(); iterator.hasNext();) { - Enum value = (Enum) iterator.next(); + final StringBuilder result = new StringBuilder(); + for (final Enum value : set) { if (seenFirst) { result.append(','); } else { @@ -57,14 +74,26 @@ return result.toString(); } - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - Class enumTypeForSet = mapper.realClass(reader.getAttribute(mapper.attributeForEnumType())); - 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)); + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + final String attributeName = mapper.aliasForSystemAttribute("enum-type"); + if (attributeName == null) { + throw new ConversionException("No EnumType specified for EnumSet"); + } + @SuppressWarnings("rawtypes") + final Class enumTypeForSet = mapper.realClass(reader.getAttribute(attributeName)); + @SuppressWarnings("unchecked") + final EnumSet set = create(enumTypeForSet, reader.getValue()); + return set; + } + + private > EnumSet create(final Class type, final String s) { + final String[] enumValues = s.split(","); + final EnumSet set = EnumSet.noneOf(type); + for (final String enumValue : enumValues) { + if (enumValue.length() > 0) { + final T value = Enum.valueOf(type, enumValue); + set.add(value); } } return set; Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/enums/EnumSingleValueConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/enums/EnumToStringConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/CharsetConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ColorConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ColorConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ColorConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ColorConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,54 +1,67 @@ +/* + * Copyright (C) 2003, 2004, 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 01. October 2003 by Joe Walnes + */ package com.thoughtworks.xstream.converters.extended; +import java.awt.Color; +import java.util.HashMap; +import java.util.Map; + 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.*; -import java.util.HashMap; -import java.util.Map; /** - * Converts a java.awt.Color to XML, using four nested elements: - * red, green, blue, alpha. - * + * Converts an AWT {@link Color}, using four nested elements: red, green, blue, alpha. + * * @author Joe Walnes */ public class ColorConverter implements Converter { - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final 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; + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final 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(); + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + final 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()); + return new Color(elements.get("red").intValue(), elements.get("green").intValue(), elements + .get("blue") + .intValue(), elements.get("alpha").intValue()); } - private void write(String fieldName, int value, HierarchicalStreamWriter writer) { - writer.startNode(fieldName); + private void write(final String fieldName, final int value, final HierarchicalStreamWriter writer) { + ExtendedHierarchicalStreamWriterHelper.startNode(writer, fieldName, int.class); writer.setValue(String.valueOf(value)); writer.endNode(); } - } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/CurrencyConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/CurrencyConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/CurrencyConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/CurrencyConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,25 +1,40 @@ +/* + * 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 24. July 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.extended; -import com.thoughtworks.xstream.converters.basic.AbstractBasicConverter; - -import java.sql.Date; 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 + * Converts a {@link Currency} to a 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 AbstractBasicConverter { +public class CurrencyConverter extends AbstractSingleValueConverter { - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.equals(Currency.class); } - protected Object fromString(String str) { + @Override + public Object fromString(final String str) { return Currency.getInstance(str); } - } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/DurationConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/DynamicProxyConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/DynamicProxyConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/DynamicProxyConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/DynamicProxyConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,81 +1,142 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * 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 25. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.extended; +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 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.InvocationHandler; -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. - * + * Converts a dynamic proxy to XML, storing the implemented interfaces and handler. + * * @author Joe Walnes */ public class DynamicProxyConverter implements Converter { - private ClassLoader classLoader; - private Mapper mapper; + private final ClassLoaderReference classLoaderReference; + private final Mapper mapper; + private static final Field HANDLER = Fields.locate(Proxy.class, InvocationHandler.class, false); + private static final InvocationHandler DUMMY = new InvocationHandler() { + @Override + public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { + return null; + } + }; - public DynamicProxyConverter(Mapper mapper) { + /** + * @deprecated As of 1.4.5 use {@link #DynamicProxyConverter(Mapper, ClassLoaderReference)} + */ + @Deprecated + public DynamicProxyConverter(final Mapper mapper) { this(mapper, DynamicProxyConverter.class.getClassLoader()); } - public DynamicProxyConverter(Mapper mapper, ClassLoader classLoader) { - this.classLoader = classLoader; + /** + * 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(final Mapper mapper, final ClassLoaderReference classLoaderReference) { + this.classLoaderReference = classLoaderReference; this.mapper = mapper; } - public boolean canConvert(Class type) { + /** + * @deprecated As of 1.4.5 use {@link #DynamicProxyConverter(Mapper, ClassLoaderReference)} + */ + @Deprecated + public DynamicProxyConverter(final Mapper mapper, final ClassLoader classLoader) { + this(mapper, new ClassLoaderReference(classLoader)); + } + + @Override + public boolean canConvert(final 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); + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final InvocationHandler invocationHandler = Proxy.getInvocationHandler(source); addInterfacesToXml(source, writer); writer.startNode("handler"); - writer.addAttribute("class", mapper.serializedClass(invocationHandler.getClass())); + final 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]; + private void addInterfacesToXml(final Object source, final HierarchicalStreamWriter writer) { + final Class[] interfaces = source.getClass().getInterfaces(); + for (final Class currentInterface : interfaces) { writer.startNode("interface"); writer.setValue(mapper.serializedClass(currentInterface)); writer.endNode(); } } - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - List interfaces = new ArrayList(); + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + final List> interfaces = new ArrayList>(); InvocationHandler handler = null; + Class handlerType = null; while (reader.hasMoreChildren()) { reader.moveDown(); - String elementName = reader.getNodeName(); + final String elementName = reader.getNodeName(); if (elementName.equals("interface")) { interfaces.add(mapper.realClass(reader.getValue())); } else if (elementName.equals("handler")) { - Class handlerType = mapper.realClass(reader.getAttribute("class")); - handler = (InvocationHandler) context.convertAnother(null, handlerType); + final String attributeName = mapper.aliasForSystemAttribute("class"); + if (attributeName != null) { + handlerType = mapper.realClass(reader.getAttribute(attributeName)); + break; + } } reader.moveUp(); } - if (handler == null) { + if (handlerType == null) { throw new ConversionException("No InvocationHandler specified for dynamic proxy"); } - Class[] interfacesAsArray = new Class[interfaces.size()]; + final Class[] interfacesAsArray = new Class[interfaces.size()]; interfaces.toArray(interfacesAsArray); - return Proxy.newProxyInstance(classLoader, interfacesAsArray, handler); + 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; } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/EncodedByteArrayConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/EncodedByteArrayConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/EncodedByteArrayConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/EncodedByteArrayConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,63 +1,87 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 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 03. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.extended; +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.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 { +public class EncodedByteArrayConverter implements Converter, SingleValueConverter { - private final Base64Encoder base64 = new Base64Encoder(); - private final ByteConverter byteConverter = new ByteConverter(); + private static final Base64Encoder base64 = new Base64Encoder(); + private static final ByteConverter byteConverter = new ByteConverter(); - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.isArray() && type.getComponentType().equals(byte.class); } - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - writer.setValue(base64.encode((byte[]) source)); + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + writer.setValue(toString(source)); } - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - String data = reader.getValue(); // needs to be called before hasMoreChildren. + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + final String data = reader.getValue(); // needs to be called before hasMoreChildren. if (!reader.hasMoreChildren()) { - return base64.decode(data); + return fromString(data); } else { - // backwards compatability ... try to unmarshal byte arrays that haven't been encoded + // 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 + private Object unmarshalIndividualByteElements(final HierarchicalStreamReader reader, + final UnmarshallingContext context) { + // have to create a temporary list because we don't know the size of the array + final List bytes = new ArrayList(); boolean firstIteration = true; while (firstIteration || reader.hasMoreChildren()) { // hangover from previous hasMoreChildren reader.moveDown(); - bytes.add(byteConverter.unmarshal(reader, context)); + bytes.add((Byte)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++; + final byte[] result = new byte[bytes.size()]; + for (int i = 0; i < result.length; ++i) { + result[i] = bytes.get(i).byteValue(); } return result; } + @Override + public String toString(final Object obj) { + return base64.encode((byte[])obj); + } + + @Override + public Object fromString(final String str) { + return base64.decode(str); + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/FileConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/FileConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/FileConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/FileConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,27 +1,44 @@ +/* + * 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 13. January 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.extended; -import com.thoughtworks.xstream.converters.basic.AbstractBasicConverter; - import java.io.File; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; + + /** - * 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. - * + * Converts a {@link File}. + * + *

This converter will take care of storing and retrieving {@link File} with either an absolute path OR a relative path + * depending on how they were created.

+ * * @author Joe Walnes */ -public class FileConverter extends AbstractBasicConverter { +public class FileConverter extends AbstractSingleValueConverter { - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.equals(File.class); } - protected Object fromString(String str) { + @Override + public Object fromString(final String str) { return new File(str); } - protected String toString(Object obj) { - return ((File) obj).getPath(); + @Override + public String toString(final Object obj) { + return ((File)obj).getPath(); } -} \ No newline at end of file +} Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/FontConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/FontConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/FontConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/FontConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,36 +1,134 @@ +/* + * Copyright (C) 2004, 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 08. July 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.extended; +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; + +import javax.swing.plaf.FontUIResource; + 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.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.*; -import java.util.Map; +/** + * Converts an AWT {@link Font}. + */ public class FontConverter implements Converter { - public boolean canConvert(Class type) { + private final SingleValueConverter textAttributeConverter; + private final Mapper mapper; + + /** + * Constructs a FontConverter. + * + * @deprecated As of 1.4.5 + */ + @Deprecated + public FontConverter() { + this(null); + } + + /** + * Constructs a FontConverter. + * + * @param mapper + * @since 1.4.5 + */ + public FontConverter(final Mapper mapper) { + this.mapper = mapper; + if (mapper == null) { + textAttributeConverter = null; + } else { + textAttributeConverter = new TextAttributeConverter(); + } + } + + @Override + public boolean canConvert(final 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(); - writer.startNode("attributes"); // - context.convertAnother(attributes); - writer.endNode(); // + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final Font font = (Font)source; + final Map attributes = font.getAttributes(); + if (mapper != null) { + final String classAlias = mapper.aliasForSystemAttribute("class"); + for (final Map.Entry entry : attributes.entrySet()) { + final String name = textAttributeConverter.toString(entry.getKey()); + final Object value = entry.getValue(); + final 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) { - reader.moveDown(); // into - Map attributes = (Map) context.convertAnother(null, Map.class); - reader.moveUp(); // out of - Font font = Font.getFont(attributes); + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + final Map attributes; + if (reader.hasMoreChildren()) { + reader.moveDown(); + if (!reader.getNodeName().equals("attributes")) { + final String classAlias = mapper.aliasForSystemAttribute("class"); + attributes = new HashMap(); + do { + if (!attributes.isEmpty()) { + reader.moveDown(); + } + final Class type = mapper.realClass(reader.getAttribute(classAlias)); + final TextAttribute attribute = (TextAttribute)textAttributeConverter.fromString(reader.getNodeName()); + final Object value = type == Mapper.Null.class ? null : context.convertAnother(null, type); + attributes.put(attribute, value); + reader.moveUp(); + } while (reader.hasMoreChildren()); + } else { + // in + @SuppressWarnings("unchecked") + final Map typedAttributes = (Map)context.convertAnother( + null, Map.class); + attributes = typedAttributes; + reader.moveUp(); // out of + } + } else { + attributes = Collections.emptyMap(); + } + for (final Iterator iter = attributes.values().iterator(); iter.hasNext();) { + if (iter.next() == null) { + iter.remove(); + } + } + final Font font = Font.getFont(attributes); if (context.getRequiredType() == FontUIResource.class) { return new FontUIResource(font); } else { Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/GregorianCalendarConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/GregorianCalendarConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/GregorianCalendarConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/GregorianCalendarConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,42 +1,60 @@ +/* + * Copyright (C) 2004, 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 24. July 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.extended; -import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; 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; + /** - * 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. - * + * Converts a {@link GregorianCalendar}. + *

+ * 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) { + @Override + public boolean canConvert(final Class type) { return type.equals(GregorianCalendar.class); } - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - GregorianCalendar calendar = (GregorianCalendar) source; - writer.startNode("time"); - long timeInMillis = calendar.getTime().getTime(); // calendar.getTimeInMillis() not available under JDK 1.3 + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final GregorianCalendar calendar = (GregorianCalendar)source; + ExtendedHierarchicalStreamWriterHelper.startNode(writer, "time", long.class); + final long timeInMillis = calendar.getTimeInMillis(); writer.setValue(String.valueOf(timeInMillis)); writer.endNode(); - writer.startNode("timezone"); + ExtendedHierarchicalStreamWriterHelper.startNode(writer, "timezone", String.class); writer.setValue(calendar.getTimeZone().getID()); writer.endNode(); } - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { reader.moveDown(); - long timeInMillis = Long.parseLong(reader.getValue()); + final long timeInMillis = Long.parseLong(reader.getValue()); reader.moveUp(); final String timeZone; if (reader.hasMoreChildren()) { @@ -47,9 +65,9 @@ timeZone = TimeZone.getDefault().getID(); } - GregorianCalendar result = new GregorianCalendar(); + final GregorianCalendar result = new GregorianCalendar(); result.setTimeZone(TimeZone.getTimeZone(timeZone)); - result.setTime(new Date(timeInMillis)); // calendar.setTimeInMillis() not available under JDK 1.3 + result.setTimeInMillis(timeInMillis); return result; } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ISO8601DateConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ISO8601DateConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ISO8601DateConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ISO8601DateConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,29 +1,47 @@ +/* + * Copyright (C) 2004, 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 22. November 2004 by Mauro Talevi + */ package com.thoughtworks.xstream.converters.extended; import java.util.Calendar; import java.util.Date; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; + /** - * A DateConverter conforming to the ISO8601 standard. - * http://www.iso.ch/iso/en/CatalogueDetailPage.CatalogueDetail?CSNUMBER=26780 + * A converter for {@link Date} conforming to the ISO8601 standard. * + * @see ISO 8601 * @author Mauro Talevi * @author Jörg Schaible */ -public class ISO8601DateConverter extends ISO8601GregorianCalendarConverter { +public class ISO8601DateConverter extends AbstractSingleValueConverter { - public boolean canConvert(Class type) { + private final ISO8601GregorianCalendarConverter converter = new ISO8601GregorianCalendarConverter(); + + @Override + public boolean canConvert(final Class type) { return type.equals(Date.class); } - protected Object fromString(String str) { - return ((Calendar)super.fromString(str)).getTime(); + @Override + public Object fromString(final String str) { + return ((Calendar)converter.fromString(str)).getTime(); } - protected String toString(Object obj) { - Calendar calendar = Calendar.getInstance(); + @Override + public String toString(final Object obj) { + final Calendar calendar = Calendar.getInstance(); calendar.setTime((Date)obj); - return super.toString(calendar); + return converter.toString(calendar); } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ISO8601GregorianCalendarConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,104 +1,123 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 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 03. October 2005 by Joerg Schaible + */ package com.thoughtworks.xstream.converters.extended; -import com.thoughtworks.xstream.converters.ConversionException; -import com.thoughtworks.xstream.converters.basic.AbstractBasicConverter; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.TimeZone; 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.Locale; -import java.util.TimeZone; +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; /** - * A GregorianCalendarConverter conforming to the ISO8601 standard. - * http://www.iso.ch/iso/en/CatalogueDetailPage.CatalogueDetail?CSNUMBER=26780 + * A converter for {@link GregorianCalendar} 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 AbstractBasicConverter { - 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 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) { + @Override + public boolean canConvert(final Class type) { return type.equals(GregorianCalendar.class); } - protected Object fromString(String str) { - for (int i = 0; i < formattersUTC.length; i++) { - DateTimeFormatter formatter = formattersUTC[i]; + @Override + public Object fromString(final String str) { + for (final DateTimeFormatter formatter : formattersUTC) { try { - DateTime dt = formatter.parseDateTime(str); - Calendar calendar = dt.toCalendar(Locale.getDefault()); + final DateTime dt = formatter.parseDateTime(str); + final Calendar calendar = dt.toGregorianCalendar(); calendar.setTimeZone(TimeZone.getDefault()); return calendar; - } catch (IllegalArgumentException e) { + } catch (final IllegalArgumentException e) { // try with next formatter } } - String timeZoneID = TimeZone.getDefault().getID(); - for (int i = 0; i < formattersNoUTC.length; i++) { + final String timeZoneID = TimeZone.getDefault().getID(); + for (final DateTimeFormatter element : formattersNoUTC) { try { - DateTimeFormatter formatter = formattersNoUTC[i].withZone(DateTimeZone.forID(timeZoneID)); - DateTime dt = formatter.parseDateTime(str); - Calendar calendar = dt.toCalendar(Locale.getDefault()); + final DateTimeFormatter formatter = element.withZone(DateTimeZone.forID(timeZoneID)); + final DateTime dt = formatter.parseDateTime(str); + final Calendar calendar = dt.toGregorianCalendar(); calendar.setTimeZone(TimeZone.getDefault()); return calendar; - } catch (IllegalArgumentException e) { + } catch (final IllegalArgumentException e) { // try with next formatter } } throw new ConversionException("Cannot parse date " + str); } - protected String toString(Object obj) { - DateTime dt = new DateTime(obj); + @Override + public String toString(final Object obj) { + final DateTime dt = new DateTime(obj); return dt.toString(formattersUTC[0]); } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ISO8601SqlTimestampConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ISO8601SqlTimestampConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ISO8601SqlTimestampConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ISO8601SqlTimestampConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,31 +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 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 + * A converter for {@link Timestamp} conforming to the ISO8601 standard. * + * @see ISO 8601 * @author Jörg Schaible - * @since 1.2 + * @since 1.1.3 */ public class ISO8601SqlTimestampConverter extends ISO8601DateConverter { - final static String PADDING = "000000000"; + private final static String PADDING = "000000000"; - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.equals(Timestamp.class); } - protected Object fromString(String str) { + @Override + 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) + 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); } @@ -35,15 +49,16 @@ return timestamp; } - protected String toString(Object obj) { + @Override + public String toString(final Object obj) { final Timestamp timestamp = (Timestamp)obj; - String str = super.toString(new Date((timestamp.getTime() / 1000) * 1000)); + 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); + + PADDING.substring(nanos.length()) + + nanos + + str.substring(idxFraction + 4); return str; } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/JavaClassConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/JavaClassConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/JavaClassConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/JavaClassConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,54 +1,81 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 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 04. April 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.extended; import com.thoughtworks.xstream.converters.ConversionException; -import com.thoughtworks.xstream.converters.basic.AbstractBasicConverter; +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. + * Converts a {@link Class} to a string. * * @author Aslak Hellesøy * @author Joe Walnes * @author Matthew Sandoz + * @author Jörg Schaible */ -public class JavaClassConverter extends AbstractBasicConverter { +public class JavaClassConverter extends AbstractSingleValueConverter { - private ClassLoader classLoader; + private final Mapper mapper; /** - * @deprecated As of 1.1.1 - use other constructor and explicitly supply a ClassLoader. + * Construct a JavaClassConverter. + * + * @param classLoaderReference the reference to the {@link ClassLoader} of the XStream instance + * @since 1.4.5 */ - public JavaClassConverter() { - this(Thread.currentThread().getContextClassLoader()); + public JavaClassConverter(final ClassLoaderReference classLoaderReference) { + this(new DefaultMapper(classLoaderReference)); } - public JavaClassConverter(ClassLoader classLoader) { - this.classLoader = classLoader; + /** + * @deprecated As of 1.4.5 use {@link #JavaClassConverter(ClassLoaderReference)} + */ + @Deprecated + public JavaClassConverter(final ClassLoader classLoader) { + this(new ClassLoaderReference(classLoader)); } - public boolean canConvert(Class clazz) { + /** + * 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(final Mapper mapper) { + this.mapper = mapper; + } + + @Override + public boolean canConvert(final Class clazz) { return Class.class.equals(clazz); // :) } - protected String toString(Object obj) { - return ((Class) obj).getName(); + @Override + public String toString(final Object obj) { + return mapper.serializedClass((Class)obj); } - protected Object fromString(String str) { + @Override + public Object fromString(final String str) { try { - return - str.equals("void") ? void.class : - str.equals("byte") ? byte.class : - str.equals("int") ? int.class : - str.equals("long") ? long.class : - str.equals("float") ? float.class : - str.equals("boolean") ? boolean.class : - str.equals("double") ? double.class : - str.equals("char") ? char.class : - str.equals("short") ? short.class : - Class.forName(str, false, classLoader); - } catch (ClassNotFoundException e) { - throw new ConversionException("Cannot load java class " + str, e); + return mapper.realClass(str); + } catch (final CannotResolveClassException e) { + throw new ConversionException("Cannot load java class " + str, e.getCause()); } } - } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/JavaFieldConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/JavaMethodConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/JavaMethodConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/JavaMethodConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/JavaMethodConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,51 +1,93 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 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 04. April 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.extended; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import com.thoughtworks.xstream.InitializationException; 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. - * + * Converts a {@link Method}. + * * @author Aslak Hellesøy + * @author Jörg Schaible */ public class JavaMethodConverter implements Converter { - private final ClassLoader classLoader; + private final SingleValueConverter javaClassConverter; - public JavaMethodConverter() { - this(JavaMethodConverter.class.getClassLoader()); + /** + * Construct a JavaMethodConverter. + * + * @param classLoaderReference the reference to the {@link ClassLoader} of the XStream instance + * @since 1.4.5 + */ + public JavaMethodConverter(final ClassLoaderReference classLoaderReference) { + this(new JavaClassConverter(classLoaderReference)); } - public JavaMethodConverter(ClassLoader classLoader) { - this.classLoader = classLoader; + /** + * @deprecated As of 1.4.5 use {@link #JavaMethodConverter(ClassLoaderReference)} + */ + @Deprecated + public JavaMethodConverter(final ClassLoader classLoader) { + this(new ClassLoaderReference(classLoader)); } - public boolean canConvert(Class type) { + /** + * Construct a JavaMethodConverter. + * + * @param javaClassConverter the converter to use + * @since 1.4.5 + */ + protected JavaMethodConverter(final SingleValueConverter javaClassConverter) { + if (!javaClassConverter.canConvert(Class.class)) { + throw new InitializationException("Java Class Converter cannot handle Class types"); + } + this.javaClassConverter = javaClassConverter; + } + + @Override + public boolean canConvert(final Class type) { return type.equals(Method.class) || type.equals(Constructor.class); } - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { if (source instanceof Method) { - Method method = (Method) source; - String declaringClassName = method.getDeclaringClass().getName(); + final Method method = (Method)source; + final String declaringClassName = javaClassConverter.toString(method.getDeclaringClass()); marshalMethod(writer, declaringClassName, method.getName(), method.getParameterTypes()); } else { - Constructor method = (Constructor) source; - String declaringClassName = method.getDeclaringClass().getName(); + final Constructor method = (Constructor)source; + final String declaringClassName = javaClassConverter.toString(method.getDeclaringClass()); marshalMethod(writer, declaringClassName, null, method.getParameterTypes()); } } - private void marshalMethod(HierarchicalStreamWriter writer, String declaringClassName, String methodName, Class[] parameterTypes) { + private void marshalMethod(final HierarchicalStreamWriter writer, final String declaringClassName, + final String methodName, final Class[] parameterTypes) { writer.startNode("class"); writer.setValue(declaringClassName); @@ -59,22 +101,22 @@ } writer.startNode("parameter-types"); - for (int i = 0; i < parameterTypes.length; i++) { - Class parameterType = parameterTypes[i]; + for (final Class parameterType : parameterTypes) { writer.startNode("class"); - writer.setValue(parameterType.getName()); + writer.setValue(javaClassConverter.toString(parameterType)); writer.endNode(); } writer.endNode(); } - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { try { - boolean isMethodNotConstructor = context.getRequiredType().equals(Method.class); + final boolean isMethodNotConstructor = context.getRequiredType().equals(Method.class); reader.moveDown(); - String declaringClassName = reader.getValue(); - Class declaringClass = loadClass(declaringClassName); + final String declaringClassName = reader.getValue(); + final Class declaringClass = (Class)javaClassConverter.fromString(declaringClassName); reader.moveUp(); String methodName = null; @@ -85,49 +127,23 @@ } reader.moveDown(); - List parameterTypeList = new ArrayList(); + final List> parameterTypeList = new ArrayList>(); while (reader.hasMoreChildren()) { reader.moveDown(); - String parameterTypeName = reader.getValue(); - parameterTypeList.add(loadClass(parameterTypeName)); + final String parameterTypeName = reader.getValue(); + parameterTypeList.add((Class)javaClassConverter.fromString(parameterTypeName)); reader.moveUp(); } - Class[] parameterTypes = (Class[]) parameterTypeList.toArray(new Class[parameterTypeList.size()]); + final Class[] parameterTypes = parameterTypeList.toArray(new Class[parameterTypeList.size()]); reader.moveUp(); if (isMethodNotConstructor) { return declaringClass.getDeclaredMethod(methodName, parameterTypes); } else { return declaringClass.getDeclaredConstructor(parameterTypes); } - } catch (ClassNotFoundException e) { + } catch (final NoSuchMethodException e) { throw new ConversionException(e); - } catch (NoSuchMethodException e) { - throw new ConversionException(e); } } - - private Class loadClass(String className) throws ClassNotFoundException { - Class primitiveClass = primitiveClassForName(className); - if( primitiveClass != null ){ - return primitiveClass; - } - return classLoader.loadClass(className); - } - - /** - * Lookup table for primitive types. - */ - private Class primitiveClassForName(String name) { - return name.equals("void") ? Void.TYPE : - name.equals("boolean") ? Boolean.TYPE : - name.equals("byte") ? Byte.TYPE : - name.equals("char") ? Character.TYPE : - name.equals("short") ? Short.TYPE : - name.equals("int") ? Integer.TYPE : - name.equals("long") ? Long.TYPE : - name.equals("float") ? Float.TYPE : - name.equals("double") ? Double.TYPE : - null; - } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/LocaleConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/LocaleConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/LocaleConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/LocaleConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,23 +1,37 @@ +/* + * 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 24. July 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.extended; -import com.thoughtworks.xstream.converters.basic.AbstractBasicConverter; - import java.util.Locale; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; + + /** - * Converts a java.util.Locale to a string. - * + * Converts a {@link Locale} to a string. + * * @author Jose A. Illescas * @author Joe Walnes */ -public class LocaleConverter extends AbstractBasicConverter { +public class LocaleConverter extends AbstractSingleValueConverter { - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.equals(Locale.class); } - protected Object fromString(String str) { - int[] underscorePositions = underscorePositions(str); + @Override + public Object fromString(final String str) { + final int[] underscorePositions = underscorePositions(str); String language, country, variant; if (underscorePositions[0] == -1) { // "language" language = str; @@ -35,13 +49,13 @@ return new Locale(language, country, variant); } - private int[] underscorePositions(String in) { - int[] result = new int[2]; + private int[] underscorePositions(final String in) { + final int[] result = new int[2]; for (int i = 0; i < result.length; i++) { - int last = i == 0 ? 0 : result[i - 1]; + final int last = i == 0 ? 0 : result[i - 1]; result[i] = in.indexOf('_', last + 1); } return result; } -} \ No newline at end of file +} Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/LookAndFeelConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/NamedArrayConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/NamedCollectionConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/NamedMapConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/PropertyEditorCapableConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/RegexPatternConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/RegexPatternConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/RegexPatternConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/RegexPatternConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,35 +1,74 @@ +/* + * Copyright (C) 2004, 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 31. July 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.extended; +import java.util.regex.Pattern; + 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; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; -import java.util.regex.Pattern; /** - * Ensures java.util.regex.Pattern is compiled upon deserialization. + * Converts a {@link Pattern} using two nested elements for the pattern itself and its flags. + *

+ * Ensures that the pattern is compiled upon deserialization. + *

+ * + * @author Joe Walnes + * @author Jörg Schaible */ public class RegexPatternConverter implements Converter { - private Converter defaultConverter; + /** + * @since 1.4.5 + */ + public RegexPatternConverter() { + } - public RegexPatternConverter(Converter defaultConverter) { - this.defaultConverter = defaultConverter; + /** + * @deprecated As of 1.4.5, use {@link #RegexPatternConverter()} instead + */ + @Deprecated + public RegexPatternConverter(final Converter defaultConverter) { } - public boolean canConvert(final Class type) { + @Override + public boolean canConvert(final Class type) { return type.equals(Pattern.class); } - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - defaultConverter.marshal(source, writer, context); + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final 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) { - Pattern notCompiled = (Pattern) defaultConverter.unmarshal(reader, context); - return Pattern.compile(notCompiled.pattern(), notCompiled.flags()); + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + reader.moveDown(); + final String pattern = reader.getValue(); + reader.moveUp(); + reader.moveDown(); + final int flags = Integer.parseInt(reader.getValue()); + reader.moveUp(); + return Pattern.compile(pattern, flags); } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/SqlDateConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/SqlDateConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/SqlDateConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/SqlDateConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,22 +1,35 @@ +/* + * 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 24. July 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.extended; -import com.thoughtworks.xstream.converters.basic.AbstractBasicConverter; - import java.sql.Date; -import java.sql.Time; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; + + /** - * Converts a java.sql.Date to text. - * - * @author Jose A. Illescas + * Converts a {@link Date} to a string. + * + * @author Jose A. Illescas */ -public class SqlDateConverter extends AbstractBasicConverter { +public class SqlDateConverter extends AbstractSingleValueConverter { - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.equals(Date.class); } - protected Object fromString(String str) { + @Override + public Object fromString(final String str) { return Date.valueOf(str); } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/SqlTimeConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/SqlTimeConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/SqlTimeConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/SqlTimeConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,21 +1,38 @@ +/* + * 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 24. July 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.extended; -import com.thoughtworks.xstream.converters.basic.AbstractBasicConverter; - import java.sql.Time; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; + + /** - * Converts a java.sql.Time to text. Warning: Any granularity smaller than seconds is lost. - * + * Converts a {@link Time} to a string. + *

+ * Warning: Any granularity smaller than seconds is lost. + *

+ * * @author Jose A. Illescas */ -public class SqlTimeConverter extends AbstractBasicConverter { +public class SqlTimeConverter extends AbstractSingleValueConverter { - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.equals(Time.class); } - protected Object fromString(String str) { + @Override + public Object fromString(final String str) { return Time.valueOf(str); } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/SqlTimestampConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/SqlTimestampConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/SqlTimestampConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/SqlTimestampConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,22 +1,77 @@ +/* + * 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.basic.AbstractBasicConverter; - import java.sql.Timestamp; +import java.text.ParseException; +import java.util.TimeZone; +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; +import com.thoughtworks.xstream.core.util.ThreadSafeSimpleDateFormat; + + /** - * Converts a java.sql.Timestamp to text. - * + * Converts a {@link Timestamp} to a string. + * * @author Joe Walnes + * @author Jörg Schaible */ -public class SqlTimestampConverter extends AbstractBasicConverter { +public class SqlTimestampConverter extends AbstractSingleValueConverter { - public boolean canConvert(Class type) { + private final ThreadSafeSimpleDateFormat format = new ThreadSafeSimpleDateFormat("yyyy-MM-dd HH:mm:ss", TimeZone + .getTimeZone("UTC"), 0, 5, false); + + @Override + public boolean canConvert(final Class type) { return type.equals(Timestamp.class); } - protected Object fromString(String str) { - return Timestamp.valueOf(str); + @Override + public String toString(final Object obj) { + final Timestamp timestamp = (Timestamp)obj; + final StringBuilder buffer = new StringBuilder(format.format(timestamp)).append('.'); + if (timestamp.getNanos() == 0) { + buffer.append('0'); + } else { + final 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(); } + @Override + public Object fromString(final String str) { + final 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 { + final Timestamp timestamp = new Timestamp(format.parse(str.substring(0, idx)).getTime()); + final StringBuilder buffer = new StringBuilder(str.substring(idx + 1)); + while (buffer.length() != 9) { + buffer.append('0'); + } + timestamp.setNanos(Integer.parseInt(buffer.toString())); + return timestamp; + } catch (final NumberFormatException e) { + throw new ConversionException("Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]", e); + } catch (final ParseException e) { + throw new ConversionException("Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]"); + } + } + } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/StackTraceElementConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/StackTraceElementConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/StackTraceElementConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/StackTraceElementConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,52 +1,70 @@ +/* + * 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 29. May 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.extended; -import com.thoughtworks.xstream.converters.MarshallingContext; -import com.thoughtworks.xstream.converters.ConversionException; -import com.thoughtworks.xstream.converters.basic.AbstractBasicConverter; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; - -import java.lang.reflect.Field; import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; + + /** - * Converter for StackTraceElement (the lines of a stack trace) - JDK 1.4+ only. - * + * Converter for {@link StackTraceElement} (the lines of a stack trace) to a string. + * * @author B. K. Oxley (binkley) * @author Joe Walnes */ -public class StackTraceElementConverter extends AbstractBasicConverter { +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| + // 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 = new StackTraceElementFactory(); - private final StackTraceElementFactory factory = new StackTraceElementFactory(); - - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return StackTraceElement.class.equals(type); } - protected Object fromString(String str) { - Matcher matcher = PATTERN.matcher(str); + @Override + public String toString(final Object obj) { + final String s = super.toString(obj); + // JRockit adds ":???" for invalid line number + return s.replaceFirst(":\\?\\?\\?", ""); + } + + @Override + public Object fromString(final String str) { + final Matcher matcher = PATTERN.matcher(str); if (matcher.matches()) { - String declaringClass = matcher.group(1); - String methodName = matcher.group(2); - String fileName = matcher.group(3); + final String declaringClass = matcher.group(1); + final String methodName = matcher.group(2); + final String fileName = matcher.group(3); if (fileName.equals("Unknown Source")) { - return factory.unknownSourceElement(declaringClass, methodName); + return FACTORY.unknownSourceElement(declaringClass, methodName); } else if (fileName.equals("Native Method")) { - return factory.nativeMethodElement(declaringClass, methodName); + 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); + final int lineNumber = Integer.parseInt(matcher.group(5)); + return FACTORY.element(declaringClass, methodName, fileName, lineNumber); } else { - return factory.element(declaringClass, methodName, fileName); + return FACTORY.element(declaringClass, methodName, fileName); } } } else { Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/StackTraceElementFactory.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/StackTraceElementFactory.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/StackTraceElementFactory.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/StackTraceElementFactory.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,16 +1,24 @@ +/* + * 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 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 upcoming, it is an internal helper class */ +@Deprecated public class StackTraceElementFactory { public StackTraceElement nativeMethodElement(String declaringClass, String methodName) { @@ -30,22 +38,6 @@ } private 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; + return new StackTraceElement(declaringClass, methodName, fileName, lineNumber); } - - 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); - } - } - } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/SubjectConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/SubjectConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/SubjectConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/SubjectConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,100 +1,123 @@ +/* + * 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.xstream.converters.extended; +import java.security.Principal; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import javax.security.auth.Subject; + 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}. - * + * 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 behavior 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) { + public SubjectConverter(final Mapper mapper) { super(mapper); } - public boolean canConvert(Class type) { + @Override + public boolean canConvert(final Class type) { return type.equals(Subject.class); } - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - Subject subject = (Subject) source; + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final 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) { + + protected void marshalPrincipals(final Set principals, final HierarchicalStreamWriter writer, + final 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 + for (final Principal principal : principals) { writeItem(principal, context, writer); } writer.endNode(); }; - - protected void marshalPublicCredentials(Set pubCredentials, HierarchicalStreamWriter writer, MarshallingContext context) { + + protected void marshalPublicCredentials(final Set pubCredentials, final HierarchicalStreamWriter writer, + final MarshallingContext context) { }; - protected void marshalPrivateCredentials(Set privCredentials, HierarchicalStreamWriter writer, MarshallingContext context) { + protected void marshalPrivateCredentials(final Set privCredentials, final HierarchicalStreamWriter writer, + final MarshallingContext context) { }; - - protected void marshalReadOnly(boolean readOnly, HierarchicalStreamWriter writer) { + + protected void marshalReadOnly(final boolean readOnly, final 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); + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + final Set principals = unmarshalPrincipals(reader, context); + final Set publicCredentials = unmarshalPublicCredentials(reader, context); + final Set privateCredentials = unmarshalPrivateCredentials(reader, context); + final boolean readOnly = unmarshalReadOnly(reader); return new Subject(readOnly, principals, publicCredentials, privateCredentials); } - - protected Set unmarshalPrincipals(HierarchicalStreamReader reader, UnmarshallingContext context) { + + protected Set unmarshalPrincipals(final HierarchicalStreamReader reader, + final UnmarshallingContext context) { return populateSet(reader, context); }; - - protected Set unmarshalPublicCredentials(HierarchicalStreamReader reader, UnmarshallingContext context) { - return Collections.EMPTY_SET; + + protected Set unmarshalPublicCredentials(final HierarchicalStreamReader reader, + final UnmarshallingContext context) { + return Collections.emptySet(); }; - protected Set unmarshalPrivateCredentials(HierarchicalStreamReader reader, UnmarshallingContext context) { - return Collections.EMPTY_SET; + protected Set unmarshalPrivateCredentials(final HierarchicalStreamReader reader, + final UnmarshallingContext context) { + return Collections.emptySet(); }; - protected boolean unmarshalReadOnly(HierarchicalStreamReader reader) { + protected boolean unmarshalReadOnly(final HierarchicalStreamReader reader) { reader.moveDown(); - boolean readOnly = Boolean.getBoolean(reader.getValue()); + final boolean readOnly = Boolean.getBoolean(reader.getValue()); reader.moveUp(); return readOnly; }; - protected Set populateSet(HierarchicalStreamReader reader, UnmarshallingContext context) { - Set set = new HashSet(); + protected Set populateSet(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + final Set set = new HashSet(); reader.moveDown(); while (reader.hasMoreChildren()) { reader.moveDown(); - Object elementl = readItem(reader, context, set); + final Principal principal = (Principal)readItem(reader, context, set); reader.moveUp(); - set.add(elementl); + set.add(principal); } reader.moveUp(); return set; Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/TextAttributeConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ThrowableConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ThrowableConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ThrowableConverter.java 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ThrowableConverter.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,40 +1,78 @@ +/* + * 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 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; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.List; /** - * Converter for Throwable (and Exception) that retains stack trace, for JDK1.4 only. - * + * Converter for {@link Throwable} (and {@link 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; - public ThrowableConverter(Converter defaultConverter) { + /** + * @deprecated As of 1.4.5 use {@link #ThrowableConverter(ConverterLookup)} + */ + @Deprecated + public ThrowableConverter(final Converter defaultConverter) { this.defaultConverter = defaultConverter; + lookup = null; } - public boolean canConvert(final Class type) { + /** + * @since 1.4.5 + */ + public ThrowableConverter(final ConverterLookup lookup) { + this.lookup = lookup; + } + + @Override + public boolean canConvert(final Class type) { return Throwable.class.isAssignableFrom(type); } - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - Throwable throwable = (Throwable) source; - throwable.getStackTrace(); // Force stackTrace field to be lazy loaded by special JVM native witchcraft (outside our control). - defaultConverter.marshal(throwable, writer, context); + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final Throwable throwable = (Throwable)source; + if (throwable.getCause() == null) { + try { + throwable.initCause(null); + } catch (final IllegalStateException e) { + // ignore, initCause failed, cause was already set + } + } + // force stackTrace field to be lazy loaded by special JVM native witchcraft (outside our control). + throwable.getStackTrace(); + getConverter().marshal(throwable, writer, context); } - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - return defaultConverter.unmarshal(reader, context); + private Converter getConverter() { + return defaultConverter != null ? defaultConverter : lookup.lookupConverterForType(Object.class); } + + @Override + public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { + return getConverter().unmarshal(reader, context); + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ToAttributedValueConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/ToStringConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/UseAttributeForEnumMapper.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/package.html,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/package.html 10 Sep 2012 19:03:04 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/extended/package.html 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,2 +1,14 @@ -

Extra converters that are not enabled in XStream -by default.

\ No newline at end of file + + +

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

+ Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/BeanProperty.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/BeanProperty.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/BeanProperty.java 10 Sep 2012 19:03:06 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/BeanProperty.java 10 Nov 2014 12:07:41 -0000 1.1.2.1 @@ -1,56 +1,65 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 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 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 */ +@Deprecated public class BeanProperty { /** the target class */ - private Class memberClass; + private final Class memberClass; /** the property name */ - private String propertyName; + private final String propertyName; /** the property type */ - private Class type; + private final 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. + * Creates a new {@link BeanProperty}that gets the specified property from the specified class. */ - public BeanProperty(Class memberClass, String propertyName, Class propertyType) { + public BeanProperty(final Class memberClass, final String propertyName, final Class propertyType) { this.memberClass = memberClass; this.propertyName = propertyName; - this.type = propertyType; + type = propertyType; } /** * Gets the base class that this getter accesses. */ - public Class getBeanClass() { + public Class getBeanClass() { return memberClass; } /** * Returns the property type - * - * @return */ - public Class getType() { + public Class getType() { return type; } @@ -65,62 +74,65 @@ * Gets whether this property can get get. */ public boolean isReadable() { - return (getter != null); + return getter != null; } /** * Gets whether this property can be set. */ public boolean isWritable() { - return (setter != null); + 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"); + public Object get(final 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) { + return getter.invoke(member); + } catch (final 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"); + public Object set(final Object member, final 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) { + return setter.invoke(member, newValue); + } catch (final InvocationTargetException e) { throw new UndeclaredThrowableException(e.getTargetException()); } } /** * @param method */ - public void setGetterMethod(Method method) { - this.getter = method; + public void setGetterMethod(final Method method) { + getter = method; } /** * @param method */ - public void setSetterMethod(Method method) { - this.setter = method; + public void setSetterMethod(final Method method) { + setter = method; } -} \ No newline at end of file +} Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/BeanProvider.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/BeanProvider.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/BeanProvider.java 10 Sep 2012 19:03:06 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/BeanProvider.java 10 Nov 2014 12:07:41 -0000 1.1.2.1 @@ -1,143 +1,192 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 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 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; -/** - * 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. - *

- */ -public class BeanProvider { -// private final Map serializedDataCache = Collections.synchronizedMap(new HashMap()); -// - protected PropertyDictionary propertyDictionary = new PropertyDictionary(); - +public class BeanProvider implements JavaBeanProvider { + + /** + * @deprecated As of 1.4.6 + */ + @Deprecated protected static final Object[] NO_PARAMS = new Object[0]; + protected PropertyDictionary propertyDictionary; - public Object newInstance(Class type) { + /** + * 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; + } + + @Override + public Object newInstance(final Class type) { try { - return getDefaultConstrutor(type).newInstance(NO_PARAMS); - } catch (InstantiationException e) { + return type.newInstance(); + } catch (final InstantiationException e) { throw new ObjectAccessException("Cannot construct " + type.getName(), e); - } catch (IllegalAccessException e) { + } catch (final 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); - } + } 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 Object instantiateUsingSerialization(Class type) { -// try { -// byte[] data; -// if (serializedDataCache.containsKey(type)) { -// data = (byte[]) serializedDataCache.get(type); -// } else { -// 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)); -// return in.readObject(); -// } catch (IOException e) { -// throw new ObjectAccessException("", e); -// } catch (ClassNotFoundException e) { -// throw new ObjectAccessException("", e); -// } -// } - - public void visitSerializableProperties(Object object, Visitor visitor) { - for (Iterator iterator = propertyDictionary.serializablePropertiesFor(object.getClass()); iterator - .hasNext();) { - BeanProperty property = (BeanProperty) iterator.next(); + @Override + public void visitSerializableProperties(final Object object, final JavaBeanProvider.Visitor visitor) { + final PropertyDescriptor[] propertyDescriptors = getSerializableProperties(object); + for (final PropertyDescriptor property : propertyDescriptors) { try { - Object value = property.get(object); - visitor.visit(property.getName(), property.getType(), value); - } catch (IllegalArgumentException e) { - throw new ObjectAccessException("Could not get property " + property.getClass() - + "." + property.getName(), e); - } catch (IllegalAccessException e) { - throw new ObjectAccessException("Could not get property " + property.getClass() - + "." + property.getName(), e); + final Method readMethod = property.getReadMethod(); + final String name = property.getName(); + final Class definedIn = readMethod.getDeclaringClass(); + if (visitor.shouldVisit(name, definedIn)) { + final Object value = readMethod.invoke(object); + visitor.visit(name, property.getPropertyType(), definedIn, value); + } + } catch (final IllegalArgumentException e) { + throw new ObjectAccessException("Could not get property " + + object.getClass() + + "." + + property.getName(), e); + } catch (final IllegalAccessException e) { + throw new ObjectAccessException("Could not get property " + + object.getClass() + + "." + + property.getName(), e); + } catch (final InvocationTargetException e) { + throw new ObjectAccessException("Could not get property " + + object.getClass() + + "." + + property.getName(), e); } } } - public void writeProperty(Object object, String propertyName, Object value) { - BeanProperty property = propertyDictionary.property(object.getClass(), propertyName); + @Override + public void writeProperty(final Object object, final String propertyName, final Object value) { + final PropertyDescriptor property = getProperty(propertyName, object.getClass()); try { - property.set(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); + property.getWriteMethod().invoke(object, new Object[]{value}); + } catch (final IllegalArgumentException e) { + throw new ObjectAccessException("Could not set property " + object.getClass() + "." + property.getName(), e); + } catch (final IllegalAccessException e) { + throw new ObjectAccessException("Could not set property " + object.getClass() + "." + property.getName(), e); + } catch (final InvocationTargetException e) { + throw new ObjectAccessException("Could not set property " + object.getClass() + "." + property.getName(), e); } } - public Class getPropertyType(Object object, String name) { - return propertyDictionary.property(object.getClass(), name).getType(); + @Override + public Class getPropertyType(final Object object, final String name) { + return getProperty(name, object.getClass()).getPropertyType(); } - public boolean propertyDefinedInClass(String name, Class type) { - return propertyDictionary.property(type, name) != null; + @Override + public boolean propertyDefinedInClass(final String name, final Class type) { + return getProperty(name, type) != null; } /** * Returns true if the Bean provider can instantiate the specified class */ - public boolean canInstantiate(Class type) { - return getDefaultConstrutor(type) != null; + @Override + public boolean canInstantiate(final Class type) { + try { + return newInstance(type) != null; + } catch (final ObjectAccessException e) { + return false; + } } - + /** * Returns the default constructor, or null if none is found + * * @param type - * @return + * @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())) + @Deprecated + protected Constructor getDefaultConstrutor(final Class type) { + + final Constructor[] constructors = type.getConstructors(); + for (final Constructor c : constructors) { + if (c.getParameterTypes().length == 0 && Modifier.isPublic(c.getModifiers())) { return c; + } } return null; } - - interface Visitor { - void visit(String name, Class type, Object value); + + protected PropertyDescriptor[] getSerializableProperties(final Object object) { + final List result = new ArrayList(); + for (final Iterator iter = propertyDictionary.propertiesFor(object.getClass()); iter + .hasNext();) { + final PropertyDescriptor descriptor = iter.next(); + if (canStreamProperty(descriptor)) { + result.add(descriptor); + } + } + return result.toArray(new PropertyDescriptor[result.size()]); } -} \ No newline at end of file + protected boolean canStreamProperty(final PropertyDescriptor descriptor) { + return descriptor.getReadMethod() != null && descriptor.getWriteMethod() != null; + } + + public boolean propertyWriteable(final String name, final Class type) { + final PropertyDescriptor property = getProperty(name, type); + return property.getWriteMethod() != null; + } + + protected PropertyDescriptor getProperty(final String name, final Class type) { + return propertyDictionary.propertyDescriptor(type, name); + } + + /** + * @deprecated As of 1.4 use {@link JavaBeanProvider.Visitor} + */ + @Deprecated + public interface Visitor extends JavaBeanProvider.Visitor {} +} Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/ComparingPropertySorter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/JavaBeanConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/JavaBeanConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/JavaBeanConverter.java 10 Sep 2012 19:03:06 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/JavaBeanConverter.java 10 Nov 2014 12:07:40 -0000 1.1.2.1 @@ -1,116 +1,167 @@ +/* + * Copyright (C) 2005 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 12. April 2005 by Joe Walnes + */ package com.thoughtworks.xstream.converters.javabean; -import com.thoughtworks.xstream.alias.ClassMapper; +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.ExtendedHierarchicalStreamWriterHelper; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + /** - * Can convert any bean with a public default constructor. BeanInfo are not - * taken into consideration, this class looks for bean patterns for simple - * properties + * 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: - * - use bean introspection instead of reflection. - * - support indexed properties - * - ignore default values - * - use BeanInfo - */ - private ClassMapper classMapper; + /* 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; - private String classAttributeIdentifier; + public JavaBeanConverter(final Mapper mapper) { + this(mapper, (Class)null); + } - private BeanProvider beanProvider; + public JavaBeanConverter(final Mapper mapper, final Class type) { + this(mapper, new BeanProvider(), type); + } - public JavaBeanConverter(ClassMapper classMapper, String classAttributeIdentifier) { - this.classMapper = classMapper; - this.classAttributeIdentifier = classAttributeIdentifier; - this.beanProvider = new BeanProvider(); + public JavaBeanConverter(final Mapper mapper, final JavaBeanProvider beanProvider) { + this(mapper, beanProvider, null); } + public JavaBeanConverter(final Mapper mapper, final JavaBeanProvider beanProvider, final Class type) { + this.mapper = mapper; + this.beanProvider = beanProvider; + this.type = type; + } + /** - * Only checks for the availability of a public default constructor. - * If you need stricter checks, subclass JavaBeanConverter + * Checks if the bean provider can instantiate this type. If you need less strict checks, subclass JavaBeanConverter */ - public boolean canConvert(Class type) { - return beanProvider.canInstantiate(type); + @Override + public boolean canConvert(final Class type) { + return (this.type == null || this.type == type) && beanProvider.canInstantiate(type); } + @Override public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final String classAttributeName = mapper.aliasForSystemAttribute("class"); + beanProvider.visitSerializableProperties(source, new JavaBeanProvider.Visitor() { + @Override + public boolean shouldVisit(final String name, final Class definedIn) { + return mapper.shouldSerializeMember(definedIn, name); + } - beanProvider.visitSerializableProperties(source, new BeanProvider.Visitor() { - public void visit(String propertyName, Class fieldType, Object newObj) { + @Override + public void visit(final String propertyName, final Class fieldType, final Class definedIn, + final Object newObj) { if (newObj != null) { - writeField(propertyName, fieldType, newObj); + writeField(propertyName, fieldType, newObj, definedIn); } } - private void writeField(String propertyName, Class fieldType, Object newObj) { - writer.startNode(classMapper.serializedMember(source.getClass(), propertyName)); - - Class actualType = newObj.getClass(); - - Class defaultType = classMapper.defaultImplementationOf(fieldType); - if (!actualType.equals(defaultType)) { - writer.addAttribute(classAttributeIdentifier, classMapper.serializedClass(actualType)); + private void writeField(final String propertyName, final Class fieldType, final Object newObj, + final Class definedIn) { + final Class actualType = newObj.getClass(); + final Class defaultType = mapper.defaultImplementationOf(fieldType); + final 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(); } - }); } + @Override public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { final Object result = instantiateNewInstance(context); + final Set seenProperties = new HashSet() { + @Override + public boolean add(final FastField e) { + if (!super.add(e)) { + throw new DuplicatePropertyException(e.getName()); + } + return true; + } + }; + final Class resultType = result.getClass(); while (reader.hasMoreChildren()) { reader.moveDown(); - String propertyName = classMapper.realMember(result.getClass(), reader.getNodeName()); + final String propertyName = mapper.realMember(resultType, reader.getNodeName()); - boolean propertyExistsInClass = beanProvider.propertyDefinedInClass(propertyName, result.getClass()); + if (mapper.shouldSerializeMember(resultType, propertyName)) { + final boolean propertyExistsInClass = beanProvider.propertyDefinedInClass(propertyName, resultType); - Class type = determineType(reader, result, propertyName); - Object value = context.convertAnother(result, type); - - if (propertyExistsInClass) { - beanProvider.writeProperty(result, propertyName, value); + if (propertyExistsInClass) { + final Class type = determineType(reader, result, propertyName); + final 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) { + private Object instantiateNewInstance(final 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) { - String classAttribute = reader.getAttribute(classAttributeIdentifier); + private Class determineType(final HierarchicalStreamReader reader, final Object result, final String fieldName) { + final String classAttributeName = mapper.aliasForSystemAttribute("class"); + final String classAttribute = classAttributeName == null ? null : reader.getAttribute(classAttributeName); if (classAttribute != null) { - return classMapper.realClass(classAttribute); + return mapper.realClass(classAttribute); } else { - return classMapper.defaultImplementationOf(beanProvider.getPropertyType(result, fieldName)); + return mapper.defaultImplementationOf(beanProvider.getPropertyType(result, fieldName)); } } - 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(final String msg) { + super("Duplicate property " + msg); + add("property", msg); } } -} \ No newline at end of file +} Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/JavaBeanProvider.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/NativePropertySorter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/PropertyDictionary.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/PropertyDictionary.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/PropertyDictionary.java 10 Sep 2012 19:03:06 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/PropertyDictionary.java 10 Nov 2014 12:07:41 -0000 1.1.2.1 @@ -1,199 +1,127 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 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 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.lang.reflect.Method; -import java.lang.reflect.Modifier; +import java.beans.PropertyDescriptor; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; -import java.util.List; +import java.util.LinkedHashMap; import java.util.Map; +import com.thoughtworks.xstream.converters.reflection.MissingFieldException; import com.thoughtworks.xstream.converters.reflection.ObjectAccessException; +import com.thoughtworks.xstream.core.Caching; + /** - * Builds the serializable properties maps for each bean and caches them. + * Builds the properties maps for each bean and caches them. + * + * @author Joe Walnes + * @author Jörg Schaible */ -public class PropertyDictionary { +public class PropertyDictionary implements Caching { + private transient Map, Map> propertyNameCache = Collections + .synchronizedMap(new HashMap, Map>()); + private final PropertySorter sorter; - private final Map keyedByPropertyNameCache = Collections.synchronizedMap(new HashMap()); + public PropertyDictionary() { + this(new NativePropertySorter()); + } - public Iterator serializablePropertiesFor(Class cls) { - return buildMap(cls).values().iterator(); + public PropertyDictionary(final PropertySorter sorter) { + this.sorter = sorter; } /** - * Locates a serializable property - * - * @param cls - * @param name - * @param definedIn - * @return + * @deprecated As of 1.3.1, use {@link #propertiesFor(Class)} instead */ - public BeanProperty property(Class cls, String name) { - Map properties = buildMap(cls); - BeanProperty property = (BeanProperty) properties.get(name); - if (property == null) { - throw new ObjectAccessException("No such property " + cls.getName() + "." + name); - } else { - return property; + @Deprecated + public Iterator serializablePropertiesFor(final Class type) { + final Collection beanProperties = new ArrayList(); + final Collection descriptors = buildMap(type).values(); + for (final PropertyDescriptor descriptor : descriptors) { + if (descriptor.getReadMethod() != null && descriptor.getWriteMethod() != null) { + beanProperties.add(new BeanProperty(type, descriptor.getName(), descriptor.getPropertyType())); + } } + return beanProperties.iterator(); } /** - * Builds the map of all serializable properties for the the provided bean + * Locates a serializable property. * * @param cls - * @param tupleKeyed - * @return + * @param name + * @deprecated As of 1.3.1, use {@link #propertyDescriptor(Class, String)} instead */ - private Map buildMap(Class cls) { - final String clsName = cls.getName(); - if (!keyedByPropertyNameCache.containsKey(clsName)) { - synchronized (keyedByPropertyNameCache) { - if (!keyedByPropertyNameCache.containsKey(clsName)) { // double check - // Gather all the properties, using only the keyed map. It - // is possible that a class have two writable only - // properties that have the same name - // but different types - final Map propertyMap = new HashMap(); - Method[] methods = cls.getMethods(); - - for (int i = 0; i < methods.length; i++) { - if (!Modifier.isPublic(methods[i].getModifiers()) - || Modifier.isStatic(methods[i].getModifiers())) - continue; - - String methodName = methods[i].getName(); - Class[] parameters = methods[i].getParameterTypes(); - Class returnType = methods[i].getReturnType(); - String propertyName; - if ((methodName.startsWith("get") || methodName.startsWith("is")) - && parameters.length == 0 && returnType != void.class) { - if (methodName.startsWith("get")) { - propertyName = Introspector.decapitalize(methodName.substring(3)); - } else { - propertyName = Introspector.decapitalize(methodName.substring(2)); - } - BeanProperty property = getBeanProperty(propertyMap, cls, propertyName, - returnType); - property.setGetterMethod(methods[i]); - } else if (methodName.startsWith("set") && parameters.length == 1 - && returnType == void.class) { - propertyName = Introspector.decapitalize(methodName.substring(3)); - BeanProperty property = getBeanProperty(propertyMap, cls, propertyName, - parameters[0]); - property.setSetterMethod(methods[i]); - } - } - - // retain only those that can be both read and written and - // sort them by name - List serializableProperties = new ArrayList(); - for (Iterator it = propertyMap.values().iterator(); it.hasNext();) { - BeanProperty property = (BeanProperty) it.next(); - if (property.isReadable() && property.isWritable()) { - serializableProperties.add(property); - } - } - Collections.sort(serializableProperties, new BeanPropertyComparator()); - - // build the maps and return - final Map keyedByFieldName = new OrderRetainingMap(); - for (Iterator it = serializableProperties.iterator(); it.hasNext();) { - BeanProperty property = (BeanProperty) it.next(); - keyedByFieldName.put(property.getName(), property); - } - - keyedByPropertyNameCache.put(clsName, keyedByFieldName); - } - } + @Deprecated + public BeanProperty property(final Class cls, final String name) { + BeanProperty beanProperty = null; + final PropertyDescriptor descriptor = buildMap(cls).get(name); + if (descriptor == null) { + throw new MissingFieldException(cls.getName(), name); } - return (Map) keyedByPropertyNameCache.get(clsName); - } - - private BeanProperty getBeanProperty(Map propertyMap, Class cls, String propertyName, Class type) { - PropertyKey key = new PropertyKey(propertyName, type); - BeanProperty property = (BeanProperty) propertyMap.get(key); - if (property == null) { - property = new BeanProperty(cls, propertyName, type); - propertyMap.put(key, property); + if (descriptor.getReadMethod() != null && descriptor.getWriteMethod() != null) { + beanProperty = new BeanProperty(cls, descriptor.getName(), descriptor.getPropertyType()); } - return property; + return beanProperty; } - /** - * Needed to avoid problems with multiple setters with the same name, but - * referred to different types - */ - private static class PropertyKey { - private String propertyName; - - private Class propertyType; - - public PropertyKey(String propertyName, Class propertyType) { - this.propertyName = propertyName; - this.propertyType = propertyType; - } - - public boolean equals(Object o) { - if (this == o) - return true; - if (!(o instanceof PropertyKey)) - return false; - - final PropertyKey propertyKey = (PropertyKey) o; - - if (propertyName != null ? !propertyName.equals(propertyKey.propertyName) - : propertyKey.propertyName != null) - return false; - if (propertyType != null ? !propertyType.equals(propertyKey.propertyType) - : propertyKey.propertyType != null) - return false; - - return true; - } - - public int hashCode() { - int result; - result = (propertyName != null ? propertyName.hashCode() : 0); - result = 29 * result + (propertyType != null ? propertyType.hashCode() : 0); - return result; - } - - public String toString() { - return "PropertyKey{propertyName='" + propertyName + "'" + ", propertyType=" - + propertyType + "}"; - } - + public Iterator propertiesFor(final Class type) { + return buildMap(type).values().iterator(); } /** - * Compares properties by name + * Locates a property descriptor. + * + * @param type + * @param name */ - private static class BeanPropertyComparator implements Comparator { - - public int compare(Object o1, Object o2) { - return ((BeanProperty) o1).getName().compareTo(((BeanProperty) o2).getName()); + public PropertyDescriptor propertyDescriptor(final Class type, final String name) { + final PropertyDescriptor descriptor = buildMap(type).get(name); + if (descriptor == null) { + throw new MissingFieldException(type.getName(), name); } - + return descriptor; } - private static class OrderRetainingMap extends HashMap { - - private List valueOrder = new ArrayList(); - - public Object put(Object key, Object value) { - valueOrder.add(value); - return super.put(key, value); + private Map buildMap(final Class type) { + Map nameMap = propertyNameCache.get(type); + if (nameMap == null) { + BeanInfo beanInfo; + try { + beanInfo = Introspector.getBeanInfo(type, Object.class); + } catch (final IntrospectionException e) { + throw new ObjectAccessException("Cannot get BeanInfo of type " + type.getName(), e); + } + nameMap = new LinkedHashMap(); + final PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); + for (final PropertyDescriptor descriptor : propertyDescriptors) { + nameMap.put(descriptor.getName(), descriptor); + } + nameMap = sorter.sort(type, nameMap); + propertyNameCache.put(type, nameMap); } - - public Collection values() { - return Collections.unmodifiableList(valueOrder); - } + return nameMap; } -} \ No newline at end of file + @Override + public void flushCache() { + propertyNameCache.clear(); + } +} Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/javabean/PropertySorter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/AbstractAttributedCharacterIteratorAttributeConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/AbstractReflectionConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/CGLIBEnhancedConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/ExternalizableConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/ExternalizableConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/ExternalizableConverter.java 10 Sep 2012 19:03:03 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/ExternalizableConverter.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,117 +1,193 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 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 24. August 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.reflection; +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; + 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.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; -import java.io.Externalizable; -import java.io.IOException; -import java.io.NotActiveException; -import java.io.ObjectInput; -import java.io.ObjectInputValidation; -import java.io.ObjectOutput; -import java.util.Map; /** - * Converts any object that implements the java.io.Externalizable interface, allowing compatability with native Java + * Converts any object that implements the {@link Externalizable} interface, allowing compatibility with native Java * serialization. - * + * * @author Joe Walnes */ public class ExternalizableConverter implements Converter { - private Mapper mapper; + private final Mapper mapper; + private final ClassLoaderReference classLoaderReference; - public ExternalizableConverter(Mapper mapper) { + /** + * Construct an ExternalizableConverter. + * + * @param mapper the Mapper chain + * @param classLoaderReference the reference to XStream's {@link ClassLoader} instance + * @since 1.4.5 + */ + public ExternalizableConverter(final Mapper mapper, final ClassLoaderReference classLoaderReference) { this.mapper = mapper; + this.classLoaderReference = classLoaderReference; } - public boolean canConvert(Class type) { - return Externalizable.class.isAssignableFrom(type); + /** + * @deprecated As of 1.4.5 use {@link #ExternalizableConverter(Mapper, ClassLoaderReference)} + */ + @Deprecated + public ExternalizableConverter(final Mapper mapper, final ClassLoader classLoader) { + this(mapper, new ClassLoaderReference(classLoader)); } - public void marshal(Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + /** + * @deprecated As of 1.4 use {@link #ExternalizableConverter(Mapper, ClassLoader)} + */ + @Deprecated + public ExternalizableConverter(final Mapper mapper) { + this(mapper, ExternalizableConverter.class.getClassLoader()); + } + + @Override + public boolean canConvert(final Class type) { + return JVM.canCreateDerivedObjectOutputStream() && Externalizable.class.isAssignableFrom(type); + } + + @Override + public void marshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { try { - Externalizable externalizable = (Externalizable) source; - CustomObjectOutputStream.StreamCallback callback = new CustomObjectOutputStream.StreamCallback() { - public void writeToStream(Object object) { + final Externalizable externalizable = (Externalizable)source; + final CustomObjectOutputStream.StreamCallback callback = new CustomObjectOutputStream.StreamCallback() { + @Override + public void writeToStream(final Object object) { if (object == null) { writer.startNode("null"); writer.endNode(); } else { - writer.startNode(mapper.serializedClass(object.getClass())); + ExtendedHierarchicalStreamWriterHelper.startNode(writer, mapper.serializedClass(object + .getClass()), object.getClass()); context.convertAnother(object); writer.endNode(); } } - public void writeFieldsToStream(Map fields) { + @Override + public void writeFieldsToStream(final Map fields) { throw new UnsupportedOperationException(); } + @Override public void defaultWriteObject() { throw new UnsupportedOperationException(); } + @Override public void flush() { writer.flush(); } + @Override public void close() { - throw new UnsupportedOperationException("Objects are not allowed to call ObjecOutput.close() from writeExternal()"); + throw new UnsupportedOperationException( + "Objects are not allowed to call ObjectOutput.close() from writeExternal()"); } }; - ObjectOutput objectOutput = CustomObjectOutputStream.getInstance(context, callback); + @SuppressWarnings("resource") + final CustomObjectOutputStream objectOutput = CustomObjectOutputStream.getInstance(context, callback); externalizable.writeExternal(objectOutput); - } catch (IOException e) { - throw new ConversionException("Cannot serialize " + source.getClass().getName() + " using Externalization", e); + objectOutput.popCallback(); + } catch (final IOException e) { + throw new ConversionException("Cannot serialize " + source.getClass().getName() + " using Externalization", + e); } } + @Override public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { - final Class type = context.getRequiredType(); + final Class type = context.getRequiredType(); + final Constructor defaultConstructor; try { - final Externalizable externalizable = (Externalizable) type.newInstance(); - CustomObjectInputStream.StreamCallback callback = new CustomObjectInputStream.StreamCallback() { + defaultConstructor = type.getDeclaredConstructor(); + if (!defaultConstructor.isAccessible()) { + defaultConstructor.setAccessible(true); + } + final Externalizable externalizable = (Externalizable)defaultConstructor.newInstance(); + final CustomObjectInputStream.StreamCallback callback = new CustomObjectInputStream.StreamCallback() { + @Override public Object readFromStream() { reader.moveDown(); - Object streamItem = context.convertAnother(externalizable, mapper.realClass(reader.getNodeName())); + final Class type = HierarchicalStreams.readClassType(reader, mapper); + final Object streamItem = context.convertAnother(externalizable, type); reader.moveUp(); return streamItem; } - public Map readFieldsFromStream() { + @Override + public Map readFieldsFromStream() { throw new UnsupportedOperationException(); } + @Override public void defaultReadObject() { throw new UnsupportedOperationException(); } - public void registerValidation(ObjectInputValidation validation, int priority) throws NotActiveException { + @Override + public void registerValidation(final ObjectInputValidation validation, final int priority) + throws NotActiveException { throw new NotActiveException("stream inactive"); } + @Override public void close() { - throw new UnsupportedOperationException("Objects are not allowed to call ObjectInput.close() from readExternal()"); + throw new UnsupportedOperationException( + "Objects are not allowed to call ObjectInput.close() from readExternal()"); } }; - ObjectInput objectInput = CustomObjectInputStream.getInstance(context, callback); - externalizable.readExternal(objectInput); + { + @SuppressWarnings("resource") + final CustomObjectInputStream objectInput = CustomObjectInputStream.getInstance(context, callback, + classLoaderReference); + externalizable.readExternal(objectInput); + objectInput.popCallback(); + } return externalizable; - } catch (InstantiationException e) { + } catch (final NoSuchMethodException e) { + throw new ConversionException("Cannot construct " + type.getClass() + ", missing default constructor", e); + } catch (final InvocationTargetException e) { throw new ConversionException("Cannot construct " + type.getClass(), e); - } catch (IllegalAccessException e) { + } catch (final InstantiationException e) { throw new ConversionException("Cannot construct " + type.getClass(), e); - } catch (IOException e) { + } catch (final IllegalAccessException e) { + throw new ConversionException("Cannot construct " + type.getClass(), e); + } catch (final IOException e) { throw new ConversionException("Cannot externalize " + type.getClass(), e); - } catch (ClassNotFoundException e) { + } catch (final ClassNotFoundException e) { throw new ConversionException("Cannot externalize " + type.getClass(), e); } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/FieldDictionary.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/FieldDictionary.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/FieldDictionary.java 10 Sep 2012 19:03:03 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/FieldDictionary.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,110 +1,178 @@ +/* + * 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 com.thoughtworks.xstream.core.util.OrderRetainingMap; - import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Set; -public class FieldDictionary { +import com.thoughtworks.xstream.core.Caching; +import com.thoughtworks.xstream.core.JVM; - private final Map keyedByFieldNameCache = Collections.synchronizedMap(new HashMap()); - private final Map keyedByFieldKeyCache = Collections.synchronizedMap(new HashMap()); - public Iterator serializableFieldsFor(Class cls) { +/** + * 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, Map> keyedByFieldNameCache; + private transient Map, Map> keyedByFieldKeyCache; + private final FieldKeySorter sorter; + + public FieldDictionary() { + this(new ImmutableFieldKeySorter()); + } + + public FieldDictionary(final FieldKeySorter sorter) { + this.sorter = sorter; + init(); + } + + private void init() { + keyedByFieldNameCache = new HashMap, Map>(); + keyedByFieldKeyCache = new HashMap, Map>(); + keyedByFieldNameCache.put(Object.class, Collections.emptyMap()); + keyedByFieldKeyCache.put(Object.class, Collections.emptyMap()); + } + + /** + * 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(); } - public Field field(Class cls, String name, Class definedIn) { - Map fields = buildMap(cls, definedIn != null); - Field field = (Field) fields.get(definedIn != null ? (Object) new FieldKey(name, definedIn, 0) : (Object) name); + /** + * 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(final Class cls, final String name, final Class definedIn) { + final Field field = fieldOrNull(cls, name, definedIn); if (field == null) { - throw new ObjectAccessException("No such field " + cls.getName() + "." + name); + throw new MissingFieldException(cls.getName(), name); } else { return field; } } - private Map buildMap(Class cls, boolean tupleKeyed) { - final String clsName = cls.getName(); - if (!keyedByFieldNameCache.containsKey(clsName)) { - synchronized (keyedByFieldKeyCache) { - if (!keyedByFieldNameCache.containsKey(clsName)) { // double check - final Map keyedByFieldName = new HashMap(); - final Map keyedByFieldKey = new OrderRetainingMap(); - while (!Object.class.equals(cls)) { - Field[] fields = cls.getDeclaredFields(); + /** + * 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(final Class cls, final String name, final Class definedIn) { + final Map fields = buildMap(cls, definedIn != null); + final Field field = fields.get(definedIn != null ? (Object)new FieldKey(name, definedIn, -1) : (Object)name); + return field; + } + + private Map buildMap(final Class type, final 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.emptyMap(); + Map lastKeyedByFieldKey = Collections.emptyMap(); + for (final Class element : superClasses) { + cls = element; + if (!keyedByFieldNameCache.containsKey(cls)) { + final Map keyedByFieldName = new HashMap(lastKeyedByFieldName); + final Map keyedByFieldKey = new LinkedHashMap( + lastKeyedByFieldKey); + final 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]; - field.setAccessible(true); - if (!keyedByFieldName.containsKey(field.getName())) { + final Field field = fields[i]; + if (!field.isAccessible()) { + field.setAccessible(true); + } + final FieldKey fieldKey = new FieldKey(field.getName(), field.getDeclaringClass(), i); + final Field existent = 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(new FieldKey(field.getName(), field.getDeclaringClass(), i), field); + keyedByFieldKey.put(fieldKey, field); } - cls = cls.getSuperclass(); + final Map sortedFieldKeys = sorter.sort(cls, keyedByFieldKey); + keyedByFieldNameCache.put(cls, keyedByFieldName); + keyedByFieldKeyCache.put(cls, sortedFieldKeys); + lastKeyedByFieldName = keyedByFieldName; + lastKeyedByFieldKey = sortedFieldKeys; + } else { + lastKeyedByFieldName = keyedByFieldNameCache.get(cls); + lastKeyedByFieldKey = keyedByFieldKeyCache.get(cls); } - keyedByFieldNameCache.put(clsName, keyedByFieldName); - keyedByFieldKeyCache.put(clsName, keyedByFieldKey); } + return tupleKeyed ? lastKeyedByFieldKey : lastKeyedByFieldName; } } - return (Map) (tupleKeyed ? keyedByFieldKeyCache.get(clsName) : keyedByFieldNameCache.get(clsName)); + return tupleKeyed ? keyedByFieldKeyCache.get(type) : keyedByFieldNameCache.get(type); } - private static class FieldKey { - private String fieldName; - private Class declaringClass; - private Integer depth; - private int order; - - public FieldKey(String fieldName, Class declaringClass, int order) { - this.fieldName = fieldName; - this.declaringClass = declaringClass; - this.order = order; - Class c = declaringClass; - int i = 0; - while (c.getSuperclass() != null) { - i++; - c = c.getSuperclass(); - } - depth = new Integer(i); + @Override + public synchronized void flushCache() { + final Set> objectTypeSet = Collections.>singleton(Object.class); + keyedByFieldNameCache.keySet().retainAll(objectTypeSet); + keyedByFieldKeyCache.keySet().retainAll(objectTypeSet); + if (sorter instanceof Caching) { + ((Caching)sorter).flushCache(); } - - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof FieldKey)) return false; - - final FieldKey fieldKey = (FieldKey) o; - - if (declaringClass != null ? !declaringClass.equals(fieldKey.declaringClass) : fieldKey.declaringClass != null) return false; - if (fieldName != null ? !fieldName.equals(fieldKey.fieldName) : fieldKey.fieldName != null) return false; - - return true; - } - - public int hashCode() { - int result; - result = (fieldName != null ? fieldName.hashCode() : 0); - result = 29 * result + (declaringClass != null ? declaringClass.hashCode() : 0); - return result; - } - - public String toString() { - return "FieldKey{" + - "order=" + order + - ", writer=" + depth + - ", declaringClass=" + declaringClass + - ", fieldName='" + fieldName + "'" + - "}"; - } - - } + protected Object readResolve() { + init(); + return this; + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/FieldKey.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/FieldKeySorter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/ImmutableFieldKeySorter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/MissingFieldException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/NativeFieldKeySorter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/ObjectAccessException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/ObjectAccessException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/ObjectAccessException.java 10 Sep 2012 19:03:03 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/ObjectAccessException.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,8 +1,19 @@ +/* + * 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.core.BaseException; +import com.thoughtworks.xstream.XStreamException; -public class ObjectAccessException extends BaseException { +public class ObjectAccessException extends XStreamException { public ObjectAccessException(String message) { super(message); } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/PureJavaReflectionProvider.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/PureJavaReflectionProvider.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/PureJavaReflectionProvider.java 10 Sep 2012 19:03:03 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/PureJavaReflectionProvider.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,154 +1,212 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 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 07. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.reflection; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.Iterator; -import java.util.Map; -import java.util.HashMap; -import java.util.Collections; -import java.io.Serializable; -import java.io.ObjectStreamConstants; -import java.io.DataOutputStream; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; import java.io.IOException; -import java.io.ByteArrayInputStream; 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.HashMap; +import java.util.Iterator; +import java.util.Map; + /** - * 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. + * 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 final Map serializedDataCache = Collections.synchronizedMap(new HashMap()); + private transient Map, byte[]> serializedDataCache; + protected FieldDictionary fieldDictionary; - protected FieldDictionary fieldDictionary = new FieldDictionary(); + public PureJavaReflectionProvider() { + this(new FieldDictionary(new ImmutableFieldKeySorter())); + } - public Object newInstance(Class type) { + public PureJavaReflectionProvider(final FieldDictionary fieldDictionary) { + this.fieldDictionary = fieldDictionary; + init(); + } + + @Override + public Object newInstance(final Class type) { try { - Constructor[] constructors = type.getDeclaredConstructors(); - for (int i = 0; i < constructors.length; i++) { - if (constructors[i].getParameterTypes().length == 0) { - if (!Modifier.isPublic(constructors[i].getModifiers())) { - constructors[i].setAccessible(true); + for (final Constructor constructor : type.getDeclaredConstructors()) { + if (constructor.getParameterTypes().length == 0) { + if (!constructor.isAccessible()) { + constructor.setAccessible(true); } - return constructors[i].newInstance(new Object[0]); + 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"); + throw new ObjectAccessException("Cannot construct " + + type.getName() + + " as it does not have a no-args constructor"); } - } catch (InstantiationException e) { + } catch (final InstantiationException e) { throw new ObjectAccessException("Cannot construct " + type.getName(), e); - } catch (IllegalAccessException e) { + } catch (final IllegalAccessException e) { throw new ObjectAccessException("Cannot construct " + type.getName(), e); - } catch (InvocationTargetException e) { + } catch (final 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); + throw new ObjectAccessException("Constructor for " + type.getName() + " threw an exception", e + .getTargetException()); } } } - private Object instantiateUsingSerialization(Class type) { + private Object instantiateUsingSerialization(final Class type) { try { - byte[] data; - if (serializedDataCache.containsKey(type)) { - data = (byte[]) serializedDataCache.get(type); - } else { - 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); - } + synchronized (serializedDataCache) { + byte[] data = serializedDataCache.get(type); + if (data == null) { + final ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + final 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)); - return in.readObject(); - } catch (IOException e) { - throw new ObjectAccessException("", e); - } catch (ClassNotFoundException e) { - throw new ObjectAccessException("", e); + final ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(data)) { + @Override + protected Class resolveClass(final ObjectStreamClass desc) throws ClassNotFoundException { + return Class.forName(desc.getName(), false, type.getClassLoader()); + } + }; + return in.readObject(); + } + } catch (final IOException e) { + throw new ObjectAccessException("Cannot create " + type.getName() + " by JDK serialization", e); + } catch (final ClassNotFoundException e) { + throw new ObjectAccessException("Cannot find class " + e.getMessage(), e); } } - public void visitSerializableFields(Object object, ReflectionProvider.Visitor visitor) { - for (Iterator iterator = fieldDictionary.serializableFieldsFor(object.getClass()); iterator.hasNext();) { - Field field = (Field) iterator.next(); + @Override + public void visitSerializableFields(final Object object, final ReflectionProvider.Visitor visitor) { + for (final Iterator iterator = fieldDictionary.fieldsFor(object.getClass()); iterator.hasNext();) { + final Field field = iterator.next(); if (!fieldModifiersSupported(field)) { continue; } validateFieldAccess(field); try { - Object value = field.get(object); + final Object value = field.get(object); visitor.visit(field.getName(), field.getType(), field.getDeclaringClass(), value); - } catch (IllegalArgumentException e) { + } catch (final IllegalArgumentException e) { throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); - } catch (IllegalAccessException e) { + } catch (final 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); + @Override + public void writeField(final Object object, final String fieldName, final Object value, final Class definedIn) { + final Field field = fieldDictionary.field(object.getClass(), fieldName, definedIn); validateFieldAccess(field); try { field.set(object, value); - } catch (IllegalArgumentException e) { + } catch (final IllegalArgumentException e) { throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), e); - } catch (IllegalAccessException e) { + } catch (final IllegalAccessException e) { throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), e); } } - public Class getFieldType(Object object, String fieldName, Class definedIn) { + @Override + public Class getFieldType(final Object object, final String fieldName, final Class definedIn) { return fieldDictionary.field(object.getClass(), fieldName, definedIn).getType(); } - public boolean fieldDefinedInClass(String fieldName, Class type) { - try { - fieldDictionary.field(type, fieldName, null); - return true; - } catch (ObjectAccessException e) { - return false; - } + /** + * @deprecated As of 1.4.5, use {@link #getFieldOrNull(Class, String)} instead + */ + @Deprecated + @Override + public boolean fieldDefinedInClass(final String fieldName, final Class type) { + final Field field = fieldDictionary.fieldOrNull(type, fieldName, null); + return field != null && fieldModifiersSupported(field); } - protected boolean fieldModifiersSupported(Field field) { - return !(Modifier.isStatic(field.getModifiers()) - || Modifier.isTransient(field.getModifiers())); + protected boolean fieldModifiersSupported(final Field field) { + final int modifiers = field.getModifiers(); + return !(Modifier.isStatic(modifiers) || Modifier.isTransient(modifiers)); } - protected void validateFieldAccess(Field field) { + protected void validateFieldAccess(final Field field) { if (Modifier.isFinal(field.getModifiers())) { - throw new ObjectAccessException("Invalid final field " - + field.getDeclaringClass().getName() + "." + field.getName()); + if (!field.isAccessible()) { + field.setAccessible(true); + } } } + @Override + public Field getField(final Class definedIn, final String fieldName) { + return fieldDictionary.field(definedIn, fieldName, null); + } + + @Override + public Field getFieldOrNull(final Class definedIn, final String fieldName) { + return fieldDictionary.fieldOrNull(definedIn, fieldName, null); + } + + public void setFieldDictionary(final FieldDictionary dictionary) { + fieldDictionary = dictionary; + } + + private Object readResolve() { + init(); + return this; + } + + protected void init() { + serializedDataCache = new HashMap, byte[]>(); + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/ReflectionConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/ReflectionConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/ReflectionConverter.java 10 Sep 2012 19:03:03 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/ReflectionConverter.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,191 +1,46 @@ +/* + * 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.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.core.JVM; import com.thoughtworks.xstream.mapper.Mapper; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -public class ReflectionConverter implements Converter { +public class ReflectionConverter extends AbstractReflectionConverter { - private final Mapper mapper; - private final ReflectionProvider reflectionProvider; - private final SerializationMethodInvoker serializationMethodInvoker; + // Might be missing in Android + private final static Class eventHandlerType = JVM.loadClassForName("java.beans.EventHandler"); + private Class type; - public ReflectionConverter(Mapper mapper, ReflectionProvider reflectionProvider) { - this.mapper = mapper; - this.reflectionProvider = reflectionProvider; - serializationMethodInvoker = new SerializationMethodInvoker(); + public ReflectionConverter(final Mapper mapper, final ReflectionProvider reflectionProvider) { + super(mapper, reflectionProvider); } - public boolean canConvert(Class type) { - return true; + /** + * 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(final Mapper mapper, final ReflectionProvider reflectionProvider, final Class type) { + this(mapper, reflectionProvider); + this.type = type; } - public void marshal(Object original, final HierarchicalStreamWriter writer, final MarshallingContext context) { - final Object source = serializationMethodInvoker.callWriteReplace(original); - - if (source.getClass() != original.getClass()) { - writer.addAttribute(mapper.attributeForReadResolveField(), mapper.serializedClass(source.getClass())); - } - - final Set seenFields = new HashSet(); - - reflectionProvider.visitSerializableFields(source, new ReflectionProvider.Visitor() { - public void visit(String fieldName, Class fieldType, Class definedIn, Object newObj) { - if (newObj != null) { - Mapper.ImplicitCollectionMapping mapping = mapper.getImplicitCollectionDefForFieldName(source.getClass(), fieldName); - if (mapping != null) { - if (mapping.getItemFieldName() != null) { - ArrayList list = (ArrayList) newObj; - for (Iterator iter = list.iterator(); iter.hasNext();) { - Object obj = iter.next(); - writeField(mapping.getItemFieldName(), mapping.getItemType(), definedIn, obj); - } - } else { - context.convertAnother(newObj); - } - } else { - writeField(fieldName, fieldType, definedIn, newObj); - seenFields.add(fieldName); - } - } - } - - private void writeField(String fieldName, Class fieldType, Class definedIn, Object newObj) { - if (!mapper.shouldSerializeMember(definedIn, fieldName)) { - return; - } - writer.startNode(mapper.serializedMember(definedIn, fieldName)); - - Class actualType = newObj.getClass(); - - Class defaultType = mapper.defaultImplementationOf(fieldType); - if (!actualType.equals(defaultType)) { - writer.addAttribute(mapper.attributeForImplementationClass(), mapper.serializedClass(actualType)); - } - - if (seenFields.contains(fieldName)) { - writer.addAttribute(mapper.attributeForClassDefiningField(), mapper.serializedClass(definedIn)); - } - context.convertAnother(newObj); - - writer.endNode(); - } - - }); + @Override + public boolean canConvert(final Class type) { + return (this.type != null && this.type == type || this.type == null && type != null && type != eventHandlerType) + && canAccess(type); } - - public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { - final Object result = instantiateNewInstance(context, reader.getAttribute(mapper.attributeForReadResolveField())); - final SeenFields seenFields = new SeenFields(); - - Map implicitCollectionsForCurrentObject = null; - while (reader.hasMoreChildren()) { - reader.moveDown(); - - String fieldName = mapper.realMember(result.getClass(), reader.getNodeName()); - - Class classDefiningField = determineWhichClassDefinesField(reader); - boolean fieldExistsInClass = reflectionProvider.fieldDefinedInClass(fieldName, result.getClass()); - - Class type = determineType(reader, fieldExistsInClass, result, fieldName, classDefiningField); - Object value = context.convertAnother(result, type); - - if (fieldExistsInClass) { - reflectionProvider.writeField(result, fieldName, value, classDefiningField); - seenFields.add(classDefiningField, fieldName); - } else { - implicitCollectionsForCurrentObject = writeValueToImplicitCollection(context, value, implicitCollectionsForCurrentObject, result, fieldName); - } - - reader.moveUp(); - } - - return serializationMethodInvoker.callReadResolve(result); - } - - - private Map writeValueToImplicitCollection(UnmarshallingContext context, Object value, Map implicitCollections, Object result, String itemFieldName) { - String fieldName = mapper.getFieldNameForItemTypeAndName(context.getRequiredType(), value.getClass(), itemFieldName); - if (fieldName != null) { - if (implicitCollections == null) { - implicitCollections = new HashMap(); // lazy instantiation - } - Collection collection = (Collection) implicitCollections.get(fieldName); - if (collection == null) { - collection = new ArrayList(); - reflectionProvider.writeField(result, fieldName, collection, null); - implicitCollections.put(fieldName, collection); - } - collection.add(value); - } - return implicitCollections; - } - - private Class determineWhichClassDefinesField(HierarchicalStreamReader reader) { - String definedIn = reader.getAttribute(mapper.attributeForClassDefiningField()); - return definedIn == null ? null : mapper.realClass(definedIn); - } - - private Object instantiateNewInstance(UnmarshallingContext context, String readResolveValue) { - 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()); - } - } - - private static class SeenFields { - - private Set seen = new HashSet(); - - public void add(Class definedInCls, String fieldName) { - String uniqueKey = fieldName; - if (definedInCls != null) { - uniqueKey += " [" + definedInCls.getName() + "]"; - } - if (seen.contains(uniqueKey)) { - throw new DuplicateFieldException(uniqueKey); - } else { - seen.add(uniqueKey); - } - } - - } - - private Class determineType(HierarchicalStreamReader reader, boolean validField, Object result, String fieldName, Class definedInCls) { - String classAttribute = reader.getAttribute(mapper.attributeForImplementationClass()); - if (classAttribute != null) { - return mapper.realClass(classAttribute); - } else if (!validField) { - Class itemType = mapper.getItemTypeForItemFieldName(result.getClass(), fieldName); - if (itemType != null) { - return itemType; - } else { - return mapper.realClass(reader.getNodeName()); - } - } else { - return mapper.defaultImplementationOf(reflectionProvider.getFieldType(result, fieldName, definedInCls)); - } - } - - public static class DuplicateFieldException extends ConversionException { - public DuplicateFieldException(String msg) { - super(msg); - } - } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/ReflectionProvider.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/ReflectionProvider.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/ReflectionProvider.java 10 Sep 2012 19:03:03 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/ReflectionProvider.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,21 +1,80 @@ +/* + * Copyright (C) 2004, 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 java.lang.reflect.Field; + + /** * Provides core reflection services. + * + * @author Joe Walnes */ public interface ReflectionProvider { - Object newInstance(Class type); + /** + * 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); + void writeField(Object object, String fieldName, Object value, Class definedIn); - Class getFieldType(Object object, String fieldName, Class definedIn); + Class getFieldType(Object object, String fieldName, Class definedIn); - boolean fieldDefinedInClass(String fieldName, Class type); + /** + * @deprecated As of 1.4.5, use {@link #getFieldOrNull(Class, String)} instead + */ + @Deprecated + boolean fieldDefinedInClass(String fieldName, Class type); + /** + * A visitor interface for serializable fields defined in a class. + */ interface Visitor { - void visit(String name, Class type, Class definedIn, Object value); + + /** + * 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); } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/ReflectionProviderWrapper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/SelfStreamingInstanceChecker.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/SerializableConverter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/SerializableConverter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/SerializableConverter.java 10 Sep 2012 19:03:03 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/SerializableConverter.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,119 +1,181 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 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 21. December 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.util.CustomObjectInputStream; -import com.thoughtworks.xstream.core.util.CustomObjectOutputStream; -import com.thoughtworks.xstream.io.HierarchicalStreamReader; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; -import com.thoughtworks.xstream.mapper.Mapper; - import java.io.IOException; import java.io.InvalidObjectException; -import java.io.ObjectInputStream; import java.io.ObjectInputValidation; -import java.io.ObjectOutputStream; 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 a custom readObject()/writeObject() method. - * - *

Supported features of serialization

+ * implement or inherit a custom readObject()/writeObject() method.

Supported features of serialization

*
    - *
  • readObject(), writeObject()
  • - *
  • class inheritance
  • - *
  • readResolve(), writeReplace()
  • + *
  • readObject(), writeObject()
  • + *
  • class inheritance
  • + *
  • readResolve(), writeReplace()
  • *
- * *

Currently unsupported features

*
    - *
  • putFields(), writeFields(), readFields()
  • - *
  • ObjectStreamField[] serialPersistentFields
  • - *
  • ObjectInputValidation
  • + *
  • putFields(), writeFields(), readFields()
  • + *
  • ObjectStreamField[] serialPersistentFields
  • + *
  • ObjectInputValidation
  • *
- * + * * @author Joe Walnes + * @author Jörg Schaible */ -public class SerializableConverter implements Converter { +public class SerializableConverter extends AbstractReflectionConverter { - private final SerializationMethodInvoker serializationMethodInvoker = new SerializationMethodInvoker(); - private final Mapper mapper; - private final ReflectionProvider reflectionProvider; - 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"; - public SerializableConverter(Mapper mapper, ReflectionProvider reflectionProvider) { - this.mapper = mapper; - this.reflectionProvider = reflectionProvider; + 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( + final Mapper mapper, final ReflectionProvider reflectionProvider, + final ClassLoaderReference classLoaderReference) { + super(mapper, new UnserializableParentsReflectionProvider(reflectionProvider)); + this.classLoaderReference = classLoaderReference; } - public boolean canConvert(Class type) { - return Serializable.class.isAssignableFrom(type) - && ( serializationMethodInvoker.supportsReadObject(type, true) - || serializationMethodInvoker.supportsWriteObject(type, true) ); + /** + * @deprecated As of 1.4.5 use {@link #SerializableConverter(Mapper, ReflectionProvider, ClassLoaderReference)} + */ + @Deprecated + public SerializableConverter( + final Mapper mapper, final ReflectionProvider reflectionProvider, final ClassLoader classLoader) { + this(mapper, reflectionProvider, new ClassLoaderReference(classLoader)); } - public void marshal(Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { - final Object replacedSource = serializationMethodInvoker.callWriteReplace(source); + /** + * @deprecated As of 1.4 use {@link #SerializableConverter(Mapper, ReflectionProvider, ClassLoaderReference)} + */ + @Deprecated + public SerializableConverter(final Mapper mapper, final ReflectionProvider reflectionProvider) { + this(mapper, new UnserializableParentsReflectionProvider(reflectionProvider), new ClassLoaderReference(null)); + } - if (replacedSource.getClass() != source.getClass()) { - writer.addAttribute(mapper.attributeForReadResolveField(), mapper.serializedClass(replacedSource.getClass())); + @Override + public boolean canConvert(final Class type) { + return JVM.canCreateDerivedObjectOutputStream() && isSerializable(type); + } + + private boolean isSerializable(final Class type) { + if (type != null + && Serializable.class.isAssignableFrom(type) + && !type.isInterface() + && (serializationMethodInvoker.supportsReadObject(type, true) || serializationMethodInvoker + .supportsWriteObject(type, true))) { + for (final Class clazz : hierarchyFor(type)) { + if (!Serializable.class.isAssignableFrom(clazz)) { + return canAccess(type); + } + } + return true; } + return false; + } - writer.addAttribute(ATTRIBUTE_SERIALIZATION, ATTRIBUTE_VALUE_CUSTOM); + @Override + public void doMarshal(final Object source, final HierarchicalStreamWriter writer, final MarshallingContext context) { + final 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 Class[] currentTypeRef = new Class[1]; final boolean[] writtenClassWrapper = {false}; - CustomObjectOutputStream.StreamCallback callback = new CustomObjectOutputStream.StreamCallback() { + final CustomObjectOutputStream.StreamCallback callback = new CustomObjectOutputStream.StreamCallback() { - public void writeToStream(Object object) { + @Override + public void writeToStream(final Object object) { if (object == null) { writer.startNode(ELEMENT_NULL); writer.endNode(); } else { - writer.startNode(mapper.serializedClass(object.getClass())); + 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]); + @Override + public void writeFieldsToStream(final Map fields) { + final Class currentType = currentTypeRef[0]; + final ObjectStreamClass objectStreamClass = ObjectStreamClass.lookup(currentType); writer.startNode(ELEMENT_DEFAULT); - for (Iterator iterator = fields.keySet().iterator(); iterator.hasNext();) { - String name = (String) iterator.next(); - ObjectStreamField field = objectStreamClass.getField(name); - Object value = fields.get(name); + for (final String name : fields.keySet()) { + if (!mapper.shouldSerializeMember(currentType, name)) { + continue; + } + final ObjectStreamField field = objectStreamClass.getField(name); + final Object value = fields.get(name); if (field == null) { - throw new ObjectAccessException("Class " + value.getClass().getName() - + " may not write a field named '" + name + "'"); + throw new ObjectAccessException("Class " + + value.getClass().getName() + + " may not write a field named '" + + name + + "'"); } if (value != null) { - writer.startNode(mapper.serializedMember(currentType[0], name)); + ExtendedHierarchicalStreamWriterHelper.startNode(writer, mapper.serializedMember(source + .getClass(), name), value.getClass()); if (field.getType() != value.getClass() && !field.getType().isPrimitive()) { - writer.addAttribute(ATTRIBUTE_CLASS, mapper.serializedClass(value.getClass())); + final String attributeName = mapper.aliasForSystemAttribute(ATTRIBUTE_CLASS); + if (attributeName != null) { + writer.addAttribute(attributeName, mapper.serializedClass(value.getClass())); + } } context.convertAnother(value); writer.endNode(); @@ -122,35 +184,40 @@ writer.endNode(); } + @Override public void defaultWriteObject() { boolean writtenDefaultFields = false; - ObjectStreamClass objectStreamClass = ObjectStreamClass.lookup(currentType[0]); - + final Class currentType = currentTypeRef[0]; + final ObjectStreamClass objectStreamClass = ObjectStreamClass.lookup(currentType); 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], replacedSource); + for (final ObjectStreamField field : objectStreamClass.getFields()) { + final Object value = readField(field, currentType, source); if (value != null) { if (!writtenClassWrapper[0]) { - writer.startNode(mapper.serializedClass(currentType[0])); + writer.startNode(mapper.serializedClass(currentType)); writtenClassWrapper[0] = true; } if (!writtenDefaultFields) { writer.startNode(ELEMENT_DEFAULT); writtenDefaultFields = true; } + if (!mapper.shouldSerializeMember(currentType, field.getName())) { + continue; + } - writer.startNode(mapper.serializedMember(currentType[0], field.getName())); - - Class actualType = value.getClass(); - Class defaultType = mapper.defaultImplementationOf(field.getType()); + final Class actualType = value.getClass(); + ExtendedHierarchicalStreamWriterHelper.startNode(writer, mapper.serializedMember(source + .getClass(), field.getName()), actualType); + final Class defaultType = mapper.defaultImplementationOf(field.getType()); if (!actualType.equals(defaultType)) { - writer.addAttribute(ATTRIBUTE_CLASS, mapper.serializedClass(actualType)); + final String attributeName = mapper.aliasForSystemAttribute(ATTRIBUTE_CLASS); + if (attributeName != null) { + writer.addAttribute(attributeName, mapper.serializedClass(actualType)); + } } context.convertAnother(value); @@ -166,147 +233,188 @@ } } + @Override public void flush() { writer.flush(); } + @Override public void close() { - throw new UnsupportedOperationException("Objects are not allowed to call ObjectOutputStream.close() from writeObject()"); + throw new UnsupportedOperationException( + "Objects are not allowed to call ObjectOutputStream.close() from writeObject()"); } }; try { - Iterator classHieararchy = hierarchyFor(replacedSource.getClass()); - while (classHieararchy.hasNext()) { - currentType[0] = (Class) classHieararchy.next(); - if (serializationMethodInvoker.supportsWriteObject(currentType[0], false)) { - writtenClassWrapper[0] = true; - writer.startNode(mapper.serializedClass(currentType[0])); - ObjectOutputStream objectOutputStream = CustomObjectOutputStream.getInstance(context, callback); - serializationMethodInvoker.callWriteObject(currentType[0], replacedSource, objectOutputStream); - writer.endNode(); - } else if (serializationMethodInvoker.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])); - callback.defaultWriteObject(); - writer.endNode(); + boolean mustHandleUnserializableParent = false; + for (final Class currentType : hierarchyFor(source.getClass())) { + currentTypeRef[0] = currentType; + if (!Serializable.class.isAssignableFrom(currentType)) { + mustHandleUnserializableParent = true; + continue; } else { - writtenClassWrapper[0] = false; - callback.defaultWriteObject(); - if (writtenClassWrapper[0]) { + if (mustHandleUnserializableParent) { + marshalUnserializableParent(writer, context, source); + mustHandleUnserializableParent = false; + } + if (serializationMethodInvoker.supportsWriteObject(currentType, false)) { + writtenClassWrapper[0] = true; + writer.startNode(mapper.serializedClass(currentType)); + if (currentType != mapper.defaultImplementationOf(currentType)) { + final String classAttributeName = mapper.aliasForSystemAttribute(ATTRIBUTE_CLASS); + if (classAttributeName != null) { + writer.addAttribute(classAttributeName, currentType.getName()); + } + } + @SuppressWarnings("resource") + final CustomObjectOutputStream objectOutputStream = CustomObjectOutputStream.getInstance( + context, callback); + serializationMethodInvoker.callWriteObject(currentType, source, objectOutputStream); + objectOutputStream.popCallback(); writer.endNode(); + } else if (serializationMethodInvoker.supportsReadObject(currentType, 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)); + if (currentType != mapper.defaultImplementationOf(currentType)) { + final String classAttributeName = mapper.aliasForSystemAttribute(ATTRIBUTE_CLASS); + if (classAttributeName != null) { + writer.addAttribute(classAttributeName, currentType.getName()); + } + } + callback.defaultWriteObject(); + writer.endNode(); + } else { + writtenClassWrapper[0] = false; + callback.defaultWriteObject(); + if (writtenClassWrapper[0]) { + writer.endNode(); + } } } } - } catch (IOException e) { + } catch (final IOException e) { throw new ObjectAccessException("Could not call defaultWriteObject()", e); } } - private Object readField(ObjectStreamField field, Class type, Object instance) { + 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(final ObjectStreamField field, final Class type, final Object instance) { try { - Field javaField = type.getDeclaredField(field.getName()); - javaField.setAccessible(true); + final Field javaField = type.getDeclaredField(field.getName()); + if (!javaField.isAccessible()) { + javaField.setAccessible(true); + } return javaField.get(instance); - } catch (IllegalArgumentException e) { + } catch (final IllegalArgumentException e) { throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); - } catch (IllegalAccessException e) { + } catch (final IllegalAccessException e) { throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); - } catch (NoSuchFieldException e) { + } catch (final NoSuchFieldException e) { throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); - } catch (SecurityException e) { + } catch (final SecurityException e) { throw new ObjectAccessException("Could not get field " + field.getClass() + "." + field.getName(), e); } } - private Iterator hierarchyFor(Class type) { - List result = new ArrayList(); - while(type != null) { + protected List> hierarchyFor(Class type) { + final 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.iterator(); + return result; } - public Object unmarshal(final HierarchicalStreamReader reader, final UnmarshallingContext context) { - String resolvesAttribute = reader.getAttribute(mapper.attributeForReadResolveField()); - Class requiredType; - if (resolvesAttribute != null) { - requiredType = mapper.realClass(resolvesAttribute); - } else { - requiredType = context.getRequiredType(); - } - final Object result = reflectionProvider.newInstance(requiredType); - + @Override + 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]; + final Class[] currentType = new Class[1]; - if (!ATTRIBUTE_VALUE_CUSTOM.equals(reader.getAttribute(ATTRIBUTE_SERIALIZATION))) { + final 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() { + final CustomObjectInputStream.StreamCallback callback = new CustomObjectInputStream.StreamCallback() { + @Override public Object readFromStream() { reader.moveDown(); - Class type = mapper.realClass(reader.getNodeName()); - Object value = context.convertAnother(result, type); + final Class type = HierarchicalStreams.readClassType(reader, mapper); + final Object value = context.convertAnother(result, type); reader.moveUp(); return value; } - public Map readFieldsFromStream() { - Map result = new HashMap(); + @Override + public Map readFieldsFromStream() { + final Map fields = new HashMap(); reader.moveDown(); if (reader.getNodeName().equals(ELEMENT_FIELDS)) { - // Maintain compatability with XStream 1.1.0 + // 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 + "/>"); + 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); - result.put(name, value); + final String name = reader.getAttribute(ATTRIBUTE_NAME); + final Class type = mapper.realClass(reader.getAttribute(ATTRIBUTE_CLASS)); + final 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]); + final ObjectStreamClass objectStreamClass = ObjectStreamClass.lookup(currentType[0]); while (reader.hasMoreChildren()) { reader.moveDown(); - String name = reader.getNodeName(); - String typeName = reader.getAttribute(ATTRIBUTE_CLASS); - Class type; - if (typeName != null) { - type = mapper.realClass(typeName); - } else { - ObjectStreamField field = objectStreamClass.getField(name); - if (field == null) { - throw new ObjectAccessException("Class " + currentType[0] - + " does not contain a field named '" + name + "'"); + final String name = mapper.realMember(currentType[0], reader.getNodeName()); + if (mapper.shouldSerializeMember(currentType[0], name)) { + final String classAttribute = HierarchicalStreams.readClassAttribute(reader, mapper); + Class type; + if (classAttribute != null) { + type = mapper.realClass(classAttribute); + } else { + final ObjectStreamField field = objectStreamClass.getField(name); + if (field == null) { + throw new MissingFieldException(currentType[0].getName(), name); + } + type = field.getType(); } - type = field.getType(); + final Object value = context.convertAnother(result, type); + fields.put(name, value); } - Object value = context.convertAnother(result, type); - result.put(name, value); reader.moveUp(); } } else { - throw new ConversionException("Expected <" + ELEMENT_FIELDS + "/> or <" + - ELEMENT_DEFAULT + "/> element when calling ObjectInputStream.readFields()"); + throw new ConversionException("Expected <" + + ELEMENT_FIELDS + + "/> or <" + + ELEMENT_DEFAULT + + "/> element when calling ObjectInputStream.readFields()"); } reader.moveUp(); - return result; + return fields; } + @Override public void defaultReadObject() { if (!reader.hasMoreChildren()) { return; @@ -318,57 +426,110 @@ while (reader.hasMoreChildren()) { reader.moveDown(); - Class type; - String fieldName = mapper.realMember(currentType[0], reader.getNodeName()); - String classAttribute = reader.getAttribute(ATTRIBUTE_CLASS); - if (classAttribute != null) { - type = mapper.realClass(classAttribute); - } else { - type = mapper.defaultImplementationOf(reflectionProvider.getFieldType(result, fieldName, currentType[0])); + final String fieldName = mapper.realMember(currentType[0], reader.getNodeName()); + if (mapper.shouldSerializeMember(currentType[0], fieldName)) { + final 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])); + } + + final Object value = context.convertAnother(result, type); + reflectionProvider.writeField(result, fieldName, value, 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) { + @Override + public void registerValidation(final ObjectInputValidation validation, final int priority) { context.addCompletionCallback(new Runnable() { + @Override public void run() { try { validation.validateObject(); - } catch (InvalidObjectException e) { + } catch (final InvalidObjectException e) { throw new ObjectAccessException("Cannot validate object : " + e.getMessage(), e); } } }, priority); } + @Override public void close() { - throw new UnsupportedOperationException("Objects are not allowed to call ObjectInputStream.close() from readObject()"); + throw new UnsupportedOperationException( + "Objects are not allowed to call ObjectInputStream.close() from readObject()"); } }; while (reader.hasMoreChildren()) { reader.moveDown(); - currentType[0] = mapper.defaultImplementationOf(mapper.realClass(reader.getNodeName())); - if (serializationMethodInvoker.supportsReadObject(currentType[0], false)) { - ObjectInputStream objectInputStream = CustomObjectInputStream.getInstance(context, callback); - serializationMethodInvoker.callReadObject(currentType[0], result, objectInputStream); + final String nodeName = reader.getNodeName(); + if (nodeName.equals(ELEMENT_UNSERIALIZABLE_PARENTS)) { + super.doUnmarshal(result, reader, context); } else { - try { - callback.defaultReadObject(); - } catch (IOException e) { - throw new ObjectAccessException("Could not call defaultWriteObject()", e); + final String classAttribute = HierarchicalStreams.readClassAttribute(reader, mapper); + if (classAttribute == null) { + currentType[0] = mapper.defaultImplementationOf(mapper.realClass(nodeName)); + } else { + currentType[0] = mapper.realClass(classAttribute); } + if (serializationMethodInvoker.supportsReadObject(currentType[0], false)) { + @SuppressWarnings("resource") + final CustomObjectInputStream objectInputStream = CustomObjectInputStream.getInstance(context, + callback, classLoaderReference); + serializationMethodInvoker.callReadObject(currentType[0], result, objectInputStream); + objectInputStream.popCallback(); + } else { + try { + callback.defaultReadObject(); + } catch (final IOException e) { + throw new ObjectAccessException("Could not call defaultWriteObject()", e); + } + } } reader.moveUp(); } - return serializationMethodInvoker.callReadResolve(result); + 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); + } + + @Override + public void visitSerializableFields(final Object object, final Visitor visitor) { + wrapped.visitSerializableFields(object, new Visitor() { + @Override + public void visit(final String name, final Class type, final Class definedIn, final Object value) { + if (!Serializable.class.isAssignableFrom(definedIn)) { + visitor.visit(name, type, definedIn, value); + } + } + }); + } + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/SerializationMethodInvoker.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/SerializationMethodInvoker.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/SerializationMethodInvoker.java 10 Sep 2012 19:03:03 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/SerializationMethodInvoker.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,128 +1,159 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 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 23. August 2004 by Joe Walnes + */ package com.thoughtworks.xstream.converters.reflection; -import com.thoughtworks.xstream.converters.ConversionException; - +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.Map; -import java.util.HashMap; +import java.util.Arrays; import java.util.Collections; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; +import java.util.HashMap; +import java.util.Map; +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.core.Caching; +import com.thoughtworks.xstream.core.util.FastField; + + /** * Convenience wrapper to invoke special serialization methods on objects (and perform reflection caching). - * + * * @author Joe Walnes + * @author Jörg Schaible */ -public class SerializationMethodInvoker { +public class SerializationMethodInvoker implements Caching { - private Map cache = Collections.synchronizedMap(new HashMap()); - private static final Object NO_METHOD = new Object(); - private static final Object[] EMPTY_ARGS = new Object[0]; + private static final Method NO_METHOD = new Object() { + @SuppressWarnings("unused") + private void noMethod() { + } + }.getClass().getDeclaredMethods()[0]; + private static final FastField[] OBJECT_TYPE_FIELDS = new FastField[]{ + new FastField(Object.class, "readResolve"), new FastField(Object.class, "writeReplace"), + new FastField(Object.class, "readObject"), new FastField(Object.class, "writeObject")}; + private final Map cache = Collections.synchronizedMap(new HashMap()); + { + for (final FastField element : OBJECT_TYPE_FIELDS) { + cache.put(element, NO_METHOD); + } + } /** * Resolves an object as native serialization does by calling readResolve(), if available. */ - public Object callReadResolve(Object result) { + public Object callReadResolve(final Object result) { if (result == null) { return null; } else { - Method readResolveMethod = getMethod(result.getClass(), "readResolve", null, true); + final Method readResolveMethod = getMethod(result.getClass(), "readResolve", true); if (readResolveMethod != null) { try { - return readResolveMethod.invoke(result, EMPTY_ARGS); - } catch (IllegalAccessException e) { - throw new ObjectAccessException("Could not call " + result.getClass().getName() + ".readResolve()", e); - } catch (InvocationTargetException e) { - throw new ObjectAccessException("Could not call " + result.getClass().getName() + ".readResolve()", e); + return readResolveMethod.invoke(result); + } catch (final IllegalAccessException e) { + throw new ObjectAccessException("Could not call " + result.getClass().getName() + ".readResolve()", + e); + } catch (final InvocationTargetException e) { + throw new ObjectAccessException("Could not call " + result.getClass().getName() + ".readResolve()", + e.getTargetException()); } } else { return result; } } } - public Object callWriteReplace(Object object) { + public Object callWriteReplace(final Object object) { if (object == null) { return null; } else { - Method writeReplaceMethod = getMethod(object.getClass(), "writeReplace", null, true); + final Method writeReplaceMethod = getMethod(object.getClass(), "writeReplace", true); if (writeReplaceMethod != null) { try { - Object[] EMPTY_ARGS = new Object[0]; - return writeReplaceMethod.invoke(object, EMPTY_ARGS); - } catch (IllegalAccessException e) { - throw new ObjectAccessException("Could not call " + object.getClass().getName() + ".writeReplace()", e); - } catch (InvocationTargetException e) { - throw new ObjectAccessException("Could not call " + object.getClass().getName() + ".writeReplace()", e); + return writeReplaceMethod.invoke(object); + } catch (final IllegalAccessException e) { + throw new ObjectAccessException( + "Could not call " + object.getClass().getName() + ".writeReplace()", e); + } catch (final InvocationTargetException e) { + throw new ObjectAccessException( + "Could not call " + object.getClass().getName() + ".writeReplace()", e.getTargetException()); } } else { return object; } } } - public boolean supportsReadObject(Class type, boolean includeBaseClasses) { - return getMethod(type, "readObject", new Class[]{ObjectInputStream.class}, includeBaseClasses) != null; + public boolean supportsReadObject(final Class type, final boolean includeBaseClasses) { + return getMethod(type, "readObject", includeBaseClasses, ObjectInputStream.class) != null; } - public void callReadObject(Class type, Object object, ObjectInputStream stream) { + 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) { + final Method readObjectMethod = getMethod(type, "readObject", false, ObjectInputStream.class); + readObjectMethod.invoke(object, stream); + } catch (final 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); + } catch (final InvocationTargetException e) { + throw new ConversionException("Could not call " + object.getClass().getName() + ".readObject()", e + .getTargetException()); } } - public boolean supportsWriteObject(Class type, boolean includeBaseClasses) { - return getMethod(type, "writeObject", new Class[]{ObjectOutputStream.class}, includeBaseClasses) != null; + public boolean supportsWriteObject(final Class type, final boolean includeBaseClasses) { + return getMethod(type, "writeObject", includeBaseClasses, ObjectOutputStream.class) != null; } - public void callWriteObject(Class type, Object instance, ObjectOutputStream stream) { + 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) { + final Method readObjectMethod = getMethod(type, "writeObject", false, ObjectOutputStream.class); + readObjectMethod.invoke(instance, stream); + } catch (final 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); + } catch (final 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) { - Object key = type.getName() + "." + name + "." + includeBaseclasses; - if (cache.containsKey(key)) { - Object result = cache.get(key); - return (Method) (result == NO_METHOD ? null : result); + private Method getMethod(final Class type, final String name, final boolean includeBaseclasses, + final Class... parameterTypes) { + final Method method = getMethod(type, name, parameterTypes); + return method == NO_METHOD || !includeBaseclasses && !method.getDeclaringClass().equals(type) ? null : method; + } + + private Method getMethod(final Class type, final String name, final Class... parameterTypes) { + if (type == null) { + return null; } - if (includeBaseclasses) { - while (type != null) { - try { - Method result = type.getDeclaredMethod(name, parameterTypes); + final FastField method = new FastField(type, name); + Method result = cache.get(method); + + if (result == null) { + try { + result = type.getDeclaredMethod(name, parameterTypes); + if (!result.isAccessible()) { result.setAccessible(true); - cache.put(key, result); - return result; - } catch (NoSuchMethodException e) { - type = type.getSuperclass(); } + } catch (final NoSuchMethodException e) { + result = getMethod(type.getSuperclass(), name, parameterTypes); } - cache.put(key, NO_METHOD); - return null; - } else { - try { - Method result = type.getDeclaredMethod(name, parameterTypes); - result.setAccessible(true); - cache.put(key, result); - return result; - } catch (NoSuchMethodException e) { - cache.put(key, NO_METHOD); - return null; - } + cache.put(method, result); } + return result; } + @Override + public void flushCache() { + cache.keySet().retainAll(Arrays.asList(OBJECT_TYPE_FIELDS)); + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/SortableFieldKeySorter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/Sun14ReflectionProvider.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/Sun14ReflectionProvider.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/Sun14ReflectionProvider.java 10 Sep 2012 19:03:03 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/Sun14ReflectionProvider.java 10 Nov 2014 12:07:35 -0000 1.1.2.1 @@ -1,115 +1,45 @@ +/* + * 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; -import sun.misc.Unsafe; -import sun.reflect.ReflectionFactory; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.util.HashMap; -import java.util.Map; -import java.util.Collections; - /** - * 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. - * + * 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 upcoming use {@link SunUnsafeReflectionProvider} */ -public class Sun14ReflectionProvider extends PureJavaReflectionProvider { - - private final ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory(); - private Unsafe cachedUnsafe; - private final Map constructorCache = Collections.synchronizedMap(new HashMap()); - - private Unsafe getUnsafe() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { - if (cachedUnsafe != null) { - return cachedUnsafe; - } - Class objectStreamClass = Class.forName("java.io.ObjectStreamClass$FieldReflector"); - Field unsafeField = objectStreamClass.getDeclaredField("unsafe"); - unsafeField.setAccessible(true); - cachedUnsafe = (Unsafe) unsafeField.get(null); - return cachedUnsafe; +@Deprecated +public class Sun14ReflectionProvider extends SunUnsafeReflectionProvider { + /** + * @deprecated As of upcoming use {@link SunUnsafeReflectionProvider#SunUnsafeReflectionProvider()} + */ + @Deprecated + public Sun14ReflectionProvider() { + super(); } - public Object newInstance(Class type) { - try { - Constructor customConstructor = getMungedConstructor(type); - return customConstructor.newInstance(new Object[0]); - } catch (NoSuchMethodException e) { - throw new ObjectAccessException("Cannot construct " + type.getName(), e); - } catch (SecurityException e) { - throw new ObjectAccessException("Cannot construct " + type.getName(), e); - } catch (InstantiationException e) { - throw new ObjectAccessException("Cannot construct " + type.getName(), e); - } catch (IllegalAccessException e) { - throw new ObjectAccessException("Cannot construct " + type.getName(), e); - } catch (IllegalArgumentException e) { - throw new ObjectAccessException("Cannot construct " + type.getName(), e); - } catch (InvocationTargetException e) { - throw new ObjectAccessException("Cannot construct " + type.getName(), e); - } + /** + * @deprecated As of upcoming use {@link SunUnsafeReflectionProvider#SunUnsafeReflectionProvider(FieldDictionary)} + */ + @Deprecated + public Sun14ReflectionProvider(final FieldDictionary dic) { + super(dic); } - private Constructor getMungedConstructor(Class type) throws NoSuchMethodException { - if (!constructorCache.containsKey(type)) { - Constructor javaLangObjectConstructor = Object.class.getDeclaredConstructor(new Class[0]); - Constructor customConstructor = reflectionFactory.newConstructorForSerialization(type, javaLangObjectConstructor); - constructorCache.put(type, customConstructor); - } - return (Constructor) constructorCache.get(type); + private Object readResolve() { + init(); + return this; } - - 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) { - try { - Unsafe unsafe = getUnsafe(); - long offset = unsafe.objectFieldOffset(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); - } catch (IllegalAccessException e) { - throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), e); - } catch (NoSuchFieldException e) { - throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), e); - } catch (ClassNotFoundException e) { - throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), e); - } - } - - protected void validateFieldAccess(Field field) { - // (overriden) don't mind final fields. - } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/SunLimitedUnsafeReflectionProvider.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/SunUnsafeReflectionProvider.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/converters/reflection/XStream12FieldKeySorter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/AbstractReferenceMarshaller.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/AbstractReferenceUnmarshaller.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/AbstractTreeMarshallingStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/BaseException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/Caching.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/ClassLoaderReference.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/DefaultClassMapper.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/DefaultConverterLookup.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/DefaultConverterLookup.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/DefaultConverterLookup.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/DefaultConverterLookup.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,55 +1,82 @@ +/* + * Copyright (C) 2004, 2005, 2006 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 07. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.core; -import com.thoughtworks.xstream.alias.ClassMapper; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.WeakHashMap; + import com.thoughtworks.xstream.converters.ConversionException; import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.ConverterLookup; -import com.thoughtworks.xstream.converters.basic.NullConverter; +import com.thoughtworks.xstream.converters.ConverterRegistry; import com.thoughtworks.xstream.core.util.PrioritizedList; -import com.thoughtworks.xstream.XStream; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -public class DefaultConverterLookup implements ConverterLookup { +/** + * 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 final Converter nullConverter = new NullConverter(); - private final Map typeToConverterMap = Collections.synchronizedMap(new HashMap()); - private final ClassMapper classMapper; + private final PrioritizedList converters = new PrioritizedList(); + private transient Map, Converter> typeToConverterMap; - public DefaultConverterLookup(ClassMapper classMapper) { - this.classMapper = classMapper; + public DefaultConverterLookup() { + readResolve(); } - /** - * @deprecated As of 1.1.1 you can register Converters with priorities, making the need for a default converter redundant. - */ - public Converter defaultConverter() { - return (Converter) converters.firstOfLowestPriority(); - } - - public Converter lookupConverterForType(Class type) { - if (type == null) { - return nullConverter; + @Override + public Converter lookupConverterForType(final Class type) { + final Converter cachedConverter = typeToConverterMap.get(type); + if (cachedConverter != null) { + return cachedConverter; } - Converter cachedConverter = (Converter) typeToConverterMap.get(type); - if (cachedConverter != null) return cachedConverter; - Class mapType = classMapper.defaultImplementationOf(type); - Iterator iterator = converters.iterator(); - while (iterator.hasNext()) { - Converter converter = (Converter) iterator.next(); - if (converter.canConvert(mapType)) { - typeToConverterMap.put(type, converter); + for (final Converter converter : converters) { + if (converter.canConvert(type)) { return converter; } } throw new ConversionException("No converter specified for " + type); } - public void registerConverter(Converter converter, int priority) { + + @Override + public void registerConverter(final Converter converter, final int priority) { converters.add(converter, priority); + for (final Iterator> iter = typeToConverterMap.keySet().iterator(); iter.hasNext();) { + final Class type = iter.next(); + if (converter.canConvert(type)) { + iter.remove(); + } + } } + @Override + public void flushCache() { + typeToConverterMap.clear(); + for (final Converter converter : converters) { + if (converter instanceof Caching) { + ((Caching)converter).flushCache(); + } + } + } + + private Object readResolve() { + // TODO: Use ConcurrentMap + typeToConverterMap = Collections.synchronizedMap(new WeakHashMap, Converter>()); + return this; + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/JVM.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/JVM.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/JVM.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/JVM.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,97 +1,555 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 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 09. May 2004 by Joe Walnes + */ package com.thoughtworks.xstream.core; +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; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; + +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.security.AccessControlException; -public class JVM { +public class JVM implements Caching { private ReflectionProvider reflectionProvider; - private static final float majorJavaVersion = getMajorJavaVersion(System.getProperty("java.version")); + 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 canCreateDerivedObjectOutputStream; - static final float DEFAULT_JAVA_VERSION = 1.3f; - + 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 { + @SuppressWarnings("unused") + private Object o; + @SuppressWarnings("unused") + private char c; + @SuppressWarnings("unused") + private byte b; + @SuppressWarnings("unused") + private short s; + @SuppressWarnings("unused") + private int i; + @SuppressWarnings("unused") + private long l; + @SuppressWarnings("unused") + private float f; + @SuppressWarnings("unused") + private double d; + @SuppressWarnings("unused") + private boolean bool; + + Test() { + throw new UnsupportedOperationException(); + } + } + + static { + boolean test = true; + Object unsafe = null; + try { + final Class unsafeClass = Class.forName("sun.misc.Unsafe"); + final Field unsafeField = unsafeClass.getDeclaredField("theUnsafe"); + unsafeField.setAccessible(true); + unsafe = unsafeField.get(null); + final Method allocateInstance = unsafeClass.getDeclaredMethod("allocateInstance", new Class[]{Class.class}); + allocateInstance.setAccessible(true); + test = allocateInstance.invoke(unsafe, new Object[]{Test.class}) != null; + } catch (final Exception e) { + test = false; + } catch (final 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 { + final ReflectionProvider provider = DependencyInjectionFactory.newInstance(cls); + final 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 (final IncompatibleClassChangeError e) { + cls = null; + } catch (final ObjectAccessException e) { + cls = null; + } + if (cls == null) { + cls = loadClassForName("com.thoughtworks.xstream.converters.reflection.SunLimitedUnsafeReflectionProvider"); + } + type = cls; + } catch (final ObjectAccessException e) { + } + } + } + reflectionProviderType = type; + canWriteWithUnsafe = test; + final Comparator comparator = new Comparator() { + @Override + public int compare(final Object o1, final Object o2) { + throw new RuntimeException(); + } + }; + final SortedMap map = new PresortedMap(comparator); + map.put("one", null); + map.put("two", null); + try { + new TreeMap(comparator).putAll(map); + test = true; + } catch (final RuntimeException e) { + test = false; + } + optimizedTreeMapPutAll = test; + final SortedSet set = new PresortedSet(comparator); + set.addAll(map.keySet()); + try { + new TreeSet(comparator).addAll(set); + test = true; + } catch (final RuntimeException e) { + test = false; + } + optimizedTreeSetAddAll = test; + try { + new SimpleDateFormat("z").parse("UTC"); + test = true; + } catch (final ParseException e) { + test = false; + } + canParseUTCDateFormat = test; + try { + test = new CustomObjectOutputStream(null) != null; + } catch (final RuntimeException e) { + test = false; + } catch (final 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; + } + /** - * Parses the java version system property to determine the major java version, - * ie 1.x + * @deprecated As of 1.4.5 use the static methods of JVM. + */ + @Deprecated + public JVM() { + } + + /** + * Parses the java version system property to determine the major java version, i.e. 1.x * - * @param javaVersion the system property 'java.version' * @return A float of the form 1.x */ - static final float getMajorJavaVersion(String javaVersion) { - try { - return Float.parseFloat(javaVersion.substring(0, 3)); - } catch ( NumberFormatException e ){ + private static final float getMajorJavaVersion() { + try { + return isAndroid() ? 1.5f : Float.parseFloat(System.getProperty("java.specification.version")); + } catch (final 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 + */ + @Deprecated 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 + */ + @Deprecated public static boolean is15() { return majorJavaVersion >= 1.5f; } - private static boolean isSun() { - return System.getProperty("java.vm.vendor").indexOf("Sun") != -1; + /** + * @deprecated As of 1.4.4, minimal JDK version will be 1.6 for next major release + */ + @Deprecated + public static boolean is16() { + return majorJavaVersion >= 1.6f; } - private static boolean isApple() { - return System.getProperty("java.vm.vendor").indexOf("Apple") != -1; + /** + * @since 1.4 + */ + public static boolean is17() { + return majorJavaVersion >= 1.7f; } - private static boolean isHPUX() { - return System.getProperty("java.vm.vendor").indexOf("Hewlett-Packard Company") != -1; + /** + * @since 1.4 + */ + public static boolean is18() { + return majorJavaVersion >= 1.8f; } private static boolean isIBM() { - return System.getProperty("java.vm.vendor").indexOf("IBM") != -1; + return vendor.indexOf("IBM") != -1; } - private static boolean isBlackdown() { - return System.getProperty("java.vm.vendor").indexOf("Blackdown") != -1; + /** + * @since 1.4 + */ + private static boolean isAndroid() { + return vendor.indexOf("Android") != -1; } - private static boolean isBEA() { - return System.getProperty("java.vm.vendor").indexOf("BEA") != -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(final String name) { + return loadClassForName(name, true); } - public Class loadClass(String name) { + /** + * @deprecated As of 1.4.5 use {@link #loadClassForName(String)} + */ + @Deprecated + public Class loadClass(final 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(final String name, final boolean initialize) { try { - return Class.forName(name, false, getClass().getClassLoader()); - } catch (ClassNotFoundException e) { + @SuppressWarnings("unchecked") + final Class clazz = (Class)Class.forName(name, initialize, JVM.class + .getClassLoader()); + return clazz; + } catch (final LinkageError e) { return null; + } catch (final ClassNotFoundException e) { + return null; } } - + + /** + * @since 1.4.4 + * @deprecated As of 1.4.5 use {@link #loadClassForName(String, boolean)} + */ + @Deprecated + public Class loadClass(final String name, final boolean initialize) { + return loadClassForName(name, initialize); + } + + /** + * Create the best matching ReflectionProvider. + * + * @return a new instance + * @since 1.4.5 + */ + public static ReflectionProvider newReflectionProvider() { + return DependencyInjectionFactory.newInstance(reflectionProviderType); + } + + /** + * 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(final FieldDictionary dictionary) { + return DependencyInjectionFactory.newInstance(reflectionProviderType, 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 + */ + @SuppressWarnings("unchecked") + public static Class getStaxInputFactory() throws ClassNotFoundException { + if (is16()) { + if (isIBM()) { + return (Class)Class.forName("com.ibm.xml.xlxp.api.stax.XMLInputFactoryImpl"); + } else { + return (Class)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 + */ + @SuppressWarnings("unchecked") + public static Class getStaxOutputFactory() throws ClassNotFoundException { + if (is16()) { + if (isIBM()) { + return (Class)Class + .forName("com.ibm.xml.xlxp.api.stax.XMLOutputFactoryImpl"); + } else { + return (Class)Class + .forName("com.sun.xml.internal.stream.XMLOutputFactoryImpl"); + } + } + return null; + } + + /** + * @deprecated As of 1.4.5 use {@link #newReflectionProvider()} + */ + @Deprecated public synchronized ReflectionProvider bestReflectionProvider() { if (reflectionProvider == null) { - try { - if ( canUseSun14ReflectionProvider() ) { - String cls = "com.thoughtworks.xstream.converters.reflection.Sun14ReflectionProvider"; - reflectionProvider = (ReflectionProvider) loadClass(cls).newInstance(); - } else { - reflectionProvider = new PureJavaReflectionProvider(); - } - } catch (InstantiationException e) { - reflectionProvider = new PureJavaReflectionProvider(); - } catch (IllegalAccessException e) { - reflectionProvider = new PureJavaReflectionProvider(); - } catch (AccessControlException e) { - // thrown when trying to access sun.misc package in Applet context. - reflectionProvider = new PureJavaReflectionProvider(); - } + reflectionProvider = newReflectionProvider(); } return reflectionProvider; } - private boolean canUseSun14ReflectionProvider() { - return (isSun() || isApple() || isHPUX() || isIBM() || isBlackdown()) && is14() && loadClass("sun.misc.Unsafe") != null; - } + private static boolean canUseSunUnsafeReflectionProvider() { + return canAllocateWithUnsafe && is14(); + } + private static boolean canUseSunLimitedUnsafeReflectionProvider() { + return canWriteWithUnsafe; + } + + /** + * @deprecated As of 1.4.5 + */ + @Deprecated + 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()} + */ + @Deprecated + public boolean supportsAWT() { + return 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()} + */ + @Deprecated + public boolean supportsSwing() { + return 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()} + */ + @Deprecated + public boolean supportsSQL() { + return 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.6 + */ + public static boolean canCreateDerivedObjectOutputStream() { + return canCreateDerivedObjectOutputStream; + } + + /** + * @deprecated As of 1.4.5 no functionality + */ + @Deprecated + @Override + public void flushCache() { + } + + public static void main(final 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 (final ClassNotFoundException e) { + staxInputFactory = e.getMessage(); + } catch (final NullPointerException e) { + } + + String staxOutputFactory = null; + try { + staxOutputFactory = getStaxOutputFactory().getName(); + } catch (final ClassNotFoundException e) { + staxOutputFactory = e.getMessage(); + } catch (final 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); + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/MapBackedDataHolder.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/MapBackedDataHolder.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/MapBackedDataHolder.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/MapBackedDataHolder.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,32 +1,47 @@ +/* + * 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 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; +import com.thoughtworks.xstream.converters.DataHolder; + + public class MapBackedDataHolder implements DataHolder { - private final Map map; + private final Map map; public MapBackedDataHolder() { - this(new HashMap()); + this(new HashMap()); } - public MapBackedDataHolder(Map map) { + public MapBackedDataHolder(final Map map) { this.map = map; } - public Object get(Object key) { + @Override + public Object get(final Object key) { return map.get(key); } - public void put(Object key, Object value) { + @Override + public void put(final Object key, final Object value) { map.put(key, value); } - public Iterator keys() { + @Override + public Iterator keys() { return Collections.unmodifiableCollection(map.keySet()).iterator(); } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByIdMarshaller.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByIdMarshaller.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByIdMarshaller.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByIdMarshaller.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,51 +1,57 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 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 15. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.core; -import com.thoughtworks.xstream.alias.ClassMapper; -import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.ConverterLookup; -import com.thoughtworks.xstream.core.util.ObjectIdDictionary; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.path.Path; +import com.thoughtworks.xstream.mapper.Mapper; -public class ReferenceByIdMarshaller extends TreeMarshaller { - private ObjectIdDictionary references = new ObjectIdDictionary(); - private IDGenerator idGenerator; +public class ReferenceByIdMarshaller extends AbstractReferenceMarshaller { + private final IDGenerator idGenerator; + public static interface IDGenerator { - String next(); + String next(Object item); } - public ReferenceByIdMarshaller(HierarchicalStreamWriter writer, - ConverterLookup converterLookup, - ClassMapper classMapper, - IDGenerator idGenerator) { - super(writer, converterLookup, classMapper); + public ReferenceByIdMarshaller( + final HierarchicalStreamWriter writer, final ConverterLookup converterLookup, final Mapper mapper, + final IDGenerator idGenerator) { + super(writer, converterLookup, mapper); this.idGenerator = idGenerator; } - public ReferenceByIdMarshaller(HierarchicalStreamWriter writer, - ConverterLookup converterLookup, - ClassMapper classMapper) { - this(writer, converterLookup, classMapper, new SequenceGenerator(1)); + public ReferenceByIdMarshaller( + final HierarchicalStreamWriter writer, final ConverterLookup converterLookup, final Mapper mapper) { + this(writer, converterLookup, mapper, new SequenceGenerator(1)); } - public void convertAnother(Object item) { - Converter converter = converterLookup.lookupConverterForType(item.getClass()); + @Override + protected String createReference(final Path currentPath, final String existingReferenceKey) { + return existingReferenceKey.toString(); + } - if (classMapper.isImmutableValueType(item.getClass())) { - // strings, ints, dates, etc... don't bother using references. - converter.marshal(item, writer, this); - } else { - Object idOfExistingReference = references.lookupId(item); - if (idOfExistingReference != null) { - writer.addAttribute("reference", idOfExistingReference.toString()); - } else { - String newId = idGenerator.next(); - writer.addAttribute("id", newId); - references.associateId(item, newId); - converter.marshal(item, writer, this); - } - } + @Override + protected String createReferenceKey(final Path currentPath, final Object item) { + return idGenerator.next(item); } + @Override + protected void fireValidReference(final String referenceKey) { + final String attributeName = getMapper().aliasForSystemAttribute("id"); + if (attributeName != null) { + writer.addAttribute(attributeName, referenceKey.toString()); + } + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByIdMarshallingStrategy.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByIdMarshallingStrategy.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByIdMarshallingStrategy.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByIdMarshallingStrategy.java 10 Nov 2014 12:07:40 -0000 1.1.2.1 @@ -1,22 +1,33 @@ +/* + * Copyright (C) 2004, 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. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.core; -import com.thoughtworks.xstream.MarshallingStrategy; -import com.thoughtworks.xstream.alias.ClassMapper; -import com.thoughtworks.xstream.converters.DataHolder; +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 implements MarshallingStrategy { - public Object unmarshal(Object root, HierarchicalStreamReader reader, DataHolder dataHolder, DefaultConverterLookup converterLookup, ClassMapper classMapper) { - return new ReferenceByIdUnmarshaller( - root, reader, converterLookup, - classMapper).start(dataHolder); - } +public class ReferenceByIdMarshallingStrategy extends AbstractTreeMarshallingStrategy { - public void marshal(HierarchicalStreamWriter writer, Object obj, DefaultConverterLookup converterLookup, ClassMapper classMapper, DataHolder dataHolder) { - new ReferenceByIdMarshaller( - writer, converterLookup, classMapper).start(obj, dataHolder); + @Override + protected TreeUnmarshaller createUnmarshallingContext(final Object root, final HierarchicalStreamReader reader, + final ConverterLookup converterLookup, final Mapper mapper) { + return new ReferenceByIdUnmarshaller(root, reader, converterLookup, mapper); } + @Override + protected TreeMarshaller createMarshallingContext(final HierarchicalStreamWriter writer, + final ConverterLookup converterLookup, final Mapper mapper) { + return new ReferenceByIdMarshaller(writer, converterLookup, mapper); + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByIdUnmarshaller.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByIdUnmarshaller.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByIdUnmarshaller.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByIdUnmarshaller.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,41 +1,37 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 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 15. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.core; -import com.thoughtworks.xstream.alias.ClassMapper; 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; -import java.util.HashMap; -import java.util.Map; -public class ReferenceByIdUnmarshaller extends TreeUnmarshaller { +public class ReferenceByIdUnmarshaller extends AbstractReferenceUnmarshaller { - private Map values = new HashMap(); - private FastStack parentIdStack = new FastStack(16); - - public ReferenceByIdUnmarshaller(Object root, HierarchicalStreamReader reader, - ConverterLookup converterLookup, ClassMapper classMapper) { - super(root, reader, converterLookup, classMapper); + public ReferenceByIdUnmarshaller( + final Object root, final HierarchicalStreamReader reader, final ConverterLookup converterLookup, + final Mapper mapper) { + super(root, reader, converterLookup, mapper); } - public Object convertAnother(Object parent, Class type) { - if (parentIdStack.size() > 0) { // handles circular references - Object parentId = parentIdStack.peek(); - if (!values.containsKey(parentId)) { // see AbstractCircularReferenceTest.testWeirdCircularReference() - values.put(parentId, parent); - } - } - String reference = reader.getAttribute("reference"); - if (reference != null) { - return values.get(reference); - } else { - String currentId = reader.getAttribute("id"); - parentIdStack.push(currentId); - Object result = super.convertAnother(parent, type); - values.put(currentId, result); - parentIdStack.popSilently(); - return result; - } + @Override + protected String getReferenceKey(final String reference) { + return reference; } + @Override + protected String getCurrentReferenceKey() { + final String attributeName = getMapper().aliasForSystemAttribute("id"); + return attributeName == null ? null : reader.getAttribute(attributeName); + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByXPathMarshaller.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByXPathMarshaller.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByXPathMarshaller.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByXPathMarshaller.java 10 Nov 2014 12:07:40 -0000 1.1.2.1 @@ -1,41 +1,50 @@ +/* + * Copyright (C) 2004, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 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 03. April 2004 by Joe Walnes + */ package com.thoughtworks.xstream.core; -import com.thoughtworks.xstream.alias.ClassMapper; -import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.ConverterLookup; -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; -public class ReferenceByXPathMarshaller extends TreeMarshaller { - private PathTracker pathTracker = new PathTracker(); - private ObjectIdDictionary references = new ObjectIdDictionary(); +public class ReferenceByXPathMarshaller extends AbstractReferenceMarshaller { - public ReferenceByXPathMarshaller(HierarchicalStreamWriter writer, ConverterLookup converterLookup, ClassMapper classMapper) { - super(writer, converterLookup, classMapper); - this.writer = new PathTrackingWriter(writer, pathTracker); + private final int mode; + + public ReferenceByXPathMarshaller( + final HierarchicalStreamWriter writer, final ConverterLookup converterLookup, final Mapper mapper, + final int mode) { + super(writer, converterLookup, mapper); + this.mode = mode; } - public void convertAnother(Object item) { - Converter converter = converterLookup.lookupConverterForType(item.getClass()); + @Override + protected String createReference(final Path currentPath, final Path existingReferenceKey) { + final Path existingPath = existingReferenceKey; + final Path referencePath = (mode & ReferenceByXPathMarshallingStrategy.ABSOLUTE) > 0 + ? existingPath + : currentPath.relativeTo(existingPath); + return (mode & ReferenceByXPathMarshallingStrategy.SINGLE_NODE) > 0 ? referencePath.explicit() : referencePath + .toString(); + } - if (classMapper.isImmutableValueType(item.getClass())) { - // strings, ints, dates, etc... don't bother using references. - converter.marshal(item, writer, this); - } else { - Path currentPath = pathTracker.getPath(); - Path pathOfExistingReference = (Path) references.lookupId(item); - if (pathOfExistingReference != null) { - Path absolutePath = currentPath.relativeTo(pathOfExistingReference); - writer.addAttribute("reference", absolutePath.toString()); - } else { - references.associateId(item, currentPath); - converter.marshal(item, writer, this); - } - } + @Override + protected Path createReferenceKey(final Path currentPath, final Object item) { + return currentPath; } + @Override + protected void fireValidReference(final Path referenceKey) { + // nothing to do + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByXPathMarshallingStrategy.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByXPathMarshallingStrategy.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByXPathMarshallingStrategy.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByXPathMarshallingStrategy.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,19 +1,42 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 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 03. April 2004 by Joe Walnes + */ package com.thoughtworks.xstream.core; -import com.thoughtworks.xstream.MarshallingStrategy; -import com.thoughtworks.xstream.alias.ClassMapper; -import com.thoughtworks.xstream.converters.DataHolder; +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 implements MarshallingStrategy { - public Object unmarshal(Object root, HierarchicalStreamReader reader, DataHolder dataHolder, DefaultConverterLookup converterLookup, ClassMapper classMapper) { - return new ReferenceByXPathUnmarshaller(root, reader, converterLookup, - classMapper).start(dataHolder); +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(final int mode) { + this.mode = mode; } - public void marshal(HierarchicalStreamWriter writer, Object obj, DefaultConverterLookup converterLookup, ClassMapper classMapper, DataHolder dataHolder) { - new ReferenceByXPathMarshaller(writer, converterLookup, classMapper).start(obj, dataHolder); + @Override + protected TreeUnmarshaller createUnmarshallingContext(final Object root, final HierarchicalStreamReader reader, + final ConverterLookup converterLookup, final Mapper mapper) { + return new ReferenceByXPathUnmarshaller(root, reader, converterLookup, mapper); } + + @Override + protected TreeMarshaller createMarshallingContext(final HierarchicalStreamWriter writer, + final ConverterLookup converterLookup, final Mapper mapper) { + return new ReferenceByXPathMarshaller(writer, converterLookup, mapper, mode); + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByXPathUnmarshaller.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByXPathUnmarshaller.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByXPathUnmarshaller.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferenceByXPathUnmarshaller.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,46 +1,50 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 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 03. April 2004 by Joe Walnes + */ package com.thoughtworks.xstream.core; -import com.thoughtworks.xstream.alias.ClassMapper; import com.thoughtworks.xstream.converters.ConverterLookup; -import com.thoughtworks.xstream.core.util.FastStack; +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; -import java.util.HashMap; -import java.util.Map; -public class ReferenceByXPathUnmarshaller extends TreeUnmarshaller { +public class ReferenceByXPathUnmarshaller extends AbstractReferenceUnmarshaller { - private Map values = new HashMap(); - private FastStack parentPathStack = new FastStack(16); - private PathTracker pathTracker = new PathTracker(); + private final PathTracker pathTracker = new PathTracker(); + protected boolean isNameEncoding; - public ReferenceByXPathUnmarshaller(Object root, HierarchicalStreamReader reader, - ConverterLookup converterLookup, ClassMapper classMapper) { - super(root, reader, converterLookup, classMapper); + public ReferenceByXPathUnmarshaller( + final Object root, final HierarchicalStreamReader reader, final ConverterLookup converterLookup, + final Mapper mapper) { + super(root, reader, converterLookup, mapper); this.reader = new PathTrackingReader(reader, pathTracker); + isNameEncoding = reader.underlyingReader() instanceof AbstractReader; } - public Object convertAnother(Object parent, Class type) { - if (parentPathStack.size() > 0) { // handles circular references - Object parentPath = parentPathStack.peek(); - if (!values.containsKey(parentPath)) { // see AbstractCircularReferenceTest.testWeirdCircularReference() - values.put(parentPath, parent); - } - } - String relativePathOfReference = reader.getAttribute("reference"); - Path currentPath = pathTracker.getPath(); - if (relativePathOfReference != null) { - return values.get(currentPath.apply(new Path(relativePathOfReference))); - } else { - parentPathStack.push(currentPath); - Object result = super.convertAnother(parent, type); - values.put(currentPath, result); - parentPathStack.popSilently(); - return result; - } + @Override + protected Path getReferenceKey(final 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; } + @Override + protected Path getCurrentReferenceKey() { + return pathTracker.getPath(); + } + } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/ReferencingMarshallingContext.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/SequenceGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/SequenceGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/SequenceGenerator.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/SequenceGenerator.java 10 Nov 2014 12:07:40 -0000 1.1.2.1 @@ -1,14 +1,26 @@ +/* + * Copyright (C) 2004 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. 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 SequenceGenerator(final int startsAt) { + counter = startsAt; } - public String next() { + @Override + public String next(final Object item) { return String.valueOf(counter++); } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/TreeMarshaller.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/TreeMarshaller.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/TreeMarshaller.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/TreeMarshaller.java 10 Nov 2014 12:07:40 -0000 1.1.2.1 @@ -1,64 +1,103 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 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 15. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.core; -import com.thoughtworks.xstream.alias.ClassMapper; +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.MarshallingContext; import com.thoughtworks.xstream.core.util.ObjectIdDictionary; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; -import java.util.Iterator; public class TreeMarshaller implements MarshallingContext { protected HierarchicalStreamWriter writer; protected ConverterLookup converterLookup; - protected ClassMapper classMapper; - private ObjectIdDictionary parentObjects = new ObjectIdDictionary(); + private final Mapper mapper; + private final ObjectIdDictionary parentObjects = new ObjectIdDictionary(); private DataHolder dataHolder; - public TreeMarshaller(HierarchicalStreamWriter writer, - ConverterLookup converterLookup, - ClassMapper classMapper) { + public TreeMarshaller( + final HierarchicalStreamWriter writer, final ConverterLookup converterLookup, final Mapper mapper) { this.writer = writer; this.converterLookup = converterLookup; - this.classMapper = classMapper; + this.mapper = mapper; } - public void convertAnother(Object item) { + @Override + public void convertAnother(final Object item) { + convertAnother(item, null); + } + + @Override + public void convertAnother(final Object item, Converter converter) { + if (converter == null) { + converter = converterLookup.lookupConverterForType(item.getClass()); + } else { + if (!converter.canConvert(item.getClass())) { + final 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(final Object item, final Converter converter) { if (parentObjects.containsId(item)) { - throw new CircularReferenceException(); + final 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 converter = converterLookup.lookupConverterForType(item.getClass()); converter.marshal(item, writer, this); parentObjects.removeId(item); } - public void start(Object item, DataHolder dataHolder) { + public void start(final Object item, final DataHolder dataHolder) { this.dataHolder = dataHolder; if (item == null) { - writer.startNode(classMapper.serializedClass(ClassMapper.Null.class)); + writer.startNode(mapper.serializedClass(null)); writer.endNode(); } else { - writer.startNode(classMapper.serializedClass(item.getClass())); + ExtendedHierarchicalStreamWriterHelper.startNode(writer, mapper.serializedClass(item.getClass()), item + .getClass()); convertAnother(item); writer.endNode(); } } - public Object get(Object key) { + @Override + public Object get(final Object key) { lazilyCreateDataHolder(); return dataHolder.get(key); } - public void put(Object key, Object value) { + @Override + public void put(final Object key, final Object value) { lazilyCreateDataHolder(); dataHolder.put(key, value); } - public Iterator keys() { + @Override + public Iterator keys() { lazilyCreateDataHolder(); return dataHolder.keys(); } @@ -69,7 +108,14 @@ } } - public static class CircularReferenceException extends RuntimeException { + protected Mapper getMapper() { + return mapper; } + public static class CircularReferenceException extends ConversionException { + + public CircularReferenceException(final String msg) { + super(msg); + } + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/TreeMarshallingStrategy.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/TreeMarshallingStrategy.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/TreeMarshallingStrategy.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/TreeMarshallingStrategy.java 10 Nov 2014 12:07:40 -0000 1.1.2.1 @@ -1,21 +1,33 @@ +/* + * Copyright (C) 2004, 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. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.core; -import com.thoughtworks.xstream.MarshallingStrategy; -import com.thoughtworks.xstream.alias.ClassMapper; -import com.thoughtworks.xstream.converters.DataHolder; +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 implements MarshallingStrategy { - public Object unmarshal(Object root, HierarchicalStreamReader reader, DataHolder dataHolder, DefaultConverterLookup converterLookup, ClassMapper classMapper) { - return new TreeUnmarshaller( - root, reader, converterLookup, - classMapper).start(dataHolder); - } +public class TreeMarshallingStrategy extends AbstractTreeMarshallingStrategy { - public void marshal(HierarchicalStreamWriter writer, Object obj, DefaultConverterLookup converterLookup, ClassMapper classMapper, DataHolder dataHolder) { - new TreeMarshaller(writer, converterLookup, classMapper).start(obj, dataHolder); + @Override + protected TreeUnmarshaller createUnmarshallingContext(final Object root, final HierarchicalStreamReader reader, + final ConverterLookup converterLookup, final Mapper mapper) { + return new TreeUnmarshaller(root, reader, converterLookup, mapper); } + @Override + protected TreeMarshaller createMarshallingContext(final HierarchicalStreamWriter writer, + final ConverterLookup converterLookup, final Mapper mapper) { + return new TreeMarshaller(writer, converterLookup, mapper); + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/TreeUnmarshaller.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/TreeUnmarshaller.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/TreeUnmarshaller.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/TreeUnmarshaller.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,82 +1,131 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 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 15. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.core; -import com.thoughtworks.xstream.alias.ClassMapper; +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.ClassStack; +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; -import java.util.Iterator; public class TreeUnmarshaller implements UnmarshallingContext { - private Object root; + private final Object root; protected HierarchicalStreamReader reader; - private ConverterLookup converterLookup; - private ClassMapper classMapper; - private ClassStack types = new ClassStack(16); + private final ConverterLookup converterLookup; + private final Mapper mapper; + private final FastStack> types = new FastStack>(16); private DataHolder dataHolder; - private final PrioritizedList validationList = new PrioritizedList(); + private final PrioritizedList validationList = new PrioritizedList(); - public TreeUnmarshaller(Object root, HierarchicalStreamReader reader, - ConverterLookup converterLookup, ClassMapper classMapper) { + public TreeUnmarshaller( + final Object root, final HierarchicalStreamReader reader, final ConverterLookup converterLookup, + final Mapper mapper) { this.root = root; this.reader = reader; this.converterLookup = converterLookup; - this.classMapper = classMapper; + this.mapper = mapper; } - public Object convertAnother(Object parent, Class type) { + @Override + public Object convertAnother(final Object parent, final Class type) { + return convertAnother(parent, type, null); + } + + @Override + public Object convertAnother(final Object parent, Class type, Converter converter) { + type = mapper.defaultImplementationOf(type); + if (converter == null) { + converter = converterLookup.lookupConverterForType(type); + } else { + if (!converter.canConvert(type)) { + final 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(final Object parent, final Class type, final Converter converter) { try { - Converter converter = converterLookup.lookupConverterForType(type); - types.push(classMapper.defaultImplementationOf(type)); - Object result = converter.unmarshal(reader, this); + types.push(type); + final Object result = converter.unmarshal(reader, this); types.popSilently(); return result; - } catch (ConversionException conversionException) { - addInformationTo(conversionException, type); + } catch (final ConversionException conversionException) { + addInformationTo(conversionException, type, converter, parent); throw conversionException; - } catch (RuntimeException e) { - ConversionException conversionException = new ConversionException(e); - addInformationTo(conversionException, type); + } catch (final RuntimeException e) { + final ConversionException conversionException = new ConversionException(e); + addInformationTo(conversionException, type, converter, parent); throw conversionException; } } - private void addInformationTo(ErrorWriter errorWriter, Class type) { + private void addInformationTo(final ErrorWriter errorWriter, final Class type, final Converter converter, + final 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) { + @Override + public void addCompletionCallback(final Runnable work, final int priority) { validationList.add(work, priority); } + @Override public Object currentObject() { return types.size() == 1 ? root : null; } - public Class getRequiredType() { + @Override + public Class getRequiredType() { return types.peek(); } - public Object get(Object key) { + @Override + public Object get(final Object key) { lazilyCreateDataHolder(); return dataHolder.get(key); } - public void put(Object key, Object value) { + @Override + public void put(final Object key, final Object value) { lazilyCreateDataHolder(); dataHolder.put(key, value); } - public Iterator keys() { + @Override + public Iterator keys() { lazilyCreateDataHolder(); return dataHolder.keys(); } @@ -87,22 +136,18 @@ } } - public Object start(DataHolder dataHolder) { + public Object start(final DataHolder dataHolder) { this.dataHolder = dataHolder; - String classAttribute = reader.getAttribute(classMapper.attributeForImplementationClass()); - Class type; - if (classAttribute == null) { - type = classMapper.realClass(reader.getNodeName()); - } else { - type = classMapper.realClass(classAttribute); - } - Object result = convertAnother(root, type); - Iterator validations = validationList.iterator(); - while (validations.hasNext()) { - Runnable runnable = (Runnable) validations.next(); + final Class type = HierarchicalStreams.readClassType(reader, mapper); + final Object result = convertAnother(null, type); + for (final Runnable runnable : validationList) { runnable.run(); } return result; } + protected Mapper getMapper() { + return mapper; + } + } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/ArrayIterator.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/Base64Encoder.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/Base64Encoder.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/Base64Encoder.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/Base64Encoder.java 10 Nov 2014 12:07:37 -0000 1.1.2.1 @@ -1,3 +1,14 @@ +/* + * 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; Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/ClassLoaderReference.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/ClassLoaderReference.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/ClassLoaderReference.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/ClassLoaderReference.java 10 Nov 2014 12:07:37 -0000 1.1.2.1 @@ -1,29 +1,75 @@ +/* + * 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.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. - * + * 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 */ +@Deprecated public class ClassLoaderReference extends ClassLoader { - private ClassLoader reference; + private transient ClassLoader reference; - public ClassLoaderReference(ClassLoader reference) { + /** + * @deprecated As of 1.4.5 use + * {@link com.thoughtworks.xstream.core.ClassLoaderReference#ClassLoaderReference(ClassLoader)} instead + */ + @Deprecated + public ClassLoaderReference(final ClassLoader reference) { this.reference = reference; } - public Class loadClass(String name) throws ClassNotFoundException { + /** + * @deprecated As of 1.4.5 use {@link com.thoughtworks.xstream.core.ClassLoaderReference#getReference()} + * .loadClass(String) instead + */ + @Deprecated + @Override + public Class loadClass(final String name) throws ClassNotFoundException { return reference.loadClass(name); } + /** + * @deprecated As of 1.4.5 use {@link com.thoughtworks.xstream.core.ClassLoaderReference#getReference()} instead + */ + @Deprecated public ClassLoader getReference() { return reference; } - public void setReference(ClassLoader reference) { + /** + * @deprecated As of 1.4.5 use {@link com.thoughtworks.xstream.core.ClassLoaderReference#setReference(ClassLoader)} + * instead + */ + @Deprecated + public void setReference(final ClassLoader reference) { this.reference = reference; } + + private Object writeReplace() { + return new Replacement(); + } + + static class Replacement { + + private Object readResolve() { + return new ClassLoaderReference(new CompositeClassLoader()); + } + + }; } Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/ClassStack.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/Cloneables.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/CompositeClassLoader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/CompositeClassLoader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/CompositeClassLoader.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/CompositeClassLoader.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,10 +1,26 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 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 16. November 2004 by Joe Walnes + */ package com.thoughtworks.xstream.core.util; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Collections; 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. @@ -28,47 +44,103 @@ *
  • 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 { + final Method m = ClassLoader.class.getDeclaredMethod("registerAsParallelCapable"); + if (!m.isAccessible()) { + m.setAccessible(true); + } + m.invoke(null); + } catch (final Exception e) { + // ignore errors, JVM will synchronize class for Java 7 or higher + } + } + } - private final List classLoaders = Collections.synchronizedList(new ArrayList()); + private final ReferenceQueue queue = new ReferenceQueue(); + private final List> classLoaders = new ArrayList>(); public CompositeClassLoader() { - add(Object.class.getClassLoader()); // bootstrap loader. - add(getClass().getClassLoader()); // whichever classloader loaded this jar. + addInternal(Object.class.getClassLoader()); // bootstrap loader. + addInternal(getClass().getClassLoader()); // whichever classloader loaded this jar. } /** * Add a loader to the n * @param classLoader */ - public void add(ClassLoader classLoader) { + public synchronized void add(final ClassLoader classLoader) { + cleanup(); if (classLoader != null) { - classLoaders.add(0, classLoader); + addInternal(classLoader); } } - public Class loadClass(String name) throws ClassNotFoundException { - for (Iterator iterator = classLoaders.iterator(); iterator.hasNext();) { - ClassLoader classLoader = (ClassLoader) iterator.next(); + private void addInternal(final ClassLoader classLoader) { + WeakReference refClassLoader = null; + for (final Iterator> iterator = classLoaders.iterator(); iterator.hasNext();) { + final WeakReference ref = iterator.next(); + final ClassLoader cl = 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)); + } + + @Override + public Class loadClass(final String name) throws ClassNotFoundException { + final List copy = new ArrayList(classLoaders.size()); + synchronized(this) { + cleanup(); + for(final WeakReference ref : classLoaders) { + final ClassLoader cl = ref.get(); + if (cl != null) { + copy.add(cl); + } + } + } + + ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + for (final ClassLoader classLoader : copy) { + if (classLoader == contextClassLoader) { + contextClassLoader = null; + } try { return classLoader.loadClass(name); - } catch (ClassNotFoundException notFound) { + } catch (final 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. - ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); if (contextClassLoader != null) { return contextClassLoader.loadClass(name); } else { throw new ClassNotFoundException(name); } } + private void cleanup() { + Reference ref; + while ((ref = queue.poll()) != null) + { + classLoaders.remove(ref); + } + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/CustomObjectInputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/CustomObjectInputStream.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/CustomObjectInputStream.java 10 Sep 2012 19:03:03 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/CustomObjectInputStream.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,236 +1,358 @@ +/* + * 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 23. August 2004 by Joe Walnes + */ package com.thoughtworks.xstream.core.util; -import com.thoughtworks.xstream.converters.ConversionException; -import com.thoughtworks.xstream.converters.DataHolder; - 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 StreamCallback callback; + private final 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; + + Map readFieldsFromStream() throws IOException; + void defaultReadObject() throws IOException; - void registerValidation(ObjectInputValidation validation, int priority) throws NotActiveException, InvalidObjectException; + + void registerValidation(ObjectInputValidation validation, int priority) + throws NotActiveException, InvalidObjectException; + void close() throws IOException; } - public static synchronized CustomObjectInputStream getInstance(DataHolder whereFrom, CustomObjectInputStream.StreamCallback callback) { + /** + * @deprecated As of 1.4 use {@link #getInstance(DataHolder, StreamCallback, ClassLoader)} + */ + @Deprecated + public static CustomObjectInputStream getInstance(final DataHolder whereFrom, + final CustomObjectInputStream.StreamCallback callback) { + return getInstance(whereFrom, callback, (ClassLoader)null); + } + + /** + * @deprecated As of 1.4.5 use {@link #getInstance(DataHolder, StreamCallback, ClassLoaderReference)} + */ + @Deprecated + public static synchronized CustomObjectInputStream getInstance(final DataHolder whereFrom, + final CustomObjectInputStream.StreamCallback callback, final ClassLoader classLoader) { + return getInstance(whereFrom, callback, new ClassLoaderReference(classLoader)); + } + + public static synchronized CustomObjectInputStream getInstance(final DataHolder whereFrom, + final CustomObjectInputStream.StreamCallback callback, final ClassLoaderReference classLoaderReference) { try { - CustomObjectInputStream result = (CustomObjectInputStream) whereFrom.get(DATA_HOLDER_KEY); + CustomObjectInputStream result = (CustomObjectInputStream)whereFrom.get(DATA_HOLDER_KEY); if (result == null) { - result = new CustomObjectInputStream(callback); + result = new CustomObjectInputStream(callback, classLoaderReference); whereFrom.put(DATA_HOLDER_KEY, result); } else { - result.setCallback(callback); + result.pushCallback(callback); } return result; - } catch (IOException e) { + } catch (final 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(com.thoughtworks.xstream.converters.DataHolder, com.thoughtworks.xstream.core.util.CustomObjectInputStream.StreamCallback) + * 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) throws IOException, SecurityException { + public CustomObjectInputStream(final StreamCallback callback, final ClassLoaderReference classLoaderReference) + throws IOException, SecurityException { super(); - this.callback = callback; + callbacks.push(callback); + this.classLoaderReference = classLoaderReference; } /** + * @deprecated As of 1.4.5 use {@link #CustomObjectInputStream(StreamCallback, ClassLoaderReference)} + */ + @Deprecated + public CustomObjectInputStream(final StreamCallback callback, final ClassLoader classLoader) + throws IOException, SecurityException { + this(callback, new ClassLoaderReference(classLoader)); + } + + /** * Allows the CustomObjectInputStream (which is expensive to create) to be reused. */ - public void setCallback(StreamCallback callback) { - this.callback = callback; + public void pushCallback(final StreamCallback callback) { + callbacks.push(callback); } - public void defaultReadObject() throws IOException, ClassNotFoundException { - callback.defaultReadObject(); + public StreamCallback popCallback() { + return callbacks.pop(); } - protected Object readObjectOverride() throws IOException, ClassNotFoundException { - return callback.readFromStream(); + public StreamCallback peekCallback() { + return callbacks.peek(); } + @Override + protected Class resolveClass(final ObjectStreamClass desc) throws IOException, ClassNotFoundException { + final ClassLoader classLoader = classLoaderReference.getReference(); + if (classLoader == null) { + return super.resolveClass(desc); + } else { + return Class.forName(desc.getName(), false, classLoader); + } + } + + @Override + public void defaultReadObject() throws IOException { + peekCallback().defaultReadObject(); + } + + @Override + protected Object readObjectOverride() throws IOException { + return peekCallback().readFromStream(); + } + + @Override + public Object readUnshared() throws IOException, ClassNotFoundException { + return readObject(); + } + + @Override public boolean readBoolean() throws IOException { - return ((Boolean)callback.readFromStream()).booleanValue(); + return ((Boolean)peekCallback().readFromStream()).booleanValue(); } + @Override public byte readByte() throws IOException { - return ((Byte)callback.readFromStream()).byteValue(); + return ((Byte)peekCallback().readFromStream()).byteValue(); } + @Override + public int readUnsignedByte() throws IOException { + int b = ((Byte)peekCallback().readFromStream()).byteValue(); + if (b < 0) { + b += Byte.MAX_VALUE; + } + return b; + } + + @Override public int readInt() throws IOException { - return ((Integer)callback.readFromStream()).intValue(); + return ((Integer)peekCallback().readFromStream()).intValue(); } + @Override public char readChar() throws IOException { - return ((Character)callback.readFromStream()).charValue(); + return ((Character)peekCallback().readFromStream()).charValue(); } + @Override public float readFloat() throws IOException { - return ((Float)callback.readFromStream()).floatValue(); + return ((Float)peekCallback().readFromStream()).floatValue(); } + @Override public double readDouble() throws IOException { - return ((Double)callback.readFromStream()).doubleValue(); + return ((Double)peekCallback().readFromStream()).doubleValue(); } + @Override public long readLong() throws IOException { - return ((Long)callback.readFromStream()).longValue(); + return ((Long)peekCallback().readFromStream()).longValue(); } + @Override public short readShort() throws IOException { - return ((Short)callback.readFromStream()).shortValue(); + return ((Short)peekCallback().readFromStream()).shortValue(); } + @Override + public int readUnsignedShort() throws IOException { + int b = ((Short)peekCallback().readFromStream()).shortValue(); + if (b < 0) { + b += Short.MAX_VALUE; + } + return b; + } + + @Override public String readUTF() throws IOException { - return (String) callback.readFromStream(); + return (String)peekCallback().readFromStream(); } - public void readFully(byte[] buf) throws IOException { + @Override + public void readFully(final byte[] buf) throws IOException { readFully(buf, 0, buf.length); } - public void readFully(byte[] buf, int off, int len) throws IOException { - byte[] b = (byte[])callback.readFromStream(); + @Override + public void readFully(final byte[] buf, final int off, final int len) throws IOException { + final byte[] b = (byte[])peekCallback().readFromStream(); System.arraycopy(b, 0, buf, off, len); } - public GetField readFields() throws IOException, ClassNotFoundException { - return new CustomGetField(callback.readFieldsFromStream()); + @Override + public int read() throws IOException { + return readUnsignedByte(); } + @Override + public int read(final byte[] buf, final int off, final int len) throws IOException { + final 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; + } + + @Override + public int read(final byte b[]) throws IOException { + return read(b, 0, b.length); + } + + @Override + public GetField readFields() throws IOException { + return new CustomGetField(peekCallback().readFieldsFromStream()); + } + private class CustomGetField extends GetField { - private Map fields; + private final Map fields; - public CustomGetField(Map fields) { + public CustomGetField(final Map fields) { this.fields = fields; } + @Override public ObjectStreamClass getObjectStreamClass() { throw new UnsupportedOperationException(); } - private Object get(String name) { + private Object get(final String name) { return fields.get(name); } - public boolean defaulted(String name) throws IOException { + @Override + public boolean defaulted(final String name) { return !fields.containsKey(name); } - public byte get(String name, byte val) throws IOException { + @Override + public byte get(final String name, final byte val) { return defaulted(name) ? val : ((Byte)get(name)).byteValue(); } - public char get(String name, char val) throws IOException { + @Override + public char get(final String name, final char val) { return defaulted(name) ? val : ((Character)get(name)).charValue(); } - public double get(String name, double val) throws IOException { + @Override + public double get(final String name, final double val) { return defaulted(name) ? val : ((Double)get(name)).doubleValue(); } - public float get(String name, float val) throws IOException { + @Override + public float get(final String name, final float val) { return defaulted(name) ? val : ((Float)get(name)).floatValue(); } - public int get(String name, int val) throws IOException { + @Override + public int get(final String name, final int val) { return defaulted(name) ? val : ((Integer)get(name)).intValue(); } - public long get(String name, long val) throws IOException { + @Override + public long get(final String name, final long val) { return defaulted(name) ? val : ((Long)get(name)).longValue(); } - public short get(String name, short val) throws IOException { + @Override + public short get(final String name, final short val) { return defaulted(name) ? val : ((Short)get(name)).shortValue(); } - public boolean get(String name, boolean val) throws IOException { + @Override + public boolean get(final String name, final boolean val) { return defaulted(name) ? val : ((Boolean)get(name)).booleanValue(); } - public Object get(String name, Object val) throws IOException { + @Override + public Object get(final String name, final Object val) { return defaulted(name) ? val : get(name); } } - public void registerValidation(ObjectInputValidation validation, int priority) throws NotActiveException, InvalidObjectException { - callback.registerValidation(validation, priority); + @Override + public void registerValidation(final ObjectInputValidation validation, final int priority) + throws NotActiveException, InvalidObjectException { + peekCallback().registerValidation(validation, priority); } - /****** Unsupported methods ******/ - - public int available() throws IOException { - throw new UnsupportedOperationException(); - } - + @Override public void close() throws IOException { - callback.close(); + peekCallback().close(); } - public int readUnsignedByte() throws IOException { - throw new UnsupportedOperationException(); - } + /****** Unsupported methods ******/ - public String readLine() throws IOException { + @Override + public int available() { throw new UnsupportedOperationException(); } - public Object readUnshared() throws IOException, ClassNotFoundException { + @Override + public String readLine() { throw new UnsupportedOperationException(); } - public int readUnsignedShort() throws IOException { + @Override + public int skipBytes(final int len) { throw new UnsupportedOperationException(); } - public int read() throws IOException { + @Override + public long skip(final long n) { throw new UnsupportedOperationException(); } - public int read(byte[] buf, int off, int len) throws IOException { + @Override + public synchronized void mark(final int readlimit) { throw new UnsupportedOperationException(); } - public int skipBytes(int len) throws IOException { + @Override + public synchronized void reset() { throw new UnsupportedOperationException(); } - public int read(byte b[]) throws IOException { - throw new UnsupportedOperationException(); - } - - public long skip(long n) throws IOException { - throw new UnsupportedOperationException(); - } - - public void mark(int readlimit) { - throw new UnsupportedOperationException(); - } - - public void reset() throws IOException { - throw new UnsupportedOperationException(); - } - + @Override public boolean markSupported() { return false; } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/CustomObjectOutputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/CustomObjectOutputStream.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/CustomObjectOutputStream.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/CustomObjectOutputStream.java 10 Nov 2014 12:07:37 -0000 1.1.2.1 @@ -1,209 +1,268 @@ +/* + * Copyright (C) 2004, 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 23. August 2004 by Joe Walnes + */ package com.thoughtworks.xstream.core.util; -import com.thoughtworks.xstream.converters.ConversionException; -import com.thoughtworks.xstream.converters.DataHolder; - import java.io.IOException; -import java.io.ObjectOutputStream; import java.io.ObjectOutput; +import java.io.ObjectOutputStream; +import java.util.LinkedHashMap; import java.util.Map; -import java.util.HashMap; +import com.thoughtworks.xstream.converters.ConversionException; +import com.thoughtworks.xstream.converters.DataHolder; + + public class CustomObjectOutputStream extends ObjectOutputStream { - private StreamCallback callback; - private FastStack customFields = new FastStack(1); + private final FastStack callbacks = new FastStack(1); + private final FastStack customFields = new FastStack(1); private static final String DATA_HOLDER_KEY = CustomObjectOutputStream.class.getName(); - public static synchronized CustomObjectOutputStream getInstance(DataHolder whereFrom, StreamCallback callback) { + public static synchronized CustomObjectOutputStream getInstance(final DataHolder whereFrom, + final StreamCallback callback) { try { - CustomObjectOutputStream result = (CustomObjectOutputStream) whereFrom.get(DATA_HOLDER_KEY); + CustomObjectOutputStream result = (CustomObjectOutputStream)whereFrom.get(DATA_HOLDER_KEY); if (result == null) { result = new CustomObjectOutputStream(callback); whereFrom.put(DATA_HOLDER_KEY, result); } else { - result.setCallback(callback); + result.pushCallback(callback); } return result; - } catch (IOException e) { + } catch (final 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 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) + * 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.callback = callback; + public CustomObjectOutputStream(final StreamCallback callback) throws IOException, SecurityException { + callbacks.push(callback); } /** * Allows the CustomObjectOutputStream (which is expensive to create) to be reused. */ - public void setCallback(StreamCallback callback) { - this.callback = callback; + public void pushCallback(final StreamCallback callback) { + callbacks.push(callback); } + public StreamCallback popCallback() { + return callbacks.pop(); + } + + public StreamCallback peekCallback() { + return callbacks.peek(); + } + /*** Methods to delegate to callback ***/ + @Override public void defaultWriteObject() throws IOException { - callback.defaultWriteObject(); + peekCallback().defaultWriteObject(); } - protected void writeObjectOverride(Object obj) throws IOException { - callback.writeToStream(obj); + @Override + protected void writeObjectOverride(final Object obj) throws IOException { + peekCallback().writeToStream(obj); } - public void writeBoolean(boolean val) throws IOException { - callback.writeToStream(val ? Boolean.TRUE : Boolean.FALSE); // JDK 1.3 friendly + @Override + public void writeBoolean(final boolean val) throws IOException { + peekCallback().writeToStream(Boolean.valueOf(val)); } - public void writeByte(int val) throws IOException { - callback.writeToStream(new Byte((byte) val)); + @Override + public void writeByte(final int val) throws IOException { + peekCallback().writeToStream(Byte.valueOf((byte)val)); } - public void writeInt(int val) throws IOException { - callback.writeToStream(new Integer(val)); + @Override + public void writeInt(final int val) throws IOException { + peekCallback().writeToStream(Integer.valueOf(val)); } - public void writeChar(int val) throws IOException { - callback.writeToStream(new Character((char)val)); + @Override + public void writeChar(final int val) throws IOException { + peekCallback().writeToStream(Character.valueOf((char)val)); } - public void writeDouble(double val) throws IOException { - callback.writeToStream(new Double(val)); + @Override + public void writeDouble(final double val) throws IOException { + peekCallback().writeToStream(Double.valueOf(val)); } - public void writeFloat(float val) throws IOException { - callback.writeToStream(new Float(val)); + @Override + public void writeFloat(final float val) throws IOException { + peekCallback().writeToStream(Float.valueOf(val)); } - public void writeLong(long val) throws IOException { - callback.writeToStream(new Long(val)); + @Override + public void writeLong(final long val) throws IOException { + peekCallback().writeToStream(Long.valueOf(val)); } - public void writeShort(int val) throws IOException { - callback.writeToStream(new Short((short) val)); + @Override + public void writeShort(final int val) throws IOException { + peekCallback().writeToStream(Short.valueOf((short)val)); } - public void write(byte[] buf) throws IOException { - callback.writeToStream(buf); + @Override + public void write(final byte[] buf) throws IOException { + peekCallback().writeToStream(buf); } - public void writeChars(String str) throws IOException { - callback.writeToStream(str.toCharArray()); + @Override + public void writeChars(final String str) throws IOException { + peekCallback().writeToStream(str.toCharArray()); } - public void writeUTF(String str) throws IOException { - callback.writeToStream(str); + @Override + public void writeUTF(final String str) throws IOException { + peekCallback().writeToStream(str); } - public void write(int val) throws IOException { - callback.writeToStream(new Byte((byte) val)); + @Override + public void write(final int val) throws IOException { + peekCallback().writeToStream(Byte.valueOf((byte)val)); } - public void write(byte[] buf, int off, int len) throws IOException { - byte[] b = new byte[len]; + @Override + public void write(final byte[] buf, final int off, final int len) throws IOException { + final byte[] b = new byte[len]; System.arraycopy(buf, off, b, 0, len); - callback.writeToStream(b); + peekCallback().writeToStream(b); } + @Override public void flush() throws IOException { - callback.flush(); + peekCallback().flush(); } + @Override public void close() throws IOException { - callback.close(); + peekCallback().close(); } - public PutField putFields() throws IOException { - CustomPutField result = new CustomPutField(); + @Override + public PutField putFields() { + final CustomPutField result = new CustomPutField(); customFields.push(result); return result; } + @Override public void writeFields() throws IOException { - CustomPutField customPutField = (CustomPutField) customFields.pop(); - callback.writeFieldsToStream(customPutField.asMap()); + final CustomPutField customPutField = customFields.pop(); + peekCallback().writeFieldsToStream(customPutField.asMap()); } private class CustomPutField extends PutField { - private final Map fields = new OrderRetainingMap(); + private final Map fields = new LinkedHashMap(); - public Map asMap() { + public Map asMap() { return fields; } - public void write(ObjectOutput out) throws IOException { - callback.writeToStream(asMap()); + @Override + public void write(final ObjectOutput out) throws IOException { + peekCallback().writeToStream(asMap()); } - public void put(String name, Object val) { + @Override + public void put(final String name, final Object val) { fields.put(name, val); } - public void put(String name, byte val) { - put(name, new Byte(val)); + @Override + public void put(final String name, final byte val) { + put(name, Byte.valueOf(val)); } - public void put(String name, char val) { - put(name, new Character(val)); + @Override + public void put(final String name, final char val) { + put(name, Character.valueOf(val)); } - public void put(String name, double val) { - put(name, new Double(val)); + @Override + public void put(final String name, final double val) { + put(name, Double.valueOf(val)); } - public void put(String name, float val) { - put(name, new Float(val)); + @Override + public void put(final String name, final float val) { + put(name, Float.valueOf(val)); } - public void put(String name, int val) { - put(name, new Integer(val)); + @Override + public void put(final String name, final int val) { + put(name, Integer.valueOf(val)); } - public void put(String name, long val) { - put(name, new Long(val)); + @Override + public void put(final String name, final long val) { + put(name, Long.valueOf(val)); } - public void put(String name, short val) { - put(name, new Short(val)); + @Override + public void put(final String name, final short val) { + put(name, Short.valueOf(val)); } - public void put(String name, boolean val) { - put(name, val ? Boolean.TRUE : Boolean.FALSE); // JDK 1.3 friendly + @Override + public void put(final String name, final boolean val) { + put(name, Boolean.valueOf(val)); } } /****** Unsupported methods ******/ - public void reset() throws IOException { + @Override + public void reset() { throw new UnsupportedOperationException(); } - public void useProtocolVersion(int version) throws IOException { + @Override + public void useProtocolVersion(final int version) { throw new UnsupportedOperationException(); } - public void writeBytes(String str) throws IOException { + @Override + public void writeBytes(final String str) { throw new UnsupportedOperationException(); } - public void writeUnshared(Object obj) throws IOException { + @Override + public void writeUnshared(final Object obj) { throw new UnsupportedOperationException(); } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/DependencyInjectionFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/FastField.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/FastStack.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/FastStack.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/FastStack.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/FastStack.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,15 +1,41 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 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 02. September 2004 by Joe Walnes + */ package com.thoughtworks.xstream.core.util; -public final class FastStack { +import java.util.Arrays; - private Object[] stack; + +/** + * An array-based stack implementation. + * + * @author Joe Walnes + * @author Jörg Schaible + */ +public final class FastStack { + + private T[] stack; private int pointer; - public FastStack(int initialCapacity) { - stack = new Object[initialCapacity]; + public FastStack(final int initialCapacity) { + @SuppressWarnings("unchecked") + final T[] array = getArray(initialCapacity); + stack = array; } - public Object push(Object value) { + private T[] getArray(final int capacity, final T... t) { + return Arrays.copyOf(t, capacity); + } + + public T push(final T value) { if (pointer + 1 >= stack.length) { resizeStack(stack.length * 2); } @@ -21,16 +47,26 @@ stack[--pointer] = null; } - public Object pop() { - final Object result = stack[--pointer]; - stack[pointer] = null; + public T pop() { + final T result = stack[--pointer]; + stack[pointer] = null; return result; } - public Object peek() { + public T peek() { return pointer == 0 ? null : stack[pointer - 1]; } + public Object replace(final T value) { + final T result = stack[pointer - 1]; + stack[pointer - 1] = value; + return result; + } + + public void replaceSilently(final T value) { + stack[pointer - 1] = value; + } + public int size() { return pointer; } @@ -39,18 +75,20 @@ return pointer > 0; } - public Object get(int i) { + public T get(final int i) { return stack[i]; } - private void resizeStack(int newCapacity) { - Object[] newStack = new Object[newCapacity]; - System.arraycopy(stack, 0, newStack, 0, Math.min(stack.length, newCapacity)); + private void resizeStack(final int newCapacity) { + @SuppressWarnings("unchecked") + final T[] newStack = getArray(newCapacity); + System.arraycopy(stack, 0, newStack, 0, Math.min(pointer, newCapacity)); stack = newStack; } + @Override public String toString() { - StringBuffer result = new StringBuffer("["); + final StringBuffer result = new StringBuffer("["); for (int i = 0; i < pointer; i++) { if (i > 0) { result.append(", "); Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/Fields.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/Fields.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/Fields.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/Fields.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,37 +1,89 @@ +/* + * Copyright (C) 2004 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 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 RuntimeExceptions. - * + * wraps exception in XStreamExceptions. + * * @author Joe Walnes + * @author Jörg Schaible */ public class Fields { - public static Field find(Class type, String name) { + public static Field locate(final Class definedIn, final Class fieldType, final boolean isStatic) { + Field field = null; try { - Field result = type.getDeclaredField(name); - result.setAccessible(true); + final Field[] fields = definedIn.getDeclaredFields(); + for (final Field field2 : fields) { + if (Modifier.isStatic(field2.getModifiers()) == isStatic) { + if (fieldType.isAssignableFrom(field2.getType())) { + field = field2; + } + } + } + if (field != null && !field.isAccessible()) { + field.setAccessible(true); + } + } catch (final SecurityException e) { + // active SecurityManager + } catch (final NoClassDefFoundError e) { + // restricted type in GAE + } + return field; + } + + public static Field find(final Class type, final String name) { + try { + final Field result = type.getDeclaredField(name); + if (!result.isAccessible()) { + result.setAccessible(true); + } return result; - } catch (NoSuchFieldException e) { - throw new RuntimeException("Could not access " + type.getName() + "." + name + " field"); + } catch (final NoSuchFieldException e) { + final String message = "Could not access " + type.getName() + "." + name + " field: " + e.getMessage(); + throw new IllegalArgumentException(message); + } catch (final NoClassDefFoundError e) { + final String message = "Could not access " + type.getName() + "." + name + " field: " + e.getMessage(); + throw new ObjectAccessException(message); } } - public static void write(Field field, Object instance, Object value) { + public static void write(final Field field, final Object instance, final Object value) { try { field.set(instance, value); - } catch (IllegalAccessException e) { - throw new RuntimeException("Could not write " + field.getType().getName() + "." + field.getName() + " field"); + } catch (final IllegalAccessException e) { + final String message = "Could not write " + field.getType().getName() + "." + field.getName() + " field"; + throw new ObjectAccessException(message, e); + } catch (final NoClassDefFoundError e) { + final String message = "Could not write " + field.getType().getName() + "." + field.getName() + " field"; + throw new ObjectAccessException(message, e); } } - public static Object read(Field field, Object instance) { + public static Object read(final Field field, final Object instance) { try { return field.get(instance); - } catch (IllegalAccessException e) { - throw new RuntimeException("Could not read " + field.getType().getName() + "." + field.getName() + " field"); + } catch (final IllegalAccessException e) { + final String message = "Could not read " + field.getType().getName() + "." + field.getName() + " field"; + throw new ObjectAccessException(message, e); + } catch (final NoClassDefFoundError e) { + final String message = "Could not read " + field.getType().getName() + "." + field.getName() + " field"; + throw new ObjectAccessException(message, e); } } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/HierarchicalStreams.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/IntQueue.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/ObjectIdDictionary.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/ObjectIdDictionary.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/ObjectIdDictionary.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/ObjectIdDictionary.java 10 Nov 2014 12:07:37 -0000 1.1.2.1 @@ -1,52 +1,134 @@ +/* + * Copyright (C) 2004 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 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 the same way as java.util.IdentityHashMap, but in JDK1.3 as well. + *

    + * 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 { +public class ObjectIdDictionary { - private Map map = new HashMap(); + private final Map map = new HashMap(); + private final ReferenceQueue queue = new ReferenceQueue(); - private static class IdWrapper { + private static interface Wrapper { + @Override + int hashCode(); + @Override + boolean equals(Object obj); + + @Override + String toString(); + + Object get(); + } + + private static class IdWrapper implements Wrapper { + private final Object obj; + private final int hashCode; - public IdWrapper(Object obj) { + public IdWrapper(final Object obj) { + hashCode = System.identityHashCode(obj); this.obj = obj; } + @Override public int hashCode() { - return System.identityHashCode(obj); + return hashCode; } - public boolean equals(Object other) { - return obj == ((IdWrapper)other).obj; + @Override + public boolean equals(final Object other) { + return obj == ((Wrapper)other).get(); } + @Override public String toString() { return obj.toString(); } + + @Override + public Object get() { + return obj; + } } - public void associateId(Object obj, Object id) { - map.put(new IdWrapper(obj), id); + private class WeakIdWrapper extends WeakReference implements Wrapper { + + private final int hashCode; + + public WeakIdWrapper(final Object obj) { + super(obj, queue); + hashCode = System.identityHashCode(obj); + } + + @Override + public int hashCode() { + return hashCode; + } + + @Override + public boolean equals(final Object other) { + return get() == ((Wrapper)other).get(); + } + + @Override + public String toString() { + final Object obj = get(); + return obj == null ? "(null)" : obj.toString(); + } } - public Object lookupId(Object obj) { - return map.get(new IdWrapper(obj)); + public void associateId(final Object obj, final E id) { + map.put(new WeakIdWrapper(obj), id); + cleanup(); } - public boolean containsId(Object item) { - return map.containsKey(new IdWrapper(item)); + public E lookupId(final Object obj) { + final E id = map.get(new IdWrapper(obj)); + return id; } - public void removeId(Object item) { + public boolean containsId(final Object item) { + final boolean b = map.containsKey(new IdWrapper(item)); + return b; + } + + public void removeId(final Object item) { map.remove(new IdWrapper(item)); + cleanup(); } + public int size() { + cleanup(); + return map.size(); + } + + @SuppressWarnings("unchecked") + private void cleanup() { + WeakIdWrapper wrapper; + while ((wrapper = (WeakIdWrapper)queue.poll()) != null) { + map.remove(wrapper); + } + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/OrderRetainingMap.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/OrderRetainingMap.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/OrderRetainingMap.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/OrderRetainingMap.java 10 Nov 2014 12:07:37 -0000 1.1.2.1 @@ -1,37 +1,101 @@ +/* + * 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.HashMap; -import java.util.List; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.Set; -import java.util.TreeSet; -public class OrderRetainingMap extends HashMap { - private Set keyOrder = new ArraySet(); - private List valueOrder = new ArrayList(); - - public Object put(Object key, Object value) { - keyOrder.add(key); - valueOrder.add(value); +/** + * @deprecated As of upcoming use {@link java.util.LinkedHashMap} + */ +@Deprecated +public class OrderRetainingMap extends HashMap { + + private final ArraySet keyOrder = new ArraySet(); + private final List valueOrder = new ArrayList(); + + public OrderRetainingMap() { + super(); + } + + public OrderRetainingMap(final Map m) { + super(); + putAll(m); + } + + @Override + public void putAll(final Map m) { + for (final Map.Entry entry : m.entrySet()) { + put(entry.getKey(), entry.getValue()); + } + } + + @Override + public V put(final K key, final V value) { + final 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 Collection values() { - return Collections.unmodifiableList(valueOrder); + @Override + public V remove(final Object key) { + final int idx = keyOrder.lastIndexOf(key); + if (idx != 0) { + keyOrder.remove(idx); + valueOrder.remove(idx); + } + return super.remove(key); } - public Set keySet() { - return Collections.unmodifiableSet(keyOrder); + @Override + public void clear() { + keyOrder.clear(); + valueOrder.clear(); + super.clear(); } - public Set entrySet() { - throw new UnsupportedOperationException(); + @Override + public Collection values() { + return Collections.unmodifiableList(valueOrder); } - private static class ArraySet extends ArrayList implements Set { + @Override + public Set keySet() { + return Collections.unmodifiableSet(keyOrder); } + @Override + public Set> entrySet() { + @SuppressWarnings("unchecked") + final Map.Entry[] entries = new Map.Entry[size()]; + for (final Map.Entry entry : super.entrySet()) { + entries[keyOrder.indexOf(entry.getKey())] = entry; + } + final Set> set = new ArraySet>(); + set.addAll(Arrays.asList(entries)); + return Collections.unmodifiableSet(set); + } + + private static class ArraySet extends ArrayList implements Set {} } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/Pool.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/PresortedMap.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/PresortedSet.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/Primitives.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/PrioritizedList.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/PrioritizedList.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/PrioritizedList.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/PrioritizedList.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,97 +1,106 @@ +/* + * Copyright (C) 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 06. February 2005 by Joe Walnes + */ package com.thoughtworks.xstream.core.util; -import com.thoughtworks.xstream.converters.Converter; - 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. - * + * 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 { +public class PrioritizedList implements Iterable { - /** - * Start of forward only linked list. Each item contains a value, priority and pointer to next item. - * The first item does not contain a value, rather just a pointer to the next real item. This makes - * the add() algorithm easier as there is no special case for adding to the beginning of the list. - */ - private final LinkedItem pointerToFirst = new LinkedItem(null, 0, null); - + private final Set> set = new TreeSet>(); private int lowestPriority = Integer.MAX_VALUE; + private int lastId = 0; - /** - * Add an item with a default priority of zero. - */ - public void add(Object item) { - add(item, 0); - } - - public void add(Object item, int priority) { - // Note: this is quite efficient if the client tends to add low priority items before high priority items - // as it will not have to iterate over much of the list. However for the other way round, maybe some - // optimizations can be made? -joe - LinkedItem current = pointerToFirst; - while(current.next != null && priority < current.next.priority) { - current = current.next; + public void add(final E item, final int priority) { + if (this.lowestPriority > priority) { + this.lowestPriority = priority; } - current.next = new LinkedItem(item, priority, current.next); - if (priority < lowestPriority) { - lowestPriority = priority; - } + this.set.add(new PrioritizedItem(item, priority, ++lastId)); } - public Iterator iterator() { - return new LinkedItemIterator(pointerToFirst.next); + @Override + public Iterator iterator() { + return new PrioritizedItemIterator(this.set.iterator()); } - public Object firstOfLowestPriority() { - for(LinkedItem current = pointerToFirst.next; current != null; current = current.next) { - if (current.priority == lowestPriority) { - return current.value; - } - } - return null; - } + private static class PrioritizedItem implements Comparable> { - private static class LinkedItem { - - final Object value; + final V value; final int priority; + final int id; - LinkedItem next; - - public LinkedItem(Object value, int priority, LinkedItem next) { + public PrioritizedItem(final V value, final int priority, final int id) { this.value = value; this.priority = priority; - this.next = next; + this.id = id; } + @Override + public int compareTo(final PrioritizedItem other) { + if (this.priority != other.priority) { + return other.priority - this.priority; + } + return other.id - this.id; + } + + @Override + public int hashCode() { + return Integer.valueOf(id).hashCode(); + } + + @Override + public boolean equals(final Object obj) { + if (!(obj instanceof PrioritizedItem)) { + return false; + } + @SuppressWarnings("unchecked") + final PrioritizedItem other = (PrioritizedItem)obj; + return this.id == other.id; + } + } - private static class LinkedItemIterator implements Iterator { + private static class PrioritizedItemIterator implements Iterator { - private LinkedItem current; + private final Iterator> iterator; - public LinkedItemIterator(LinkedItem current) { - this.current = current; + public PrioritizedItemIterator(final Iterator> iterator) { + this.iterator = iterator; } + @Override public void remove() { throw new UnsupportedOperationException(); } + @Override public boolean hasNext() { - return current != null; + return iterator.hasNext(); } - public Object next() { - Object result = current.value; - current = current.next; - return result; + @Override + public V next() { + return iterator.next().value; } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/QuickWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/QuickWriter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/QuickWriter.java 10 Sep 2012 19:03:02 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/QuickWriter.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,28 +1,40 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 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 07. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.core.util; -import com.thoughtworks.xstream.io.StreamException; - +import java.io.Closeable; import java.io.IOException; import java.io.Writer; -public class QuickWriter { +import com.thoughtworks.xstream.io.StreamException; + +public class QuickWriter implements Closeable { + private final Writer writer; - private char[] buffer; + private final char[] buffer; private int pointer; - public QuickWriter(Writer writer) { - this.writer = writer; - buffer = new char[1024]; + public QuickWriter(final Writer writer) { + this(writer, 1024); } - public QuickWriter(Writer writer, int bufferSize) { + public QuickWriter(final Writer writer, final int bufferSize) { this.writer = writer; buffer = new char[bufferSize]; } - public void write(String str) { - int len = str.length(); + public void write(final String str) { + final int len = str.length(); if (pointer + len >= buffer.length) { flush(); if (len > buffer.length) { @@ -34,15 +46,19 @@ pointer += len; } - public void write(char c) { + public void write(final 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; + public void write(final char[] c) { + final int len = c.length; if (pointer + len >= buffer.length) { flush(); if (len > buffer.length) { @@ -59,27 +75,37 @@ writer.write(buffer, 0, pointer); pointer = 0; writer.flush(); - } catch (IOException e) { + } catch (final IOException e) { throw new StreamException(e); } } + @Override public void close() { try { writer.write(buffer, 0, pointer); pointer = 0; writer.close(); - } catch (IOException e) { + } catch (final IOException e) { throw new StreamException(e); } } - private void raw(char[] c) { + private void raw(final char[] c) { try { writer.write(c); writer.flush(); - } catch (IOException e) { + } catch (final IOException e) { throw new StreamException(e); } } + + private void raw(final char c) { + try { + writer.write(c); + writer.flush(); + } catch (final IOException e) { + throw new StreamException(e); + } + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/SelfStreamingInstanceChecker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/ThreadSafePropertyEditor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/ThreadSafeSimpleDateFormat.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/TypedNull.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/WeakCache.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/core/util/XmlHeaderAwareReader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/AbstractDriver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/AbstractReader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/AbstractWriter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/AttributeNameIterator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/AttributeNameIterator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/AttributeNameIterator.java 10 Sep 2012 19:03:01 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/AttributeNameIterator.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,33 +1,48 @@ +/* + * 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 com.thoughtworks.xstream.io.HierarchicalStreamReader; - import java.util.Iterator; + /** * Provide an iterator over the attribute names of the current node of a reader. - * + * * @author Joe Walnes + * @deprecated As of upcoming, it is an internal helper class only */ -public class AttributeNameIterator implements Iterator { +@Deprecated +public class AttributeNameIterator implements Iterator { private int current; private final int count; private final HierarchicalStreamReader reader; - public AttributeNameIterator(HierarchicalStreamReader reader) { + public AttributeNameIterator(final HierarchicalStreamReader reader) { this.reader = reader; count = reader.getAttributeCount(); } + @Override public boolean hasNext() { return current < count; } - public Object next() { + @Override + public String next() { return reader.getAttributeName(current++); } + @Override public void remove() { throw new UnsupportedOperationException(); } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamReader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamWriter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/ExtendedHierarchicalStreamWriterHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/HierarchicalStreamDriver.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/HierarchicalStreamDriver.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/HierarchicalStreamDriver.java 10 Sep 2012 19:03:01 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/HierarchicalStreamDriver.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,24 +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.Reader; -import java.io.Writer; +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 XML parsers and writers to XStream. + * 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); - /** @since 1.2 */ + + /** + * 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); - /** @since 1.2 */ + /** + * 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); } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/HierarchicalStreamReader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/HierarchicalStreamReader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/HierarchicalStreamReader.java 10 Sep 2012 19:03:01 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/HierarchicalStreamReader.java 10 Nov 2014 12:07:39 -0000 1.1.2.1 @@ -1,21 +1,42 @@ +/* + * 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 07. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io; +import java.io.Closeable; +import java.util.Iterator; + +import com.thoughtworks.xstream.converters.ErrorReporter; import com.thoughtworks.xstream.converters.ErrorWriter; -import java.util.Iterator; /** * @author Joe Walnes */ -public interface HierarchicalStreamReader { +public interface HierarchicalStreamReader extends ErrorReporter, Closeable { /** * 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(); /** @@ -37,7 +58,7 @@ * Get the value of an attribute of the current node, by index. */ String getAttribute(int index); - + /** * Number of attributes in current node. */ @@ -49,46 +70,49 @@ String getAttributeName(int index); /** - * Names of attributes (as Strings). + * Names of attributes. */ - Iterator getAttributeNames(); + 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). + * If any errors are detected, allow the reader to add any additional information that can aid debugging (such as + * line numbers, XPath expressions, etc). */ + @Override void appendErrors(ErrorWriter errorWriter); /** * Close the reader, if necessary. */ + @Override 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.

    + *

    + * 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(); - /** - * @deprecated This method should not be used and is only provided for backwards compatability. - * As of XStream 1.1.1, you can use the {@link #underlyingReader()} method to get the underlying - * reader implementation and call implementation specific methods on that. - */ - Object peekUnderlyingNode(); - } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/HierarchicalStreamWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/HierarchicalStreamWriter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/HierarchicalStreamWriter.java 10 Sep 2012 19:03:01 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/HierarchicalStreamWriter.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,9 +1,23 @@ +/* + * Copyright (C) 2004, 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 07. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io; +import java.io.Closeable; + + /** * @author Joe Walnes */ -public interface HierarchicalStreamWriter { +public interface HierarchicalStreamWriter extends Closeable { void startNode(String name); @@ -24,25 +38,34 @@ /** * Close the writer, if necessary. */ + @Override 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.

    + *

    + * 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(); Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/ReaderWrapper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/ReaderWrapper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/ReaderWrapper.java 10 Sep 2012 19:03:01 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/ReaderWrapper.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,74 +1,103 @@ +/* + * Copyright (C) 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 10. April 2005 by Joe Walnes + */ package com.thoughtworks.xstream.io; +import java.util.Iterator; + 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 HierarchicalStreamReader { +public abstract class ReaderWrapper implements ExtendedHierarchicalStreamReader { protected HierarchicalStreamReader wrapped; - protected ReaderWrapper(HierarchicalStreamReader reader) { - this.wrapped = reader; + protected ReaderWrapper(final HierarchicalStreamReader reader) { + wrapped = reader; } + @Override public boolean hasMoreChildren() { return wrapped.hasMoreChildren(); } + @Override public void moveDown() { wrapped.moveDown(); } + @Override public void moveUp() { wrapped.moveUp(); } + @Override public String getNodeName() { return wrapped.getNodeName(); } + @Override public String getValue() { return wrapped.getValue(); } - public String getAttribute(String name) { + @Override + public String getAttribute(final String name) { return wrapped.getAttribute(name); } - public String getAttribute(int index) { + @Override + public String getAttribute(final int index) { return wrapped.getAttribute(index); } + @Override public int getAttributeCount() { return wrapped.getAttributeCount(); } - public String getAttributeName(int index) { + @Override + public String getAttributeName(final int index) { return wrapped.getAttributeName(index); } - public Iterator getAttributeNames() { + @Override + public Iterator getAttributeNames() { return wrapped.getAttributeNames(); } - public Object peekUnderlyingNode() { - return wrapped.peekUnderlyingNode(); - } - - public void appendErrors(ErrorWriter errorWriter) { + @Override + public void appendErrors(final ErrorWriter errorWriter) { wrapped.appendErrors(errorWriter); } + @Override public void close() { wrapped.close(); } + @Override + public String peekNextChild() { + if (!(wrapped instanceof ExtendedHierarchicalStreamReader)) { + throw new UnsupportedOperationException("peekNextChild"); + } + return ((ExtendedHierarchicalStreamReader)wrapped).peekNextChild(); + } + + @Override public HierarchicalStreamReader underlyingReader() { return wrapped.underlyingReader(); } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/StatefulWriter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/StreamException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/StreamException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/StreamException.java 10 Sep 2012 19:03:01 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/StreamException.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,9 +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.core.BaseException; +import com.thoughtworks.xstream.XStreamException; -public class StreamException extends BaseException { +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); + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/WriterWrapper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/WriterWrapper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/WriterWrapper.java 10 Sep 2012 19:03:01 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/WriterWrapper.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,42 +1,66 @@ +/* + * 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 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 HierarchicalStreamWriter { +public abstract class WriterWrapper implements ExtendedHierarchicalStreamWriter { protected HierarchicalStreamWriter wrapped; - protected WriterWrapper(HierarchicalStreamWriter wrapped) { + protected WriterWrapper(final HierarchicalStreamWriter wrapped) { this.wrapped = wrapped; } - public void startNode(String name) { + @Override + public void startNode(final String name) { wrapped.startNode(name); } + @Override + public void startNode(final String name, final Class clazz) { + + ((ExtendedHierarchicalStreamWriter)wrapped).startNode(name, clazz); + } + + @Override public void endNode() { wrapped.endNode(); } - public void addAttribute(String key, String value) { + @Override + public void addAttribute(final String key, final String value) { wrapped.addAttribute(key, value); } - public void setValue(String text) { + @Override + public void setValue(final String text) { wrapped.setValue(text); } + @Override public void flush() { wrapped.flush(); } + @Override public void close() { wrapped.close(); } + @Override public HierarchicalStreamWriter underlyingWriter() { return wrapped.underlyingWriter(); } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/binary/BinaryStreamDriver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/binary/BinaryStreamReader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/binary/BinaryStreamWriter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/binary/ReaderDepthState.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/binary/Token.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/copy/HierarchicalStreamCopier.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/json/AbstractJsonWriter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/json/JettisonMappedXmlDriver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/json/JettisonStaxWriter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/json/JsonHierarchicalStreamDriver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/json/JsonHierarchicalStreamWriter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/json/JsonWriter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/naming/NameCoder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/naming/NameCoderWrapper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/naming/NoNameCoder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/naming/StaticNameCoder.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/Path.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/Path.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/Path.java 10 Sep 2012 19:03:06 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/Path.java 10 Nov 2014 12:07:41 -0000 1.1.2.1 @@ -1,102 +1,173 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 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 02. September 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.path; +import java.util.ArrayList; +import java.util.List; + import com.thoughtworks.xstream.core.util.FastStack; -import java.util.List; -import java.util.ArrayList; /** - * Represents a path (subset of XPath) 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 produced are XPath compliant, so can be read by other XPath engines. - * The following are examples of path expressions that the Path object supports:

    + * 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
    • - *
    • /some[3]/node[2]/a
    • - *
    • ../../../another[3]/node
    • + *
    • /
    • + *
    • /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

    - * + *

    Example

    + * *
    - * Path a = new Path("/html/body/div/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 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 static final Path DOT = new Path(new String[] {"."}); + private transient String pathExplicit; + private static final Path DOT = new Path(new String[]{"."}); - public Path(String pathAsString) { + public Path(final String pathAsString) { // String.split() too slow. StringTokenizer too crappy. - List result = new ArrayList(); + final List result = new ArrayList(); int currentIndex = 0; - int nextSeperator; - while ((nextSeperator = pathAsString.indexOf('/', currentIndex)) != -1) { - result.add(pathAsString.substring(currentIndex, nextSeperator)); - currentIndex = nextSeperator + 1; + 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(pathAsString.substring(currentIndex)); - String[] arr = new String[result.size()]; + result.add(normalize(pathAsString, currentIndex, pathAsString.length())); + final String[] arr = new String[result.size()]; result.toArray(arr); chunks = arr; - this.pathAsString = pathAsString; } - public Path(String[] chunks) { + private String normalize(final String s, final int start, final int end) { + if (end - start > 3 && s.charAt(end - 3) == '[' && s.charAt(end - 2) == '1' && s.charAt(end - 1) == ']') { + pathAsString = null; + return s.substring(start, end - 3); + } else { + return s.substring(start, end); + } + + } + + public Path(final String[] chunks) { this.chunks = chunks; } + @Override public String toString() { if (pathAsString == null) { - StringBuffer buffer = new StringBuffer(); + final StringBuilder buffer = new StringBuilder(); for (int i = 0; i < chunks.length; i++) { - if (i > 0) buffer.append('/'); + if (i > 0) { + buffer.append('/'); + } buffer.append(chunks[i]); } pathAsString = buffer.toString(); } return pathAsString; } - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Path)) return false; + public String explicit() { + if (pathExplicit == null) { + final StringBuilder buffer = new StringBuilder(); + for (int i = 0; i < chunks.length; i++) { + if (i > 0) { + buffer.append('/'); + } + final String chunk = chunks[i]; + buffer.append(chunk); + final int length = chunk.length(); + if (length > 0) { + final char c = chunk.charAt(length - 1); + if (c != ']' && c != '.') { + buffer.append("[1]"); + } + } + } + pathExplicit = buffer.toString(); + } + return pathExplicit; + } - final Path other = (Path) o; - if (chunks.length != other.chunks.length) return false; + @Override + public boolean equals(final 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; + if (!chunks[i].equals(other.chunks[i])) { + return false; + } } return true; } + @Override public int hashCode() { int result = 543645643; - for (int i = 0; i < chunks.length; i++) { - result = 29 * result + chunks[i].hashCode(); + for (final String chunk : chunks) { + result = 29 * result + chunk.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]; + public Path relativeTo(final Path that) { + final int depthOfPathDivergence = depthOfPathDivergence(chunks, that.chunks); + final String[] result = new String[chunks.length + that.chunks.length - 2 * depthOfPathDivergence]; int count = 0; for (int i = depthOfPathDivergence; i < chunks.length; i++) { @@ -113,8 +184,8 @@ } } - private int depthOfPathDivergence(String[] path1, String[] path2) { - int minLength = Math.min(path1.length, path2.length); + private int depthOfPathDivergence(final String[] path1, final String[] path2) { + final int minLength = Math.min(path1.length, path2.length); for (int i = 0; i < minLength; i++) { if (!path1[i].equals(path2[i])) { return i; @@ -123,27 +194,38 @@ return minLength; } - public Path apply(Path relativePath) { - FastStack absoluteStack = new FastStack(16); + public Path apply(final Path relativePath) { + final FastStack absoluteStack = new FastStack(16); - for (int i = 0; i < chunks.length; i++) { - absoluteStack.push(chunks[i]); + for (final String chunk : chunks) { + absoluteStack.push(chunk); } - for (int i = 0; i < relativePath.chunks.length; i++) { - String relativeChunk = relativePath.chunks[i]; + for (final String relativeChunk : relativePath.chunks) { if (relativeChunk.equals("..")) { absoluteStack.pop(); } else if (!relativeChunk.equals(".")) { absoluteStack.push(relativeChunk); } } - String[] result = new String[absoluteStack.size()]; + final String[] result = new String[absoluteStack.size()]; for (int i = 0; i < result.length; i++) { - result[i] = (String) absoluteStack.get(i); + result[i] = absoluteStack.get(i); } return new Path(result); } + + public boolean isAncestor(final 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; + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/PathTracker.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/PathTracker.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/PathTracker.java 10 Sep 2012 19:03:06 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/PathTracker.java 10 Nov 2014 12:07:41 -0000 1.1.2.1 @@ -1,44 +1,54 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 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 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 HierarchicalStreamWriter or - * HierarchicalStreamReader by wrapping them with a - * PathTrackingWriter or - * PathTrackingReader.

    - * + *

    + * 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"
    + * 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 Map[] indexMapStack; private Path currentPath; @@ -48,32 +58,34 @@ /** * @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. + * 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 = initialCapacity; + public PathTracker(final int initialCapacity) { + capacity = Math.max(1, initialCapacity); pathStack = new String[capacity]; - indexMapStack = new Map[capacity]; + @SuppressWarnings("unchecked") + final Map[] newIndexMapStack = new Map[capacity]; + indexMapStack = newIndexMapStack; } /** * Notify the tracker that the stream has moved into a new element. - * + * * @param name Name of the element */ - public void pushElement(String name) { + public void pushElement(final String name) { if (pointer + 1 >= capacity) { resizeStacks(capacity * 2); } pathStack[pointer] = name; - Map indexMap = indexMapStack[pointer]; + Map indexMap = indexMapStack[pointer]; if (indexMap == null) { - indexMap = new HashMap(); + indexMap = new HashMap(); indexMapStack[pointer] = indexMap; } if (indexMap.containsKey(name)) { - indexMap.put(name, new Integer(((Integer) indexMap.get(name)).intValue() + 1)); + indexMap.put(name, new Integer(indexMap.get(name).intValue() + 1)); } else { indexMap.put(name, new Integer(1)); } @@ -86,21 +98,62 @@ */ public void popElement() { indexMapStack[pointer] = null; + pathStack[pointer] = null; currentPath = null; pointer--; } /** - * @deprecated Use {@link #getPath()} instead. + * Get the last path element from the stack. + * + * @return the name of the path element + * @since 1.4.2 */ - public String getCurrentPath() { - return getPath().toString(); + public String peekElement() { + return peekElement(0); } - private void resizeStacks(int newCapacity) { - String[] newPathStack = new String[newCapacity]; - Map[] newIndexMapStack = new Map[newCapacity]; - int min = Math.min(capacity, newCapacity); + /** + * 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(final int i) { + if (i < -pointer || i > 0) { + throw new ArrayIndexOutOfBoundsException(i); + } + final int idx = pointer + i - 1; + final String name; + final Integer integer = indexMapStack[idx].get(pathStack[idx]); + final int index = integer.intValue(); + if (index > 1) { + final 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(final int newCapacity) { + final String[] newPathStack = new String[newCapacity]; + @SuppressWarnings("unchecked") + final Map[] newIndexMapStack = new Map[newCapacity]; + final int min = Math.min(capacity, newCapacity); System.arraycopy(pathStack, 0, newPathStack, 0, min); System.arraycopy(indexMapStack, 0, newIndexMapStack, 0, min); pathStack = newPathStack; @@ -113,16 +166,11 @@ */ public Path getPath() { if (currentPath == null) { - String[] chunks = new String[pointer + 1]; + final String[] chunks = new String[pointer + 1]; chunks[0] = ""; - for (int i = 0; i < pointer; i++) { - Integer integer = ((Integer) indexMapStack[i].get(pathStack[i])); - int index = integer.intValue(); - if (index > 1) { - chunks[i + 1] = pathStack[i] + '[' + index + ']'; - } else { - chunks[i + 1] = pathStack[i]; - } + for (int i = -pointer; ++i <= 0;) { + final String name = peekElement(i); + chunks[i + pointer] = name; } currentPath = new Path(chunks); } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/PathTrackingReader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/PathTrackingReader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/PathTrackingReader.java 10 Sep 2012 19:03:06 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/PathTrackingReader.java 10 Nov 2014 12:07:41 -0000 1.1.2.1 @@ -1,38 +1,52 @@ +/* + * Copyright (C) 2004, 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 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) { + public PathTrackingReader(final HierarchicalStreamReader reader, final PathTracker pathTracker) { super(reader); this.pathTracker = pathTracker; pathTracker.pushElement(getNodeName()); } + @Override public void moveDown() { super.moveDown(); pathTracker.pushElement(getNodeName()); } + @Override public void moveUp() { super.moveUp(); pathTracker.popElement(); } - public void appendErrors(ErrorWriter errorWriter) { + @Override + public void appendErrors(final ErrorWriter errorWriter) { errorWriter.add("path", pathTracker.getPath().toString()); super.appendErrors(errorWriter); } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/PathTrackingWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/PathTrackingWriter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/PathTrackingWriter.java 10 Sep 2012 19:03:06 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/PathTrackingWriter.java 10 Nov 2014 12:07:41 -0000 1.1.2.1 @@ -1,33 +1,55 @@ +/* + * Copyright (C) 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 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. - * + * 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) { + public PathTrackingWriter(final HierarchicalStreamWriter writer, final PathTracker pathTracker) { super(writer); + isNameEncoding = writer.underlyingWriter() instanceof AbstractWriter; this.pathTracker = pathTracker; } - public void startNode(String name) { - pathTracker.pushElement(name); + @Override + public void startNode(final String name) { + pathTracker.pushElement(isNameEncoding ? ((AbstractWriter)wrapped.underlyingWriter()).encodeNode(name) : name); super.startNode(name); } + @Override + public void startNode(final String name, final Class clazz) { + pathTracker.pushElement(isNameEncoding ? ((AbstractWriter)wrapped.underlyingWriter()).encodeNode(name) : name); + super.startNode(name, clazz); + } + + @Override public void endNode() { super.endNode(); pathTracker.popElement(); } - } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/package.html,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/package.html 10 Sep 2012 19:03:06 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/path/package.html 10 Nov 2014 12:07:41 -0000 1.1.2.1 @@ -1,3 +1,14 @@ + Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/AbstractDocumentReader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/AbstractDocumentReader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/AbstractDocumentReader.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/AbstractDocumentReader.java 10 Nov 2014 12:07:37 -0000 1.1.2.1 @@ -1,34 +1,67 @@ +/* + * Copyright (C) 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 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 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.HierarchicalStreamReader; import com.thoughtworks.xstream.io.AttributeNameIterator; +import com.thoughtworks.xstream.io.naming.NameCoder; -import java.util.Iterator; -public abstract class AbstractDocumentReader implements HierarchicalStreamReader { +public abstract class AbstractDocumentReader extends AbstractXmlReader implements DocumentReader { - private FastStack pointers = new FastStack(16); + private final FastStack pointers = new FastStack(16); private Object current; - protected AbstractDocumentReader(Object rootElement) { - this.current = rootElement; + protected AbstractDocumentReader(final Object rootElement) { + this(rootElement, new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + protected AbstractDocumentReader(final Object rootElement, final NameCoder nameCoder) { + super(nameCoder); + current = rootElement; pointers.push(new Pointer()); reassignCurrentElement(current); } + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link AbstractDocumentReader#AbstractDocumentReader(Object, NameCoder)} instead. + */ + @Deprecated + protected AbstractDocumentReader(final Object rootElement, final 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; } + @Override public boolean hasMoreChildren() { - Pointer pointer = (Pointer) pointers.peek(); + final Pointer pointer = pointers.peek(); if (pointer.v < getChildCount()) { return true; @@ -37,14 +70,16 @@ } } + @Override public void moveUp() { current = getParent(); pointers.popSilently(); reassignCurrentElement(current); } + @Override public void moveDown() { - Pointer pointer = (Pointer) pointers.peek(); + final Pointer pointer = pointers.peek(); pointers.push(new Pointer()); current = getChild(pointer.v); @@ -53,22 +88,22 @@ reassignCurrentElement(current); } - public Iterator getAttributeNames() { + @Override + public Iterator getAttributeNames() { return new AttributeNameIterator(this); } - public void appendErrors(ErrorWriter errorWriter) { + @Override + public void appendErrors(final ErrorWriter errorWriter) { } - public Object peekUnderlyingNode() { + @Override + public Object getCurrent() { return current; } + @Override public void close() { // don't need to do anything } - - public HierarchicalStreamReader underlyingReader() { - return this; - } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/AbstractDocumentWriter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/AbstractPullReader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/AbstractPullReader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/AbstractPullReader.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/AbstractPullReader.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,30 +1,43 @@ +/* + * Copyright (C) 2005, 2006 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 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.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.naming.NameCoder; -import java.util.Iterator; /** - * Base class that contains common functionality across HierarchicalStreamReader implementations - * that need to read from a pull parser. - * + * 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 implements HierarchicalStreamReader { +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 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 final FastStack lookahead = new FastStack(4); + private final FastStack lookback = new FastStack(4); private boolean marked; private static class Event { @@ -33,13 +46,31 @@ } /** + * @since 1.4 + */ + protected AbstractPullReader(final NameCoder nameCoder) { + super(nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link AbstractPullReader#AbstractPullReader(NameCoder)} instead + */ + @Deprecated + protected AbstractPullReader(final 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.

    + *

    + * 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(); @@ -53,24 +84,26 @@ */ protected abstract String pullText(); + @Override public boolean hasMoreChildren() { mark(); while (true) { switch (readEvent().type) { - case START_NODE: - reset(); - return true; - case END_NODE: - reset(); - return false; - default: - continue; + case START_NODE: + reset(); + return true; + case END_NODE: + reset(); + return false; + default: + continue; } } } + @Override public void moveDown() { - int currentDepth = elementStack.size(); + final int currentDepth = elementStack.size(); while (elementStack.size() <= currentDepth) { move(); if (elementStack.size() < currentDepth) { @@ -79,47 +112,52 @@ } } + @Override public void moveUp() { - int currentDepth = elementStack.size(); + final int currentDepth = elementStack.size(); while (elementStack.size() >= currentDepth) { move(); } } private void move() { - switch (readEvent().type) { - case START_NODE: - elementStack.push(pullElementName()); - break; - case END_NODE: - elementStack.pop(); - break; + 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()); + return lookahead.push(lookback.pop()); } else { - return (Event) lookahead.push(readRealEvent()); + return lookahead.push(readRealEvent()); } } else { if (lookback.hasStuff()) { - return (Event) lookback.pop(); + return lookback.pop(); } else { return readRealEvent(); } } } private Event readRealEvent() { - Event event = new Event(); + final 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; } @@ -129,12 +167,13 @@ } public void reset() { - while(lookahead.hasStuff()) { + while (lookahead.hasStuff()) { lookback.push(lookahead.pop()); } marked = false; } + @Override public String getValue() { // we should collapse together any text which // contains comments @@ -148,7 +187,7 @@ Event event = readEvent(); while (true) { if (event.type == TEXT) { - String text = event.value; + final String text = event.value; if (text != null && text.length() > 0) { if (last == null) { last = text; @@ -168,24 +207,35 @@ if (buffer != null) { return buffer.toString(); } else { - return (last == null) ? "" : last; + return last == null ? "" : last; } } - public Iterator getAttributeNames() { + @Override + public Iterator getAttributeNames() { return new AttributeNameIterator(this); } + @Override public String getNodeName() { - return (String) elementStack.peek(); + return unescapeXmlName(elementStack.peek()); } - public Object peekUnderlyingNode() { - throw new UnsupportedOperationException(); + @Override + public String peekNextChild() { + mark(); + while (true) { + final Event ev = readEvent(); + switch (ev.type) { + case START_NODE: + reset(); + return ev.value; + case END_NODE: + reset(); + return null; + default: + continue; + } + } } - - public HierarchicalStreamReader underlyingReader() { - return this; - } - } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/AbstractXmlDriver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/AbstractXmlReader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/AbstractXmlWriter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/AbstractXppDomDriver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/AbstractXppDriver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/BEAStaxDriver.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/CompactWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/CompactWriter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/CompactWriter.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/CompactWriter.java 10 Nov 2014 12:07:37 -0000 1.1.2.1 @@ -1,13 +1,66 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 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 07. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; import java.io.Writer; +import com.thoughtworks.xstream.io.naming.NameCoder; + + public class CompactWriter extends PrettyPrintWriter { - public CompactWriter(Writer writer) { + public CompactWriter(final Writer writer) { super(writer); } + /** + * @since 1.3 + */ + public CompactWriter(final Writer writer, final int mode) { + super(writer, mode); + } + + /** + * @since 1.4 + */ + public CompactWriter(final Writer writer, final NameCoder nameCoder) { + super(writer, nameCoder); + } + + /** + * @since 1.4 + */ + public CompactWriter(final Writer writer, final int mode, final NameCoder nameCoder) { + super(writer, mode, nameCoder); + } + + /** + * @deprecated As of 1.4 use {@link CompactWriter#CompactWriter(Writer, NameCoder)} instead. + */ + @Deprecated + public CompactWriter(final Writer writer, final XmlFriendlyReplacer replacer) { + super(writer, replacer); + } + + /** + * @since 1.3 + * @deprecated As of 1.4 use {@link CompactWriter#CompactWriter(Writer, int, NameCoder)} instead. + */ + @Deprecated + public CompactWriter(final Writer writer, final int mode, final XmlFriendlyReplacer replacer) { + super(writer, mode, replacer); + } + + @Override protected void endOfLine() { // override parent: don't write anything at end of line } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/DocumentReader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/DocumentWriter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/Dom4JDriver.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/Dom4JDriver.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/Dom4JDriver.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/Dom4JDriver.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,105 +1,160 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 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 07. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; -import com.thoughtworks.xstream.io.*; +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 java.io.*; +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 implements HierarchicalStreamDriver { +public class Dom4JDriver extends AbstractXmlDriver { + private DocumentFactory documentFactory; private OutputFormat outputFormat; - public Dom4JDriver(DocumentFactory documentFactory, OutputFormat outputFormat) { + public Dom4JDriver() { + this(new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + public Dom4JDriver(final NameCoder nameCoder) { + this(new DocumentFactory(), OutputFormat.createPrettyPrint(), nameCoder); + outputFormat.setTrimText(false); + } + + public Dom4JDriver(final DocumentFactory documentFactory, final OutputFormat outputFormat) { + this(documentFactory, outputFormat, new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + public Dom4JDriver(final DocumentFactory documentFactory, final OutputFormat outputFormat, final NameCoder nameCoder) { + super(nameCoder); this.documentFactory = documentFactory; this.outputFormat = outputFormat; } - public Dom4JDriver() { - this(new DocumentFactory(), OutputFormat.createPrettyPrint()); + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link Dom4JDriver#Dom4JDriver(DocumentFactory, OutputFormat, NameCoder)} instead. + */ + @Deprecated + public Dom4JDriver( + final DocumentFactory documentFactory, final OutputFormat outputFormat, final XmlFriendlyReplacer replacer) { + this(documentFactory, outputFormat, (NameCoder)replacer); } public DocumentFactory getDocumentFactory() { return documentFactory; } - public void setDocumentFactory(DocumentFactory documentFactory) { + public void setDocumentFactory(final DocumentFactory documentFactory) { this.documentFactory = documentFactory; } public OutputFormat getOutputFormat() { return outputFormat; } - public void setOutputFormat(OutputFormat outputFormat) { + public void setOutputFormat(final OutputFormat outputFormat) { this.outputFormat = outputFormat; } - public HierarchicalStreamReader createReader(Reader text) { + @Override + public HierarchicalStreamReader createReader(final Reader text) { try { - SAXReader reader = new SAXReader(); - Document document = reader.read(text); - return new Dom4JReader(document); - } catch (DocumentException e) { + final SAXReader reader = new SAXReader(); + final Document document = reader.read(text); + return new Dom4JReader(document, getNameCoder()); + } catch (final DocumentException e) { throw new StreamException(e); } } - public HierarchicalStreamReader createReader(InputStream in) { + @Override + public HierarchicalStreamReader createReader(final InputStream in) { try { - SAXReader reader = new SAXReader(); - Document document = reader.read(in); - return new Dom4JReader(document); - } catch (DocumentException e) { + final SAXReader reader = new SAXReader(); + final Document document = reader.read(in); + return new Dom4JReader(document, getNameCoder()); + } catch (final DocumentException e) { throw new StreamException(e); } } - public HierarchicalStreamWriter createWriter(final Writer out) { - final Document document = documentFactory.createDocument(); - HierarchicalStreamWriter writer = new Dom4JWriter(document); + /** + * @since 1.4 + */ + @Override + public HierarchicalStreamReader createReader(final URL in) { + try { + final SAXReader reader = new SAXReader(); + final Document document = reader.read(in); + return new Dom4JReader(document, getNameCoder()); + } catch (final DocumentException e) { + throw new StreamException(e); + } + } - // Ensure that on writer.close(), the Document is written back to the text output. - writer = new WriterWrapper(writer) { - public void close() { - super.close(); - try { - XMLWriter writer = new XMLWriter(out, outputFormat); - writer.write(document); - writer.flush(); - } catch (IOException e) { - throw new StreamException(e); - } - } - }; - - return writer; + /** + * @since 1.4 + */ + @Override + public HierarchicalStreamReader createReader(final File in) { + try { + final SAXReader reader = new SAXReader(); + final Document document = reader.read(in); + return new Dom4JReader(document, getNameCoder()); + } catch (final DocumentException e) { + throw new StreamException(e); + } } - public HierarchicalStreamWriter createWriter(final OutputStream out) { - final Document document = documentFactory.createDocument(); - HierarchicalStreamWriter writer = new Dom4JWriter(document); - - // Ensure that on writer.close(), the Document is written back to the text output. - writer = new WriterWrapper(writer) { + @Override + public HierarchicalStreamWriter createWriter(final Writer out) { + final HierarchicalStreamWriter[] writer = new HierarchicalStreamWriter[1]; + final FilterWriter filter = new FilterWriter(out) { + @Override public void close() { - super.close(); - try { - XMLWriter writer = new XMLWriter(out, outputFormat); - writer.write(document); - writer.flush(); - } catch (IOException e) { - throw new StreamException(e); - } + writer[0].close(); } }; - - return writer; + writer[0] = new Dom4JXmlWriter(new XMLWriter(filter, outputFormat), getNameCoder()); + return writer[0]; } + @Override + public HierarchicalStreamWriter createWriter(final OutputStream out) { + final Writer writer = new OutputStreamWriter(out); + return createWriter(writer); + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/Dom4JReader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/Dom4JReader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/Dom4JReader.java 10 Sep 2012 19:03:06 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/Dom4JReader.java 10 Nov 2014 12:07:37 -0000 1.1.2.1 @@ -1,64 +1,131 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 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 07. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; -import com.thoughtworks.xstream.converters.ErrorWriter; -import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import java.util.List; + import org.dom4j.Document; import org.dom4j.Element; -import org.dom4j.Attribute; +import com.thoughtworks.xstream.converters.ErrorWriter; +import com.thoughtworks.xstream.io.naming.NameCoder; + + public class Dom4JReader extends AbstractDocumentReader { private Element currentElement; - public Dom4JReader(Element rootElement) { - super(rootElement); + public Dom4JReader(final Element rootElement) { + this(rootElement, new XmlFriendlyNameCoder()); } - public Dom4JReader(Document document) { + public Dom4JReader(final Document document) { this(document.getRootElement()); } + /** + * @since 1.4 + */ + public Dom4JReader(final Element rootElement, final NameCoder nameCoder) { + super(rootElement, nameCoder); + } + + /** + * @since 1.4 + */ + public Dom4JReader(final Document document, final NameCoder nameCoder) { + this(document.getRootElement(), nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link Dom4JReader#Dom4JReader(Element, NameCoder)} instead + */ + @Deprecated + public Dom4JReader(final Element rootElement, final XmlFriendlyReplacer replacer) { + this(rootElement, (NameCoder)replacer); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link Dom4JReader#Dom4JReader(Document, NameCoder)} instead + */ + @Deprecated + public Dom4JReader(final Document document, final XmlFriendlyReplacer replacer) { + this(document.getRootElement(), (NameCoder)replacer); + } + + @Override public String getNodeName() { - return currentElement.getName(); + return decodeNode(currentElement.getName()); } + @Override public String getValue() { return currentElement.getText(); } - public String getAttribute(String name) { - return currentElement.attributeValue(name); + @Override + public String getAttribute(final String name) { + return currentElement.attributeValue(encodeAttribute(name)); } - public String getAttribute(int index) { + @Override + public String getAttribute(final int index) { return currentElement.attribute(index).getValue(); } + @Override public int getAttributeCount() { return currentElement.attributeCount(); } - public String getAttributeName(int index) { - return currentElement.attribute(index).getQualifiedName(); + @Override + public String getAttributeName(final int index) { + return decodeAttribute(currentElement.attribute(index).getQualifiedName()); } + @Override protected Object getParent() { return currentElement.getParent(); } - protected Object getChild(int index) { + @Override + protected Object getChild(final int index) { return currentElement.elements().get(index); } + @Override protected int getChildCount() { return currentElement.elements().size(); } - protected void reassignCurrentElement(Object current) { - currentElement = (Element) current; + @Override + protected void reassignCurrentElement(final Object current) { + currentElement = (Element)current; } - public void appendErrors(ErrorWriter errorWriter) { + @Override + public String peekNextChild() { + @SuppressWarnings("unchecked") + final List list = currentElement.elements(); + if (null == list || list.isEmpty()) { + return null; + } + return decodeNode(list.get(0).getName()); + } + + @Override + public void appendErrors(final ErrorWriter errorWriter) { errorWriter.add("xpath", currentElement.getPath()); } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/Dom4JWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/Dom4JWriter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/Dom4JWriter.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/Dom4JWriter.java 10 Nov 2014 12:07:37 -0000 1.1.2.1 @@ -1,52 +1,115 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 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 07. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import org.dom4j.Branch; import org.dom4j.DocumentFactory; import org.dom4j.Element; -import java.util.LinkedList; +import com.thoughtworks.xstream.io.naming.NameCoder; -public class Dom4JWriter implements HierarchicalStreamWriter { - private DocumentFactory documentFactory = new DocumentFactory(); - private LinkedList elementStack = new LinkedList(); +public class Dom4JWriter extends AbstractDocumentWriter { - public Dom4JWriter(Branch container) { - elementStack.addLast(container); + private final DocumentFactory documentFactory; + + /** + * @since 1.4 + */ + public Dom4JWriter(final Branch root, final DocumentFactory factory, final NameCoder nameCoder) { + super(root, nameCoder); + documentFactory = factory; } - public void startNode(String name) { - Element element = documentFactory.createElement(name); - top().add(element); - elementStack.addLast(element); + /** + * @since 1.4 + */ + public Dom4JWriter(final DocumentFactory factory, final NameCoder nameCoder) { + this(null, factory, nameCoder); } - public void setValue(String text) { - top().setText(text); + /** + * @since 1.4 + */ + public Dom4JWriter(final Branch root, final NameCoder nameCoder) { + this(root, new DocumentFactory(), nameCoder); } - public void addAttribute(String key, String value) { - ((Element) top()).addAttribute(key, value); + /** + * @since 1.2.1 + * @deprecated As of 1.4 use {@link Dom4JWriter#Dom4JWriter(Branch, DocumentFactory, NameCoder)} instead. + */ + @Deprecated + public Dom4JWriter(final Branch root, final DocumentFactory factory, final XmlFriendlyReplacer replacer) { + this(root, factory, (NameCoder)replacer); } - public void endNode() { - elementStack.removeLast(); + /** + * @since 1.2.1 + * @deprecated As of 1.4 use {@link Dom4JWriter#Dom4JWriter(DocumentFactory, NameCoder)} instead. + */ + @Deprecated + public Dom4JWriter(final DocumentFactory factory, final XmlFriendlyReplacer replacer) { + this(null, factory, (NameCoder)replacer); } - private Branch top() { - return (Branch) elementStack.getLast(); + /** + * @since 1.2.1 + */ + public Dom4JWriter(final DocumentFactory documentFactory) { + this(documentFactory, new XmlFriendlyNameCoder()); } - public void flush() { - // don't need to do anything + /** + * @since 1.2.1 + * @deprecated As of 1.4 use {@link Dom4JWriter#Dom4JWriter(Branch, NameCoder)} instead + */ + @Deprecated + public Dom4JWriter(final Branch root, final XmlFriendlyReplacer replacer) { + this(root, new DocumentFactory(), (NameCoder)replacer); } - public void close() { - // don't need to do anything + public Dom4JWriter(final Branch root) { + this(root, new DocumentFactory(), new XmlFriendlyNameCoder()); } - public HierarchicalStreamWriter underlyingWriter() { - return this; + /** + * @since 1.2.1 + */ + public Dom4JWriter() { + this(new DocumentFactory(), new XmlFriendlyNameCoder()); } + + @Override + 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; + } + + @Override + public void setValue(final String text) { + top().setText(text); + } + + @Override + public void addAttribute(final String key, final String value) { + ((Element)top()).addAttribute(encodeAttribute(key), value); + } + + private Branch top() { + return (Branch)getCurrent(); + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/Dom4JXmlWriter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/DomDriver.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/DomDriver.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/DomDriver.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/DomDriver.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,60 +1,129 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 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 07. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; -import com.thoughtworks.xstream.io.*; -import org.w3c.dom.Document; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; +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 java.io.*; -public class DomDriver implements HierarchicalStreamDriver { +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; - public DomDriver(String encoding) { + /** + * 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(final String encoding) { + this(encoding, new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + public DomDriver(final String encoding, final NameCoder nameCoder) { + super(nameCoder); documentBuilderFactory = DocumentBuilderFactory.newInstance(); this.encoding = encoding; } - public DomDriver() { - this("UTF-8"); + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link #DomDriver(String, NameCoder)} instead. + */ + @Deprecated + public DomDriver(final String encoding, final XmlFriendlyReplacer replacer) { + this(encoding, (NameCoder)replacer); } - public HierarchicalStreamReader createReader(Reader xml) { - return createReader(new InputSource(xml)); + @Override + public HierarchicalStreamReader createReader(final Reader in) { + return createReader(new InputSource(in)); } - public HierarchicalStreamReader createReader(InputStream xml) { - return createReader(new InputSource(xml)); + @Override + public HierarchicalStreamReader createReader(final InputStream in) { + return createReader(new InputSource(in)); } - private HierarchicalStreamReader createReader(InputSource source) { + @Override + public HierarchicalStreamReader createReader(final URL in) { + return createReader(new InputSource(in.toExternalForm())); + } + + @Override + public HierarchicalStreamReader createReader(final File in) { + return createReader(new InputSource(in.toURI().toASCIIString())); + } + + private HierarchicalStreamReader createReader(final InputSource source) { try { - DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); - source.setEncoding(encoding); - Document document = documentBuilder.parse(source); - return new DomReader(document); - } catch (FactoryConfigurationError e) { + final DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + if (encoding != null) { + source.setEncoding(encoding); + } + final Document document = documentBuilder.parse(source); + return new DomReader(document, getNameCoder()); + } catch (final FactoryConfigurationError e) { throw new StreamException(e); - } catch (ParserConfigurationException e) { + } catch (final ParserConfigurationException e) { throw new StreamException(e); - } catch (SAXException e) { + } catch (final SAXException e) { throw new StreamException(e); - } catch (IOException e) { + } catch (final IOException e) { throw new StreamException(e); } } - public HierarchicalStreamWriter createWriter(Writer out) { - return new PrettyPrintWriter(out); + @Override + public HierarchicalStreamWriter createWriter(final Writer out) { + return new PrettyPrintWriter(out, getNameCoder()); } - public HierarchicalStreamWriter createWriter(OutputStream out) { - return createWriter(new OutputStreamWriter(out)); + @Override + public HierarchicalStreamWriter createWriter(final OutputStream out) { + try { + return createWriter(encoding != null ? new OutputStreamWriter(out, encoding) : new OutputStreamWriter(out)); + } catch (final UnsupportedEncodingException e) { + throw new StreamException(e); + } } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/DomReader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/DomReader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/DomReader.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/DomReader.java 10 Nov 2014 12:07:37 -0000 1.1.2.1 @@ -1,89 +1,154 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 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 07. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; +import java.util.ArrayList; +import java.util.List; + 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; +import com.thoughtworks.xstream.io.naming.NameCoder; -import com.thoughtworks.xstream.io.HierarchicalStreamReader; public class DomReader extends AbstractDocumentReader { private Element currentElement; - private StringBuffer textBuffer; - private List childElements; + private final StringBuilder textBuffer; + private List childElements; - public DomReader(Element rootElement) { - super(rootElement); - textBuffer = new StringBuffer(); + public DomReader(final Element rootElement) { + this(rootElement, new XmlFriendlyNameCoder()); } - public DomReader(Document document) { + public DomReader(final Document document) { this(document.getDocumentElement()); } + /** + * @since 1.4 + */ + public DomReader(final Element rootElement, final NameCoder nameCoder) { + super(rootElement, nameCoder); + textBuffer = new StringBuilder(); + } + + /** + * @since 1.4 + */ + public DomReader(final Document document, final NameCoder nameCoder) { + this(document.getDocumentElement(), nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link DomReader#DomReader(Element, NameCoder)} instead. + */ + @Deprecated + public DomReader(final Element rootElement, final XmlFriendlyReplacer replacer) { + this(rootElement, (NameCoder)replacer); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link DomReader#DomReader(Document, NameCoder)} instead. + */ + @Deprecated + public DomReader(final Document document, final XmlFriendlyReplacer replacer) { + this(document.getDocumentElement(), (NameCoder)replacer); + } + + @Override public String getNodeName() { - return currentElement.getTagName(); + return decodeNode(currentElement.getTagName()); } + @Override public String getValue() { - NodeList childNodes = currentElement.getChildNodes(); + final NodeList childNodes = currentElement.getChildNodes(); textBuffer.setLength(0); - int length = childNodes.getLength(); + final int length = childNodes.getLength(); for (int i = 0; i < length; i++) { - Node childNode = childNodes.item(i); + final Node childNode = childNodes.item(i); if (childNode instanceof Text) { - Text text = (Text) childNode; + final Text text = (Text)childNode; textBuffer.append(text.getData()); } } return textBuffer.toString(); } - public String getAttribute(String name) { - Attr attribute = currentElement.getAttributeNode(name); + @Override + public String getAttribute(final String name) { + final Attr attribute = currentElement.getAttributeNode(encodeAttribute(name)); return attribute == null ? null : attribute.getValue(); } - public String getAttribute(int index) { - return ((Attr) currentElement.getAttributes().item(index)).getValue(); + @Override + public String getAttribute(final int index) { + return ((Attr)currentElement.getAttributes().item(index)).getValue(); } + @Override public int getAttributeCount() { return currentElement.getAttributes().getLength(); } - public String getAttributeName(int index) { - return ((Attr) currentElement.getAttributes().item(index)).getName(); + @Override + public String getAttributeName(final int index) { + return decodeAttribute(((Attr)currentElement.getAttributes().item(index)).getName()); } + @Override protected Object getParent() { return currentElement.getParentNode(); } - protected Object getChild(int index) { + @Override + protected Object getChild(final int index) { return childElements.get(index); } + @Override protected int getChildCount() { return childElements.size(); } - protected void reassignCurrentElement(Object current) { - currentElement = (Element) current; - NodeList childNodes = currentElement.getChildNodes(); - childElements = new ArrayList(); + @Override + protected void reassignCurrentElement(final Object current) { + currentElement = (Element)current; + final NodeList childNodes = currentElement.getChildNodes(); + childElements = new ArrayList(); for (int i = 0; i < childNodes.getLength(); i++) { - Node node = childNodes.item(i); + final Node node = childNodes.item(i); if (node instanceof Element) { - childElements.add(node); + childElements.add((Element)node); } } } + @Override + public String peekNextChild() { + final NodeList childNodes = currentElement.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + final Node node = childNodes.item(i); + if (node instanceof Element) { + return decodeNode(((Element)node).getTagName()); + } + } + return null; + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/DomWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/DomWriter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/DomWriter.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/DomWriter.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,59 +1,112 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 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 02. September 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import org.w3c.dom.Document; import org.w3c.dom.Element; -import org.w3c.dom.Node; +import com.thoughtworks.xstream.io.naming.NameCoder; + + /** * @author Michael Kopp */ -public class DomWriter implements HierarchicalStreamWriter { +public class DomWriter extends AbstractDocumentWriter { + private final Document document; - private Element current; + private boolean hasRootElement; - public DomWriter(Document document) { + 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; - this.current = document.getDocumentElement(); + hasRootElement = document.getDocumentElement() != null; } - public DomWriter(Element rootElement) { - document = rootElement.getOwnerDocument(); - current = rootElement; + /** + * @since 1.4 + */ + public DomWriter(final Element rootElement, final NameCoder nameCoder) { + this(rootElement, rootElement.getOwnerDocument(), nameCoder); } - public void startNode(String name) { - final Element child = document.createElement(name); - if (current == null) { - document.appendChild(child); - } else { - current.appendChild(child); - } - current = child; + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link DomWriter#DomWriter(Document, NameCoder)} instead. + */ + @Deprecated + public DomWriter(final Document document, final XmlFriendlyReplacer replacer) { + this(document.getDocumentElement(), document, (NameCoder)replacer); } - public void addAttribute(String name, String value) { - current.setAttribute(name, value); + /** + * @since 1.2.1 + * @deprecated As of 1.4 use {@link DomWriter#DomWriter(Element, Document, NameCoder)} instead. + */ + @Deprecated + public DomWriter(final Element element, final Document document, final XmlFriendlyReplacer replacer) { + this(element, document, (NameCoder)replacer); } - public void setValue(String text) { - current.appendChild(document.createTextNode(text)); + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link DomWriter#DomWriter(Element, NameCoder)} instead. + */ + @Deprecated + public DomWriter(final Element rootElement, final XmlFriendlyReplacer replacer) { + this(rootElement, rootElement.getOwnerDocument(), (NameCoder)replacer); } - public void endNode() { - Node parent = current.getParentNode(); - current = parent instanceof Element ? (Element)parent : null; + @Override + 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 flush() { - // don't need to do anything + @Override + public void addAttribute(final String name, final String value) { + top().setAttribute(encodeAttribute(name), value); } - public void close() { - // don't need to do anything + @Override + public void setValue(final String text) { + top().appendChild(document.createTextNode(text)); } - public HierarchicalStreamWriter underlyingWriter() { - return this; + private Element top() { + return (Element)getCurrent(); } -} \ No newline at end of file +} Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/JDom2Driver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/JDom2Reader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/JDom2Writer.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/JDomDriver.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/JDomDriver.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/JDomDriver.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/JDomDriver.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,52 +1,120 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 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 03. September 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; -import java.io.*; +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.HierarchicalStreamDriver; import com.thoughtworks.xstream.io.HierarchicalStreamReader; -import com.thoughtworks.xstream.io.StreamException; 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 implements HierarchicalStreamDriver { +public class JDomDriver extends AbstractXmlDriver { - public HierarchicalStreamReader createReader(Reader reader) { + public JDomDriver() { + super(new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + public JDomDriver(final NameCoder nameCoder) { + super(nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link JDomDriver#JDomDriver(NameCoder)} instead. + */ + @Deprecated + public JDomDriver(final XmlFriendlyReplacer replacer) { + this((NameCoder)replacer); + } + + @Override + public HierarchicalStreamReader createReader(final Reader reader) { try { - SAXBuilder builder = new SAXBuilder(); - Document document = builder.build(reader); - return new JDomReader(document); - } catch (IOException e) { + final SAXBuilder builder = new SAXBuilder(); + final Document document = builder.build(reader); + return new JDomReader(document, getNameCoder()); + } catch (final IOException e) { throw new StreamException(e); - } catch (JDOMException e) { + } catch (final JDOMException e) { throw new StreamException(e); } } - public HierarchicalStreamReader createReader(InputStream in) { + @Override + public HierarchicalStreamReader createReader(final InputStream in) { try { - SAXBuilder builder = new SAXBuilder(); - Document document = builder.build(in); - return new JDomReader(document); - } catch (IOException e) { + final SAXBuilder builder = new SAXBuilder(); + final Document document = builder.build(in); + return new JDomReader(document, getNameCoder()); + } catch (final IOException e) { throw new StreamException(e); - } catch (JDOMException e) { + } catch (final JDOMException e) { throw new StreamException(e); } } - public HierarchicalStreamWriter createWriter(Writer out) { - return new PrettyPrintWriter(out); + @Override + public HierarchicalStreamReader createReader(final URL in) { + try { + final SAXBuilder builder = new SAXBuilder(); + final Document document = builder.build(in); + return new JDomReader(document, getNameCoder()); + } catch (final IOException e) { + throw new StreamException(e); + } catch (final JDOMException e) { + throw new StreamException(e); + } } - public HierarchicalStreamWriter createWriter(OutputStream out) { + @Override + public HierarchicalStreamReader createReader(final File in) { + try { + final SAXBuilder builder = new SAXBuilder(); + final Document document = builder.build(in); + return new JDomReader(document, getNameCoder()); + } catch (final IOException e) { + throw new StreamException(e); + } catch (final JDOMException e) { + throw new StreamException(e); + } + } + + @Override + public HierarchicalStreamWriter createWriter(final Writer out) { + return new PrettyPrintWriter(out, getNameCoder()); + } + + @Override + public HierarchicalStreamWriter createWriter(final OutputStream out) { return new PrettyPrintWriter(new OutputStreamWriter(out)); } } - Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/JDomReader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/JDomReader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/JDomReader.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/JDomReader.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,29 +1,78 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 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 03. September 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; +import java.util.List; + +import org.jdom.Attribute; import org.jdom.Document; import org.jdom.Element; -import org.jdom.Parent; -import org.jdom.Attribute; +import com.thoughtworks.xstream.io.naming.NameCoder; + + /** * @author Laurent Bihanic */ public class JDomReader extends AbstractDocumentReader { private Element currentElement; - public JDomReader(Element root) { + public JDomReader(final Element root) { super(root); } - public JDomReader(Document document) { + public JDomReader(final Document document) { super(document.getRootElement()); } - protected void reassignCurrentElement(Object current) { - currentElement = (Element) current; + /** + * @since 1.4 + */ + public JDomReader(final Element root, final NameCoder nameCoder) { + super(root, nameCoder); } + /** + * @since 1.4 + */ + public JDomReader(final Document document, final NameCoder nameCoder) { + super(document.getRootElement(), nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link JDomReader#JDomReader(Element, NameCoder)} instead. + */ + @Deprecated + public JDomReader(final Element root, final XmlFriendlyReplacer replacer) { + this(root, (NameCoder)replacer); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link JDomReader#JDomReader(Document, NameCoder)} instead. + */ + @Deprecated + public JDomReader(final Document document, final XmlFriendlyReplacer replacer) { + this(document.getRootElement(), (NameCoder)replacer); + } + + @Override + protected void reassignCurrentElement(final Object current) { + currentElement = (Element)current; + } + + @Override protected Object getParent() { // JDOM 1.0: return currentElement.getParentElement(); @@ -36,36 +85,54 @@ // return currentElement.getParent(); } - protected Object getChild(int index) { + @Override + protected Object getChild(final int index) { return currentElement.getChildren().get(index); } + @Override protected int getChildCount() { return currentElement.getChildren().size(); } + @Override public String getNodeName() { - return currentElement.getName(); + return decodeNode(currentElement.getName()); } + @Override public String getValue() { return currentElement.getText(); } - public String getAttribute(String name) { - return currentElement.getAttributeValue(name); + @Override + public String getAttribute(final String name) { + return currentElement.getAttributeValue(encodeAttribute(name)); } - public String getAttribute(int index) { - return ((Attribute) currentElement.getAttributes().get(index)).getValue(); + @Override + public String getAttribute(final int index) { + return ((Attribute)currentElement.getAttributes().get(index)).getValue(); } + @Override public int getAttributeCount() { return currentElement.getAttributes().size(); } - public String getAttributeName(int index) { - return ((Attribute) currentElement.getAttributes().get(index)).getQualifiedName(); + @Override + public String getAttributeName(final int index) { + return decodeAttribute(((Attribute)currentElement.getAttributes().get(index)).getQualifiedName()); } -} + @Override + public String peekNextChild() { + @SuppressWarnings("unchecked") + final List list = currentElement.getChildren(); + if (null == list || list.isEmpty()) { + return null; + } + return decodeNode(list.get(0).getName()); + } + +} Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/JDomWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/JDomWriter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/JDomWriter.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/JDomWriter.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,89 +1,116 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 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 03. September 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; -import java.util.List; -import java.util.LinkedList; - +import org.jdom.DefaultJDOMFactory; import org.jdom.Element; import org.jdom.JDOMFactory; -import org.jdom.DefaultJDOMFactory; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.naming.NameCoder; + /** * @author Laurent Bihanic */ -public class JDomWriter implements HierarchicalStreamWriter { +public class JDomWriter extends AbstractDocumentWriter { - private List result = new LinkedList(); - private List elementStack = new LinkedList(); private final JDOMFactory documentFactory; - public JDomWriter(Element container, JDOMFactory factory) { - elementStack.add(0, container); - result.add(container); - this.documentFactory = factory; + /** + * @since 1.4 + */ + public JDomWriter(final Element container, final JDOMFactory factory, final NameCoder nameCoder) { + super(container, nameCoder); + documentFactory = factory; } - public JDomWriter(JDOMFactory documentFactory) { - this.documentFactory = documentFactory; + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link JDomWriter#JDomWriter(Element, JDOMFactory, NameCoder)} instead. + */ + @Deprecated + public JDomWriter(final Element container, final JDOMFactory factory, final XmlFriendlyReplacer replacer) { + this(container, factory, (NameCoder)replacer); } - public JDomWriter(Element container) { - this(container, new DefaultJDOMFactory()); + public JDomWriter(final Element container, final JDOMFactory factory) { + this(container, factory, new XmlFriendlyNameCoder()); } - public JDomWriter() { - this(new DefaultJDOMFactory()); + /** + * @since 1.4 + */ + public JDomWriter(final JDOMFactory factory, final NameCoder nameCoder) { + this(null, factory, nameCoder); } - public void startNode(String name) { - Element element = this.documentFactory.element(name); + /** + * @since 1.2.1 + * @deprecated As of 1.4 use {@link JDomWriter#JDomWriter(JDOMFactory, NameCoder)} instead. + */ + @Deprecated + public JDomWriter(final JDOMFactory factory, final XmlFriendlyReplacer replacer) { + this(null, factory, (NameCoder)replacer); + } - Element parent = this.top(); - if (parent != null) { - parent.addContent(element); - } - else { - result.add(element); - } - elementStack.add(0, element); + public JDomWriter(final JDOMFactory factory) { + this(null, factory); } - public void setValue(String text) { - top().addContent(this.documentFactory.text(text)); + /** + * @since 1.4 + */ + public JDomWriter(final Element container, final NameCoder nameCoder) { + this(container, new DefaultJDOMFactory(), nameCoder); } - public void addAttribute(String key, String value) { - top().setAttribute( - this.documentFactory.attribute(key, value)); + /** + * @since 1.2.1 + * @deprecated As of 1.4 use {@link JDomWriter#JDomWriter(Element, NameCoder)} instead. + */ + @Deprecated + public JDomWriter(final Element container, final XmlFriendlyReplacer replacer) { + this(container, new DefaultJDOMFactory(), (NameCoder)replacer); } - public void endNode() { - this.elementStack.remove(0); + public JDomWriter(final Element container) { + this(container, new DefaultJDOMFactory()); } - private Element top() { - Element top = null; + public JDomWriter() { + this(new DefaultJDOMFactory()); + } - if (this.elementStack.isEmpty() == false) { - top = (Element) this.elementStack.get(0); + @Override + protected Object createNode(final String name) { + final Element element = documentFactory.element(encodeNode(name)); + final Element parent = top(); + if (parent != null) { + parent.addContent(element); } - return top; + return element; } - public List getResult() { - return this.result; + @Override + public void setValue(final String text) { + top().addContent(documentFactory.text(text)); } - public void flush() { - // don't need to do anything + @Override + public void addAttribute(final String key, final String value) { + top().setAttribute(documentFactory.attribute(encodeAttribute(key), value)); } - public void close() { - // don't need to do anything + private Element top() { + return (Element)getCurrent(); } - - public HierarchicalStreamWriter underlyingWriter() { - return this; - } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/KXml2DomDriver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/KXml2Driver.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/PrettyPrintWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/PrettyPrintWriter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/PrettyPrintWriter.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/PrettyPrintWriter.java 10 Nov 2014 12:07:37 -0000 1.1.2.1 @@ -1,122 +1,281 @@ +/* + * Copyright (C) 2004, 2005, 2006 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 07. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; +import java.io.Writer; + import com.thoughtworks.xstream.core.util.FastStack; import com.thoughtworks.xstream.core.util.QuickWriter; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +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 the {@link #writeText(com.thoughtworks.xstream.core.util.QuickWriter, String)} - * and {@link #writeAttributeValue(com.thoughtworks.xstream.core.util.QuickWriter, String)} methods.

    - * + *

    + * 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 implements HierarchicalStreamWriter { +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 FastStack elementStack = new FastStack(16); private final char[] lineIndenter; + private final int mode; private boolean tagInProgress; - private int depth; + protected int depth; private boolean readyForNewLine; private boolean tagIsEmpty; 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[] SLASH_R = " ".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"); + } } - public PrettyPrintWriter(Writer writer, String lineIndenter) { + /** + * @since 1.3 + * @deprecated As of 1.4 use {@link PrettyPrintWriter#PrettyPrintWriter(Writer, int, char[], NameCoder)} instead + */ + @Deprecated + public PrettyPrintWriter( + final Writer writer, final int mode, final char[] lineIndenter, final XmlFriendlyReplacer replacer) { + this(writer, mode, lineIndenter, (NameCoder)replacer); + } + + /** + * @since 1.3 + */ + public PrettyPrintWriter(final Writer writer, final int mode, final char[] lineIndenter) { + this(writer, mode, lineIndenter, new XmlFriendlyNameCoder()); + } + + public PrettyPrintWriter(final Writer writer, final char[] lineIndenter) { + this(writer, XML_QUIRKS, lineIndenter); + } + + /** + * @since 1.3 + */ + public PrettyPrintWriter(final Writer writer, final int mode, final String lineIndenter) { + this(writer, mode, lineIndenter.toCharArray()); + } + + public PrettyPrintWriter(final Writer writer, final String lineIndenter) { this(writer, lineIndenter.toCharArray()); } - public PrettyPrintWriter(Writer writer) { + /** + * @since 1.4 + */ + public PrettyPrintWriter(final Writer writer, final int mode, final NameCoder nameCoder) { + this(writer, mode, new char[]{' ', ' '}, nameCoder); + } + + /** + * @since 1.3 + * @deprecated As of 1.4 use {@link PrettyPrintWriter#PrettyPrintWriter(Writer, int, NameCoder)} instead + */ + @Deprecated + public PrettyPrintWriter(final Writer writer, final int mode, final XmlFriendlyReplacer replacer) { + this(writer, mode, new char[]{' ', ' '}, replacer); + } + + /** + * @since 1.4 + */ + public PrettyPrintWriter(final Writer writer, final NameCoder nameCoder) { + this(writer, XML_QUIRKS, new char[]{' ', ' '}, nameCoder); + } + + /** + * @deprecated As of 1.4 use {@link PrettyPrintWriter#PrettyPrintWriter(Writer, NameCoder)} instead. + */ + @Deprecated + public PrettyPrintWriter(final Writer writer, final XmlFriendlyReplacer replacer) { + this(writer, XML_QUIRKS, new char[]{' ', ' '}, replacer); + } + + /** + * @since 1.3 + */ + public PrettyPrintWriter(final Writer writer, final int mode) { + this(writer, mode, new char[]{' ', ' '}); + } + + public PrettyPrintWriter(final Writer writer) { this(writer, new char[]{' ', ' '}); } - public void startNode(String name) { + @Override + public void startNode(final String name) { + final String escapedName = encodeNode(name); tagIsEmpty = false; finishTag(); writer.write('<'); - writer.write(name); - elementStack.push(name); + writer.write(escapedName); + elementStack.push(escapedName); tagInProgress = true; depth++; readyForNewLine = true; tagIsEmpty = true; } - public void setValue(String text) { + @Override + public void startNode(final String name, final Class clazz) { + startNode(name); + } + + @Override + public void setValue(final String text) { readyForNewLine = false; tagIsEmpty = false; finishTag(); writeText(writer, text); } - public void addAttribute(String key, String value) { + @Override + public void addAttribute(final String key, final String value) { writer.write(' '); - writer.write(key); + writer.write(encodeAttribute(key)); writer.write('='); writer.write('\"'); writeAttributeValue(writer, value); writer.write('\"'); } - protected void writeAttributeValue(QuickWriter writer, String text) { - writeText(text); + protected void writeAttributeValue(final QuickWriter writer, final String text) { + writeText(text, true); } - protected void writeText(QuickWriter writer, String text) { - writeText(text); + protected void writeText(final QuickWriter writer, final String text) { + writeText(text, false); } - private void writeText(String text) { - int length = text.length(); + private void writeText(final String text, final boolean isAttribute) { + final int length = text.length(); for (int i = 0; i < length; i++) { - char c = text.charAt(i); + final char c = text.charAt(i); switch (c) { - case '\0': - this.writer.write(NULL); + case '\0': + if (mode == XML_QUIRKS) { + writer.write(NULL); + } else { + throw new StreamException("Invalid character 0x0 in XML stream"); + } + break; + case '&': + writer.write(AMP); + break; + case '<': + writer.write(LT); + break; + case '>': + writer.write(GT); + break; + case '"': + writer.write(QUOT); + break; + case '\'': + writer.write(APOS); + break; + case '\r': + writer.write(CR); + break; + case '\t': + case '\n': + if (!isAttribute) { + writer.write(c); 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(SLASH_R); - break; - default: - this.writer.write(c); + } + //$FALL-THROUGH$ + 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"); + } + } + 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"); + } + } + writer.write("&#x"); + writer.write(Integer.toHexString(c)); + writer.write(';'); + } } } } + @Override public void endNode() { depth--; if (tagIsEmpty) { @@ -127,11 +286,11 @@ } else { finishTag(); writer.write(CLOSE); - writer.write((String)elementStack.pop()); + writer.write(elementStack.pop()); writer.write('>'); } readyForNewLine = true; - if (depth == 0 ) { + if (depth == 0) { writer.flush(); } } @@ -149,21 +308,30 @@ } protected void endOfLine() { - writer.write('\n'); + writer.write(getNewLine()); for (int i = 0; i < depth; i++) { writer.write(lineIndenter); } } + @Override public void flush() { writer.flush(); } + @Override public void close() { writer.close(); } - public HierarchicalStreamWriter underlyingWriter() { - return this; + /** + * 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 "\n"; } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/QNameMap.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/QNameMap.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/QNameMap.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/QNameMap.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,33 +1,45 @@ +/* + * 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 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; +import javax.xml.namespace.QName; + + /** - * Represents a mapping of {@link QName} intsnaces to Java class names - * allowing class aliases and namespace aware mappings of QNames to class names. - * + * 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$ */ public class QNameMap { // lets make the mapping a no-op unless we specify some mapping - private Map qnameToJava; - private Map javaToQName; + 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. + * 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) { + public String getJavaClassName(final QName qname) { if (qnameToJava != null) { - String answer = (String) qnameToJava.get(qname); + final String answer = qnameToJava.get(qname); if (answer != null) { return answer; } @@ -36,13 +48,12 @@ } /** - * 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. + * 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) { + public QName getQName(final String javaClassName) { if (javaToQName != null) { - QName answer = (QName) javaToQName.get(javaClassName); + final QName answer = javaToQName.get(javaClassName); if (answer != null) { return answer; } @@ -53,12 +64,12 @@ /** * Registers the mapping of the Java class name to the QName */ - public synchronized void registerMapping(QName qname, String javaClassName) { + public synchronized void registerMapping(final QName qname, final String javaClassName) { if (javaToQName == null) { - javaToQName = Collections.synchronizedMap(new HashMap()); + javaToQName = Collections.synchronizedMap(new HashMap()); } if (qnameToJava == null) { - qnameToJava = Collections.synchronizedMap(new HashMap()); + qnameToJava = Collections.synchronizedMap(new HashMap()); } javaToQName.put(javaClassName, qname); qnameToJava.put(qname, javaClassName); @@ -67,23 +78,23 @@ /** * Registers the mapping of the type to the QName */ - public synchronized void registerMapping(QName qname, Class type) { + public synchronized void registerMapping(final QName qname, final Class type) { registerMapping(qname, type.getName()); } public String getDefaultNamespace() { return defaultNamespace; } - public void setDefaultNamespace(String defaultNamespace) { + public void setDefaultNamespace(final String defaultNamespace) { this.defaultNamespace = defaultNamespace; } public String getDefaultPrefix() { return defaultPrefix; } - public void setDefaultPrefix(String defaultPrefix) { + public void setDefaultPrefix(final String defaultPrefix) { this.defaultPrefix = defaultPrefix; } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/SaxWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/SaxWriter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/SaxWriter.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/SaxWriter.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,8 +1,23 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 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 14. August 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; -import com.thoughtworks.xstream.XStream; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; -import com.thoughtworks.xstream.io.StreamException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + import org.xml.sax.ContentHandler; import org.xml.sax.DTDHandler; import org.xml.sax.EntityResolver; @@ -14,63 +29,51 @@ 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; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.naming.NameCoder; + /** * A SAX {@link org.xml.sax.XMLReader parser} that acts as an XStream - * {@link 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 mecanism}. 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 mecanism 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}.

    - * + * {@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 implements HierarchicalStreamWriter, XMLReader { +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. + * 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"; + 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. - * + * 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"; + 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. @@ -94,99 +97,123 @@ /** * 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.

    + *

    + * 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(); + private final Map features = new HashMap(); /** * The SAX properties defined for this XMLReader. */ - private final Map properties = new HashMap(); + private final Map properties = new HashMap(); private final boolean includeEnclosingDocument; - public SaxWriter(boolean includeEnclosingDocument) { + /** + * @since 1.4 + */ + public SaxWriter(final NameCoder nameCoder) { + this(true, nameCoder); + } + + /** + * @since 1.4 + */ + public SaxWriter(final boolean includeEnclosingDocument, final NameCoder nameCoder) { + super(nameCoder); this.includeEnclosingDocument = includeEnclosingDocument; } + /** + * @deprecated As of 1.4 use {@link SaxWriter#SaxWriter(NameCoder)} instead. + */ + @Deprecated + public SaxWriter(final XmlFriendlyReplacer replacer) { + this(true, replacer); + } + + /** + * @deprecated As of 1.4 use {@link SaxWriter#SaxWriter(boolean, NameCoder)} instead. + */ + @Deprecated + public SaxWriter(final boolean includeEnclosingDocument, final XmlFriendlyReplacer replacer) { + this(includeEnclosingDocument, (NameCoder)replacer); + } + + public SaxWriter(final 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 implemention only supports the two - * mandatory SAX features.

    - * - * @param name the feature name, which is a fully-qualified URI. + *

    + * 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. + * @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 + @Override + public void setFeature(final String name, final boolean value) throws SAXNotRecognizedException { + if (name.equals("http://xml.org/sax/features/namespaces") + || name.equals("http://xml.org/sax/features/namespace-prefixes")) { + 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.

    - * + *

    + * 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. + * @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)); + @Override + public boolean getFeature(final String name) throws SAXNotRecognizedException { + if (name.equals("http://xml.org/sax/features/namespaces") + || name.equals("http://xml.org/sax/features/namespace-prefixes")) { + Boolean value = features.get(name); if (value == null) { value = Boolean.FALSE; @@ -199,488 +226,474 @@ /** * 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 implemention 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. + *

    + * 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. + * @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 { + @Override + public void setProperty(final 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"); + 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; + final List list = (List)value; if (list.isEmpty()) { - throw new SAXNotSupportedException("Value for property \"" + - SOURCE_OBJECT_LIST_PROPERTY + - "\" shall not be an empty list"); + 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)); + value = Collections.unmodifiableList(new ArrayList(list)); } } else { - throw new SAXNotSupportedException("Value for property \"" + - SOURCE_OBJECT_LIST_PROPERTY + - "\" must be a non-null List object"); + 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); + 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.

    - * + *

    + * 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. + * @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); + @Override + public Object getProperty(final String name) throws SAXNotRecognizedException { + if (name.equals(CONFIGURED_XSTREAM_PROPERTY) || name.equals(SOURCE_OBJECT_LIST_PROPERTY)) { + return 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.

    - * + *

    + * 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. + * @throws NullPointerException if the resolver argument is null. * @see #getEntityResolver */ - public void setEntityResolver(EntityResolver resolver) { + @Override + public void setEntityResolver(final EntityResolver resolver) { if (resolver == null) { throw new NullPointerException("resolver"); } - this.entityResolver = resolver; + entityResolver = resolver; return; } /** * Returns the current entity resolver. - * - * @return the current entity resolver, or null if none - * has been registered. + * + * @return the current entity resolver, or null if none has been registered. * @see #setEntityResolver */ + @Override public EntityResolver getEntityResolver() { - return this.entityResolver; + return 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.

    - * + *

    + * 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. + * @throws NullPointerException if the handler argument is null. * @see #getDTDHandler */ - public void setDTDHandler(DTDHandler handler) { + @Override + public void setDTDHandler(final DTDHandler handler) { if (handler == null) { throw new NullPointerException("handler"); } - this.dtdHandler = handler; + dtdHandler = handler; return; } /** * Returns the current DTD handler. - * - * @return the current DTD handler, or null if none - * has been registered. + * + * @return the current DTD handler, or null if none has been registered. * @see #setDTDHandler */ + @Override public DTDHandler getDTDHandler() { - return this.dtdHandler; + return 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.

    - * + *

    + * 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. + * @throws NullPointerException if the handler argument is null. * @see #getContentHandler */ - public void setContentHandler(ContentHandler handler) { + @Override + public void setContentHandler(final ContentHandler handler) { if (handler == null) { throw new NullPointerException("handler"); } - this.contentHandler = handler; + contentHandler = handler; return; } /** * Returns the current content handler. - * - * @return the current content handler, or null if none - * has been registered. + * + * @return the current content handler, or null if none has been registered. * @see #setContentHandler */ + @Override public ContentHandler getContentHandler() { - return this.contentHandler; + return 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.

    - * + *

    + * 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. + * @throws NullPointerException if the handler argument is null. * @see #getErrorHandler */ - public void setErrorHandler(ErrorHandler handler) { + @Override + public void setErrorHandler(final ErrorHandler handler) { if (handler == null) { throw new NullPointerException("handler"); } - this.errorHandler = handler; + errorHandler = handler; return; } /** * Returns the current error handler. - * - * @return the current error handler, or null if none - * has been registered. + * + * @return the current error handler, or null if none has been registered. * @see #setErrorHandler */ + @Override public ErrorHandler getErrorHandler() { - return this.errorHandler; + return 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:

    + *

    + * 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));
    -     *  
    + * 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.

    - * + *

    + * 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. + * @throws SAXException Any SAX exception, possibly wrapping another exception. * @see #parse(org.xml.sax.InputSource) */ - public void parse(String systemId) throws SAXException { + @Override + public void parse(final 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. + *

    + * 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 { + @Override + public void parse(final 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. + * 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)); + XStream xstream = (XStream)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"); + final List source = (List)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); + startDocument(true); + for (final Object name : source) { + xstream.marshal(name, this); } - this.endDocument(true); - } catch (StreamException e) { + endDocument(true); + } catch (final StreamException e) { if (e.getCause() instanceof SAXException) { - throw (SAXException) (e.getCause()); + throw (SAXException)e.getCause(); } else { throw new SAXException(e); } } } - - //========================================================================= + // ========================================================================= // XStream HierarchicalStreamWriter interface support - //========================================================================= + // ========================================================================= private int depth = 0; - private List elementStack = new LinkedList(); + private final 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) { + @Override + public void startNode(final String name) { try { - if (this.depth != 0) { - this.flushStartTag(); + if (depth != 0) { + flushStartTag(); } else if (includeEnclosingDocument) { - this.startDocument(false); + startDocument(false); } - this.elementStack.add(0, name); + elementStack.add(0, escapeXmlName(name)); - this.startTagInProgress = true; - this.depth++; - } catch (SAXException e) { + startTagInProgress = true; + depth++; + } catch (final SAXException e) { throw new StreamException(e); } } - public void addAttribute(String name, String value) { - if (this.startTagInProgress) { - this.attributeList.addAttribute("", name, name, "CDATA", value); + @Override + public void addAttribute(final String name, final String value) { + if (startTagInProgress) { + final String escapedName = escapeXmlName(name); + attributeList.addAttribute("", escapedName, escapedName, "CDATA", value); } else { throw new StreamException(new IllegalStateException("No startElement being processed")); } } - public void setValue(String text) { + @Override + public void setValue(final String text) { try { - this.flushStartTag(); + flushStartTag(); - int lg = text.length(); + final 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) { + contentHandler.characters(buffer, 0, lg); + } catch (final SAXException e) { throw new StreamException(e); } } + @Override public void endNode() { try { - this.flushStartTag(); + flushStartTag(); - String tagName = (String) (this.elementStack.remove(0)); + final String tagName = elementStack.remove(0); - this.contentHandler.endElement("", tagName, tagName); + contentHandler.endElement("", tagName, tagName); - this.depth--; - if (this.depth == 0 && includeEnclosingDocument) { - this.endDocument(false); + depth--; + if (depth == 0 && includeEnclosingDocument) { + endDocument(false); } - } catch (SAXException e) { + } catch (final 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. + * 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) { + private void startDocument(final boolean multiObjectMode) throws SAXException { + if (depth == 0) { // Notify contentHandler of document start. - this.contentHandler.startDocument(); + contentHandler.startDocument(); if (multiObjectMode) { // Prevent marshalling of each object to fire its own // start/endDocument events. - this.depth++; + 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. + * 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; + private void endDocument(final boolean multiObjectMode) throws SAXException { + if (depth == 0 || depth == 1 && multiObjectMode) { + contentHandler.endDocument(); + depth = 0; } } /** - * Fires any pending SAX startElement event towards the - * configured ContentHandler. - * + * 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)); + if (startTagInProgress) { + final String tagName = elementStack.get(0); - this.contentHandler.startElement("", tagName, - tagName, this.attributeList); - this.attributeList.clear(); - this.startTagInProgress = false; + contentHandler.startElement("", tagName, tagName, attributeList); + attributeList.clear(); + startTagInProgress = false; } } + @Override public void flush() { // don't need to do anything } + @Override public void close() { // don't need to do anything } - - public HierarchicalStreamWriter underlyingWriter() { - return this; - } } - Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/SjsxpDriver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/StandardStaxDriver.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/StaxDriver.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/StaxDriver.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/StaxDriver.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/StaxDriver.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,145 +1,260 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 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 29. September 2004 by James Strachan + */ package com.thoughtworks.xstream.io.xml; -import com.thoughtworks.xstream.io.HierarchicalStreamDriver; -import com.thoughtworks.xstream.io.HierarchicalStreamReader; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; -import com.thoughtworks.xstream.io.StreamException; - -import javax.xml.stream.*; +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 - * + * A driver using the StAX API to create XML reader and writer. + * * @author James Strachan + * @author Jörg Schaible * @version $Revision$ */ -public class StaxDriver implements HierarchicalStreamDriver { +public class StaxDriver extends AbstractXmlDriver { - private static boolean libraryPresent; - private QNameMap qnameMap; private XMLInputFactory inputFactory; private XMLOutputFactory outputFactory; - private boolean repairingNamespace = false; public StaxDriver() { - this.qnameMap = new QNameMap(); + this(new QNameMap()); } - public StaxDriver(QNameMap qnameMap) { - this.qnameMap = qnameMap; + public StaxDriver(final QNameMap qnameMap) { + this(qnameMap, new XmlFriendlyNameCoder()); } - public StaxDriver(QNameMap qnameMap, boolean repairingNamespace) { + /** + * @since 1.4 + */ + public StaxDriver(final QNameMap qnameMap, final NameCoder nameCoder) { + super(nameCoder); this.qnameMap = qnameMap; - this.repairingNamespace = repairingNamespace; } - public HierarchicalStreamReader createReader(Reader xml) { - loadLibrary(); + /** + * @since 1.4 + */ + public StaxDriver(final NameCoder nameCoder) { + this(new QNameMap(), nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link StaxDriver#StaxDriver(QNameMap, NameCoder)} instead. + */ + @Deprecated + public StaxDriver(final QNameMap qnameMap, final XmlFriendlyReplacer replacer) { + this(qnameMap, (NameCoder)replacer); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link StaxDriver#StaxDriver(NameCoder)} instead. + */ + @Deprecated + public StaxDriver(final XmlFriendlyReplacer replacer) { + this(new QNameMap(), (NameCoder)replacer); + } + + @Override + public HierarchicalStreamReader createReader(final Reader xml) { try { - return new StaxReader(qnameMap, createParser(xml)); - } - catch (XMLStreamException e) { + return createStaxReader(createParser(xml)); + } catch (final XMLStreamException e) { throw new StreamException(e); } } - public HierarchicalStreamReader createReader(InputStream in) { - loadLibrary(); + @Override + public HierarchicalStreamReader createReader(final InputStream in) { try { - return new StaxReader(qnameMap, createParser(in)); - } - catch (XMLStreamException e) { + return createStaxReader(createParser(in)); + } catch (final XMLStreamException e) { throw new StreamException(e); } } - private void loadLibrary() { - if (!libraryPresent) { - try { - Class.forName("javax.xml.stream.XMLStreamReader"); - } - catch (ClassNotFoundException e) { - throw new IllegalArgumentException("StAX API is not present. Specify another driver." + - " For example: new XStream(new DomDriver())"); - } - libraryPresent = true; + @SuppressWarnings("resource") + @Override + public HierarchicalStreamReader createReader(final URL in) { + final InputStream stream; + try { + stream = in.openStream(); + final HierarchicalStreamReader reader = createStaxReader(createParser(new StreamSource(stream, in + .toExternalForm()))); + return new ReaderWrapper(reader) { + + @Override + public void close() { + super.close(); + try { + stream.close(); + } catch (final IOException e) { + // ignore + } + } + }; + } catch (final XMLStreamException e) { + throw new StreamException(e); + } catch (final IOException e) { + throw new StreamException(e); } } - public HierarchicalStreamWriter createWriter(Writer out) { + @SuppressWarnings("resource") + @Override + public HierarchicalStreamReader createReader(final File in) { + final InputStream stream; try { - return new StaxWriter(qnameMap, getOutputFactory().createXMLStreamWriter(out), true, isRepairingNamespace()); - } - catch (XMLStreamException e) { + stream = new FileInputStream(in); + final HierarchicalStreamReader reader = createStaxReader(createParser(new StreamSource(stream, in + .toURI() + .toASCIIString()))); + return new ReaderWrapper(reader) { + + @Override + public void close() { + super.close(); + try { + stream.close(); + } catch (final IOException e) { + // ignore + } + } + }; + } catch (final XMLStreamException e) { throw new StreamException(e); + } catch (final FileNotFoundException e) { + throw new StreamException(e); } } - public HierarchicalStreamWriter createWriter(OutputStream out) { + @Override + public HierarchicalStreamWriter createWriter(final Writer out) { try { - return new StaxWriter(qnameMap, getOutputFactory().createXMLStreamWriter(out), true, isRepairingNamespace()); + return createStaxWriter(getOutputFactory().createXMLStreamWriter(out)); + } catch (final XMLStreamException e) { + throw new StreamException(e); } - catch (XMLStreamException e) { + } + + @Override + public HierarchicalStreamWriter createWriter(final OutputStream out) { + try { + return createStaxWriter(getOutputFactory().createXMLStreamWriter(out)); + } catch (final XMLStreamException e) { throw new StreamException(e); } } - public AbstractPullReader createStaxReader(XMLStreamReader in) { - return new StaxReader(qnameMap, in); + public AbstractPullReader createStaxReader(final XMLStreamReader in) { + return new StaxReader(qnameMap, in, getNameCoder()); } - public StaxWriter createStaxWriter(XMLStreamWriter out, boolean writeStartEndDocument) throws XMLStreamException { - return new StaxWriter(qnameMap, out, writeStartEndDocument, repairingNamespace); + public StaxWriter createStaxWriter(final XMLStreamWriter out, final boolean writeStartEndDocument) + throws XMLStreamException { + return new StaxWriter(qnameMap, out, writeStartEndDocument, isRepairingNamespace(), getNameCoder()); } - public StaxWriter createStaxWriter(XMLStreamWriter out) throws XMLStreamException { + public StaxWriter createStaxWriter(final XMLStreamWriter out) throws XMLStreamException { return createStaxWriter(out, true); } - // Properties - //------------------------------------------------------------------------- + // ------------------------------------------------------------------------- public QNameMap getQnameMap() { return qnameMap; } - public void setQnameMap(QNameMap qnameMap) { + public void setQnameMap(final QNameMap qnameMap) { this.qnameMap = qnameMap; } public XMLInputFactory getInputFactory() { if (inputFactory == null) { - inputFactory = XMLInputFactory.newInstance(); + inputFactory = createInputFactory(); } return inputFactory; } public XMLOutputFactory getOutputFactory() { if (outputFactory == null) { - outputFactory = XMLOutputFactory.newInstance(); - outputFactory.setProperty("javax.xml.stream.isRepairingNamespaces", isRepairingNamespace() ? Boolean.TRUE : Boolean.FALSE); + outputFactory = createOutputFactory(); } return outputFactory; } public boolean isRepairingNamespace() { - return repairingNamespace; + return Boolean.TRUE.equals(getOutputFactory().getProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES)); } + /** + * @since 1.2 + */ + public void setRepairingNamespace(final boolean repairing) { + getOutputFactory().setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, + repairing ? Boolean.TRUE : Boolean.FALSE); + } // Implementation methods - //------------------------------------------------------------------------- - protected XMLStreamReader createParser(Reader xml) throws XMLStreamException { + // ------------------------------------------------------------------------- + protected XMLStreamReader createParser(final Reader xml) throws XMLStreamException { return getInputFactory().createXMLStreamReader(xml); } - protected XMLStreamReader createParser(InputStream xml) throws XMLStreamException { + protected XMLStreamReader createParser(final InputStream xml) throws XMLStreamException { return getInputFactory().createXMLStreamReader(xml); } + + protected XMLStreamReader createParser(final 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(); + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/StaxReader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/StaxReader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/StaxReader.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/StaxReader.java 10 Nov 2014 12:07:37 -0000 1.1.2.1 @@ -1,16 +1,29 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 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 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 javax.xml.namespace.QName; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; +import com.thoughtworks.xstream.converters.ErrorWriter; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.naming.NameCoder; + + /** * A reader using the StAX API. - * + * * @author James Strachan * @version $Revision$ */ @@ -19,69 +32,95 @@ private final QNameMap qnameMap; private final XMLStreamReader in; - public StaxReader(QNameMap qnameMap, XMLStreamReader in) { + public StaxReader(final QNameMap qnameMap, final XMLStreamReader in) { + this(qnameMap, in, new XmlFriendlyNameCoder()); + } + + /** + * @since 1.4 + */ + public StaxReader(final QNameMap qnameMap, final XMLStreamReader in, final 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. + */ + @Deprecated + public StaxReader(final QNameMap qnameMap, final XMLStreamReader in, final XmlFriendlyReplacer replacer) { + this(qnameMap, in, (NameCoder)replacer); + } + + @Override 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; + 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) { + } catch (final XMLStreamException e) { throw new StreamException(e); } } + @Override protected String pullElementName() { // let the QNameMap handle any mapping of QNames to Java class names - QName qname = in.getName(); + final QName qname = in.getName(); return qnameMap.getJavaClassName(qname); } + @Override protected String pullText() { return in.getText(); } - public String getAttribute(String name) { - return in.getAttributeValue(null, name); + @Override + public String getAttribute(final String name) { + return in.getAttributeValue(null, encodeAttribute(name)); } - public String getAttribute(int index) { + @Override + public String getAttribute(final int index) { return in.getAttributeValue(index); } + @Override public int getAttributeCount() { return in.getAttributeCount(); } - public String getAttributeName(int index) { - return in.getAttributeLocalName(index); + @Override + public String getAttributeName(final int index) { + return decodeAttribute(in.getAttributeLocalName(index)); } - public void appendErrors(ErrorWriter errorWriter) { + @Override + public void appendErrors(final ErrorWriter errorWriter) { errorWriter.add("line number", String.valueOf(in.getLocation().getLineNumber())); } + @Override public void close() { try { in.close(); - } catch (XMLStreamException e) { + } catch (final XMLStreamException e) { throw new StreamException(e); } } -} \ No newline at end of file +} Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/StaxWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/StaxWriter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/StaxWriter.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/StaxWriter.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,39 +1,72 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 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 29. September 2004 by James Strachan + */ package com.thoughtworks.xstream.io.xml; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; -import com.thoughtworks.xstream.io.StreamException; - import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; +import com.thoughtworks.xstream.io.StreamException; +import com.thoughtworks.xstream.io.naming.NameCoder; + + /** * A stream writing that outputs to a StAX stream writer - * + * * @author James Strachan * @version $Revision$ */ -public class StaxWriter implements HierarchicalStreamWriter { +public class StaxWriter extends AbstractXmlWriter { + private final QNameMap qnameMap; private final XMLStreamWriter out; private final boolean writeEnclosingDocument; - private boolean namespaceRepairingMode; + private final boolean namespaceRepairingMode; private int tagDepth; - public StaxWriter(QNameMap qnameMap, XMLStreamWriter out) throws XMLStreamException { + public StaxWriter(final QNameMap qnameMap, final 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 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(final QNameMap qnameMap, final XMLStreamWriter out, final 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) throws XMLStreamException { + public StaxWriter( + final QNameMap qnameMap, final XMLStreamWriter out, final boolean writeEnclosingDocument, + final boolean namespaceRepairingMode, final NameCoder nameCoder) throws XMLStreamException { + super(nameCoder); this.qnameMap = qnameMap; this.out = out; this.writeEnclosingDocument = writeEnclosingDocument; @@ -43,121 +76,153 @@ } } + /** + * 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( + final QNameMap qnameMap, final XMLStreamWriter out, final boolean writeEnclosingDocument, + final 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 + */ + @Deprecated + public StaxWriter( + final QNameMap qnameMap, final XMLStreamWriter out, final boolean writeEnclosingDocument, + final boolean namespaceRepairingMode, final XmlFriendlyReplacer replacer) throws XMLStreamException { + this(qnameMap, out, writeEnclosingDocument, namespaceRepairingMode, (NameCoder)replacer); + } + + @Override public void flush() { try { - out.close(); - } - catch (XMLStreamException e) { + out.flush(); + } catch (final XMLStreamException e) { throw new StreamException(e); } } /** * Call this method when you're finished with me */ + @Override public void close() { try { out.close(); - } - catch (XMLStreamException e) { + } catch (final XMLStreamException e) { throw new StreamException(e); } } - public void addAttribute(String name, String value) { + @Override + public void addAttribute(final String name, final String value) { try { - out.writeAttribute(name, value); - } - catch (XMLStreamException e) { + out.writeAttribute(encodeAttribute(name), value); + } catch (final XMLStreamException e) { throw new StreamException(e); } } + @Override public void endNode() { try { tagDepth--; out.writeEndElement(); if (tagDepth == 0 && writeEnclosingDocument) { out.writeEndDocument(); } - } - catch (XMLStreamException e) { + } catch (final XMLStreamException e) { throw new StreamException(e); } } - public void setValue(String text) { + @Override + public void setValue(final String text) { try { out.writeCharacters(text); - } - catch (XMLStreamException e) { + } catch (final XMLStreamException e) { throw new StreamException(e); } } - public void startNode(String name) { + @Override + public void startNode(final String name) { try { - QName qname = qnameMap.getQName(name); - String prefix = qname.getPrefix(); - String uri = qname.getNamespaceURI(); + final QName qname = qnameMap.getQName(encodeNode(name)); + final String prefix = qname.getPrefix(); + final 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; + final boolean hasPrefix = prefix != null && prefix.length() > 0; + final boolean hasURI = uri != null && uri.length() > 0; boolean writeNamespace = false; if (hasURI) { if (hasPrefix) { - String currentNamespace = out.getNamespaceContext().getNamespaceURI(prefix); + final String currentNamespace = out.getNamespaceContext().getNamespaceURI(prefix); if (currentNamespace == null || !currentNamespace.equals(uri)) { writeNamespace = true; } - } - else { - String defaultNamespace = out.getNamespaceContext().getNamespaceURI(""); + } else { + final 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) { + } else if (hasURI) { if (writeNamespace) { out.setDefaultNamespace(uri); } } - out.writeStartElement(prefix, qname.getLocalPart(), uri); if (hasURI && writeNamespace && !isNamespaceRepairingMode()) { if (hasPrefix) { out.writeNamespace(prefix, uri); - } - else { + } else { out.writeDefaultNamespace(uri); } } tagDepth++; - } - catch (XMLStreamException e) { + } catch (final XMLStreamException e) { throw new StreamException(e); } } - public HierarchicalStreamWriter underlyingWriter() { - return this; - } - /** * Is StAX namespace repairing mode on or off? - * - * @return */ public boolean isNamespaceRepairingMode() { return namespaceRepairingMode; } + protected QNameMap getQNameMap() { + return qnameMap; + } + + protected XMLStreamWriter getXMLStreamWriter() { + return out; + } + } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/TraxSource.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/TraxSource.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/TraxSource.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/TraxSource.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,62 +1,72 @@ +/* + * 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 14. August 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; -import com.thoughtworks.xstream.XStream; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.transform.sax.SAXSource; + 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; +import com.thoughtworks.xstream.XStream; + /** - * 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) {
    + * 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));
    - *       XStreamSource in = new XStreamSource(source);
    - *       Writer out = new StringWriter();
    - *       transformer.transform(in, new StreamResult(out));
    - *       return out.toString();
    + *         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);
      *     }
    - *     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 + * 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"; + 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. - * + * The XMLReader object associated to this source or null if no XMLReader has yet been requested. + * * @see #getXMLReader */ private XMLReader xmlReader = null; @@ -69,12 +79,11 @@ /** * The list of Java objects to be serialized. */ - private List source = null; + private List source = null; - - //------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // Constructors - //------------------------------------------------------------------------- + // ------------------------------------------------------------------------- /** * Creates a XStream TrAX source. @@ -84,226 +93,209 @@ } /** - * Creates a XStream TrAX source, specifying the object to - * marshal. - * + * Creates a XStream TrAX source, specifying the object to marshal. + * * @param source the object to marshal. - * @throws IllegalArgumentException if source is - * null. + * @throws IllegalArgumentException if source is null. * @see #setSource(java.lang.Object) */ - public TraxSource(Object source) { + public TraxSource(final Object source) { super(new InputSource()); - this.setSource(source); + 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. + * 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. + * @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) { + public TraxSource(final Object source, final XStream xstream) { super(new InputSource()); - this.setSource(source); - this.setXStream(xstream); + setSource(source); + setXStream(xstream); } /** - * Creates a XStream TrAX source, setting the objects to - * marshal. - * + * 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. + * @throws IllegalArgumentException if source is null or empty. * @see #setSourceAsList(java.util.List) */ - public TraxSource(List source) { + public TraxSource(final List source) { super(new InputSource()); - this.setSourceAsList(source); + 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. + * 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. + * @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) { + public TraxSource(final List source, final XStream xstream) { super(new InputSource()); - this.setSourceAsList(source); - this.setXStream(xstream); + setSourceAsList(source); + 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 + *

    + * 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) { + @Override + public void setInputSource(final 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.

    - * + *

    + * 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}. + * @throws UnsupportedOperationException if reader is not a SAX {@link XMLFilter}. * @see #getXMLReader */ - public void setXMLReader(XMLReader reader) { - this.createXMLReader(reader); + @Override + public void setXMLReader(final XMLReader reader) { + 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 + *

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

    + * 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. + * @throws IllegalArgumentException if source is null or empty. */ - public void setSourceAsList(List list) { - if ((list == null) || (list.isEmpty())) { + public void setSourceAsList(final List list) { + if (list == null || list.isEmpty()) { throw new IllegalArgumentException("list"); } - this.source = list; + source = list; - this.configureXMLReader(); + configureXMLReader(); } - private void createXMLReader(XMLReader filterChain) { + private void createXMLReader(final XMLReader filterChain) { if (filterChain == null) { - this.xmlReader = new SaxWriter(); + xmlReader = new SaxWriter(); } else { if (filterChain instanceof XMLFilter) { // Connect the filter chain to a document reader. - XMLFilter filter = (XMLFilter) filterChain; + XMLFilter filter = (XMLFilter)filterChain; while (filter.getParent() instanceof XMLFilter) { - filter = (XMLFilter) (filter.getParent()); + filter = (XMLFilter)filter.getParent(); } - filter.setParent(new SaxWriter()); + if (!(filter.getParent() instanceof SaxWriter)) { + @SuppressWarnings("resource") + final SaxWriter saxWriter = new SaxWriter(); + filter.setParent(saxWriter); + } // Read XML data from filter chain. - this.xmlReader = filterChain; + xmlReader = filterChain; } else { throw new UnsupportedOperationException(); } } - this.configureXMLReader(); + configureXMLReader(); } private void configureXMLReader() { - if (this.xmlReader != null) { + if (xmlReader != null) { try { - if (this.xstream != null) { - this.xmlReader.setProperty(SaxWriter.CONFIGURED_XSTREAM_PROPERTY, this.xstream); + if (xstream != null) { + xmlReader.setProperty(SaxWriter.CONFIGURED_XSTREAM_PROPERTY, xstream); } - if (this.source != null) { - this.xmlReader.setProperty(SaxWriter.SOURCE_OBJECT_LIST_PROPERTY, this.source); + if (source != null) { + xmlReader.setProperty(SaxWriter.SOURCE_OBJECT_LIST_PROPERTY, source); } - } catch (SAXException e) { + } catch (final SAXException e) { throw new IllegalArgumentException(e.getMessage()); } } } } - Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/WstxDriver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XStream11NameCoder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XStream11XmlFriendlyReplacer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XmlFriendlyNameCoder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XmlFriendlyReader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XmlFriendlyReplacer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XmlFriendlyWriter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XomDriver.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XomReader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XomReader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XomReader.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XomReader.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,66 +1,135 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 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 02. September 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; -import nu.xom.*; +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) { + public XomReader(final Element rootElement) { super(rootElement); } - public XomReader(Document document) { + public XomReader(final Document document) { super(document.getRootElement()); } + /** + * @since 1.4 + */ + public XomReader(final Element rootElement, final NameCoder nameCoder) { + super(rootElement, nameCoder); + } + + /** + * @since 1.4 + */ + public XomReader(final Document document, final NameCoder nameCoder) { + super(document.getRootElement(), nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link XomReader#XomReader(Element, NameCoder)} instead. + */ + @Deprecated + public XomReader(final Element rootElement, final XmlFriendlyReplacer replacer) { + this(rootElement, (NameCoder)replacer); + } + + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link XomReader#XomReader(Element, NameCoder)} instead. + */ + @Deprecated + public XomReader(final Document document, final XmlFriendlyReplacer replacer) { + this(document.getRootElement(), (NameCoder)replacer); + } + + @Override public String getNodeName() { - return currentElement.getLocalName(); + return decodeNode(currentElement.getLocalName()); } + @Override 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); + final StringBuffer result = new StringBuffer(); + final int childCount = currentElement.getChildCount(); + for (int i = 0; i < childCount; i++) { + final Node child = currentElement.getChild(i); if (child instanceof Text) { - Text text = (Text) child; + final Text text = (Text)child; result.append(text.getValue()); } } return result.toString(); } - public String getAttribute(String name) { - return currentElement.getAttributeValue(name); + @Override + public String getAttribute(final String name) { + return currentElement.getAttributeValue(encodeAttribute(name)); } - public String getAttribute(int index) { + @Override + public String getAttribute(final int index) { return currentElement.getAttribute(index).getValue(); } + @Override public int getAttributeCount() { return currentElement.getAttributeCount(); } - public String getAttributeName(int index) { - return currentElement.getAttribute(index).getQualifiedName(); + @Override + public String getAttributeName(final int index) { + return decodeAttribute(currentElement.getAttribute(index).getQualifiedName()); } + @Override protected int getChildCount() { return currentElement.getChildElements().size(); } + @Override protected Object getParent() { return currentElement.getParent(); } - protected Object getChild(int index) { + @Override + protected Object getChild(final int index) { return currentElement.getChildElements().get(index); } - protected void reassignCurrentElement(Object current) { - currentElement = (Element) current; + @Override + protected void reassignCurrentElement(final Object current) { + currentElement = (Element)current; } + + @Override + public String peekNextChild() { + final Elements children = currentElement.getChildElements(); + if (null == children || children.size() == 0) { + return null; + } + return decodeNode(children.get(0).getLocalName()); + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XomWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XomWriter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XomWriter.java 10 Sep 2012 19:03:06 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XomWriter.java 10 Nov 2014 12:07:37 -0000 1.1.2.1 @@ -1,44 +1,72 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 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 03. September 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; -import nu.xom.Element; +import com.thoughtworks.xstream.io.naming.NameCoder; + import nu.xom.Attribute; +import nu.xom.Element; -public class XomWriter implements HierarchicalStreamWriter { - private Element node; +public class XomWriter extends AbstractDocumentWriter { - public XomWriter(Element parentElement) { - this.node = parentElement; + /** + * @since 1.2.1 + */ + public XomWriter() { + this(null); } - public void startNode(String name) { - Element newNode = new Element(name); - node.appendChild(newNode); - node = newNode; + public XomWriter(final Element parentElement) { + this(parentElement, new XmlFriendlyNameCoder()); } - public void addAttribute(String name, String value) { - node.addAttribute(new Attribute(name, value)); + /** + * @since 1.4 + */ + public XomWriter(final Element parentElement, final NameCoder nameCoder) { + super(parentElement, nameCoder); } - public void setValue(String text) { - node.appendChild(text); + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link XomWriter#XomWriter(Element, NameCoder)} instead + */ + @Deprecated + public XomWriter(final Element parentElement, final XmlFriendlyReplacer replacer) { + this(parentElement, (NameCoder)replacer); } - public void endNode() { - node = (Element) node.getParent(); + @Override + 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 flush() { - // don't need to do anything + @Override + public void addAttribute(final String name, final String value) { + top().addAttribute(new Attribute(encodeAttribute(name), value)); } - public void close() { - // don't need to do anything + @Override + public void setValue(final String text) { + top().appendChild(text); } - public HierarchicalStreamWriter underlyingWriter() { - return this; + private Element top() { + return (Element)getCurrent(); } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/Xpp3DomDriver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/Xpp3Driver.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppDomDriver.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppDomDriver.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppDomDriver.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppDomDriver.java 10 Nov 2014 12:07:37 -0000 1.1.2.1 @@ -1,32 +1,59 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 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 07. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + import com.thoughtworks.xstream.io.HierarchicalStreamDriver; -import com.thoughtworks.xstream.io.HierarchicalStreamReader; -import com.thoughtworks.xstream.io.StreamException; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; -import com.thoughtworks.xstream.io.xml.xppdom.Xpp3DomBuilder; +import com.thoughtworks.xstream.io.naming.NameCoder; -import java.io.*; -public class XppDomDriver implements HierarchicalStreamDriver { +/** + * 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 { - public HierarchicalStreamReader createReader(Reader xml) { - try { - return new XppDomReader(Xpp3DomBuilder.build(xml)); - } catch (Exception e) { - throw new StreamException(e); - } + private static XmlPullParserFactory factory; + + public XppDomDriver() { + super(new XmlFriendlyNameCoder()); } - public HierarchicalStreamReader createReader(InputStream in) { - return createReader(new InputStreamReader(in)); + /** + * @since 1.4 + */ + public XppDomDriver(final NameCoder nameCoder) { + super(nameCoder); } - public HierarchicalStreamWriter createWriter(Writer out) { - return new PrettyPrintWriter(out); + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link XppDomDriver#XppDomDriver(NameCoder)} instead. + */ + @Deprecated + public XppDomDriver(final XmlFriendlyReplacer replacer) { + super(replacer); } - public HierarchicalStreamWriter createWriter(OutputStream out) { - return createWriter(new OutputStreamWriter(out)); + @Override + protected synchronized XmlPullParser createParser() throws XmlPullParserException { + if (factory == null) { + factory = XmlPullParserFactory.newInstance(null, XppDomDriver.class); + } + return factory.newPullParser(); } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppDomReader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppDomReader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppDomReader.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppDomReader.java 10 Nov 2014 12:07:36 -0000 1.1.2.1 @@ -1,65 +1,111 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 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 07. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; -import com.thoughtworks.xstream.io.xml.xppdom.Xpp3Dom; +import com.thoughtworks.xstream.io.naming.NameCoder; +import com.thoughtworks.xstream.io.xml.xppdom.XppDom; + /** - * @author Jason van Zyl - * @version $Id$ + * @author Jason van Zyl */ public class XppDomReader extends AbstractDocumentReader { - private Xpp3Dom currentElement; + private XppDom currentElement; - public XppDomReader(Xpp3Dom xpp3Dom) { - super(xpp3Dom); + public XppDomReader(final XppDom xppDom) { + super(xppDom); } + /** + * @since 1.4 + */ + public XppDomReader(final XppDom xppDom, final NameCoder nameCoder) { + super(xppDom, nameCoder); + } + + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link XppDomReader#XppDomReader(XppDom, NameCoder)} instead. + */ + @Deprecated + public XppDomReader(final XppDom xppDom, final XmlFriendlyReplacer replacer) { + this(xppDom, (NameCoder)replacer); + } + + @Override public String getNodeName() { - return currentElement.getName(); + return decodeNode(currentElement.getName()); } + @Override public String getValue() { String text = null; try { text = currentElement.getValue(); - } catch (Exception e) { + } catch (final Exception e) { // do nothing. } return text == null ? "" : text; } - public String getAttribute(String attributeName) { - return currentElement.getAttribute(attributeName); + @Override + public String getAttribute(final String attributeName) { + return currentElement.getAttribute(encodeAttribute(attributeName)); } - public String getAttribute(int index) { + @Override + public String getAttribute(final int index) { return currentElement.getAttribute(currentElement.getAttributeNames()[index]); } + @Override public int getAttributeCount() { return currentElement.getAttributeNames().length; } - public String getAttributeName(int index) { - return currentElement.getAttributeNames()[index]; + @Override + public String getAttributeName(final int index) { + return decodeAttribute(currentElement.getAttributeNames()[index]); } + @Override protected Object getParent() { return currentElement.getParent(); } - protected Object getChild(int index) { + @Override + protected Object getChild(final int index) { return currentElement.getChild(index); } + @Override protected int getChildCount() { return currentElement.getChildCount(); } - protected void reassignCurrentElement(Object current) { - this.currentElement = (Xpp3Dom) current; + @Override + protected void reassignCurrentElement(final Object current) { + currentElement = (XppDom)current; } + @Override + public String peekNextChild() { + if (currentElement.getChildCount() == 0) { + return null; + } + return decodeNode(currentElement.getChild(0).getName()); + } + } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppDomWriter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppDomWriter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppDomWriter.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppDomWriter.java 10 Nov 2014 12:07:37 -0000 1.1.2.1 @@ -1,60 +1,89 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 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 07. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; -import com.thoughtworks.xstream.io.xml.xppdom.Xpp3Dom; +import com.thoughtworks.xstream.io.naming.NameCoder; +import com.thoughtworks.xstream.io.xml.xppdom.XppDom; -import java.util.LinkedList; -public class XppDomWriter implements HierarchicalStreamWriter { - private LinkedList elementStack = new LinkedList(); - - private Xpp3Dom configuration; - +public class XppDomWriter extends AbstractDocumentWriter { public XppDomWriter() { + this(null, new XmlFriendlyNameCoder()); } - public Xpp3Dom getConfiguration() { - return configuration; + /** + * @since 1.2.1 + */ + public XppDomWriter(final XppDom parent) { + this(parent, new XmlFriendlyNameCoder()); } - public void startNode(String name) { - Xpp3Dom configuration = new Xpp3Dom(name); + /** + * @since 1.4 + */ + public XppDomWriter(final NameCoder nameCoder) { + this(null, nameCoder); + } - if (this.configuration == null) { - this.configuration = configuration; - } else { - top().addChild(configuration); - } - - elementStack.addLast(configuration); + /** + * @since 1.4 + */ + public XppDomWriter(final XppDom parent, final NameCoder nameCoder) { + super(parent, nameCoder); } - public void setValue(String text) { - top().setValue(text); + /** + * @since 1.2 + * @deprecated As of 1.4 use {@link XppDomWriter#XppDomWriter(NameCoder)} instead + */ + @Deprecated + public XppDomWriter(final XmlFriendlyReplacer replacer) { + this(null, replacer); } - public void addAttribute(String key, String value) { - top().setAttribute(key, value); + /** + * @since 1.2.1 + * @deprecated As of 1.4 use {@link XppDomWriter#XppDomWriter(XppDom, NameCoder)} instead. + */ + @Deprecated + public XppDomWriter(final XppDom parent, final XmlFriendlyReplacer replacer) { + this(parent, (NameCoder)replacer); } - public void endNode() { - elementStack.removeLast(); + public XppDom getConfiguration() { + return (XppDom)getTopLevelNodes().get(0); } - private Xpp3Dom top() { - return (Xpp3Dom) elementStack.getLast(); + @Override + 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 flush() { - // don't need to do anything + @Override + public void setValue(final String text) { + top().setValue(text); } - public void close() { - // don't need to do anything + @Override + public void addAttribute(final String key, final String value) { + top().setAttribute(encodeAttribute(key), value); } - public HierarchicalStreamWriter underlyingWriter() { - return this; + private XppDom top() { + return (XppDom)getCurrent(); } - } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppDriver.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppDriver.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppDriver.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppDriver.java 10 Nov 2014 12:07:37 -0000 1.1.2.1 @@ -1,41 +1,59 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 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 08. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + import com.thoughtworks.xstream.io.HierarchicalStreamDriver; -import com.thoughtworks.xstream.io.HierarchicalStreamReader; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.naming.NameCoder; -import java.io.*; -public class XppDriver implements HierarchicalStreamDriver { +/** + * 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 boolean xppLibraryPresent; + private static XmlPullParserFactory factory; - public HierarchicalStreamReader createReader(Reader xml) { - loadLibrary(); - return new XppReader(xml); + public XppDriver() { + super(new XmlFriendlyNameCoder()); } - public HierarchicalStreamReader createReader(InputStream in) { - return createReader(new InputStreamReader(in)); + /** + * @since 1.4 + */ + public XppDriver(final NameCoder nameCoder) { + super(nameCoder); } - private void loadLibrary() { - if (!xppLibraryPresent) { - try { - Class.forName("org.xmlpull.mxp1.MXParser"); - } catch (ClassNotFoundException e) { - throw new IllegalArgumentException("XPP3 pull parser library not present. Specify another driver." + - " For example: new XStream(new DomDriver())"); - } - xppLibraryPresent = true; - } + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link XppDriver#XppDriver(NameCoder)} instead. + */ + @Deprecated + public XppDriver(final XmlFriendlyReplacer replacer) { + this((NameCoder)replacer); } - public HierarchicalStreamWriter createWriter(Writer out) { - return new PrettyPrintWriter(out); + @Override + protected synchronized XmlPullParser createParser() throws XmlPullParserException { + if (factory == null) { + factory = XmlPullParserFactory.newInstance(); + } + return factory.newPullParser(); } - - public HierarchicalStreamWriter createWriter(OutputStream out) { - return createWriter(new OutputStreamWriter(out)); - } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppReader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppReader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppReader.java 10 Sep 2012 19:03:05 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/XppReader.java 10 Nov 2014 12:07:37 -0000 1.1.2.1 @@ -1,100 +1,182 @@ +/* + * Copyright (C) 2004, 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 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 08. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml; -import com.thoughtworks.xstream.converters.ErrorWriter; -import com.thoughtworks.xstream.io.StreamException; -import org.xmlpull.mxp1.MXParser; +import java.io.IOException; +import java.io.Reader; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.Reader; +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 BufferedReader reader; + private final Reader reader; - public XppReader(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(final Reader reader, final 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(final Reader reader, final XmlPullParser parser, final NameCoder nameCoder) { + super(nameCoder); + this.parser = parser; + this.reader = reader; try { + parser.setInput(this.reader); + } catch (final XmlPullParserException e) { + throw new StreamException(e); + } + moveDown(); + } + + /** + * @deprecated As of 1.4, use {@link #XppReader(Reader, XmlPullParser)} instead + */ + @Deprecated + public XppReader(final Reader reader) { + this(reader, new XmlFriendlyReplacer()); + } + + /** + * @since 1.2 + * @deprecated As of 1.4, use {@link #XppReader(Reader, XmlPullParser, NameCoder)} instead + */ + @Deprecated + public XppReader(final Reader reader, final XmlFriendlyReplacer replacer) { + super(replacer); + try { parser = createParser(); - this.reader = new BufferedReader(reader); + this.reader = reader; parser.setInput(this.reader); moveDown(); - } catch (XmlPullParserException e) { + } catch (final 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 */ + @Deprecated protected XmlPullParser createParser() { - return new MXParser(); + Exception exception = null; + try { + return (XmlPullParser)Class + .forName("org.xmlpull.mxp1.MXParser", true, XmlPullParser.class.getClassLoader()) + .newInstance(); + } catch (final InstantiationException e) { + exception = e; + } catch (final IllegalAccessException e) { + exception = e; + } catch (final ClassNotFoundException e) { + exception = e; + } + throw new StreamException("Cannot create Xpp3 parser instance.", exception); } + @Override 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; + 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) { + } catch (final XmlPullParserException e) { throw new StreamException(e); - } catch (IOException e) { + } catch (final IOException e) { throw new StreamException(e); } } + @Override protected String pullElementName() { return parser.getName(); } + @Override protected String pullText() { return parser.getText(); } - public String getAttribute(String name) { - return parser.getAttributeValue(null, name); + @Override + public String getAttribute(final String name) { + return parser.getAttributeValue(null, encodeAttribute(name)); } - public String getAttribute(int index) { + @Override + public String getAttribute(final int index) { return parser.getAttributeValue(index); } + @Override public int getAttributeCount() { return parser.getAttributeCount(); } - public String getAttributeName(int index) { - return parser.getAttributeName(index); + @Override + public String getAttributeName(final int index) { + return decodeAttribute(parser.getAttributeName(index)); } - public void appendErrors(ErrorWriter errorWriter) { + @Override + public void appendErrors(final ErrorWriter errorWriter) { errorWriter.add("line number", String.valueOf(parser.getLineNumber())); } + @Override public void close() { try { reader.close(); - } catch (IOException e) { + } catch (final IOException e) { throw new StreamException(e); } } -} \ No newline at end of file +} Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/xppdom/Xpp3Dom.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/xppdom/Xpp3Dom.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/xppdom/Xpp3Dom.java 10 Sep 2012 19:03:07 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/xppdom/Xpp3Dom.java 10 Nov 2014 12:07:42 -0000 1.1.2.1 @@ -1,137 +1,32 @@ +/* + * Copyright (C) 2004 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 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 07. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml.xppdom; -import java.util.ArrayList; -import java.util.HashMap; -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 + * @deprecated As of 1.4, use {@link XppDom} instead + */ +@Deprecated +public class Xpp3Dom extends XppDom { -public class Xpp3Dom { - protected String name; - - protected String value; - - protected Map attributes; - - protected List childList; - - protected Map childMap; - - protected Xpp3Dom parent; - - public Xpp3Dom(String name) { - this.name = name; - childList = new ArrayList(); - childMap = new HashMap(); + /** + * @deprecated As of 1.4, use {@link XppDom} instead + */ + @Deprecated + public Xpp3Dom(final String name) { + super(name); } - - // ---------------------------------------------------------------------- - // 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 Xpp3Dom getChild(int i) { - return (Xpp3Dom) childList.get(i); - } - - public Xpp3Dom getChild(String name) { - return (Xpp3Dom) childMap.get(name); - } - - public void addChild(Xpp3Dom xpp3Dom) { - xpp3Dom.setParent(this); - childList.add(xpp3Dom); - childMap.put(xpp3Dom.getName(), xpp3Dom); - } - - public Xpp3Dom[] getChildren() { - if ( null == childList ) { - return new Xpp3Dom[0]; - } - else { - return (Xpp3Dom[]) childList.toArray( new Xpp3Dom[0] ); - } - } - - public Xpp3Dom[] getChildren( String name ) { - if ( null == childList ) { - return new Xpp3Dom[0]; - } - else { - ArrayList children = new ArrayList(); - int size = this.childList.size(); - - for ( int i = 0; i < size; i++ ) { - Xpp3Dom configuration = (Xpp3Dom) this.childList.get( i ); - if ( name.equals( configuration.getName() ) ) { - children.add( configuration ); - } - } - - return (Xpp3Dom[]) children.toArray( new Xpp3Dom[0] ); - } - } - - public int getChildCount() { - if (null == childList) { - return 0; - } - - return childList.size(); - } - - // ---------------------------------------------------------------------- - // Parent handling - // ---------------------------------------------------------------------- - - public Xpp3Dom getParent() { - return parent; - } - - public void setParent(Xpp3Dom parent) { - this.parent = parent; - } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/xppdom/Xpp3DomBuilder.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/xppdom/Xpp3DomBuilder.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/xppdom/Xpp3DomBuilder.java 10 Sep 2012 19:03:07 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/xppdom/Xpp3DomBuilder.java 10 Nov 2014 12:07:42 -0000 1.1.2.1 @@ -1,88 +1,41 @@ +/* + * Copyright (C) 2004, 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2009, 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 07. March 2004 by Joe Walnes + */ package com.thoughtworks.xstream.io.xml.xppdom; +import java.io.Reader; + import org.xmlpull.mxp1.MXParser; import org.xmlpull.v1.XmlPullParser; -import java.io.Reader; -import java.util.ArrayList; -import java.util.List; +/** + * @author Jason van Zyl + * @author Joe Walnes + * @author Jörg Schaible + * @deprecated As of 1.4, use {@link XppDom#build(XmlPullParser)} instead + */ +@Deprecated public class Xpp3DomBuilder { - public static Xpp3Dom build(Reader reader) - throws Exception { - List elements = new ArrayList(); - - List values = new ArrayList(); - - Xpp3Dom node = null; - - XmlPullParser parser = new MXParser(); - + /** + * @deprecated As of 1.4, use {@link XppDom#build(XmlPullParser)} instead + */ + @Deprecated + public static Xpp3Dom build(final Reader reader) throws Exception { + final XmlPullParser parser = new MXParser(); parser.setInput(reader); - - int eventType = parser.getEventType(); - - while (eventType != XmlPullParser.END_DOCUMENT) { - if (eventType == XmlPullParser.START_TAG) { - String rawName = parser.getName(); - - Xpp3Dom child = new Xpp3Dom(rawName); - - int depth = elements.size(); - - if (depth > 0) { - Xpp3Dom parent = (Xpp3Dom) 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; - - Xpp3Dom finalNode = (Xpp3Dom) 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(); + try { + return (Xpp3Dom)XppDom.build(parser); + } finally { + reader.close(); } - - reader.close(); - - return node; } - -} \ No newline at end of file +} Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/xppdom/XppDom.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/xppdom/XppDomComparator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/io/xml/xppdom/XppFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/AbstractAttributeAliasingMapper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/AbstractXmlFriendlyMapper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/AnnotationConfiguration.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/AnnotationMapper.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/ArrayMapper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/ArrayMapper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/ArrayMapper.java 10 Sep 2012 19:03:00 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/ArrayMapper.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,43 +1,49 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 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 22. January 2005 by Joe Walnes + */ package com.thoughtworks.xstream.mapper; -import com.thoughtworks.xstream.alias.ClassMapper; -import com.thoughtworks.xstream.alias.CannotResolveClassException; +import com.thoughtworks.xstream.core.util.Primitives; -import java.util.Arrays; -import java.util.Collection; /** - * 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 + * 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 { - private final static Collection BOXED_TYPES = Arrays.asList( - new Class[] { - Boolean.class, - Byte.class, - Character.class, - Short.class, - Integer.class, - Long.class, - Float.class, - Double.class - }); - - public ArrayMapper(ClassMapper wrapped) { + public ArrayMapper(final Mapper wrapped) { super(wrapped); } - public String serializedClass(Class type) { - StringBuffer arraySuffix = new StringBuffer(); + @Override + public String serializedClass(Class type) { + final StringBuilder arraySuffix = new StringBuilder(); + String name = null; while (type.isArray()) { - type = type.getComponentType(); - arraySuffix.append("-array"); + name = super.serializedClass(type); + if (type.getName().equals(name)) { + type = type.getComponentType(); + arraySuffix.append("-array"); + name = null; + } else { + break; + } } - String name = boxedTypeName(type); if (name == null) { + name = boxedTypeName(type); + } + if (name == null) { name = super.serializedClass(type); } if (arraySuffix.length() > 0) { @@ -47,72 +53,46 @@ } } - public Class realClass(String elementName) { + @Override + 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++; + ++dimensions; } if (dimensions > 0) { - Class componentType = primitiveClassNamed(elementName); + Class componentType = Primitives.primitiveType(elementName); if (componentType == null) { componentType = super.realClass(elementName); } - try { - return arrayType(dimensions, componentType); - } catch (ClassNotFoundException e) { - throw new CannotResolveClassException(elementName + " : " + e.getMessage()); + while (componentType.isArray()) { + componentType = componentType.getComponentType(); + ++dimensions; } + return super.realClass(arrayType(dimensions, componentType)); } else { return super.realClass(elementName); } } - private Class arrayType(int dimensions, Class componentType) throws ClassNotFoundException { - StringBuffer className = new StringBuffer(); + private String arrayType(final int dimensions, final Class componentType) { + final StringBuilder className = new StringBuilder(); for (int i = 0; i < dimensions; i++) { className.append('['); } if (componentType.isPrimitive()) { - className.append(charThatJavaUsesToRepresentPrimitiveArrayType(componentType)); - return Class.forName(className.toString()); + className.append(Primitives.representingChar(componentType)); + return className.toString(); } else { className.append('L').append(componentType.getName()).append(';'); - return Class.forName(className.toString(), false, componentType.getClassLoader()); + return className.toString(); } } - private Class primitiveClassNamed(String name) { - return - name.equals("void") ? Void.TYPE : - name.equals("boolean") ? Boolean.TYPE : - name.equals("byte") ? Byte.TYPE : - name.equals("char") ? Character.TYPE : - name.equals("short") ? Short.TYPE : - name.equals("int") ? Integer.TYPE : - name.equals("long") ? Long.TYPE : - name.equals("float") ? Float.TYPE : - name.equals("double") ? Double.TYPE : - null; + private String boxedTypeName(final Class type) { + return Primitives.isBoxed(type) ? type.getName() : null; } - - private char charThatJavaUsesToRepresentPrimitiveArrayType(Class primvCls) { - return - (primvCls == boolean.class) ? 'Z' : - (primvCls == byte.class) ? 'B' : - (primvCls == char.class) ? 'C' : - (primvCls == short.class) ? 'S' : - (primvCls == int.class) ? 'I' : - (primvCls == long.class) ? 'J' : - (primvCls == float.class) ? 'F' : - (primvCls == double.class) ? 'D' : - 0; - } - - private String boxedTypeName(Class type) { - return BOXED_TYPES.contains(type) ? type.getName() : null; - } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/AttributeAliasingMapper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/AttributeMapper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/CGLIBMapper.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/CachingMapper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/CachingMapper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/CachingMapper.java 10 Sep 2012 19:03:00 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/CachingMapper.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,33 +1,70 @@ +/* + * 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 com.thoughtworks.xstream.alias.ClassMapper; - -import java.util.Map; 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 { +public class CachingMapper extends MapperWrapper implements Caching { - private final Map cache = Collections.synchronizedMap(new HashMap()); + private transient Map realClassCache; - public CachingMapper(ClassMapper wrapped) { + public CachingMapper(final Mapper wrapped) { super(wrapped); + readResolve(); } - public Class realClass(String elementName) { - Class cached = (Class) cache.get(elementName); + @Override + public Class realClass(final String elementName) { + final Object cached = realClassCache.get(elementName); if (cached != null) { - return cached; - } else { - Class result = super.realClass(elementName); - cache.put(elementName, result); + if (cached instanceof Class) { + return (Class)cached; + } + throw (XStreamException)cached; + } + + try { + final Class result = super.realClass(elementName); + realClassCache.put(elementName, result); return result; + } catch (final ForbiddenClassException e) { + realClassCache.put(elementName, e); + throw e; + } catch (final CannotResolveClassException e) { + realClassCache.put(elementName, e); + throw e; } } + @Override + public void flushCache() { + realClassCache.clear(); + } + + private Object readResolve() { + realClassCache = Collections.synchronizedMap(new HashMap(128)); + return this; + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/CannotResolveClassException.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/ClassAliasingMapper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/ClassAliasingMapper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/ClassAliasingMapper.java 10 Sep 2012 19:03:01 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/ClassAliasingMapper.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,52 +1,94 @@ +/* + * Copyright (C) 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 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 09. April 2005 by Joe Walnes + */ package com.thoughtworks.xstream.mapper; -import com.thoughtworks.xstream.alias.ClassMapper; - -import java.util.Map; -import java.util.Collections; import java.util.HashMap; +import java.util.Map; +import com.thoughtworks.xstream.core.util.Primitives; + + /** - * Mapper that allows a fully qualified class name to be replaced with a shorter alias. - * + * 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 { - protected final Map typeToNameMap = Collections.synchronizedMap(new HashMap()); - protected final Map nameToTypeMap = Collections.synchronizedMap(new HashMap()); + private final Map, String> typeToName = new HashMap, String>(); + private final Map classToName = new HashMap(); + private transient Map nameToType = new HashMap(); - public ClassAliasingMapper(ClassMapper wrapped) { + public ClassAliasingMapper(final Mapper wrapped) { super(wrapped); } - public void addClassAlias(String name, Class type) { - nameToTypeMap.put(name, type.getName()); - typeToNameMap.put(type.getName(), name); + public void addClassAlias(final String name, final Class type) { + nameToType.put(name, type.getName()); + classToName.put(type.getName(), name); } - public String serializedClass(Class type) { - String name = super.serializedClass(type); - String alias = (String) typeToNameMap.get(type.getName()); + public void addTypeAlias(final String name, final Class type) { + nameToType.put(name, type.getName()); + typeToName.put(type, name); + } + + @Override + public String serializedClass(final Class type) { + final String alias = classToName.get(type.getName()); if (alias != null) { return alias; } else { - return name; + for (final Class compatibleType : typeToName.keySet()) { + if (compatibleType.isAssignableFrom(type)) { + return typeToName.get(compatibleType); + } + } + return super.serializedClass(type); } } - public Class realClass(String elementName) { - if (elementName.equals("null")) { // TODO: This is probably the wrong place for this. - return null; - } + @Override + public Class realClass(String elementName) { + final String mappedName = nameToType.get(elementName); - String mappedName = (String) nameToTypeMap.get(mapNameFromXML(elementName)); - if (mappedName != null) { + final Class type = Primitives.primitiveType(mappedName); + if (type != null) { + return type; + } elementName = mappedName; } return super.realClass(elementName); } + public boolean itemTypeAsAttribute(final Class clazz) { + return classToName.containsKey(clazz); + } + + public boolean aliasIsAttribute(final String name) { + return nameToType.containsKey(name); + } + + private Object readResolve() { + nameToType = new HashMap(); + for (final String type : classToName.keySet()) { + nameToType.put(classToName.get(type), type); + } + for (final Class type : typeToName.keySet()) { + nameToType.put(typeToName.get(type), type.getName()); + } + return this; + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/DefaultImplementationsMapper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/DefaultImplementationsMapper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/DefaultImplementationsMapper.java 10 Sep 2012 19:03:01 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/DefaultImplementationsMapper.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,28 +1,41 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 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 22. January 2005 by Joe Walnes + */ package com.thoughtworks.xstream.mapper; -import com.thoughtworks.xstream.alias.ClassMapper; - -import java.util.Collections; import java.util.HashMap; import java.util.Map; +import com.thoughtworks.xstream.InitializationException; + + /** - * Mapper that resolves default implementations of classes. For example, mapper.lookupName(ArrayList.class) will return - * java.util.List. Calling mapper.defaultImplementationOf(List.class) will return ArrayList. - * - * @author Joe Walnes + * 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 = Collections.synchronizedMap(new HashMap()); - private final Map implToType = Collections.synchronizedMap(new HashMap()); + private final Map, Class> typeToImpl = new HashMap, Class>(); + private transient Map, Class> implToType = new HashMap, Class>(); - public DefaultImplementationsMapper(ClassMapper wrapped) { + public DefaultImplementationsMapper(final 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); @@ -34,19 +47,35 @@ addDefaultImplementation(Long.class, long.class); } - public void addDefaultImplementation(Class defaultImplementation, Class ofType) { + public void addDefaultImplementation(final Class defaultImplementation, final 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); + @Override + public String serializedClass(final Class type) { + final Class baseType = implToType.get(type); return baseType == null ? super.serializedClass(type) : super.serializedClass(baseType); } - public Class defaultImplementationOf(Class type) { - Class result = (Class) typeToImpl.get(type); - return result == null ? super.defaultImplementationOf(type) : result; + @Override + public Class defaultImplementationOf(final Class type) { + if (typeToImpl.containsKey(type)) { + return typeToImpl.get(type); + } else { + return super.defaultImplementationOf(type); + } } + private Object readResolve() { + implToType = new HashMap, Class>(); + for (final Class type : typeToImpl.keySet()) { + implToType.put(typeToImpl.get(type), type); + } + return this; + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/DefaultMapper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/DefaultMapper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/DefaultMapper.java 10 Sep 2012 19:03:01 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/DefaultMapper.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,110 +1,226 @@ +/* + * Copyright (C) 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2013, 3014 XStream Committers. + * All rights reserved. + * + * The software in this package is published under 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.alias.CannotResolveClassException; -import com.thoughtworks.xstream.alias.ClassMapper; +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. - * + * 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 extends MapperWrapper { +public class DefaultMapper implements Mapper { - private final ClassLoader classLoader; - private final String classAttributeIdentifier; + private static String XSTREAM_PACKAGE_ROOT; + static { + final String packageName = DefaultMapper.class.getName(); + final int idx = packageName.indexOf(".xstream."); + XSTREAM_PACKAGE_ROOT = idx > 0 ? packageName.substring(0, idx + 9) : ".N/A"; + } - public DefaultMapper(ClassLoader classLoader) { - this(classLoader, "class"); + 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(final ClassLoaderReference classLoaderReference) { + this.classLoaderReference = classLoaderReference; } - public DefaultMapper(ClassLoader classLoader, String classAttributeIdentifier) { - super(null); - this.classLoader = classLoader; - this.classAttributeIdentifier = classAttributeIdentifier == null ? "class" : classAttributeIdentifier; + /** + * Construct a DefaultMapper. + * + * @param classLoader the ClassLoader used by the XStream instance. + * @deprecated As of 1.4.5 use {@link #DefaultMapper(ClassLoaderReference)} + */ + @Deprecated + public DefaultMapper(final ClassLoader classLoader) { + this(new ClassLoaderReference(classLoader)); } - public String serializedClass(Class type) { + @Override + public String serializedClass(final Class type) { return type.getName(); } - public Class realClass(String elementName) { + @Override + public Class realClass(final String elementName) { + final Class resultingClass = Primitives.primitiveType(elementName); + if (resultingClass != null) { + return resultingClass; + } try { - return classLoader.loadClass(elementName); - } catch (ClassNotFoundException e) { - throw new CannotResolveClassException(elementName + " : " + e.getMessage()); + 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 (final ClassNotFoundException e) { + throw new CannotResolveClassException(elementName); } } - public Class lookupDefaultType(Class baseType) { - return baseType; - } - - public Class defaultImplementationOf(Class type) { + @Override + public Class defaultImplementationOf(final Class type) { return type; } - public String attributeForClassDefiningField() { - return "defined-in"; + @Override + public String aliasForAttribute(final String attribute) { + return attribute; } - public String attributeForReadResolveField() { - return "resolves-to"; + @Override + public String attributeForAlias(final String alias) { + return alias; } - public String attributeForEnumType() { - return "enum-type"; + @Override + public String aliasForSystemAttribute(final String attribute) { + return attribute; } - public String attributeForImplementationClass() { - return classAttributeIdentifier; - } - - public boolean isImmutableValueType(Class type) { + @Override + public boolean isImmutableValueType(final Class type) { return false; } - public String getFieldNameForItemTypeAndName(Class definedIn, Class itemType, String itemFieldName) { + @Override + public String getFieldNameForItemTypeAndName(final Class definedIn, final Class itemType, + final String itemFieldName) { return null; } - public Class getItemTypeForItemFieldName(Class definedIn, String itemFieldName) { + @Override + public Class getItemTypeForItemFieldName(final Class definedIn, final String itemFieldName) { return null; } - public ImplicitCollectionMapping getImplicitCollectionDefForFieldName(Class itemType, String fieldName) { + @Override + public ImplicitCollectionMapping getImplicitCollectionDefForFieldName(final Class itemType, + final String fieldName) { return null; } - public boolean shouldSerializeMember(Class definedIn, String fieldName) { + @Override + public boolean shouldSerializeMember(final Class definedIn, final String fieldName) { return true; } - public String lookupName(Class type) { + public String lookupName(final Class type) { return serializedClass(type); } - public Class lookupType(String elementName) { + public Class lookupType(final String elementName) { return realClass(elementName); } - public String serializedMember(Class type, String memberName) { + @Override + public String serializedMember(final Class type, final String memberName) { return memberName; } - public String realMember(Class type, String serialized) { + @Override + public String realMember(final Class type, final String serialized) { return serialized; } - public String mapNameFromXML(String xmlName) { - return xmlName; + /** + * @deprecated As of 1.3, use {@link #getConverterFromAttribute(Class, String, Class)} + */ + @Deprecated + public SingleValueConverter getConverterFromAttribute(final String name) { + throw new UnsupportedOperationException(); } - public String mapNameToXML(String javaName) { - return javaName; + /** + * @deprecated As of 1.3, use {@link #getConverterFromItemType(String, Class, Class)} + */ + @Deprecated + public SingleValueConverter getConverterFromItemType(final String fieldName, final Class type) { + throw new UnsupportedOperationException(); } - public void alias(String elementName, Class type, Class defaultImplementation) { + /** + * @deprecated As of 1.3, use {@link #getConverterFromItemType(String, Class, Class)} + */ + @Deprecated + public SingleValueConverter getConverterFromItemType(final Class type) { + throw new UnsupportedOperationException(); } + @Override + public SingleValueConverter getConverterFromItemType(final String fieldName, final Class type, + final Class definedIn) { + return null; + } + + @Override + public Converter getLocalConverter(final Class definedIn, final String fieldName) { + return null; + } + + @Override + public T lookupMapperOfType(final Class type) { + @SuppressWarnings("unchecked") + final T t = type.isAssignableFrom(getClass()) ? (T)this : null; + return t; + } + + /** + * @deprecated As of 1.3, use combination of {@link #serializedMember(Class, String)} and + * {@link #getConverterFromItemType(String, Class, Class)} + */ + @Deprecated + public String aliasForAttribute(final Class definedIn, final String fieldName) { + throw new UnsupportedOperationException(); + } + + /** + * @deprecated As of 1.3, use combination of {@link #realMember(Class, String)} and + * {@link #getConverterFromItemType(String, Class, Class)} + */ + @Deprecated + public String attributeForAlias(final Class definedIn, final String alias) { + throw new UnsupportedOperationException(); + } + + /** + * @deprecated As of 1.3.1, use {@link #getConverterFromAttribute(Class, String, Class)} + */ + @Deprecated + @Override + public SingleValueConverter getConverterFromAttribute(final Class definedIn, final String attribute) { + return null; + } + + @Override + public SingleValueConverter getConverterFromAttribute(final Class definedIn, final String attribute, + final Class type) { + return null; + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/DynamicProxyMapper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/DynamicProxyMapper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/DynamicProxyMapper.java 10 Sep 2012 19:03:01 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/DynamicProxyMapper.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,24 +1,36 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 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 22. January 2005 by Joe Walnes + */ package com.thoughtworks.xstream.mapper; -import com.thoughtworks.xstream.alias.ClassMapper; - 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. - * + * 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 = "dynamic-proxy"; + private String alias; - public DynamicProxyMapper(ClassMapper wrapped) { - super(wrapped); + public DynamicProxyMapper(final Mapper wrapped) { + this(wrapped, "dynamic-proxy"); } - public DynamicProxyMapper(ClassMapper wrapped, String alias) { + public DynamicProxyMapper(final Mapper wrapped, final String alias) { super(wrapped); this.alias = alias; } @@ -27,19 +39,21 @@ return alias; } - public void setAlias(String alias) { + public void setAlias(final String alias) { this.alias = alias; } - public String serializedClass(Class type) { + @Override + public String serializedClass(final Class type) { if (Proxy.isProxyClass(type)) { return alias; } else { return super.serializedClass(type); } } - public Class realClass(String elementName) { + @Override + public Class realClass(final String elementName) { if (elementName.equals(alias)) { return DynamicProxy.class; } else { Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/EnumMapper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/EnumMapper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/EnumMapper.java 10 Sep 2012 19:03:00 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/EnumMapper.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,40 +1,111 @@ +/* + * 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 20. March 2005 by Joe Walnes + */ package com.thoughtworks.xstream.mapper; -import com.thoughtworks.xstream.alias.ClassMapper; -import com.thoughtworks.xstream.core.JVM; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.enums.EnumSingleValueConverter; +import com.thoughtworks.xstream.core.Caching; + + /** - * 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. - * + * 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 { +public class EnumMapper extends MapperWrapper implements Caching { - // Dynamically try to load Enum class. Pre JDK1.5 will silently fail. - private static JVM jvm = new JVM(); - private static final Class enumClass = jvm.loadClass("java.lang.Enum"); + private transient AttributeMapper attributeMapper; + private transient Map, SingleValueConverter> enumConverterMap; - private static final boolean active = enumClass != null; - - private static final Class enumSetClass = active ? jvm.loadClass("java.util.EnumSet") : null; - - public EnumMapper(ClassMapper wrapped) { + public EnumMapper(final Mapper wrapped) { super(wrapped); + readResolve(); } - public String serializedClass(Class type) { - if (!active) { + @Override + public String serializedClass(final 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 { - if (enumClass.isAssignableFrom(type) && type.getSuperclass() != enumClass) { - return super.serializedClass(type.getSuperclass()); - } else if (enumSetClass.isAssignableFrom(type)) { - return super.serializedClass(enumSetClass); - } else { - return super.serializedClass(type); + return super.serializedClass(type); + } + } + + @Override + public boolean isImmutableValueType(final Class type) { + return Enum.class.isAssignableFrom(type) || super.isImmutableValueType(type); + } + + @Override + public SingleValueConverter getConverterFromItemType(final String fieldName, final Class type, + final Class definedIn) { + final SingleValueConverter converter = getLocalConverter(fieldName, type, definedIn); + return converter == null ? super.getConverterFromItemType(fieldName, type, definedIn) : converter; + } + + @Override + public SingleValueConverter getConverterFromAttribute(final Class definedIn, final String attribute, + final Class type) { + final SingleValueConverter converter = getLocalConverter(attribute, type, definedIn); + return converter == null ? super.getConverterFromAttribute(definedIn, attribute, type) : converter; + } + + private SingleValueConverter getLocalConverter(final String fieldName, final Class type, final 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") + final Class> enumType = (Class>)type; + @SuppressWarnings({"rawtypes", "unchecked"}) + final EnumSingleValueConverter enumConverter = new EnumSingleValueConverter(enumType); + singleValueConverter = enumConverter; + } + enumConverterMap.put(type, singleValueConverter); + } + return singleValueConverter; } } + return null; } + @Override + public void flushCache() { + if (enumConverterMap.size() > 0) { + synchronized (enumConverterMap) { + enumConverterMap.clear(); + } + } + } + + private Object readResolve() { + enumConverterMap = new HashMap, SingleValueConverter>(); + attributeMapper = lookupMapperOfType(AttributeMapper.class); + return this; + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/FieldAliasingMapper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/FieldAliasingMapper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/FieldAliasingMapper.java 10 Sep 2012 19:03:01 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/FieldAliasingMapper.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,57 +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.alias.ClassMapper; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; -import java.util.*; +import com.thoughtworks.xstream.core.util.FastField; + /** - * Mapper that allows a field of a specific class to be replaced with a shorter alias, or omitted - * entirely. - * + * 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 = Collections.synchronizedMap(new HashMap()); - protected final Map aliasToFieldMap = Collections.synchronizedMap(new HashMap()); - protected final Set fieldsToOmit = Collections.synchronizedSet(new HashSet()); + 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(ClassMapper wrapped) { + public FieldAliasingMapper(final Mapper wrapped) { super(wrapped); } - public void addFieldAlias(String alias, Class type, String fieldName) { + public void addFieldAlias(final String alias, final Class type, final String fieldName) { fieldToAliasMap.put(key(type, fieldName), alias); aliasToFieldMap.put(key(type, alias), fieldName); } - private Object key(Class type, String value) { - return type.getName() + '.' + value; + public void addFieldsToIgnore(final Pattern pattern) { + unknownFieldsToIgnore.add(pattern); } - public String serializedMember(Class type, String memberName) { - String alias = (String) fieldToAliasMap.get(key(type, memberName)); + private FastField key(final Class type, final String name) { + return new FastField(type, name); + } + + @Override + public String serializedMember(final Class type, final String memberName) { + final 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 = (String) aliasToFieldMap.get(key(type, serialized)); + @Override + public String realMember(final Class type, final String serialized) { + final String real = getMember(type, serialized, aliasToFieldMap); if (real == null) { return super.realMember(type, serialized); } else { return real; } } - public boolean shouldSerializeMember(Class definedIn, String fieldName) { - return !fieldsToOmit.contains(key(definedIn, fieldName)); + private String getMember(final Class type, final String name, final Map map) { + String member = null; + for (Class declaringType = type; member == null && declaringType != Object.class && declaringType != null; declaringType = declaringType + .getSuperclass()) { + member = map.get(key(declaringType, name)); + } + return member; } - public void omitField(Class type, String fieldName) { - fieldsToOmit.add(key(type, fieldName)); + @Override + public boolean shouldSerializeMember(final Class definedIn, final String fieldName) { + if (fieldsToOmit.contains(key(definedIn, fieldName))) { + return false; + } else if (definedIn == Object.class && !unknownFieldsToIgnore.isEmpty()) { + for (final Pattern pattern : unknownFieldsToIgnore) { + if (pattern.matcher(fieldName).matches()) { + return false; + } + } + } + return true; } + + public void omitField(final Class definedIn, final String fieldName) { + fieldsToOmit.add(key(definedIn, fieldName)); + } } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/ImmutableTypesMapper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/ImmutableTypesMapper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/ImmutableTypesMapper.java 10 Sep 2012 19:03:01 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/ImmutableTypesMapper.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,30 +1,40 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 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 22. January 2005 by Joe Walnes + */ package com.thoughtworks.xstream.mapper; -import com.thoughtworks.xstream.alias.ClassMapper; - -import java.util.Collections; 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 = Collections.synchronizedSet(new HashSet()); + private final Set> immutableTypes = new HashSet>(); - public ImmutableTypesMapper(ClassMapper wrapped) { + public ImmutableTypesMapper(final Mapper wrapped) { super(wrapped); } - public void addImmutableType(Class type) { + public void addImmutableType(final Class type) { immutableTypes.add(type); } - public boolean isImmutableValueType(Class type) { + @Override + public boolean isImmutableValueType(final Class type) { if (immutableTypes.contains(type)) { return true; } else { Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/ImplicitCollectionMapper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/ImplicitCollectionMapper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/ImplicitCollectionMapper.java 10 Sep 2012 19:03:00 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/ImplicitCollectionMapper.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,24 +1,36 @@ +/* + * 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.alias.ClassMapper; - -import java.util.Collections; +import java.lang.reflect.Field; +import java.util.Collection; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; +import com.thoughtworks.xstream.InitializationException; +import com.thoughtworks.xstream.core.util.Primitives; + + public class ImplicitCollectionMapper extends MapperWrapper { - public ImplicitCollectionMapper(ClassMapper wrapped) { + public ImplicitCollectionMapper(final Mapper wrapped) { super(wrapped); } - // { definedIn (Class) -> (ImplicitCollectionMapperForClass) } - private Map classNameToMapper = Collections.synchronizedMap(new HashMap()); + private final Map, ImplicitCollectionMapperForClass> classNameToMapper = new HashMap, ImplicitCollectionMapperForClass>(); - private ImplicitCollectionMapperForClass getMapper(Class definedIn) { + private ImplicitCollectionMapperForClass getMapper(Class definedIn) { while (definedIn != null) { - ImplicitCollectionMapperForClass mapper = (ImplicitCollectionMapperForClass) classNameToMapper.get(definedIn); + final ImplicitCollectionMapperForClass mapper = classNameToMapper.get(definedIn); if (mapper != null) { return mapper; } @@ -27,108 +39,176 @@ return null; } - private ImplicitCollectionMapperForClass getOrCreateMapper(Class definedIn) { - ImplicitCollectionMapperForClass mapper = getMapper(definedIn); + private ImplicitCollectionMapperForClass getOrCreateMapper(final Class definedIn) { + ImplicitCollectionMapperForClass mapper = 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); + @Override + public String getFieldNameForItemTypeAndName(final Class definedIn, final Class itemType, + final String itemFieldName) { + final 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); + @Override + public Class getItemTypeForItemFieldName(final Class definedIn, final String itemFieldName) { + final 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); + @Override + public ImplicitCollectionMapping getImplicitCollectionDefForFieldName(final Class itemType, + final String fieldName) { + final ImplicitCollectionMapperForClass mapper = getMapper(itemType); if (mapper != null) { return mapper.getImplicitCollectionDefForFieldName(fieldName); } else { return null; } } - public void add(Class definedIn, String fieldName, Class itemType) { + public void add(final Class definedIn, final String fieldName, final Class itemType) { add(definedIn, fieldName, null, itemType); } - public void add(Class definedIn, String fieldName, String itemFieldName, Class itemType) { - ImplicitCollectionMapperForClass mapper = getOrCreateMapper(definedIn); - mapper.add(new ImplicitCollectionMappingImpl(fieldName, itemType, itemFieldName)); + public void add(final Class definedIn, final String fieldName, final String itemFieldName, + final Class itemType) { + add(definedIn, fieldName, itemFieldName, itemType, null); } - private static class ImplicitCollectionMapperForClass { - //private Class definedIn; - private Map namedItemTypeToDef = new HashMap(); // { (NamedItemType) -> (ImplicitCollectionDefImpl) } - private Map itemFieldNameToDef = new HashMap(); // { itemFieldName (String) -> (ImplicitCollectionDefImpl) } - private Map fieldNameToDef = new HashMap(); // { fieldName (String) -> (ImplicitCollectionDefImpl) } + public void add(final Class definedIn, final String fieldName, final String itemFieldName, Class itemType, + final String keyFieldName) { + Field field = null; + Class declaredIn = definedIn; + while (declaredIn != Object.class && definedIn != null) { + try { + field = declaredIn.getDeclaredField(fieldName); + break; + } catch (final SecurityException e) { + throw new InitializationException("Access denied for field with implicit collection", e); + } catch (final 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())) { + final 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()); - public ImplicitCollectionMapperForClass(Class definedIn) { - //this.definedIn = definedIn; + } + } + } } + final ImplicitCollectionMapperForClass mapper = getOrCreateMapper(definedIn); + mapper.add(new ImplicitCollectionMappingImpl(fieldName, itemType, itemFieldName, keyFieldName)); + } - public String getFieldNameForItemTypeAndName(Class itemType, String itemFieldName) { + private class ImplicitCollectionMapperForClass { + private final Class definedIn; + private final Map namedItemTypeToDef = new HashMap(); + private final Map itemFieldNameToDef = new HashMap(); + private final Map fieldNameToDef = new HashMap(); + + ImplicitCollectionMapperForClass(final Class definedIn) { + this.definedIn = definedIn; + } + + public String getFieldNameForItemTypeAndName(final Class itemType, final String itemFieldName) { ImplicitCollectionMappingImpl unnamed = null; - for (Iterator iterator = namedItemTypeToDef.keySet().iterator(); iterator.hasNext();) { - NamedItemType itemTypeForFieldName = (NamedItemType) iterator.next(); - if (itemTypeForFieldName.itemType.isAssignableFrom(itemType)) { - ImplicitCollectionMappingImpl def = (ImplicitCollectionMappingImpl) namedItemTypeToDef.get(itemTypeForFieldName); + for (final NamedItemType itemTypeForFieldName : namedItemTypeToDef.keySet()) { + final ImplicitCollectionMappingImpl def = 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 { - unnamed = def; - if (itemFieldName == null) { - break; + if (unnamed == null + || unnamed.getItemType() == null + || def.getItemType() != null + && unnamed.getItemType().isAssignableFrom(def.getItemType())) { + unnamed = def; } } } } - return unnamed != null ? unnamed.getFieldName() : null; + if (unnamed != null) { + return unnamed.getFieldName(); + } else { + final ImplicitCollectionMapperForClass mapper = getMapper(definedIn.getSuperclass()); + return mapper != null ? mapper.getFieldNameForItemTypeAndName(itemType, itemFieldName) : null; + } } - public Class getItemTypeForItemFieldName(String itemFieldName) { - ImplicitCollectionMappingImpl def = getImplicitCollectionDefByItemFieldName(itemFieldName); + public Class getItemTypeForItemFieldName(final String itemFieldName) { + final ImplicitCollectionMappingImpl def = getImplicitCollectionDefByItemFieldName(itemFieldName); if (def != null) { return def.getItemType(); } else { - return null; + final ImplicitCollectionMapperForClass mapper = getMapper(definedIn.getSuperclass()); + return mapper != null ? mapper.getItemTypeForItemFieldName(itemFieldName) : null; } } - private ImplicitCollectionMappingImpl getImplicitCollectionDefByItemFieldName(String itemFieldName) { + private ImplicitCollectionMappingImpl getImplicitCollectionDefByItemFieldName(final String itemFieldName) { if (itemFieldName == null) { return null; } else { - return (ImplicitCollectionMappingImpl) itemFieldNameToDef.get(itemFieldName); + final ImplicitCollectionMappingImpl mapping = itemFieldNameToDef.get(itemFieldName); + if (mapping != null) { + return mapping; + } else { + final ImplicitCollectionMapperForClass mapper = getMapper(definedIn.getSuperclass()); + return mapper != null ? mapper.getImplicitCollectionDefByItemFieldName(itemFieldName) : null; + } } } - public ImplicitCollectionMappingImpl getImplicitCollectionDefByFieldName(String fieldName) { - return (ImplicitCollectionMappingImpl) fieldNameToDef.get(fieldName); + public ImplicitCollectionMapping getImplicitCollectionDefForFieldName(final String fieldName) { + final ImplicitCollectionMapping mapping = fieldNameToDef.get(fieldName); + if (mapping != null) { + return mapping; + } else { + final ImplicitCollectionMapperForClass mapper = getMapper(definedIn.getSuperclass()); + return mapper != null ? mapper.getImplicitCollectionDefForFieldName(fieldName) : null; + } } - public ImplicitCollectionMapping getImplicitCollectionDefForFieldName(String fieldName) { - return (ImplicitCollectionMapping) fieldNameToDef.get(fieldName); - } - - public void add(ImplicitCollectionMappingImpl def) { + public void add(final ImplicitCollectionMappingImpl def) { fieldNameToDef.put(def.getFieldName(), def); namedItemTypeToDef.put(def.createNamedItemType(), def); if (def.getItemFieldName() != null) { @@ -139,88 +219,72 @@ } private static class ImplicitCollectionMappingImpl implements ImplicitCollectionMapping { - private String fieldName; - private String itemFieldName; - private Class itemType; + private final String fieldName; + private final String itemFieldName; + private final Class itemType; + private final String keyFieldName; - ImplicitCollectionMappingImpl(String fieldName, Class itemType, String itemFieldName) { + ImplicitCollectionMappingImpl( + final String fieldName, final Class itemType, final String itemFieldName, final String keyFieldName) { this.fieldName = fieldName; this.itemFieldName = itemFieldName; this.itemType = itemType; + this.keyFieldName = keyFieldName; } - - public boolean equals(Object obj) { - if (obj instanceof ImplicitCollectionMappingImpl) { - ImplicitCollectionMappingImpl b = (ImplicitCollectionMappingImpl) obj; - return fieldName.equals(b.fieldName) - && isEquals(itemFieldName, b.itemFieldName); - } else { - return false; - } - } - public NamedItemType createNamedItemType() { return new NamedItemType(itemType, itemFieldName); } - private static boolean isEquals(Object a, Object b) { - if (a == null) { - return b == null; - } else { - return a.equals(b); - } - } - - public int hashCode() { - int hash = fieldName.hashCode(); - if (itemFieldName != null) { - hash += itemFieldName.hashCode() << 7; - } - return hash; - } - + @Override public String getFieldName() { return fieldName; } + @Override public String getItemFieldName() { return itemFieldName; } - public Class getItemType() { + @Override + public Class getItemType() { return itemType; } + + @Override + public String getKeyFieldName() { + return keyFieldName; + } } private static class NamedItemType { - Class itemType; + Class itemType; String itemFieldName; - NamedItemType(Class itemType, String itemFieldName) { - this.itemType = itemType; + NamedItemType(final Class itemType, final String itemFieldName) { + this.itemType = itemType == null ? Object.class : itemType; this.itemFieldName = itemFieldName; } - - public boolean equals(Object obj) { + @Override + public boolean equals(final Object obj) { if (obj instanceof NamedItemType) { - NamedItemType b = (NamedItemType) obj; - return itemType.equals(b.itemType) - && isEquals(itemFieldName, b.itemFieldName); + final NamedItemType b = (NamedItemType)obj; + return itemType.equals(b.itemType) && isEquals(itemFieldName, b.itemFieldName); } else { return false; } } - private static boolean isEquals(Object a, Object b) { + private static boolean isEquals(final Object a, final Object b) { if (a == null) { return b == null; } else { return a.equals(b); } } + @Override public int hashCode() { int hash = itemType.hashCode() << 7; if (itemFieldName != null) { @@ -230,4 +294,3 @@ } } } - Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/LocalConversionMapper.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/Mapper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/Mapper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/Mapper.java 10 Sep 2012 19:03:01 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/Mapper.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,67 +1,143 @@ +/* + * Copyright (C) 2005, 2006 Joe Walnes. + * Copyright (C) 2006, 2007, 2008, 2009, 2011, 2103, 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 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); + String serializedClass(Class type); /** * How a serialized class representation should be mapped back to a real class. */ - Class realClass(String elementName); + Class realClass(String elementName); /** * How a class member should be represented in its serialized form. */ - String serializedMember(Class type, String memberName); + 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); + 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. + * 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); + boolean isImmutableValueType(Class type); - Class defaultImplementationOf(Class type); + Class defaultImplementationOf(Class type); - String attributeForImplementationClass(); + /** + * Get the alias for an attribute's name. + * + * @param attribute the attribute + * @return the alias + * @since 1.2 + */ + String aliasForAttribute(String attribute); - String attributeForClassDefiningField(); + /** + * Get the attribute's name for an alias. + * + * @param alias the alias + * @return the attribute's name + * @since 1.2 + */ + String attributeForAlias(String alias); - String attributeForReadResolveField(); + /** + * 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); - String attributeForEnumType(); - /** * 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 definedIn owning type + * @param itemType item type * @param itemFieldName optional item element name */ - String getFieldNameForItemTypeAndName(Class definedIn, Class itemType, String itemFieldName); + String getFieldNameForItemTypeAndName(Class definedIn, Class itemType, String itemFieldName); - Class getItemTypeForItemFieldName(Class definedIn, String itemFieldName); + Class getItemTypeForItemFieldName(Class definedIn, String itemFieldName); - ImplicitCollectionMapping getImplicitCollectionDefForFieldName(Class itemType, String fieldName); + ImplicitCollectionMapping getImplicitCollectionDefForFieldName(Class itemType, String fieldName); /** * Determine whether a specific member should be serialized. - * - * @since 1.2 + * + * @since 1.1.3 */ - boolean shouldSerializeMember(Class definedIn, String fieldName); + boolean shouldSerializeMember(Class definedIn, String fieldName); interface ImplicitCollectionMapping { String getFieldName(); + String getItemFieldName(); - Class getItemType(); + + Class getItemType(); + + String getKeyFieldName(); } + Converter getLocalConverter(Class definedIn, String fieldName); + + T lookupMapperOfType(final 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 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)} + */ + @Deprecated + 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); } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/MapperWrapper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/MapperWrapper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/MapperWrapper.java 10 Sep 2012 19:03:01 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/MapperWrapper.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,127 +1,126 @@ +/* + * Copyright (C) 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 22. January 2005 by Joe Walnes + */ package com.thoughtworks.xstream.mapper; -import com.thoughtworks.xstream.alias.ClassMapper; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.SingleValueConverter; -public abstract class MapperWrapper implements ClassMapper { - private final ClassMapper wrapped; +public abstract class MapperWrapper implements Mapper { - public MapperWrapper(ClassMapper wrapped) { + private final Mapper wrapped; + + public MapperWrapper(final Mapper wrapped) { this.wrapped = wrapped; } - public String serializedClass(Class type) { + @Override + public String serializedClass(final Class type) { return wrapped.serializedClass(type); } - public Class realClass(String elementName) { + @Override + public Class realClass(final String elementName) { return wrapped.realClass(elementName); } - public String serializedMember(Class type, String memberName) { + @Override + public String serializedMember(final Class type, final String memberName) { return wrapped.serializedMember(type, memberName); } - public String realMember(Class type, String serialized) { + @Override + public String realMember(final Class type, final String serialized) { return wrapped.realMember(type, serialized); } - public String mapNameFromXML(String xmlName) { - return wrapped.mapNameFromXML(xmlName); - } - - public String mapNameToXML(String javaName) { - return wrapped.mapNameToXML(javaName); - } - - public boolean isImmutableValueType(Class type) { + @Override + public boolean isImmutableValueType(final Class type) { return wrapped.isImmutableValueType(type); } - public Class defaultImplementationOf(Class type) { + @Override + public Class defaultImplementationOf(final Class type) { return wrapped.defaultImplementationOf(type); } - public String attributeForClassDefiningField() { - return wrapped.attributeForClassDefiningField(); + @Override + public String aliasForAttribute(final String attribute) { + return wrapped.aliasForAttribute(attribute); } - public String attributeForImplementationClass() { - return wrapped.attributeForImplementationClass(); + @Override + public String attributeForAlias(final String alias) { + return wrapped.attributeForAlias(alias); } - public String attributeForReadResolveField() { - return wrapped.attributeForReadResolveField(); + @Override + public String aliasForSystemAttribute(final String attribute) { + return wrapped.aliasForSystemAttribute(attribute); } - public String attributeForEnumType() { - return wrapped.attributeForEnumType(); - } - - public String getFieldNameForItemTypeAndName(Class definedIn, Class itemType, String itemFieldName) { + @Override + public String getFieldNameForItemTypeAndName(final Class definedIn, final Class itemType, + final String itemFieldName) { return wrapped.getFieldNameForItemTypeAndName(definedIn, itemType, itemFieldName); } - public Class getItemTypeForItemFieldName(Class definedIn, String itemFieldName) { + @Override + public Class getItemTypeForItemFieldName(final Class definedIn, final String itemFieldName) { return wrapped.getItemTypeForItemFieldName(definedIn, itemFieldName); } - public ImplicitCollectionMapping getImplicitCollectionDefForFieldName(Class itemType, String fieldName) { + @Override + public ImplicitCollectionMapping getImplicitCollectionDefForFieldName(final Class itemType, + final String fieldName) { return wrapped.getImplicitCollectionDefForFieldName(itemType, fieldName); } - public boolean shouldSerializeMember(Class definedIn, String fieldName) { + @Override + public boolean shouldSerializeMember(final Class definedIn, final String fieldName) { return wrapped.shouldSerializeMember(definedIn, fieldName); } - /** - * @deprecated As of 1.1.1, use {@link #defaultImplementationOf(Class)} - */ - public Class lookupDefaultType(Class baseType) { - return defaultImplementationOf(baseType); + @Override + public Converter getLocalConverter(final Class definedIn, final String fieldName) { + return wrapped.getLocalConverter(definedIn, fieldName); } - public String lookupName(Class type) { - return serializedClass(type); + @Override + public T lookupMapperOfType(final Class type) { + @SuppressWarnings("unchecked") + final T t = type.isAssignableFrom(getClass()) ? (T)this : wrapped.lookupMapperOfType(type); + return t; } - public Class lookupType(String elementName) { - return realClass(elementName); + @Override + public SingleValueConverter getConverterFromItemType(final String fieldName, final Class type, + final Class definedIn) { + return wrapped.getConverterFromItemType(fieldName, type, definedIn); } /** - * @deprecated As of 1.1.1, use {@link com.thoughtworks.xstream.mapper.ClassAliasingMapper#addClassAlias(String, Class)} for creating an alias and - * {@link DefaultImplementationsMapper#addDefaultImplementation(Class, Class)} for specifiny a - * default implementation. + * @deprecated As of 1.3.1, use {@link #getConverterFromAttribute(Class, String, Class)} */ - public void alias(String elementName, Class type, Class defaultImplementation) { - ClassAliasingMapper classAliasingMapper = (ClassAliasingMapper) findWrapped(ClassAliasingMapper.class); - if (classAliasingMapper == null) { - throw new UnsupportedOperationException("ClassMapper.alias() longer supported. Use ClassAliasingMapper.alias() instead."); - } else { - classAliasingMapper.addClassAlias(elementName, type); - } - if (defaultImplementation != null && defaultImplementation != type) { - DefaultImplementationsMapper defaultImplementationsMapper = (DefaultImplementationsMapper) findWrapped(DefaultImplementationsMapper.class); - if (defaultImplementationsMapper == null) { - throw new UnsupportedOperationException("ClassMapper.alias() longer supported. Use DefaultImplementatoinsMapper.add() instead."); - } else { - defaultImplementationsMapper.addDefaultImplementation(defaultImplementation, type); - } - } + @Deprecated + @Override + public SingleValueConverter getConverterFromAttribute(final Class type, final String attribute) { + return wrapped.getConverterFromAttribute(type, attribute); } - private ClassMapper findWrapped(Class typeOfMapper) { - ClassMapper current = this; - while (true) { - if (current.getClass().isAssignableFrom(typeOfMapper)) { - return current; - } else if (current instanceof MapperWrapper) { - MapperWrapper wrapper = (MapperWrapper) current; - current = wrapper.wrapped; - } else { - return null; - } - } + @Override + public SingleValueConverter getConverterFromAttribute(final Class definedIn, final String attribute, + final Class type) { + return wrapped.getConverterFromAttribute(definedIn, attribute, type); } + } Index: 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/OuterClassMapper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/OuterClassMapper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/OuterClassMapper.java 10 Sep 2012 19:03:00 -0000 1.1 +++ 3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/OuterClassMapper.java 10 Nov 2014 12:07:38 -0000 1.1.2.1 @@ -1,57 +1,49 @@ +/* + * Copyright (C) 2005 Joe Walnes. + * Copyright (C) 2006, 2007, 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 31. January 2005 by Joe Walnes + */ package com.thoughtworks.xstream.mapper; -import com.thoughtworks.xstream.alias.ClassMapper; - /** * 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(ClassMapper wrapped, String alias) { + public OuterClassMapper(final Mapper wrapped) { + this(wrapped, "outer-class"); + } + + public OuterClassMapper(final Mapper wrapped, final String alias) { super(wrapped); this.alias = alias; } - public OuterClassMapper(ClassMapper wrapped) { - this(wrapped, "outer-class"); - } - - public String serializedMember(Class type, String memberName) { + @Override + public String serializedMember(final Class type, final String memberName) { if (memberName.equals("this$0")) { return alias; } else { return super.serializedMember(type, memberName); } } - public String realMember(Class type, String serialized) { + @Override + public String realMember(final Class type, final String serialized) { if (serialized.equals(alias)) { return "this$0"; } else { return super.realMember(type, serialized); } } - - // --- Maintain backwards compatability - - public String mapNameToXML(String javaName) { - if (javaName.equals("this$0")) { - return alias; - } else { - return super.mapNameToXML(javaName); - } - } - - public String mapNameFromXML(String xmlName) { - if (xmlName.equals(alias)) { - return "this$0"; - } else { - return super.mapNameFromXML(xmlName); - } - } - } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/PackageAliasingMapper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/SecurityMapper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/SystemAttributeAliasingMapper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/XStream11XmlFriendlyMapper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/mapper/XmlFriendlyMapper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/persistence/AbstractFilePersistenceStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/persistence/FilePersistenceStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/persistence/FileStreamStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/persistence/PersistenceStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/persistence/StreamStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/persistence/XmlArrayList.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/persistence/XmlMap.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/persistence/XmlSet.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/security/AnyTypePermission.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/security/ArrayTypePermission.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/security/CGLIBProxyTypePermission.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/security/ExplicitTypePermission.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/security/ForbiddenClassException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/security/InterfaceTypePermission.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/security/NoPermission.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/security/NoTypePermission.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/security/NullPermission.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/security/PrimitiveTypePermission.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/security/ProxyTypePermission.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/security/RegExpTypePermission.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/security/TypeHierarchyPermission.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/security/TypePermission.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/xstream/com/thoughtworks/xstream/security/WildcardTypePermission.java'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_build/3rdParty.userlibraries =================================================================== RCS file: /usr/local/cvsroot/lams_build/3rdParty.userlibraries,v diff -u -r1.71.2.14 -r1.71.2.15 --- lams_build/3rdParty.userlibraries 12 Oct 2014 18:00:23 -0000 1.71.2.14 +++ lams_build/3rdParty.userlibraries 10 Nov 2014 12:07:45 -0000 1.71.2.15 @@ -23,14 +23,11 @@ - - - @@ -44,5 +41,7 @@ + + Index: lams_build/build.xml =================================================================== RCS file: /usr/local/cvsroot/lams_build/build.xml,v diff -u -r1.120.2.47 -r1.120.2.48 --- lams_build/build.xml 4 Nov 2014 22:55:29 -0000 1.120.2.47 +++ lams_build/build.xml 10 Nov 2014 12:07:45 -0000 1.120.2.48 @@ -711,19 +711,20 @@ - + + - + file="lib/xstream/xmlpull.module.xml" overwrite="true" verbose="true" /> + - + + file="lib/joda/joda.module.xml" overwrite="true" verbose="true" /> Index: lams_build/liblist.txt =================================================================== RCS file: /usr/local/cvsroot/lams_build/liblist.txt,v diff -u -r1.25.2.22 -r1.25.2.23 --- lams_build/liblist.txt 12 Oct 2014 18:00:23 -0000 1.25.2.22 +++ lams_build/liblist.txt 10 Nov 2014 12:07:45 -0000 1.25.2.23 @@ -35,6 +35,8 @@ jdom jdom.jar 0.7 BSD/Apache style Jason Hunter, Rolf Lear Java representation of an XML document +joda joda-time-2.1.jar 2.1 Apache License 2.0 Joda.org time calculation library + joid joid.jar 2.0 Apache License 2.0 Java Open ID library @@ -74,12 +76,11 @@ xml-commons xml-apis.jar 1.3 xml-apis-ext.jar 1.3 Apache License 2.0 Apache Common code and guidelines for xml projects -xstream joda-time-2.1.jar 2.1 Apache License 2.0 Joda.org Joda Time - xpp3-1.1.3.4d_b4_min.jar 1.1.3.4d_b4_min - xstream-1.1.3.jar 1.1.3 +xstream xmlpull-1.1.3.1.jar 1.1.3.1 + xpp3_min-1.1.4c.jar 1.1.4c + xstream-1.5.0-SNAPSHOT.jar 1.5.0 XML serializer - ******Build Related Libraries****** Folder Library Version License Vendor Description Index: lams_build/conf/j2ee/jboss-deployment-structure.xml =================================================================== RCS file: /usr/local/cvsroot/lams_build/conf/j2ee/Attic/jboss-deployment-structure.xml,v diff -u -r1.1.2.38 -r1.1.2.39 --- lams_build/conf/j2ee/jboss-deployment-structure.xml 19 Oct 2014 08:35:12 -0000 1.1.2.38 +++ lams_build/conf/j2ee/jboss-deployment-structure.xml 10 Nov 2014 12:07:45 -0000 1.1.2.39 @@ -35,6 +35,7 @@ + @@ -52,6 +53,7 @@ +