JavaScript is disabled on your browser.

Package javolution.xml

Support for the encoding of objects, and the objects reachable from them, into XML; and the complementary reconstruction of the object graph from XML.

See: Description

Package javolution.xml Description

Support for the encoding of objects, and the objects reachable from them, into XML; and the complementary reconstruction of the object graph from XML.

This page has been translated into Spanish language by Maria Ramos from Webhostinghub.com/support/edu.

XML marshalling/unmarshalling facility:

XML Data Binding

Key Advantages:

  • Real-time characteristics with no adverse effect on memory footprint or garbage collection (e.g. it can be used for time critical communications). XMLFormat is basically a "smart" wrapper around our real-time StAX-like XMLStreamReader and XMLStreamWriter.
  • Works directly with your existing Java classes, no need to create new classes or customize your implementation in any way.
  • The XML representation can be high level and impervious to obfuscation or changes to your implementation.
  • Performance on a par or better than default JavaTM Serialization/Deserialization (See bindmark for performance comparison).
  • Small footprint, runs on any platform including Android.
  • The XML mapping can be defined for a top class (or interface) and is automatically inherited by all sub-classes (or all implementing classes).
  • Supports object references (to avoid expanding objects already serialized).

The default XML format for a class is typically defined using the DefaultXMLFormat annotation tag.

@DefaultXMLFormat(Graphic.XML.class) 
public abstract class Graphic implements XMLSerializable {
 private boolean isVisible;
 private Paint paint; // null if none.
 private Stroke stroke; // null if none.
 private Transform transform; // null if none.
 // Default XML format with name associations (members identified by an unique name).
 // See XMLFormat for examples of positional associations.
 public static class XML extends XMLFormat {
 public void write(Graphic g, OutputElement xml) throws XMLStreamException {
 xml.setAttribute("isVisible", g.isVisible); 
 xml.add(g.paint, "Paint");
 xml.add(g.stroke, "Stroke");
 xml.add(g.transform, "Transform");
 }
 public void read(InputElement xml, Graphic g) throws XMLStreamException {
 g.isVisible = xml.getAttribute("isVisible", true);
 g.paint = xml.get("Paint");
 g.stroke = xml.get("Stroke");
 g.transform = xml.get("Transform");
 }
 };
}
Sub-classes may override the inherited XML format:
@DefaultXMLFormat(Area.XML.class) 
public class Area extends Graphic {
 private Shape geometry; 
 // Adds geometry to format.
 public static class XML extends XMLFormat<Area> {
 XMLFormat graphicXML = new Graphic.XML();
 public void write(Area area, OutputElement xml) throws XMLStreamException {
 graphicXML.write(area, xml); // Calls parent write.
 xml.add(area.geometry, "Geometry");
 }
 public void read(InputElement xml, Area area) throws XMLStreamException {
 graphicXML.read(xml, area); // Calls parent read.
 area.geometry = xml.get("Geometry");
 }
 };
}
The following writes a graphic area to a file, then reads it:
 
// Creates some useful aliases for class names.
XMLBinding binding = new XMLBinding();
binding.setAlias(Color.class, "Color");
binding.setAlias(Polygon.class, "Polygon");
binding.setClassAttribute("type"); // Use "type" instead of "class" for class attribute.
// Writes the area to a file.
XMLObjectWriter writer = XMLObjectWriter.newInstance(new FileOutputStream("C:/area.xml"));
writer.setBinding(binding); // Optional.
writer.setIndentation("\t"); // Optional (use tabulation for indentation).
writer.write(area, "Area", Area.class);
writer.close(); 
// Reads the area back
XMLObjectReader reader = XMLObjectReader.newInstance(new FileInputStream("C:/area.xml"));
reader.setBinding(binding);
Area a = reader.read("Area", Area.class);
reader.close();
Here is an example of valid XML representation for an area:
<Area isVisible="true">
 <Paint type="Color" rgb="#F3EBC6" />
 <Geometry type="Polygon">
 <Vertex x="123" y="-34" />
 <Vertex x="-43" y="-34" />
 <Vertex x="-12" y="123" />
 </Geometry>
</Area>

The following table illustrates the variety of XML representations supported (Foo class with a single String member named text):

XML FORMAT XML DATA
XMLFormat<Foo> XML = new XMLFormat<Foo>() {
 public void write(Foo foo, OutputElement xml) throws XMLStreamException {
 xml.setAttribute("text", foo.text); 
 }
 public void read(InputElement xml, Foo foo) throws XMLStreamException {
 foo.text = xml.getAttribute("text", "");
 }
};
 <!-- Member as attribute -->
 <Foo text="This is a text"/>
XMLFormat<Foo> XML = new XMLFormat<Foo>() {
 public void write(Foo foo, OutputElement xml) throws XMLStreamException {
 xml.add(foo.text); 
 }
 public void read(InputElement xml, Foo foo) throws XMLStreamException {
 foo.text = xml.getNext();
 }
};
 <!-- Member as anonymous nested element -->
 <Foo>
 <java.lang.String value="This is a text"/>
 </Foo>
