...
The current version of CIP4 XJdfLib provides the following builder classes:
- XJdfBuilder
Creation of XJDF Documents. Manages the dealing with Products and Parameters.
- ProductBuilder
Creation of Product-Nodes. Handles all Intent nodes.
- ContactBuilder
Creation of Contact-Nodes. Organize the handling with contact details.
XJDFBuilder
The XJdfBuilder is responsible for the creation and management of XJDF-Root-Nodes as well as the main structure in XJDF Documents. All child nodes can easily be appended by calling the associated "add-" methods. The logic where exactely a specific node has to be put is covered by the builder class.
For instance the XJDF Specification defines that all Parameter-Nodes have to be embedded within a specific ParameterSet element. This mechanism is fully supported by the builder class. So when adding a new Parameter item, the addParameter() method checks if the right ParameterSet-Node already exists. If not, a new one is created automatically. The following is a Java code snippet of how to use the XJdfBuilder.
Code Block |
---|
|
// new factory instance
XJdfNodeFactory nf = new XJdfNodeFactory();
Contact contact = [...];
Product product = [...];
// create XJDF with builder
XJdfBuilder xJdfBuilder = XJdfBuilder.newInstance("FA-SIG-123456");
xJdfBuilder.addParameter(nf.createRunList("test_file.pdf"));
xJdfBuilder.addParameter(contact);
xJdfBuilder.addProduct(product);
XJDF xjdf = xJdfBuilder.build();
// build XJDF Doc
XJDF xJdf = xJdfBuilder.build(); |
Partitioning of Parameter Nodes
Following a sample of a XJDF Document with a partitioned RunList. The XJDF Document references the PDF files for cover and body separately. This mechanism is called partitioning and requires an Part-Node per item.
Code Block |
---|
|
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated by CIP4 xJdfLib 0.4 -->
<xjdf:XJDF xmlns:xjdf="http://www.CIP4.org/JDFSchema_2_0" ID="XJDF_2GYLJJJG"
JobID="FA-SIG-123456" Category="Web2Print" Version="2.0">
<xjdf:ProductList>
<xjdf:Product Amount="1500"/>
</xjdf:ProductList>
<xjdf:ParameterSet Name="RunList">
<xjdf:Parameter>
<xjdf:RunList>
<xjdf:FileSpec URL="cover.pdf"/>
</xjdf:RunList>
<xjdf:Part Run="cover"/>
</xjdf:Parameter>
<xjdf:Parameter>
<xjdf:RunList>
<xjdf:FileSpec URL="body.pdf"/>
</xjdf:RunList>
<xjdf:Part Run="body"/>
</xjdf:Parameter>
</xjdf:ParameterSet>
</xjdf:XJDF> |
Here a demonstration of how to create such partitioned XJDF Documents using the CIP4 XJDF Library. The XJdfBuilder class provides a further override of the addParameter() method to handle paritioning:
Code Block |
---|
|
// new factory instance
XJdfNodeFactory nf = new XJdfNodeFactory();
// create XJDF Document
ProductBuilder productBuilder = new ProductBuilder(1500);
Product product = productBuilder.build();
Part partCover = nf.createPart();
partCover.setRun("cover");
Part partBody = nf.createPart();
partBody.setRun("body");
XJdfBuilder xJdfBuilder = new XJdfBuilder("FA-SIG-123456", "Web2Print");
xJdfBuilder.addParameter(nf.createRunList("cover.pdf"), partCover);
xJdfBuilder.addParameter(nf.createRunList("body.pdf"), partBody);
xJdfBuilder.addProduct(product);
XJDF xjdf = xJdfBuilder.build(); |
ProductBuilder
The Product-Node is another signification element in an XJDF Document. This node specifies the product configuration how desired by the customer. In XJDF, most product configurations are defined as Intent-Nodes. A Product-Node consists of at least itself, its attributes and a set of Intent-Node subelements. The ProductBuilder organizes the creation of a Product-Node as well as the handling of all its Intent-Nodes.
Code Block |
---|
|
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated by CIP4 xJdfLib 0.4 -->
<xjdf:XJDF xmlns:xjdf="http://www.CIP4.org/JDFSchema_2_0" ID="XJDF_4Q1KC6OM"
JobID="FA-SIG-123456" Category="Web2Print" Version="2.0">
<xjdf:ProductList>
<xjdf:Product Amount="1500">
<xjdf:Intent Name="MediaIntent">
<xjdf:MediaIntent MediaQuality="IPG_90"/>
</xjdf:Intent>
<xjdf:Intent Name="LayoutIntent">
<xjdf:LayoutIntent Sides="TwoSidedHeadToHead" Pages="2"
FinishedDimensions="297.63779528 419.52755906 0.0"/>
</xjdf:Intent>
<xjdf:Intent Name="ColorIntent">
<xjdf:ColorIntent NumColors="4 4"/>
</xjdf:Intent>
</xjdf:Product>
</xjdf:ProductList>
</xjdf:XJDF> |
The following the associated Java code snippet for the creation of such a Product-Node:
Code Block |
---|
|
// new factory instance
XJdfNodeFactory nf = new XJdfNodeFactory();
// create product node
ProductBuilder productBuilder = new ProductBuilder(1500);
productBuilder.addIntent(nf.createMediaIntent("IPG_90"));
productBuilder.addIntent(nf.createLayoutIntent(2, "TwoSidedHeadToHead",
new Shape(297.63779528, 419.52755906)));
productBuilder.addIntent(nf.createColorIntent(new IntegerList(4, 4)));
Product product = productBuilder.build();
XJdfBuilder xJdfBuilder = new XJdfBuilder("FA-SIG-123456", "Web2Print");
xJdfBuilder.addProduct(product);
XJDF xjdf = xJdfBuilder.build(); |
ContactBuilder
The ContactBuilder simplify the creation of Contact-Nodes. Contact-Nodes hold all the customers contact and delivery details and can be added as parameter to an XJDF Document. Usually, a contact parameter consists of the Contact-Node with at least an Address-Node, a Company-Node and a ComChannel-Node as subelements.
Code Block |
---|
|
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated by CIP4 xJdfLib 0.4 -->
<xjdf:XJDF xmlns:xjdf="http://www.CIP4.org/JDFSchema_2_0" ID="XJDF_C7C2Q04K"
JobID="FA-SIG-123456" Category="Web2Print" Version="2.0">
<xjdf:ParameterSet Name="Contact">
<xjdf:Parameter>
<xjdf:Contact ContactTypes="Delivery Customer">
<xjdf:Person FamilyName="Meissner" FirstName="Stefan"/>
<xjdf:Company OrganizationName="flyeralarm GmbH"/>
<xjdf:ComChannel ChannelType="Phone" Locator="tel:+49.931.465840"/>
<xjdf:Address PostalCode="97082" City="Wuerzburg"
Street="Alfred-Nobel-Strasse 15"/>
</xjdf:Contact>
</xjdf:Parameter>
</xjdf:ParameterSet>
</xjdf:XJDF> |
Using the ContactBuilder, all subnodes easily can be created and added by simple method calls:
Code Block |
---|
|
// create contact node
ContactBuilder contactBuilder = new ContactBuilder();
contactBuilder.addCompany("flyeralarm GmbH");
contactBuilder.addPerson("Meissner", "Stefan", null);
contactBuilder.addAddress("Alfred-Nobel-Strasse 15", "97082", "Wuerzburg");
contactBuilder.addComChannel("Phone", "tel:+49.931.465840");
contactBuilder.addContactType("Delivery");
contactBuilder.addContactType("Customer");
Contact contact = contactBuilder.build();
XJdfBuilder xJdfBuilder = new XJdfBuilder("FA-SIG-123456", "Web2Print");
xJdfBuilder.addParameter(contact);
XJDF xjdf = xJdfBuilder.build(); |
XJdfParser
The XJdfParser writes an XJDF Document Object Tree either to a binary stream or to a byte array and vice versa. Cases of practical use are dealing with XJDF Documents and http transmissions or working on file system. When using binary streams, internally the parser is working with the Java interfaces java.io.InputStream and java.io.OutputStream. So it doesn’t matter which kind of stream is used for reading or writing. The following is a sample of how to save an XJDF Document to a local file system.
Code Block |
---|
|
// any XJDF Document
XJDF xJdf = [...];
// target file
File tmpFile = new File("/var/tmp/myXJdfDoc.xjdf");
OutputStream os = new FileOutputStream(tmpFile);
// write XJDF Document to file using XJdfParser
XJdfParser xJdfParser = new XJdfParser();
xJdfParser.parseXJdf(xJdf, os);
// close stream
os.close(); |
The other option is working with a byte array. Here a sample of how to get a Byte Array from a XJDF Document:
Code Block |
---|
|
// any XJDF Document
XJDF xJdf = [...];
// write XJDF Document to file using XJdfParser
XJdfParser xJdfParser = new XJdfParser();
byte[] bytes = xJdfParser.parseXJdf(xJdf); |
When parsing XJDF Document Object Trees to binary streams, the document is automatically being validated against the XJDF Schema. Internally the XJdfValidator class is used to achieve this. In case the document is invalid a ValidationException is thrown. The message of the exception lists all points making the document invalid. In order to skip the validation process during parsing there is an optional parameter skipValidation in parseXJdf() method.
Code Block |
---|
|
// skip validation when parsing
xJdfParser.parseXJdf(xJdf, os, true); |
In order to create an XJDF Object Tree from a binary stream the XJdfParser class contains a method parseStream(). This method accepts an InputStream as input parameter. Out of the box the Java framework provides many different implementations of this interface. All InputStreams can easily be parsed to an XJDF Document Object Tree by calling the method parseStream(). The sample below, for example, uses the FileInputStream implementation which is responsible for creating an InputStream from a local file. An InputStream created from an HttpRequest also would be suitable and often is being used when working with http transmissions.
Code Block |
---|
|
// open XJDF Document as InputStream
File tmpFile = new File("/var/tmp/myXJdfDoc.xjdf");
InputStream is = new FileInputStream(tmpFile);
// parse stream to XJDF Document Object Tree
XJdfParser xJdfParser = XJdfParser.newInstance();
XJDF xJdf = xJdfParser.parseStream(is); |
As before, there also is a second method for using Byte Arrays:
Code Block |
---|
|
// XJDF Byte Array
byte[] bytes = [...];
// write XJDF Document to file using XJdfParser
XJdfParser xJdfParser = new XJdfParser();
XJDF xJdf = xJdfParser.parseBytes(bytes); |
Info |
---|
|
In order to analyze or extract details from an XJDF Document it is recommended to work with XPath expressions. Parsing the whole document and working with the DOM Tree Objects is no longer state of the art. This mechanism consumes time and raises code complexity. Besides, parsing an InputStream is also prone to errors because it requires fully conform documents. CIP4 xJdfLib provides an extra class XJdfNavigator for dealing with XPath expressions in XJDF Documents. XJDF is desinged for XPath so the preferred way of reading XJDF Documents is XPath. |