package com.gmail.dpierron.calibre.opds; /** * This class controls the generation of appropriate HTML files from * the XML documents created during the catalog build process. * * The process uses an XSLT transform on the DOM document. A number * of different transformation variants are possible according to the * document type that is being handled */ import com.gmail.dpierron.calibre.configuration.ConfigurationManager; import com.gmail.dpierron.tools.i18n.Localization; import com.gmail.dpierron.tools.Helper; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jdom2.Document; import org.jdom2.transform.JDOMSource; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.stream.StreamResult; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; public class HtmlManager { public enum FeedType { Catalog, BookFullEntry, MainCatalog } private final static Logger logger = LogManager.getLogger(HtmlManager.class); private static long timeInHtml = 0; public HtmlManager() { timeInHtml = 0; } public long getTimeInHtml() { return timeInHtml; } public static void generateHtmlFromDOM(Document document, File outputFile, FeedType feedType) throws IOException { FileOutputStream fos = null; try { // create the same file as html long now = System.currentTimeMillis(); JDOMSource source = new JDOMSource(document); fos = new FileOutputStream(outputFile); StreamResult streamResult = new StreamResult(fos); try { Transformer transformer = null; switch (feedType) { case MainCatalog: generateIncludedHtml(document, CatalogManager.getGenerateFolder(), Constants.HEADER_XSL); generateIncludedHtml(document, CatalogManager.getGenerateFolder(), Constants.GENERATED_XSL); transformer = JDOMManager.getMainCatalogTransformer(); break; case Catalog: transformer = JDOMManager.getCatalogTransformer(); break; case BookFullEntry: transformer = JDOMManager.getBookFullEntryTransformer(); break; default: assert false : "generateHtmlFromXml: Unknown feed type " + feedType; } if (transformer == null) { logger.fatal("Failed to get transformer: Probably means XSL file invalid and failed to compile!" ); } else { transformer.transform(source, streamResult); } } catch (TransformerException e) { logger.error(Localization.Main.getText("error.cannotTransform", outputFile.getAbsolutePath()), e); } timeInHtml += (System.currentTimeMillis() - now); } finally { if (fos != null) fos.close(); } } /** * This routine is sued to generate files that have no .xml file, but only a .xsl file. * It is used for files included by other html files to avoid repreating the contents; * - header.html * - generated.html */ public static void generateIncludedHtml(Document document, File outputPath, String xslname) throws IOException { if (ConfigurationManager.getCurrentProfile().getGenerateHtml()) { FileOutputStream fos = null; try { JDOMSource source = new JDOMSource(document); File htmlFile = new File(outputPath,getHtmlFilename(xslname)); fos = new FileOutputStream(htmlFile); StreamResult streamResult = new StreamResult(fos); try { Transformer transformer; transformer = JDOMManager.getIncludeTransformer(xslname); transformer.transform(source, streamResult); } catch (TransformerException e) { logger.error(Localization.Main.getText("error.cannotTransform", xslname), e); } } finally { if (fos != null) fos.close(); } } } /** * create the HTML filename. * Handle the case of both no file extension, and existing XML/XSL one. * * @param filename * @return */ public static String getHtmlFilename(String filename) { assert Helper.isNotNullOrEmpty(filename) : "Program error: Attempt to create HTML filename for empty/null filename"; assert ! filename.startsWith(ConfigurationManager.getCurrentProfile().getCatalogFolderName()): "Program Error: Filename should not include catalog folder" ; assert filename.endsWith(Constants.XML_EXTENSION) || filename.endsWith(Constants.XSL_EXTENSION) : "Program Error: Filename '" + filename + "' does not end with " + Constants.XML_EXTENSION + " or " + Constants.XML_EXTENSION; int pos = filename.lastIndexOf(Constants.EXTENSION_SEPARATOR); // if (pos == -1) pos = filename.length(); return filename.substring(0, pos) + Constants.HTML_EXTENSION; } }