/** * 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; }
/** * This <code>write</code> method is used to convert the provided * object to an XML element. This creates a child node from the * given <code>OutputNode</code> object. Once this child element * is created it is populated with the fields of the source object * in accordance with the XML schema class. * * @param source this is the object to be serialized to XML * @param expect this is the class that is expected to be written * @param name this is the name of the root annotation used * * @throws Exception thrown if there is a problem serializing */ public void write(OutputNode node, Object source, Class expect, String name) throws Exception { OutputNode child = node.getChild(name); Type type = getType(expect); if(source != null) { Class actual = source.getClass(); Decorator decorator = getDecorator(actual); if(decorator != null) { decorator.decorate(child); } if(!context.setOverride(type, source, child)) { getComposite(actual).write(child, source); } } child.commit(); }
public void testLargeList() throws Exception { Context context = getContext(); Group group = getGroup(); Type type = new ClassType(CompositeListUnionTest.class); List<Shape> list = new ArrayList<Shape>(); Expression expression = new PathParser("some/path", type, new Format()); CompositeListUnion union = new CompositeListUnion( context, group, expression, type); InputNode node = NodeBuilder.read(new StringReader(LARGE_SOURCE)); for(InputNode next = node.getNext(); next != null; next = node.getNext()) { union.read(next, list); } OutputNode output = NodeBuilder.write(new PrintWriter(System.err), new Format(3)); OutputNode parent = output.getChild("parent"); union.write(parent, list); }
/** * This write method is used to append the provided object as an * element to the given XML element object. This will recursively * write the contacts from the provided object as elements. This is * done using the <code>Converter</code> acquired from the contact * label. If the type of the contact value is not of the same * type as the XML schema class a "class" attribute is appended. * <p> * If the element being written is inline, then this will not * check to see if there is a "class" attribute specifying the * name of the class. This is because inline elements do not have * an outer class and thus could never have an override. * * @param value this is the value to be set as an element * @param node this is the XML element to write the element to * @param label the label that contains the contact details */ private void writeElement(OutputNode node, Object value, Label label) throws Exception { if(value != null) { Class real = value.getClass(); Label match = label.getLabel(real); String name = match.getName(); Type type = label.getType(real); OutputNode next = node.getChild(name); if(!match.isInline()) { writeNamespaces(next, type, match); } if(match.isInline() || !isOverridden(next, value, type)) { Converter convert = match.getConverter(context); boolean data = match.isData(); next.setData(data); writeElement(next, value, convert); } } }
@Override public void write(final Type type, final NodeMap<OutputNode> node) throws Exception { if (type.getType().equals(Command[].class)) { OutputNode element = node.getNode(); StringBuilder builder = new StringBuilder("A configuration must have 9 commands, one for each button.\n Possible icons are:"); for (Command.Icon icon : Command.Icon.values()) builder.append("\n - ").append(icon.toString()); element.setComment(builder.toString()); } }
@Override public void write(Type type, NodeMap<OutputNode> node) throws Exception { OutputNode outputNode = node.getNode(); if ("DdsRequestObject".equals(outputNode.getName())) { OutputNode operationNameAtribute = outputNode.getParent().getAttributes().get("DdsOperationName"); outputNode.setName(operationNameAtribute.getValue()); } }
/** * This is used to acquire the dependent type for the annotated * list. This will simply return the type that the map object is * composed to hold. This must be a serializable type, that is, * a type that is annotated with the <code>Root</code> class. * * @return this returns the component type for the map object */ public Type getDependent() throws Exception { Contact contact = getContact(); if(items == null) { items = contact.getDependents(); } if(items == null) { throw new ElementException("Unable to determine type for %s", contact); } if(items.length == 0) { return new ClassType(Object.class); } return new ClassType(items[0]); }
/** * This method is used to scan the provided <code>Type</code> for * an annotation. If the <code>Type</code> 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 get the entry name of a label using * the type of the label. This ensures that if there is no * entry XML element name declared by the annotation that a * suitable name can be calculated from the annotated type. * * @return this returns a suitable XML entry element name */ public String getEntry() throws Exception { Type depend = getDependent(); Class type = depend.getType(); if(type.isArray()) { type = type.getComponentType(); } return getName(type); }
/** * Constructor for the <code>PathParser</code> object. This must * be given a valid XPath expression. Currently only a subset of * the XPath syntax is supported by this parser. Once finished * the parser will contain all the extracted path segments. * * @param path this is the XPath expression to be parsed * @param type this is the type the expressions are parsed for * @param format this is the format used to style the path */ public PathParser(String path, Type type, Format format) throws Exception { this.attributes = new ConcurrentCache<String>(); this.elements = new ConcurrentCache<String>(); this.indexes = new ArrayList<Integer>(); this.prefixes = new ArrayList<String>(); this.names = new ArrayList<String>(); this.builder = new StringBuilder(); this.style = format.getStyle(); this.type = type; this.path = path; this.parse(path); }
/** * This is used to acquire the dependent type for the annotated * list. This will simply return the type that the collection is * composed to hold. This must be a serializable type, that is, * a type that is annotated with the <code>Root</code> class. * * @return this returns the component type for the collection */ public Type getDependent() throws Exception { Contact contact = getContact(); if(item == void.class) { item = contact.getDependent(); } if(item == null) { throw new ElementException("Unable to determine generic type for %s", contact); } return new ClassType(item); }
/** * Creates a converter that can be used to transform an XML node to * an object and vice versa. The converter created will handles * only XML elements and requires the context object to be provided. * * @param context this is the context object used for serialization * * @return this returns a converter for serializing XML elements */ public Converter getConverter(Context context) throws Exception { Type type = getContact(); if(context.isPrimitive(type)) { return new Primitive(context, type); } if(expect == void.class) { return new Composite(context, type); } return new Composite(context, type, expect); }
public void testEmptyPath() throws Exception { Format format = new Format(); Type type = new ClassType(EmptyExpressionTest.class); Expression path = new PathParser(".", type, format); Expression empty = new EmptyExpression(format); assertEquals(path.isEmpty(), empty.isEmpty()); assertEquals(path.isAttribute(), empty.isAttribute()); assertEquals(path.isPath(), empty.isPath()); assertEquals(path.getAttribute("a"), empty.getAttribute("a")); assertEquals(path.getElement("a"), empty.getElement("a")); assertEquals(path.getPath(), empty.getPath()); }
public void testEmptyPath() throws Exception { Type type = new ClassType(PathParserTest.class); Expression expression = new PathParser( ".", type, new Format()); String element = expression.getElement("a"); assertEquals(expression.getPath(), ""); assertEquals(element, "a"); String attribute = expression.getAttribute("a"); assertEquals(attribute, "a"); assertTrue(expression.isEmpty()); Expression single = new PathParser("name", type, new Format()); Expression empty = single.getPath(1); assertTrue(empty.isEmpty()); }
public void testStyledPathWithPrefixes() throws Exception { Type type = new ClassType(PathParserTest.class); Expression expression = new PathParser("pre:this/is/a/pre:path", type, new Format(new CamelCaseStyle())); String attributePath = expression.getAttribute("final"); assertEquals(attributePath, "pre:This[1]/Is[1]/A[1]/pre:Path[1]/@final"); String elementPath = expression.getElement("final"); assertEquals(elementPath, "pre:This[1]/Is[1]/A[1]/pre:Path[1]/Final[1]"); }
public void testStyledPath() throws Exception { Type type = new ClassType(PathParserTest.class); Expression expression = new PathParser( "this/is/a/path", type, new Format(new CamelCaseStyle())); String attributePath = expression.getAttribute("final"); assertEquals(attributePath, "This[1]/Is[1]/A[1]/Path[1]/@final"); String elementPath = expression.getElement("final"); assertEquals(elementPath, "This[1]/Is[1]/A[1]/Path[1]/Final[1]"); }
/** * This is used to acquire the dependent value for the annotated * map. This will simply return the type that the map object is * composed to hold. This must be a serializable type, that is, * it must be a composite or supported primitive type. * * @return this returns the value object type for the map object */ protected Type getValueType() throws Exception { if(valueType == null) { valueType = label.valueType(); if(valueType == void.class) { valueType = getDependent(1); } } return new ClassType(valueType); }
public boolean write(Type field, Object value, NodeMap<OutputNode> node, Map map) throws Exception { boolean reference = strategy.write(field, value, node, map); if(!reference) { Class type = value.getClass(); Converter converter = registry.resolve(type); OutputNode source = node.getNode(); if(converter != null) { converter.write(source, value); return true; } return false; } return reference; }
/** * This is used to acquire the dependent type for the annotated * array. This will simply return the type that the array is * composed to hold. This must be a serializable type, that is, * a type that is annotated with the <code>Root</code> class. * * @return this returns the component type for the array */ public Type getDependent() { Class entry = type.getComponentType(); if(entry == null) { return new ClassType(type); } return new ClassType(entry); }
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 void testSimpleList() throws Exception { Context context = getContext(); Group group = getGroup(); Type type = new ClassType(CompositeListUnionTest.class); List<Shape> list = new ArrayList<Shape>(); Expression expression = new PathParser("some/path", type, new Format()); CompositeListUnion union = new CompositeListUnion( context, group, expression, type); InputNode node = NodeBuilder.read(new StringReader(SOURCE)); InputNode circle = node.getNext(); union.read(circle, list); InputNode square = node.getNext(); union.read(square, list); InputNode triangle = node.getNext(); union.read(triangle, list); assertEquals(list.get(0).getClass(), Circle.class); assertEquals(list.get(1).getClass(), Square.class); assertEquals(list.get(2).getClass(), Triangle.class); OutputNode output = NodeBuilder.write(new PrintWriter(System.out), new Format(3)); OutputNode parent = output.getChild("parent"); union.write(parent, list); }
/** * This is used to acquire the <code>Type</code> that the type * provided is represented by. Typically this will return the * field or method represented by the label. However, in the * case of unions this will provide an override type. * * @param type this is the class to acquire the type for * * @return this returns the type represented by this class */ public Type getType(Class type) throws Exception { Type contact = getContact(); if(!extractor.isValid(type)) { throw new UnionException("No type matches %s in %s for %s", type, union, contact); } if(extractor.isDeclared(type)) { return new OverrideType(contact, type); } return contact; }
/** * Creates a converter that can be used to transform an XML node to * an object and vice versa. The converter created will handles * only XML text and requires the context object to be provided. * * @param context this is the context object used for serialization * * @return this returns a converter for serializing XML elements */ public Converter getConverter(Context context) throws Exception { String ignore = getEmpty(context); Type type = getContact(); if(!context.isPrimitive(type)) { throw new TextException("Cannot use %s to represent %s", type, label); } return new Primitive(context, type, ignore); }
@Override public void read(final Type type, final NodeMap<InputNode> node) throws Exception { // do nothing }
@Override public void read(Type type, NodeMap<InputNode> node) throws Exception { //No need to read request objects }
public Type getType(Class type) throws Exception { return null; }
public Type getDependent() throws Exception { return null; }
public boolean write(Type field, Object value, NodeMap node, Map map) throws Exception { if(field.getType() != value.getClass()) { node.put(ELEMENT_NAME, value.getClass().getName()); } return false; }
public void read(Type type, NodeMap<InputNode> node) throws Exception { InputNode value = node.get("type"); System.out.println(value); }
public void write(Type type, NodeMap<OutputNode> node) throws Exception { OutputNode parent = node.getNode(); String name = parent.getName(); name = name.toUpperCase(); parent.setName(name); }
public void write(Type type, NodeMap<OutputNode> node) throws Exception { if(!node.getNode().isRoot()) { node.getNode().setComment(type.getType().getName()); } }
/** * 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 serialize a representation of the object value * provided. If there is a <code>Registry</code> 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<OutputNode> 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 <code>Registry</code> 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<OutputNode> 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 <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 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 <code>Type</code> for * an annotation. If the <code>Type</code> 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; }