XMLFormat<Foo> XML = new XMLFormat<Foo>(Foo.class) {
 public void write(Foo foo, OutputElement xml) throws XMLStreamException {
 xml.addText(foo.text); // or xml.getStreamWriter().writeCDATA(foo.text) to use CDATA block. 
 }
 public void read(InputElement xml, Foo foo) throws XMLStreamException {
 foo.text = xml.getText().toString(); // Content of a text-only element.
 }
};
 <!-- Member as Character Data -->
 <Foo>This is a text</Foo>
XMLFormat<Foo> XML = new XMLFormat<Foo>(Foo.class) {
 public void write(Foo foo, OutputElement xml) throws XMLStreamException {
 xml.add(foo.text, "Text"); 
 }
 public void read(InputElement xml, Foo foo) throws XMLStreamException {
 foo.text = xml.get("Text");
 }
};
 <!-- Member as named element of unknown type -->
 <Foo>
 <Text class="java.lang.String" value="This is a text"/>
 </Foo>
XMLFormat<Foo> XML = new XMLFormat<Foo>(Foo.class) {
 public void write(Foo foo, OutputElement xml) throws XMLStreamException {
 xml.add(foo.text, "Text", String.class); 
 }
 public void read(InputElement xml, Foo foo) throws XMLStreamException {
 foo.text = xml.get("Text", String.class);
 }
};
 <!-- Member as named element of actual type known -->
 <Foo>
 <Text value="This is a text"/>
 </Foo>

XML format do not have to use the classes public no-arg constructors, instances can be created using factory methods, private constructors (with constructor parameters set from the XML element) or even retrieved from a collection (if the object is shared or unique). For example:

@DefaultXMLFormat(Point.XML.class) 
public final class Point implements XMLSerializable { 
 private int x;
 private int y;
 private Point() {}; // No-arg constructor not visible.
 public static Point valueOf(int x, int y) { ... }
 public static class XML = new XMLFormat<Point>() {
 public boolean isReferencable() {
 return false; // Always manipulated by value.
 }
 public Point newInstance(Class<Point> cls, InputElement xml) throws XMLStreamException {
 return Point.valueOf(xml.getAttribute("x", 0), xml.getAttribute("y", 0)); 
 }
 public void write(Point point, OutputElement xml) throws XMLStreamException {
 xml.setAttribute("x", point.x);
 xml.setAttribute("y", point.y);
 }
 public void read(InputElement xml, Point point) throws XMLStreamException {
 // Do nothing immutable.
 }
 };
}

Document cross-references are supported, including circular references. Let's take for example:

@DefaultXMLFormat(xml=Polygon.XML.class) 
public class Polygon implements Shape, XMLSerializable { 
 private Point[] vertices;
 public static class XML extends XMLFormat<Polygon> {
 public void write(Polygon polygon, OutputElement xml) throws XMLStreamException {
 xml.setAttibutes("count", vertices.length);
 for (Point p : vertices) {
 xml.add(p, "Vertex", Point.class);
 }
 }
 public void read(InputElement xml, Polygon polygon) throws XMLStreamException {
 int count = xml.getAttributes("count", 0);
 polygon.vertices = new Point[count];
 for (int i=0; i < count; i++) {
 vertices[i] = xml.get("Vertex", Point.class);
 }
 }
 };
}
Polygon[] polygons = new Polygon[] {p1, p2, p1};
...
TextBuilder xml = TextBuilder.newInstance();
AppendableWriter out = new AppendableWriter().setOutput(xml)
XMLObjectWriter writer = XMLObjectWriter.newInstance(out);
writer.setXMLReferenceResolver(new XMLReferenceResolver()); // Enables cross-references.
writer.write(polygons, "Polygons", Polygon[].class); 
writer.close();
System.out.println(xml);
Prints the following (noticed that the first polygon and last one are being shared).
<Polygons length="3">
 <Polygon id="0" count="3">
 <Vertex x="123" y="-34" /> 
 <Vertex x="-43" y="-34" />
 <Vertex x="-12" y="123" />
 </Polygon>
 <Polygon id="1" count="3">
 <Vertex x="-43" y="-34" />
 <Vertex x="123" y="-34" />
 <Vertex x="-12" y="123" />
 </Polygon>
 <Polygon ref="0"/>
 </Polygons>

ALGORITHMS:

Our XMLObjectReader/XMLObjectWriter are in fact simple wrappers around our Javolution high-performance StAX-like XMLStreamReader and XMLStreamWriter classes. The logic of these wrappers is described below:

OutputElement.add(object, name, uri, class):
1. if (object == null) return
2. getStreamWriter().writeStartElement(uri, name)
3. isReference = referenceResolver.writeReference(object, this)
4. if (!isReference) binding.getFormat(class).write(object, this)
5. getStreamWriter().writeEndElement()
6. end
InputElement.get(name, uri, class):
1. if (!getStreamReader().getLocalName().equals(name) ||
!getStreamReader().getNamespaceURI().equals(uri)) return null
2. object = referenceResolver.readReference(inputElement)
3. if (object != null) Goto 8 // Found reference
4. format = binding.getFormat(class)
5. object = format.newInstance(class, inputElement)
6. referenceResolver.createReference(object, inputElement) // Done before parsing to support circular references.
7. format.read(inputElement, object)
8. getStreamReader().nextTag()
9. end

Copyright © 2005-2013 Javolution. All Rights Reserved.

AltStyle によって変換されたページ (->オリジナル) /