Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagexml
<?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:GeneralID IDUsage="CatalogID" IDValue="46" />
    <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>

Commonly used XPath Expression also are provided as Java Constants in XJdfNavigator as well. Here a list of such predefined XPath Expressions:

Java Constant NameXPath Expression
JOB_ID/XJDF/@JobID
CATEGORY/XJDF/@Category
GENERAL_CATALOG_ID

/XJDF/GeneralID[@IDUsage='CatalogID']/@IDValue

GENERAL_LINE_ID

/XJDF/GeneralID[@IDUsage='LineID']/@IDValue

FILE_SPEC_URL

/XJDF/ParameterSet[@Name='RunList']/Parameter/RunList/FileSpec/@URL

MIN_APPROVALS

/XJDF/ParameterSet[@Name='ApprovalParams']/Parameter/ApprovalParams/@MinApprovals

CUSTOMER_ID

/XJDF/ParameterSet[@Name='CustomerInfo']/Parameter/CustomerInfo/@CustomerID

AMOUNT/XJDF/ProductList/Product/@Amount
MEDIA_QUALITY

/XJDF/ProductList/Product/Intent[@Name='MediaIntent']/MediaIntent/@MediaQuality

LAYOUT_FINISHED_DIMENSIONS

/XJDF/ProductList/Product/Intent[@Name='LayoutIntent']/LayoutIntent/@FinishedDimensions

LAYOUT_DIMENSIONS

/XJDF/ProductList/Product/Intent[@Name='LayoutIntent']/LayoutIntent/@Dimensions

PRODUCTION_PRINT_PROCESS

/XJDF/ProductList/Product/Intent[@Name='ProductionIntent']/ProductionIntent/@PrintProcess

FOLDING_CATALOG

/XJDF/ProductList/Product/Intent[@Name='FoldingIntent']/FoldingIntent/@FoldingCatalog

COLOR_NUM_COLORS

/XJDF/ProductList/Product/Intent[@Name='ColorIntent']/ColorIntent/@NumColors

Read and Modify Attributes

All attributes in document easily can be addressed and read using the method readAttribute() and the specific XPath expression as parameter. Modifications also can be done. The method updateAttribute() accepts a XPath expression plus the (new) attribute value. When all modifications are done finally the new XJDF Document is returned as InputStream by calling the getXJdfStream() method or as Byte Array by calling the getXJdfBytes() method.

Code Block
languagejava
// load XJDF as InputStream
InputStream is = XJdfLibSamples.class.getResourceAsStream(RES_SIMPLE_PRODUCT);
XJdfNavigator nav = new XJdfNavigator(is);

// define xPath
String xPath = "/XJDF/ProductList/Product/Intent[@Name='LayoutIntent']";
xPath += "/LayoutIntent/@FinishedDimensions";

// read finished dimensions
String att = nav.readAttribute(xPath);

// modify attribute
att = att.replace("0.0", "2.222");

// update finished dimensions
nav.updateAttribute(xPath, att);

// output
byte[] bytes = nav.getXJdfBytes();
System.out.println(new String(bytes));

The sample above is working with String objects. The XJdfNavigator also provides a second way for reading and modifying based on XJDF Data Types. The following a Java code snippet which has quitely exactly the same functionalty but is using XJDF Data Types and Java Constants for XPath expressions:

Code Block
languagejava
// load XJDF as InputStream
InputStream is = XJdfLibSamples.class.getResourceAsStream(RES_SIMPLE_PRODUCT);
XJdfNavigator nav = new XJdfNavigator(is);

// define xPath
String xPath = XJdfNavigator.LAYOUT_FINISHED_DIMENSIONS;

// read finished dimensions
Shape attShape = (Shape) nav.readAttribute(xPath, Shape.class);

// modify attribute
attShape = new Shape(attShape.getX(), attShape.getY(), 2.222);

// update finished dimensions
nav.updateAttribute(xPath, attShape);

// output
byte[] bytes = nav.getXJdfBytes();
System.out.println(new String(bytes));

Extended XPath Functionality

Specific XPath expressions can be evaluated using the method evaluate(). The return type of this method is Object but in specific it depends on the XPath expression and the resultant return type. Both parameters must be defined when using this method. The following a table of all supported return types:

XPathConstantsDescription
XPathConstants.BOOLEAN

Returns a Boolean object. This constant must be used in case the XPath expressions return a Boolean value.

XPathConstants.NUMBER

Returns a Double object. This constant must be used in case the XPath expressions return a Double value.

XPathConstants.STRING

Returns a String object. This constant must be used in case the XPath expressions return a String value.

XPathConstants.NODE

Returns an org.w3c.dom.Node object. This constant must be used in case the XPath expression returns a single node.

XPathConstants.NODESET

Returns an org.w3c.dom.NodeList object. This constant must be used in case the XPath expression returns multiple nodes.

The next few samples demonstrate how to use the evaluate() method in detail:

Code Block
languagejava
// load XJDF as InputStream
InputStream is = XJdfLibSamples.class.getResourceAsStream(RES_SIMPLE_PRODUCT);
XJdfNavigator nav = new XJdfNavigator(is);

// get number of Intent nodes
String xPath = "count(/XJDF/ProductList/Product/Intent)";
double cnt = (Double) nav.evaluate(xPath, XPathConstants.NUMBER);

