com.erikHolz.vertretungsplan.Converter.java Source code

Java tutorial

Introduction

Here is the source code for com.erikHolz.vertretungsplan.Converter.java

Source

/*
Copyright (C) 2014  Erik Holzwirth
    
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.
    
You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.erikHolz.vertretungsplan;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

import android.os.Environment;

import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.LocationTextExtractionStrategy;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
import com.itextpdf.text.pdf.parser.TextExtractionStrategy;

public class Converter {

    // Dateiname
    String fileName = "";
    // Dateipfad
    String fileDest = "";

    // Konstruktor setzt Dateinamen / Dateipfad abhngig vom bergebenen
    // Parameter

    public Converter(String filename) {
        fileDest = Environment.getExternalStorageDirectory().getPath() + "/" + filename;
        fileName = filename;
    }

    // Konvertieren der PDF in txt - Format
    // das Codebeispiel stammt von
    // http://svn.code.sf.net/p/itext/code/book/src/part4/chapter15/ExtractPageContentSorted1.java
    // Dateiname der Ausgabe Datei nach dem Schema YYYY MM DD__.txt

    public void parsePDF() throws IOException {

        PdfReader reader = new PdfReader(fileDest + ".pdf");
        PdfReaderContentParser parser = new PdfReaderContentParser(reader);
        PrintWriter out = new PrintWriter(new FileOutputStream(fileDest + "__.txt"));

        TextExtractionStrategy strategy;
        for (int intI = 1; intI <= reader.getNumberOfPages(); intI++) {
            strategy = parser.processContent(intI, new LocationTextExtractionStrategy());
            out.println(strategy.getResultantText());
        }

        out.flush();
        out.close();
        reader.close();

        // lschen der ursprnglichen pdf
        File f = new File(fileDest + ".pdf");
        if (f.exists())
            f.delete();
    }

    // von hier an erfolgt die Reinigung der erstellten txt - Datei von den
    // Steuerzeichen der pdf

    public void cleanTXT() {

        try {
            // signalisiert, ob die gelesene Zeile gespeichert werden soll
            // (false) oder nicht (true)
            boolean boolSkip = false;

            // signalisiert das Ende der zu lesenden (wichtigen) Zeilen
            boolean boolEnd = false;

            // Objekt, um aus der erstellten txt zu lesen
            BufferedReader input = new BufferedReader(new FileReader(fileDest + "__.txt"));

            // Objekt, um in eine neue txt (zwischen) zu speichern
            // Dateiname der Ausgabedatei nach dem Schema YYYY MM DD_.txt
            BufferedWriter output = new BufferedWriter(new FileWriter(new File(fileDest + "_.txt"), false));

            // Zwischenspeicher fr die gerade eingelesene Zeile
            String line = null;

            // Zwischenspeicher fr einzelne Zeichen
            char[] charBuffer = null;

            // zeilenweises Lesen der Datei bis zum Dateiende
            // wobei boolEnd durch das Programm belegt wird und
            // das "natrliche" Ende der Datei input.readLine()
            // null zurckgibt
            while ((line = input.readLine()) != null && !boolEnd) {

                // einige Zhlvariablen, werden spter bentigt
                Integer intJ = 0;
                Integer intK = 0;
                Integer intL = 0;

                // die eingelesene Zeile wird an den Leerzeichen geteilt
                // und jedes Einzielglied in einen String - Array gespeichert
                // (in der PDF sind die einzelnen Spalten und ihre Bestandteile
                // jeweils durch Leerzeichen getrennt:
                // Klassenstufe / Klasse Fach Raum Herr Lehrer Frau Lehrerin
                String[] splittedLine = line.split(" ");

                // der String line aus dem Schleifenkopf kann hier weiter
                // verwendet werden, da seine Daten gesplitted in
                // splittedLine[] gespeichert sind
                // dies spart den Speicher den ein neuer String bentigen
                // wrde
                line = "";

                for (int intI = 0; intI < splittedLine.length; intI++) {
                    // in besonderen Fllen steht an erster Steller des
                    // ersten Strings (also an Position [0] ein "*"
                    // das das Ende relevanter Informationen ankndigt
                    charBuffer = splittedLine[0].toCharArray();

                    // intI = splittedLine.length lsst den Zhler innerhalb der
                    // Zeile in die letzte Spalte springen, um unntige
                    // berprfungen der restlichen Felder der Zeile zu umgehen

                    // die Signalwrter treten nur im Tiel bzw. in den
                    // berschriften
                    // der Spalten auf, die ganze Zeile kann bersprungen werden
                    if (splittedLine[intI].equals("Vertretungsplan")) {
                        intI = splittedLine.length;
                        boolSkip = true;
                    } else if (splittedLine[intI].equals("Klasse/Block")) {
                        intI = splittedLine.length;
                        boolSkip = true;
                    } else if (splittedLine[intI].equals("Nachtrag")) {
                        intI = splittedLine.length;
                        boolSkip = true;
                    } else if (splittedLine[intI].equals("Klasse")) {
                        intI = splittedLine.length;
                        boolSkip = true;
                    }

                    // die Signalwrter treten nur in der Zeile nach den
                    // Vertretungen
                    // auf und im folgenden Teil werden Informationen
                    // dargestellt,
                    // die nicht in der App dargestellt werden sollen
                    // --> ab hier kann das speichern in die neue Datei
                    // abgebrochen
                    // werden
                    else if (splittedLine[intI].equals("Aufsicht:")) {
                        intI = splittedLine.length;
                        boolEnd = true;
                    } else if (splittedLine[intI].equals("Aufsichten:")) {
                        intI = splittedLine.length;
                        boolEnd = true;
                    } else if (splittedLine[intI].equals("Aufsicht")) {
                        intI = splittedLine.length;
                        boolEnd = true;
                    } else if (charBuffer[0] == '*') {
                        intI = splittedLine.length;
                        boolEnd = true;
                    }

                    // in den Felder 0,1,2 stehen die Daten Klassenstufe, "/"
                    // und Klasse, diese knnen zusammengehrig in line
                    // gespeichert werden
                    else if (intI <= 2)
                        line += splittedLine[intI];

                    // alle anderen Felder enthalten die restlichen Daten
                    else {

                        // Sonderfall, wenn das Feld "Herr" oder "Frau" enthlt,
                        // da die Anrede und der Name in der entstandenen txt
                        // getrennt wurden
                        // einserseits sollen "Herr/Frau" und "Name" als eine
                        // Einheit gespeichert werden, anderseits, muss der
                        // Sonderfall von Doppelnamen wie "Herr Dr. Klose"
                        // bercksichtigt werden, so dass nicht davon
                        // ausgegangen werden kann das intI und intI + 1
                        // den vollstndigen Namen reprsentieren
                        if (splittedLine[intI].equals("Herr") || splittedLine[intI].equals("Frau")) {

                            // zunchst wird ein "_" als Trenner zum vorherigen
                            // Feld eingefgt, anschlieend der Inhalt des
                            // aktuellen Feldes, also "Herr" oder "Frau"
                            line += "_" + splittedLine[intI];

                            // nun wird der zugehrige Name des Lehrers gesucht
                            if (intJ == 0 && intK == 0) {

                                // das nchste Feld, in dem "Herr" oder "Frau"
                                // steht,
                                // wird gesucht (also in der Spalte "Ausfall")
                                for (intJ = intI + 1; intJ < splittedLine.length; intJ++)
                                    if (splittedLine[intJ].equals("Herr") || splittedLine[intJ].equals("Frau"))
                                        break;

                                // dennoch ist es mglich, das dies nicht zu
                                // finden ist, da es keine Vertretung, sodnern
                                // Ausfall geben wird
                                // somit wird gesucht, ob ein Feld mit dem
                                // Inhalt "Ausfall" existiert
                                for (intK = intI + 1; intK < splittedLine.length; intK++)
                                    if (splittedLine[intK].equals("Ausfall"))
                                        break;

                                // springen zum nchsten Feld
                                intI++;

                                // bei dieser Schleife wurde jedes Feld von
                                // splittedLines
                                // berprft und jedes mal der jeweilige Zhler
                                // erhht
                                // gibt es Vertretung, wurde kein Aufall
                                // gefunden, folglich
                                // ist der Zhler intJ kleiner als intK
                                // gibt es Ausfall, aber keine Vertretung, so
                                // ist der Zhler
                                // intJ grer als intK

                                if (intJ < intK) {
                                    while (intI < intJ) {
                                        // es werden nun alle Felder bis zum
                                        // Signalfeld "Herr"
                                        // oder "Frau" dem String hinzugefgt
                                        line += " " + splittedLine[intI];
                                        intI++;
                                    }
                                }

                                else if (intJ > intK) {
                                    while (intI < intK) {
                                        // es werden nun alle Felder bis zum
                                        // Signalfeld "Aufall"
                                        // dem String hinzugefgt
                                        line += " " + splittedLine[intI];
                                        intI++;
                                    }
                                }

                                // Rckkehr zum vorherigen Feld, damit die
                                // Schleife
                                // dies durch intI++ weiter handhaben kann, ohne
                                // dass ein Feld bersprungen wird
                                intI--;

                                // es wurde erneut ein "Herr" oder "Frau"
                                // gefunden, da intJ bzw. intK aber nicht mehr
                                // 0 sind, muss das vorherige Feld den Ausfall
                                // gezeigt haben und dieses aktuelle Feld muss
                                // die Vertretung anzeigen
                                // da es das (vor)letzte Feld ist, knnen nun
                                // alle brigen Felder der Zeile hinzugefgt
                                // werden
                            } else {
                                intI++;
                                for (intL = intI; intL < splittedLine.length; intL++)
                                    line += " " + splittedLine[intL];

                                // intI wird auf intL, also den letzten Index
                                // des Arrays gesetzt, somit ist die Zeile
                                // vollstndig eingelesen und die
                                // Schleifenbedingung nicht mehr erfllt,
                                // das Einlesen der Zeile in den String endet
                                // hiermit
                                intI = intL;
                            }

                            // das Feld entht z.B. den das Fach oder den Raum
                            // und kann ohne weitere Anpassung einfach in den
                            // String geschrieben werden
                        } else
                            line += "_" + splittedLine[intI];
                    }
                }

                // die eingelesene (verarbeitete) Zeile wird in die txt-Datei
                // geschrieben
                output.write(line);

                // wenn eine Zeile geschrieben wurde die Datei nicht zu Ende ist
                // wird das Steuerzeichen fr eine neue Zeile hinzugefgt
                if (boolSkip == false && boolEnd == false) {
                    output.newLine();
                } else
                    boolSkip = false;
            }

            // schlieen der Streams, um Speicher frei zu machen
            input.close();
            output.close();

            // lschen der Zwischenspeicherdatei
            File f = new File(fileDest + "__.txt");
            if (f.exists())
                f.delete();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // abschlieende Vernderungen an der neu erstellten txt
    // Eintrge wie 5/1,2,3 werden in 3 Eitnrge zu "5/1", 5"2" und "5/3"
    // zerlegt, auerdem werden fr Eintrge wie "12/A" Eintrge fr "12/1",
    // "12/2" und "12/3" angelegt, da diese nicht eindeutig zuzuordnen sind

    public void finish() {

        try {

            // auch hier werden Objekte zum Lesen der alten und schreiben der
            // neuen (endgltigen) Datei angelegt
            BufferedReader input = new BufferedReader(new FileReader(fileDest + "_.txt"));
            BufferedWriter output = new BufferedWriter(new FileWriter(new File(fileDest + ".txt"), false));

            // der Buffer fr die eingelesene Zeile
            String line = null;

            // die Schleife in der bis zum Dateiende eingelesen wird
            while ((line = input.readLine()) != null) {
                // Teilung der Zeile am im vorherigen Schritt gesetzten "_"
                String[] splittedLine = line.split("_");

                // Zhlvariable
                int intI = 0;

                // line wird weiter als Buffer verwendet, siehe clean
                line = "";

                // berprfung, ob eine Zeile mehrere Klassen verkrpert
                // also z.B. "5/1,2,3"
                // ab > 4 Zeichen sind es mehrere Klassen: 5 / 1 , 2
                if (splittedLine[0].length() > 4) {
                    // buffer1[0] enthlt dann "5"
                    // buffer1[1] 1,2,3
                    String[] buffer1 = splittedLine[0].split("/");
                    // dieser buffer1[1] wird dann an den ","
                    // gespaltet
                    String[] buffer2 = buffer1[1].split(",");

                    // schlielich wird jetzt fr jede Klasse eine eigene
                    // Zeile hinzugefgt
                    for (intI = 0; intI < buffer2.length; intI++) {

                        for (int i = 0; i < splittedLine.length; i++)
                            if (i == 0)
                                line += buffer1[0] + "/" + buffer2[intI] + "_";
                            else {
                                line += splittedLine[i];
                                if (i < splittedLine.length)
                                    line += "_";
                            }

                        output.write(line);
                        output.newLine();
                        line = "";
                    }
                }

                // berprfung, ob der Klassenname 11 oder 12 fr die Kursstufe
                // enthlt
                else {
                    String[] buffer1 = splittedLine[0].split("/");

                    // aufgrund der Planstruktur, werden Vertretungen der Kursstufe
                    // fr alle Kurse angezeigt
                    boolean forAllClasses = false;
                    if ((buffer1[0].equals("11") || buffer1[0].equals("12")))
                        forAllClasses = true;

                    // ja, es ist ein Eintrag fr die Kursstufe
                    if (forAllClasses) {
                        // intI < 4 bedeutet, dass der Eintrag fr 3 Klassen
                        // also "12/1", "12/2" und "12/3" angelegt wird
                        for (intI = 1; intI < 4; intI++) {

                            for (int i = 0; i < splittedLine.length; i++)
                                if (i == 0)
                                    line += buffer1[0] + "/" + intI + "_";
                                else {
                                    line += splittedLine[i];
                                    if (i < splittedLine.length)
                                        line += "_";
                                }

                            output.write(line);
                            output.newLine();
                            line = "";
                        }

                        // ansonsten wird die Zeile genau wie vorher wieder
                        // geschrieben
                    } else {

                        for (int i = 0; i < splittedLine.length; i++)
                            line += splittedLine[i] + "_";

                        output.write(line);
                        output.newLine();
                    }
                }

            }

            // schlieen der Streams
            input.close();
            output.close();

            // Lschen des vorherigen Zwischenspeichers
            File f = new File(fileDest + "_.txt");
            if (f.exists())
                f.delete();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // Zusammenfgen des regulren Vertretungsplanes mit dem mglicherweise
    // existierenden Nachtrag

    public void merge() {

        try {
            // der Datei Name YYYY MM DD N wird in seine Einzelteile
            // gespaltet
            String[] filenameSplitted = fileName.split(" ");

            // davon ausgehend muss die Datei des eigentlichen Planes
            // YYYY MM DD ohne das N am Schluss heien
            String mainFile = filenameSplitted[0] + " " + filenameSplitted[1] + " " + filenameSplitted[2];

            // Erstellung der Objekte zum Lesen und Schreiben der Daten
            // hier gibt es zwei Lesende: fr den Nachtrag und den eigentlichen
            // Vertretungsplan
            BufferedReader input = new BufferedReader(
                    new FileReader(Environment.getExternalStorageDirectory().getPath() + "/" + mainFile + ".txt"));
            BufferedReader inputN = new BufferedReader(new FileReader(fileDest + ".txt"));

            // _b als kurzer Zwischenspeicher
            BufferedWriter outputB = new BufferedWriter(new FileWriter(new File(fileDest + "_b.txt"), true));

            // Buffer fr die eingelesene Zeile
            String line = null;

            // Lesen bis zum Datei Ende innerhalb der Schleife
            while ((line = input.readLine()) != null) {
                // Datei wird 1:1 geschrieben
                outputB.write(line);
                outputB.newLine();
            }

            // Lesen bis zum Datei Ende innerhalb der Schleife
            while ((line = inputN.readLine()) != null) {
                // Inhalt wird 1:1 in die selbe Datei dazugeschrieben
                outputB.write(line);
                outputB.newLine();
            }

            // Streams werden geschlossen
            input.close();
            inputN.close();
            outputB.close();

            // die Ursprnglichen Dateien werden gelscht
            File f1 = new File(Environment.getExternalStorageDirectory().getPath() + "/" + mainFile + ".txt");
            if (f1.exists())
                f1.delete();
            File f2 = new File(fileDest + ".txt");
            if (f2.exists())
                f2.delete();

            // die erstellte Datei YYYY MM DD_b.txt wird umbenannt zu
            // YYYY MM DD.txt
            File oldFile = new File(fileDest + "_b.txt");

            oldFile.renameTo(
                    new File(Environment.getExternalStorageDirectory().getPath() + "/" + mainFile + ".txt"));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // Befreien des heruntergeladenen Essensplanes von HTML Steuerzeichen

    public void cleanMenu() throws IOException {

        // Schritt 1:

        // Objekte zum Lesen der ursprnglichen HTML Datei und zum Schreiben
        // der ersten txt-Datei
        BufferedReader inStep1 = new BufferedReader(
                new FileReader(Environment.getExternalStorageDirectory().getPath() + "/" + "menu.html"));
        BufferedWriter outStep1 = new BufferedWriter(new FileWriter(
                new File(Environment.getExternalStorageDirectory().getPath() + "/" + "essenBufferStep1.txt"),
                false));

        // Erstellen der bekannten Buffer wie in den vorhergegangenen Funktionen
        String line = null;
        String[] lineSplitted;
        String[] buffer = null;

        while ((line = inStep1.readLine()) != null) {
            // ce_speiseplan_day_label als Kennzeichner fr
            // Container des jeweiligen Tages
            lineSplitted = line.split("ce_speiseplan_day_label");
            // ist der Kennzeichner nicht vorhanden, entspricht
            // lineSplitted[0] line, sie kann also komplett
            // vernachlssigt werden
            if (!(line.equals(lineSplitted[0])))
                for (int intI = 0; intI < lineSplitted.length - 1; intI++) {
                    if (intI + 1 == lineSplitted.length) {
                        buffer = lineSplitted[intI].split("/Speiseplan - Startseite_files/lift_footer_verlauf.png");
                        outStep1.write(buffer[0] + "\n");
                    } else
                        outStep1.write(lineSplitted[intI + 1] + "\n");
                }
        }

        inStep1.close();
        outStep1.close();

        // Schritt 2:

        BufferedReader inStep2 = new BufferedReader(
                new FileReader(Environment.getExternalStorageDirectory().getPath() + "/" + "essenBufferStep1.txt"));
        BufferedWriter outStep2 = new BufferedWriter(new FileWriter(
                new File(Environment.getExternalStorageDirectory().getPath() + "/" + "essenBufferStep2.txt"),
                false));

        // Aufteilen in einzelne Zeilen mit ">" als Signalzeichen
        // fr Trennung
        while ((line = inStep2.readLine()) != null) {
            lineSplitted = line.split(">");
            for (int intJ = 0; intJ < lineSplitted.length; intJ++)
                outStep2.write(lineSplitted[intJ] + "\n");
        }

        inStep2.close();
        outStep2.close();

        // Schritt 3:

        BufferedReader inStep3 = new BufferedReader(
                new FileReader(Environment.getExternalStorageDirectory().getPath() + "/" + "essenBufferStep2.txt"));
        BufferedWriter outStep3 = new BufferedWriter(new FileWriter(
                new File(Environment.getExternalStorageDirectory().getPath() + "/" + "essenBufferStep3.txt"),
                false));

        // Zeilen die Bezeichnungen des Essens enthalten, haben am Ende
        // ein "</strong", die folgende Zeile besteht aus "</span"
        while ((line = inStep3.readLine()) != null) {

            // Trennen der Zeile an "</strong"
            lineSplitted = line.split("</strong");

            // entspricht die Zeile nicht </span" so wird
            // sie an diesem als Signalzeichen geteilt
            if (!(line.equals("</span")))
                buffer = line.split("</span");

            // ansonsten wird die Zeile an buffer[0] bergeben
            else
                buffer[0] = line;

            if (!(line.equals(lineSplitted[0])) || !(line.equals(buffer[0])))
                outStep3.write(lineSplitted[0] + "\n");
        }

        inStep3.close();
        outStep3.close();

        // Schritt 4:

        BufferedReader inStep4 = new BufferedReader(
                new FileReader(Environment.getExternalStorageDirectory().getPath() + "/" + "essenBufferStep3.txt"));
        BufferedWriter outStep4 = new BufferedWriter(new FileWriter(
                new File(Environment.getExternalStorageDirectory().getPath() + "/" + "essenBufferStep4.txt"),
                false));

        while ((line = inStep4.readLine()) != null) {
            lineSplitted = line.split("</span");
            if (!(lineSplitted[0].equals("1")))
                outStep4.write(lineSplitted[0] + "\n");
        }

        inStep4.close();
        outStep4.close();

        // some last layouting to make easier to read

        BufferedReader inStep5 = new BufferedReader(
                new FileReader(Environment.getExternalStorageDirectory().getPath() + "/" + "essenBufferStep4.txt"));
        BufferedWriter outStep5 = new BufferedWriter(new FileWriter(
                new File(Environment.getExternalStorageDirectory().getPath() + "/" + "essenBuffer.txt"), false));

        int intMergeCount = 0;

        while ((line = inStep5.readLine()) != null) {
            if (line.equals("MONTAG")) {
                line = "1";
                intMergeCount = 3;
            }
            if (line.equals("DIENSTAG")) {
                line = "2";
                intMergeCount = 3;
            }
            if (line.equals("MITTWOCH")) {
                line = "3";
                intMergeCount = 3;
            }
            if (line.equals("DONNERSTAG")) {
                line = "4";
                intMergeCount = 3;
            }
            if (line.equals("FREITAG")) {
                line = "5";
                intMergeCount = 3;
            }
            if (line.equals("SAMSTAG")) {
                line = "6";
                intMergeCount = 3;
            }
            if (line.equals("SONNTAG")) {
                line = "7";
                intMergeCount = 3;
            }

            if (intMergeCount > 0) {
                intMergeCount -= 1;
                if (intMergeCount == 0)
                    outStep5.write(line + "\n");
                else
                    outStep5.write(line + "_");
            }

        }

        inStep5.close();
        outStep5.close();

        // delete buffer files

        File f = null;

        f = new File(Environment.getExternalStorageDirectory().getPath() + "/" + "menu.html");
        if (f.exists())
            f.delete();
        f = new File(Environment.getExternalStorageDirectory().getPath() + "/" + "essenBufferStep1.txt");
        if (f.exists())
            f.delete();
        f = new File(Environment.getExternalStorageDirectory().getPath() + "/" + "essenBufferStep2.txt");
        if (f.exists())
            f.delete();
        f = new File(Environment.getExternalStorageDirectory().getPath() + "/" + "essenBufferStep3.txt");
        if (f.exists())
            f.delete();
        f = new File(Environment.getExternalStorageDirectory().getPath() + "/" + "essenBufferStep4.txt");
        if (f.exists())
            f.delete();

    }

}