#20 Skriptování: vnořování maker – zadání tabulky nebo diagramu může být generované skriptem.
2 * XML Web generátor – program na generování webových stránek
3 * Copyright © 2012 František Kučera (frantovo.cz)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
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 General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 package cz.frantovo.xmlWebGenerator.makra;
20 import static cz.frantovo.xmlWebGenerator.NástrojeCLI.načtiProud;
21 import static cz.frantovo.xmlWebGenerator.Xmlns.*;
22 import java.io.ByteArrayInputStream;
24 import java.io.PrintStream;
26 import java.util.Collections;
27 import java.util.HashMap;
29 import javax.xml.parsers.DocumentBuilder;
30 import javax.xml.parsers.DocumentBuilderFactory;
31 import javax.xml.transform.Source;
32 import javax.xml.transform.dom.DOMSource;
33 import org.w3c.dom.Document;
34 import org.w3c.dom.Node;
37 * Provedeme skript a do stránky vložíme jeho výstup.
39 * @author František Kučera (frantovo.cz)
41 public class Skriptování {
50 * klíč = jazyk – např. bash
51 * hodnota = interpret – např. /bin/bash
53 private static final Map<String, String> interpreti;
56 Map<String, String> podporovanýJazyk = new HashMap<String, String>();
57 podporovanýJazyk.put("bash", "/bin/bash");
58 podporovanýJazyk.put("perl", "/usr/bin/perl");
59 podporovanýJazyk.put("php", "/usr/bin/php");
60 podporovanýJazyk.put("python", "/usr/bin/python");
61 interpreti = Collections.unmodifiableMap(podporovanýJazyk);
65 * TODO: podporovat i složitější scénáře (např. kompilaci),
66 * než jen vložení do souboru a přidání správného záhlaví.
68 * @param skriptText skript k vykonání
69 * @param skriptSoubor cesta k souboru se skriptem/programem
70 * @param jazyk programovací jazyk
71 * @param výstupníFormát text (výchozí) | xml (v tom případě kontrolujeme validitu)
72 * @param uriStránky URI aktuálně generované stránky → proměnná prostředí
73 * @param nadpisStránky nadpis stránky → proměnná prostředí
74 * @param perexStránky perex stránky → proměnná prostředí
75 * @return výstup příkazu buď jako textový řetězec nebo jako XML (DOMSource)
77 public static Source interpretuj(String skriptText, String skriptSoubor, String jazyk, String výstupníFormát, String uriStránky, String nadpisStránky, String perexStránky) throws Exception {
78 String výstupSkriptu = získejVýstupSkriptu(skriptText, skriptSoubor, jazyk, uriStránky, nadpisStránky, perexStránky);
79 return vyrobXml(výstupSkriptu, zjistiFormát(výstupníFormát));
82 private static String získejVýstupSkriptu(String skriptText, String skriptSoubor, String jazyk, String uriStránky, String nadpisStránky, String perexStránky) throws Exception {
85 if (isNeprázdný(skriptSoubor)) {
86 System.err.println("\tInterpretuji skript ze souboru: " + skriptSoubor);
88 System.err.println("\tInterpretuji skript v jazyce: " + jazyk);
91 File souborStránky = new File(new URI(uriStránky));
94 if (isNeprázdný(skriptText)) {
95 /** Skript je zadán uvnitř elementu přímo ve stránce */
96 String interpret = interpreti.get(jazyk);
97 if (interpret == null) {
98 throw new Exception("Neznámý skriptovací jazyk: " + jazyk);
101 f = File.createTempFile("xml-web-generátor-", ".skript");
103 f.setExecutable(true);
105 PrintStream ps = new PrintStream(f);
107 ps.println(interpret);
109 ps.print(skriptText);
111 } else if (isNeprázdný(skriptSoubor)) {
112 /** Skript/program je uložen v externím souboru */
113 if (skriptSoubor.startsWith(File.separator)) {
114 /** absolutní cesta */
115 f = new File(skriptSoubor);
117 /** relativní cesta */
118 f = new File(souborStránky.getParent(), File.separatorChar + skriptSoubor);
121 if (!f.canExecute()) {
122 throw new Exception("Soubor se skriptem není spustitelný → nastavte: chmod +x " + f);
125 throw new Exception("Musí být vyplněn text skriptu, nebo cesta k souboru.");
129 String[] prostředí = new String[]{
130 "LANG=" + System.getenv("LANG"),
131 "USER=" + System.getenv("USER"),
132 "XWG_SKRIPTOVANI_JAVA=" + "šablona" + File.separator + "funkce" + File.separator + "src" + File.separator + Skriptování.class.getName().replaceAll("\\.", File.separator) + ".java",
133 "XWG_STRANKA_URI=" + uriStránky, // env:URI aktuálně zpracovávané stránky
134 "XWG_STRANKA_SOUBOR=" + souborStránky.getAbsolutePath(), // env:absolutní cesta k souboru
135 "XWG_STRANKA_NADPIS=" + nadpisStránky, // env:nadpis stránky
136 "XWG_STRANKA_PEREX=" + perexStránky // env:perex stránky
139 Runtime r = Runtime.getRuntime();
140 Process p = r.exec(new String[]{f.getAbsolutePath()}, prostředí);
142 String výsledek = načtiProud(p.getInputStream());
143 String chyby = načtiProud(p.getErrorStream());
147 if (p.exitValue() == 0) {
148 if (chyby.length() > 0) {
149 System.err.println("--- Chybový výstup skriptu -----");
150 System.err.println(chyby);
151 System.err.println("--------------------------------");
152 System.err.println("Nicméně skript skončil úspěšně, takže pokračujeme dál.");
155 return výsledek.trim();
157 System.err.println("--- Standardní výstup skriptu: -----");
158 System.err.println(výsledek);
159 System.err.println("--- Cyhbový výstup skriptu: ---------");
160 System.err.println(chyby);
161 System.err.println("--------------------------------------");
162 throw new Exception("Návratová hodnota: " + p.exitValue());
164 } catch (Exception e) {
165 System.err.println("Došlo k chybě při vykonávání skriptu.");
166 System.err.println("--------");
167 System.err.println(skriptText);
168 System.err.println("--------");
169 e.printStackTrace(System.err);
174 private static boolean isNeprázdný(String s) {
175 return !(s == null || s.trim().isEmpty());
178 private static FORMÁT zjistiFormát(String výstupníFormát) {
180 return FORMÁT.valueOf(výstupníFormát);
181 } catch (NullPointerException e) {
183 } catch (IllegalArgumentException e) {
189 * @param zadání výstup vygenerovaný skriptem
190 * @param xmlFormát formát zadání: true = xml fragment | false = prostý text
191 * @return xml fragment nebo prostý text zabalený do html/body
194 private static Source vyrobXml(String zadání, FORMÁT formát) throws Exception {
195 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
196 DocumentBuilder db = dbf.newDocumentBuilder();
200 if (formát == FORMÁT.text) {
201 d = db.newDocument();
202 Node html = d.createElementNS(XHTML, "html");
203 Node body = d.createElementNS(XHTML, "body");
204 Node text = d.createTextNode(zadání);
205 body.appendChild(text);
206 html.appendChild(body);
209 if (formát == FORMÁT.xhtml) {
210 zadání = "<html xmlns='" + XHTML + "' xmlns:m='" + MAKRO + "'><body>" + zadání + "</body></html>";
213 d = db.parse(new ByteArrayInputStream(zadání.getBytes()));
214 } catch (Exception e) {
215 System.err.println("Chyba: Skript vrátil neplatné XML.");
220 return new DOMSource(d);