mfi.filejuggler.responsibles.BasicApplication.java Source code

Java tutorial

Introduction

Here is the source code for mfi.filejuggler.responsibles.BasicApplication.java

Source

package mfi.filejuggler.responsibles;

import it.sauronsoftware.cron4j.Scheduler;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.Cookie;

import mfi.filejuggler.annotation.Responsible;
import mfi.filejuggler.helper.Hilfsklasse;
import mfi.filejuggler.helper.ServletHelper;
import mfi.filejuggler.helper.StringHelper;
import mfi.filejuggler.htmlgen.Button;
import mfi.filejuggler.htmlgen.ButtonBar;
import mfi.filejuggler.htmlgen.HTMLTable;
import mfi.filejuggler.htmlgen.HTMLUtils;
import mfi.filejuggler.logic.Crypto;
import mfi.filejuggler.logic.DateiZugriff;
import mfi.filejuggler.logic.Security;
import mfi.filejuggler.maps.KVMemoryMap;
import mfi.filejuggler.model.Condition;
import mfi.filejuggler.model.CronSchedulers;
import mfi.filejuggler.model.Model;
import mfi.filejuggler.servlet.FileJugglerMainServlet;

import org.apache.commons.codec.binary.Base32;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

public class BasicApplication extends AbstractResponsible {

    @Responsible(conditions = { Condition.NULL, Condition.LOGIN_FORMULAR })
    public void fjAnmeldeSeite(StringBuilder sb, Map<String, String> parameters, Model model) throws Exception {

        ButtonBar buttonBar = new ButtonBar();
        buttonBar.getButtons().add(
                new Button("Lizenzen anzeigen / View Licence Attribution", Condition.VIEW_LICENCE_ATTRIBUTION));

        if (model.isUserAuthenticated() && model.lookupConversation().getCondition().equals(Condition.NULL)) {
            // Neue Conversation
            // Schnellstart
            // schnellstartLeiste(sb, model);
            // Weiterleiten zum normalen Men
            model.lookupConversation().setForwardCondition(Condition.FS_NAVIGATE);
        } else {
            sb.append(HTMLUtils.buildMenuNar(model, "FileJuggler Anmeldung", false, buttonBar, false));
            HTMLTable table = new HTMLTable();
            table.addTD("Name: ", 1, null);
            table.addNewRow();
            table.addTDSource(HTMLUtils.buildTextField("login_user", "", 20, Condition.LOGIN), 1, null);
            HTMLUtils.setFocus("login_user", model);
            table.addNewRow();
            table.addTD("Passwort: ", 1, null);
            table.addNewRow();
            table.addTDSource(HTMLUtils.buildPasswordField("login_pass", "", 20, Condition.LOGIN), 1, null);
            table.addNewRow();
            table.addTDSource(new Button("Anmelden", Condition.LOGIN).printForUseInTable(), 1, null);
            table.addNewRow();
            sb.append(table.buildTable(model));
            model.lookupConversation().setForwardCondition(null);
            return;
        }
    }

    @Responsible(conditions = { Condition.LOGIN_GENERATE_CREDENTIALS_FORM })
    public void fjAccountAnlegenSeite(StringBuilder sb, Map<String, String> parameters, Model model)
            throws Exception {

        ButtonBar buttonBar = new ButtonBar();
        buttonBar.getButtons().add(new Button("Zur Anmeldeseite", Condition.LOGIN_FORMULAR));

        sb.append(HTMLUtils.buildMenuNar(model, "Account anlegen", false, buttonBar, false));
        HTMLTable table = new HTMLTable();
        table.addTD("Neuer Name: ", 1, null);
        table.addNewRow();
        table.addTDSource(HTMLUtils.buildTextField("new_user", "", 20, null), 1, null);
        HTMLUtils.setFocus("new_user", model);
        table.addNewRow();
        table.addTD("Neues Passwort: ", 1, null);
        table.addNewRow();
        table.addTDSource(HTMLUtils.buildPasswordField("new_pass1", "", 20, Condition.LOGIN_GENERATE_CREDENTIALS),
                1, null);
        table.addNewRow();
        table.addTD("Passwort wiederholen: ", 1, null);
        table.addNewRow();
        table.addTDSource(HTMLUtils.buildPasswordField("new_pass2", "", 20, Condition.LOGIN_GENERATE_CREDENTIALS),
                1, null);
        table.addNewRow();
        table.addTDSource(new Button("OK", Condition.LOGIN_GENERATE_CREDENTIALS).printForUseInTable(), 1, null);
        table.addNewRow();
        sb.append(table.buildTable(model));
        model.lookupConversation().setForwardCondition(null);
        return;
    }

