#20 Skriptování: Makra ve skriptech a Skripty v makrech + výpis verzí z Mercurialu.
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í {
44 * klíč = jazyk – např. bash
45 * hodnota = interpret – např. /bin/bash
47 private static final Map<String, String> interpreti;
50 Map<String, String> podporovanýJazyk = new HashMap<String, String>();
51 podporovanýJazyk.put("bash", "/bin/bash");
52 podporovanýJazyk.put("perl", "/usr/bin/perl");
53 podporovanýJazyk.put("php", "/usr/bin/php");
54 podporovanýJazyk.put("python", "/usr/bin/python");
55 interpreti = Collections.unmodifiableMap(podporovanýJazyk);
59 * TODO: podporovat i složitější scénáře (např. kompilaci),
60 * než jen vložení do souboru a přidání správného záhlaví.
62 * @param skriptText skript k vykonání
63 * @param skriptSoubor cesta k souboru se skriptem/programem
64 * @param jazyk programovací jazyk
65 * @param výstupníFormát text (výchozí) | xml (v tom případě kontrolujeme validitu)
66 * @param uriStránky URI aktuálně generované stránky → proměnná prostředí
67 * @param nadpisStránky nadpis stránky → proměnná prostředí
68 * @param perexStránky perex stránky → proměnná prostředí
69 * @return výstup příkazu buď jako textový řetězec nebo jako XML (DOMSource)
71 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 {
72 String výstupSkriptu = získejVýstupSkriptu(skriptText, skriptSoubor, jazyk, uriStránky, nadpisStránky, perexStránky);
73 return vyrobXml(výstupSkriptu, "xml".equals(výstupníFormát));
76 private static String získejVýstupSkriptu(String skriptText, String skriptSoubor, String jazyk, String uriStránky, String nadpisStránky, String perexStránky) throws Exception {
79 if (isNeprázdný(skriptSoubor)) {
80 System.err.println("\tInterpretuji skript ze souboru: " + skriptSoubor);
82 System.err.println("\tInterpretuji skript v jazyce: " + jazyk);
85 File souborStránky = new File(new URI(uriStránky));
88 if (isNeprázdný(skriptText)) {
89 /** Skript je zadán uvnitř elementu přímo ve stránce */
90 String interpret = interpreti.get(jazyk);
91 if (interpret == null) {
92 throw new Exception("Neznámý skriptovací jazyk: " + jazyk);
95 f = File.createTempFile("xml-web-generátor-", ".skript");
97 f.setExecutable(true);
99 PrintStream ps = new PrintStream(f);
101 ps.println(interpret);
103 ps.print(skriptText);
105 } else if (isNeprázdný(skriptSoubor)) {
106 /** Skript/program je uložen v externím souboru */
107 if (skriptSoubor.startsWith(File.separator)) {
108 /** absolutní cesta */
109 f = new File(skriptSoubor);
111 /** relativní cesta */
112 f = new File(souborStránky.getParent(), File.separatorChar + skriptSoubor);
115 if (!f.canExecute()) {
116 throw new Exception("Soubor se skriptem není spustitelný → nastavte: chmod +x " + f);
119 throw new Exception("Musí být vyplněn text skriptu, nebo cesta k souboru.");
123 String[] prostředí = new String[]{
124 "LANG=" + System.getenv("LANG"),
125 "USER=" + System.getenv("USER"),
126 "XWG_SKRIPTOVANI_JAVA=" + "šablona" + File.separator + "funkce" + File.separator + "src" + File.separator + Skriptování.class.getName().replaceAll("\\.", File.separator) + ".java",
127 "XWG_STRANKA_URI=" + uriStránky, // env:URI aktuálně zpracovávané stránky
128 "XWG_STRANKA_SOUBOR=" + souborStránky.getAbsolutePath(), // env:absolutní cesta k souboru
129 "XWG_STRANKA_NADPIS=" + nadpisStránky, // env:nadpis stránky
130 "XWG_STRANKA_PEREX=" + perexStránky // env:perex stránky
133 Runtime r = Runtime.getRuntime();
134 Process p = r.exec(new String[]{f.getAbsolutePath()}, prostředí);
136 String výsledek = načtiProud(p.getInputStream());
137 String chyby = načtiProud(p.getErrorStream());
141 if (p.exitValue() == 0) {
142 if (chyby.length() > 0) {
143 System.err.println("--- Chybový výstup skriptu -----");
144 System.err.println(chyby);
145 System.err.println("--------------------------------");
146 System.err.println("Nicméně skript skončil úspěšně, takže pokračujeme dál.");
149 return výsledek.trim();
151 System.err.println("--- Standardní výstup skriptu: -----");
152 System.err.println(výsledek);
153 System.err.println("--- Cyhbový výstup skriptu: ---------");
154 System.err.println(chyby);
155 System.err.println("--------------------------------------");
156 throw new Exception("Návratová hodnota: " + p.exitValue());
158 } catch (Exception e) {
159 System.err.println("Došlo k chybě při vykonávání skriptu.");
160 System.err.println("--------");
161 System.err.println(skriptText);
162 System.err.println("--------");
163 e.printStackTrace(System.err);
168 private static boolean isNeprázdný(String s) {
169 return !(s == null || s.trim().isEmpty());
173 * @param zadání výstup vygenerovaný skriptem
174 * @param xmlFormát formát zadání: true = xml fragment | false = prostý text
175 * @return xml fragment nebo prostý text zabalený do html/body
178 private static Source vyrobXml(String zadání, boolean xmlFormát) throws Exception {
179 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
180 DocumentBuilder db = dbf.newDocumentBuilder();
185 zadání = "<html xmlns='" + XHTML + "' xmlns:m='" + MAKRO + "'><body>" + zadání + "</body></html>";
186 d = db.parse(new ByteArrayInputStream(zadání.getBytes()));
187 } catch (Exception e) {
188 System.err.println("Chyba: Skript vrátil neplatné XML.");
192 d = db.newDocument();
193 Node html = d.createElementNS(XHTML, "html");
194 Node body = d.createElementNS(XHTML, "body");
195 Node text = d.createTextNode(zadání);
196 body.appendChild(text);
197 html.appendChild(body);
201 return new DOMSource(d);