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