WebBox Klassenbibliothek
ulrich
2021-01-28 96dfd62fbfe771616045a253bbeb1415538e815f
commit | author | age
1385d2 1 /*
U 2     WebBox - Dein Server.
3     Copyright (C) 2020 Ulrich Hilger, http://uhilger.de
4
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU Affero General Public License as
7     published by the Free Software Foundation, either version 3 of the
8     License, or (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU Affero General Public License for more details.
14
15     You should have received a copy of the GNU Affero General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 package de.uhilger.wbx.web;
20
21 import java.io.BufferedReader;
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.IOException;
e4ff59 25 import java.io.InputStream;
1385d2 26 import java.io.InputStreamReader;
U 27 import java.io.PrintWriter;
3bbfbc 28 import java.util.HashMap;
1385d2 29 import javax.servlet.ServletException;
U 30 import javax.servlet.http.HttpServlet;
31 import javax.servlet.http.HttpServletRequest;
32 import javax.servlet.http.HttpServletResponse;
33 import java.util.Map;
e4ff59 34 import javax.servlet.ServletOutputStream;
1385d2 35
U 36 import static org.asciidoctor.Asciidoctor.Factory.create;
37 import org.asciidoctor.Asciidoctor;
c5090a 38 import static org.asciidoctor.AttributesBuilder.attributes;
U 39 import static org.asciidoctor.OptionsBuilder.options;
bc2fc2 40 import org.asciidoctor.SafeMode;
1385d2 41
U 42
43
44 /**
45  * Das AdocServlet wandelt AsciiDoc-Inhalte (*.adoc) 
70be19 46  * zu HTML-Seiten und PDF-Dokumenten
d8a1ab 47  * 
d572ec 48  * Mit Angabe des Parameters ?pdf=true im URL wird PDF erzeugt, andernfalls HTML
1385d2 49  */
U 50 public class AdocServlet extends HttpServlet  {
51   
52   private static final String DOT = ".";
3bbfbc 53   private static final String HTML = "html";
70be19 54   private static final String PDF = "pdf";
U 55   private static final String SERVLET_NAME = "AdocServlet";
1385d2 56   
U 57   /**
d572ec 58    * Die Methode processRequest verarbeitet HTTP-Anfragen des Typs  
U 59    * <code>GET</code> und <code>POST</code>.
1385d2 60    *
d572ec 61    * @param request die Servlet-Anfrage
U 62    * @param response die Servlet-Antwort
63    * @throws ServletException wenn ein Servlet-spezifischer Fehler passiert
64    * @throws IOException wenn ein Eingabe- oder Ausgabe-Fehler passiert
1385d2 65    */
U 66   protected void processRequest(HttpServletRequest request, HttpServletResponse response)
67           throws ServletException, IOException 
68   {
69
a22ef6 70     // Asciidoc-Quelldatei aus HTTP-Request ermitteln
U 71     String vPath = request.getServletPath();
72     String absname = getServletContext().getRealPath(vPath);
73     File adocfile = new File(absname);
74
75     // HTML-Datei ermitteln
76     String nameext = adocfile.getName();
77     String fname = nameext.substring(0, nameext.lastIndexOf(DOT));
78     File htmlfile = new File(adocfile.getParentFile(), fname + DOT + HTML);
79     File outfile = htmlfile; // Standardmaessig wird HTML zurueckgegeben
0fa5e7 80     response.setCharacterEncoding("UTF-8");
U 81     
a22ef6 82     /*
U 83       nach HTML transformieren, wenn die Quelle sich geandert hat oder 
84       die HTML-Datei noch nicht existiert
85     */
86     if(!htmlfile.exists() || adocfile.lastModified() > htmlfile.lastModified()) {
87       transform(absname);
88     }
89
90     /*
91       nach PDF transformieren, wenn der Parameter pdf=true existiert und 
92       wenn die Quelle sich geandert hat oder 
93       die PDF-Datei noch nicht existiert
94     */
e4ff59 95     
a22ef6 96     String pdf = request.getParameter(PDF);
U 97     if(null != pdf && pdf.equalsIgnoreCase(Boolean.TRUE.toString())) {
98       File pdffile = new File(adocfile.getParentFile(), fname + DOT + PDF);
99       outfile = pdffile; // PDF soll zurueckgegeben werden
100       if(!pdffile.exists() || adocfile.lastModified() > pdffile.lastModified()) {
f2a703 101         response.setContentType("application/pdf");
a22ef6 102         transform(absname, PDF);
70be19 103       }
e4ff59 104       ServletOutputStream os = response.getOutputStream();
U 105       InputStream bytes = new FileInputStream(outfile);
106       int b = bytes.read();
107       while(b > -1 ) {
108         os.write(b);
109         b = bytes.read();
1385d2 110       }
e4ff59 111     } else {
U 112       PrintWriter out = response.getWriter();
113       InputStreamReader in = new InputStreamReader(new FileInputStream(outfile), "UTF-8");
114       in.transferTo(out);
1385d2 115     }
U 116   }
117   
d572ec 118   /**
U 119    * Nach HTML transformieren
120    * @param fileName der Dateiname der Quelldatei samt absoluter Pfadangabe
121    */
3bbfbc 122   private void transform(String fileName) {
U 123     transform(fileName, null);
1385d2 124   }  
3bbfbc 125   
d572ec 126   /**
U 127    * In ein Format transformieren, das von einem 'Backend' von Asciidoctor 
128    * unterstuetzt wird
129    * @param fileName der Dateiname der Quelldatei samt absoluter Pfadangabe
130    * @param backend das Kuerzel des Backends, z.B. der String 'pdf', wenn 
131    * nach PDF transformiert werden soll
132    */
3bbfbc 133   private void transform(String fileName, String backend) {    
e70523 134     Map<String, Object> attributes;
38929a 135     File outFile = new File(fileName);
f2a703 136     String thisDirName = outFile.getParent();
e70523 137     File pdfStyles = new File(outFile.getParentFile(), "custom-theme.yml");
U 138     if(pdfStyles.exists()) {
139       attributes = attributes()
f2a703 140               .attribute("pdf-themesdir", thisDirName)
e70523 141               .attribute("pdf-theme","custom")
f2a703 142               .attribute("pdf-fontsdir", thisDirName + "/fonts")
U 143               .attribute("allow-uri-read")
e70523 144               .sourceHighlighter("highlightjs")
U 145               .asMap();
146     } else {
147       attributes = attributes()
148               .sourceHighlighter("highlightjs")
149               .asMap();
150     }
7bee9c 151     Map<String, Object> options;
U 152     if(null != backend) {
153       options = options().inPlace(false)
bc2fc2 154               .safe(SafeMode.SERVER)
7bee9c 155               .backend(backend).attributes(attributes).asMap();
U 156       
157     } else {
158       options = options().inPlace(false)
bc2fc2 159               .safe(SafeMode.SERVER)
7bee9c 160               .attributes(attributes).asMap();
U 161     }
3bbfbc 162     
U 163     Asciidoctor asciidoctor = create();    
16c6c6 164     asciidoctor.requireLibrary("asciidoctor-diagram");
3bbfbc 165     asciidoctor.convertFile(new File(fileName), options);    
U 166   }
1385d2 167
U 168   /**
d572ec 169    * Die HTTP-<code>GET</code>-Methode verarbeiten.
1385d2 170    *
d572ec 171    * @param request die Servlet-Anfrage
U 172    * @param response die Servlet-Antwort
173    * @throws ServletException wenn ein Servlet-spezifischer Fehler passiert
174    * @throws IOException wenn ein Eingabe- oder Ausgabe-Fehler passiert
1385d2 175    */
U 176   @Override
177   protected void doGet(HttpServletRequest request, HttpServletResponse response)
178           throws ServletException, IOException {
179     processRequest(request, response);
180   }
181
182   /**
d572ec 183    * Die HTTP-<code>POST</code>-Methode verarbeiten.
1385d2 184    *
d572ec 185    * @param request die Servlet-Anfrage
U 186    * @param response die Servlet-Antwort
187    * @throws ServletException wenn ein Servlet-spezifischer Fehler passiert
188    * @throws IOException wenn ein Eingabe- oder Ausgabe-Fehler passiert
1385d2 189    */
U 190   @Override
191   protected void doPost(HttpServletRequest request, HttpServletResponse response)
192           throws ServletException, IOException {
193     processRequest(request, response);
194   }
195
196   /**
d572ec 197    * Eine Kurzbeschreibung des Servlets ausgeben.
1385d2 198    *
d572ec 199    * @return einen String mit der Kurzbeschreibung des Servlets
1385d2 200    */
U 201   @Override
202   public String getServletInfo() {
70be19 203     return SERVLET_NAME;
U 204   }
1385d2 205
U 206 }