// print result
System.out.println("Count: " + cnt);
Code Block
languagejava
// load XJDF as InputStream
InputStream is = XJdfLibSamples.class.getResourceAsStream(RES_SIMPLE_PRODUCT);
XJdfNavigator nav = new XJdfNavigator(is);

// read names of all Intent nodes
String xPath = "/XJDF/ProductList/Product/Intent";
NodeList nodes = (NodeList) nav.evaluate(xPath, XPathConstants.NODESET);

for (int i = 0; i < nodes.getLength(); i++) {
    Node node = nodes.item(i);
    String name = node.getAttributes().getNamedItem("Name").getTextContent();
    System.out.println(name);
}
Code Block
languagejava
// load XJDF as InputStream
InputStream is = XJdfLibSamples.class.getResourceAsStream(RES_SIMPLE_PRODUCT);
XJdfNavigator nav = new XJdfNavigator(is);

// update node
String xPath = "/XJDF/ProductList/Product/Intent[@Name='MediaIntent']/MediaIntent";
Node node = (Node) nav.evaluate(xPath, XPathConstants.NODE);
node.getAttributes().getNamedItem("MediaQuality").setNodeValue("IPM_170");

// output
byte[] bytes = nav.getXJdfBytes();
System.out.println(new String(bytes));

XJdfPackager

The XJdfPackager is responsible for the packaging of an XJDF Document including all its references into a ZIP Package. One instance is required for each XJDF Document processed. If necessary, the compression level can be adjusted manually using the method setCompressionLevel(). The optional parameter "docName" of method packageXJdf() defines the name of the XJDF Document file within the ZIP Package. Out of the box the documents name is the XJDFs JobID plus the extension ".xjdf". The following there is a demonstration how to use the XJdfPackager class:

Code Block
languagejava
// path to artwork
String pathArtwork = XJdfLibSamples.class.getResource(RES_PDF_ARTWORK).getFile();

// build XJDF Document
XJdfNodeFactory nf = new XJdfNodeFactory();

ProductBuilder productBuilder = new ProductBuilder(1500);
Product product = productBuilder.build();

XJdfBuilder xJdfBuilder = new XJdfBuilder("JOB-12345678");
xJdfBuilder.addProduct(product);
xJdfBuilder.addParameter(nf.createRunList(pathArtwork));
XJDF xJdf = xJdfBuilder.build();

byte[] bytes = new XJdfParser().parseXJdf(xJdf, true);

// package to temporarily file
File tmp = File.createTempFile("XJdfPackage", "zip");
tmp.deleteOnExit();
OutputStream os = new FileOutputStream(tmp);

XJdfPackager packager = new XJdfPackager(bytes);
packager.setCompressionLevel(CompressionLevel.BEST_SPEED);
packager.packageXJdf(os);

os.close();

XJdfConstants

When working with XJDF, there are several constants which are required in some cases. So the CIP4 xJdfLib also provides a static class XJdfConstants, where most common constants are already defined. Here is a list of all items in this class:

ConstantValueUse
NAMESPACE_JDF20

"http://www.cip4.org/JDFSchema_2_0"

JDF Default Namespace
NAMESPACE_W3_XML"http://www.w3.org/2001/XMLSchema"W3C XML Namespace
XJDF_CURRENT_VERSION"2.0"Current JDF Version Number
XJDF_LIB_VERSION"0.4"xJdfLib Version Number
XJDF_LIB_BUILD_DATE"2013-02-24 13:19"xJdfLib Build Date
JMF_ICS_VERSION"JMF_L1-2.0"JMF ICS Version Number
MEDIA_TYPE_VND_JMF

"application/vnd.cip4-jmf+xml"

MIME Type JMF
MEDIA_TYPE_VND_JDF

"application/vnd.cip4-jdf+xml"

MIME Type JDF

All constants are static and public. So they can be easily accessed by typing the class name XJdfConstants and the specific name of the constant:

Code Block
languagejava
// get XJDF default namespace
String defaultNamespace = XJdfConstants.NAMESPACE_JDF20;

// get current version of XJDF
String currentVersion = XJdfConstants.XJDF_CURRENT_VERSION;

Util Classes

Util classes provide tools and other simplifications for simplifying working with XJDF. The following is a list of all utils with a short description:

Util ClassDescription
IDGeneratorUtil

Generation of randomly created alphanumeric 8-digits IDs with or without customized prefix.

DimensionUtil

Conversion from millimeter to dtp and the way around.

Performance Optimizations

The CIP4 XJDF Library is based on the Java JAX-B Framework. The framework brings a lot of benefits to the CIP4 xJdfLib but unfortunately the initialization takes a few seconds. Usually this happens automatically when the first XJDF Document is being parsed. In some cases this is not acceptable, thus the library provides additional functionalty for manual initialization. The XJdfFactory class is responsible for such a manual initialization process. The init() method starts the process synchronously. By setting the parameter "initAsync", the same process starts asynchronously. A recommendation is using the asynchronous method when the application starts. By the way the manual initialization process also initializes some other components.

Code Block
languagejava
// synchronous initialization
XJdfFactory.init();

// asynchronous initialization
XJdfFactory.init(true);