    @Responsible(conditions = { Condition.LOGIN_GENERATE_CREDENTIALS })
    public void fjAnmeldeCredentialsGenerieren(StringBuilder sb, Map<String, String> parameters, Model model)
            throws Exception {

        String user = StringUtils.trim(parameters.get("new_user"));
        String pass1 = StringUtils.trim(parameters.get("new_pass1"));
        String pass2 = StringUtils.trim(parameters.get("new_pass2"));

        if (StringUtils.isNotBlank(user) && StringUtils.isNotBlank(pass1) && StringUtils.isNotBlank(pass2)) {

            if (!StringUtils.equals(pass1, pass2)) {
                model.lookupConversation().getMeldungen()
                        .add("Die beiden eingegebenen Passwrter sind nicht identisch");
                model.lookupConversation().setForwardCondition(Condition.LOGIN_GENERATE_CREDENTIALS_FORM);
                return;
            }

            if (KVMemoryMap.getInstance().containsKey("user." + user)) {
                model.lookupConversation().getMeldungen().add("Ein Account mit dem Namen existiert bereits.");
                model.lookupConversation().setForwardCondition(Condition.LOGIN_GENERATE_CREDENTIALS_FORM);
                return;
            }

            String hash = Crypto.encryptLoginCredentials(user, pass1);
            String verification = Security.generateVerificationString();

            KVMemoryMap.getInstance().writeKeyValue("user." + user, "FALSE" + " # " + verification, false);
            KVMemoryMap.getInstance().writeKeyValue("user." + user + ".pass", hash, false);
            KVMemoryMap.getInstance().writeKeyValue("user." + user + ".allowedDirectory", "##########", false);
            KVMemoryMap.getInstance().writeKeyValue("user." + user + ".favoriteFolders", "##########", false);
            KVMemoryMap.getInstance().writeKeyValue("user." + user + ".homeDirectory", "##########", false);
            KVMemoryMap.getInstance().save();

            logger.info("User/Passwort generiert fuer: " + user);
            model.lookupConversation().getMeldungen()
                    .add("Neuer Account fr Benutzer " + user + " wurde vorbereitet.");
            model.lookupConversation().getMeldungen().add(
                    "Bitte den Administrator informieren, um das Konto freizuschalten und dabei den Verifikationsschlssel '"
                            + verification + "' nennen");
        } else {
            model.lookupConversation().getMeldungen().add("Bitte Name und Passwort eingeben.");
        }

        model.lookupConversation().setForwardCondition(Condition.LOGIN_FORMULAR);
        return;
    }

    @Responsible(conditions = { Condition.LOGIN_CHANGE_PASS_FORM })
    public void fjAccountPasswortAendernSeite(StringBuilder sb, Map<String, String> parameters, Model model)
            throws Exception {

        ButtonBar buttonBar = new ButtonBar();
        buttonBar.getButtons().add(new Button("Zur Anmeldeseite", Condition.LOGIN_FORMULAR));

        model.lookupConversation().getMeldungen()
                .add("Falls das alte Passwort nicht mehr bekannt ist, bitte das entsprechende Feld leer lassen. "
                        + "In diesem Fall muss der Administrator das neue Passwort erst freischalten. "
                        + "Ist das alte Passwort noch bekannt, kann es direkt durch Eingabe aller u.g. Felder gendert werden.");

        sb.append(HTMLUtils.buildMenuNar(model, "Passwort ndern", false, buttonBar, false));
        HTMLTable table = new HTMLTable();
        table.addTD("Name: ", 1, null);
        table.addNewRow();
        table.addTDSource(HTMLUtils.buildTextField("pw_change_user", "", 20, null), 1, null);
        HTMLUtils.setFocus("pw_change_user", model);
        table.addNewRow();
        table.addTD("Altes Passwort: ", 1, null);
        table.addNewRow();
        table.addTDSource(HTMLUtils.buildPasswordField("pw_change_old_pw", "", 20, Condition.LOGIN_CHANGE_PASS), 1,
                null);
        table.addNewRow();
        table.addTD("Neues Passwort: ", 1, null);
        table.addNewRow();
        table.addTDSource(HTMLUtils.buildPasswordField("pw_change_new_pass1", "", 20, Condition.LOGIN_CHANGE_PASS),
                1, null);
        table.addNewRow();
        table.addTD("Neues Passwort wiederholen: ", 1, null);
        table.addNewRow();
        table.addTDSource(HTMLUtils.buildPasswordField("pw_change_new_pass2", "", 20, Condition.LOGIN_CHANGE_PASS),
                1, null);
        table.addNewRow();
        table.addTDSource(new Button("OK", Condition.LOGIN_CHANGE_PASS).printForUseInTable(), 1, null);
        table.addNewRow();
        sb.append(table.buildTable(model));
        model.lookupConversation().setForwardCondition(null);
        return;
    }

