java/nekurak.net-ejb/src/java/cz/frantovo/nekurak/ext/WikiSyntaxProcesor.java
author František Kučera <franta-hg@frantovo.cz>
Thu Feb 09 12:23:09 2012 +0100 (2012-02-09)
changeset 202 8d141ea76a2d
parent 197 40b7aa9126d0
permissions -rw-r--r--
Texy syntaxe: oprava chyby – ztrácely se konce řádků (problém u elementů s atributy).
     1 package cz.frantovo.nekurak.ext;
     2 
     3 import cz.frantovo.nekurak.dto.Komentar;
     4 import cz.frantovo.nekurak.vyjimky.WikiSyntaxVyjimka;
     5 import java.io.BufferedReader;
     6 import java.io.IOException;
     7 import java.io.InputStream;
     8 import java.io.InputStreamReader;
     9 import java.io.OutputStreamWriter;
    10 import java.io.PrintStream;
    11 import java.net.URL;
    12 import java.net.URLConnection;
    13 import java.net.URLEncoder;
    14 import java.util.logging.Level;
    15 import java.util.logging.Logger;
    16 
    17 /**
    18  * Neprovádí vlastní interpretaci wiki syntaxe syntaxe, ale volá HTTP službu napsanou v PHP nebo samostatný proces v systému.
    19  * TODO: použít webové služby, nebo něco lepšího než ruční práci s URL.
    20  * @author fiki
    21  */
    22 public class WikiSyntaxProcesor {
    23 
    24 	/** TODO: parametrizovatelnost */
    25 	private static final String URL_SLUZBY = "http://nekurak.net/texy/http/";
    26 	private static final String KODOVANI = "UTF-8";
    27 	private static final Logger log = Logger.getLogger(WikiSyntaxProcesor.class.getSimpleName());
    28 	private String[] markdownPříkaz = new String[]{"sudo", "-u", "markdown", "/usr/bin/markdown"};
    29 
    30 	public String převeď(String text, Komentar.TYP syntaxe) throws WikiSyntaxVyjimka {
    31 		switch (syntaxe) {
    32 			case MARKDOWN:
    33 				return převeďMarkdown(text);
    34 			case TEXY:
    35 				return převeďTexy(text);
    36 			default:
    37 				throw new WikiSyntaxVyjimka("Nepodporovaná wiki syntaxe.", null);
    38 		}
    39 	}
    40 
    41 	private String převeďMarkdown(String text) throws WikiSyntaxVyjimka {
    42 		try {
    43 			Runtime r = Runtime.getRuntime();
    44 			Process p = r.exec(markdownPříkaz);
    45 
    46 			PrintStream processInput = new PrintStream(p.getOutputStream());
    47 			processInput.print(text);
    48 			processInput.close();
    49 
    50 			String errors = načtiProud(p.getErrorStream());
    51 			String htmlFragment = načtiProud(p.getInputStream());
    52 
    53 			if (errors.length() == 0) {
    54 				return htmlFragment;
    55 			} else {
    56 				throw new WikiSyntaxVyjimka("Markdown procesor vrátil chyby: " + errors, null);
    57 			}
    58 		} catch (Exception e) {
    59 			throw new WikiSyntaxVyjimka("Chyba při transformaci Markdown → XHTML", e);
    60 		}
    61 	}
    62 
    63 	private String převeďTexy(String text) throws WikiSyntaxVyjimka {
    64 		OutputStreamWriter wr = null;
    65 		BufferedReader rd = null;
    66 		try {
    67 			URL url = new URL(URL_SLUZBY);
    68 			URLConnection spojeni = url.openConnection();
    69 			spojeni.setDoOutput(true);
    70 
    71 			/** Odešleme data */
    72 			wr = new OutputStreamWriter(spojeni.getOutputStream());
    73 			wr.write(URLEncoder.encode(text, KODOVANI));
    74 			wr.flush();
    75 
    76 			/** Přijmeme odpověď */
    77 			rd = new BufferedReader(new InputStreamReader(spojeni.getInputStream(), KODOVANI));
    78 			StringBuilder vysledek = new StringBuilder();
    79 			String radka;
    80 			while ((radka = rd.readLine()) != null) {
    81 				vysledek.append(radka);
    82 				vysledek.append("\n");
    83 			}
    84 
    85 			return vysledek.toString();
    86 		} catch (Exception e) {
    87 			throw new WikiSyntaxVyjimka("Chyba při zpracovávání textu: " + text, e);
    88 		} finally {
    89 			try {
    90 				wr.close();
    91 			} catch (IOException e) {
    92 				log.log(Level.WARNING, "Selhalo zavírání OutputStreamWriteru", e);
    93 			}
    94 			try {
    95 				rd.close();
    96 			} catch (IOException e) {
    97 				log.log(Level.WARNING, "Selhalo zavírání BufferedReaderu", e);
    98 			}
    99 		}
   100 	}
   101 
   102 	/**
   103 	 * Čte proud dat dokud to jde a výsledek pak vrátí jako text.
   104 	 * @param proud vstupní proud
   105 	 * @return obsah proudu jako text
   106 	 * @throws IOException 
   107 	 */
   108 	public static String načtiProud(InputStream proud) throws IOException {
   109 		StringBuilder výsledek = new StringBuilder();
   110 		BufferedReader buf = new BufferedReader(new InputStreamReader(proud));
   111 		while (true) {
   112 			String radek = buf.readLine();
   113 			if (radek == null) {
   114 				break;
   115 			} else {
   116 				výsledek.append(radek);
   117 				výsledek.append("\n");
   118 			}
   119 		}
   120 		return výsledek.toString();
   121 	}
   122 
   123 	/**
   124 	 * Můžeme nastavit vlastní příkaz pro transformaci Markdown syntaxe.
   125 	 * Ve výchozím nastavení se Markdown procesor volá přes sudo pod uživatelem markdown.
   126 	 * @param markdownPříkaz první je příkaz, následují případné parametry
   127 	 */
   128 	public void setMarkdownPříkaz(String[] markdownPříkaz) {
   129 		this.markdownPříkaz = markdownPříkaz;
   130 	}
   131 }