package net.sf.jpluck.jxl;
import java.io.File;
import java.io.FileOutputStream;
import java.io.StringReader;
import java.text.ParseException;
import java.util.Date;
import java.util.Iterator;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import net.sf.jpluck.apps.ExitCodes;
import net.sf.jpluck.apps.OptionsUtil;
import net.sf.jpluck.jxl.JXL.JXLEntityResolver;
import net.sf.jpluck.xml.DOMUtil;
import net.sf.jpluck.xml.NamespaceURI;
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.ri.model.dom.DOMAttributePointer;
import org.apache.commons.jxpath.ri.model.dom.DOMNodePointer;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
/**
* Converts JXL 2.0 to JXL 2.1
*/
public class JXL21Converter {
public static final String VERSION = "1.0.1";
public static final String RELEASE_DATE = "2004-02-26";
private Document document;
private JXPathContext ctx;
public static void Convert(Document document) {
JXL21Converter convert = new JXL21Converter();
convert.document = document;
convert.ctx = JXPathContext.newContext(document);
convert.convertDates();
convert.convertXSL();
convert.convertLanguage();
convert.convertURIPatterns();
convert.convertReferrer();
convert.setNamespaceURIs();
convert.convertInfo();
}
private void convertInfo() {
for (Iterator it = ctx.iteratePointers("//info/title"); it.hasNext();) {
DOMNodePointer p = (DOMNodePointer) it.next();
Element title = (Element) p.getBaseValue();
Element newTitle = document.createElementNS(NamespaceURI.DUBLIN_CORE, "dc:title");
newTitle.appendChild(document.createTextNode(DOMUtil.getText(title)));
Element info = (Element) title.getParentNode();
info.insertBefore(newTitle, title);
info.removeChild(title);
}
for (Iterator it = ctx.iteratePointers("//info/description"); it.hasNext();) {
DOMNodePointer p = (DOMNodePointer) it.next();
Element description = (Element) p.getBaseValue();
Element newDescription = document.createElementNS(NamespaceURI.DUBLIN_CORE, "dc:description");
newDescription.appendChild(document.createTextNode(DOMUtil.getText(description)));
Element info = (Element) description.getParentNode();
info.insertBefore(newDescription, description);
info.removeChild(description);
}
for (Iterator it = ctx.iteratePointers("//site/description|//feed/description"); it.hasNext(); ) {
DOMNodePointer p = (DOMNodePointer) it.next();
Element description = (Element) p.getBaseValue();
Element parent = (Element) description.getParentNode();
Element newDescription = document.createElementNS(NamespaceURI.DUBLIN_CORE, "dc:description");
newDescription.appendChild(document.createTextNode(DOMUtil.getText(description)));
parent.removeChild(description);
Element info = document.createElement("info");
info.appendChild(newDescription);
parent.insertBefore(info, parent.getFirstChild());
}
ctx.removeAll("//info/date");
}
private void convertReferrer() {
for (Iterator it = ctx.iteratePointers("//site|//feed|//template"); it.hasNext();) {
DOMNodePointer p = (DOMNodePointer) it.next();
Element elem = (Element) p.getBaseValue();
if (elem.hasAttribute("referrer")) {
if (!elem.getNodeName().equals("template")) {
Element uri = (Element)elem.getElementsByTagName("uri").item(0);
uri.setAttribute("referrer", elem.getAttribute("referrer"));
}
elem.removeAttribute("referrer");
}
}
}
private void convertLanguage() {
for (Iterator it = ctx.iteratePointers("//@language"); it.hasNext();) {
DOMAttributePointer p = (DOMAttributePointer) it.next();
Attr attribute = (Attr) p.getBaseValue();
attribute.setValue(attribute.getValue().toLowerCase());
}
}
private void convertURIPatterns() {
for (Iterator it = ctx.iteratePointers("//site|//feed|//template"); it.hasNext();) {
DOMNodePointer p = (DOMNodePointer) it.next();
Element elem = (Element) p.getBaseValue();
Element uriPatterns = document.createElement("uriPatterns");
Element include = null;
NodeList nodeList = elem.getElementsByTagName("include");
if (nodeList.getLength() > 0) {
include = (Element) nodeList.item(0);
JXPathContext ctx = JXPathContext.newContext(include);
for (Iterator it2 = ctx.iteratePointers("pattern"); it2.hasNext();) {
DOMNodePointer p2 = (DOMNodePointer) it2.next();
Element pattern = (Element) p2.getBaseValue();
Element newInclude = document.createElement("include");
newInclude.appendChild(document.createTextNode(DOMUtil.getText(pattern)));
uriPatterns.appendChild(newInclude);
}
}
Element exclude = null;
nodeList = elem.getElementsByTagName("exclude");
if (nodeList.getLength() > 0) {
exclude = (Element) nodeList.item(0);
JXPathContext ctx = JXPathContext.newContext(exclude);
for (Iterator it2 = ctx.iteratePointers("pattern"); it2.hasNext();) {
DOMNodePointer p2 = (DOMNodePointer) it2.next();
Element pattern = (Element) p2.getBaseValue();
Element newExclude = document.createElement("exclude");
newExclude.appendChild(document.createTextNode(DOMUtil.getText(pattern)));
uriPatterns.appendChild(newExclude);
}
}
if (include != null) {
elem.insertBefore(uriPatterns, include);
elem.removeChild(include);
}
if (exclude != null) {
if (include == null) {
elem.insertBefore(uriPatterns, exclude);
}
elem.removeChild(exclude);
}
}
}
private void setNamespaceURIs() {
Element jxl = document.getDocumentElement();
jxl.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
jxl.setAttribute("xsi:noNamespaceSchemaLocation", "http://jpluck.sourceforge.net/jxl/jxl-2.1.xsd");
jxl.setAttribute("xmlns:dc", NamespaceURI.DUBLIN_CORE);
}
private void convertDates() {
for (Iterator it = ctx.iteratePointers("//@lastConverted|//@start|//@date"); it.hasNext();) {
DOMAttributePointer p = (DOMAttributePointer) it.next();
Attr attribute = (Attr) p.getBaseValue();
try {
Date date = JXL.stringToDate(attribute.getValue());
attribute.setValue(JXL.dateToString(date));
} catch (ParseException e) {
attribute.getParentNode().removeChild(attribute);
}
}
}
private void convertXSL() {
for (Iterator it = ctx.iteratePointers("//transform"); it.hasNext();) {
DOMNodePointer p = (DOMNodePointer) it.next();
Element transform = (Element) p.getBaseValue();
transform.setAttribute("uriPattern", transform.getAttribute("pattern"));
transform.removeAttribute("pattern");
NodeList nodeList = transform.getElementsByTagName("xsl");
for (int i = 0, n = nodeList.getLength(); i < n; i++) {
Element xsl = (Element)nodeList.item(0);
Element xslt = document.createElement("xslt");
transform.insertBefore(xslt, xsl);
if (xsl.hasAttribute("href")) {
xslt.setAttribute("href", xsl.getAttribute("href"));
transform.removeChild(xsl);
continue;
}
NodeList nodeList2 = xsl.getElementsByTagName("stylesheet");
if (nodeList2.getLength() > 0) {
String stylesheet = DOMUtil.getText((Element) nodeList2.item(0)).trim();
try {
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document stylesheetDocument = db.parse(new InputSource(new StringReader(stylesheet)));
Element clone = (Element) xslt.getOwnerDocument().importNode(stylesheetDocument.getDocumentElement(),
true);
xslt.appendChild(clone);
} catch (Exception e) {
e.printStackTrace();
}
}
transform.removeChild(xsl);
}
}
}
public static void main(String[] args) throws Exception {
Options options = OptionsUtil.createGeneric();
CommandLine cl = new GnuParser().parse(options, args);
if (cl.hasOption("help")) {
String usage = "java -jar convertjxl21.jar <JXL 2.0 file> <JXL 2.1 file>";
String description = "Converts JXL 2.0 files to JXL 2.1 format.";
OptionsUtil.printHelp(usage, description, options);
System.exit(ExitCodes.OK);
} else if (cl.hasOption("version")) {
System.out.println("JXL 2.1 Converter " + VERSION + " (" + RELEASE_DATE + ")");
System.exit(ExitCodes.OK);
}
if (cl.getArgs().length != 2) {
System.err.println("ERROR: Invalid number of arguments " + cl.getArgs().length);
System.exit(ExitCodes.ERROR_INVALID_NUMBER_OF_ARGUMENTS);
}
File jxl20File = new File(cl.getArgs()[0]);
File jxl21File = new File(cl.getArgs()[1]);
if (jxl20File.equals(jxl21File)) {
System.err.println("ERROR: Source and destination files are the same.");
System.exit(ExitCodes.UNSPECIFIED);
}
System.out.println("Reading " + jxl20File.getAbsolutePath());
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(true);
DocumentBuilder db = dbf.newDocumentBuilder();
db.setEntityResolver(new JXLEntityResolver());
Document document = db.parse(jxl20File);
System.out.println("Converting to JXL 2.1");
JXL21Converter.Convert(document);
System.out.println("Writing " + jxl21File.getAbsolutePath());
OutputFormat outputFormat = new OutputFormat("xml", "UTF-8", true);
outputFormat.setOmitDocumentType(true);
outputFormat.setLineSeparator(System.getProperty("line.separator"));
FileOutputStream out = new FileOutputStream(jxl21File);
XMLSerializer serializer = new XMLSerializer(out, outputFormat);
serializer.asDOMSerializer().serialize(document);
out.close();
System.out.println("Done!");
}
}