Changeset 95:eea9c4713045
- Timestamp:
- 06/23/12 19:22:21 (13 years ago)
- Author:
- František Kučera <franta-hg@…>
- Branch:
- default
- Message:
-
#20 Skriptování: podpora výstupu ve formátu XML (musí být validní)
- Files:
-
Legend:
- Unmodified
- Added
- Removed
-
|
r94
|
r95
|
|
| 9 | 9 | <p> |
| 10 | 10 | Na stránkách můžeme používat skripty. |
| 11 | | Spouští se při generování a jejich standardní výstup se vloží do stránky. |
| 12 | | Třeba doprostřed ostavce nebo do jiného elementu. |
| | 11 | Spouští se při generování a jejich standardní výstup se vloží do stránky. |
| | 12 | Třeba doprostřed textu ostavce nebo do jiného elementu. |
| 13 | 13 | </p> |
| 14 | 14 | <p> |
| 15 | 15 | Příklad: |
| 16 | | Tyto stránky byly vygenerované v systému <m:skript jazyk="bash">uname -o</m:skript>. |
| | 16 | <em> |
| | 17 | Tyto stránky byly vygenerované v systému |
| | 18 | <span title="tento text pochází ze skriptu"><m:skript jazyk="bash">uname -o</m:skript></span>. |
| | 19 | </em> |
| | 20 | </p> |
| | 21 | |
| | 22 | <p> |
| | 23 | Díky skriptování můžeme stránky obohatit o prakticky libovolný obsah. |
| | 24 | Tato funkce ale může být nebezpečná – pokud byste spustili generátor na stránkách, |
| | 25 | které psal někdo nedůvěryhodný a vložil do nich škodlivý kód. |
| | 26 | Proto je skriptování ve výchozím stavu vypnuté – je potřeba ho povolit v souboru <code>web.conf</code>. |
| | 27 | </p> |
| | 28 | |
| | 29 | <h2>Podporované jazyky</h2> |
| | 30 | <p> |
| | 31 | V současnosti jsou podporované tyto jazyky: |
| 17 | 32 | </p> |
| 18 | 33 | |
| 19 | | <p> |
| 20 | | V současnosti jsou podporované tyto jazyky: |
| 21 | | </p> |
| 22 | | |
| 23 | | <pre><m:skript jazyk="perl"><![CDATA[ |
| | 34 | <table> |
| | 35 | <thead> |
| | 36 | <tr> |
| | 37 | <td>Jazyk</td> |
| | 38 | <td>Interpret</td> |
| | 39 | </tr> |
| | 40 | </thead> |
| | 41 | <tbody> |
| | 42 | <m:skript jazyk="perl" výstup="xml"><![CDATA[ |
| 24 | 43 | use strict; |
| 25 | 44 | |
| 26 | | open(JAVA, "<", "šablona/funkce/src/cz/frantovo/xmlWebGenerator/makra/Skriptování.java") or die $!; |
| | 45 | open(JAVA, "<", $ENV{"XWG_SKRIPTOVANI_JAVA"}) or die $!; |
| 27 | 46 | |
| 28 | 47 | while (<JAVA>) { |
| 29 | 48 | #i.put("bash", "/bin/bash"); |
| 30 | 49 | if (/podporovanýJazyk\.put\("(\w+)",\s*"(.*)"\);/) { |
| 31 | | print "$1\n"; |
| | 50 | print "<tr><td><code>$1</code></td><td><code>$2</code></td></tr>\n"; |
| 32 | 51 | } |
| 33 | 52 | } |
| 34 | | ]]></m:skript></pre> |
| | 53 | ]]></m:skript> |
| | 54 | </tbody> |
| | 55 | </table> |
| 35 | 56 | |
| 36 | 57 | <h2>Perl</h2> |
| … |
… |
|
| 77 | 98 | </p> |
| 78 | 99 | |
| 79 | | <ul> |
| 80 | | <li><code>XWG_STRANKA_URI</code> – URI aktuálně zpracovávané stránky</li> |
| 81 | | <li><code>XWG_STRANKA_SOUBOR</code> – absolutní cesta k souboru</li> |
| 82 | | <li><code>XWG_STRANKA_NADPIS</code> – nadpis stránky</li> |
| 83 | | <li><code>XWG_STRANKA_PEREX</code> – perex stránky</li> |
| 84 | | </ul> |
| | 100 | <table> |
| | 101 | <thead> |
| | 102 | <tr> |
| | 103 | <td>Proměnná</td> |
| | 104 | <td>Význam</td> |
| | 105 | </tr> |
| | 106 | </thead> |
| | 107 | <tbody> |
| | 108 | <m:skript jazyk="perl" výstup="xml"><![CDATA[ |
| | 109 | use strict; |
| | 110 | |
| | 111 | open(JAVA, "<", $ENV{"XWG_SKRIPTOVANI_JAVA"}) or die $!; |
| | 112 | |
| | 113 | while (<JAVA>) { |
| | 114 | #i.put("bash", "/bin/bash"); |
| | 115 | if (/"(.*)=".*\/\/\s+env:(.*)/) { |
| | 116 | print "<tr><td><code>$1</code></td><td>$2</td></tr>\n"; |
| | 117 | } |
| | 118 | } |
| | 119 | ]]></m:skript> |
| | 120 | </tbody> |
| | 121 | </table> |
| 85 | 122 | |
| 86 | 123 | <p> |
-
|
r94
|
r95
|
|
| 19 | 19 | |
| 20 | 20 | import static cz.frantovo.xmlWebGenerator.NástrojeCLI.načtiProud; |
| | 21 | import java.io.ByteArrayInputStream; |
| 21 | 22 | import java.io.File; |
| 22 | 23 | import java.io.PrintStream; |
| … |
… |
|
| 25 | 26 | import java.util.HashMap; |
| 26 | 27 | import java.util.Map; |
| | 28 | import javax.xml.parsers.DocumentBuilder; |
| | 29 | import javax.xml.parsers.DocumentBuilderFactory; |
| | 30 | import org.w3c.dom.Document; |
| 27 | 31 | |
| 28 | 32 | /** |
| … |
… |
|
| 54 | 58 | * @param skript program k vykonání |
| 55 | 59 | * @param jazyk programovací jazyk |
| | 60 | * @param výstupníFormát text (výchozí) | xml (v tom případě kontrolujeme validitu) |
| 56 | 61 | * @param uriStránky URI aktuálně generované stránky → proměnná prostředí |
| 57 | 62 | * @param nadpisStránky nadpis stránky → proměnná prostředí |
| … |
… |
|
| 59 | 64 | * @return výstup příkazu |
| 60 | 65 | */ |
| 61 | | public static String interpretuj(String skript, String jazyk, String uriStránky, String nadpisStránky, String perexStránky) { |
| | 66 | public static String interpretuj(String skript, String jazyk, String výstupníFormát, String uriStránky, String nadpisStránky, String perexStránky) { |
| 62 | 67 | try { |
| 63 | 68 | System.err.println("\tInterpretuji skript v jazyce: " + jazyk); |
| … |
… |
|
| 77 | 82 | ps.close(); |
| 78 | 83 | |
| 79 | | f.setExecutable(true); |
| 80 | 84 | |
| 81 | 85 | String[] prostředí = new String[]{ |
| 82 | 86 | "LANG=" + System.getenv("LANG"), |
| 83 | 87 | "USER=" + System.getenv("USER"), |
| 84 | | "XWG_STRANKA_URI=" + uriStránky, |
| 85 | | "XWG_STRANKA_SOUBOR=" + (new File(new URI(uriStránky)).getAbsolutePath()), |
| 86 | | "XWG_STRANKA_NADPIS=" + nadpisStránky, |
| 87 | | "XWG_STRANKA_PEREX=" + perexStránky |
| | 88 | "XWG_SKRIPTOVANI_JAVA=" + "šablona" + File.separator + "funkce" + File.separator + "src" + File.separator + Skriptování.class.getName().replaceAll("\\.", File.separator) + ".java", |
| | 89 | "XWG_STRANKA_URI=" + uriStránky, // env:URI aktuálně zpracovávané stránky |
| | 90 | "XWG_STRANKA_SOUBOR=" + (new File(new URI(uriStránky)).getAbsolutePath()), // env:absolutní cesta k souboru |
| | 91 | "XWG_STRANKA_NADPIS=" + nadpisStránky, // env:nadpis stránky |
| | 92 | "XWG_STRANKA_PEREX=" + perexStránky // env:perex stránky |
| 88 | 93 | }; |
| 89 | 94 | |
| 90 | 95 | |
| 91 | 96 | |
| | 97 | f.setExecutable(true); |
| 92 | 98 | Runtime r = Runtime.getRuntime(); |
| 93 | 99 | Process p = r.exec(new String[]{f.getAbsolutePath()}, prostředí); |
| … |
… |
|
| 98 | 104 | p.waitFor(); |
| 99 | 105 | |
| 100 | | /** |
| 101 | | * TODO: podporovat zvláštní návratový kód, kterým skript řekne, |
| 102 | | * že výstupem je XML a má se vložit jako fragment do dokumentu, |
| 103 | | * ne jako prostý text. |
| 104 | | */ |
| 105 | 106 | if (p.exitValue() == 0) { |
| 106 | 107 | if (chyby.length() > 0) { |
| 107 | | System.err.println("--- Cyhbový výstup skriptu -----"); |
| | 108 | System.err.println("--- Chybový výstup skriptu -----"); |
| 108 | 109 | System.err.println(chyby); |
| 109 | 110 | System.err.println("--------------------------------"); |
| | 111 | System.err.println("Nicméně skript skončil úspěšně, takže pokračujeme dál."); |
| 110 | 112 | } |
| 111 | 113 | |
| 112 | | return výsledek.trim(); |
| | 114 | return připravVýstup(výsledek, výstupníFormát); |
| 113 | 115 | } else { |
| 114 | 116 | System.err.println("--- Standardní výstup skriptu: -----"); |
| … |
… |
|
| 129 | 131 | } |
| 130 | 132 | } |
| | 133 | |
| | 134 | private static String připravVýstup(String výsledek, String formát) { |
| | 135 | if ("xml".equals(formát)) { |
| | 136 | if (zkontrolujXml(výsledek)) { |
| | 137 | return výsledek.trim(); |
| | 138 | } else { |
| | 139 | System.err.println("Chyba v XML generovaném skriptem:"); |
| | 140 | System.err.println(výsledek); |
| | 141 | return null; |
| | 142 | } |
| | 143 | } else { |
| | 144 | return výsledek.trim(); |
| | 145 | } |
| | 146 | } |
| | 147 | |
| | 148 | /** |
| | 149 | * @param xml fragment XML vygenerovaný skriptem |
| | 150 | * @return true v případě, že výstup je validním fragmentem XML |
| | 151 | */ |
| | 152 | private static boolean zkontrolujXml(String xml) { |
| | 153 | try { |
| | 154 | DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); |
| | 155 | DocumentBuilder db = dbf.newDocumentBuilder(); |
| | 156 | xml = "<xml>" + xml + "</xml>"; |
| | 157 | Document d = db.parse(new ByteArrayInputStream(xml.getBytes())); |
| | 158 | return true; |
| | 159 | } catch (Exception e) { |
| | 160 | e.printStackTrace(System.err); |
| | 161 | return false; |
| | 162 | } |
| | 163 | } |
| 131 | 164 | } |
-
|
r94
|
r95
|
|
| 31 | 31 | * |
| 32 | 32 | @jazyk programovací jazyk, např. bash, perl, php |
| | 33 | @výstup formát výstupu skriptu: text (výchozí) | xml (musí být validním fragmentem XML) |
| 33 | 34 | @src skript uložený v souboru místo v těle elementu |
| 34 | 35 | --> |
| … |
… |
|
| 40 | 41 | - podpora vkládání fragmentů XML, ne jen prostého textu |
| 41 | 42 | --> |
| 42 | | <xsl:value-of select="j:interpretuj(text(), @jazyk, document-uri(/), //s:stránka/s:nadpis/text(), //s:stránka/s:perex/text())"/> |
| | 43 | |
| | 44 | <xsl:variable name="výstupSkriptu" select="j:interpretuj( |
| | 45 | text(), |
| | 46 | @jazyk, |
| | 47 | @výstup, |
| | 48 | document-uri(/), |
| | 49 | //s:stránka/s:nadpis/text(), |
| | 50 | //s:stránka/s:perex/text() |
| | 51 | )"/> |
| | 52 | <xsl:choose> |
| | 53 | <xsl:when test="$výstupSkriptu"> |
| | 54 | <xsl:choose> |
| | 55 | <xsl:when test="@výstup = 'xml'"><xsl:value-of select="$výstupSkriptu" disable-output-escaping="yes"/></xsl:when> |
| | 56 | <xsl:otherwise><xsl:value-of select="$výstupSkriptu"/></xsl:otherwise> |
| | 57 | </xsl:choose> |
| | 58 | </xsl:when> |
| | 59 | <xsl:otherwise> |
| | 60 | <xsl:message terminate="yes">Při interpretaci skriptu došlo k chybě.</xsl:message> |
| | 61 | </xsl:otherwise> |
| | 62 | </xsl:choose> |
| | 63 | |
| | 64 | |
| 43 | 65 | </xsl:template> |
| 44 | 66 | |