X-Git-Url: https://git.argeo.org/?p=gpl%2Fargeo-suite.git;a=blobdiff_plain;f=org.argeo.publishing.ui%2Fsrc%2Forg%2Fargeo%2Fpublishing%2Fservlet%2FDbkServlet.java;fp=org.argeo.publishing.ui%2Fsrc%2Forg%2Fargeo%2Fpublishing%2Fservlet%2FDbkServlet.java;h=0000000000000000000000000000000000000000;hp=e892562bbcfb0f7eb542f3575504ca57a99af015;hb=6e56ffa34cb02ab04d028423aea342e3dfed4358;hpb=c285180bece610b2c2921d44fe14b6dde2123efa diff --git a/org.argeo.publishing.ui/src/org/argeo/publishing/servlet/DbkServlet.java b/org.argeo.publishing.ui/src/org/argeo/publishing/servlet/DbkServlet.java deleted file mode 100644 index e892562..0000000 --- a/org.argeo.publishing.ui/src/org/argeo/publishing/servlet/DbkServlet.java +++ /dev/null @@ -1,225 +0,0 @@ -package org.argeo.publishing.servlet; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import javax.jcr.Node; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.jcr.nodetype.NodeType; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.transform.Result; -import javax.xml.transform.Source; -import javax.xml.transform.Templates; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; -import javax.xml.transform.stream.StreamSource; - -import org.apache.commons.io.IOUtils; -import org.apache.xalan.processor.TransformerFactoryImpl; -import org.argeo.cms.servlet.ServletAuthUtils; -import org.argeo.cms.ui.CmsTheme; -import org.argeo.docbook.DbkType; -import org.argeo.docbook.DbkUtils; -import org.argeo.jcr.Jcr; -import org.argeo.jcr.JcrException; -import org.argeo.jcr.JcrUtils; -import org.w3c.dom.Document; - -/** - * A servlet transforming a dbk:* JCR node into HTML, using the DocBook XSL. - */ -public class DbkServlet extends HttpServlet { - private static final long serialVersionUID = 6906020513498289335L; - - private Repository repository; - - private DocumentBuilderFactory documentBuilderFactory; - private TransformerFactory transformerFactory; - private Templates docBoookTemplates; - - private Map themes = Collections.synchronizedMap(new HashMap<>()); - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - - String pathInfo = req.getPathInfo(); - if (pathInfo.startsWith("//")) - pathInfo = pathInfo.substring(1); - String path = URLDecoder.decode(pathInfo, StandardCharsets.UTF_8); - - if (path.toLowerCase().endsWith(".css")) { - path = path.substring(1); - int firstSlash = path.indexOf('/'); - String themeId = path.substring(0, firstSlash); - String cssPath = path.substring(firstSlash); - CmsTheme cmsTheme = themes.get(themeId); - if (cmsTheme == null) - throw new IllegalArgumentException("Theme " + themeId + " not found."); - resp.setContentType("text/css"); - IOUtils.copy(cmsTheme.getResourceAsStream(cssPath), resp.getOutputStream()); - return; - } - - if (path.toLowerCase().endsWith("/index.html")) { - path = path.substring(0, path.length() - "/index.html".length()); - } - - Session session = null; - try { - session = ServletAuthUtils.doAs(() -> Jcr.login(repository, null), req); - Node node = session.getNode(path); - - if (node.hasNode(DbkType.article.get())) { - Node dbkNode = node.getNode(DbkType.article.get()); - if (DbkUtils.isDbk(dbkNode)) { - CmsTheme cmsTheme = null; - String themeId = req.getParameter("themeId"); - if (themeId != null) { - cmsTheme = themes.get(themeId); - if (cmsTheme == null) - throw new IllegalArgumentException("Theme " + themeId + " not found."); - } - - // TODO customise DocBook so that it outputs UTF-8 - // see http://www.sagehill.net/docbookxsl/OutputEncoding.html - resp.setContentType("text/html; charset=ISO-8859-1"); - - // TODO optimise with pipes, SAX, etc. ? - byte[] arr; - try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { - session.exportDocumentView(dbkNode.getPath(), out, true, false); - arr = out.toByteArray(); -// System.out.println(new String(arr, StandardCharsets.UTF_8)); - } catch (RepositoryException e) { - throw new JcrException(e); - } - - try (InputStream in = new ByteArrayInputStream(arr); -// ByteArrayOutputStream out = new ByteArrayOutputStream(); - ) { - - Result xmlOutput = new StreamResult(resp.getOutputStream()); - - DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder(); -// Document doc = docBuilder.parse(new File( -// System.getProperty("user.home") + "/dev/git/gpl/argeo-qa/doc/platform/argeo-platform.dbk.xml")); - Document doc = docBuilder.parse(in); - Source xmlInput = new DOMSource(doc); - - Transformer transformer = docBoookTemplates.newTransformer(); - - // gather CSS - if (cmsTheme != null) { - StringBuilder sb = new StringBuilder(); - for (String cssPath : cmsTheme.getWebCssPaths()) { - sb.append(req.getContextPath()).append(req.getServletPath()).append('/'); - sb.append(themeId).append('/').append(cssPath).append(' '); - } - // FIXME make it more generic - sb.append("https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap") - .append(' '); - sb.append( - "https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,300;0,400;0,600;1,400&display=swap") - .append(' '); - if (sb.length() > 0) - transformer.setParameter("html.stylesheet", sb.toString()); - } - transformer.transform(xmlInput, xmlOutput); -// resp.getOutputStream().write(out.toByteArray()); - } catch (Exception e) { - throw new ServletException("Cannot transform " + path, e); - } - } - } else { - if (node.isNodeType(NodeType.NT_FILE)) {// media download etc. - String fileNameLowerCase = node.getName().toLowerCase(); - if (fileNameLowerCase.endsWith(".jpg") || fileNameLowerCase.endsWith(".jpeg")) { - resp.setContentType("image/jpeg"); - } else if (fileNameLowerCase.endsWith(".png")) { - resp.setContentType("image/png"); - } else if (fileNameLowerCase.endsWith(".gif")) { - resp.setContentType("image/gif"); - } else if (fileNameLowerCase.endsWith(".svg")) { - resp.setContentType("image/svg+xml"); - } else { - // TODO know more content types... - resp.setHeader("Content-Disposition", "attachment; filename=\"" + node.getName() + "\""); - } - IOUtils.copy(JcrUtils.getFileAsStream(node), resp.getOutputStream()); - } else { - throw new IllegalArgumentException("Unsupported node " + node); - } - } - } catch (RepositoryException e1) { - throw new JcrException(e1); - } finally { - Jcr.logout(session); - } - } - - @Override - public void init() throws ServletException { - - // TODO improve configuration and provisioning of DocBook XSL - String xslBase = System.getProperty("argeo.docbook.xsl"); - if (xslBase == null) { - String defaultXslBase = "/opt/docbook-xsl"; - if (!Files.exists(Paths.get(defaultXslBase))) { - throw new ServletException("System property argeo.docbook.xsl is not set and default location " - + defaultXslBase + " does not exist."); - } else { - xslBase = defaultXslBase; - } - } - String xsl = xslBase + "/html/docbook.xsl"; - - documentBuilderFactory = DocumentBuilderFactory.newInstance(); - documentBuilderFactory.setXIncludeAware(true); - documentBuilderFactory.setNamespaceAware(true); - - // We must explicitly use the non-XSLTC transformer, as XSLTC is not working - // with DocBook stylesheets - transformerFactory = new TransformerFactoryImpl(); - - Source xslSource = new StreamSource(xsl); - try { - docBoookTemplates = transformerFactory.newTemplates(xslSource); - if (docBoookTemplates == null) - throw new ServletException("Could not instantiate XSL " + xsl); - } catch (TransformerConfigurationException e) { - throw new ServletException("Cannot instantiate XSL " + xsl, e); - } - } - - public void setRepository(Repository repository) { - this.repository = repository; - } - - public void addTheme(CmsTheme theme, Map properties) { - themes.put(theme.getThemeId(), theme); - } - - public void removeTheme(CmsTheme theme, Map properties) { - themes.remove(theme.getThemeId()); - } - -}