de.willuhn.jameica.hbci.io.csv.ProfileUtil.java Source code

Java tutorial

Introduction

Here is the source code for de.willuhn.jameica.hbci.io.csv.ProfileUtil.java

Source

/**********************************************************************
 *
 * Copyright (c) 2018 Olaf Willuhn
 * All rights reserved.
 * 
 * This software is copyrighted work licensed under the terms of the
 * Jameica License.  Please consult the file "LICENSE" for details. 
 *
 **********************************************************************/

package de.willuhn.jameica.hbci.io.csv;

import java.beans.ExceptionListener;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import de.willuhn.jameica.hbci.HBCI;
import de.willuhn.jameica.hbci.gui.dialogs.CSVProfileStoreDialog;
import de.willuhn.jameica.messaging.StatusBarMessage;
import de.willuhn.jameica.system.Application;
import de.willuhn.jameica.system.OperationCanceledException;
import de.willuhn.logging.Logger;
import de.willuhn.util.I18N;

/**
 * Hilfeklasse zum Laden und Speichern von CSV-Import-Profilen.
 */
public class ProfileUtil {
    private final static I18N i18n = Application.getPluginLoader().getPlugin(HBCI.class).getResources().getI18N();

    /**
     * Laedt die vorhandenen Profile fuer das Format.
     * @param format das Format.
     * @return die Liste der Profile.
     */
    public static List<Profile> read(Format format) {
        List<Profile> result = new ArrayList<Profile>();

        if (format == null) {
            Logger.warn("no format given");
            Application.getMessagingFactory().sendMessage(
                    new StatusBarMessage(i18n.tr("Kein Format ausgewhlt"), StatusBarMessage.TYPE_ERROR));
            return result;
        }

        final Profile dp = format.getDefaultProfile();
        result.add(dp); // System-Profil wird immer vorn einsortiert

        // 1. Mal schauen, ob wir gespeicherte Profil fuer das Format haben
        File dir = new File(Application.getPluginLoader().getPlugin(HBCI.class).getResources().getWorkPath(),
                "csv");
        if (!dir.exists())
            return result;

        File file = new File(dir, format.getClass().getName() + ".xml");
        if (!file.exists() || !file.canRead())
            return result;

        Logger.info("reading csv profile " + file);
        XMLDecoder decoder = null;
        try {
            decoder = new XMLDecoder(new BufferedInputStream(new FileInputStream(file)));
            decoder.setExceptionListener(new ExceptionListener() {
                public void exceptionThrown(Exception e) {
                    throw new RuntimeException(e);
                }
            });

            // Es ist tatsaechlich so, dass "readObject()" nicht etwa NULL liefert, wenn keine Objekte mehr in der
            // Datei sind sondern eine ArrayIndexOutOfBoundsException wirft.
            try {
                for (int i = 0; i < 1000; ++i) {
                    Profile p = (Profile) decoder.readObject();
                    // Migration aus der Zeit vor dem Support mulitpler Profile:
                    // Da konnte der User nur das eine existierende Profil aendern, es wurde automatisch gespeichert
                    // Das hatte gar keinen Namen. Falls also ein Profil ohne Name existiert (inzwischen koennen keine
                    // mehr ohne Name gespeichert werden), dann ist es das vom User geaenderte Profil. Das machen wir
                    // automatisch zum ersten User-spezifischen Profil
                    if (StringUtils.trimToNull(p.getName()) == null) {
                        p.setName(dp.getName() + " 2");
                        p.setSystem(false);
                    }
                    result.add(p);
                }
            } catch (ArrayIndexOutOfBoundsException e) {
                // EOF
            }

            Logger.info("read " + (result.size() - 1) + " profiles from " + file);
            Collections.sort(result);

            // Der User hat beim letzten Mal eventuell nicht alle Spalten zugeordnet.
            // Die wuerden jetzt hier in dem Objekt fehlen. Daher nehmen wir
            // noch die Spalten aus dem Default-Profil und haengen die fehlenden noch an.
        } catch (Exception e) {
            Logger.error("unable to read profile " + file, e);
            Application.getMessagingFactory().sendMessage(new StatusBarMessage(
                    i18n.tr("Laden der Profile fehlgeschlagen: {0}", e.getMessage()), StatusBarMessage.TYPE_ERROR));
        } finally {
            if (decoder != null) {
                try {
                    decoder.close();
                } catch (Exception e) {
                    /* useless */}
            }
        }
        return result;
    }

