All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
cdc.io.tools.XmlToHtml Maven / Gradle / Ivy
package cdc.io.tools;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import cdc.util.cli.AbstractMainSupport;
import cdc.util.files.Resources;
import cdc.util.lang.Checks;
/**
* Utility to convert an XML file to HTML using an XSLT.
*
* @author Damien Carbonne
*
*/
public final class XmlToHtml {
protected static final Logger LOGGER = LogManager.getLogger(XmlToHtml.class);
private final MainArgs margs;
public static class MainArgs {
/** XML input file (mandatory). */
public URL xml;
/** XSLT transformation file (mandatory). */
public URL xslt;
/** HTML output file or directory (mandatory). */
public File output;
/** Map of parameters (name, value) pairs to be passed to the style sheet. */
public final Map params = new HashMap<>();
}
private XmlToHtml(MainArgs margs) {
Checks.isNotNull(margs, "margs");
Checks.isNotNull(margs.xml, "margs.xml");
Checks.isNotNull(margs.xslt, "margs.xslt");
this.margs = margs;
}
private static class ClasspathURIResolver implements URIResolver {
private static final Logger LOGGER = LogManager.getLogger(ClasspathURIResolver.class);
public ClasspathURIResolver() {
super();
}
private static String decode(String s) {
try {
return URLDecoder.decode(s, "UTF-8");
} catch (final UnsupportedEncodingException e) {
LOGGER.error("decode({}) Failed, {}", s, e.getMessage());
return s;
}
}
@Override
public Source resolve(String href,
String base) throws TransformerException {
LOGGER.trace("resolve({}, {})", href, base);
// If href is absolute, don't need to use base
final URL url = Resources.getResource(decode(href), false);
if (url != null) {
try {
return new StreamSource(url.openStream(), url.toExternalForm());
} catch (final IOException e) {
throw new TransformerException(e);
}
} else if (base != null) {
try {
final URI baseUri = new URI(base);
final URL baseUrl = baseUri.toURL();
if ("file".equals(baseUrl.getProtocol())) {
final File basefile = new File(baseUri);
LOGGER.trace("base file: {}", basefile);
final File basedir = basefile.getParentFile();
final File target = new File(basedir, href);
final URL url2 = Resources.getResource(target.getPath());
Checks.assertTrue(url2 != null, "Failed to find {}", target);
LOGGER.trace("url: {}", url2);
return new StreamSource(url2.openStream(), url2.toExternalForm());
} else if ("jar".equals(baseUrl.getProtocol())) {
final String filename = baseUrl.getPath().substring(baseUrl.getPath().indexOf('!') + 1);
final File basedir = new File(filename).getParentFile();
LOGGER.trace("file: {} {}", filename, basedir);
final File target = new File(basedir, href);
final URL url2 = Resources.getResource(target.getPath());
LOGGER.trace("url: {}", url2);
return new StreamSource(url2.openStream(), url2.toExternalForm());
} else {
throw new TransformerException("Unsupported protocol");
}
} catch (final URISyntaxException | IOException e) {
LOGGER.catching(e);
}
}
return null;
}
}
private void execute() throws Exception {
LOGGER.info("Convert '{}'", margs.xml);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("xslt: {} {}", margs.xslt, margs.xslt.toExternalForm());
}
try (final InputStream xmlInput = margs.xml.openStream();
final InputStream xsltInput = margs.xslt.openStream()) {
// TODO Java 9 use default JDK factory.
// TODO Java 9 final TransformerFactory transformerFactory = TransformerFactory.newDefaultInstance();
final TransformerFactory transformerFactory = TransformerFactory.newInstance();
// Do not enable XMLConstants.FEATURE_SECURE_PROCESSING
// This disables handling of xsl:result-document with saxon,
// unless FeatureKeys.ALLOW_EXTERNAL_FUNCTIONS is enabled
transformerFactory.setURIResolver(new ClasspathURIResolver());
final StreamSource xmlSource = new StreamSource(xmlInput, margs.xml.toExternalForm());
final StreamSource xsltSource = new StreamSource(xsltInput, margs.xslt.toExternalForm());
final Transformer transformer = transformerFactory.newTransformer(xsltSource);
transformer.setOutputProperty(OutputKeys.METHOD, "html");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
for (final Map.Entry entry : margs.params.entrySet()) {
transformer.setParameter(entry.getKey(), entry.getValue());
}
// There is an issue on Window when using StreamResult(File) and file name contains special characters.
final File file = margs.output == null
? File.createTempFile("xmltohtml-", "")
: margs.output;
final Result result;
if (file.isDirectory()) {
result = new StreamResult(file);
} else {
result = new StreamResult(new BufferedOutputStream(new FileOutputStream(file)));
}
result.setSystemId(URLDecoder.decode(file.toURI().toURL().toString(), "UTF-8"));
transformer.transform(xmlSource, result);
LOGGER.info("Conversion done into: {}", result.getSystemId());
} catch (final IOException | TransformerException e) {
LOGGER.catching(e);
throw e;
}
}
public static void execute(MainArgs margs) throws Exception {
final XmlToHtml instance = new XmlToHtml(margs);
instance.execute();
}
public static void main(String[] args) {
final MainSupport support = new MainSupport();
support.main(args);
}
private static class MainSupport extends AbstractMainSupport {
private static final String XML = "xml";
private static final String XSLT = "xslt";
private static final String PARAM = "param";
public MainSupport() {
super(XmlToHtml.class, LOGGER);
}
@Override
protected String getVersion() {
return Config.VERSION;
}
@Override
protected void addSpecificOptions(Options options) {
options.addOption(Option.builder()
.longOpt(XML)
.desc("Name of the XML input .")
.hasArg()
.required()
.build());
options.addOption(Option.builder()
.longOpt(XSLT)
.desc("Name of the containing the XSLT to apply.")
.hasArg()
.required()
.build());
options.addOption(Option.builder()
.longOpt(OUTPUT)
.desc("Name of the HTML to generate.")
.hasArg()
.build());
options.addOption(Option.builder()
.longOpt(PARAM)
.desc("Parameter(s) (name=value) to be passed to the transformation.")
.hasArgs()
.build());
}
private static void addParam(MainArgs margs,
String s) throws ParseException {
final int pos = s.indexOf('=');
if (pos >= 0) {
final String name = s.substring(0, pos);
final String value = pos + 1 < s.length() ? s.substring(pos + 1) : "";
margs.params.put(name, value);
} else {
throw new ParseException("Invalid param '" + s + "'");
}
}
@Override
protected MainArgs analyze(CommandLine cl) throws ParseException {
final MainArgs margs = new MainArgs();
margs.xml = Resources.getResource(cl.getOptionValue(XML));
if (margs.xml == null) {
throw new ParseException("Invalid xml: " + margs.xml);
}
margs.xslt = Resources.getResource(cl.getOptionValue(XSLT));
if (margs.xml == null) {
throw new ParseException("Invalid xslt: " + margs.xslt);
}
if (cl.hasOption(OUTPUT)) {
margs.output = new File(cl.getOptionValue(OUTPUT));
}
if (cl.hasOption(PARAM)) {
for (final String s : cl.getOptionValues(PARAM)) {
addParam(margs, s);
}
}
return margs;
}
@Override
protected Void execute(MainArgs margs) throws Exception {
XmlToHtml.execute(margs);
return null;
}
}
}