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