    @Responsible(conditions = { Condition.LOGIN_CHANGE_PASS })
    public void fjPasswortAendern(StringBuilder sb, Map<String, String> parameters, Model model) throws Exception {

        String user = StringUtils.trim(parameters.get("pw_change_user"));
        String passOld = StringUtils.trim(parameters.get("pw_change_old_pw"));
        String passNew1 = StringUtils.trim(parameters.get("pw_change_new_pass1"));
        String passNew2 = StringUtils.trim(parameters.get("pw_change_new_pass2"));

        if (StringUtils.isNotBlank(user) && StringUtils.isNotBlank(passOld) && StringUtils.isNotBlank(passNew1)
                && StringUtils.isNotBlank(passNew2)) {

            if (!StringUtils.equals(passNew1, passNew2)) {
                model.lookupConversation().getMeldungen()
                        .add("Die beiden eingegebenen neuen Passwrter sind nicht identisch");
                model.lookupConversation().setForwardCondition(Condition.LOGIN_CHANGE_PASS_FORM);
                return;
            }

            if (!Security.checkUserCredentials(user, passOld)) {
                model.lookupConversation().getMeldungen().add("Name und altes Passwort sind nicht korrekt.");
                model.lookupConversation().setForwardCondition(Condition.LOGIN_CHANGE_PASS_FORM);
                return;
            }

            String hash = Crypto.encryptLoginCredentials(user, passNew1);

            KVMemoryMap.getInstance().writeKeyValue("user." + user + ".pass", hash, true);
            KVMemoryMap.getInstance().save();

            logger.info("User/Passwort geaendert fuer: " + user);
            model.lookupConversation().getMeldungen().add("Das Passwort wurde erfolgreich gendert.");

        } else if (StringUtils.isNotBlank(user) && StringUtils.isBlank(passOld) && StringUtils.isNotBlank(passNew1)
                && StringUtils.isNotBlank(passNew2)) {

            if (!StringUtils.equals(passNew1, passNew2)) {
                model.lookupConversation().getMeldungen()
                        .add("Die beiden eingegebenen neuen Passwrter sind nicht identisch");
                model.lookupConversation().setForwardCondition(Condition.LOGIN_CHANGE_PASS_FORM);
                return;
            }

            if (!Security.isUserActive(user)) {
                model.lookupConversation().getMeldungen().add("Der Name ist nicht bekannt oder gesperrt.");
                model.lookupConversation().setForwardCondition(Condition.LOGIN_CHANGE_PASS_FORM);
                return;
            }

            String hash = Crypto.encryptLoginCredentials(user, passNew1);
            String verification = Security.generateVerificationString();

            KVMemoryMap.getInstance().writeKeyValue("user." + user + ".resetPass",
                    hash + " # " + verification + " @ " + Hilfsklasse.zeitstempelAlsString(), true);
            KVMemoryMap.getInstance().save();

            logger.info("Passwort Reset vorbereitet fuer: " + user);
            model.lookupConversation().getMeldungen().add(
                    "Das Passwort wurde gespeichert, muss aber noch vom Administrator freigeschaltet werden, da das alte Passwort nicht angegeben wurde. "
                            + "Bitte hierzu dem Administrator den Verifikationsschlssel '" + verification
                            + "' nennen");

        } else {
            model.lookupConversation().getMeldungen().add("Bitte erst alle bentigten Felder eingeben.");
        }

        model.lookupConversation().setForwardCondition(Condition.LOGIN_FORMULAR);
        return;
    }

    @Responsible(conditions = { Condition.SSL_NOTICE })
    public void fjSSLHinweis(StringBuilder sb, Map<String, String> parameters, Model model) throws Exception {

        sb.append(HTMLUtils.buildMenuNar(model, "FileJuggler", false, null, false));
        HTMLTable table = new HTMLTable();
        table.addTD(
                "In der produktiven Umgebung ist der Aufruf der Anwendung nur ber eine verschlsselte Verbindung zugelassen.",
                1, null);
        table.addNewRow();
        sb.append(table.buildTable(model));
        model.lookupConversation().setForwardCondition(null);
        return;
    }

    @Responsible(conditions = { Condition.AUTOLOGIN_FROM_COOKIE })
    public void fjAnmeldungDurchCookie(StringBuilder sb, Map<String, String> parameters, Model model)
            throws Exception {

        model.lookupConversation().setForwardCondition(Condition.FS_NAVIGATE);
        return;
    }

    @Responsible(conditions = { Condition.LOGIN })
    public void fjAnmeldung(StringBuilder sb, Map<String, String> parameters, Model model) throws Exception {

        if (!parameters.containsKey("login_user")) {
            model.lookupConversation().setForwardCondition(Condition.LOGIN_FORMULAR);
            return;
        }

        String user = parameters.get("login_user");
        String pass = parameters.get("login_pass");

        Security.authenticateUser(model, user, pass, null, parameters, false);
        if (model.isUserAuthenticated()) {
            model.lookupConversation().setForwardCondition(Condition.FS_NAVIGATE);
        } else {
            model.lookupConversation().setForwardCondition(Condition.LOGIN_FORMULAR);
            model.setDeleteModelAfterRequest(true);
        }
        return;
    }

