/* $Id: MyDataStore.java,v 1.5 2005/06/10 18:03:03 kleiner Exp $
This file is part of HBCI4Java
Copyright (C) 2001-2005 Stefan Palme
HBCI4Java is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
HBCI4Java 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.kapott.demo.hbci.server;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;
import org.kapott.hbci.exceptions.HBCI_Exception;
import org.kapott.hbci.manager.HBCIKey;
import org.kapott.hbci.server.StatusProtEntry;
import org.kapott.hbci.server.datastore.DataStore;
import org.kapott.hbci.status.HBCIRetVal;
import org.kapott.hbci.structures.Konto;
/* eigene implementation eines DataStores, welche alle dynamischen
Serverdaten in Dateien im Filesystem ablegt */
public class MyDataStore
implements DataStore
{
private String directory;
// mit Verzeichnis fr die Speicherung der einzelnen Dateien initialisieren
public MyDataStore(String directory)
{
this.directory=directory;
}
// einzeiligen Wert aus einer Datei einlesen
public synchronized String getSingleLine(String filename)
{
try {
// System.out.println("reading "+what);
BufferedReader in=new BufferedReader(new FileReader(directory+File.separator+filename));
String st=in.readLine();
in.close();
return st;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// einzeiligen Wert in einer Datei speichern
public synchronized void storeSingleLine(String data,String filename)
{
try {
// System.out.println("writing "+what);
PrintWriter out=new PrintWriter(new BufferedWriter(new FileWriter(directory+File.separator+filename)));
out.println(data);
out.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// mehrzeiligen Dateiinhalt als Array zurckgeben
public synchronized String[] getMultipleLines(String filename)
{
try {
// System.out.println("reading "+what);
BufferedReader in=new BufferedReader(new FileReader(directory+File.separator+filename));
ArrayList data=new ArrayList();
String st;
while ((st=in.readLine())!=null) {
if (st.trim().length()!=0)
data.add(st.trim());
}
in.close();
return (String[])data.toArray(new String[0]);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public synchronized void storeMultipleLines(String[] data,String filename)
{
try {
// System.out.println("writing "+what);
PrintWriter out=new PrintWriter(new BufferedWriter(new FileWriter(directory+File.separator+filename)));
for (int i=0;i<data.length;i++) {
out.println(data[i]);
}
out.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// Schlsseldaten aus Datei einlesen (wird ber Objektserialisierung realisiert)
private synchronized HBCIKey[] getXKeys(String prefix)
{
// System.out.println("reading "+prefix+" keys");
HBCIKey[] ret=null;
try {
ObjectInputStream in=new ObjectInputStream(new FileInputStream(directory+File.separator+prefix+"_keys"));
ret=(HBCIKey[])in.readObject();
in.close();
} catch (Exception e) {
System.out.println(" no "+prefix+"_keys found");
}
return ret;
}
// Schlsseldaten in Datei schreiben (via Objektserialisierung)
private synchronized void storeXKeys(HBCIKey[] keys,String prefix)
{
// System.out.println("writing "+prefix+" keys");
try {
ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream(directory+File.separator+prefix+"_keys"));
out.writeObject(keys);
out.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// Loglevel aus Datei "loglevel" zurckgeben
public int getLogLevel()
{
return Integer.parseInt(getSingleLine("loglevel"));
}
// Verbindungsarbten zurckgeben
public String[] getListeners()
{
return getMultipleLines("listeners");
}
// Lndercode ist fest "DE"
public String getCountry()
{
return "DE";
}
// Bankleitzahl aus Datei "blz" zurckmelden
public String getBLZ()
{
return getSingleLine("blz");
}
// Name der "Testbank" aus Datei "kiname" auslesen und zurckmelden
public String getKIName()
{
return getSingleLine("kiname");
}
// Kommunikationsdaten zurckmelden, IP-Adresse dafr aus Datei "address" einlesen
public String[][] getCommData(String hbciversion)
{
return new String[][] {{"2",getSingleLine("address"),null,null,null},
{"3",getSingleLine("pintanurl"),null,"MIM","1"}};
}
// liste der zu untersttzenden Sprachen aus datei "languages" einlesen
public String[] getSuppLangs(String hbciversion)
{
return getMultipleLines("languages");
}
// standardsprache ist immer erste sprache, die via getSuppLangs() zurckgemeldet wird
public String getDefaultLang(String hbciversion)
{
return getSuppLangs(hbciversion)[0];
}
// liste der zu untersttzenden HBCI-versionsn aus datei "hbciversions" einlesen
public String[] getSuppHBCIVersions()
{
return getMultipleLines("hbciversions");
}
// noch keine kompression untersttzt
public String[][] getSuppCompMethods(String hbciversion)
{
return new String[0][];
}
// untersttzte sicherheitsmechanismen hardcoded (nur RDH)
public String[][] getSuppSecMethods(String hbciversion)
{
return new String[][] {{"RDH","1"}};
}
// anonyme anfragen erlaubt
public boolean isAnonAllowed()
{
return true;
}
// liste der zu untersttzenden geschftsvorflle aus datei "jobs_X" einlesen,
// wobei X die hbciversion ist, fr die diese liste gelten soll
public String[] getSupportedGVs(String hbciversion)
{
return getMultipleLines("jobs_"+hbciversion);
}
// liste der jobs, die via pin/tan untersttzt werden
public Properties getPinTanGVs()
{
Properties ret=new Properties();
String[] jobs=getMultipleLines("jobs_pintan");
for (int i=0;i<jobs.length;i++) {
StringTokenizer tok=new StringTokenizer(jobs[i],":");
String jobname=tok.nextToken();
String needsTan=tok.nextToken();
ret.setProperty(jobname,needsTan);
}
return ret;
}
// liste der zu untersttzenden GV-versionen fr einen GV aus der datei "JOB_versions_VERSION"
// einlesen, wobei JOB der name des GVs und VERSION die hbciversion ist, fr die diese
// liste gelten soll
public int[] getGVVersions(String gvname,String hbciversion)
{
String[] st=getMultipleLines(gvname+"_versions_"+hbciversion);
int[] ret=new int[st.length];
for (int i=0;i<st.length;i++)
ret[i]=Integer.parseInt(st[i]);
return ret;
}
// mindestanzahl der bentigten signaturen fr einen bestimmten GV aus der datei
// "GVNAME_minsigs" auslesen (die version des GVs wird dabei also ignoriert)
public int getGVMinSigs(String gvname,int gvversion)
{
return Integer.parseInt(getSingleLine(gvname+"_minsigs"));
}
// mindestanzahl der bentigten signaturen fr einen bestimmten GV aus der datei
// "GVNAME_maxnum" auslesen (die version des GVs wird dabei also ignoriert)
public int getGVMaxNum(String gvname,int gvversion)
{
return Integer.parseInt(getSingleLine(gvname+"_maxnum"));
}
// parameterdaten fr einen GV aus der datei "GVNAME_params" auslesen
public Properties getGVParams(String gvname,int gvversion)
{
try {
// System.out.println("reading params of job "+gvname+gvversion);
Properties ret=new Properties();
InputStream in=new FileInputStream(directory+File.separator+gvname+"_params");
ret.load(in);
in.close();
return ret;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// max. anzahl der GVs pro hbci-nachricht aus datei "gvspermsg" auslesen
public int getNumOfGVsPerMsg(String hbciVersion)
{
return Integer.parseInt(getSingleLine("gvspermsg"));
}
// max. erlaubte nachrichtengre aus datei "maxmsgsize" auslesen
public int getMaxMsgSize(String hbciVersion)
{
return Integer.parseInt(getSingleLine("maxmsgsize"));
}
// usw. usf.
public int getBPDVersion(String hbciVersion)
{
return Integer.parseInt(getSingleLine("bpdversion_"+hbciVersion));
}
// signaturschlssel der bank aus datei "sig_keys" auslesen
public HBCIKey[] getSigKeys()
{
return getXKeys("sig");
}
// neue bankensignaturschlssel in datei "sig_keys" speichern
public void setSigKeys(HBCIKey[] keys)
{
storeXKeys(keys,"sig");
}
public HBCIKey[] getCryptKeys()
{
return getXKeys("enc");
}
public void setCryptKeys(HBCIKey[] keys)
{
storeXKeys(keys,"enc");
}
public Long getSigId()
{
return new Long(getSingleLine("sigid"));
}
public void setSigId(Long sigid)
{
storeSingleLine(sigid.toString(),"sigid");
}
// gltige nutzerkennungen aus datei "userids" auslesen
public String[] getUserIds()
{
return getMultipleLines("userids");
}
// kunden-ids fr einen nutzer aus datei "USERID_customerids" auslesen
public String[] getCustomerIds(String userid)
{
return getMultipleLines(userid+"_customerids");
}
// kontodaten fr einen nutzer aus datei "USERID_accounts" einlesen
// format je zeile: "KONTONUMMER|KONTOBEZEICHNUNG|NAME_DES_INHABERS|KUNDEN-ID"
// als Lnderkennung und BLZ fr die Kontoverbindung werden die gleichen daten
// wie fr den Server benutzt (getCountry()/getBLZ()); als Whrung wird "EUR" benutzt
public Konto[] getAccounts(String userid)
{
String[] accountData=getMultipleLines(userid+"_accounts");
ArrayList ret=new ArrayList();
for (int i=0;i<accountData.length;i++) {
StringTokenizer tok=new StringTokenizer(accountData[i],"|");
Konto acc=new Konto();
acc.number=tok.nextToken();
acc.type=tok.nextToken();
acc.name=tok.nextToken();
acc.customerid=tok.nextToken();
acc.country=getCountry();
acc.blz=getBLZ();
acc.curr="EUR";
ret.add(acc);
}
return (Konto[])ret.toArray(new Konto[0]);
}
public int getAccountInfoVersion(String userid)
{
return Integer.parseInt(getSingleLine(userid+"_accinfoversion"));
}
public String[] getSysIds(String userid)
{
return getMultipleLines(userid+"_sysids");
}
public void addSysId(String userid,String sysid)
{
try {
PrintWriter out=new PrintWriter(new FileWriter(directory+File.separator+userid+"_sysids",true));
out.println(sysid);
out.close();
storeMultipleLines(new String[0],userid+"_sigids_"+sysid);
} catch (Exception e) {
throw new HBCI_Exception(e.getMessage());
}
}
// ffentliche schlssel eines nutzers aus dateien "USERID_sig_keys" und
// "USERID_enc_keys" einlesen
public HBCIKey[] getUserKeys(String userid)
{
HBCIKey[] sig=getXKeys(userid+"_sig");
HBCIKey[] enc=getXKeys(userid+"_enc");
return (sig!=null)?(new HBCIKey[] {sig[0],enc[0]}):null;
}
public String getUserPIN(String userid)
{
return getSingleLine(userid+"_pt_pin");
}
public void setUserPIN(String userid,String pin)
{
storeSingleLine(pin,userid+"_pt_pin");
}
public String[] getUserTANList(String userid)
{
return getMultipleLines(userid+"_pt_tans");
}
public void setUserTANList(String userid,String[] tans)
{
storeMultipleLines(tans,userid+"_pt_tans");
}
public void removeUserTAN(String userid,String tan)
{
String[] tans=getMultipleLines(userid+"_pt_tans");
List tanlist=new ArrayList(Arrays.asList(tans));
tanlist.remove(tan+":1");
tanlist.add(tan+":0");
storeMultipleLines((String[])tanlist.toArray(new String[0]),
userid+"_pt_tans");
}
// signierschlssel eines nutzers in "USERID_sig_keys" speichern
public void storeUserSigKey(String userid,HBCIKey key)
{
storeXKeys((key!=null)?(new HBCIKey[] {key}):null,userid+"_sig");
}
public void storeUserEncKey(String userid,HBCIKey key)
{
storeXKeys((key!=null)?(new HBCIKey[] {key}):null,userid+"_enc");
}
// schon eingereichte sigids zurckmelden
public long[] getSigIds(String userid,String sysid)
{
String[] sigids_s=getMultipleLines(userid+"_sigids_"+sysid);
int len=sigids_s.length;
long[] sigids_l=new long[len];
for (int i=0;i<len;i++) {
sigids_l[i]=Long.parseLong(sigids_s[i]);
}
return sigids_l;
}
// liste der schon eingereichten sigids resetten
public void clearSigIds(String userid,String sysid)
{
storeMultipleLines(new String[0],userid+"_sigids_"+sysid);
}
// signatur-ids zur liste der schon eingereichten ids hinzufgen
public void addSigId(String userid,String sysid,long sigid)
{
try {
PrintWriter out=new PrintWriter(new FileWriter(directory+File.separator+userid+"_sigids_"+sysid,true));
out.println(sigid);
out.close();
} catch (Exception e) {
throw new HBCI_Exception(e.getMessage());
}
}
public synchronized void addToStatusProt(String userid,StatusProtEntry entry)
{
try {
PrintWriter out=new PrintWriter(new FileWriter(directory+File.separator+userid+"_statusprot",true));
// TODO auch parameter ins status-protokoll schreiben
out.println(
new SimpleDateFormat("yyyyMMddHHmmss").format(entry.timestamp)+"|"+
entry.dialogid+"|"+
entry.msgnum+"|"+
((entry.segref!=null)?entry.segref:"<>")+"|"+
entry.retval.code+"|"+
((entry.retval.deref!=null)?entry.retval.deref:"<>")+"|"+
entry.retval.text
);
out.close();
} catch (Exception e) {
throw new HBCI_Exception(e.getMessage());
}
}
public StatusProtEntry[] getStatusProt(String userid,Date start,Date end)
{
try {
ArrayList ret=new ArrayList();
String[] statusdata=getMultipleLines(userid+"_statusprot");
for (int i=0;i<statusdata.length;i++) {
String line=statusdata[i];
StringTokenizer tok=new StringTokenizer(line,"|");
String timestamp_s=tok.nextToken();
Date timestamp=new SimpleDateFormat("yyyyMMddHHmmss").parse(timestamp_s);
Date date=new SimpleDateFormat("yyyyMMdd").parse(timestamp_s.substring(0,8));
if ((start==null || date.compareTo(start)>=0) &&
(end==null || date.compareTo(end)<=0)) {
StatusProtEntry entry=new StatusProtEntry();
entry.timestamp=timestamp;
entry.dialogid=tok.nextToken();
entry.msgnum=tok.nextToken();
entry.segref=tok.nextToken();
if (entry.segref.equals("<>")) {
entry.segref=null;
}
String code=tok.nextToken();
String deref=tok.nextToken();
String text=tok.nextToken();
// TODO param auch zurckgeben
String[] params=null;
if (deref.equals("<>")) {
deref=null;
}
entry.retval=new HBCIRetVal(
entry.segref,deref,null,
code,text,params);
ret.add(entry);
}
}
return (StatusProtEntry[])ret.toArray(new StatusProtEntry[0]);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}