|
Letzte
Bearbeitung dieses Dokuments: |
Voraussetzungen für das Verständnis dieses Dokuments:Grundkenntnisse in
der Programmierung von Java (Klassen, Methoden,
Schleifen). |
Ungefährer Zeitbedarf zum Durcharbeiten dieses Dokuments:Arbeitszeit:
Für das Implementieren komplexerer Abfragen hängt der Arbeitsaufwand stark von der Aufgabe und der Routine ab. Eine Schätzung des Zeitaufwandes kann in diesen Fällen nicht gegeben werden. |
Dieses Dokument enthält Code-Muster für eine einfache Client-Side-Klasse mit einer Liste mit BO (BOC_Set) und Erweiterungen, die entsprechend den jeweiligen Anforderungen zusätzlich implementiert werden können.
Einfacher Muster-Code für ein BOC_Set
Anleitung
zur Adaptierung
* Änderung
des Namens der Java-Packages der Anwendung
* Änderung
des Namens der Klasse des CommandCenters
* Änderung
des Namens dieser Klasse und der Klassen der zugehörigen
Generellen und Server-Side BO
* Adaptieren
des Kommentars
* Definitionen
der symbolischen Namen und deren Verwendung in der Methode
buildRawDataVector()
* Erstellen
der 'Werte-Zeilen' der Matrix in der Methode buildRawDataVector()
*
Vorbereitende Tätigkeiten bei Entwicklung einer 'MobileClient'
Version des Anwendungsprogramms
*
Verändern der Methode synchronizeBO() wenn eine 'MobileClient'
Version nicht verwendet wird
Generelle
Tätigkeiten bei Verwendung von EJB
(Client-Server-Architektur)
* Methode
selectByVariables(String
parmVariable_1,
String parmVariable_2)
des BOS
daptieren
* Methode
selectByVariables(String
parmVariable_1,
String parmVariable_2)
des EJB adaptieren
* Bei Version 'MobileClient': Codieren der Sortier-Methode(n)
Weitere Schritte und verwandte Dokumentation
Tutorial für die Programmierung eines Heavyweight-Clients (Fat-Client) durchgearbeitet.
Datenmodell fertig ausgearbeitet.
Generelle Klasse für das BO erstellt; siehe Muster-Code für ein BO (Generelle Klasse eine Business-Object).
Wenn das
Anwendungsprogramm als Client/Server-Anwendung konzipiert ist, ist
es hilfreich, zuerst das EJB und die Klasse für die Verbindung
zum JAS (Java Application Server) zu codieren.
Die Anleitung für
das Entwickeln der Klasse mit dem Standard-EJB finden Sie unter
Leitfaden
für die Entwicklung von Heavyweight-Clients mit dem JS-FCF –
Alle Schritte zur Entwicklung von DBA (DataBase-Access) und BO
(Business-Object) Klassen > Leitfaden - EJB.
Die
Anleitung für das Entwickeln der Klasse für die Verbindung
zum JAS finden Sie unter Leitfaden
für die Entwicklung von Heavyweight-Clients mit dem JS-FCF –
Alle Schritte zur Entwicklung des Start-Frames > Leitfaden –
Schritte bei einer Client/Server Version.
Welche Platzhalter
durch Bezeichnungen des eigentlichen Projektes zu ersetzen sind
finden Sie im Abschnitt
Anleitung
zur Adaptierung.
package
application_package
.boc;
/*
* Package
und Klasse für die Herstellung der Connection zur Datenbank.
*/import
java.sql.Connection;
import
js_base.connections.JSBS_DB_ConnectionManager;
/*
/*
* Package
und Klasse die beim Auftreten von Fehlern bei der Verbindung zum
JAS
* (Java Application Server) benötigt wird.
*/import
java.rmi.RemoteException;
/*
* Package
mit der Bibliothek für den Vector, der für den Aufbau der
Liste mit den formatierten
* Daten benötigt wird.
*/import
java.util.*;
/*
*
Package mit der Bibliothek der GUI-Elemente. */import
javax.swing.*;
/*
*
Package mit der Basisklasse für Konstanten und Fehler für
die BOs. */import
js_base.bo.*;
/*
*
Package mit der Basisklasse für Start- und Task-Frame. */import
js_base.frame.*;
/*
*
Package mit der Basisklasse mit dem minimalen Set an Parametern für
die
* Übergabe bei der Konstruktion eines BOS.
*/import
js_base.structures.JSBS_MinimalParameters;
/*
*
Package mit der Basisklasse für die Formattierung von Werten.
*/import
js_base.utilities.JSBS_Formatter;
/*
*
Klasse für das CommandCenter (Start-Frame) der Anwendung.
*/import
application_package
.client.
application
_CommandCenter;
/*
* Packages
mit der zugehörigen Klassen (Generelle Klasse und
Server-Side-Klasse) dieses BO. */import
application_package
.bo.*;
import
application_package
.bos.
application_entity
_BOS_Set;
/**
*
* @author
name[at]company
* @date
20xx-xx-xx
*
* @description
* Client-Seitige
Klasse für eine Liste von Business-Objects
* der
Klasse application_entity
_BO.
* Für
eine Beschreibung des BO sehen Sie bitte im Kommentar
* der
Klasse application_entity
_BO
nach.
*
* @change-log
* when who why
* -----------------------------------------------------------------
*
*/public
class
application_entity
_BOC_Set
extends
application_entity
_BO_Set
{
/* ---------------------
* KONSTANTE für die symbolischen Namen der
'Spalten' in der Matrix der formatierten
Daten.
* ---------------------
* Diese
symbolischen Namen werden in der Methode 'buildRawDataVector'
verwendet.
* Über XML-Parameter in der Datei
'DisplayStrings.xml' wird damit die Anordnung der
* Spalten
für die Auswahl-Tabelle gesteuert. */
public
static final
String
CONST_ColumnName_
SymbolicName_1
=
"
SymbolicName_1
"
;
public
static final
String
CONST_ColumnName_
SymbolicName_2
=
"
SymbolicName_2
"
;
public
static final
String
CONST_ColumnName_
SymbolicName_3
=
"
SymbolicName_3
"
;
/* ---------------------
* VARIABLE dieser Klasse.
* ---------------------
*/
/*
* Referenz
auf das Task-Frame, das das Objekt dieser Klasse 'konstruiert'
hat.
* Über diese Referenz werden jene Parameter
abgefragt, die bestimmen, ob der zugehörige
* Server-Side
Teil des BO direkt 'konstruiert' werden soll (bei einer StandAlone /
Einzelplatz-
* Version) oder ein EJB (Enterprise Java
Bean) aufgerufen werden muß (bei
einer
* Client/Server-Version). */
private
JSBS_TaskFrame
frmTask
=
null
;
/*
* Referenz
auf das CommandCenter (Start-Frame) der Anwendung.
* Die
Referenz auf diese Klasse wird gebraucht, weil dort die 'Home
interface(s)'
* der EJB (Enterprise Java Beans)
implementiert sind.
* Diese(s) EJB sind speziell für
die Anwendung entwickelt.
*
Damit kann nicht über die Basisklassen auf die (auf der
Client-Seite) implementierte(n)
* 'Home interface(s)'
zugegriffen werden. */
private
application
_CommandCenter
frmCC
=
null
;
/*
* Struktur
mit den minimalen Parametern, die beim Konstruieren eines BOS
* übergeben werden müssen. */
private
JSBS_MinimalParameters
structMinParm
;
/*
* Referenz
zu der in diesem Objekt geöffnete DB-Connection.
* Dieser
Wert ist notwendig wenn das Anwendungsprogramm im Einzelplatz-Modus
(stand-alone)
* konfiguriert ist. */
private
Connection
structDBCon
=
null
;
/*
* Nummer
der in diesem Objekt geöffneten 'Connection' zur Datenbank.
*/
private
int
intDBConReference
=
0;
/*
* Objekt
für den Abgleich bei einer 'MobileClient' Version.
* In
der Klasse ist implementiert, wie die Daten eines mobile Client mit
den Daten
* am Server abgeglichen werden wenn der
mobile Client wieder mit dem Server verbunden ist.
* Wenn
eine 'MobileClient' Version implementiert ist dann muss die folgende
Zeile
* 'auskommentiert' werden. *///
private
application_entity
_BO_Synchronizer
struct
application_entity
_BO_Synchronizer
=
null
;
/* ---------------------
* CONSTRUCTOR-METHODE *//* ---------------------
* Als Parameter des 'Constructors' sind das
aufrufende Task-Frame und
* das 'CommandCenter'
(Start-Frame) erforderlich. */
public
application_entity
_BOC_Set(
application
_CommandCenter
parmfrmCC,
JSBS_TaskFrame parmfrmTask)
{
/*
* Die im Parameter übergebenen Referenzen auf
Start-Frame und Task-Frame
* werden in den Variablen
dieser Klasse 'aufgehoben'. */
frmCC
=
parmfrmCC;
frmTask
=
parmfrmTask;
}/*
* 'Constructors'
für den Fall, dass das BOC im 'CommandCenter' (Start-Frame)
* verwendet wird. */
public
application_entity
_BOC_Set(
application
_CommandCenter
parmfrmCC) {
/*
* Die im Parameter übergebene Referenz auf das
Start-Frame wird in der
* Variable dieser Klasse
'aufgehoben'. */
frmCC
=
parmfrmCC;
frmTask
=
null
;
/*
* Die Struktur mit den minimal notwendigen Parametern
für die Konstruktion
* eines BOS werden aus der
Struktur mit allen Parametern gebildet. */
structMinParm
=
new
JSBS_MinimalParameters(
frmCC
.
structJSBS_UniversalParameters
);
}/* ---------------------------
*/
/*
* METHODE
zum Eröffnen einer Verbindung zur Datenbank
(DB-Connection).
* Über den übergebenen
Parameter (parmReadOnly) wird gesteuert ob die DB-Connection
* im
'autocommit'-Modus geöffnet werden soll.
* Wenn
nur von der Datenbank gelesen werden soll ist die Übergabe von
'true' als
* Parameter-Wert sinnvoll weil dann mit
'autocommit' geöffnet wird und damit ein
* schnellerer
Zugriff (bessere Performanz) erreicht wird.
*
* Der
Rückgabe-Wert
* signaliesiert ob die Verbindung
zur Datenbank (DB-Connection) erfolgreich eröffnet wurde.
*/
private
boolean
getDatabaseConnection(
boolean
parmReadOnly)
{
/*
* Anfordern einer DB-Verbindung vom
DB-Connection-Manager.
* Die Referenz-Nummer wird in
der globalen Variable dieser Klasse gespeichert.
*/
intDBConReference
=
frmCC
.
structJSBS_DB_ConnectionManager
.reserveConnection(
this
,
parmReadOnly);
/*
* Prüfen ob eine Verbindung zur Datenbank
hergestellt werden konnte.
* Eine Referenz-Nummer
gleich oder größer '0' bedeutet eine ordnungsgemäße
Verbindung zur DB. */
if
(
intDBConReference
<
0) {
/* Verbindung
zur Datenbank konnte nicht hergestellt werden.
* Status-Code
(auf Fehler) setzen und Fehlermeldung übernehmen.
*/
StatusCode
=
JSBS_BO
.
CONST_DB_SYSTEM_ERROR
;
StatusMsg
=
frmCC
.
structJSBS_DB_ConnectionManager
.
StatusMsg
;
/*
* Fehler an aufrufende Methode signalisieren.
*/
return
false
;
}/*
* Anfordern einer DB-Verbindung war fehlerfrei;
* Referenz auf die DB-Verbindung in die Variable der
Klasse übernehmen und
* erfolgreiche Anforderung
an aufrufende Methode signalisieren. */
structDBCon
=
frmCC
.
structJSBS_DB_ConnectionManager
.getReservedConnection(
this
,
intDBConReference
);
return
true
;
}/* ---------------------
* METHODE zum Aufbau der Matrix mit den formatierten
Daten.
* ---------------------
* In
dieser Matrix sind in der ersten Zeile die symbolischen Spalten-Namen
enthalten.
* Über XML-Parameter in der Datei
'DisplayStrings.xml' wird damit die Anordnung der
* Spalten
für die Auswahl-Tabelle gesteuert.
* Die 'Matrix'
besteht aus einem 'Vector' der für jede Zeile wieder einen
'Vector'
* mit den Daten für die Spalten
enthält.
* In der ersten 'Reihe' der Matrix sind
die symbolischen Spaltennamen enthalten. */
public
void
buildRawDataVector()
{
/*
* Vector für die Zeilen leeren; dieser Vector ist
in der geerbten Basisklasse definiert.
*/
vecRawDisplayData
.removeAllElements();
/*
* Neuen 'Vector' für die erste Zeile
'konstruieren'; diese Zeile enthält die
* symbolischen
Namen für die Spalten. */
Vector
vecHeader = new
Vector();
/* Die
Konstante für die Zeilen-Nummer ist in der geerbten Basisklasse
definiert.
*/
vecHeader.addElement(
CONST_ColumnName_RowNr
);
vecHeader.addElement(
CONST_ColumnName_
SymbolicName_1
);
vecHeader.addElement(
CONST_ColumnName_
SymbolicName_2
);
vecHeader.addElement(
CONST_ColumnName_
SymbolicName_3
);
/* Die
gerade erstellte 'Zeile' einfügen.
*/
vecRawDisplayData
.addElement(vecHeader);
/*
* In einer for-Schleife die Daten dieses BO-Set in die
Matrix einfügen. */
int
locintVectorIndex;
int
locintVectorSize
=
vecRecordSet
.size();
for
(locintVectorIndex
= 0; locintVectorIndex < locintVectorSize; locintVectorIndex++)
{
/*
* Neuen 'Vector' für die Zeile 'konstruieren'.
*/
Vector
vecData = new
Vector();
/* Die
Zeilennummer einfügen; das Formatieren erfolgt in der Methode
zum Füllen der Tabelle.
*/
vecData.addElement(locintVectorIndex
+ 1);
/*
* Das indizierte BO aus der Liste mit den (von der
Datenbank gelesenen) BO 'herauslösen'.
* Die Werte
werden auf ein neu 'konstruiertes' BO kopiert weil innerhalb des
Vector
* nur mit Referenzen gearbeitet wird und
deswegen ein Objekt, auf das der Vector 'zeigen'
* kann,
notwendig ist. */
application_entity
_BO
tmp
application_entity
_BO
=
new
application_entity
_BO();
tmpapplication_entity
_BO.copyFrom
application_entity
_BO(
(application_entity
_BO)
vecRecordSet
.elementAt(locintVectorIndex));
/*
* Werte der Variablen aus dem 'herausgelösten' BO
in den 'Matrix'-Vector einfügen.
* Die ersten
beiden Beispiele sind für Variablen vom Java-Typ 'String'.
*/
vecData.addElement(tmpapplication_entity
_BO.
Variable_1
);
vecData.addElement(tmpapplication_entity
_BO.
Variable_2
);
/*
* Variable eines 'numerischen' Java-Typs werden nicht
vor dem Einfügen in den Vector formatiert.
* Die
Formatierung erfolgt, wenn der Wert angezeigt wird.
*/
vecData.addElement(tmpapplication_entity
_BO.
Variable_3
);
/*
* Die
gerade erstellte 'Zeile' einfügen.
*/
vecRawDisplayData
.addElement(vecData);
}
}/* ---------------------
* METHODE zum Anzeigen der Werte aus diesem BO-Set in
einem GUI-Element vom Typ JTable. *//* ---------------------
* Diese Methode verwendet eine Methode der Basisklasse
'JSBS_XML_DisplayStrings'
* um ein GUI-Element vom Typ
'JTable' mit den Daten zu füllen.
* Im Parameter
'parmArrayColumnWidth' wird eine Information über die
Spaltenbreite
* übergeben. */
public
void
setToGUI(JTable
parmJTable,
String[]
parmArrayColumnWidth)
{
/*
* Diese Methode kann nur ausgeführt werden wenn
ein TaskFrame
* als Parameter im Constructor übergeben
wurde. */
if
(
frmTask
==
null
)
return
;
/*
* Namen der Klasse des Task-Frames ermitteln.
*/
String
strFrameClassName = frmTask
.getClass().getName();
/*
* Methode, die in der Klasse für die
DisplayStrings implementiert ist aufrufen.
*/
frmTask
.
frmCC
.
structJSBS_XML_DisplayStrings
.processJTable(
parmJTable,
strFrameClassName,
vecRawDisplayData
,
parmArrayColumnWidth);
}/*
* --------------------
* METHODE
zum Aufrufen der eigenen Klasse für das Abgleichen von
BO
* wenn
das Anwendungsprogramm in der Version 'MobileClient' läuft.
* Soll
eine 'MobileClient' Version nicht implementiert werden dann muss
diese Methode
* gelöscht werden. */
private
void
synchronizeBO()
{
/*
* Wenn das Anwendungsprogramm nicht für die
Version 'MobileClient' implementiert wird
* entfernen
Sie bitte den Code innerhalb dieser Methode oder kommentieren Sie
aus. *//*
* Zuerst Prüfen ob schon ein Objekt für den
nebenläufigen Prozess (Thread) existiert.
* Bei
Bedarf ein Objekt 'konstruieren'.
* Hinweis:
* Im
Muster ist die Variablendeklaration für die Synchronizer-Klasse
auskommentiert. */
if
(
struct
application_entity
_BO_Synchronizer
==
null
)
struct
application_entity
_BO_Synchronizer
=
new
application_entity
_BO
_Synchronizer(
frmCC
,
frmTask
);
/*
* Dieses BO-Set (gesamtes Objekt) an den Synchronizer
übergeben.
* Der asynchrone Prozess wird in der
aufgerufenen Methode gestartet.
*/
struct
application_entity
_BO_Synchronizer
.passBOList(
this
);
}
/*
* --------------------
*
METHODE zum Vergleichen von zwei BO-Sets und Übernehmen der
jeweils neuesten Version
*
eines BO in das vecRecordSet dieses Objekts. */
private
void
mergeList(
application_entity
_BO
_Set
parm
application_entity
_BO
_Set_1,
application_entity
_BO
_Set
parm
application_entity
_BO
_Set_2)
{
/*
* Zuerst Prüfen ob gültige Werte in den
Parametern vorhanden sind. */
if
(parm
application_entity
_BO
_Set_1
==
null
)
{
this
.
StatusCode
=
JSBS_BO.
CONST_INCONSISTENT_DATA
;
this
.
StatusMsg
=
"mergeList:
parm
application_entity
_BO
_Set_1
is 'null'"
;
}
if
(parm
application_entity
_BO
_Set_1.
vecRecordSet
==
null
)
{
this
.
StatusCode
=
JSBS_BO.
CONST_INCONSISTENT_DATA
;
this
.
StatusMsg
=
"mergeList:
parm
application_entity
_BO
_Set_1.vecRecordSet
is 'null'"
;
}
if
(parm
application_entity
_BO
_Set_2
==
null
)
{
this
.
StatusCode
=
JSBS_BO.
CONST_INCONSISTENT_DATA
;
this
.
StatusMsg
=
"mergeList:
parm
application_entity
_BO
_Set_2
is 'null'"
;
}
if
(parm
application_entity
_BO
_Set_2.
vecRecordSet
==
null
)
{
this
.
StatusCode
=
JSBS_BO.
CONST_INCONSISTENT_DATA
;
this
.
StatusMsg
=
"mergeList:
parm
application_entity
_BO
_Set_2.vecRecordSet
is 'null'"
;
}
/*
* Variable die für den Abgleich gebraucht werden
definieren. */
int
intVectorSizeThis;
int
intVectorIndexThis;
int
intVectorSizeParm;
int
intVectorIndexParm;
application_entity
_BO
loc
application_entity
_BO
_This;
application_entity
_BO
loc
application_entity
_BO
_Parm;
application_entity
_BO
loc
application_entity
_BO
_ToInsert;
/*
* Vector mit den BO dieses Objekts leeren und BO aus
dem Vector des Parameter 1 übertragen. */
vecRecordSet
=
new
Vector();
intVectorSizeParm
= parm
application_entity
_BO
_Set_1.
vecRecordSet
.size();
for
(intVectorIndexParm
= 0; intVectorIndexParm < intVectorSizeParm; intVectorIndexParm++)
{
loc
application_entity
_BO
_Parm
= (
application_entity
_BO
)
parm
application_entity
_BO
_Set_1.
vecRecordSet
.elementAt(intVectorIndexParm);
loc
application_entity
_BO
_ToInsert
=
new
application_entity
_BO
();
loc
application_entity
_BO
_ToInsert.copyFrom
application_entity
_BO
(loc
application_entity
_BO
_Parm);
vecRecordSet
.addElement(loc
application_entity
_BO
_ToInsert);
}
/*
* In einem zweiten Durchgang alle BO des Parameter 2
mit den bereits im vecRecordSet dieses
*
Objektes enthaltenen vergleichen.
*
Sind im Parameter 2 neue oder 'jüngere' BO enthalten, dann diese
in das vecRecordSet dieses
*
Objektes einfügen bzw. 'ältere' ersetzen.
*/
intVectorSizeParm
= parm
application_entity
_BO
_Set_2.
vecRecordSet
.size();
for
(intVectorIndexParm
= 0; intVectorIndexParm < intVectorSizeParm; intVectorIndexParm++)
{
loc
application_entity
_BO
_Parm
= (
application_entity
_BO
)
parm
application_entity
_BO
_Set_2.
vecRecordSet
.elementAt(intVectorIndexParm);
/*
* BO für das eventuelle Einfügen mit dem BO
aus dem Parameter 2 versorgen. Das wird später zum
*
Signalisieren benutzt, ob
das
BO aus dem Parameter 2 eingefügt werden soll. */
loc
application_entity
_BO
_ToInsert
=
new
application_entity
_BO
();
loc
application_entity
_BO
_ToInsert.copyFrom
application_entity
_BO
(loc
application_entity
_BO
_Parm);
/*
* In einer inneren for-Schleife das BO-Set dieses
Objektes durchsuchen und die BO vergleichen. */
intVectorSizeThis
=
this
.
vecRecordSet
.size();
for
(intVectorIndexThis
= 0; intVectorIndexThis < intVectorSizeThis; intVectorIndexThis++)
{
loc
application_entity
_BO
_This
= (
application_entity
_BO
)
this
.
vecRecordSet
.elementAt(intVectorIndexThis);
/*
* Vergleichen ob die beiden BO den gleichen ObjectID
haben - also das gleiche BO sind. */
if
(loc
application_entity
_BO
_This.
ObjectID
==
loc
application_entity
_BO
_Parm.
ObjectID
)
{
/*
Markieren, dass dieses BO nicht mehr in das vecRecordSet dieses
Objekts eingefügt werden muss. */
loc
application_entity
_BO
_ToInsert
=
null
;
/*
Prüfen, ob das BO aus dem Parameter 2 'jünger' ist. */
if
(loc
application_entity
_BO
_This.
ChangedAt
.before(loc
application_entity
_BO
_Parm.
ChangedAt
))
{
/*
BO aus dem Parameter 2 ist 'jünger'; dessen Werte in das BO im
vecRecordSet dieses Objekts übertragen. */
((
application_entity
_BO
)
this
.
vecRecordSet
.elementAt(intVectorIndexThis)).
copyFrom
application_entity
_BO
(loc
application_entity
_BO
_Parm);
}
}
}
/*
* Prüfen ob das bearbeitete BO aus dem Parameter
2 in das vecRecordSet dieses Objekts eingefügt werden muss.
*/
if
(loc
application_entity
_BO
_ToInsert
!=
null
)
vecRecordSet
.addElement(loc
application_entity
_BO
_ToInsert);
}
}
/* ---------------------
* METHODEN FÜR DB-ABFRAGEN ZUR INTERNEN
VERWENDUNG.
* Die folgenden Methoden führen
jeweils eine Datenbank-Abfrage aus bei der per Definition
* mehr
als ein Datensatz gefunden werden kann.
*
* Zweck
dieser Abfragen ist die Verwendung für Zwecke, die nicht direkt
durch die Bearbeitung
* eines Geschäftsfalls
bedingt sind.
* Die folgenden Methoden dienen zum
Abfragen der Änderung eines Business-Object und zur
* Synchronisation von Daten wenn eine Client-Anwendung
in der 'MobileClient' Version ausgeführt
wird.
* --------------------- *//*
* Diese
METHODE enthält den Muster-Code für das Selektieren aller
Datensätze für einen gegebenen
* ObjectID.
Diese Methode wird zum Anzeigen von Veränderungen (History) des
BO und zum
* Ableichen der Daten bei einer
'MobileClient' Version verwendet.
* Weiters wird damit
beim 'deaktivieren' des BO festgestellt, welche Datensätze noch
über das
* aktuelle Datum hinaus gültig
sind. *//*
* METHODE
zum Lesen der Daten von der lokalen Datenbank. */
public
void
select
AllByObjectID_DB(
double
parmObjectID){
/* Methode,
die die Verbindung zur Datenbank herstellt, aufrufen.
* Weil
in einem BO-Set nur gelesen wird, wird als Parameter 'autocommit'
(read-only) festgelegt. */
getDatabaseConnection(true
);
/*
* Prüfen ob eine Verbindung zur Datenbank
hergestellt werden konnte.
* Eine Referenz-Nummer
gleich oder größer '0' bedeutet eine ordnungsgemäße
Verbindung zur DB. */
if
(
intDBConReference
<
0) {
/* Verbindung
zur Datenbank konnte nicht hergestellt werden.
* Status-Code
(auf Fehler) setzen und Fehlermeldung übernehmen.
*/
StatusCode
=
JSBS_BO
.
CONST_DB_SYSTEM_ERROR
;
StatusMsg
=
frmCC
.
structJSBS_DB_ConnectionManager
.
StatusMsg
;
/*
* Weitere Verarbeitung abbrechen;
* Aufrufende
Methode bekommt Fehler über StatusCode signalisiert.
*/
return
;
}/*
* Wenn ein TaskFrame als Parameter im Constructor
übergeben wurde
* dann wird die Struktur mit dem
minimalen Set an Parametern aus dem
* TaskFrame
übernommen. */
if
(
frmTask
!
=
null
)
structMinParm
=
new
JSBS_MinimalParameters(
frmTask
.
structMinParm
);
/*
* Einzelplatz-Version bzw. Datenbank-Zugriff über
TCP/IP-Netzwerk.
* Server-Side-BO-Set 'konstruieren'.
*/
application_entity
_BOS_Set
bos_BO_Set =
new
application_entity
_BOS_Set(
structMinParm
,
structDBCon
,
true
);
/*
* Methode zum Selektieren der Werte aufrufen.
*/
bos_BO_Set.selectAllByObjectID(
parmObjectID
);
/*
* Neue Werte des BOS wieder in dieses BOC
übertragen.
* Damit sind geschäfts-spezifische
Attribute, Common-Attributes, Status-Code
* und
Status-Message in diesem BOC verfügbar.
*/
copyFromapplication_entity
_BO_Set(bos_BO_Set);
/*
* DB-Connection an den Connection-Manager zurück
geben – der Connection-Manager verwaltet
* die
offene DB-Connection und verwendet sie wieder bei der nächsten
Anforderung.
*/
frmCC
.
structJSBS_DB_ConnectionManager
.returnReservedConnection(
this
,
intDBConReference
);
}/*
* METHODE
zum Lesen der Daten über den JAS (Java Application Server).
*/
public
void
selectAllByObjectID_JAS(
double
parmObjectID)
{
/*
* Zugriff auf die Datenbank über den EJB-Mechanismus.
*//*
* Damit Fehler bei der Verbindung zum EJB behandelt werden
können ist der try/catch-Mechanismus
* erforderlich.
*///
try
{
/*
*
Instanziieren (Konstruieren) des Client-seitigen Objekts ('Remote
interface') für
* den Aufruf von Methoden des EJB. Die
Methode zum Instanziieren ist im Start-Frame implementiert.
*
In diesem Muster wird das Standard-EJB verwendet.
*
* Sollte die Methode für den Datenbankzugriff in einem
anderen EJB enthalten sein
* ist das passende EJB zu
instanziieren.
*/
//
application_package
.ejb.interfaces.remote.
application
_
StandardBeanRemote
instanceStandardEJB
=
//
frmCC.struct
application
_
CommandCenter__JASConnections.get_
application
_
StandardBeanRemote();
/*
* Wenn ein TaskFrame als Parameter im Constructor
übergeben wurde
* dann wird die Struktur mit dem
minimalen Set an Parametern aus dem
* TaskFrame
übernommen. */
if
(
frmTask
!
=
null
)
structMinParm
=
new
JSBS_MinimalParameters(
frmTask
.
structMinParm
);
/*
* Aufrufen der 'Wrapper'-Methode des EJB.
* In
dieser 'Wrapper'-Methode wird die - zu diesem Client-seitigen Teil
gehörende -
* passende Server-seitige Methode
aufgerufen.
* Die über die Selektion gefundenen BO sind
im zurück gelieferten BO-Set enthalten.
*///
application_entity
_BO_Set bo_BO_Set
=
//
instanceStandardEJB.
application_entity
_BO_Set__selectAllByObjectID(
//
structMinParm
,
parmObjectID);
/*
* Werte des zurück gelieferten BO auf diese BOC
(Client-seitiger Teil des BO) kopieren.
*///
this
.copyFrom
application_entity
_BO_Set(bo_BO_Set);
//
}
//
catch
(Exception
e){
/*
* Fehler beim Ausführen der Methode des EJB.
*
Fehlermeldung aus der Exception übernehmen und Status setzen.
*///
this
.
StatusCode
=
JSBS_BO.
CONST_DB_UNKNOWN_ERROR
;
//
this
.
StatusMsg
= e.getMessage();
//
}
}/*
* METHODE
zum Selektieren aller aktuell gültigen Datensätze
entsprechend
* den Selektionskriterien die als
Parameter übergeben werden.
* 'Aktuell gültig'
bedeutet, dass die Gültigkeit des Datensatzes mit dem
* im
Minimalen Set von Parametern übergebenen Arbeitsdatum
übereinstimmt. */
public
void
selectAllByObjectID(
double
parmObjectID)
{
/*
* Entscheiden, ob diese Application als
Einzelplatz-Version (StandAlone) oder
* Client/Server-Version
(FatClient) implementiert ist. */
switch
(
frmCC
.
RunVersion
)
{
case
JSBS_StartFrame.
CONST_StandAlone
:
/*
Einzelplatzversion. Datenbank läuft auf der lokalen Maschine;
Spezielle Methode aufrufen. */
selectAllByObjectID_DB(parmObjectID);
break
;
/*
*/
case
JSBS_StartFrame.
CONST_FatClient
:
/*
Client-Server-Version.
*
Datenzugriff erfolgt über den EJB-Mechanismus und JAS (Java
Application Server); spezielle Methode aufrufen. */
selectAllByObjectID_JAS(parmObjectID);
break
;
/*
*/
case
JSBS_StartFrame.
CONST_MobileClient
:
/*
* Für diese Version folgt jetzt ein generelles
Muster.
* Es ist im Einzelfall zu analysieren und zu
entscheiden, welcher Algorithmus (welches Vorgehen)
*
möglich ist wenn der Mobile Client (z.B. Notebook) keine
Verbindung zum Server aufbauen kann.
* Wenn eine
'MobileClient' Version nicht für das Anwendungsprogramm
vorgesehen ist, dann kann
* der Code innerhalb dieses
'case' gelöscht werden.
* Damit wird vermieden,
dass nicht vorhandene Klassen und Methoden 'auskommentiert' werden
müssen. */
/*
* Zuerst die Daten von der lokalen
Datenbank abfragen. Per Definition muss das immer möglich sein.
*/
selectAllByObjectID_DB(parmObjectID);
/*
Prüfen, ob ein Fehler bei der Abfrage auf der lokalen Datenbank
aufgetreten ist. In diesem Fall die
* Methode beenden -
damit ist der Status für die aufrufende Methode verfügbar.
*/
if
((
this
.
StatusCode
==
JSBS_BO.
CONST_OK
)
|| (
this
.
StatusCode
==
JSBS_BO.
CONST_NOT_FOUND
))
{
/*
'Erlaubte' Status-Codes für die Abfrage von der lokalen
Datenbank. */
}
else
return
;
/*
Prüfen, ob die Verbindung zum JAS existiert. Abhängig davon
erfolgt die weitere Verarbeitung. */
if
(
frmCC
.testJASConnection())
{
/*
BO-Sets für die Daten der lokalen Datenbank und den Daten vom
JAS konstruieren.
* Damit können später die
jeweiligen Daten verglichen und Unterschiede behandelt werden.
*/
application_entity
_BO_Set
struct
application_entity
_BO_Set_Local
=
new
application_entity
_BO_Set();
application_entity
_BO_Set
struct
application_entity
_BO_Set_JAS
=
new
application_entity
_BO_Set();
/*
Ergebnis der Abfrage der lokalen Datenbank auf die dafür
vorgesehene Variable übertragen und den
* Vector mit
den BO in diesem Objekt leeren.
*/
struct
application_entity
_BO_Set_Local.copyFrom
application_entity
_BO_Set(
this
);
vecRecordSet
.removeAllElements();
/*
Daten vom JAS abfragen.
*/
selectAllByObjectID_JAS(parmObjectID);
/*
Prüfen, ob ein Fehler bei der Abfrage vom JAS aufgetreten ist.
In diesem Fall die
* Methode beenden - damit ist der Status
für die aufrufende Methode verfügbar. */
if
((
this
.
StatusCode
==
JSBS_BO.
CONST_OK
)
|| (
this
.
StatusCode
==
JSBS_BO.
CONST_NOT_FOUND
))
{
/*
'Erlaubte' Status-Codes für die Abfrage von der lokalen
Datenbank. */
}
else
return
;
/*
Ergebnis der Abfrage über den JAS auf die dafür vorgesehene
Variable übertragen und den
* Vector mit den BO in
diesem Objekt leeren.
*/
struct
application_entity
_BO_Set_JAS.copyFrom
application_entity
_BO_Set(
this
);
vecRecordSet
.removeAllElements();
/*
Methode zum Abgleich der Daten von beiden Quellen aufrufen.
*/
mergeList(struct
application_entity
_BO_Set_Local,
struct
application_entity
_BO_Set_JAS);
}
break
;
}
/*
* Methode aufrufen, die die Matrix mit den
formatierten Daten erstellt.
*/
buildRawDataVector();
}/* ---------------------
* METHODEN zum Aufrufen der Geschäfts-spezifischen
Datenbank-Operationen. *//*
* METHODE
zum Selektieren aller aktuell gültigen Datensätze
entsprechend
* den Selektionskriterien die als
Parameter übergeben werden.
* 'Aktuell gültig'
bedeutet, dass die Gültigkeit des Datensatzes mit dem
* im
Minimalen Set von Parametern übergebenen Arbeitsdatum
übereinstimmt. *//*
* METHODE
zum Lesen der Daten von der lokalen Datenbank. */
public
void
selectBy
Variables
_DB(String
parm
Variable_1
,
String
parm
Variable_2
)
{
/* Methode,
die die Verbindung zur Datenbank herstellt, aufrufen.
* Weil
in einem BO-Set nur gelesen wird, wird als Parameter 'autocommit'
(read-only) festgelegt. */
getDatabaseConnection(true
);
/*
* Prüfen ob eine Verbindung zur Datenbank
hergestellt werden konnte.
* Eine Referenz-Nummer
gleich oder größer '0' bedeutet eine ordnungsgemäße
Verbindung zur DB. */
if
(
intDBConReference
<
0) {
/* Verbindung
zur Datenbank konnte nicht hergestellt werden.
* Status-Code
(auf Fehler) setzen und Fehlermeldung übernehmen.
*/
StatusCode
=
JSBS_BO
.
CONST_DB_SYSTEM_ERROR
;
StatusMsg
=
frmCC
.
structJSBS_DB_ConnectionManager
.
StatusMsg
;
/*
* Weitere Verarbeitung abbrechen;
* Aufrufende
Methode bekommt Fehler über StatusCode signalisiert.
*/
return
;
}/*
* Wenn ein TaskFrame als Parameter im Constructor
übergeben wurde
* dann wird die Struktur mit dem
minimalen Set an Parametern aus dem
* TaskFrame
übernommen. */
if
(
frmTask
!
=
null
)
structMinParm
=
new
JSBS_MinimalParameters(
frmTask
.
structMinParm
);
/*
* Einzelplatz-Version bzw. Datenbank-Zugriff über
TCP/IP-Netzwerk.
* Server-Side-BO-Set 'konstruieren'.
*/
application_entity
_BOS_Set
bos_BO_Set =
new
application_entity
_BOS_Set(
structMinParm
,
structDBCon
,
true
);
/*
* Methode zum Selektieren der Werte aufrufen.
*/
bos_BO_Set.selectByVariables
(
parm
Variable_1
,
parm
Variable_2
);
/*
* Neue Werte des BOS wieder in dieses BOC
übertragen.
* Damit sind geschäfts-spezifische
Attribute, Common-Attributes, Status-Code
* und
Status-Message in diesem BOC verfügbar.
*/
copyFromapplication_entity
_BO_Set(bos_BO_Set);
/*
* DB-Connection an den Connection-Manager zurück
geben – der Connection-Manager verwaltet
* die
offene DB-Connection und verwendet sie wieder bei der nächsten
Anforderung.
*/
frmCC
.
structJSBS_DB_ConnectionManager
.returnReservedConnection(
this
,
intDBConReference
);
}/*
* METHODE
zum Lesen der Daten über den JAS (Java Application Server).
*/
public
void
selectBy
Variables
_JAS(String
parm
Variable_1
,
String
parm
Variable_2
)
{
/*
* Zugriff auf die Datenbank über den EJB-Mechanismus.
*//*
* Damit Fehler bei der Verbindung zum EJB behandelt werden
können ist der try/catch-Mechanismus
* erforderlich.
*///
try
{
/*
*
Instanziieren (Konstruieren) des Client-seitigen Objekts ('Remote
interface') für
* den Aufruf von Methoden des EJB. Die
Methode zum Instanziieren ist im Start-Frame implementiert.
*
In diesem Muster wird das Standard-EJB verwendet.
*
* Sollte die Methode für den Datenbankzugriff in einem
anderen EJB enthalten sein
* ist das passende EJB zu
instanziieren.
*/
//
application_package
.ejb.interfaces.remote.
application
_
StandardBeanRemote
instanceStandardEJB
=
//
frmCC.struct
application
_
CommandCenter__JASConnections.get_
application
_
StandardBeanRemote();
/*
* Wenn ein TaskFrame als Parameter im Constructor
übergeben wurde
* dann wird die Struktur mit dem
minimalen Set an Parametern aus dem
* TaskFrame
übernommen. */
if
(
frmTask
!
=
null
)
structMinParm
=
new
JSBS_MinimalParameters(
frmTask
.
structMinParm
);
/*
* Aufrufen der 'Wrapper'-Methode des EJB.
* In
dieser 'Wrapper'-Methode wird die - zu diesem Client-seitigen Teil
gehörende -
* passende Server-seitige Methode
aufgerufen.
* Die über die Selektion gefundenen BO sind
im zurück gelieferten BO-Set enthalten.
*///
application_entity
_BO_Set bo_BO_Set
=
//
instanceStandardEJB.
application_entity
_BO_Set__selectBy
method
(
//
structMinParm
,
parm
Variable_1
,
parm
Variable_2
);
/*
* Werte des zurück gelieferten BO auf diese BOC
(Client-seitiger Teil des BO) kopieren.
*///
this
.copyFrom
a
pplication_entity
_BO_Set(bo_BO_Set);
//
}
//
catch
(Exception
e){
/*
* Fehler beim Ausführen der Methode des EJB.
*
Fehlermeldung aus der Exception übernehmen und Status setzen.
*///
this
.
StatusCode
=
JSBS_BO.
CONST_DB_UNKNOWN_ERROR
;
//
this
.
StatusMsg
= e.getMessage();
//
}
}/*
* METHODE
zum Selektieren aller aktuell gültigen Datensätze
entsprechend
* den Selektionskriterien die als
Parameter übergeben werden.
* 'Aktuell gültig'
bedeutet, dass die Gültigkeit des Datensatzes mit dem
* im
Minimalen Set von Parametern übergebenen Arbeitsdatum
übereinstimmt. */
public
void
selectBy
Variables
(String
parm
Variable_1
,
String parm
Variable_2
)
{
/*
* Entscheiden, ob diese Application als
Einzelplatz-Version (StandAlone) oder
* Client/Server-Version
(FatClient) implementiert ist. */
switch
(
frmCC
.
RunVersion
)
{
case
JSBS_StartFrame.
CONST_StandAlone
:
/*
Einzelplatzversion. Datenbank läuft auf der lokalen Maschine;
Spezielle Methode aufrufen. */
selectBy
Variables
_DB(parm
Variable_1
,
parm
Variable_2
);
break
;
/*
*/
case
JSBS_StartFrame.
CONST_FatClient
:
/*
Client-Server-Version.
*
Datenzugriff erfolgt über den EJB-Mechanismus und JAS (Java
Application Server); spezielle Methode aufrufen. */
selectBy
Variables
_JAS(parm
Variable_1
,
parm
Variable_2
);
break
;
/*
*/
case
JSBS_StartFrame.
CONST_MobileClient
:
/*
* Für diese Version folgt jetzt ein generelles
Muster.
* Es ist im Einzelfall zu analysieren und zu
entscheiden, welcher Algorithmus (welches Vorgehen)
*
möglich ist wenn der Mobile Client (z.B. Notebook) keine
Verbindung zum Server aufbauen kann.
* Wenn eine
'MobileClient' Version nicht für das Anwendungsprogramm
vorgesehen ist, dann kann
* der Code innerhalb dieses
'case' gelöscht werden.
* Damit wird vermieden,
dass nicht vorhandene Klassen und Methoden 'auskommentiert' werden
müssen. */
/*
* Zuerst die Daten von der lokalen
Datenbank abfragen. Per Definition muss das immer möglich sein.
*/
select
By
Variables
_DB(parm
Variable_1
,
parm
Variable_2
);
/*
Prüfen, ob ein Fehler bei der Abfrage auf der lokalen Datenbank
aufgetreten ist. In diesem Fall die
* Methode beenden -
damit ist der Status für die aufrufende Methode verfügbar.
*/
if
((
this
.
StatusCode
==
JSBS_BO.
CONST_OK
)
|| (
this
.
StatusCode
==
JSBS_BO.
CONST_NOT_FOUND
))
{
/*
'Erlaubte' Status-Codes für die Abfrage von der lokalen
Datenbank. */
}
else
return
;
/*
Prüfen, ob die Verbindung zum JAS existiert. Abhängig davon
erfolgt die weitere Verarbeitung. */
if
(
frmCC
.testJASConnection())
{
/*
BO-Sets für die Daten der lokalen Datenbank und den Daten vom
JAS konstruieren.
* Damit können später die
jeweiligen Daten verglichen und Unterschiede behandelt werden.
*/
application_entity
_BO_Set
struct
application_entity
_BO_Set_Local
=
new
application_entity
_BO_Set();
application_entity
_BO_Set
struct
application_entity
_BO_Set_JAS
=
new
application_entity
_BO_Set();
/*
Ergebnis der Abfrage der lokalen Datenbank auf die dafür
vorgesehene Variable übertragen und den
* Vector mit
den BO in diesem Objekt leeren.
*/
struct
application_entity
_BO_Set_Local.copyFrom
application_entity
_BO_Set(
this
);
vecRecordSet
.removeAllElements();
/*
Daten vom JAS abfragen.
*/
selectBy
Variables
_JAS(parm
Variable_1
,
parm
Variable_2
);
/*
Prüfen, ob ein Fehler bei der Abfrage vom JAS aufgetreten ist.
In diesem Fall die
* Methode beenden - damit ist der Status
für die aufrufende Methode verfügbar. */
if
((
this
.
StatusCode
==
JSBS_BO.
CONST_OK
)
|| (
this
.
StatusCode
==
JSBS_BO.
CONST_NOT_FOUND
))
{
/*
'Erlaubte' Status-Codes für die Abfrage von der lokalen
Datenbank. */
}
else
return
;
/*
Ergebnis der Abfrage über den JAS auf die dafür vorgesehene
Variable übertragen und den
* Vector mit den BO in
diesem Objekt leeren.
*/
struct
application_entity
_BO_Set_JAS.copyFrom
application_entity
_BO_Set(
this
);
vecRecordSet
.removeAllElements();
/*
Methode zum Abgleich der Daten von beiden Quellen aufrufen.
*/
mergeList(struct
application_entity
_BO_Set_Local,
struct
application_entity
_BO_Set_JAS);
/*
Methode zum Sortieren aufrufen weil die BO nach dem Abgleich nach
ihrer Herkunft sortiert sind.
* Anleitungen für
das Codieren der Sortierung finden Sie im Abschnitt
* Bei
Version 'MobileClient': Codieren der Sortier-Methoden
.
*/
sortBy
Variables
();
/*
Methode zum Prüfen, ob die Daten zwischen Server und mobilem
Client abgeglichen werden müssen,
* und zum
eventuell notwendigen Abgleichen aufrufen.
*/
synchronizeBO();
}
break
;
}
/*
* Methode aufrufen, die die Matrix mit den
formatierten Daten erstellt. */
buildRawDataVector();
}
}
Anleitung
zur Adaptierung
Am leichtesten
funktioniert die Anpassung des Muster-Codes an die eigenen
Erfordernisse durch Kopieren des Muster-Codes und Verwendung von
Edit
> Find/Replace...
.
|
|
Für
'Platzhalter', die nur einmalig im Muster-Code vorkommen ist die
'Find'-Funktion hilfreich zum finden der beschriebenen 'Platzhalter'.
Änderung
des Namens der Java-Packages der Anwendung
package
application_package
.boc;
/*
.
. . . .
.
. . . .
/*
* Packages
mit der zugehörigen Klassen (Generelle Klasse und
Server-Side-Klasse) dieses BO. */import
application_package
.bo.*;
import
application_package
.bos.
application_entity
_BOS_Set;
/**
Der
Name dieses Packages kommt in der ersten Zeile des Muster-Codes und
dann noch mehrmals beim Import der zugehörigen Packages mit den
Generellen und Server-Seitigen BO Klassen, der Klasse für das
CommandCenter (Start-Frame) und auch in - noch auskommentierten -
Code-Teilen für den Aufruf der Methoden des EJB vor.
Änderung
des Namens der Klasse des CommandCenters
/*
*
Package mit der Basisklasse für Start- und Task-Frame. */import
js_base.frame.*;
/*
*
Klasse für das CommendCenter (Start-Frame) der Anwendung.
*/import
application_package
.client.
application
_CommandCenter
;
/*
*
Geerbte Generelle Klasse des BO. */
D
er
Name dieser Klasse kommt mehrmals im Muster-Code vor.
Wenn Sie
'Find/Replace' zum Ersetzen verwenden, geben Sie bitte den Text
application
_CommandCenter
als
Suchbegriff ein; damit wird nur der Name dieser Klasse ersetzt und
nicht auch Teile anderer 'Platzhalter' die
application
enthalten.
Änderung
des Namens dieser Klasse und der Klassen der zugehörigen
Generellen und Server-Side BO
/*
* Packages
mit der zugehörigen Klassen (Generelle Klasse und
Server-Side-Klasse) dieses BO. */import
application_package
.bo.*;
import
application_package
.bos.
application_entity
_BO
S_Set;
/**
D
er
Name dieser Klasse kommt mehrmals im Muster-Code vor.
Damit wird
auch der Name der BOC-Klasse und der Constructor geändert.
Adaptieren
des Kommentars
'Kein Kommentar
ist besser als ein falscher'
.
Aus
diesem Grund ist im Muster-Code auch keine Hintergrund-Information
über Entwurfs-Entscheidungen für das BOC_Set
vorhanden.
Meiner Erfahrung nach ist es ausreichend für die
Beschreibung der Variablen des BO auf die Generelle Klasse für
das BO zu verweisen.
Die einzelnen Methoden der BOC_Set-Klasse
sind innerhalb des Codes kommentiert.
Definitionen
der symbolischen Namen und deren Verwendung in der Methode
buildRawDataVector()
public
class
application_entity
_BOC_Set
extends
application_entity
_BO_Set
{
/* ---------------------
* KONSTANTE für die symbolischen Namen der
'Spalten' in der Matrix der formatierten
Daten.
* ---------------------
* Diese
symbolischen Namen werden in der Methode 'buildRawDataVector'
verwendet.
* Über XML-Parameter in der Datei
'DisplayStrings.xml' wird damit die Anordnung der
* Spalten
für die Auswahl-Tabelle gesteuert. */
public
static final
String
CONST_ColumnName_
SymbolicName_1
=
"
SymbolicName_1
"
;
public
static final
String
CONST_ColumnName_
SymbolicName_2
=
"
SymbolicName_2
"
;
public
static final
String
CONST_ColumnName_
SymbolicName_3
=
"
SymbolicName_3
"
;
/* ---------------------
* VARIABLE dieser Klasse.
Über
diese symbolischen Namen wird die Anordnung der Spalten bei der
tabellarischen Anzeige der Datensätze gesteuert.
Die
Anordnung der Spalten (und welche Werte überhaupt in der Tabelle
angezeigt werden) ist in der Datei mit den sprachabhängigen
Texten für die GUI-Elemente, 'DisplayStrings.xml', festgelegt.
Diese
symbolischen Namen werden dann in der Methode
buildRawDataVector()
den
Variablen des BO zugeordnet.
Diese Matrix mit 'roh-formatierten
Daten' wird dann über die in der Basisklasse
JSBS_XML_DisplayStrings
enthaltene Methode processJTable(...)
(die
in der Methode
setToGUI(...)
dieser
Klasse aufgerufenen wird) in einem GUI-Element vom Typ 'JTable'
angezeigt.
/* ---------------------
* METHODE zum Aufbau der Matrix mit den formatierten
Daten.
* ---------------------
* In
dieser Matrix sind in der ersten Zeile die symbolischen Spalten-Namen
enthalten.
* Über XML-Parameter in der Datei
'DisplayStrings.xml' wird damit die Anordnung der
* Spalten
für die Auswahl-Tabelle gesteuert.
* Die 'Matrix'
besteht aus einem 'Vector' der für jede Zeile wieder einen
'Vector'
* mit den Daten für die Spalten
enthält.
* In der ersten 'Reihe' der Matrix sind
die symbolischen Spaltennamen enthalten. */
public
void
buildRawDataVector()
{
/*
.
. . . .
.
. . . .
Vector
vecHeader =
new
Vector();
/* Die
Konstante für die Zeilen-Nummer ist in der geerbten Basisklasse
definiert.
*/
vecHeader.addElement(
CONST_ColumnName_RowNr
);
vecHeader.addElement(
CONST_ColumnName_
SymbolicName_1
);
vecHeader.addElement(
CONST_ColumnName_
SymbolicName_2
);
vecHeader.addElement(
CONST_ColumnName_
SymbolicName_3
);
/* Die
gerade erstellte 'Zeile' einfügen.
*/
vecRawDisplayData
.addElement(
vecHeader
);
.
. . . .
.
. . . .
}
Mehr
Information darüber finden Sie im Dokument
Datei
'DisplayStrings.xml' mit sprachabhängigen Texten für die
Anzeige auf der GUI
.
Eine
genauere Anleitung ist im Tutorial:
JavaScout ProjectAssist, Task-Frame Grundlagen (Java_Fatclient_01) –
Liste der Daten anzeigen und zur Bearbeitung auswählen >
Anzeigen der Liste
enthalten.
Erstellen der
'Werte-Zeilen' der Matrix in der Methode
buildRawDataVector()
In
der gleichen Reihenfolge wie die symbolischen Namen angeordnet sind,
müssen auch die Werte in die Zeilen-Vectoren eingefügt
werden.
/*
* Werte der Variablen aus dem 'herausgelösten' BO
in den 'Matrix'-Vector einfügen.
* Die ersten
beiden Beispiele sind für Variablen vom Java-Typ 'String'.
*/
vecData.addElement(tmp
application_entity
_BO.
Variable_1
);
vecData.addElement(tmp
application_entity
_BO.
Variable_2
);
/*
* Variable eines 'numerischen' Java-Typs werden nicht
vor dem Einfügen in den Vector formatiert.
* Die
Formatierung erfolgt, wenn der Wert angezeigt wird.
*/
vecData.addElement(tmp
application_entity
_BO.
Variable_3
);
/*
* Die
gerade erstellte 'Zeile' einfügen.
*/
vecRawDisplayData
.addElement(
vecData
);
}
}
In
den beiden Methoden müssen für jede Geschäfts-spezifische
Variable die entsprechenden Code-Zeilen zum Kopieren des Wertes bzw.
zum Prüfen des Unterschiedes von Werten eingefügt werden.
Beispiele
für das Kopieren bzw. Vergleichen ganzer Objekte finden Sie
unter
Objekte
als Variable dieses BO kopieren
bzw.
Objekte
als Variable dieses BO auf Unterschiede prüfen
.
Vorbereitende
Tätigkeiten bei Entwicklung einer 'MobileClient' Version des
Anwendungsprogramms
Wenn
Sie Ihr Anwendungsprogramm auch mit der möglichen Version für
einen 'MobileClient' entwickeln, ist jetzt der optimale Zeitpunkt,
die dafür notwendige 'Synchronizer'-Klasse zu
implementieren.
Die Anleitung dafür finden Sie unter
Leitfaden
für die Entwicklung von Heavyweight-Clients mit dem JS-FCF –
Alle Schritte zur Entwicklung von DBA (DataBase-Access) und BO
(Business-Object) Klassen > Leitfaden – BO-Synchronizer
(Klasse zur Datensynchronisation zwischen JAS und lokaler Datenbank)
und
den darin gelisteten weiteren Anleitungen.
Entfernen
Sie den Kommentar vor der Variablen-Definition für die Klasse
des 'Synchronizers':
Anmerkung:
Im
Abschnitt Änderung
des Namens der Klasse und der 'Constructor-Methoden'
wurden
die Platzhalter
application_entity
_BO
bereits
durch den passenden Name für die Klasse ersetzt.
.
. . . . . . . .
. . . . . . . . .
/*
* Nummer
der in diesem Objekt geöffneten 'Connection' zur Datenbank.
*/
private
int
intDBConReference
=
0;
/*
* Objekt
für den Abgleich bei einer 'MobileClient' Version.
* In
der Klasse ist implementiert, wie die Daten eines mobile Client mit
den Daten
* am Server abgeglichen werden wenn der
mobile Client wieder mit dem Server verbunden ist.
* Wenn
eine 'MobileClient' Version implementiert ist dann muss die folgende
Zeile
* 'auskommentiert' werden. *///
private
application_entity
_BO_Synchronizer
struct
application_entity
_BO_Synchronizer
=
null
;
/* ---------------------
* CONSTRUCTOR-METHODE *//* ---------------------
.
. . . . . . . .
. . . . . . . . .
Verändern
der Methode
synchronizeBO()
wenn
eine 'MobileClient' Version nicht verwendet wird
Wenn
das Anwendungsprogramm nicht mit der möglichen Version für
einen 'MobileClient' entwickelt wird, muss der Code innerhalb der
Methode
synchronizeBO()
entfernt
werden weil das darin verwendete Objekt der Klasse
application_entity
_BO_Synchronizer
nicht
implementiert wurde.
Löschen Sie den Code innerhalb der
Methode oder setzen Sie Kommentare an die Anfänge der Zeilen,
Löschen
Sie nicht die gesamte Methode – diese wird mehrmals innerhalb
des Codes der Klasse aufgerufen !
n,
ist jetzt der optimale Zeitpunkt, die dafür notwendige
'Synchronizer'-Klasse zu implementieren.
Die Anleitung dafür
finden Sie unter Leitfaden
für die Entwicklung von Heavyweight-Clients mit dem JS-FCF –
Alle Schritte zur Entwicklung von DBA (DataBase-Access) und BO
(Business-Object) Klassen > Leitfaden – BO-Synchronizer
(Klasse zur Datensynchronisation zwischen JAS und lokaler Datenbank)
und
den darin gelisteten weiteren Anleitungen.
.
. . . . . . . .
. . . . . . . .
.
/*
* --------------------
* METHODE
zum Aufrufen der eigenen Klasse für das Abgleichen von
BO
* wenn
das Anwendungsprogramm in der Version 'MobileClient' läuft.
* Soll
eine 'MobileClient' Version nicht implementiert werden dann muss
diese Methode
* gelöscht werden. */
private
void
synchronizeBO()
{
/*
* Wenn das Anwendungsprogramm nicht für die
Version 'MobileClient' implementiert wird
* entfernen
Sie bitte den Code innerhalb dieser Methode oder kommentieren Sie
aus. *//*
* Zuerst Prüfen ob schon ein Objekt für den
nebenläufigen Prozess (Thread) existiert.
* Bei
Bedarf ein Objekt 'konstruieren'.
* Hinweis:
* Im
Muster ist die Variablendeklaration für die Synchronizer-Klasse
auskommentiert. */
if
(
struct
application_entity
_BO_Synchronizer
==
null
)
struct
application_entity
_BO_Synchronizer
=
new
application_entity
_BO
_Synchronizer(
frmCC
,
frmTask
);
/*
* Dieses BO-Set (gesamtes Objekt) an den Synchronizer
übergeben.
* Der asynchrone Prozess wird in der
aufgerufenen Methode gestartet.
*/
struct
application_entity
_BO_Synchronizer
.passBOList(
this
);
}
.
. . . . . . . .
. . . . . . . . .
Generelle
Tätigkeiten bei Verwendung von EJB (Client-Server-Architektur)
Bevor
die Methoden des EJB (Enterprise Java Bean) aufgerufen werden
können, müssen die Methoden in den Interfaces und der
Klasse für das EJB implementiert sein.
Die Anleitung für
das Hinzufügen und Adaptieren der Methoden für ein BO
finden Sie unter Muster-Codes
für die Klasse eine EJB (Enterprise Java Bean) mit
Datenbankzugriff > Methoden für die Datenzugriffe adaptieren
– generell
und
den dort folgenden Abschnitten.
Entfernen
Sie die Kommentare vor den Anweisungen zum Instanziieren des EJB,
zum Aufrufen der Methoden und zur Fehlerbehandlung.
.
. . . . . . . .
. . . . . . . . ./*
* Damit Fehler bei der Verbindung zum EJB behandelt werden
können ist der try/catch-Mechanismus
* erforderlich.
*///
try
{
/*
*
Instanziieren (Konstruieren) des Client-seitigen Objekts ('Remote
interface') für
* den Aufruf von Methoden des EJB.
Die Methode zum Instanziieren ist im Start-Frame implementiert.
*
In diesem Muster wird das Standard-EJB verwendet.
*
* Sollte die Methode für den Datenbankzugriff in
einem anderen EJB enthalten sein
* ist das passende EJB zu
instanziieren.
*/
//
application_package
.ejb.interfaces.remote.
application
_
StandardBeanRemote
instanceStandardEJB
=
//
frmCC.struct
application
_
CommandCenter__JASConnections
.get_
application
_
StandardBeanRemote
();
/*
* Aufrufen der 'Wrapper'-Methode des EJB.
* In
dieser 'Wrapper'-Methode wird die - zu diesem Client-seitigen Teil
gehörende -
* passende Server-seitige Methode
aufgerufen.
* Die über die Selektion gefundenen BO
sind im zurück gelieferten BO-Set enthalten. *///
application_entity
_BO_Set bo_BO_Set
=
//
instanceStandardEJB.
application_entity
_BO_Set__selectBy
method
(
//
frmTask
.
structMinParm
,
parm
Variable_1
,
parm
Variable_2
);
/*
* Werte des zurück gelieferten BO auf diese BOC
(Client-seitiger Teil des BO) kopieren. *///
this
.copyFrom
application_entity
_BO_Set(bo_BO_Set);
//
}
//
catch
(Exception
e){
/*
* Fehler beim Ausführen der Methode des EJB.
*
Fehlermeldung aus der Exception übernehmen und Status setzen.
*///
this
.
StatusCode
=
JSBS_BO.
CONST_DB_UNKNOWN_ERROR
;
//
this
.
StatusMsg
= e.getMessage();
//
}
break
;
/*
*/
Beim
Instanziieren des EJB ist die entsprechende EJB-Klasse und die
Methode zum 'Holen' eines Objekts der EJB-Klasse manuell zu
adaptieren:
*
Sollte die Methode für den Datenbankzugriff in einem anderen
EJB enthalten sein
* ist das passende EJB zu
instanziieren.
*/
application_package
.ejb.interfaces.remote.
application
_
StandardBeanRemote
instanceStandardEJB
=
frmCC
.
struct
application
_
CommandCenter__JASConnections
.get_
application
_
StandardBeanRemote
();
/*
Beim
Adaptieren dieser Platzhalter beachten Sie bitte, dass das Ausführen
von Methoden des BOS auch in verschiedenen EJB erfolgen kann –
abhängig von Ihrer Architektur des Anwendungsprogramms - und
damit auch die Verbindung zu verschiedenen EJB hergestellt werden
muss.
Aus
diesem Grund enthält dieses Dokument auch keine Beschreibung,
wie die Platzhalter durch 'Find/Replace' ersetzt werden können.
Aufruf
der Methode
selectBy
Variables
(
String
parm
Variable_1
,
String parm
Variable_2
)
des BOS
adaptieren
Die
Platzhalter des Design-Patterns sind so standardisiert, dass über
ein 'Find/Replace' im Abschnitt
Änderung
des Namens der Klasse und der 'Constructor Methoden'
auch
in den Methoden für die Abfragen (
select...(...)
)
auf die Datenbank-Tabellen die Platzhalter
(
application_entity
_BO_Set
)
durch die geforderten Werte ersetzt werden.
Zusätzlich
ist noch eine Anpassung des Namens der Methode und der
Selektionskriterien für die Abfrage notwendig.
Das ist einmal
in der Methodendeklaration notwendig:/*
* METHODE
zum Selektieren aller aktuell gültigen Datensätze
entsprechend
* den Selektionskriterien die als
Parameter übergeben werden.
* 'Aktuell gültig'
bedeutet, dass die Gültigkeit des Datensatzes mit dem
* im
Minimalen Set von Parametern übergebenen Arbeitsdatum
übereinstimmt. */
public
void
selectBy
Variables
(String
parm
Variable_1
,
String
parm
Variable_2
)
{
/*
* Entscheiden, ob diese Application als
Einzelplatz-Version (StandAlone) oder
Weiters
muss auch der Aufruf der Methode des zugehörigen BOS adaptiert
werden:
/*
* Einzelplatz-Version bzw. Datenbank-Zugriff über
TCP/IP-Netzwerk.
* Server-Side-BO-Set 'konstruieren'.
*/
application_entity
_BOS_Set
bos_BO_Set =
new
application_entity
_BOS_Set(
frmTask
.
structMinParm
,
structDBCon
,
true
);
/*
* Methode zum Selektieren der Werte aufrufen.
*/
bos_BO_Set.selectByVariables
(
parm
Variable_1
,
parm
Variable_2
);
/*
* Neue Werte des BOS wieder in dieses BOC
übertragen.
* Damit sind geschäfts-spezifische
Attribute, Common-Attributes, Status-Code
Aufruf
der Methode
selectBy
Variables
(
String
parm
Variable_1
,
String
parm
Variable_2
)
des EJB
adaptieren
Die
Platzhalter des Design-Patterns sind so standardisiert, dass über
die generellen Adaptierungen alle allgemeinen Platzhalter durch die
benötigten Namen ersetzt werden.
Individuell
muss der Aufruf der Methode des zugehörigen BOS adaptiert
werden:
/*
* Aufrufen der 'Wrapper'-Methode des EJB.
* In
dieser 'Wrapper'-Methode wird die - zu diesem Client-seitigen Teil
gehörende -
* passende Server-seitige Methode
aufgerufen.
* Die über die Selektion gefundenen BO sind
im zurück gelieferten BO-Set enthalten. */
application_entity
_BO_Set bo_BO_Set
=
instanceStandardEJB.
application_entity
_BO_Set__selectBy
method
(
frmTask
.
structMinParm
,
parm
Variable_1
,
parm
Variable_2
);
/*
* Werte des zurück gelieferten BO auf diese BOC
(Client-seitiger Teil des BO) kopieren. */
this
.copyFrom
application_entity
_BO_Set(bo_BO_Set);
Bei Version
'MobileClient': Codieren der Sortier-Methode(n)
Wenn
für dieses Business-Object auch die Version 'MobileClient'
(Erfassen und Verwalten von Daten auf der lokalen Datenbank eines
'Client'-Gerätes mit späterer Synchronisation mit der
zentralen Datenbank des Servers) vorgesehen ist, muss nach dem
Synchronisieren der Daten die Liste mit den BO möglicherweise
neu sortiert werden.
Nach
welchen Variablen sortiert wird und in welcher Klasse (dieser
Client-seitigen, Server-Seite, Generelle Klasse für das BO) die
Sortierung erfolgt hängt von den Anforderungen des
Anwendungsprogramms ab und kann nicht generell beantwortet
werden.
Eine Implementierung in dieser (Client-seitigen) Klasse
für das BO ist sinnvoll, wenn das Sortieren nur auf der
Client-Seite und nicht
auf
der Server-Seite erforderlich ist.
Den
Muster-Algorithmus für das Sortieren finden Sie in unter
Muster-Code
für ein BO_Set (Liste mit Business-Objects, Generelle Klasse) >
Sortieren der Liste (aufsteigend)
und
>
Sortieren der Liste (absteigend)
.
Spezieller
Muster-Code
In diesem Teil
wird Muster-Code vorgestellt, der nicht in jeder Generellen Klasse
eines BO vorkommen wird und deswegen nicht in den Muster-Code der
Klasse aufgenommen wurde.
Dokument |
Inhalt |
In diesem Leitfaden werden alle Tätigkeiten für die Entwicklung der Zugriffe auf Daten gelistet – auch jene die nicht direkt das Codieren in Java umfassen. |
|
Muster-Code für ein BOC (Client-Side Klasse eines Business-Object) |
Muster-Code für
die BOC-Klasse, mit denen ein BO bearbeitet wird. |
Schritt desTutorials für die Entwicklung von Heavyweight-Client Anwendungen in dem die Implementierung der Client-Side-Klasse für ein Set von BO vorgestellt wird. |