    @Responsible(conditions = { Condition.LOGOFF })
    public void fjAbmeldungDurchAnwender(StringBuilder sb, Map<String, String> parameters, Model model)
            throws Exception {

        model.lookupConversation().getMeldungen().add("Du bist jetzt abgemeldet.");
        Security.logoffUser(model);
        return;
    }

    @Responsible(conditions = { Condition.PASSWORD_ASK_ENCRYPT })
    public void fjPasswortEncryptAbfrage(StringBuilder sb, Map<String, String> parameters, Model model)
            throws Exception {

        sb.append(HTMLUtils.buildMenuNar(model, "Passwort-Abfrage", true, null, false));
        HTMLTable table = new HTMLTable();
        table.addTD("Neues Passwort", 1, HTMLTable.TABLE_HEADER);
        table.addNewRow();
        table.addTD("Zum Verschlsseln dieser Datei bitte ein Passwort eingeben.", 1, " align='center'");
        table.addNewRow();
        table.addTDSource(HTMLUtils.buildPasswordField("inapp_pass_one", "", 30, null), 1, " align='center'");
        HTMLUtils.setFocus("inapp_pass_one", model);
        table.addNewRow();
        table.addTD("Besttigung: ", 1, " align='center'");
        table.addNewRow();
        table.addTDSource(HTMLUtils.buildPasswordField("inapp_pass_two", "", 30, Condition.PASSWORD_CHECK_ENCRYPT),
                1, " align='center'");
        table.addNewRow();
        table.addTDSource(new Button("Verschlsseln", Condition.PASSWORD_CHECK_ENCRYPT).printForUseInTable(), 1,
                " align='center'");
        table.addNewRow();

        sb.append(table.buildTable(model));

        // Parameter fuer naechsten Request retten
        // Ziel-Condition steht in parameters.get(HTMLUtils.CONDITION)
        Base32 base32 = new Base32();
        for (String key : parameters.keySet()) {
            if (StringUtils.isNotEmpty(key)) {
                String valueBase32 = base32.encodeAsString(parameters.get(key).getBytes());
                sb.append(HTMLUtils.buildHiddenField("pass_routing_" + key, valueBase32));
            }
        }
        return;
    }

    @Responsible(conditions = { Condition.PASSWORD_ASK_DECRYPT })
    public void fjPasswortDecryptAbfrage(StringBuilder sb, Map<String, String> parameters, Model model)
            throws Exception {

        if (model.lookupConversation().getEditingFile().isBaseCrypted()) {
            Condition forward = Condition.valueOf(parameters.get(HTMLUtils.CONDITION));
            model.lookupConversation().setForwardCondition(forward);
        } else {
            sb.append(HTMLUtils.buildMenuNar(model, "Passwort-Abfrage", true, null, false));
            HTMLTable table = new HTMLTable();
            table.addTD(model.lookupConversation().getEditingFile().dateiNameKlartext(), 1, HTMLTable.TABLE_HEADER);
            table.addNewRow();
            table.addTD("Diese Datei ist verschlsselt.", 1, " align='center'");
            table.addNewRow();
            table.addTD("Bitte Passwort eingeben, dann geht's weiter.", 1, " align='center'");
            table.addNewRow();
            table.addTDSource(
                    HTMLUtils.buildPasswordField("inapp_pass_one", "", 30, Condition.PASSWORD_CHECK_DECRYPT), 1,
                    " align='center'");
            HTMLUtils.setFocus("inapp_pass_one", model);
            table.addNewRow();
            table.addTDSource(new Button("Entschlsseln", Condition.PASSWORD_CHECK_DECRYPT).printForUseInTable(),
                    1, " align='center'");
            table.addNewRow();
            sb.append(table.buildTable(model));

            // Parameter fuer naechsten Request retten
            // Ziel-Condition steht in parameters.get(HTMLUtils.CONDITION)
            Base32 base32 = new Base32();
            for (String key : parameters.keySet()) {
                if (StringUtils.isNotEmpty(key)) {
                    String valueBase32 = base32.encodeAsString(parameters.get(key).getBytes());
                    sb.append(HTMLUtils.buildHiddenField("pass_routing_" + key, valueBase32));
                }
            }
        }

    }

