package net.sf.jpluck.apps.cmdline;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Iterator;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import net.sf.jpluck.apps.OptionsUtil;
import net.sf.jpluck.jxl.JXL;
import net.sf.jpluck.palm.Database;
import net.sf.jpluck.palm.PdbOutputStream;
import net.sf.jpluck.palm.Record;
import net.sf.jpluck.util.CompressionUtil;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.Options;
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.Pointer;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class JXL2PDB {
public static final String VERSION = "1.0.2";
public static final String DATE = "2004-02-23";
public static void main(String[] args) throws Exception {
Options options = OptionsUtil.createGeneric();
CommandLine cl = new GnuParser().parse(options, args);
if (cl.hasOption("help")) {
OptionsUtil.printHelp("java -jar on-device-jxl.jar <jxl file> [pdb file]",
"Creates on-device JXLs for use by the HotSync conduit.", options);
}
if (cl.hasOption("version")) {
System.out.println("JPluck JPB-JXL " + VERSION + " (" + DATE + ")");
System.exit(0);
}
args = cl.getArgs();
if ((args.length < 1) || (args.length > 2)) {
System.err.println("Error: invalid number of arguments: " + args.length);
System.exit(-1);
}
File file = new File(args[0]);
System.out.println("Reading " + file.getAbsolutePath());
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
DocumentBuilder db = dbf.newDocumentBuilder();
db.setEntityResolver(new JXL.JXLEntityResolver());
Document document = db.parse(file);
JXPathContext ctx= JXPathContext.newContext(document);
Iterator it = ctx.iteratePointers("//xslt[@href]");
URI uri = file.toURI();
while (it.hasNext()) {
Pointer p = (Pointer) it.next();
Element xsltElem = (Element) p.getNode();
URI xslURI = uri.resolve(xsltElem.getAttribute("href"));
File xslFile = new File(xslURI);
System.out.println("Embedding " + xslFile.getAbsolutePath());
Document xslStylesheet = db.parse(xslFile);
xsltElem.removeAttribute("href");
xsltElem.appendChild(document.importNode(xslStylesheet.getDocumentElement(), true));
}
String name = file.getName();
if (name.endsWith(".jxl")) {
name = name.substring(0, name.length() - 4);
}
if (args.length == 2) {
file = new File(args[1]);
} else {
file = new File(file.getParent(), name + ".pdb");
}
System.out.println("Writing " + file.getAbsolutePath());
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
transformer.transform(new DOMSource(document), new StreamResult(baos));
JXLDatabase pdb = new JXLDatabase(CompressionUtil.compressZLIB(baos.toByteArray()));
pdb.write(file);
System.out.println("Done!");
}
private static class JXLDatabase extends Database {
public JXLDatabase(byte[] data) {
super(1, "JXLd", "JPlk");
setName("JPlk-JXL");
recordList.add(new JXLRecord(data));
}
}
private static class JXLRecord implements Record {
private byte[] data;
JXLRecord(byte[] data) {
this.data = data;
}
public int getRecordId() {
return 1;
}
public void write(PdbOutputStream out) throws IOException {
out.write(data);
}
}
}