diff -r 0efefbf5f8b6 -r 40b7aa9126d0 java/nekurak.net-ejb/src/java/cz/frantovo/nekurak/ext/WikiSyntaxProcesor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java/nekurak.net-ejb/src/java/cz/frantovo/nekurak/ext/WikiSyntaxProcesor.java Mon Nov 07 20:31:44 2011 +0100 @@ -0,0 +1,130 @@ +package cz.frantovo.nekurak.ext; + +import cz.frantovo.nekurak.dto.Komentar; +import cz.frantovo.nekurak.vyjimky.WikiSyntaxVyjimka; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintStream; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Neprovádí vlastní interpretaci wiki syntaxe syntaxe, ale volá HTTP službu napsanou v PHP nebo samostatný proces v systému. + * TODO: použít webové služby, nebo něco lepšího než ruční práci s URL. + * @author fiki + */ +public class WikiSyntaxProcesor { + + /** TODO: parametrizovatelnost */ + private static final String URL_SLUZBY = "http://nekurak.net/texy/http/"; + private static final String KODOVANI = "UTF-8"; + private static final Logger log = Logger.getLogger(WikiSyntaxProcesor.class.getSimpleName()); + private String[] markdownPříkaz = new String[]{"sudo", "-u", "markdown", "/usr/bin/markdown"}; + + public String převeď(String text, Komentar.TYP syntaxe) throws WikiSyntaxVyjimka { + switch (syntaxe) { + case MARKDOWN: + return převeďMarkdown(text); + case TEXY: + return převeďTexy(text); + default: + throw new WikiSyntaxVyjimka("Nepodporovaná wiki syntaxe.", null); + } + } + + private String převeďMarkdown(String text) throws WikiSyntaxVyjimka { + try { + Runtime r = Runtime.getRuntime(); + Process p = r.exec(markdownPříkaz); + + PrintStream processInput = new PrintStream(p.getOutputStream()); + processInput.print(text); + processInput.close(); + + String errors = načtiProud(p.getErrorStream()); + String htmlFragment = načtiProud(p.getInputStream()); + + if (errors.length() == 0) { + return htmlFragment; + } else { + throw new WikiSyntaxVyjimka("Markdown procesor vrátil chyby: " + errors, null); + } + } catch (Exception e) { + throw new WikiSyntaxVyjimka("Chyba při transformaci Markdown → XHTML", e); + } + } + + private String převeďTexy(String text) throws WikiSyntaxVyjimka { + OutputStreamWriter wr = null; + BufferedReader rd = null; + try { + URL url = new URL(URL_SLUZBY); + URLConnection spojeni = url.openConnection(); + spojeni.setDoOutput(true); + + /** Odešleme data */ + wr = new OutputStreamWriter(spojeni.getOutputStream()); + wr.write(URLEncoder.encode(text, KODOVANI)); + wr.flush(); + + /** Přijmeme odpověď */ + rd = new BufferedReader(new InputStreamReader(spojeni.getInputStream(), KODOVANI)); + StringBuilder vysledek = new StringBuilder(); + String radka; + while ((radka = rd.readLine()) != null) { + vysledek.append(radka); + } + + return vysledek.toString(); + } catch (Exception e) { + throw new WikiSyntaxVyjimka("Chyba při zpracovávání textu: " + text, e); + } finally { + try { + wr.close(); + } catch (IOException e) { + log.log(Level.WARNING, "Selhalo zavírání OutputStreamWriteru", e); + } + try { + rd.close(); + } catch (IOException e) { + log.log(Level.WARNING, "Selhalo zavírání BufferedReaderu", e); + } + } + } + + /** + * Čte proud dat dokud to jde a výsledek pak vrátí jako text. + * @param proud vstupní proud + * @return obsah proudu jako text + * @throws IOException + */ + public static String načtiProud(InputStream proud) throws IOException { + StringBuilder výsledek = new StringBuilder(); + BufferedReader buf = new BufferedReader(new InputStreamReader(proud)); + while (true) { + String radek = buf.readLine(); + if (radek == null) { + break; + } else { + výsledek.append(radek); + výsledek.append("\n"); + } + } + return výsledek.toString(); + } + + /** + * Můžeme nastavit vlastní příkaz pro transformaci Markdown syntaxe. + * Ve výchozím nastavení se Markdown procesor volá přes sudo pod uživatelem markdown. + * @param markdownPříkaz první je příkaz, následují případné parametry + */ + public void setMarkdownPříkaz(String[] markdownPříkaz) { + this.markdownPříkaz = markdownPříkaz; + } +}