    @Responsible(conditions = { Condition.PASSWORD_CHECK_DECRYPT, Condition.PASSWORD_CHECK_ENCRYPT })
    public void fjPasswortPruefen(StringBuilder sb, Map<String, String> parameters, Model model) throws Exception {

        // Die via Hidden Fields durchgeschleiften Parameter uebernehmen, sofern nicht vorhanden
        Base32 base32 = new Base32();
        Object[] keys = parameters.keySet().toArray();
        for (Object key : keys) {
            String keyString = (String) key;
            if (StringUtils.startsWith(keyString, "pass_routing_")) {
                String keyOriginal = StringUtils.removeStart(keyString, "pass_routing_");
                // Alle nicht gesetzten Parameter setzen.
                // Damit wird vermieden, dass Sessionvariablen ueberschrieben werden
                // Ausnahme: Die Ziel-Condition (z.B. FILE_VIEW). Diese immer ueberschreiben, sonst geht bei >1 Versuchen der
                // Passwort-Eingabe die Ziel-Condition verloren und nach der Eingabe des korrektes Passworts wissen wir nicht mehr, wohin
                // wir zurueck springen muessen.
                if (!parameters.containsKey(keyOriginal) || StringUtils.equals(keyOriginal, HTMLUtils.CONDITION)) {
                    String valueDecoded = new String(base32.decode(parameters.get(keyString)));
                    parameters.put(keyOriginal, valueDecoded);
                    // Xystem.out.println("durchschleifen rein:" + keyOriginal + " / " + valueDecoded);
                }
                // String valueBase32 = new String(base32.decode(parameters.get(key).getBytes()));
                // sb.append(HTMLUtils.buildHiddenField("pass_routing_" + key, valueBase32));
            }
        }

        String pass1 = parameters.get("inapp_pass_one");
        String pass2 = parameters.get("inapp_pass_two");

        if (model.lookupConversation().getCondition().equals(Condition.PASSWORD_CHECK_ENCRYPT)) {
            // verschluesseln
            if (StringUtils.isNotEmpty(pass1) && StringUtils.equals(pass1, pass2)) {
                // Neues Passwort ist gueltig
                model.lookupConversation().getEditingFile().prospectivePassword(pass1);
            } else {
                model.lookupConversation().getMeldungen()
                        .add("Die Passwrter waren nicht gleich oder leer. Bitte nochmal eingeben.");
                // Zurueck zur Eingabe
                model.lookupConversation().setForwardCondition(Condition.PASSWORD_ASK_ENCRYPT);
                return;
            }
        } else {
            // entschluesseln
            if (model.lookupConversation().getEditingFile().pendingPassword(pass1)) {
                // eingegebenes Passwort ist richtig bzw kann die Datei entschluesseln
            } else {
                // Zurueck zur Eingabe
                model.lookupConversation().getMeldungen()
                        .add("Mit dem eingegebenen Passwort konnte die Datei nicht entschlsselt werden.");
                Security.addCounterToBlacklist(model.getUser());
                model.lookupConversation().setForwardCondition(Condition.PASSWORD_ASK_DECRYPT);
                return;
            }
        }
        // Wenn wir bis hier gekommen sind, ist/sind die Passwoerter richtig und es kann zur eigentlichen Ziel-Condition weitergeleitet
        // werden.
        Condition forward = Condition.valueOf(
                new String(base32.decode(parameters.get("pass_routing_" + HTMLUtils.CONDITION).getBytes())));
        model.lookupConversation().setForwardCondition(forward);
        return;
    }

    @Responsible(conditions = { Condition.WEBLINK_INTERN })
    public void fjWeblinkInternOeffnen(StringBuilder sb, Map<String, String> parameters, Model model)
            throws Exception {

        int index = Integer.parseInt(parameters.get(HTMLUtils.TABLEINDEX));
        String link = model.lookupConversation().getAnzeigeAuswahlListe().get(index);
        String iframe = HTMLUtils.buildIFrame("weblinkIntern", link);

        String host = null;
        try {
            host = new URL(link).getHost();
            if (StringUtils.startsWith(host, "www.")) {
                host = StringUtils.replaceOnce(host, "www.", "");
            }
        } catch (MalformedURLException mue) {
            host = "";
        }

        ButtonBar buttonBar = new ButtonBar();
        buttonBar.getButtons().add(new Button("Im Browser ffnen", link, true));
        sb.append(HTMLUtils.buildMenuNar(model, "Website Vorschau", true, buttonBar, true));

        HTMLTable table = new HTMLTable();
        table.addTD(host, 1, HTMLTable.TABLE_HEADER);
        table.addNewRow();
        table.addTDSource(iframe, 1, HTMLTable.NO_BORDER);
        table.setWidthTo100Percent(true);
        sb.append(table.buildTable(model));
        return;
    }

    @Responsible(conditions = { Condition.BROWSER_VIEWABLE_FILE })
    public void fjBrowserDarstellbareDateiAnzeigen(StringBuilder sb, Map<String, String> parameters, Model model)
            throws Exception {

        ButtonBar buttonBar = new ButtonBar();
        buttonBar.getButtons()
                .add(new Button("Herunterladen", HTMLUtils.buildDownloadURLForDirectAttachmentDownload(model,
                        model.lookupConversation().getEditingFile()), false));

        sb.append(HTMLUtils.buildMenuNar(model, "Datei Vorschau", Condition.FS_NAVIGATE, buttonBar, false));

        String name = model.lookupConversation().getEditingFile().dateiNameKlartext();
        HTMLTable table = new HTMLTable();
        table.addTD(name, 1, HTMLTable.TABLE_HEADER);
        table.addNewRow();
        table.setWidthTo100Percent(true);
        sb.append(table.buildTable(model));

        model.lookupConversation().getHtmlElementsAfterFormular().add(HTMLUtils.buildEmbedTag(model));

        return;
    }