    /**
     * Speichert die Profile.
     * @param format das Format.
     * @param profiles die zu speichernden Profile.
     */
    public static void store(Format format, List<Profile> profiles) {
        if (format == null) {
            Application.getMessagingFactory().sendMessage(
                    new StatusBarMessage(i18n.tr("Kein Format ausgewhlt"), StatusBarMessage.TYPE_ERROR));
            return;
        }

        if (profiles == null) {
            Application.getMessagingFactory().sendMessage(
                    new StatusBarMessage(i18n.tr("Keine Profile angegeben"), StatusBarMessage.TYPE_ERROR));
            return;
        }

        // 2. Mal schauen, ob wir ein gespeichertes Profil fuer das Format haben
        File dir = new File(Application.getPluginLoader().getPlugin(HBCI.class).getResources().getWorkPath(),
                "csv");
        if (!dir.exists()) {
            Logger.info("creating dir: " + dir);
            if (!dir.mkdirs()) {
                Application.getMessagingFactory()
                        .sendMessage(new StatusBarMessage(
                                i18n.tr("Ordner {0} kann nicht erstellt werden", dir.getAbsolutePath()),
                                StatusBarMessage.TYPE_ERROR));
                return;
            }
        }

        File file = new File(dir, format.getClass().getName() + ".xml");

        Logger.info("writing csv profile " + file);
        XMLEncoder encoder = null;
        try {
            encoder = new XMLEncoder(new BufferedOutputStream(new FileOutputStream(file)));
            encoder.setExceptionListener(new ExceptionListener() {
                public void exceptionThrown(Exception e) {
                    throw new RuntimeException(e);
                }
            });

            for (Profile p : profiles) {
                // Das System-Profil wird nicht mit gespeichert
                if (p.isSystem())
                    continue;

                // Ebenso Profile ohne Namen.
                if (StringUtils.trimToNull(p.getName()) == null)
                    continue;

                encoder.writeObject(p);
            }
        } catch (Exception e) {
            Logger.error("unable to store profile " + file, e);
        } finally {
            if (encoder != null) {
                try {
                    encoder.close();
                } catch (Exception e) {
                    /* useless */}
            }
        }
    }

    /**
     * Fuegt ein neues Profil hinzu.
     * @param format das Format.
     * @param profile das zu speichernde Profil.
     * @return das hinzugefuegte oder geaenderte Profil. NULL, wenn nicht gespeichert wurde.
     */
    public static Profile add(Format format, Profile profile) {
        try {
            if (profile == null || format == null) {
                Application.getCallback().notifyUser(i18n.tr("Kein Profil angegeben"));
                return null;
            }

            // Der Dialog uebernimmt auch gleich das Speichern.
            CSVProfileStoreDialog d = new CSVProfileStoreDialog(format, profile);
            return (Profile) d.open();
        } catch (OperationCanceledException oce) {
            // ignore
        } catch (Exception e) {
            Logger.error("unable to delete profile", e);
        }
        return null;
    }

    /**
     * Loescht das angegebene Profil.
     * @param format das Format.
     * @param profile das zu speichernde Profil.
     * @return true, wenn das Profil geloescht wurde.
     */
    public static boolean delete(Format format, Profile profile) {
        if (profile == null || format == null)
            return false;

        try {
            if (profile.isSystem()) {
                Application.getCallback().notifyUser(i18n.tr("Das Default-Profil darf nicht gelscht werden"));
                return false;
            }

            List<Profile> profiles = ProfileUtil.read(format);
            boolean found = false;
            for (Profile p : profiles) {
                if (p.isSystem())
                    continue;

                if (p.getName().equals(profile.getName())) {
                    profiles.remove(p);
                    found = true;
                    break;
                }
            }

            // Nichts zum Loeschen gefunden
            if (!found)
                return false;

            // Speichern
            ProfileUtil.store(format, profiles);
            return true;
        } catch (OperationCanceledException oce) {
            // ignore
        } catch (Exception e) {
            Logger.error("unable to delete profile", e);
        }
        return false;
    }
}