/**
* SINDB2XHTML project
* This utility converts docbook slides into XHTML
* https://code.google.com/p/sindb2xhtm
*/
package cz.muni.fi.sindb2xhtml;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import com.icl.saxon.StyleSheet;
import cz.muni.fi.sindb2xhtml.utils.FileUtils;
/**
* The Sindb2xhtml class
* provides functionality for the transformation
* of docbook slides into xhtml 1.0
*
*/
public class Sindb2xhtml {
/**
*path to "style.css" (loaded from properties file
*/
private String styleCssFile = "/files/style.css";
/**
* path to docbook slides xml file - file to be converted into xhtml
* (set on commandline)
*/
private String sourceXMLFile = "";
/**
* path to /docbook/slides/xhtml/docbook.xsl (loaded from properties file)
*/
private String sourceXSLFile = "/docbook/slides/xhtml/default.xsl";
//output can be generated ONLY to actual work dir (blame saxon)
private String actualWorkDir = "./";
/**
* CTOR
* @throws Sindb2xhtmlException when someting bad happens
*/
public Sindb2xhtml(final String[] args) throws Sindb2xhtmlException {
//process command line arguments
processArgs(args);
try {
final String actualDirPath = System.getProperty("user.dir");
if (actualDirPath == null)
{
throw new Sindb2xhtmlException("Cannot resolve actual working directory.");
}
final File actualDir = new File(actualDirPath);
actualWorkDir = actualDir.getCanonicalPath();
} catch (IOException e) {
throw new Sindb2xhtmlException(e);
}
}
/**
* Processes arguments list
* -i [source docbook slides.xml]
* -h help
* @param args command-line arguments
* @throws Sindb2xhtmlException when file read error occurs
*/
private void processArgs(final String[] args) throws Sindb2xhtmlException {
// -i switch set?
boolean sourceSet = false;
// -h switch set?
boolean helpSet = false;
// error occured?
boolean fail = false;
// argument list position
int argNo = 0;
while (argNo < args.length) { //loop over all arguments
// Set the source xml file here
if (args[argNo].equals("-i") && (args.length >= argNo + 2)) {
if (sourceSet) {
fail = true; // trying to re-set source file => fail
}
else {
// Get the absolute path of the source xml file
sourceXMLFile = args[++argNo];
if (sourceXMLFile == null || sourceXMLFile.length() == 0) {
throw new Sindb2xhtmlException("Input XML file was not set.");
}
try {
File xmlFile = new File(sourceXMLFile);
if (!xmlFile.exists())
{
throw new Sindb2xhtmlException("Failed to open input file " + sourceXMLFile + ".");
}
sourceXMLFile = xmlFile.getCanonicalPath(); //path to source file
} catch (IOException e) {
throw new Sindb2xhtmlException("Failed to get the path of input file " + sourceXMLFile + ".",e);
}
sourceSet = true; //source file has been set
}
}
//user needs help?
if (args[argNo].equals("-h"))
{
helpSet = true;
}
argNo++; //next command-line argument
}
//invalid arguments / need help?
if (args.length < 2 || fail || !sourceSet || helpSet)
{
printHelp();
System.exit(0);
}
}
/**
* Displays short manual
*/
private void printHelp() {
System.out.println("converts docbook/slides into XHTML");
System.out.println("expected command-line arguments:");
System.out.println("\t-i [path to source XML file (docbook slides)]");
System.out.println("\t-h Help");
}
/**
* The entry point of this application
* @param args command line args
*/
public static void main(String[] args) {
System.out.println("SINDB2XHTML 2011");
Sindb2xhtml sindb2xhtml = null;
try {
sindb2xhtml = new Sindb2xhtml(args);
} catch (Sindb2xhtmlException e1) {
System.out.println("Failed to transform the docbook slidess.\n" + e1.getLocalizedMessage());
e1.printStackTrace();
System.exit(2);
}
try { //run the transformation
sindb2xhtml.xsltTransformation();
} catch (Sindb2xhtmlException e) {
e.printStackTrace();
System.exit(4);
}
}
/**
* Transforms file set in processArgs
* @throws Sindb2xhtmlException
*/
public void xsltTransformation() throws Sindb2xhtmlException
{
System.out.println("xslt in use:\t" + sourceXSLFile);
System.out.println("input:\t" + sourceXMLFile);
xsltTransformation(sourceXMLFile); //transform!
copyNecessaryFiles(actualWorkDir); //copy style.css into target dir
}
/**
* Transforms file set in processArgs
* @param inXSLFileName path to docbook.xsl
* @throws Sindb2xhtmlException
*/
private void xsltTransformation (final String inputXMLFilePath) throws Sindb2xhtmlException
{
final File inputXMLFile = new File(inputXMLFilePath);
final InputStream inputXSLStream = getClass().getResourceAsStream("/docbook/slides/xhtml/default.xsl");
final StreamSource inputXSLSource = new StreamSource(inputXSLStream);
//Saxon bug work-around (<xsl:import> relative reference)
final URL url = getClass().getResource("/docbook/slides/xhtml/");
inputXSLSource.setSystemId(url.toExternalForm());
//Run it!
xsltTransformation( new StreamSource(inputXMLFile), inputXSLSource);
}
/**
* Transforms file set in processArgs
* @param inXMLsrc input docbook slides source
* @param inXSLsrc input defualt.xsl source
* @throws Sindb2xhtmlException when something doesn't work as expected
* (
*/
private void xsltTransformation(final Source inXMLsrc,final Source inXSLsrc) throws Sindb2xhtmlException
{
// temporary file - needed for transformation
File tmp = new File(System.getProperty("java.io.tmpdir") + System.getProperty("file.separator") + "sindb2xhtml.tmp");
TransformerFactory factory = TransformerFactory.newInstance();
Templates templates = null;
try {
templates = factory.newTemplates(inXSLsrc);
} catch (TransformerConfigurationException e) {
throw new Sindb2xhtmlException("Failed to compile input sources.",e);
}
StyleSheet stylesheet = new StyleSheet();
try {
stylesheet.processFile(inXMLsrc, templates, tmp, null);
tmp.deleteOnExit();
} catch (TransformerException e) {
throw new Sindb2xhtmlException(e);
}
}
/**
* Copies necessary files into target directory
* @param targetDir target directory
* @throws Sindb2xhtmlException when copying fails
*/
private void copyNecessaryFiles(final String targetDir) throws Sindb2xhtmlException {
InputStream cssFileStream = getClass().getResourceAsStream(styleCssFile);
FileUtils.copyfile(cssFileStream, targetDir + "/style.css");
}
public String getStyleCssFile() {
return styleCssFile;
}
public void setStyleCssFile(String styleCssFile) {
this.styleCssFile = styleCssFile;
}
public String getSourceXMLFile() {
return sourceXMLFile;
}
public void setSourceXMLFile(String sourceXMLFile) {
this.sourceXMLFile = sourceXMLFile;
}
public String getSourceXSLFile() {
return sourceXSLFile;
}
public void setSourceXSLFile(String sourceXSLFile) {
this.sourceXSLFile = sourceXSLFile;
}
public String getActualWorkDir() {
return actualWorkDir;
}
public void setActualWorkDir(String actualWorkDir) {
this.actualWorkDir = actualWorkDir;
}
}