    @Responsible(conditions = { Condition.SYS_FJ_OPTIONS })
    public void fjSystemOptionen(StringBuilder sb, Map<String, String> parameters, Model model) throws Exception {

        Condition backCondition = null;
        if (model.lookupConversation().getStepBackCondition() != null
                && model.lookupConversation().getEditingFile() != null) {
            backCondition = model.lookupConversation().getStepBackCondition();
        } else {
            backCondition = Condition.FS_NAVIGATE;
        }

        sb.append(HTMLUtils.buildMenuNar(model, "Anwendung", backCondition, null, false));

        HTMLTable table = new HTMLTable();

        if (model.isPhone()) {
            table.addTD("Allgemein", 3, HTMLTable.TABLE_HEADER);
            table.addNewRow();
            table.addTDSource(
                    new Button("Neues Fenster", FileJugglerMainServlet.SERVLETPFAD, true).printForUseInTable(), 3,
                    null);
            table.addNewRow();
            table.addTDSource(new Button(model.getUser() + " abmelden", Condition.LOGOFF).printForUseInTable(), 3,
                    null);
            table.addNewRow();
        }

        table.addTD("Einstellungen", 3, HTMLTable.TABLE_HEADER);
        table.addNewRow();

        table.addTDSource(HTMLUtils.buildCheckBox("Zeilennummern", "LINE_NUMBERS",
                model.lookupConversation().isTextViewNumbers(), Condition.FS_NUMBERS_TEXTVIEW), 3, null);
        table.addNewRow();
        table.addTDSource(
                HTMLUtils.buildCheckBox("Datei Details", "FILE_DETAILS",
                        model.lookupConversation().isFilesystemViewDetails(), Condition.FS_SWITCH_VIEW_DETAILS),
                3, null);
        table.addNewRow();
        table.addTDSource(HTMLUtils.buildCheckBox("Push Nachrichten", "PUSH",
                model.lookupConversation().isTextViewPush(), Condition.FS_PUSH_TEXTVIEW), 3, null);
        table.addNewRow();

        table.addTD("Verzeichnisse", 3, HTMLTable.TABLE_HEADER);
        table.addNewRow();

        List<String> fav = new LinkedList<String>();
        fav.addAll(model.getFavoriteFolders());
        for (String ber : model.getVerzeichnisBerechtigungen()) {
            if (!fav.contains(ber)) {
                fav.add(ber);
            }
        }
        table.addTDSource(HTMLUtils.buildDropDownListe("gotoFolder", fav, null), 3, " align='center'");
        table.addNewRow();
        table.addTDSource(new Button("wechseln", Condition.FS_GOTO).printForUseInTable(), 3, HTMLTable.NO_BORDER);
        table.addNewRow();
        table.addTD("Anwendungen", 3, HTMLTable.TABLE_HEADER);
        table.addNewRow();
        table.addTDSource(new Button("System-Info", Condition.SYS_SYSTEM_INFO).printForUseInTable(), 3, null);
        table.addNewRow();
        table.addTDSource(
                new Button("Lizenzen anzeigen / View Licence Attribution", Condition.VIEW_LICENCE_ATTRIBUTION)
                        .printForUseInTable(),
                3, null);
        table.addNewRow();
        boolean admin = StringUtils.equalsIgnoreCase(
                KVMemoryMap.getInstance().readValueFromKey("user." + model.getUser() + ".isAdmin"),
                Boolean.toString(true));
        if (admin) {
            table.addTDSource(new Button("Backups", Condition.BACKUPS_START).printForUseInTable(), 3, null);
            table.addNewRow();
            table.addTDSource(new Button("KVDB Editor", Condition.KVDB_EDIT_START).printForUseInTable(), 3, null);
            table.addNewRow();
        }

        sb.append(table.buildTable(model));
        return;
    }

