The User Guide is organized as a series of recipes. This is likely to be more interesting for our intended audience of Java developers. Each recipe illustrates how to do some specific function with PLists using the JPList library.
TopWe will assume that the PList comes to us as a java.io.InputStream object, because that is likely to be most common use-case, but the procedure to read the PList from a java.io.File, java.io.Reader, java.net.URL or a java.lang.String is identical.
AsciiBuilder builder = new AsciiBuilder(); Document doc = builder.build(new File("/our/file/name");
We use the PojoBuilder class to parse a POJO (Plain Old Java Object) into a JPList Document object. Once that is done, the application can walk the JPList Document object using getContent() calls. The builder will invoke all the public getXXX() methods on the POJO, and build a JPList Document object with 2 Dictionary Elements. The first is a single name-value pair with the classname, and the second is a set of name-value pairs representing the contents of the POJO's variables. If the value returned from the getXXX() call is a primitive (int, long, etc) or a primitive wrapper Object (Integer, Long, etc), then the value is a StringElement. If the value returned is a Collection, then it is an ArrayElement. If it is an Object by itself, it is a subordinate Dictionary built in the same way as the parent POJO element.
OurPojoObject obj; obj.populate(); PojoBuilder builder = new PojoBuilder(); Document doc = builder.build(obj);
We can output a JPList Document object to a java.lang.String using the outputString() method, or to a java.io.OutputStream or java.io.Writer using one of the output() methods of the AsciiOutputter.
AsciiOutputter outputter = new AsciiOutputter(); outputter.outputString(doc); outputter.write(doc, writer);
This recipe is similar to Recipe #3. We will call various functions on the outputter to set the formatting of the PList being outputted.
AsciiOutputter outputter = new AsciiOutputter(); outputter.setIndent("\t"); outputter.setLineSeparator("\r\n"); outputter.setNewLine(true); outputter.outputString(doc); outputter.write(doc, writer);
Sometimes we need to interoperate with applications that can consume only XML. Using an XmlOutputter will output our JPLIst object as a XML PList. The recipe is identical to using the AsciiOutputter, except that we use the XmlOutputter class instead.
XmlOutputter outputter = new XmlOutputter(); outputter.outputString(doc); outputter.write(doc, writer);
Identical to recipe #4, except that we use the XmlOutputter instead of the AsciiOutputter to generate formatted (human-readable) XML.
XmlOutputter outputter = new XmlOutputter(); outputter.setIndent("\t"); outputter.setLineSeparator("\r\n"); outputter.setNewLine(true); outputter.outputString(doc); outputter.write(doc, writer);
All IElement implementations provide a getContent() method, although they are not required to do this by the interface. The reason they are not is becuase each of these return a different kind of Object. This could have been enforced this by defining a Object::getContent() method in the interface, but having them return specific Objects was considered to be more convenient. StringElements and DataElements return a String, ArrayElement returns a List, and DictionaryElement returns a Map. The getContent() method is also available for a Document object, and it returns a List. Here is a code snippet for walking a JPList Document object one level deep. Obviously the walking code needs to have some knowledge of the Document structure, or use recursion to go as deep as it needs to.
Document doc = builder.build(new File("test/data/" + TESTFILES[i])); List elements = doc.getContent(); for (Iterator it = elements.iterator(); it.hasNext();) { IElement element = (IElement) it.next(); switch (element.typeOf()) { case IElement.STRING: System.out.println("STRING: " + ((StringElement) element).getContent()); break; case IElement.DATA: System.out.println("DATA: " + ((DataElement) element).getContent()); break; case IElement.ARRAY: ArrayElement array = (ArrayElement) element; List contents = array.getContent(); System.out.println("ARRAY: size = " + contents.size()); break; case IElement.DICTIONARY: DictionaryElement dictionary = (DictionaryElement) element; Map dcontents = dictionary.getContent(); System.out.println("DICTIONARY: size = " + dcontents.keySet().size()); break; default: System.out.println("UNKNOWN DATA!"); break; } }