package ConvertAnyDoc; /** * $Id: ConvertAnyDoc2.java 1 2007-06-04 10:06:18Z pascal $ * * * TODO : alot */ import java.io.*; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; /** * @category anyProjekt -> anyDocument * @see anyForum * @serial $Id: ConvertAnyDoc2.java 1 2007-07-04 10:06:18Z pascal $ * @since 2007-06-01 Description: converts an anyDocument to another format like html, anyWiki etc. * @author pc * @description Kannn als Skript und als Servlet eingesetzt werden. * @TODO: MVC richtig umsetzen, Fehlerbehandlungen, Umsetzung als barrierefreies Servlet, GUI fŸrs Taggen des anyDocuments ... */ public class ConvertAnyDoc2 { /** * Description: das ist die Methode die im Skript-Modus aufgerufen wird. Verbiegt lediglich die Ausgabe ("out"). Erwartet zwei Parameter: 1. * quelle.txt, 2. Format, in das zu konvertieren ist * * @param: String args[] */ static void main(String args[]) { PrintWriter out = new PrintWriter(System.out, true); ini(args, out); } /** * Description: erwartet zwei Parameter: 1. quelle.txt, 2. Format, in das zu konvertieren ist * * @param: String args[] */ void mainHTML(String[] args, PrintWriter out) throws IOException { ini(args, out); } static void ini(String args[], PrintWriter out) { if (args.length == 1) { print_hilfe(out); return; } if (args.length < 2) { out.println("Es werden die internen Testparameter genommen: 'ConvertAnyDoc2 convertQuelleTest.txt anyForum'\n "); args = new String[] { "ConvertQuelleTest.txt", "anyForum" }; } try { ConvertAnyDoc_MVC cad = new ConvertAnyDoc_MVC(args[0], out); cad.str_view = cad.model_convert2("Convert_regEx." + args[1]); cad.view_save("Converted.txt"); } catch (Exception e) { System.out.println("ERROR: es gab einen Fehler:\n"); e.printStackTrace(); } } /** * Description: Gibt eine Anleitung raus. */ final static String[] formate = { "anyWiki", "2do:pdf", "2do:anyForum", "2do:html", "2do:rtf" }; // spaeter mal auslagern in eine Datei. dadurch dynamischer static public void print_hilfe(PrintWriter out) { out.println("Der richtige Aufruf lautet z.B. so: \n java ConvertAnyDoc2 ConvertQuelleTest.txt anyForum \nDie Datei 'ConvertQuelleTest.txt' muss den anyDocument Anforderungen genuegen , in Zukunft sollen folgende Formate untersuetzt werden:\n"); for (int i = 0; i < formate.length; i++) { out.println(formate[i]); } } } /** * Description: diese Classe bildet die eigentliche Funktionalitaet ab. * * @author pc */ class ConvertAnyDoc_MVC { String str_model; String str_view; private PrintWriter out; /** * Description: Der eigene Konstruktor nimmt zur Initialisierung die Aufrufparameter entgegen Ausserdem werden das miminale ch'sche Subset * eingelesen - ohne das gehts nicht. * * @param model_filename * @param str_format */ ConvertAnyDoc_MVC(String str_model, PrintWriter out) { this.out = out; try { this.str_model = str_model; } catch (Exception e) { out.println("ERROR: es gab einen Fehler beim Laden der Daten:\n"); e.printStackTrace(); out.println("Der richtige Aufruf lautet z.B. so: \n ConvertAnyDoc2 quelle.txt anyWiki \nDie Datei 'quelle.txt' genŸgt den anyDoc Anforderungen, die UnterstŸtzten Formate sind:\n"); for (int i = 0; i < ConvertAnyDoc2.formate.length; i++) { out.println(ConvertAnyDoc2.formate[i]); } } } /** * hilfslklassen zum finden vom KlassenPfad * * @return */ private String classResName() { String className = getClass().getName(); return "/" + className.replace('.', '/') + ".class"; } private File findExtRoot() { URL url = getClass().getResource(classResName()); try { URLConnection connection = url.openConnection(); URL jarURL = (connection).getURL(); File jarFile = new File(jarURL.getFile()); return new File(jarFile.getParent()); } catch (IOException err) { err.printStackTrace(); } return null; } /** * Description: loads a given filename and return a String[] of the content of the file. * * @param filename * @return String[] content of the file, line per line in an [] */ private String[] loadFile2Array(String filename) { ArrayList al = new ArrayList(); try { File file = new File(new File(findExtRoot().getAbsolutePath()).getParent() + File.separatorChar + "Daten" + File.separatorChar + filename); // out.println("Der Pfad ist:" + file.getPath()); if (file.exists()) { FileReader fileReader = new FileReader(file); BufferedReader reader = new BufferedReader(fileReader); String entry; while ((entry = reader.readLine()) != null) { al.add(entry); } reader.close(); } else { out.println("ERROR: Das Filed " + file.getName() + " existiert nicht in " + file.getAbsolutePath()); } } catch (Exception e) { out.println("es gab einen IO-Fehler:\n"); e.printStackTrace(); } String[] tmp_strArr = new String[al.size()]; for (int i = 0; i < tmp_strArr.length; i++) { tmp_strArr[i] = al.get(i); } return tmp_strArr; } /** * Description: es wird ein String uebergeben, welcher das Format bezeichnet, in das konvertiert werden soll. Dann wird die dazugehoerige Datei * ConvertAnyDoc_regexe.* gesucht und wenn vorhanden in das Stringarray geladen. * * @param format */ private String[][] setRegexReplace(String filename) { String[] regexReplace_oneLine = loadFile2Array(filename); String[] str_tmp; ArrayList spalte1_regexSourceModel = new ArrayList(); ArrayList spalte2_regexReplaceBegin = new ArrayList(); ArrayList spalte3_regexReplaceEnd = new ArrayList(); try { for (int i = 0; i < regexReplace_oneLine.length; i++) { if (regexReplace_oneLine[i].length() > 6) { // z.b. leerzeilen nicht lesen str_tmp = regexReplace_oneLine[i].split(" , "); if (str_tmp.length > 3) { out.println("WARNING: Die Datei zum Format von " + filename + "hat mehr als die erlaubten drei Spalten in einer Zeile. "); } // hier werden die drei Spalten ins temporŠre regex-Model gelesen ... spalte1_regexSourceModel.add(i, str_tmp[0]); spalte2_regexReplaceBegin.add(i, str_tmp[1]); spalte3_regexReplaceEnd.add(i, str_tmp[2]); } } } catch (Exception e) { out.println("Die RegEx-Datei " + filename + " ist korruptiv. Moeglicherweise fehlen bloss leerzeichen zwischen dem Kommas der Spalten"); } // ... hier werden die drei Spalten in die passende [][] kopiert String[][] tmp_strArr = new String[3][spalte1_regexSourceModel.size()]; for (int i = 0; i < spalte1_regexSourceModel.size(); i++) { // ORIG -1 tmp_strArr[0][i] = spalte1_regexSourceModel.get(i); tmp_strArr[1][i] = spalte2_regexReplaceBegin.get(i); tmp_strArr[2][i] = spalte3_regexReplaceEnd.get(i); } return tmp_strArr; } /** * Description: speichert den aktuellen view der Klasse. * * @param fileName * @throws java.io.IOException */ void view_save(String fileName) throws java.io.IOException { FileOutputStream fos; byte[] b; File file = new File(new File(findExtRoot().getAbsolutePath()).getParent() + File.separatorChar + "Daten" + File.separatorChar + fileName); fos = new FileOutputStream(file); b = str_view.getBytes(); fos.write(b); fos.flush(); fos.close(); } /** * Description: nimmt den String, der aus der ModelDatei gemacht wurde, und wendet darauf die regexe (aus einem anderen file, identifiziert durch * den Paramter "format") an. */ String model_convert2(String format) throws java.io.IOException { String[][] regexReplace = new String[3][]; String str_model = this.str_model; out.println(getHtmlHead()); regexReplace = setRegexReplace(format); str_view = model2View(str_model, regexReplace); // str_view = str_model; return str_view; } /** * Eigene Implementation der Ersetzung. Kann besser sein, z.B. ohne byteweises umkopieren, stattdessen loeschenmit zaehler * * @param str_model * @param regexSrc * @param regexSub */ String model2View(String str_model, String[][] regexReplace) { StringBuffer newView = new StringBuffer(); int endklammerPos = 0; // byteweises kopieren nach newView for (int modelPos = 0; modelPos < str_model.length(); modelPos++) { if (str_model.charAt(modelPos) == '\\') { int alleRegexZeilen; for (alleRegexZeilen = 0; alleRegexZeilen < regexReplace[0].length; alleRegexZeilen++) { if (str_model.regionMatches(modelPos, regexReplace[0][alleRegexZeilen], 0, regexReplace[0][alleRegexZeilen].length())) { newView.append(regexReplace[1][alleRegexZeilen]); // der "replace" im neuen View modelPos = modelPos + regexReplace[0][alleRegexZeilen].length(); endklammerPos = find_lonleyGeschlosseneKlammer(str_model.substring(modelPos, +str_model.length())); if (endklammerPos == '0') { out.println("ERROR: Es fehlt wohl eine geschlossene Klammer!"); return null; } // das was zwischen den {} steht kopieren newView.append(str_model.substring(modelPos, (modelPos + endklammerPos))); // die } ersetzen im neuen View modelPos = modelPos + endklammerPos; newView.append(regexReplace[2][alleRegexZeilen]); break; } } // sollte nix gefunden sein, ist ein Tag nicht spezifiziert. if (alleRegexZeilen==regexReplace[0].length) { System.out.println ("Ein Tag konnte nicht uebersetzt werden, an Position "+modelPos+" in:\n "+str_model); newView.append("\\"); } } else { newView.append(str_model.charAt(modelPos)); } } out.println(CR_and_LF2BR(newView.toString())); out.println(getHtmlTail()); return newView.toString(); } private String getHtmlHead() { return new String("" + "" + "" + "\n " + "AnyDocument: View" + "" + ""); } private String getHtmlTail() { return new String(""); } private String CR_and_LF2BR(String str) { return new String(str.replaceAll("\n", "
")); } /** * Gibt den index der ersten einzelnen geschlossenen Klammer zurŸck. * * @param str_model * @return index */ int find_lonleyGeschlosseneKlammer(String str_model_substring) { int offeneKlammer = 1; int geschlosseneKlammer = 0; // 1:0 fŸr die offfeneKlammer for (int i = 0; i < str_model_substring.length(); i++) { if (str_model_substring.charAt(i) == '{') { offeneKlammer++; } else if (str_model_substring.charAt(i) == '}') { geschlosseneKlammer++; } if (offeneKlammer == geschlosseneKlammer) { return i; // success } } return 0; // failed } }