    @Responsible(conditions = { Condition.SYS_SYSTEM_INFO, Condition.SYS_EXECUTE_JOB })
    public void fjSystemInfo(StringBuilder sb, Map<String, String> parameters, Model model) throws Exception {

        if (model.lookupConversation().getCondition().equals(Condition.SYS_EXECUTE_JOB)) {
            String executeJob = StringUtils.trimToEmpty(parameters.get("execute_job"));
            for (String schedulerName : CronSchedulers.getInstance().getSchedulersIDs().keySet()) {
                if (StringUtils.equalsIgnoreCase(schedulerName, executeJob)) {
                    Runnable r = CronSchedulers.getInstance().getSchedulersInstances().get(schedulerName);
                    r.run();
                    model.lookupConversation().getMeldungen().add(r.getClass().getName() + " wurde gestartet");
                    break;
                }
            }
        }

        String warfilename = KVMemoryMap.getInstance().readValueFromKey("application.warfile");
        String builddate = KVMemoryMap.getInstance().readValueFromKey("application.builddate");
        if (warfilename == null) {
            warfilename = "Development Version";
        }
        if (builddate == null) {
            builddate = "n/v";
        }

        ButtonBar buttonBar = new ButtonBar();
        buttonBar.getButtons().add(new Button("Reload", Condition.SYS_SYSTEM_INFO));
        sb.append(HTMLUtils.buildMenuNar(model, "Systeminformationen", Condition.FS_NAVIGATE, buttonBar, false));

        String attributeLeftCol = model.isPhone() ? HTMLUtils.buildAttribute("width", "40%") : null;

        HTMLTable table = new HTMLTable();

        table.addTD("Anwendungsvariablen:", 2, HTMLTable.TABLE_HEADER);
        table.addNewRow();
        table.addTD("Build:", 1, null);
        table.addTD(builddate, 1, null);
        table.addNewRow();
        table.addTD("Systemzeit:", 1, null);
        table.addTD(Hilfsklasse.zeitstempelAlsString(), 1, null);
        table.addNewRow();
        table.addTD("Zwischenablage:", 1, attributeLeftCol);
        String clip;
        if (model.getZwischenablage() != null) {
            clip = HTMLUtils.spacifyFilePath(model.getZwischenablage(), model);
        } else {
            clip = "[ leer ]";
        }
        table.addTD(clip, 1, null);
        table.addNewRow();
        table.addTD("Session:", 1, null);
        table.addTD(StringHelper.langenStringFuerAnzeigeAufbereiten(model.getSessionID()), 1, null);
        table.addNewRow();
        table.addTD("Login:", 1, null);
        table.addTD(StringHelper.langenStringFuerAnzeigeAufbereiten(model.getLoginCookieID()), 1, null);
        table.addNewRow();
        if (model.lookupConversation().getCookiesReadFromRequest() != null && model.isDevelopmentMode()) {
            for (Cookie cookieReadFromRequest : model.lookupConversation().getCookiesReadFromRequest()) {
                String cookieName = cookieReadFromRequest.getName();
                String cookieValue = cookieReadFromRequest.getValue();
                table.addTD("Cookie (Request):", 1, null);
                table.addTD(cookieName, 1, null);
                table.addNewRow();
                table.addTD("", 1, null);
                table.addTD(StringHelper.langenStringFuerAnzeigeAufbereiten(cookieValue), 1, null);
                table.addNewRow();
            }
        }
        table.addTD("Conversation ID:", 1, null);
        table.addTD(model.lookupConversation().getConversationID().toString(), 1, null);
        table.addNewRow();
        table.addTD("Remote IP:", 1, null);
        table.addTD(parameters.get(ServletHelper.SERVLET_REMOTE_IP), 1, null);
        table.addNewRow();
        table.addTD("LocalNetwork:", 1, null);
        table.addTD(ServletHelper.isLocalNetworkClient(parameters) + "", 1, null);
        table.addNewRow();
        table.addTD("Touch / Phone / Tablet:", 1, null);
        table.addTD(Boolean.toString(model.isClientTouchDevice()) + " / " + Boolean.toString(model.isPhone())
                + " / " + Boolean.toString(model.isTablet()), 1, null);
        table.addNewRow();
        table.addTD("Ist FullScreen:", 1, null);
        table.addTD(Boolean.toString(model.isIstWebApp()), 1, null);
        table.addNewRow();
        table.addTD("Ajax / current request:", 1, null);
        table.addTD(Boolean.toString(ServletHelper.lookupUseAjax()) + " / "
                + ServletHelper.lookupIsCurrentRequestTypeAjax(parameters), 1, null);
        table.addNewRow();
        table.addTD("Gzip Response:", 1, null);
        table.addTD(Boolean.toString(ServletHelper.lookupUseGzip(parameters)), 1, null);
        table.addNewRow();

        if (model.isPhone()) {
            sb.append(table.buildTable(model));
            table = new HTMLTable();
        }

        table.addTD("Java", 2, HTMLTable.TABLE_HEADER);
        table.addNewRow();
        table.addTD("total / max memory:", 1, attributeLeftCol);
        table.addTD(DateiZugriff.speicherGroesseFormatieren(Runtime.getRuntime().totalMemory()) + " / "
                + DateiZugriff.speicherGroesseFormatieren(Runtime.getRuntime().maxMemory()), 1, null);
        table.addNewRow();
        table.addTD("freeMemory:", 1, null);
        table.addTD(DateiZugriff.speicherGroesseFormatieren(Runtime.getRuntime().freeMemory()), 1, null);
        table.addNewRow();
        table.addTD("catalina.home:", 1, null);
        table.addTD(
                HTMLUtils.spacifyFilePath(
                        System.getProperties().getProperty(ServletHelper.SYSTEM_PROPERTY_CATALINA_HOME), model),
                1, null);
        table.addNewRow();
        table.addTD("catalina.base:", 1, null);
        table.addTD(
                HTMLUtils.spacifyFilePath(
                        System.getProperties().getProperty(ServletHelper.SYSTEM_PROPERTY_CATALINA_BASE), model),
                1, null);
        table.addNewRow();
        table.addTD("WarFile:", 1, HTMLTable.NO_BORDER);
        table.addTD(HTMLUtils.spacifyFilePath(warfilename, model), 1, HTMLTable.NO_BORDER);
        table.addNewRow();

        if (model.isPhone()) {
            sb.append(table.buildTable(model));
            table = new HTMLTable();
        }

        table.addTD("Hardware / Software", 2, HTMLTable.TABLE_HEADER);
        table.addNewRow();
        table.addTD("CPU Cores:", 1, attributeLeftCol);
        table.addTD(Runtime.getRuntime().availableProcessors() + "", 1, null);
        table.addNewRow();
        table.addTD("Architecture:", 1, null);
        table.addTD(System.getProperty("sun.arch.data.model", "") + " bit", 1, null);
        table.addNewRow();
        table.addTD("Java Version:", 1, null);
        table.addTD(System.getProperty("java.version", ""), 1, null);
        table.addNewRow();
        table.addTD("Java VM:", 1, null);
        table.addTD(System.getProperty("java.vm.name", ""), 1, null);
        table.addNewRow();
        table.addTD("Server:", 1, null);
        table.addTD(KVMemoryMap.getInstance().readValueFromKey("application.server"), 1, null);
        table.addNewRow();

        if (model.isPhone()) {
            sb.append(table.buildTable(model));
            table = new HTMLTable();
        }

        table.addTD("Cron Jobs", 2, HTMLTable.TABLE_HEADER);
        table.addNewRow();

        int a = 0;
        List<String> jobs = new LinkedList<String>();
        jobs.add("");
        for (String schedulerName : CronSchedulers.getInstance().getSchedulersIDs().keySet()) {
            jobs.add(schedulerName);
            String cssClass = a % 2 != 0 ? attributeLeftCol : HTMLUtils.buildAttribute("class", "alt");
            Scheduler s = CronSchedulers.getInstance().getSchedulers().get(schedulerName);
            table.addTD(schedulerName, 1, cssClass);
            table.addTD(((s != null && s.isStarted()) ? "@ " : "not running")
                    + CronSchedulers.getInstance().lookupCronStringOfScheduler(schedulerName), 1, cssClass);
            table.addNewRow();
            table.addTD("", 1, cssClass);
            table.addTD(CronSchedulers.getInstance().getSchedulersInstances().get(schedulerName).status(), 1,
                    cssClass);
            table.addNewRow();
            a++;
        }

        if (model.isPhone()) {
            sb.append(table.buildTable(model));
            table = new HTMLTable();
        }

        table.addTD("Manueller Job-Start", 2, HTMLTable.TABLE_HEADER);
        table.addNewRow();
        table.addTDSource(HTMLUtils.buildDropDownListe("execute_job", jobs, null), 2, null);
        table.addNewRow();
        String buttonJobStart = new Button("Job starten", Condition.SYS_EXECUTE_JOB).printForUseInTable();
        table.addTDSource(buttonJobStart, 2, HTMLTable.NO_BORDER);
        table.addNewRow();

        sb.append(table.buildTable(model));
        return;
    }

