/* $Id: HBCIServer.java,v 1.3 2005/06/10 18:03:02 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.hbci.server; import java.util.Iterator; import java.util.List; import org.kapott.hbci.exceptions.HBCI_Exception; import org.kapott.hbci.manager.HBCIUtils; import org.kapott.hbci.server.datastore.DataStore; import org.kapott.hbci.server.listener.ConnectionListener; /** Diese Klasse reprsentiert einen HBCI-Server. Eine HBCI-Server-Anwendung muss eine Instanz dieser Klasse erzeugen. Anschlieend kann der HBCI-Server mit {@link #start()} gestartet werden. */ public class HBCIServer { private CleanupThread cleanup; /** Erzeugen einer HBCI-Server-Instanz. Intern wird eine Reihe von Datenstrukturen fr den Betrieb eines HBCI-Servers initialisiert. Die beiden bergebenen Argumente mssen Objekte sein, die die jeweiligen Interfaces implementieren (und drfen nicht <code>null</code> sein!). Die Methoden dieser Interfaces werden vom Server-Code aus aufgerufen, um mit der HBCI-Server-Anwendung (und damit indirekt wahrscheinlich mit dem Backend-System der Bank) zu kommunizieren. @param dataStore Objekt, welches intern benutzt wird, um Zugriff auf Laufzeitdaten des Servers zu erhalten (Nutzerkennungen, untersttzte Geschftsvorflle usw.) @param callback Objekt, dessen Methoden aufgerufen werden, wenn whrend eines HBCI-Dialoges mit einem HBCI-Client bestimmte Ereignisse auftreten (z.B. das Eintreffen eines Auftrages). */ public HBCIServer(DataStore dataStore,ServerCallback callback) { if (dataStore==null) throw new NullPointerException("dataStore must not be zero"); if (callback==null) throw new NullPointerException("callback must not be zero"); // Serverdaten initialisieren ServerData.getInstance().setCallbackObject(callback); HBCIUtils.init(null,null,new HBCICallbackInternal()); HBCIUtils.setParam("log.loglevel.default",Integer.toString(dataStore.getLogLevel())); ServerData.getInstance().init(dataStore); } /** Starten des HBCI-Servers. Diese Methode blockiert, solange der Server luft. Soll die HBCI-Server-Anwendung also noch andere Aufgaben erledigen (z.B. die externe Steuerung des HBCI-Servers ermglichen [siehe {@link #stop()} oder {@link #reInitializeServerData()}]), so muss ein zustzlicher Thread erzeugt werden. Die <code>start()</code>-Methode muss aus der gleichen <code>ThreadGroup</code> aufgerufen werden die der <code>HBCIServer()</code>-Constructor. */ public void start() { try { HBCIUtils.log("starting HBCI server",HBCIUtils.LOG_INFO); List listeners=ServerData.getInstance().getListeners(); for (Iterator i=listeners.iterator();i.hasNext();) { final ConnectionListener listener=(ConnectionListener)i.next(); String name=listener.getName(); HBCIUtils.log("starting connection listener '"+name+"'", HBCIUtils.LOG_INFO); new Thread(new ThreadGroup("listener-"+name),"listener-"+name) { public void run() { HBCIUtils.initThread(null,null); HBCIUtils.setParam("log.loglevel.default", Integer.toString(ServerData.getInstance().getLogLevel())); listener.start(); } }.start(); } (cleanup=new CleanupThread()).start(); HBCIUtils.log("falling asleep",HBCIUtils.LOG_DEBUG); synchronized (this) { wait(); } HBCIUtils.log("server is exiting",HBCIUtils.LOG_DEBUG); } catch (Exception e) { throw new HBCI_Exception("error while creating server socket",e); } } /** <p>Aktualisieren der vom HBCI-Server verwendeten Laufzeitdaten. Beim Starten des HBCI-Servers (siehe {@link #start()}) wird das <code>dataStore</code>-Objekt (siehe {@link #HBCIServer(DataStore,ServerCallback)}) benutzt, um einige Daten der Laufzeitumgebung zu initialisieren. Whrend der Laufzeit des Servers werden diese Daten nicht immer wieder ber dieses Interface abgefragt, sondern es wird ein Groteil dieser Informationen innerhalb des HBCI4Java-Server-Codes gecacht. Eine nachtrgliche Vernderung der Daten, die von den <code>dataStore</code>-Methoden zurckgegeben werden, hat also u.U. keine Auswirkung auf den HBCI-Server.</p> <p>Durch den Aufruf dieser Methode wird der HBCI-Server gezwungen, smtliche Caches zu lschen und alle bentigten Daten erneut ber das <code>dataStore</code>-Objekt abzufragen.</p> <p>Diese Methode kann natrlich nur aufgerufen werden, wenn der Server luft (siehe {@link #start()}). Da ein laufender Server aber die <code>start()</code>-Methode blockiert, muss die Server-Anwendung mehrere Threads realisieren, wobei in einem Thread die <code>start()</code>-Methode (und damit der Server) luft, aus einem andern Thread heraus kann <code>reInitializeServerData()</code> aufgerufen werden.</p>*/ public void reInitializeServerData() { ServerData.getInstance().reInitializeServerData(); } /** Aktualisieren der server-internen Daten fr einen bestimmten Nutzer. Es werden die serverseitig gecachten nutzerbezogenen Daten fr die angegebene <code>userid</code> als ungltig markiert, so dass diese vor der nchsten Verwendung neu vom {@link org.kapott.hbci.server.datastore.DataStore} abgeholt werden. Es gelten die gleichen Anmerkungen wie fr die Methode {@link #reInitializeServerData()}. @param userid Nutzer-ID, fr die die Daten vor der nchsten Verwendung neu geladen werden sollen. */ public void reInitializeUserData(String userid) { ServerData.getInstance().reInitializeUserData(userid); } /** Damit kann ein laufender Server wieder gestoppt werden. Es gelten die gleichen Anmerkungen zum MultiThreading wie bei der Methode {@link #reInitializeServerData()}.*/ public void stop() { cleanup.quit(); List listeners=ServerData.getInstance().getListeners(); for (Iterator i=listeners.iterator();i.hasNext();) { final ConnectionListener listener=(ConnectionListener)i.next(); String name=listener.getName(); HBCIUtils.log("stopping connection listener '"+name+"'", HBCIUtils.LOG_INFO); listener.stop(); } HBCIUtils.log("awaking server main thread",HBCIUtils.LOG_DEBUG); synchronized (this) { notify(); } } }