simple-xml-2.7.1/0000755000175000017500000000000012166517662013102 5ustar bengenbengensimple-xml-2.7.1/src/0000755000175000017500000000000012166517661013670 5ustar bengenbengensimple-xml-2.7.1/src/org/0000755000175000017500000000000012166517661014457 5ustar bengenbengensimple-xml-2.7.1/src/org/simpleframework/0000755000175000017500000000000012166517661017666 5ustar bengenbengensimple-xml-2.7.1/src/org/simpleframework/xml/0000755000175000017500000000000012271465260020460 5ustar bengenbengensimple-xml-2.7.1/src/org/simpleframework/xml/convert/0000755000175000017500000000000012271465260022140 5ustar bengenbengensimple-xml-2.7.1/src/org/simpleframework/xml/convert/RegistryBinder.java0000644000175000017500000000676012166517661025756 0ustar bengenbengen/* * RegistryBinder.java January 2010 * * Copyright (C) 2010, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.convert; import org.simpleframework.xml.util.Cache; import org.simpleframework.xml.util.ConcurrentCache; /** * The RegistryBinder object is used acquire converters * using a binding between a type and its converter. All converters * instantiated are cached internally to ensure that the overhead * of acquiring a converter is reduced. Converters are created on * demand to ensure they are instantiated only if required. * * @author Niall Gallagher * * @see org.simpleframework.xml.convert.Registry */ class RegistryBinder { /** * This is used to instantiate and cache the converter objects. */ private final ConverterFactory factory; /** * This is used to cache bindings between types and converters. */ private final Cache cache; /** * Constructor for the RegistryBinder object. This * is used to create bindings between classes and the converters * that should be used to serialize and deserialize the instances. * All converters are instantiated once and cached for reuse. */ public RegistryBinder() { this.cache = new ConcurrentCache(); this.factory = new ConverterFactory(); } /** * This is used to acquire a Converter instance from * this binder. All instances are cached to reduce the overhead * of lookups during the serialization process. Converters are * lazily instantiated and so are only created if demanded. * * @param type this is the type to find the converter for * * @return this returns the converter instance for the type */ public Converter lookup(Class type) throws Exception { Class result = cache.fetch(type); if(result != null) { return create(result); } return null; } /** * This is used to acquire a Converter instance from * this binder. All instances are cached to reduce the overhead * of lookups during the serialization process. Converters are * lazily instantiated and so are only created if demanded. * * @param type this is the type to find the converter for * * @return this returns the converter instance for the type */ private Converter create(Class type) throws Exception { return factory.getInstance(type); } /** * This is used to register a binding between a type and the * converter used to serialize and deserialize it. During the * serialization process the converters are retrieved and * used to convert the object properties to XML. * * @param type this is the object type to bind to a converter * @param converter this is the converter class to be used */ public void bind(Class type, Class converter) throws Exception { cache.cache(type, converter); } } simple-xml-2.7.1/src/org/simpleframework/xml/convert/Registry.java0000644000175000017500000001053412166517661024624 0ustar bengenbengen/* * Registry.java January 2010 * * Copyright (C) 2010, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.convert; import org.simpleframework.xml.util.Cache; import org.simpleframework.xml.util.ConcurrentCache; /** * The Registry represents an object that is used to * register bindings between a class and a converter implementation. * Converter instances created by this registry are lazily created * and cached so that they are instantiated only once. This ensures * that the overhead of serialization is reduced. * * @author Niall Gallagher * * @see org.simpleframework.xml.convert.RegistryStrategy */ public class Registry { /** * This is used to cache the converters based on object types. */ private final Cache cache; /** * This is used to bind converter types to serializable types. */ private final RegistryBinder binder; /** * Constructor for the Registry object. This is used * to create a registry between classes and the converters that * should be used to serialize and deserialize the instances. All * converters are instantiated once and cached for reuse. */ public Registry() { this.cache = new ConcurrentCache(); this.binder = new RegistryBinder(); } /** * This is used to acquire a Converter instance from * the registry. All instances are cache to reduce the overhead * of lookups during the serialization process. Converters are * lazily instantiated and so are only created if demanded. * * @param type this is the type to find the converter for * * @return this returns the converter instance for the type */ public Converter lookup(Class type) throws Exception { Converter converter = cache.fetch(type); if(converter == null) { return create(type); } return converter; } /** * This is used to acquire a Converter instance from * the registry. All instances are cached to reduce the overhead * of lookups during the serialization process. Converters are * lazily instantiated and so are only created if demanded. * * @param type this is the type to find the converter for * * @return this returns the converter instance for the type */ private Converter create(Class type) throws Exception { Converter converter = binder.lookup(type); if(converter != null) { cache.cache(type, converter); } return converter; } /** * This is used to register a binding between a type and the * converter used to serialize and deserialize it. During the * serialization process the converters are retrieved and * used to convert the object members to XML. * * @param type this is the object type to bind to a converter * @param converter this is the converter class to be used * * @return this will return this registry instance to use */ public Registry bind(Class type, Class converter) throws Exception { if(type != null) { binder.bind(type, converter); } return this; } /** * This is used to register a binding between a type and the * converter used to serialize and deserialize it. During the * serialization process the converters are retrieved and * used to convert the object properties to XML. * * @param type this is the object type to bind to a converter * @param converter this is the converter instance to be used * * @return this will return this registry instance to use */ public Registry bind(Class type, Converter converter) throws Exception { if(type != null) { cache.cache(type, converter); } return this; } } simple-xml-2.7.1/src/org/simpleframework/xml/convert/ConverterScanner.java0000644000175000017500000001777712166517661026315 0ustar bengenbengen/* * ConverterScanner.java January 2010 * * Copyright (C) 2010, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.convert; import java.lang.annotation.Annotation; import org.simpleframework.xml.Element; import org.simpleframework.xml.Root; import org.simpleframework.xml.strategy.Type; import org.simpleframework.xml.strategy.Value; /** * The ConverterScanner is used to create a converter * given a method or field representation. Creation of the converter * is done using the Convert annotation, which may * be used to annotate a field, method or class. This describes the * implementation to use for object serialization. To account for * polymorphism the type scanned for annotations can be overridden * from type provided in the Type object. This ensures * that if a collection of objects are serialized the correct * implementation will be used for each type or subtype. * * @author Niall Gallagher */ class ConverterScanner { /** * This is used to instantiate converters given the type. */ private final ConverterFactory factory; /** * This is used to build a scanner to scan for annotations. */ private final ScannerBuilder builder; /** * Constructor for the ConverterScanner object. This * uses an internal factory to instantiate and cache all of the * converters created. This will ensure that there is reduced * overhead for a serialization process using converters. */ public ConverterScanner() { this.factory = new ConverterFactory(); this.builder = new ScannerBuilder(); } /** * This method will lookup and instantiate a converter found from * scanning the field or method type provided. If the type has * been overridden then the Value object will provide * the type to scan. If no annotation is found on the class, field * or method then this will return null. * * @param type this is the type to search for the annotation * @param value this contains the type if it was overridden * * @return a converter scanned from the provided field or method */ public Converter getConverter(Type type, Value value) throws Exception { Class real = getType(type, value); Convert convert = getConvert(type, real); if(convert != null) { return factory.getInstance(convert); } return null; } /** * This method will lookup and instantiate a converter found from * scanning the field or method type provided. If the type has * been overridden then the object instance will provide the type * to scan. If no annotation is found on the class, field or * method then this will return null. * * @param type this is the type to search for the annotation * @param value this contains the type if it was overridden * * @return a converter scanned from the provided field or method */ public Converter getConverter(Type type, Object value) throws Exception { Class real = getType(type, value); Convert convert = getConvert(type, real); if(convert != null) { return factory.getInstance(convert); } return null; } /** * This method is used to scan the provided Type for * an annotation. If the Type represents a field or * method then the annotation can be taken directly from that * field or method. If however the type represents a class then * the class itself must contain the annotation. * * @param type the field or method containing the annotation * @param real the type that represents the field or method * * @return this returns the annotation on the field or method */ private Convert getConvert(Type type, Class real) throws Exception { Convert convert = getConvert(type); if(convert == null) { return getConvert(real); } return convert; } /** * This method is used to scan the provided Type for * an annotation. If the Type represents a field or * method then the annotation can be taken directly from that * field or method. If however the type represents a class then * the class itself must contain the annotation. * * @param type the field or method containing the annotation * * @return this returns the annotation on the field or method */ private Convert getConvert(Type type) throws Exception { Convert convert = type.getAnnotation(Convert.class); if(convert != null) { Element element = type.getAnnotation(Element.class); if(element == null) { throw new ConvertException("Element annotation required for %s", type); } } return convert; } /** * This method is used to scan the provided Type for * an annotation. If the Type represents a field or * method then the annotation can be taken directly from that * field or method. If however the type represents a class then * the class itself must contain the annotation. * * @param real the type that represents the field or method * * @return this returns the annotation on the field or method */ private Convert getConvert(Class real) throws Exception { Convert convert = getAnnotation(real, Convert.class); if(convert != null) { Root root = getAnnotation(real, Root.class); if(root == null) { throw new ConvertException("Root annotation required for %s", real); } } return convert; } /** * This is used to acquire the Convert annotation from * the class provided. If the type does not contain the annotation * then this scans all supertypes until either an annotation is * found or there are no further supertypes. * * @param type this is the type to scan for annotations * @param label this is the annotation type that is to be found * * @return this returns the annotation if found otherwise null */ private T getAnnotation(Class type, Class label) { return builder.build(type).scan(label); } /** * This is used to acquire the class that should be scanned. The * type is found either on the method or field, or should there * be a subtype then the class is taken from the provided value. * * @param type this is the type representing the field or method * @param value this contains the type if it was overridden * * @return this returns the class that has been scanned */ private Class getType(Type type, Value value) { Class real = type.getType(); if(value != null) { return value.getType(); } return real; } /** * This is used to acquire the class that should be scanned. The * type is found either on the method or field, or should there * be a subtype then the class is taken from the provided value. * * @param type this is the type representing the field or method * @param value this contains the type if it was overridden * * @return this returns the class that has been scanned */ private Class getType(Type type, Object value) { Class real = type.getType(); if(value != null) { return value.getClass(); } return real; } } simple-xml-2.7.1/src/org/simpleframework/xml/convert/Convert.java0000644000175000017500000000533712166517661024441 0ustar bengenbengen/* * Convert.java January 2010 * * Copyright (C) 2010, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.convert; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * The Convert annotation is used to specify a converter * class to use for serialization. This annotation is used when an * object needs to be serialized but can not be annotated or when the * object can not conform to an existing XML structure. In order to * specify a Converter object a field or method can be * annotated like the field below. *
 * 
 *    @Element
 *    @Convert(ExampleConverter.class)
 *    private Example example;
 * 
 * 
* Note that for the above field the Element annotation * is required. If this is used with any other XML annotation such * as the ElementList or Text annotation * then an exception will be thrown. As well as field and methods * this can be used to suggest a converter for a class. Take the * class below which is annotated. *
 * 
 *    @Root
 *    @Convert(DemoConverter.class)
 *    public class Demo {
 *       ...
 *    }
 * 
 * 
* For the above class the specified converter will be used. This is * useful when the class is used within a java.util.List * or another similar collection. Finally, in order for this to work * it must be used with the AnnotationStrategy which is * used to scan for annotations in order to delegate to converters. * * @author Niall Gallagher * * @see org.simpleframework.xml.convert.AnnotationStrategy */ @Retention(RetentionPolicy.RUNTIME) public @interface Convert { /** * Specifies the Converter implementation to be used * to convert the annotated object. The converter specified will * be used to convert the object to XML by intercepting the * serialization and deserialization process as it happens. A * converter should typically be used to handle an object of * a specific type. * * @return this returns the converter that has been specified */ Class value(); } simple-xml-2.7.1/src/org/simpleframework/xml/convert/Scanner.java0000644000175000017500000000300512166517661024400 0ustar bengenbengen/* * Scanner.java January 2010 * * Copyright (C) 2010, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.convert; import java.lang.annotation.Annotation; /** * The Scanner interface is used to scan a class for a * given annotation. A scanner will cache all previous lookups to * ensure the look time is reduced. Caches include misses, so if a * class does not contain an annotation when scanned it will not * be scanned again. * * @author Niall Gallagher */ interface Scanner { /** * This method will scan a class for the specified annotation. * If the annotation is found on the class, or on one of the super * types then it is returned. All scans should be cached to ensure * scanning is only performed once. * * @param type this is the annotation type to be scanned for * * @return this will return the annotation if it is found */ T scan(Class type); } simple-xml-2.7.1/src/org/simpleframework/xml/convert/RegistryStrategy.java0000644000175000017500000002151012166517661026343 0ustar bengenbengen/* * RegistryStrategy.java January 2010 * * Copyright (C) 2010, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.convert; import java.util.Map; import org.simpleframework.xml.strategy.Strategy; import org.simpleframework.xml.strategy.TreeStrategy; import org.simpleframework.xml.strategy.Type; import org.simpleframework.xml.strategy.Value; import org.simpleframework.xml.stream.InputNode; import org.simpleframework.xml.stream.NodeMap; import org.simpleframework.xml.stream.OutputNode; /** * The RegistryStrategy object is used to intercept * the serialization process and delegate to custom converters. The * custom converters are resolved from a Registry * object, which is provided to the constructor. If there is no * binding for a particular object then serialization is delegated * to an internal strategy. All converters resolved by this are * instantiated once and cached internally for performance. *

* By default the TreeStrategy is used to perform the * normal serialization process should there be no class binding * specifying a converter to use. However, any implementation can * be used, including the CycleStrategy, which handles * cycles in the object graph. To specify the internal strategy to * use it can be provided in the constructor. * * @author Niall Gallagher * * @see org.simpleframework.xml.convert.Registry */ public class RegistryStrategy implements Strategy { /** * This is the registry that is used to resolve bindings. */ private final Registry registry; /** * This is the strategy used if there is no bindings. */ private final Strategy strategy; /** * Constructor for the RegistryStrategy object. This * is used to create a strategy that will intercept the normal * serialization process by searching for bindings within the * provided Registry instance. * * @param registry this is the registry instance with bindings */ public RegistryStrategy(Registry registry) { this(registry, new TreeStrategy()); } /** * Constructor for the RegistryStrategy object. This * is used to create a strategy that will intercept the normal * serialization process by searching for bindings within the * provided Registry instance. * * @param registry this is the registry instance with bindings * @param strategy this is the strategy to delegate to */ public RegistryStrategy(Registry registry, Strategy strategy){ this.registry = registry; this.strategy = strategy; } /** * This is used to read the Value which will be used * to represent the deserialized object. If there is an binding * present then the value will contain an object instance. If it * does not then it is up to the internal strategy to determine * what the returned value contains. * * @param type this is the type that represents a method or field * @param node this is the node representing the XML element * @param map this is the session map that contain variables * * @return the value representing the deserialized value */ public Value read(Type type, NodeMap node, Map map) throws Exception { Value value = strategy.read(type, node, map); if(isReference(value)) { return value; } return read(type, node, value); } /** * This is used to read the Value which will be used * to represent the deserialized object. If there is an binding * present then the value will contain an object instance. If it * does not then it is up to the internal strategy to determine * what the returned value contains. * * @param type this is the type that represents a method or field * @param node this is the node representing the XML element * @param value this is the value from the internal strategy * * @return the value representing the deserialized value */ private Value read(Type type, NodeMap node, Value value) throws Exception { Converter converter = lookup(type, value); InputNode source = node.getNode(); if(converter != null) { Object data = converter.read(source); Class actual = type.getType(); if(value != null) { value.setValue(data); } return new Reference(value, data, actual); } return value; } /** * This is used to serialize a representation of the object value * provided. If there is a Registry binding present * for the provided type then this will use the converter specified * to serialize a representation of the object. If however there * is no binding present then this will delegate to the internal * strategy. This returns true if the serialization has completed. * * @param type this is the type that represents the field or method * @param value this is the object instance to be serialized * @param node this is the XML element to be serialized to * @param map this is the session map used by the serializer * * @return this returns true if it was serialized, false otherwise */ public boolean write(Type type, Object value, NodeMap node, Map map) throws Exception { boolean reference = strategy.write(type, value, node, map); if(!reference) { return write(type, value, node); } return reference; } /** * This is used to serialize a representation of the object value * provided. If there is a Registry binding present * for the provided type then this will use the converter specified * to serialize a representation of the object. If however there * is no binding present then this will delegate to the internal * strategy. This returns true if the serialization has completed. * * @param type this is the type that represents the field or method * @param value this is the object instance to be serialized * @param node this is the XML element to be serialized to * * @return this returns true if it was serialized, false otherwise */ private boolean write(Type type, Object value, NodeMap node) throws Exception { Converter converter = lookup(type, value); OutputNode source = node.getNode(); if(converter != null) { converter.write(source, value); return true; } return false; } /** * This is used to acquire a Converter instance for * the provided value object. The value object is used to resolve * the converter to use for the serialization process. * * @param type this is the type representing the field or method * @param value this is the value that is to be serialized * * @return this returns the converter instance that is matched */ private Converter lookup(Type type, Value value) throws Exception { Class real = type.getType(); if(value != null) { real = value.getType(); } return registry.lookup(real); } /** * This is used to acquire a Converter instance for * the provided object instance. The instance class is used to * resolve the converter to use for the serialization process. * * @param type this is the type representing the field or method * @param value this is the value that is to be serialized * * @return this returns the converter instance that is matched */ private Converter lookup(Type type, Object value) throws Exception { Class real = type.getType(); if(value != null) { real = value.getClass(); } return registry.lookup(real); } /** * This is used to determine if the Value provided * represents a reference. If it does represent a reference then * this will return true, if it does not then this returns false. * * @param value this is the value instance to be evaluated * * @return this returns true if the value represents a reference */ private boolean isReference(Value value) { return value != null && value.isReference(); } } simple-xml-2.7.1/src/org/simpleframework/xml/convert/AnnotationStrategy.java0000644000175000017500000001674112166517661026657 0ustar bengenbengen/* * AnnotationStrategy.java January 2010 * * Copyright (C) 2010, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.convert; import java.util.Map; import org.simpleframework.xml.strategy.Strategy; import org.simpleframework.xml.strategy.TreeStrategy; import org.simpleframework.xml.strategy.Type; import org.simpleframework.xml.strategy.Value; import org.simpleframework.xml.stream.InputNode; import org.simpleframework.xml.stream.NodeMap; import org.simpleframework.xml.stream.OutputNode; /** * The AnnotationStrategy object is used to intercept * the serialization process and delegate to custom converters. This * strategy uses the Convert annotation to specify the * converter to use for serialization and deserialization. If there * is no annotation present on the field or method representing the * object instance to be serialized then this acts as a transparent * proxy to an internal strategy. *

* By default the TreeStrategy is used to perform the * normal serialization process should there be no annotation * specifying a converter to use. However, any implementation can * be used, including the CycleStrategy, which handles * cycles in the object graph. To specify the internal strategy to * use it can be provided in the constructor. * * @author Niall Gallagher * * @see org.simpleframework.xml.strategy.TreeStrategy */ public class AnnotationStrategy implements Strategy { /** * This is used to scan for an annotation and create a converter. */ private final ConverterScanner scanner; /** * This is the strategy that is delegated to for serialization. */ private final Strategy strategy; /** * Constructor for the AnnotationStrategy object. * This creates a strategy that intercepts serialization on any * annotated method or field. If no annotation exists then this * delegates to an internal TreeStrategy object. */ public AnnotationStrategy() { this(new TreeStrategy()); } /** * Constructor for the AnnotationStrategy object. * This creates a strategy that intercepts serialization on any * annotated method or field. If no annotation exists then this * will delegate to the Strategy provided. * * @param strategy the internal strategy to delegate to */ public AnnotationStrategy(Strategy strategy) { this.scanner = new ConverterScanner(); this.strategy = strategy; } /** * This is used to read the Value which will be used * to represent the deserialized object. If there is an annotation * present then the value will contain an object instance. If it * does not then it is up to the internal strategy to determine * what the returned value contains. * * @param type this is the type that represents a method or field * @param node this is the node representing the XML element * @param map this is the session map that contain variables * * @return the value representing the deserialized value */ public Value read(Type type, NodeMap node, Map map) throws Exception { Value value = strategy.read(type, node, map); if(isReference(value)) { return value; } return read(type, node, value); } /** * This is used to read the Value which will be used * to represent the deserialized object. If there is an annotation * present then the value will contain an object instance. If it * does not then it is up to the internal strategy to determine * what the returned value contains. * * @param type this is the type that represents a method or field * @param node this is the node representing the XML element * @param value this is the value from the internal strategy * * @return the value representing the deserialized value */ private Value read(Type type, NodeMap node, Value value) throws Exception { Converter converter = scanner.getConverter(type, value); InputNode parent = node.getNode(); if(converter != null) { Object data = converter.read(parent); Class actual = type.getType(); if(value != null) { value.setValue(data); } return new Reference(value, data, actual); } return value; } /** * This is used to serialize a representation of the object value * provided. If there is a Convert annotation present * on the provided type then this will use the converter specified * to serialize a representation of the object. If however there * is no annotation then this will delegate to the internal * strategy. This returns true if the serialization has completed. * * @param type this is the type that represents the field or method * @param value this is the object instance to be serialized * @param node this is the XML element to be serialized to * @param map this is the session map used by the serializer * * @return this returns true if it was serialized, false otherwise */ public boolean write(Type type, Object value, NodeMap node, Map map) throws Exception { boolean reference = strategy.write(type, value, node, map); if(!reference) { return write(type, value, node); } return reference; } /** * This is used to serialize a representation of the object value * provided. If there is a Convert annotation present * on the provided type then this will use the converter specified * to serialize a representation of the object. If however there * is no annotation then this will delegate to the internal * strategy. This returns true if the serialization has completed. * * @param type this is the type that represents the field or method * @param value this is the object instance to be serialized * @param node this is the XML element to be serialized to * * @return this returns true if it was serialized, false otherwise */ private boolean write(Type type, Object value, NodeMap node) throws Exception { Converter converter = scanner.getConverter(type, value); OutputNode parent = node.getNode(); if(converter != null) { converter.write(parent, value); return true; } return false; } /** * This is used to determine if the Value provided * represents a reference. If it does represent a reference then * this will return true, if it does not then this returns false. * * @param value this is the value instance to be evaluated * * @return this returns true if the value represents a reference */ private boolean isReference(Value value) { return value != null && value.isReference(); } } simple-xml-2.7.1/src/org/simpleframework/xml/convert/ConvertException.java0000644000175000017500000000311712166517661026312 0ustar bengenbengen/* * ConvertException.java January 2010 * * Copyright (C) 2010, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.convert; /** * The ConvertException is thrown when there is a * problem converting an object. Such an exception can occur if an * annotation is use incorrectly, or if a Converter * can not be instantiated. Messages provided to this exception are * formatted similar to the PrintStream.printf method. * * @author Niall Gallagher */ public class ConvertException extends Exception { /** * Constructor for the ConvertException object. * This constructor takes a format string an a variable number of * object arguments, which can be inserted into the format string. * * @param text a format string used to present the error message * @param list a list of arguments to insert into the string */ public ConvertException(String text, Object... list) { super(String.format(text, list)); } } simple-xml-2.7.1/src/org/simpleframework/xml/convert/Reference.java0000644000175000017500000000727312166517661024720 0ustar bengenbengen/* * Reference.java January 2010 * * Copyright (C) 2010, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.convert; import org.simpleframework.xml.strategy.Value; /** * The Reference object represents a value that holds * an object instance. If an object instance is to be provided from * a Strategy implementation it must be wrapped in a * value object. The value object can then provide the details of * the instance and the actual object instance to the serializer. * * @author Niall Gallagher */ class Reference implements Value { /** * This represents the original value returned from a strategy. */ private Value value; /** * This represents the object instance that this represents. */ private Object data; /** * This is the actual type of the reference that is represented. */ private Class actual; /** * Constructor for a Reference object. To create * this a value and an object instance is required. The value * provided may be null, but the instance should be a valid * object instance to be used by the serializer. * * @param value this is the original value from a strategy * @param data this is the object instance that is wrapped * @param actual this is the overriding type of the reference */ public Reference(Value value, Object data, Class actual){ this.actual = actual; this.value = value; this.data = data; } /** * This will return the length of an array reference. Because * the value will represent the value itself the length is * never used, as no instance needs to be created. * * @return this will always return zero for a reference */ public int getLength() { return 0; } /** * This is the type of the object instance this represents. The * type returned by this is used to instantiate an object which * will be set on this value and the internal graph maintained. * * @return the type of the object that must be instantiated */ public Class getType() { if(data != null) { return data.getClass(); } return actual; } /** * This returns the actual object instance that is held by this * reference object. */ public Object getValue() { return data; } /** * This will always return true as this Value object * will always contain an object instance. Returning true from * this method tells the serializer that there is no need to * actually perform any further deserialization. * * @return this always returns true as this will be a reference */ public boolean isReference() { return true; } /** * This is used to set the value of the object. If the internal * Value is not null then the internal value will * have the instance set also. * * @param data this is the object instance that is to be set */ public void setValue(Object data) { if(value != null) { value.setValue(data); } this.data = data; } }simple-xml-2.7.1/src/org/simpleframework/xml/convert/Converter.java0000644000175000017500000000530512166517661024763 0ustar bengenbengen/* * Converter.java January 2010 * * Copyright (C) 2010, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.convert; import org.simpleframework.xml.stream.InputNode; import org.simpleframework.xml.stream.OutputNode; /** * The Converter object is used to convert an object * to XML by intercepting the normal serialization process. When * serializing an object the write method is invoked. * This is provided with the object instance to be serialized and * the OutputNode to use to write the XML. Values * can be taken from the instance and transferred to the node. *

* For deserialization the read method is invoked. * This is provided with the InputNode, which can be * used to read the elements and attributes representing the * member data of the object being deserialized. Once the object * has been instantiated it must be returned. * * @author Niall Gallagher * * @see org.simpleframework.xml.convert.AnnotationStrategy * @see org.simpleframework.xml.convert.RegistryStrategy */ public interface Converter { /** * This read method is used to deserialize an object * from the source XML. The deserialization is performed using * the XML node provided. This node can be used to read the XML * elements and attributes in any format required. Once all of * the data has been extracted an instance must be returned. * * @param node this is the node to deserialize the object from * * @return the object instance resulting from the deserialization */ T read(InputNode node) throws Exception; /** * This write method is used to serialize an object * to XML. The serialization should be performed in such a way * that all of the objects values are represented by an element * or attribute of the provided node. This ensures that it can * be fully deserialized at a later time. * * @param node this is the node to serialized to object to * @param value this is the value that is to be serialized */ void write(OutputNode node, T value) throws Exception; }simple-xml-2.7.1/src/org/simpleframework/xml/convert/ScannerBuilder.java0000644000175000017500000001125712166517661025717 0ustar bengenbengen/* * ScannerBuilder.java January 2010 * * Copyright (C) 2010, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.convert; import java.lang.annotation.Annotation; import org.simpleframework.xml.util.ConcurrentCache; /** * The ScannerBuilder is used to build and cache each * scanner requested. Building and caching scanners ensures that * annotations can be acquired from a class quickly as a scan only * needs to be performed once. Each scanner built scans the class * provided as well as all the classes in the hierarchy. * * @author Niall Gallagher * * @see org.simpleframework.xml.convert.ConverterScanner */ class ScannerBuilder extends ConcurrentCache { /** * Constructor for the ScannerBuilder object. This * will create a builder for annotation scanners. Each of the * scanners build will be cached internally to ensure that any * further requests for the scanner are quicker. */ public ScannerBuilder() { super(); } /** * This is used to build Scanner objects that are * used to scan the provided class for annotations. Each scanner * instance is cached once created to ensure it does not need to * be built twice, which improves the performance. * * @param type this is the type to build a scanner object for * * @return this will return a scanner instance for the given type */ public Scanner build(Class type) { Scanner scanner = get(type); if(scanner == null) { scanner = new Entry(type); put(type, scanner); } return scanner; } /** * The Entry object represents a scanner that is * used to scan a specified type for annotations. All annotations * scanned from the type are cached so that they do not need to * be looked up twice. This ensures scanning is much quicker. * * @author Niall Gallagher */ private static class Entry extends ConcurrentCache implements Scanner { /** * This class is the subject for all annotation scans performed. */ private final Class root; /** * Constructor for the Entry object is used to * create a scanner that will scan the specified type. All * annotations that are scanned are cached to ensure that they * do not need to be looked up twice. This ensures that scans * are quicker including ones that result in null. * * @param root this is the root class that is to be scanned */ public Entry(Class root) { this.root = root; } /** * This method will scan a class for the specified annotation. * If the annotation is found on the class, or on one of the * super types then it is returned. All scans will be cached * to ensure scanning is only performed once. * * @param type this is the annotation type to be scanned for * * @return this will return the annotation if it is found */ public T scan(Class type) { if(!contains(type)) { T value = find(type); if(type != null && value != null) { put(type, value); } } return (T)get(type); } /** * This method will scan a class for the specified annotation. * If the annotation is found on the class, or on one of the * super types then it is returned. All scans will be cached * to ensure scanning is only performed once. * * @param label this is the annotation type to be scanned for * * @return this will return the annotation if it is found */ private T find(Class label) { Class type = root; while(type != null) { T value = type.getAnnotation(label); if(value != null) { return value; } type = type.getSuperclass(); } return null; } } }simple-xml-2.7.1/src/org/simpleframework/xml/convert/ConverterFactory.java0000644000175000017500000001156612166517661026321 0ustar bengenbengen/* * ConverterFactory.java January 2010 * * Copyright (C) 2010, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.convert; import java.lang.reflect.Constructor; import org.simpleframework.xml.util.Cache; import org.simpleframework.xml.util.ConcurrentCache; /** * The ConverterFactory is used to instantiate objects * based on a provided type or annotation. This provides a single * point of creation for all converters within the framework. For * performance all the instantiated converters are cached against * the class for that converter. This ensures the converters can * be acquired without the overhead of instantiation. * * @author Niall Gallagher * * @see org.simpleframework.xml.convert.ConverterCache */ class ConverterFactory { /** * This is the cache that is used to cache converter instances. */ private final Cache cache; /** * Constructor for the ConverterFactory object. * This will create an internal cache which is used to cache all * instantiations made by the factory. Caching the converters * ensures there is no overhead with instantiations. */ public ConverterFactory() { this.cache = new ConcurrentCache(); } /** * This is used to instantiate the converter based on the type * provided. If the type provided can not be instantiated for * some reason then an exception is thrown from this method. * * @param type this is the converter type to be instantiated * * @return this returns an instance of the provided type */ public Converter getInstance(Class type) throws Exception { Converter converter = cache.fetch(type); if(converter == null) { return getConverter(type); } return converter; } /** * This is used to instantiate the converter based on the type * of the Convert annotation provided. If the type * can not be instantiated for some reason then an exception is * thrown from this method. * * @param convert this is the annotation containing the type * * @return this returns an instance of the provided type */ public Converter getInstance(Convert convert) throws Exception { Class type = convert.value(); if(type.isInterface()) { throw new ConvertException("Can not instantiate %s", type); } return getInstance(type); } /** * This is used to instantiate the converter based on the type * provided. If the type provided can not be instantiated for * some reason then an exception is thrown from this method. * * @param type this is the converter type to be instantiated * * @return this returns an instance of the provided type */ private Converter getConverter(Class type) throws Exception { Constructor factory = getConstructor(type); if(factory == null){ throw new ConvertException("No default constructor for %s", type); } return getConverter(type, factory); } /** * This is used to instantiate the converter based on the type * provided. If the type provided can not be instantiated for * some reason then an exception is thrown from this method. * * @param type this is the converter type to be instantiated * @param factory this is the constructor used to instantiate * * @return this returns an instance of the provided type */ private Converter getConverter(Class type, Constructor factory) throws Exception { Converter converter = (Converter)factory.newInstance(); if(converter != null){ cache.cache(type, converter); } return converter; } /** * This is used to acquire the default no argument constructor * for the the provided type. If the constructor is not accessible * then it will be made accessible so that it can be instantiated. * * @param type this is the type to acquire the constructor for * * @return this returns the constructor for the type provided */ private Constructor getConstructor(Class type) throws Exception { Constructor factory = type.getDeclaredConstructor(); if(!factory.isAccessible()) { factory.setAccessible(true); } return factory; } } simple-xml-2.7.1/src/org/simpleframework/xml/util/0000755000175000017500000000000012271465260021435 5ustar bengenbengensimple-xml-2.7.1/src/org/simpleframework/xml/util/Resolver.java0000644000175000017500000003534712166517661024123 0ustar bengenbengen/* * Resolver.java February 2001 * * Copyright (C) 2001, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.util; import java.util.AbstractSet; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; /** * This is used to store Match objects, which can then be * retrieved using a string by comparing that string to the pattern of * the Match objects. Patterns consist of characters * with either the '*' or '?' characters as wild characters. The '*' * character is completely wild meaning that is will match nothing or * a long sequence of characters. The '?' character matches a single * character. *

* If the '?' character immediately follows the '*' character then the * match is made as any sequence of characters up to the first match * of the next character. For example "/*?/index.jsp" will match all * files preceeded by only a single path. So "/pub/index.jsp" will * match, however "/pub/bin/index.jsp" will not, as it has two paths. * So, in effect the '*?' sequence will match anything or nothing up * to the first occurence of the next character in the pattern. *

* A design goal of the Resolver was to make it capable * of high performance. In order to achieve a high performance the * Resolver can cache the resolutions it makes so that if * the same text is given to the Resolver.resolve method * a cached result can be retrived quickly which will decrease the * length of time and work required to perform the match. *

* The semantics of the resolver are such that the last pattern added * with a wild string is the first one checked for a match. This means * that if a sequence of insertions like add(x) followed * by add(y) is made, then a resolve(z) will * result in a comparison to y first and then x, if z matches y then * it is given as the result and if z does not match y and matches x * then x is returned, remember if z matches both x and y then y will * be the result due to the fact that is was the last pattern added. * * @author Niall Gallagher */ public class Resolver extends AbstractSet { /** * Caches the text resolutions made to reduce the work required. */ protected final Cache cache; /** * Stores the matches added to the resolver in resolution order. */ protected final Stack stack; /** * The default constructor will create a Resolver * without a large cache size. This is intended for use when * the requests for resolve tend to use strings * that are reasonably similar. If the strings issued to this * instance are dramatically different then the cache tends * to be an overhead rather than a bonus. */ public Resolver(){ this.stack = new Stack(); this.cache = new Cache(); } /** * This will search the patterns in this Resolver to * see if there is a pattern in it that matches the string given. * This will search the patterns from the last entered pattern to * the first entered. So that the last entered patterns are the * most searched patterns and will resolve it first if it matches. * * @param text this is the string that is to be matched by this * * @return this will return the first match within the resolver */ public M resolve(String text){ List list = cache.get(text); if(list == null) { list = resolveAll(text); } if(list.isEmpty()) { return null; } return list.get(0); } /** * This will search the patterns in this Resolver to * see if there is a pattern in it that matches the string given. * This will search the patterns from the last entered pattern to * the first entered. So that the last entered patterns are the * most searched patterns and will resolve it first if it matches. * * @param text this is the string that is to be matched by this * * @return this will return all of the matches within the resolver */ public List resolveAll(String text){ List list = cache.get(text); if(list != null) { return list; } char[] array = text.toCharArray(); if(array == null) { return null; } return resolveAll(text, array); } /** * This will search the patterns in this Resolver to * see if there is a pattern in it that matches the string given. * This will search the patterns from the last entered pattern to * the first entered. So that the last entered patterns are the * most searched patterns and will resolve it first if it matches. * * @param text this is the string that is to be matched by this * @param array this is the character array of the text string * * @return this will return all of the matches within the resolver */ private List resolveAll(String text, char[] array){ List list = new ArrayList(); for(M match : stack) { String wild = match.getPattern(); if(match(array, wild.toCharArray())){ cache.put(text, list); list.add(match); } } return list; } /** * This inserts the Match implementation into the set * so that it can be used for resolutions. The last added match is * the first resolved. Because this changes the state of the * resolver this clears the cache as it may affect resolutions. * * @param match this is the match that is to be inserted to this * * @return returns true if the addition succeeded, always true */ public boolean add(M match) { stack.push(match); return true; } /** * This returns an Iterator that iterates over the * matches in insertion order. So the first match added is the * first retrieved from the Iterator. This order is * used to ensure that resolver can be serialized properly. * * @return returns an iterator for the sequence of insertion */ public Iterator iterator() { return stack.sequence(); } /** * This is used to remove the Match implementation * from the resolver. This clears the cache as the removal of * a match may affect the resoultions existing in the cache. The * equals method of the match must be implemented. * * @param match this is the match that is to be removed * * @return true of the removal of the match was successful */ public boolean remove(M match) { cache.clear(); return stack.remove(match); } /** * Returns the number of matches that have been inserted into * the Resolver. Although this is a set, it does * not mean that matches cannot used the same pattern string. * * @return this returns the number of matches within the set */ public int size() { return stack.size(); } /** * This is used to clear all matches from the set. This ensures * that the resolver contains no matches and that the resolution * cache is cleared. This is used to that the set can be reused * and have new pattern matches inserted into it for resolution. */ public void clear() { cache.clear(); stack.clear(); } /** * This acts as a driver to the match method so that * the offsets can be used as zeros for the start of matching for * the match(char[],int,char[],int). method. This is * also used as the initializing driver for the recursive method. * * @param text this is the buffer that is to be resolved * @param wild this is the pattern that will be used */ private boolean match(char[] text, char[] wild){ return match(text, 0, wild, 0); } /** * This will be used to check to see if a certain buffer matches * the pattern if it does then it returns true. This * is a recursive method that will attempt to match the buffers * based on the wild characters '?' and '*'. If there is a match * then this returns true. * * @param text this is the buffer that is to be resolved * @param off this is the read offset for the text buffer * @param wild this is the pattern that will be used * @param pos this is the read offset for the wild buffer */ private boolean match(char[] text, int off, char[] wild, int pos){ while(pos < wild.length && off < text.length){ /* examine chars */ if(wild[pos] == '*'){ while(wild[pos] == '*'){ /* totally wild */ if(++pos >= wild.length) /* if finished */ return true; } if(wild[pos] == '?') { /* *? is special */ if(++pos >= wild.length) return true; } for(; off < text.length; off++){ /* find next matching char */ if(text[off] == wild[pos] || wild[pos] == '?'){ /* match */ if(wild[pos - 1] != '?'){ if(match(text, off, wild, pos)) return true; } else { break; } } } if(text.length == off) return false; } if(text[off++] != wild[pos++]){ if(wild[pos-1] != '?') return false; /* if not equal */ } } if(wild.length == pos){ /* if wild is finished */ return text.length == off; /* is text finished */ } while(wild[pos] == '*'){ /* ends in all stars */ if(++pos >= wild.length) /* if finished */ return true; } return false; } /** * This is used to cache resolutions made so that the matches can * be acquired the next time without performing the resolution. * This is an LRU cache so regardless of the number of resolutions * made this will not result in a memory leak for the resolver. * * @author Niall Gallagher */ private class Cache extends LimitedCache> { /** * Constructor for the Cache object. This is a * constructor that creates the linked hash map such that * it will purge the entries that are oldest within the map. */ public Cache() { super(1024); } } /** * This is used to store the Match implementations in * resolution order. Resolving the match objects is performed so * that the last inserted match object is the first used in the * resolution process. This gives priority to the last inserted. * * @author Niall Gallagher */ private class Stack extends LinkedList { /** * The push method is used to push the match to * the top of the stack. This also ensures that the cache is * cleared so the semantics of the resolver are not affected. * * @param match this is the match to be inserted to the stack */ public void push(M match) { cache.clear(); addFirst(match); } /** * The purge method is used to purge a match from * the provided position. This also ensures that the cache is * cleared so that the semantics of the resolver do not change. * * @param index the index of the match that is to be removed */ public void purge(int index) { cache.clear(); remove(index); } /** * This is returned from the Resolver.iterator so * that matches can be iterated in insertion order. When a * match is removed from this iterator then it clears the cache * and removed the match from the Stack object. * * @return returns an iterator to iterate in insertion order */ public Iterator sequence() { return new Sequence(); } /** * The is used to order the Match objects in the * insertion order. Iterating in insertion order allows the * resolver object to be serialized and deserialized to and * from an XML document without disruption resolution order. * * @author Niall Gallagher */ private class Sequence implements Iterator { /** * The cursor used to acquire objects from the stack. */ private int cursor; /** * Constructor for the Sequence object. This is * used to position the cursor at the end of the list so the * first inserted match is the first returned from this. */ public Sequence() { this.cursor = size(); } /** * This returns the Match object at the cursor * position. If the cursor has reached the start of the * list then this returns null instead of the first match. * * @return this returns the match from the cursor position */ public M next() { if(hasNext()) { return get(--cursor); } return null; } /** * This is used to determine if the cursor has reached the * start of the list. When the cursor reaches the start of * the list then this method returns false. * * @return this returns true if there are more matches left */ public boolean hasNext() { return cursor > 0; } /** * Removes the match from the cursor position. This also * ensures that the cache is cleared so that resolutions * made before the removal do not affect the semantics. */ public void remove() { purge(cursor); } } } } simple-xml-2.7.1/src/org/simpleframework/xml/util/Dictionary.java0000644000175000017500000001174212166517661024420 0ustar bengenbengen/* * Dictionary.java July 2006 * * Copyright (C) 2006, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.util; import java.util.AbstractSet; import java.util.HashMap; import java.util.Iterator; /** * The Dictionary object represents a mapped set of entry * objects that can be serialized and deserialized. This is used when * there is a need to load a list of objects that can be mapped using * a name attribute. Using this object avoids the need to implement a * commonly required pattern of building a map of XML element objects. *

 *
 *    <dictionary>
 *       <entry name="example">
 *          <element>example text</element>
 *       </entry>
 *       <entry name="example">
 *          <element>example text</element>
 *       </entry>       
 *    </dictionary>
 * 
 * 
* This can contain implementations of the Entry object * which contains a required "name" attribute. Implementations of the * entry object can add further XML attributes an elements. This must * be annotated with the ElementList annotation in order * to be serialized and deserialized as an object field. * * @author Niall Gallagher * * @see org.simpleframework.xml.util.Entry */ public class Dictionary extends AbstractSet { /** * Used to map the entries to their configured names. */ protected final Table map; /** * Constructor for the Dictionary object. This * is used to create a set that contains entry objects mapped * to an XML attribute name value. Entry objects added to this * dictionary can be retrieved using its name value. */ public Dictionary() { this.map = new Table(); } /** * This method is used to add the provided entry to this set. If * an entry of the same name already existed within the set then * it is replaced with the specified Entry object. * * @param item this is the entry object that is to be inserted */ public boolean add(T item) { return map.put(item.getName(), item) != null; } /** * This returns the number of Entry objects within * the dictionary. This will use the internal map to acquire the * number of entry objects that have been inserted to the map. * * @return this returns the number of entry objects in the set */ public int size() { return map.size(); } /** * Returns an iterator of Entry objects which can be * used to remove items from this set. This will use the internal * map object and return the iterator for the map values. * * @return this returns an iterator for the entry objects */ public Iterator iterator() { return map.values().iterator(); } /** * This is used to acquire an Entry from the set by * its name. This uses the internal map to look for the entry, if * the entry exists it is returned, if not this returns null. * * @param name this is the name of the entry object to retrieve * * @return this returns the entry mapped to the specified name */ public T get(String name) { return map.get(name); } /** * This is used to remove an Entry from the set by * its name. This uses the internal map to look for the entry, if * the entry exists it is returned and removed from the map. * * @param name this is the name of the entry object to remove * * @return this returns the entry mapped to the specified name */ public T remove(String name) { return map.remove(name); } /** * The Table object is used to represent a map of * entries mapped to a string name. Each implementation of the * entry must contain a name attribute, which is used to insert * the entry into the map. This acts as a typedef. * * @see org.simpleframework.xml.util.Entry */ private static class Table extends HashMap { /** * Constructor for the Table object. This will * create a map that is used to store the entry objects that * are serialized and deserialized to and from an XML source. */ public Table() { super(); } } } simple-xml-2.7.1/src/org/simpleframework/xml/util/LimitedCache.java0000644000175000017500000001020012166517661024612 0ustar bengenbengen/* * LinkedCache.java July 2012 * * Copyright (C) 2006, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.util; import java.util.LinkedHashMap; import java.util.Map.Entry; /** * The LimitedCache interface is used to represent a * cache that will store key value pairs. This implementation is * backed by a LinkedHashMap so that only a specific * number of elements can be stored in the cache at one time. * * @author Niall Gallagher */ public class LimitedCache extends LinkedHashMap implements Cache { /** * This represents the capacity of this cache instance. */ private final int capacity; /** * Constructor of the LimitedCache object. This is * used to create a cache with a fixed size. The strategy for * this cache is least recently used. Any insert or fetch from * the cache is considered to be a use. */ public LimitedCache() { this(50000); } /** * Constructor of the LimitedCache object. This is * used to create a cache with a fixed size. The strategy for * this cache is least recently used. Any insert or fetch from * the cache is considered to be a use. * * @param capacity this is the capacity of the cache object */ public LimitedCache(int capacity) { this.capacity = capacity; } /** * This method is used to insert a key value mapping in to the * cache. The value can later be retrieved or removed from the * cache if desired. If the value associated with the key is * null then nothing is stored within the cache. * * @param key this is the key to cache the provided value to * @param value this is the value that is to be cached */ public void cache(Object key, T value) { put(key, value); } /** * This is used to exclusively take the value mapped to the * specified key from the cache. Invoking this is effectively * removing the value from the cache. * * @param key this is the key to acquire the cache value with * * @return this returns the value mapped to the specified key */ public T take(Object key) { return remove(key); } /** * This method is used to get the value from the cache that is * mapped to the specified key. If there is no value mapped to * the specified key then this method will return a null. * * @param key this is the key to acquire the cache value with * * @return this returns the value mapped to the specified key */ public T fetch(Object key) { return get(key); } /** * This is used to determine whether the specified key exists * with in the cache. Typically this can be done using the * fetch method, which will acquire the object. * * @param key this is the key to check within this segment * * @return true if the specified key is within the cache */ public boolean contains(Object key) { return containsKey(key); } /** * This is used to remove the eldest entry from the cache. * The eldest entry is removed from the cache if the size of * the map grows larger than the maximum entries permitted. * * @param entry this is the eldest entry that can be removed * * @return this returns true if the entry should be removed */ protected boolean removeEldestEntry(Entry entry) { return size() > capacity; } } simple-xml-2.7.1/src/org/simpleframework/xml/util/Cache.java0000644000175000017500000000543712166517661023322 0ustar bengenbengen/* * Cache.java July 2006 * * Copyright (C) 2006, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.util; /** * The Cache interface is used to represent a cache * that will store key value pairs. The cache exposes only several * methods to ensure that implementations can focus on performance * concerns rather than how to manage the cached values. * * @author Niall Gallagher */ public interface Cache { /** * This method is used to determine if the cache is empty. This * is done by checking if there are any elements in the cache. * If anything has been cached this will return false. * * @return this returns true if the cache is empty */ boolean isEmpty(); /** * This method is used to insert a key value mapping in to the * cache. The value can later be retrieved or removed from the * cache if desired. If the value associated with the key is * null then nothing is stored within the cache. * * @param key this is the key to cache the provided value to * @param value this is the value that is to be cached */ void cache(Object key, T value); /** * This is used to exclusively take the value mapped to the * specified key from the cache. Invoking this is effectively * removing the value from the cache. * * @param key this is the key to acquire the cache value with * * @return this returns the value mapped to the specified key */ T take(Object key); /** * This method is used to get the value from the cache that is * mapped to the specified key. If there is no value mapped to * the specified key then this method will return a null. * * @param key this is the key to acquire the cache value with * * @return this returns the value mapped to the specified key */ T fetch(Object key); /** * This is used to determine whether the specified key exists * with in the cache. Typically this can be done using the * fetch method, which will acquire the object. * * @param key this is the key to check within this segment * * @return true if the specified key is within the cache */ boolean contains(Object key); }simple-xml-2.7.1/src/org/simpleframework/xml/util/Match.java0000644000175000017500000000320212166517661023337 0ustar bengenbengen/* * Match.java March 2002 * * Copyright (C) 2001, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.util; /** * This object is stored within a Resolver so that it * can be retrieved using a string that matches its pattern. Any * object that extends this can be inserted into the resolver and * retrieved using a string that matches its pattern. For example * take the following pattern "*.html" this will match the string * "/index.html" or "readme.html". This object should be extended * to add more XML attributes and elements, which can be retrieved * when the Match object is retrieve from a resolver. * * @author Niall Gallagher */ public interface Match { /** * This is the pattern string that is used by the resolver. A * pattern can consist of a "*" character and a "?" character * to match the pattern. Implementations of this class should * provide the pattern so that it can be used for resolution. * * @return this returns the pattern that is to be matched */ String getPattern(); } simple-xml-2.7.1/src/org/simpleframework/xml/util/WeakCache.java0000644000175000017500000002243312166517661024125 0ustar bengenbengen/* * WeakCache.java July 2006 * * Copyright (C) 2006, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.util; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.WeakHashMap; /** * The WeakCache object is an implementation of a cache * that holds on to cached items only if the key remains in memory. * This is effectively like a concurrent hash map with weak keys, it * ensures that multiple threads can concurrently access weak hash * maps in a way that lowers contention for the locks used. * * @author Niall Gallagher */ public class WeakCache implements Cache { /** * This is used to store a list of segments for the cache. */ private SegmentList list; /** * Constructor for the WeakCache object. This is * used to create a cache that stores values in such a way that * when the key is garbage collected the value is removed from * the map. This is similar to the concurrent hash map. */ public WeakCache() { this(10); } /** * Constructor for the WeakCache object. This is * used to create a cache that stores values in such a way that * when the key is garbage collected the value is removed from * the map. This is similar to the concurrent hash map. * * @param size this is the number of segments within the cache */ public WeakCache(int size) { this.list = new SegmentList(size); } public boolean isEmpty() { for(Segment segment : list) { if(!segment.isEmpty()) { return false; } } return true; } /** * This method is used to insert a key value mapping in to the * cache. The value can later be retrieved or removed from the * cache if desired. If the value associated with the key is * null then nothing is stored within the cache. * * @param key this is the key to cache the provided value to * @param value this is the value that is to be cached */ public void cache(Object key, T value) { map(key).cache(key, value); } /** * This is used to exclusively take the value mapped to the * specified key from the cache. Invoking this is effectively * removing the value from the cache. * * @param key this is the key to acquire the cache value with * * @return this returns the value mapped to the specified key */ public T take(Object key) { return map(key).take(key); } /** * This method is used to get the value from the cache that is * mapped to the specified key. If there is no value mapped to * the specified key then this method will return a null. * * @param key this is the key to acquire the cache value with * * @return this returns the value mapped to the specified key */ public T fetch(Object key) { return map(key).fetch(key); } /** * This is used to determine whether the specified key exists * with in the cache. Typically this can be done using the * fetch method, which will acquire the object. * * @param key this is the key to check within this segment * * @return true if the specified key is within the cache */ public boolean contains(Object key) { return map(key).contains(key); } /** * This method is used to acquire a Segment using * the keys has code. This method effectively uses the hash to * find a specific segment within the fixed list of segments. * * @param key this is the key used to acquire the segment * * @return this returns the segment used to get acquire value */ private Segment map(Object key) { return list.get(key); } /** * This is used to maintain a list of segments. All segments that * are stored by this object can be acquired using a given key. * The keys hash is used to select the segment, this ensures that * all read and write operations with the same key result in the * same segment object within this list. * * @author Niall Gallagher */ private class SegmentList implements Iterable { /** * The list of segment objects maintained by this object. */ private List list; /** * Represents the number of segments this object maintains. */ private int size; /** * Constructor for the SegmentList object. This * is used to create a list of weak hash maps that can be * acquired using the hash code of a given key. * * @param size this is the number of hash maps to maintain */ public SegmentList(int size) { this.list = new ArrayList(); this.size = size; this.create(size); } public Iterator iterator() { return list.iterator(); } /** * This is used to acquire the segment using the given key. * The keys hash is used to determine the index within the * list to acquire the segment, which is a synchronized weak * hash map storing the key value pairs for a given hash. * * @param key this is the key used to determine the segment * * @return the segment that is stored at the resolved hash */ public Segment get(Object key) { int segment = segment(key); if(segment < size) { return list.get(segment); } return null; } /** * Upon initialization the segment list is populated in such * a way that synchronization is not needed. Each segment is * created and stored in an increasing index within the list. * * @param size this is the number of segments to be used */ private void create(int size) { int count = size; while(count-- > 0) { list.add(new Segment()); } } /** * This method performs the translation of the key hash code * to the segment index within the list. Translation is done * by acquiring the modulus of the hash and the list size. * * @param key this is the key used to resolve the index * * @return the index of the segment within the list */ private int segment(Object key) { return Math.abs(key.hashCode() % size); } } /** * The segment is effectively a synchronized weak hash map. If is * used to store the key value pairs in such a way that they are * kept only as long as the garbage collector does not collect * the key. This ensures the cache does not cause memory issues. * * @author Niall Gallagher */ private class Segment extends WeakHashMap { /** * This method is used to insert a key value mapping in to the * cache. The value can later be retrieved or removed from the * cache if desired. If the value associated with the key is * null then nothing is stored within the cache. * * @param key this is the key to cache the provided value to * @param value this is the value that is to be cached */ public synchronized void cache(Object key, T value) { put(key, value); } /** * This method is used to get the value from the cache that is * mapped to the specified key. If there is no value mapped to * the specified key then this method will return a null. * * @param key this is the key to acquire the cache value with * * @return this returns the value mapped to the specified key */ public synchronized T fetch(Object key) { return get(key); } /** * This is used to exclusively take the value mapped to the * specified key from the cache. Invoking this is effectively * removing the value from the cache. * * @param key this is the key to acquire the cache value with * * @return this returns the value mapped to the specified key */ public synchronized T take(Object key) { return remove(key); } /** * This is used to determine whether the specified key exists * with in the cache. Typically this can be done using the * fetch method, which will acquire the object. * * @param key this is the key to check within this segment * * @return true if the specified key is within the cache */ public synchronized boolean contains(Object key) { return containsKey(key); } } } simple-xml-2.7.1/src/org/simpleframework/xml/util/Entry.java0000644000175000017500000000322112166517661023405 0ustar bengenbengen/* * Entry.java July 2006 * * Copyright (C) 2006, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.util; /** * The Entry object represents entries to the dictionary * object. Every entry must have a name attribute, which is used to * establish mappings within the Dictionary object. Each * entry entered into the dictionary can be retrieved using its name. *

* The entry can be serialzed with the dictionary to an XML document. * Items stored within the dictionary need to extend this entry * object to ensure that they can be mapped and serialized with the * dictionary. Implementations should override the root annotation. * * @author Niall Gallagher */ public interface Entry { /** * Represents the name of the entry instance used for mappings. * This will be used to map the object to the internal map in * the Dictionary. This allows serialized objects * to be added to the dictionary transparently. * * @return this returns the name of the entry that is used */ String getName(); } simple-xml-2.7.1/src/org/simpleframework/xml/util/ConcurrentCache.java0000644000175000017500000000605712166517661025364 0ustar bengenbengen/* * ConcurrentCache.java July 2012 * * Copyright (C) 2006, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.util; import java.util.concurrent.ConcurrentHashMap; /** * The ConcurrentCache interface is used to represent a * cache that will store key value pairs. This implementation is * backed by a ConcurrentHashMap for best performance. * * @author Niall Gallagher */ public class ConcurrentCache extends ConcurrentHashMap implements Cache { /** * Constructor for the ConcurrentCache object. This * is an implementation of a cache that uses the conventional * concurrent hash map from the Java collections API. */ public ConcurrentCache() { super(); } /** * This method is used to insert a key value mapping in to the * cache. The value can later be retrieved or removed from the * cache if desired. If the value associated with the key is * null then nothing is stored within the cache. * * @param key this is the key to cache the provided value to * @param value this is the value that is to be cached */ public void cache(Object key, T value) { put(key, value); } /** * This is used to exclusively take the value mapped to the * specified key from the cache. Invoking this is effectively * removing the value from the cache. * * @param key this is the key to acquire the cache value with * * @return this returns the value mapped to the specified key */ public T take(Object key) { return remove(key); } /** * This method is used to get the value from the cache that is * mapped to the specified key. If there is no value mapped to * the specified key then this method will return a null. * * @param key this is the key to acquire the cache value with * * @return this returns the value mapped to the specified key */ public T fetch(Object key) { return get(key); } /** * This is used to determine whether the specified key exists * with in the cache. Typically this can be done using the * fetch method, which will acquire the object. * * @param key this is the key to check within this segment * * @return true if the specified key is within the cache */ public boolean contains(Object key) { return containsKey(key); } } simple-xml-2.7.1/src/org/simpleframework/xml/ElementListUnion.java0000644000175000017500000000534712166517661024600 0ustar bengenbengen/* * ElementListUnion.java March 2011 * * Copyright (C) 2011, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * The ElementListUnion annotation is used to describe * fields and methods that can dynamically match a schema class. Each * union can have a number of different XML class schemas matched based * on an XML element name or the instance type. Here a collection of * element list annotations can be declared. Each annotation expresses * the types the list can accept. Taking the declaration below, if the * annotation is inline, the list can take a number of varying types * all determined from the XML element name. *

 * 
 *    @ElementListUnion({
 *       @ElementList(entry="x", inline=true, type=X.class),
 *       @ElementList(entry="y", inline=true, type=Y.class),
 *       @ElementList(entry="z", inline=true, type=Z.class)               
 *    })
 *    private List<Code> codes;
 *    
 * 
* For the above definition the list field can take any of the declared * types. On deserialization the name of the element will determine the * type that is instantiated and inserted in to the list. When the list * is serialized the list entry instance type will determine the name * of the element the instance will serialized as. This provides a * useful means of consume more complicated sources. * * @author Niall Gallagher * * @see org.simpleframework.xml.ElementList */ @Retention(RetentionPolicy.RUNTIME) public @interface ElementListUnion { /** * This provides the ElementList annotations that have * been defined for this union. Each element list describes the * XML class schema to use and the name of the XML element. This * allows the serialization process to determine which elements * map to the defined types. Also, the types define how the XML * is generated for a given instance. * * @return the element lists defined for the union declaration */ ElementList[] value(); } simple-xml-2.7.1/src/org/simpleframework/xml/core/0000755000175000017500000000000012271465260021410 5ustar bengenbengensimple-xml-2.7.1/src/org/simpleframework/xml/core/CompositeInlineMap.java0000644000175000017500000002206012166517661026020 0ustar bengenbengen/* * CompositeInlineMap.java July 2007 * * Copyright (C) 2007, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.core; import java.util.Map; import org.simpleframework.xml.strategy.Type; import org.simpleframework.xml.stream.InputNode; import org.simpleframework.xml.stream.Mode; import org.simpleframework.xml.stream.OutputNode; import org.simpleframework.xml.stream.Style; /** * The CompositeMap is used to serialize and deserialize * maps to and from a source XML document. The structure of the map in * the XML format is determined by the annotation. Keys can be either * attributes or elements, and values can be inline. This can perform * serialization and deserialization of the key and value objects * whether the object types are primitive or composite. *
 * 
 *    <map>
 *       <entry key='1'>           
 *          <value>one</value>
 *       </entry>
 *       <entry key='2'>
 *          <value>two</value>
 *       </entry>      
 *    </map>
 *    
 * 
* For the above XML element map the element entry is * used to wrap the key and value such that they can be grouped. This * element does not represent any real object. The names of each of * the XML elements serialized and deserialized can be configured. * * @author Niall Gallagher * * @see org.simpleframework.xml.core.Entry */ class CompositeInlineMap implements Repeater { /** * The factory used to create suitable map object instances. */ private final MapFactory factory; /** * This is the type that the value objects are instances of. */ private final Converter value; /** * This is the name of the entry wrapping the key and value. */ private final Converter key; /** * This is the style used to style the names used for the XML. */ private final Style style; /** * The entry object contains the details on how to write the map. */ private final Entry entry; /** * Constructor for the CompositeMap object. This will * create a converter that is capable of writing map objects to * and from XML. The resulting XML is configured by an annotation * such that key values can attributes and values can be inline. * * @param context this is the root context for the serialization * @param entry this provides configuration for the resulting XML * @param type this is the map type that is to be converted */ public CompositeInlineMap(Context context, Entry entry, Type type) throws Exception { this.factory = new MapFactory(context, type); this.value = entry.getValue(context); this.key = entry.getKey(context); this.style = context.getStyle(); this.entry = entry; } /** * This read method will read the XML element map from * the provided node and deserialize its children as entry types. * Each entry type must contain a key and value so that the entry * can be inserted in to the map as a pair. If either the key or * value is composite it is read as a root object, which means its * Root annotation must be present and the name of the * object element must match that root element name. * * @param node this is the XML element that is to be deserialized * * @return this returns the item to attach to the object contact */ public Object read(InputNode node) throws Exception{ Object value = factory.getInstance(); Map table = (Map) value; if(table != null) { return read(node, table); } return null; } /** * This read method will read the XML element map from * the provided node and deserialize its children as entry types. * Each entry type must contain a key and value so that the entry * can be inserted in to the map as a pair. If either the key or * value is composite it is read as a root object, which means its * Root annotation must be present and the name of the * object element must match that root element name. * * @param node this is the XML element that is to be deserialized * * @return this returns the item to attach to the object contact */ public Object read(InputNode node, Object value) throws Exception { Map map = (Map) value; if(map != null) { return read(node, map); } return read(node); } /** * This read method will read the XML element map from * the provided node and deserialize its children as entry types. * Each entry type must contain a key and value so that the entry * can be inserted in to the map as a pair. If either the key or * value is composite it is read as a root object, which means its * Root annotation must be present and the name of the * object element must match that root element name. * * @param node this is the XML element that is to be deserialized * @param map this is the map object that is to be populated * * @return this returns the item to attach to the object contact */ private Object read(InputNode node, Map map) throws Exception { InputNode from = node.getParent(); String name = node.getName(); while(node != null) { Object index = key.read(node); Object item = value.read(node); if(map != null) { map.put(index, item); } node = from.getNext(name); } return map; } /** * This read method will read the XML element map from * the provided node and deserialize its children as entry types. * Each entry type must contain a key and value so that the entry * can be inserted in to the map as a pair. If either the key or * value is composite it is read as a root object, which means its * Root annotation must be present and the name of the * object element must match that root element name. * * @param node this is the XML element that is to be deserialized * * @return this returns the item to attach to the object contact */ public boolean validate(InputNode node) throws Exception{ InputNode from = node.getParent(); String name = node.getName(); while(node != null) { if(!key.validate(node)) { return false; } if(!value.validate(node)) { return false; } node = from.getNext(name); } return true; } /** * This write method will write the key value pairs * within the provided map to the specified XML node. This will * write each entry type must contain a key and value so that * the entry can be deserialized in to the map as a pair. If the * key or value object is composite it is read as a root object * so its Root annotation must be present. * * @param node this is the node the map is to be written to * @param source this is the source map that is to be written */ public void write(OutputNode node, Object source) throws Exception { OutputNode parent = node.getParent(); Mode mode = node.getMode(); Map map = (Map) source; if(!node.isCommitted()) { node.remove(); } write(parent, map, mode); } /** * This write method will write the key value pairs * within the provided map to the specified XML node. This will * write each entry type must contain a key and value so that * the entry can be deserialized in to the map as a pair. If the * key or value object is composite it is read as a root object * so its Root annotation must be present. * * @param node this is the node the map is to be written to * @param map this is the source map that is to be written * @param mode this is the mode that has been inherited */ private void write(OutputNode node, Map map, Mode mode) throws Exception { String root = entry.getEntry(); String name = style.getElement(root); for(Object index : map.keySet()) { OutputNode next = node.getChild(name); Object item = map.get(index); next.setMode(mode); key.write(next, index); value.write(next, item); } } }simple-xml-2.7.1/src/org/simpleframework/xml/core/ModelAssembler.java0000644000175000017500000002116012166517661025157 0ustar bengenbengen/* * ModelAssembler.java November 2010 * * Copyright (C) 2010, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.core; import org.simpleframework.xml.Order; import org.simpleframework.xml.stream.Format; import org.simpleframework.xml.stream.Style; /** * The ModelAssembler is used to assemble the model * using registrations based on the specified order. The order of * elements and attributes is specified by an Order * annotation. For order, all attributes within an XPath expression * must be valid attribute references, for example *
 * 
 *    some[1]/path/@attribute
 *    path/to/@attribute
 *    attribute    
 * 
 * 
* The above expressions are all legal references. The final * reference specifies an attribute that is not within an XPath * expression. If the '@' character is missing from attribute * orderings an exception is thrown to indicate this. * * @author Niall Gallagher * * @see org.simpleframework.xml.Order */ class ModelAssembler { /** * This is used to parse the XPath expressions in the order */ private final ExpressionBuilder builder; /** * This is the format that is used to style the order values. */ private final Format format; /** * This is the type this this is assembling the model for. */ private final Detail detail; /** * Constructor for the ModelAssembler object. If * no order has been specified for the schema class then this * will perform no registrations on the specified model. * * @param builder this is the builder for XPath expressions * @param detail this contains the details for the assembler * @param support this contains various support functions */ public ModelAssembler(ExpressionBuilder builder, Detail detail, Support support) throws Exception { this.format = support.getFormat(); this.builder = builder; this.detail = detail; } /** * This is used to assemble the model by perform registrations * based on the Order annotation. The initial * registrations performed by this establish the element and * attribute order for serialization of the schema class. * * @param model the model to perform registrations on * @param order this is the order specified by the class */ public void assemble(Model model, Order order) throws Exception { assembleElements(model, order); assembleAttributes(model, order); } /** * This is used to assemble the model by perform registrations * based on the Order annotation. The initial * registrations performed by this establish the element and * attribute order for serialization of the schema class. * * @param model the model to perform registrations on * @param order this is the order specified by the class */ private void assembleElements(Model model, Order order) throws Exception { for(String value : order.elements()) { Expression path = builder.build(value); if(path.isAttribute()) { throw new PathException("Ordered element '%s' references an attribute in %s", path, detail); } registerElements(model, path); } } /** * This is used to assemble the model by perform registrations * based on the Order annotation. The initial * registrations performed by this establish the element and * attribute order for serialization of the schema class. * * @param model the model to perform registrations on * @param order this is the order specified by the class */ private void assembleAttributes(Model model, Order order) throws Exception { for(String value : order.attributes()) { Expression path = builder.build(value); if(!path.isAttribute() && path.isPath()) { throw new PathException("Ordered attribute '%s' references an element in %s", path, detail); } if(!path.isPath()) { Style style = format.getStyle(); String name = style.getAttribute(value); model.registerAttribute(name); } else { registerAttributes(model, path); } } } /** * This is used to perform registrations using an expression. * Each segment in the expression will create a new model and * the final segment of the expression is the attribute. * * @param model the model to register the attribute with * @param path this is the expression to be evaluated */ private void registerAttributes(Model model, Expression path) throws Exception { String prefix = path.getPrefix(); String name = path.getFirst(); int index = path.getIndex(); if(path.isPath()) { Model next = model.register(name, prefix, index); Expression child = path.getPath(1); if(next == null) { throw new PathException("Element '%s' does not exist in %s", name, detail); } registerAttributes(next, child); } else { registerAttribute(model, path); } } /** * This will register the attribute specified in the path within * the provided model. Registration here will ensure that the * attribute is ordered so that it is placed within the document * in a required position. * * @param model this is the model to register the attribute in * @param path this is the path referencing the attribute */ private void registerAttribute(Model model, Expression path) throws Exception { String name = path.getFirst(); if(name != null) { model.registerAttribute(name); } } /** * This is used to perform registrations using an expression. * Each segment in the expression will create a new model and * the final segment of the expression is the element. * * @param model the model to register the element with * @param path this is the expression to be evaluated */ private void registerElements(Model model, Expression path) throws Exception { String prefix = path.getPrefix(); String name = path.getFirst(); int index = path.getIndex(); if(name != null) { Model next = model.register(name, prefix, index); Expression child = path.getPath(1); if(path.isPath()) { registerElements(next, child); } } registerElement(model, path); } /** * This is used to register the element within the specified * model. To ensure the order does not conflict with expressions * the index of the ordered path is checked. If the order comes * before an expected order then an exception is thrown. * For example, take the following expressions. *
    *    
    *    path[1]/element
    *    path[3]/element
    *    path[2]/element
    *    
    * 
* In the above the order of appearance of the expressions does * not match the indexes of the paths. This causes a conflict. * To ensure such a situation does not arise this is checked. * * @param model this is the model to register the element in * @param path this is the expression referencing the element */ private void registerElement(Model model, Expression path) throws Exception { String prefix = path.getPrefix(); String name = path.getFirst(); int index = path.getIndex(); if(index > 1) { Model previous = model.lookup(name, index -1); if(previous == null) { throw new PathException("Ordered element '%s' in path '%s' is out of sequence for %s", name, path, detail); } } model.register(name, prefix, index); } } simple-xml-2.7.1/src/org/simpleframework/xml/core/Instantiator.java0000644000175000017500000000664012166517661024746 0ustar bengenbengen/* * Instantiator.java December 2009 * * Copyright (C) 2009, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.core; import java.util.List; /** * The Instantiator object is used for instantiating * objects using either the default no argument constructor or one * that takes deserialized values as parameters. This also exposes * the parameters and constructors used to instantiate the object. * * @author Niall Gallagher */ interface Instantiator { /** * This is used to determine if this Instantiator has * a default constructor. If the only constructor this contains * is a default no argument constructor this returns true. * * @return true if the class only has a default constructor */ boolean isDefault(); /** * This is used to instantiate the object using the default no * argument constructor. If for some reason the object can not be * instantiated then this will throw an exception with the reason. * * @return this returns the object that has been instantiated */ Object getInstance() throws Exception; /** * This is used to instantiate the object using a constructor that * takes deserialized objects as arguments. The object that have * been deserialized can be taken from the Criteria * object which contains the deserialized values. * * @param criteria this contains the criteria to be used * * @return this returns the object that has been instantiated */ Object getInstance(Criteria criteria) throws Exception; /** * This is used to acquire the named Parameter from * the creator. A parameter is taken from the constructor which * contains annotations for each object that is required. These * parameters must have a matching field or method. * * @param name this is the name of the parameter to be acquired * * @return this returns the named parameter for the creator */ Parameter getParameter(String name); /** * This is used to acquire all parameters annotated for the class * schema. Providing all parameters ensures that they can be * validated against the annotated methods and fields to ensure * that each parameter is valid and has a corresponding match. * * @return this returns the parameters declared in the schema */ List getParameters(); /** * This is used to acquire the Creator objects * used to create an instance of the object. Each represents a * constructor and contains the parameters to the constructor. * This is primarily used to validate each constructor against the * fields and methods annotated to ensure they are compatible. * * @return this returns a list of creators for the type */ List getCreators(); }simple-xml-2.7.1/src/org/simpleframework/xml/core/ModelSection.java0000644000175000017500000002202612166517661024650 0ustar bengenbengen/* * ModelSection.java November 2010 * * Copyright (C) 2010, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.core; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * The ModelSection represents a section that is backed * by a Model instance. This is used to expose the XML * structure of a schema class. In addition to wrapping the model * this will also apply a Style to the names of the * attributes and elements of the class schema. * * @author Niall Gallagher */ class ModelSection implements Section { /** * Represents a mapping between styled names and attributes. */ private LabelMap attributes; /** * Represents a mapping between styled names and elements. */ private LabelMap elements; /** * Represents a mapping between styled names and models. */ private ModelMap models; /** * This is the model that contains the elements and attributes. */ private Model model; /** * Constructor for the ModelSection object. This is * used to wrap a Model in such a way that it can * not be modified. This allows it to be used concurrently. * * @param model this is the model this section will wrap */ public ModelSection(Model model) { this.model = model; } /** * This is used to return the name of the section. The name is * must be a valid XML element name. It is used when a style * is applied to a path as the section name must be styled. * * @return this returns the name of this section instance */ public String getName() { return model.getName(); } /** * This is used to acquire the path prefix for the section. The * path prefix is used when the section is transformed in to an * XML structure. This ensures that the XML element created to * represent the section contains the optional prefix. * * @return this returns the prefix for this section */ public String getPrefix() { return model.getPrefix(); } /** * This is used to acquire the full element path for this * section. The element path is simply the fully qualified * path for this expression with the provided name appended. * If this is an empty path, the provided name is returned. * * @param name this is the name of the element to be used * * @return a fully qualified path for the specified name */ public String getPath(String name) throws Exception { Expression path = model.getExpression(); if(path == null) { return name; } return path.getElement(name); } /** * This is used to acquire the full attribute path for this * section. The attribute path is simply the fully qualified * path for this expression with the provided name appended. * If this is an empty path, the provided name is returned. * * @param name this is the name of the attribute to be used * * @return a fully qualified path for the specified name */ public String getAttribute(String name) throws Exception { Expression path = model.getExpression(); if(path == null) { return name; } return path.getAttribute(name); } /** * This will return the names of all elements contained within * the model. This includes the names of all XML elements that * have been registered as well as any other models that have * been added. Iteration is done in an ordered manner, according * to the registration of elements and models. * * @return an ordered and styled list of elements and models */ public Iterator iterator() { List list = new ArrayList(); for(String element : model) { list.add(element); } return list.iterator(); } /** * To differentiate between a section and an element this can be * used. When iterating over the elements within the section the * names of both elements and sections are provided. So in order * to determine how to interpret the structure this can be used. * * @param name this is the name of the element to be determined * * @return this returns true if the name represents a section */ public boolean isSection(String name) throws Exception { return getModels().get(name) != null; } /** * Returns a LabelMap that contains the details for * all fields and methods marked with XML annotations. All of the * attribute annotations are considered and gathered by name in * this map. Also, if there is an associated Style * for serialization the attribute names are renamed with this. * * @return returns the attributes associated with this section */ public ModelMap getModels() throws Exception { if(models == null) { models = model.getModels(); } return models; } /** * This is used to acquire the text label for this section if * one has been specified. A text label can only exist in a * section if there are no elements associated with the section * and the section is not composite, as in it does not contain * any further sections. * * @return this returns the text label for this section */ public Label getText() throws Exception { return model.getText(); } /** * Returns a LabelMap that contains the details for * all fields and methods marked with XML annotations. All of the * attribute annotations are considered and gathered by name in * this map. Also, if there is an associated Style * for serialization the attribute names are renamed with this. * * @return returns the attributes associated with this section */ public LabelMap getAttributes() throws Exception { if(attributes == null) { attributes = model.getAttributes(); } return attributes; } /** * Returns a LabelMap that contains the details for * all fields and methods marked with XML annotations. All of the * element annotations are considered and gathered by name in * this map. Also, if there is an associated Style * for serialization the element names are renamed with this. * * @return returns the elements associated with this section */ public LabelMap getElements() throws Exception { if(elements == null) { elements = model.getElements(); } return elements; } /** * Returns the named element as a Label object. * For convenience this method is provided so that when iterating * over the names of the elements in the section a specific one * of interest can be acquired. *

* To ensure that elements of the same name are not referenced * more than once this will remove the element once acquired. * This ensures that they are visited only once in serialization. * * @param name the name of the element that is to be acquired * * @return this returns the label associated with the name */ public Label getElement(String name) throws Exception { return getElements().getLabel(name); } /** * Returns the named section as a Section object. * For convenience this method is provided so that when iterating * over the names of the elements in the section a specific one * of interest can be acquired. *

* To ensure that models of the same name are not referenced * more than once this will remove the model once acquired. * This ensures that they are visited only once in serialization. * * @param name the name of the element that is to be acquired * * @return this returns the section associated with the name */ public Section getSection(String name) throws Exception { ModelMap map = getModels(); ModelList list = map.get(name); if(list != null) { Model model = list.take(); if(model != null){ return new ModelSection(model); } } return null; } } simple-xml-2.7.1/src/org/simpleframework/xml/core/PrimitiveArray.java0000644000175000017500000002166712166517661025244 0ustar bengenbengen/* * PrimitiveArray.java July 2006 * * Copyright (C) 2006, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.core; import java.lang.reflect.Array; import org.simpleframework.xml.strategy.Type; import org.simpleframework.xml.stream.InputNode; import org.simpleframework.xml.stream.OutputNode; import org.simpleframework.xml.stream.Position; /** * The PrimitiveArray object is used to convert a list of * elements to an array of object entries. This in effect performs a * serialization and deserialization of primitive elements for the * array object. On serialization each primitive type must be checked * against the array component type so that it is serialized in a form * that can be deserialized dynamically. *

 *
 *    <array>
 *       <entry>example text one</entry>
 *       <entry>example text two</entry>
 *       <entry>example text three</entry>
 *    </array>
 * 
 * 
* For the above XML element list the element entry is * contained within the array. Each entry element is deserialized as * a from a parent XML element, which is specified in the annotation. * For serialization the reverse is done, each element taken from the * array is written into an element created from the parent element. * * @author Niall Gallagher * * @see org.simpleframework.xml.core.Primitive * @see org.simpleframework.xml.ElementArray */ class PrimitiveArray implements Converter { /** * This factory is used to create an array for the contact. */ private final ArrayFactory factory; /** * This performs the serialization of the primitive element. */ private final Primitive root; /** * This is the name that each array element is wrapped with. */ private final String parent; /** * This is the type of object that will be held in the list. */ private final Type entry; /** * This represents the actual field or method for the array. */ private final Type type; /** * Constructor for the PrimitiveArray object. This is * given the array type for the contact that is to be converted. An * array of the specified type is used to hold the deserialized * elements and will be the same length as the number of elements. * * @param context this is the context object used for serialization * @param type this is the actual field type from the schema * @param entry the entry type to be stored within the array * @param parent this is the name to wrap the array element with */ public PrimitiveArray(Context context, Type type, Type entry, String parent) { this.factory = new ArrayFactory(context, type); this.root = new Primitive(context, entry); this.parent = parent; this.entry = entry; this.type = type; } /** * This read method will read the XML element list from * the provided node and deserialize its children as entry types. * This will deserialize each entry type as a primitive value. In * order to do this the parent string provided forms the element. * * @param node this is the XML element that is to be deserialized * * @return this returns the item to attach to the object contact */ public Object read(InputNode node) throws Exception{ Instance type = factory.getInstance(node); Object list = type.getInstance(); if(!type.isReference()) { return read(node, list); } return list; } /** * This read method will read the XML element list from * the provided node and deserialize its children as entry types. * This will deserialize each entry type as a primitive value. In * order to do this the parent string provided forms the element. * * @param node this is the XML element that is to be deserialized * @param list this is the array to read the array values in to * * @return this returns the item to attach to the object contact */ public Object read(InputNode node, Object list) throws Exception{ int length = Array.getLength(list); for(int pos = 0; true; pos++) { Position line = node.getPosition(); InputNode next = node.getNext(); if(next == null) { return list; } if(pos >= length){ throw new ElementException("Array length missing or incorrect for %s at %s", type, line); } Array.set(list, pos, root.read(next)); } } /** * This validate method will validate the XML element list * from the provided node and validate its children as entry types. * This will validate each entry type as a primitive value. In order * to do this the parent string provided forms the element. * * @param node this is the XML element that is to be validated * * @return true if the element matches the XML schema class given */ public boolean validate(InputNode node) throws Exception{ Instance value = factory.getInstance(node); if(!value.isReference()) { Object result = value.setInstance(null); Class expect = value.getType(); return validate(node, expect); } return true; } /** * This validate method will validate the XML element list * from the provided node and validate its children as entry types. * This will validate each entry type as a primitive value. In order * to do this the parent string provided forms the element. * * @param node this is the XML element that is to be validated * @param type this is the array type used to create the array * * @return true if the element matches the XML schema class given */ private boolean validate(InputNode node, Class type) throws Exception{ while(true) { InputNode next = node.getNext(); if(next == null) { return true; } root.validate(next); } } /** * This write method will write the specified object * to the given XML element as as array entries. Each entry within * the given array must be assignable to the array component type. * This will deserialize each entry type as a primitive value. In * order to do this the parent string provided forms the element. * * @param source this is the source object array to be serialized * @param node this is the XML element container to be populated */ public void write(OutputNode node, Object source) throws Exception { int size = Array.getLength(source); for(int i = 0; i < size; i++) { OutputNode child = node.getChild(parent); if(child == null) { break; } write(child, source, i); } } /** * This write method will write the specified object * to the given XML element as as array entries. Each entry within * the given array must be assignable to the array component type. * This will deserialize each entry type as a primitive value. In * order to do this the parent string provided forms the element. * * @param source this is the source object array to be serialized * @param node this is the XML element container to be populated * @param index this is the position in the array to set the item */ private void write(OutputNode node, Object source, int index) throws Exception { Object item = Array.get(source, index); if(item != null) { if(!isOverridden(node, item)) { root.write(node, item); } } } /** * This is used to determine whether the specified value has been * overridden by the strategy. If the item has been overridden * then no more serialization is require for that value, this is * effectively telling the serialization process to stop writing. * * @param node the node that a potential override is written to * @param value this is the object instance to be serialized * * @return returns true if the strategy overrides the object */ private boolean isOverridden(OutputNode node, Object value) throws Exception{ return factory.setOverride(entry, value, node); } } simple-xml-2.7.1/src/org/simpleframework/xml/core/AttributeParameter.java0000644000175000017500000002042112166517661026064 0ustar bengenbengen/* * AttributeParameter.java July 2009 * * Copyright (C) 2009, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.core; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import org.simpleframework.xml.Attribute; import org.simpleframework.xml.stream.Format; /** * The AttributeParameter represents a constructor * parameter. It contains the XML annotation used on the parameter * as well as the name of the parameter and its position index. * A parameter is used to validate against the annotated methods * and fields and also to determine the deserialized values that * should be injected in to the constructor to instantiate it. * * @author Niall Gallagher */ class AttributeParameter extends TemplateParameter { /** * This is the expression used to represent this parameter. */ private final Expression expression; /** * This is the contact used to determine the parameter name. */ private final Contact contact; /** * This is the label that will create the parameter name. */ private final Label label; /** * This is the fully qualified path used for this parameter. */ private final String path; /** * This is the actual name that has been determined. */ private final String name; /** * This is the type of the label represented by this. */ private final Class type; /** * This is the key used to represent this parameter object. */ private final Object key; /** * This is the index that the parameter was declared at. */ private final int index; /** * Constructor for the AttributeParameter object. * This is used to create a parameter that can be used to * determine a consistent name using the provided XML annotation. * * @param factory this is the constructor the parameter is in * @param value this is the annotation used for the parameter * @param index this is the index the parameter appears at * @param format this is the format used to style the paths */ public AttributeParameter(Constructor factory, Attribute value, Format format, int index) throws Exception { this.contact = new Contact(value, factory, index); this.label = new AttributeLabel(contact, value, format); this.expression = label.getExpression(); this.path = label.getPath(); this.type = label.getType(); this.name = label.getName(); this.key = label.getKey(); this.index = index; } /** * This is the key used to represent the parameter. The key is * used to store the parameter in hash containers. Unlike the * path is not necessarily the path for the parameter. * * @return this is the key used to represent the parameter */ public Object getKey() { return key; } /** * This is used to acquire the path of the element or attribute * represented by this parameter. The path is determined by * acquiring the XPath expression and appending the name of the * label to form a fully qualified path. * * @return returns the path that is used for this parameter */ public String getPath() { return path; } /** * This is used to acquire the name of the parameter that this * represents. The name is determined using annotation and * the name attribute of that annotation, if one is provided. * * @return this returns the name of the annotated parameter */ public String getName() { return name; } /** * This method is used to return an XPath expression that is * used to represent the position of this parameter. If there is * no XPath expression associated with this then an empty path * is returned. This will never return a null expression. * * @return the XPath expression identifying the location */ public Expression getExpression() { return expression; } /** * This is used to acquire the annotated type class. The class * is the type that is to be deserialized from the XML. This * is used to validate against annotated fields and methods. * * @return this returns the type used for the parameter */ public Class getType() { return type; } /** * This is used to acquire the annotation that is used for the * parameter. The annotation provided will be an XML annotation * such as the Element or Attribute * annotation. * * @return this returns the annotation used on the parameter */ public Annotation getAnnotation() { return contact.getAnnotation(); } /** * This returns the index position of the parameter in the * constructor. This is used to determine the order of values * that are to be injected in to the constructor. * * @return this returns the index for the parameter */ public int getIndex() { return index; } /** * This is used to determine if the parameter is required. If * an attribute is not required then it can be null. Which * means that we can inject a null value. Also, this means we * can match constructors in a more flexible manner. * * @return this returns true if the parameter is required */ public boolean isRequired() { return label.isRequired(); } /** * This is used to determine if the parameter is primitive. A * primitive parameter must not be null. As there is no way to * provide the value to the constructor. A default value is * not a good solution as it affects the constructor score. * * @return this returns true if the parameter is primitive */ public boolean isPrimitive() { return type.isPrimitive(); } /** * This method is used to determine if the parameter represents * an attribute. This is used to style the name so that elements * are styled as elements and attributes are styled as required. * * @return this is used to determine if this is an attribute */ public boolean isAttribute() { return true; } /** * This is used to provide a textual representation of the * parameter. Providing a string describing the parameter is * useful for debugging and for exception messages. * * @return this returns the string representation for this */ public String toString() { return contact.toString(); } /** * The Contact represents a contact object that is * to be used for a label in order to extract a parameter name. * The parameter name is taken from the XML annotation. * * @author Niall Gallagher */ private static class Contact extends ParameterContact { /** * Constructor for the Contact object. This is * used to create an object that acts like an adapter so that * the label can create a consistent name for the parameter. * * @param label this is the annotation for the parameter * @param factory this is the constructor the parameter is in * @param index this is the index for the parameter */ public Contact(Attribute label, Constructor factory, int index) { super(label, factory, index); } /** * This returns the name of the parameter as taken from the XML * annotation. The name provided here is taken by the label * and used to compose a name consistent with how fields and * methods are named by the system. * * @return this returns the name of the annotated parameter */ public String getName() { return label.name(); } } }simple-xml-2.7.1/src/org/simpleframework/xml/core/InstantiationException.java0000644000175000017500000000436112166517661026770 0ustar bengenbengen/* * InstantiationException.java July 2006 * * Copyright (C) 2006, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.core; /** * The InstantiationException is thrown when an object * cannot be instantiated either because it is an abstract class or an * interface. Such a situation can arise if a serializable field is an * abstract type and a suitable concrete class cannot be found. Also, * if an override type is not assignable to the field type this is * thrown, for example if an XML element list is not a collection. * * @author Niall Gallagher */ public class InstantiationException extends PersistenceException { /** * Constructor for the InstantiationException object. * This constructor takes a format string an a variable number of * object arguments, which can be inserted into the format string. * * @param text a format string used to present the error message * @param list a list of arguments to insert into the string */ public InstantiationException(String text, Object... list) { super(text, list); } /** * Constructor for the InstantiationException object. * This constructor takes a format string an a variable number of * object arguments, which can be inserted into the format string. * * @param cause the source exception this is used to represent * @param text a format string used to present the error message * @param list a list of arguments to insert into the string */ public InstantiationException(Throwable cause, String text, Object... list) { super(cause, text, list); } } simple-xml-2.7.1/src/org/simpleframework/xml/core/DefaultDetail.java0000644000175000017500000002234012166517661024771 0ustar bengenbengen/* * DefaultDetail.java December 2012 * * Copyright (C) 2012, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.core; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.util.List; import org.simpleframework.xml.DefaultType; import org.simpleframework.xml.Namespace; import org.simpleframework.xml.NamespaceList; import org.simpleframework.xml.Order; import org.simpleframework.xml.Root; /** * This DefaultDetail object is used to create a detail * object that contains a default access override. Default overrides * can be used to scan a class with no annotations and treat it as if * it was annotated with the Default annotation. This * allows external classes to be serialized without modification. * * @author Niall Gallagher */ class DefaultDetail implements Detail { /** * This is the default access type to be used with this detail. */ private final DefaultType access; /** * This is the original detail object that is to be delegated to. */ private final Detail detail; /** * Constructor for the DefaultDetail object. This is * used to create a description of a class and also provide a * default access override type. This is used when we want to scan * a class with no annotations and extract default details. * * @param detail this is the detail that is delegated to * @param access this is the access type override used */ public DefaultDetail(Detail detail, DefaultType access) { this.detail = detail; this.access = access; } /** * This method is used to determine whether strict mappings are * required. Strict mapping means that all labels in the class * schema must match the XML elements and attributes in the * source XML document. When strict mapping is disabled, then * XML elements and attributes that do not exist in the schema * class will be ignored without breaking the parser. * * @return true if strict parsing is enabled, false otherwise */ public boolean isStrict() { return detail.isStrict(); } /** * This is used to determine if the generated annotations are * required or not. By default generated parameters are required. * Setting this to false means that null values are accepted * by all defaulted fields or methods depending on the type. * * @return this is used to determine if defaults are required */ public boolean isRequired() { return detail.isRequired(); } /** * This is used to determine if the class is an inner class. If * the class is a inner class and not static then this returns * false. Only static inner classes can be instantiated using * reflection as they do not require a "this" argument. * * @return this returns true if the class is a static inner */ public boolean isInstantiable() { return detail.isInstantiable(); } /** * This is used to determine whether this detail represents a * primitive type. A primitive type is any type that does not * extend Object, examples are int, long and double. * * @return this returns true if no XML annotations were found */ public boolean isPrimitive() { return detail.isPrimitive(); } /** * This is used to acquire the super type for the class that is * represented by this detail. If the super type for the class * is Object then this will return null. * * @return returns the super type for this class or null */ public Class getSuper() { return detail.getSuper(); } /** * This returns the type represented by this detail. The type is * the class that has been scanned for annotations, methods and * fields. All super types of this are represented in the detail. * * @return the type that this detail object represents */ public Class getType() { return detail.getType(); } /** * This returns the name of the class represented by this detail. * The name is either the name as specified in the last found * Root annotation, or if a name was not specified * within the discovered root then the Java Bean class name of * the last class annotated with a root annotation. * * @return this returns the name of the object being scanned */ public String getName() { return detail.getName(); } /** * This returns the Root annotation for the class. * The root determines the type of deserialization that is to * be performed and also contains the name of the root element. * * @return this returns the name of the object being scanned */ public Root getRoot() { return detail.getRoot(); } /** * This returns the order annotation used to determine the order * of serialization of attributes and elements. The order is a * class level annotation that can be used only once per class * XML schema. If none exists then this will return null. * of the class processed by this scanner. * * @return this returns the name of the object being scanned */ public Order getOrder() { return detail.getOrder(); } /** * This returns the Default annotation access type * that has been specified by this. If no default annotation has * been declared on the type then this will return null. * * @return this returns the default access type for this type */ public DefaultType getAccess() { return detail.getAccess(); } /** * This returns the Default annotation access type * that has been specified by this. If no default annotation has * been declared on the type then this will return null. * * @return this returns the default access type for this type */ public DefaultType getOverride() { return access; } /** * This returns the Namespace annotation that was * declared on the type. If no annotation has been declared on the * type this will return null as not belonging to any. * * @return this returns the namespace this type belongs to, if any */ public Namespace getNamespace() { return detail.getNamespace(); } /** * This returns the NamespaceList annotation that was * declared on the type. A list of namespaces are used to simply * declare the namespaces without specifically making the type * belong to any of the declared namespaces. * * @return this returns the namespace declarations, if any */ public NamespaceList getNamespaceList() { return detail.getNamespaceList(); } /** * This returns a list of the methods that belong to this type. * The methods here do not include any methods from the super * types and simply provides a means of caching method data. * * @return returns the list of methods declared for the type */ public List getMethods() { return detail.getMethods(); } /** * This returns a list of the fields that belong to this type. * The fields here do not include any fields from the super * types and simply provides a means of caching method data. * * @return returns the list of fields declared for the type */ public List getFields() { return detail.getFields(); } /** * This returns the annotations that have been declared for this * type. It is preferable to acquire the declared annotations * from this method as they are cached. Older versions of some * runtime environments, particularly Android, are slow at this. * * @return this returns the annotations associated with this */ public Annotation[] getAnnotations() { return detail.getAnnotations(); } /** * This returns the constructors that have been declared for this * type. It is preferable to acquire the declared constructors * from this method as they are cached. Older versions of some * runtime environments, particularly Android, are slow at this. * * @return this returns the constructors associated with this */ public Constructor[] getConstructors() { return detail.getConstructors(); } /** * This is used to return a string representation of the detail. * The string returned from this is the same that is returned * from the toString of the type represented. * * @return this returns the string representation of the type */ public String toString() { return detail.toString(); } } simple-xml-2.7.1/src/org/simpleframework/xml/core/Caller.java0000644000175000017500000001523112166517661023465 0ustar bengenbengen/* * Caller.java June 2007 * * Copyright (C) 2007, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.core; /** * The Caller acts as a means for the schema to invoke * the callback methods on an object. This ensures that the correct * method is invoked within the schema class. If the annotated method * accepts a map then this will provide that map to the method. This * also ensures that if specific annotation is not present in the * class that no action is taken on a persister callback. * * @author Niall Gallagher */ class Caller { /** * This is the pointer to the schema class commit function. */ private final Function commit; /** * This is the pointer to the schema class validation function. */ private final Function validate; /** * This is the pointer to the schema class persist function. */ private final Function persist; /** * This is the pointer to the schema class complete function. */ private final Function complete; /** * This is the pointer to the schema class replace function. */ private final Function replace; /** * This is the pointer to the schema class resolve function. */ private final Function resolve; /** * This is the context that is used to invoke the functions. */ private final Context context; /** * Constructor for the Caller object. This is used * to wrap the schema class such that callbacks from the persister * can be dealt with in a seamless manner. This ensures that the * correct function and arguments are provided to the functions. * element and attribute XML annotations scanned from * * @param schema this is the scanner that contains the functions * @param context this is the context used to acquire the session */ public Caller(Scanner schema, Context context) { this.validate = schema.getValidate(); this.complete = schema.getComplete(); this.replace = schema.getReplace(); this.resolve = schema.getResolve(); this.persist = schema.getPersist(); this.commit = schema.getCommit(); this.context = context; } /** * This is used to replace the deserialized object with another * instance, perhaps of a different type. This is useful when an * XML schema class acts as a reference to another XML document * which needs to be loaded externally to create an object of * a different type. * * @param source the source object to invoke the function on * * @return this returns the object that acts as the replacement * * @throws Exception if the replacement function cannot complete */ public Object replace(Object source) throws Exception { if(replace != null) { return replace.call(context, source); } return source; } /** * This is used to replace the deserialized object with another * instance, perhaps of a different type. This is useful when an * XML schema class acts as a reference to another XML document * which needs to be loaded externally to create an object of * a different type. * * @param source the source object to invoke the function on * * @return this returns the object that acts as the replacement * * @throws Exception if the replacement function cannot complete */ public Object resolve(Object source) throws Exception { if(resolve != null) { return resolve.call(context, source); } return source; } /** * This method is used to invoke the provided objects commit function * during the deserialization process. The commit function must be * marked with the Commit annotation so that when the * object is deserialized the persister has a chance to invoke the * function so that the object can build further data structures. * * @param source this is the object that has just been deserialized * * @throws Exception thrown if the commit process cannot complete */ public void commit(Object source) throws Exception { if(commit != null) { commit.call(context, source); } } /** * This method is used to invoke the provided objects validation * function during the deserialization process. The validation function * must be marked with the Validate annotation so that * when the object is deserialized the persister has a chance to * invoke that function so that object can validate its field values. * * @param source this is the object that has just been deserialized * * @throws Exception thrown if the validation process failed */ public void validate(Object source) throws Exception { if(validate != null) { validate.call(context, source); } } /** * This method is used to invoke the provided objects persistence * function. This is invoked during the serialization process to * get the object a chance to perform an necessary preparation * before the serialization of the object proceeds. The persist * function must be marked with the Persist annotation. * * @param source the object that is about to be serialized * * @throws Exception thrown if the object cannot be persisted */ public void persist(Object source) throws Exception { if(persist != null) { persist.call(context, source); } } /** * This method is used to invoke the provided objects completion * function. This is invoked after the serialization process has * completed and gives the object a chance to restore its state * if the persist function required some alteration or locking. * This is marked with the Complete annotation. * * @param source this is the object that has been serialized * * @throws Exception thrown if the object cannot complete */ public void complete(Object source) throws Exception { if(complete != null) { complete.call(context, source); } } } simple-xml-2.7.1/src/org/simpleframework/xml/core/LabelGroup.java0000644000175000017500000000526312166517661024323 0ustar bengenbengen/* * LabelGroup.java July 2006 * * Copyright (C) 2006, Niall Gallagher * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.xml.core; import java.util.Arrays; import java.util.List; /** * The LabelList contains a group of labels associated * with a specific contact. Here any number of annotations can be * associated with a single contact. This allows for element unions * that may contain more than one label to be represented. * * @author Niall Gallagher */ class LabelGroup { /** * This contains the list of labels associated with a contact. */ private final List