    @Responsible(conditions = { Condition.VIEW_LICENCE_ATTRIBUTION })
    public void fjLizenzbedingungenAnzeigen(StringBuilder sb, Map<String, String> parameters, Model model)
            throws Exception {

        Condition back;
        if (model.lookupConversation().getStepBackCondition() != null) {
            back = model.lookupConversation().getStepBackCondition();
        } else {
            if (model.getUser() != null) {
                back = Condition.FS_NAVIGATE;
            } else {
                back = Condition.LOGIN;
            }
        }

        sb.append(HTMLUtils.buildMenuNar(model, "Lizenzen anzeigen / View Licence Attribution", back, null, true));

        List<String> lines = null;
        try {
            String licence = "";
            URL url = this.getClass().getClassLoader().getResource("licenseattribution.txt");
            URLConnection resConn = url.openConnection();
            resConn.setUseCaches(false);
            InputStream in = resConn.getInputStream();
            StringWriter writer = new StringWriter();
            IOUtils.copy(in, writer, "UTF-8");
            licence = writer.toString();
            licence = StringUtils.remove(licence, "\r");
            lines = Arrays.asList(StringUtils.split(licence, "\n"));

        } catch (IOException e) {
            logger.error("Error loading Resource licenseattribution.txt: ", e);
        }

        buildTextviewTable("Lizenzen anzeigen / View Licence Attribution", sb, model, lines,
                model.lookupConversation().isTextViewNumbers(), true, true);

    }
}