/** * This is used to read the <code>Value</code> 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<InputNode> 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 read the <code>Value</code> 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<InputNode> 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; }
/** * Creates the collection to use. The <code>Strategy</code> object * is consulted for the collection class, if one is not resolved * by the strategy implementation or if the collection resolved is * abstract then the Java Collections framework is consulted. * * @param node this is the input node representing the list * * @return this is the collection instantiated for the field */ public Instance getInstance(InputNode node) throws Exception { Value value = getOverride(node); Class expect = getType(); if(value != null) { return getInstance(value); } if(!isInstantiable(expect)) { expect = getConversion(expect); } if(!isCollection(expect)) { throw new InstantiationException("Invalid collection %s for %s", expect, type); } return context.getInstance(expect); }
/** * Creates the map object to use. The <code>Strategy</code> object * is consulted for the map object class, if one is not resolved * by the strategy implementation or if the collection resolved is * abstract then the Java Collections framework is consulted. * * @param node this is the input node representing the list * * @return this is the map object instantiated for the field */ public Instance getInstance(InputNode node) throws Exception { Value value = getOverride(node); Class expect = getType(); if(value != null) { return getInstance(value); } if(!isInstantiable(expect)) { expect = getConversion(expect); } if(!isMap(expect)) { throw new InstantiationException("Invalid map %s for %s", expect, type); } return context.getInstance(expect); }
/** * This is used to get a possible override from the provided node. * If the node provided is an element then this checks for a * specific class override using the <code>Strategy</code> object. * If the strategy cannot resolve a class then this will return * null. If the resolved <code>Value</code> is not assignable to * the field then this will thrown an exception. * * @param node this is the node used to search for the override * * @return this returns null if no override type can be found * * @throws Exception if the override type is not compatible */ protected Value getOverride(InputNode node) throws Exception { Value value = getConversion(node); if(value != null) { Position line = node.getPosition(); Class proposed = value.getType(); Class expect = getType(); if(!isCompatible(expect, proposed)) { throw new InstantiationException("Incompatible %s for %s at %s", proposed, type, line); } } return value; }
/** * This creates a <code>Collection</code> instance from the type * provided. If the type provided is abstract or an interface then * this can promote the type to a collection type that can be * instantiated. This is done by asking the type to convert itself. * * @param value the type used to instantiate the collection * * @return this returns a compatible collection instance */ public Instance getInstance(Value value) throws Exception { Class expect = value.getType(); if(!isInstantiable(expect)) { expect = getConversion(expect); } if(!isCollection(expect)) { throw new InstantiationException("Invalid collection %s for %s", expect, type); } return new ConversionInstance(context, value, expect); }
/** * This creates a <code>Map</code> object instance from the type * provided. If the type provided is abstract or an interface then * this can promote the type to a map object type that can be * instantiated. This is done by asking the type to convert itself. * * @param value the type used to instantiate the map object * * @return this returns a compatible map object instance */ public Instance getInstance(Value value) throws Exception { Class expect = value.getType(); if(!isInstantiable(expect)) { expect = getConversion(expect); } if(!isMap(expect)) { throw new InstantiationException("Invalid map %s for %s", expect, type); } return new ConversionInstance(context, value, expect); }
/** * This method will instantiate an object of the field type, or if * the <code>Strategy</code> object can resolve a class from the * XML element then this is used instead. If the resulting type is * abstract or an interface then this method throws an exception. * * @param node this is the node to check for the override * * @return this returns an instance of the resulting type */ @Override public Instance getInstance(InputNode node) throws Exception { Value value = getOverride(node); Class expect = getType(); if(value == null) { if(!isInstantiable(expect)) { throw new InstantiationException("Cannot instantiate %s for %s", expect, type); } return context.getInstance(expect); } return new ObjectInstance(context, value); }
public Value read(Type field, NodeMap<InputNode> node, Map map) throws Exception { Node entry = node.remove("type"); if(entry != null) { String value = entry.getValue(); Class type = backward.get(value); if(type == null) { throw new PersistenceException("Could not find class for alias %s", value); } node.put("class", type.getName()); } return strategy.read(field, node, map); }
public Value read(Type field, NodeMap node, Map map) throws Exception { Node value = node.remove(ELEMENT_NAME); if(value == null) { return null; } String name = value.getValue(); Class type = Class.forName(name); return new SimpleType(type); }
public Value read(Type field, NodeMap<InputNode> node, Map map) throws Exception { Value value = strategy.read(field, node, map); Class type = value == null ? field.getType() : value.getType(); Converter converter = registry.resolve(type); if(converter != null) { InputNode source = node.getNode(); Object data = converter.read(source); return new Wrapper(value, data); } return value; }
public Wrapper(Value value, Object data){ this.value = value; this.data = data; }
/** * This is used to read the <code>Value</code> 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<InputNode> 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 acquire a <code>Converter</code> 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 method will lookup and instantiate a converter found from * scanning the field or method type provided. If the type has * been overridden then the <code>Value</code> 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 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 read the <code>Value</code> 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<InputNode> node, Map map) throws Exception { Value value = strategy.read(type, node, map); if(isReference(value)) { return value; } return read(type, node, value); }
/** * This performs the conversion from the element node to a type. This * is where the <code>Strategy</code> object is consulted and asked * for a class that will represent the provided XML element. This will, * depending on the strategy implementation, make use of attributes * and/or elements to determine the type for the field. * * @param node this is the element used to extract the override * * @return this returns null if no override type can be found * * @throws Exception thrown if the override class cannot be loaded */ public Value getConversion(InputNode node) throws Exception { Value value = context.getOverride(type, node); if(value != null && override != null) { Class proposed = value.getType(); if(!isCompatible(override, proposed)) { return new OverrideValue(value, override); } } return value; }
/** * This method will instantiate an object of the field type, or if * the <code>Strategy</code> object can resolve a class from the * XML element then this is used instead. If the resulting type is * abstract or an interface then this method throws an exception. * * @param node this is the node to check for the override * * @return this returns an instance of the resulting type */ public Instance getInstance(InputNode node) throws Exception { Value value = getOverride(node); Class type = getType(); if(value == null) { return context.getInstance(type); } return new ObjectInstance(context, value); }
/** * This is used to resolve and load a class for the given element. * The class should be of the same type or a subclass of the class * specified. It can be resolved using the details within the * provided XML element, if the details used do not represent any * serializable values they should be removed so as not to disrupt * the deserialization process. For example the default strategy * removes all "class" attributes from the given elements. * * @param type this is the type of the root element expected * @param node this is the element used to resolve an override * * @return returns the type that should be used for the object * * @throws Exception thrown if the class cannot be resolved */ public Value getOverride(Type type, InputNode node) throws Exception { NodeMap<InputNode> map = node.getAttributes(); if(map == null) { throw new PersistenceException("No attributes for %s", node); } return strategy.read(type, map, session); }
/** * Creates the array type to use. This will use the provided * XML element to determine the array type and provide a means * for creating an array with the <code>Value</code> object. If * the array types are not compatible an exception is thrown. * * @param value this is the type object with the array details * @param entry this is the entry type for the array instance * * @return this object array type used for the instantiation */ private Instance getInstance(Value value, Class entry) throws Exception { Class expect = getComponentType(); if(!expect.isAssignableFrom(entry)) { throw new InstantiationException("Array of type %s cannot hold %s for %s", expect, entry, type); } return new ArrayInstance(value); }