root/šablona/funkce/src/cz/frantovo/xmlWebGenerator/makra/Skriptování.java @ 107:379a2a893fd1

Revision 107:379a2a893fd1, 7.4 KB (checked in by František Kučera <franta-hg@…>, 12 years ago)

#20 Skriptování: Makra ve skriptech a Skripty v makrech + výpis verzí z Mercurialu.

Line 
1/**
2 * XML Web generátor – program na generování webových stránek
3 * Copyright © 2012 František Kučera (frantovo.cz)
4 *
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.
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 General Public License for more details.
14 *
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/>.
17 */
18package cz.frantovo.xmlWebGenerator.makra;
19
20import static cz.frantovo.xmlWebGenerator.NástrojeCLI.načtiProud;
21import static cz.frantovo.xmlWebGenerator.Xmlns.*;
22import java.io.ByteArrayInputStream;
23import java.io.File;
24import java.io.PrintStream;
25import java.net.URI;
26import java.util.Collections;
27import java.util.HashMap;
28import java.util.Map;
29import javax.xml.parsers.DocumentBuilder;
30import javax.xml.parsers.DocumentBuilderFactory;
31import javax.xml.transform.Source;
32import javax.xml.transform.dom.DOMSource;
33import org.w3c.dom.Document;
34import org.w3c.dom.Node;
35
36/**
37 * Provedeme skript a do stránky vložíme jeho výstup.
38 *
39 * @author František Kučera (frantovo.cz)
40 */
41public class Skriptování {
42
43        /**
44         * klíč = jazyk – např. bash
45         * hodnota = interpret – např. /bin/bash
46         */
47        private static final Map<String, String> interpreti;
48
49        static {
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);
56        }
57
58        /**
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í.
61         *
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)
70         */
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));
74        }
75
76        private static String získejVýstupSkriptu(String skriptText, String skriptSoubor, String jazyk, String uriStránky, String nadpisStránky, String perexStránky) throws Exception {
77
78                try {
79                        if (isNeprázdný(skriptSoubor)) {
80                                System.err.println("\tInterpretuji skript ze souboru: " + skriptSoubor);
81                        } else {
82                                System.err.println("\tInterpretuji skript v jazyce:   " + jazyk);
83                        }
84
85                        File souborStránky = new File(new URI(uriStránky));
86                        File f;
87
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);
93                                }
94
95                                f = File.createTempFile("xml-web-generátor-", ".skript");
96                                f.deleteOnExit();
97                                f.setExecutable(true);
98
99                                PrintStream ps = new PrintStream(f);
100                                ps.print("#!");
101                                ps.println(interpret);
102                                ps.println();
103                                ps.print(skriptText);
104                                ps.close();
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);
110                                } else {
111                                        /** relativní cesta */
112                                        f = new File(souborStránky.getParent(), File.separatorChar + skriptSoubor);
113                                }
114
115                                if (!f.canExecute()) {
116                                        throw new Exception("Soubor se skriptem není spustitelný → nastavte: chmod +x " + f);
117                                }
118                        } else {
119                                throw new Exception("Musí být vyplněn text skriptu, nebo cesta k souboru.");
120                        }
121
122
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
131                        };
132
133                        Runtime r = Runtime.getRuntime();
134                        Process p = r.exec(new String[]{f.getAbsolutePath()}, prostředí);
135
136                        String výsledek = načtiProud(p.getInputStream());
137                        String chyby = načtiProud(p.getErrorStream());
138
139                        p.waitFor();
140
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.");
147                                }
148
149                                return výsledek.trim();
150                        } else {
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());
157                        }
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);
164                        throw e;
165                }
166        }
167
168        private static boolean isNeprázdný(String s) {
169                return !(s == null || s.trim().isEmpty());
170        }
171
172        /**
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
176         * @throws Exception
177         */
178        private static Source vyrobXml(String zadání, boolean xmlFormát) throws Exception {
179                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
180                DocumentBuilder db = dbf.newDocumentBuilder();
181                Document d;
182
183                if (xmlFormát) {
184                        try {
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.");
189                                throw e;
190                        }
191                } else {
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);
198                        d.appendChild(html);
199                }
200
201                return new DOMSource(d);
202        }
203}
Note: See TracBrowser for help on using the browser.