Datenaustausch mit XML - DIUF

Werbung
Datenaustausch mit XML
Entwicklung eines generischen Vermittlungs-Werkzeuges zwischen
XML Schemas und Datenbanken
Diplomarbeit im Fach Informatik
an der Universität Fribourg
1. Referent: Prof. Andreas Meier
2. Referent: Prof. Pius Hättenschwiler
Betreuer:
Ass. Stefan Hüsemann
Eingereicht am:
30.8.2002
Vorgelegt von:
Thomas Schädler
Rue de l'Industrie 2
1700 Fribourg
[email protected]
Kurzfassung
Kurzfassung
Diese Diplomarbeit befasst sich mit der Erstellung eines Vermittlungswerkzeuges zwischen XML
Schemas und Datenbanken. XML Schemas werden heute immer mehr eingesetzt um Daten zwischen
verschiedenen Systemen auszutauschen. Als Beispiel wird die Verwendung des AIDA IDML Schemas
genauer erläutert. Dieses XML Schema wird von Organisationen im Bereich der Entwicklungsarbeit
ausgearbeitet und eingesetzt. Ein noch ungelöstes Problem ist es aber, wie man die in diversen Datenbanken vorhandenen Informationen ohne grossen Aufwand in das gewünschte Format konvertieren kann.
Die bisherige Praxis geht davon aus, dass man eine Datenbank besitzt, die selbst in der Lage ist dies
zu bewerkstelligen oder aber man beauftragt einen Experten der diese Arbeit durch eine speziell zugeschnittene, neu zu erstellende Software erledigt. Dies setzt meist grosse Geldmittel voraus, was
aber genau in dieser Branche nicht unbedingt gegeben ist, oder die anderweitig besser verwendet
werden könnten.
Hier setzt diese Diplomarbeit an und versucht diese Nachteile durch ein generisches Vermittlungs werkzeug zu beseitigen. Es ist detailliert beschrieben welche Grundkonzepte hinter einem solchen
Werkzeug stehen. Die verschiedenen Ansätze um die Daten von einem Modell (Datenbank) in ein
anderes Modell (XML Schema) zu konvertieren werden vertiefend erklärt.
In einem weiteren Teil werden die genauen Anforderungen an das zu erstellenden Werkzeug aufgelistet und schliesslich wird genauer auf die Implementation eingegangen. Das Werkzeug wird dabei
schrittweise - nach anfallender Komplexität des jeweiligen Modells - implementiert. Der aufmerksame
Leser kann somit den Entstehungsprozess besser verfolgen und durch den modularen Aufbau ist eine
mögliche Erweiterung dieses Werkzeuges nicht auszuschliessen.
In einem letzten Teil wird die Arbeit mit dem neu erstellen Werkzeug für den Anwender erläutert. Da
dieses Werkzeug nicht auf ein einzelnes XML Schema fixiert ist, sind viele Anwendungsmöglichkeiten
denkbar und der Autor hofft, dass sein Werkzeug - da Open Source und damit absolut lizenzfrei - vielen Entwicklern aber auch normalen Anwendern gute Dienste leistet.
Keywords
XML - XML Schema - Mapping - Datenbanken - Vermittlungswerkzeug
Autor: Thomas Schädler
i
Inhaltsverzeichnis
Inhaltsverzeichnis
1
Einleitung............................................................................................................................... 1
1.1
Problemstellung .................................................................................................................. 1
1.2
Zielsetzung ......................................................................................................................... 2
1.3
Vorgehensweise ................................................................................................................. 3
2
Datenaustausch mit XML ........................................................................................................ 4
2.1
Grundlagen von XML........................................................................................................... 4
2.1.1
XML allgemein ................................................................................................................. 4
2.1.2
XML Schema und Namensräume...................................................................................... 5
2.1.3
DOM und SA X ................................................................................................................. 9
2.2
Vor- und Nachteile von XML ...............................................................................................11
2.3
Alternative Möglichkeiten zum Datenaustausch....................................................................12
2.4
IDML Schema....................................................................................................................13
2.5
Client/Server- oder Dreischichtenarchitektur ........................................................................17
3
Datenbanken.........................................................................................................................19
3.1
Grundlegende Anforderungen.............................................................................................19
3.2
Schnittstellen .....................................................................................................................19
3.3
Beziehung zwischen Datenbanken und XML........................................................................20
3.4
Mapping ............................................................................................................................21
3.4.1
Tabellen-basiertes Mapping.............................................................................................21
3.4.2
Vorlagen-gesteuertes Mapping ........................................................................................22
3.4.3
Objekt-relationales Mapping ............................................................................................22
4
Erstellung eines Modells ........................................................................................................25
4.1
Anforderungen an das Modell .............................................................................................25
4.2
Konstruktion des Modells ....................................................................................................25
4.3
Festlegung des Modells ......................................................................................................27
4.3.1
Der Konfigurator .............................................................................................................27
4.3.2
Die Serverkomponente....................................................................................................29
4.3.3
Die Mappingmodule ........................................................................................................29
5
Auswahl der Software / Programmiersprache ..........................................................................31
5.1
Anforderungen ...................................................................................................................31
5.2
Auswahl der Programmiersprache.......................................................................................31
5.3
Auswahl der Werkzeuge.....................................................................................................31
5.4
Auswahl der Bibliotheken....................................................................................................32
6
Implementation des Modells ...................................................................................................33
6.1
Speicherungshierarchie der Projektdaten.............................................................................33
6.2
Implementation des Konfigurators .......................................................................................33
6.2.1
Implementation des Moduls «Simple DB Export» ..............................................................36
6.2.2
Implementation des Moduls «Database to XML»...............................................................39
Autor: Thomas Schädler
ii
Inhaltsverzeichnis
6.3
Implementation des Servers ................................................................................................44
6.4
Erfahrungsbericht ...............................................................................................................45
7
Informationen für Anwender ...................................................................................................46
7.1
Einführung.........................................................................................................................46
7.2
Systemvoraussetzungen und Installation .............................................................................46
7.3
Handbuch: <xmlizer> configurator .......................................................................................47
7.3.1
Startparameter................................................................................................................47
7.3.2
Anleitung........................................................................................................................48
7.4
Handbuch: <xmlizer> server ...............................................................................................51
7.4.1
Startparameter................................................................................................................51
7.4.2
Anleitung........................................................................................................................52
7.4.3
Anpassung an Ihre Bedürfnisse .......................................................................................55
8
Schlussfolgerungen ...............................................................................................................56
9
Quellenangaben und Literaturverzeichnis................................................................................57
Anhang A: Quelltext <xmlizer> configurator....................................................................................60
Anhang B: Quelltext <xmlizer> server .......................................................................................... 239
Ehrenwörtliche Erklärung ............................................................................................................ 299
Autor: Thomas Schädler
iii
Abkürzungsverzeichnis
Abkürzungsverzeichnis
AIDA
Accessible Information on Development Activities
API
Application Programming Interface (Programmierschnittstelle zu einer Applikation)
ASP
Active Server Pages (Proprietäre Internet-Technologie von Microsoft)
DOM
Document Object Model
DTD
Document Type Definition
EDI
Electronic Data/Document Interchange
EDIFACT
Electronic Data Interchange for Administration, Commerce and Transport
HTML
Hypertext Markup Language
HTTP
Hypertext Transfer Protocol
IDE
Integrated Development Environment
IDML
International Development Markup Language
ISO
International Standardization Organization (Internationales Normierungsgremium für
den technischen Bereich)
JDBC
Java Database Connectivity
JDOM
Java-based Document Object Model
NPO
Non-Profit Organization
ODBC
Open Data Base Connectivity (Microsoft)
PHP
PHP Hypertext Preprocessor (rekursives Akronym)
RDF
Resource Description Framework (Standard für Metadaten-Formate)
RFC
Request for Comments (Vorschlag für eine Norm im TCP/IP-Bereich)
RSS
Rich Site Summary / RDF Site Summary / Really Simple Syndication
SAX
Simple API for XML
SGML
Standard Generalized Markup Language
SQL
Structured Query Language
TCP/IP
Transmission Control Protocol / Internet Protocol (Kommunikationsstandard)
UML
Unified Modeling Language
URI
Uniform/Universal Resource Identifier (Generische Menge an Zeichenketten um
Ressourcen zu referenzieren)
URL
Universal/Uniform Resource Locator (Term für populäre URI's: http, ftp, etc…)
URN
Universal Resource Name (nach RFC 2141 definierter, eindeutiger Identifizierer)
W3C
World Wide Web Consortium (Vereinigung die sich um WWW-Standards kümmert)
WWW
World Wide Web
XML
Extensible Markup Language
XOR
Exclusive Or (Logischer Operator)
Autor: Thomas Schädler
iv
Abbildungsverzeichnis
Abbildungsverzeichnis
Abbildung 1
: AIDA Projects Development Gateway Website ................................................... 2
Abbildung 2
: Beispieldokument garage.xml (XML Dokument).................................................. 4
Abbildung 3
: Bedeutung der Namensräume in XML................................................................ 6
Abbildung 4
: Beispieldokument garage.xsd (XML Schema)..................................................... 8
Abbildung 5
: Baumstruktur des Beispielschemas [XMLSPY 01] .............................................. 9
Abbildung 6
: Konzeption von DOM (Document Object Model)................................................. 9
Abbildung 7
: Gegenüberstellung von DOM und SAX.............................................................11
Abbildung 8
: Site Description Schema: Beispiel von idmlInfo.xml ...........................................13
Abbildung 9
: IDML Core Activity Schema (Baum) [XMLSPY 01] .............................................14
Abbildung 10
: Core Activity Schema: Beispiel von activities.xml ...............................................16
Abbildung 11
: IDML Datenaustausch (Standardprozedur)........................................................17
Abbildung 12
: IDML Datenaustausch (mit Vermittlungswerkzeug) ............................................18
Abbildung 13
: Beispiel für Tabellen-basiertes Mapping [Bourret 02] ..........................................22
Abbildung 14
: Beispiel für Vorlagen-gesteuertes Mapping .......................................................22
Abbildung 15
: XML Dokument aus Abbildung 2 als Objekt-Schema..........................................23
Abbildung 16
: XML Dokument aus Abbildung 2 als Objekt-Baum, DOM-Baum und
Klassenhierarchie .............................................................................................24
Abbildung 17
: Architektur des Vermittlungswerkzeugs in der Übersicht.....................................26
Abbildung 18
: xmlizer.project.config.xsd (Baum, kein Mapping) [XMLSPY 01] ...........................28
Abbildung 19
: Beispiel einer Konfigurationsdatei ohne Mappinginformationen ...........................29
Abbildung 20
: UML Klassen-Diagramm des Konfigurators (User Interface) [JVision 02] .............34
Abbildung 21
: UML Klassen-Diagramm des Konfigurators (Daten) [JVision 02] .........................35
Abbildung 22
: Beispielausgabe des Moduls «Simple DB Export» (simple) ................................36
Abbildung 23
: xmlizer.smdbe.verbose.dtd...............................................................................37
Abbildung 24
: Beispielausgabe des Moduls «Simple DB Export» (verbose) ..............................38
Abbildung 25
: Beispiel der Mappingdaten für das Modul «Simple DB Export» (gekürzt).............38
Abbildung 26
: xmlizer.project.config.xsd (Baum, nur Mapping) [XMLSPY 01] ............................39
Abbildung 27
: Beispiel der Mappingdaten für das Modul «Database to XML» ...........................40
Abbildung 28
: UML Klassen-Diagramm des Servers (Komplett) [JVision 02] .............................44
Abbildung 29
: Der Konfigurator in Aktion ................................................................................48
Abbildung 30
: Das Module «Simple DB Export» in Aktion ........................................................49
Abbildung 31
: Das Modul «Database to XML» in Aktion : Der Datenbankbrowser .....................50
Abbildung 32
: Das Modul «Database to XML» in Aktion: Drag und Drop einer Abfrage ..............51
Abbildung 33
: Beispiel zweier URL's für das Modul «Simple DB Export» ..................................53
Abbildung 34
: Beispiel einer URL für das Modul «Database to XML» .......................................53
Abbildung 35
: Auflistung der Projekte des Servers (index.html) ................................................53
Abbildung 36
: Projektdetails für das Modul «Database to XML»...............................................54
Abbildung 37
: Beispiel einer HTML-formatierten Ausgabe der XML Daten ................................54
Autor: Thomas Schädler
v
1 Einleitung
1
Einleitung
1.1
Problemstellung
Humanitäre Organisationen haben ein grosses Bedürfnis nach Kommunikation innerhalb der Organisation selber, aber auch gegenüber ihren Partnern, die im folgenden als Stakeholder bezeichnet werden. Die internationale Arbeit von humanitären Organisationen stellt eine weitere Hürde für eine gute
Kommunikation und Information aller Stakeholder dar.
Humanitäre Projekte müssen geplant, durchgeführt und anschliessend evaluiert werden. Diese Arbeit
generiert eine grosse Menge von Daten bei allen Beteiligten. Das Medium Internet kann dabei eine
grosse Hilfe sein, da dessen Einsatz relativ billig und ortsunabhängig ist. Das Problem ist allerdings
die Menge an Daten und die verschiedenen Datenformate die bei den verschiedenen Stakeholdern
eingesetzt werden. Um an die Daten zu kommen müssen die Stakeholder viele verschiedene Quellen
finden und analysieren.
Besser wäre es ein definiertes Datenformat zu haben, das dezentral gespeichert, aber von einer zent ralen Stelle aus (z.B. von einer Website) durchsucht werden kann. Weitere Ansprüche an eine solche
Webapplikation sind v.a. aus der Sicht von NPO's (Non-Profit Organisationen) der Einsatz von lizenzfreier Software und offenen Standards. Ausserdem sollten die eingesetzten Standards zukunftssicher
sein, damit die angehäuften Daten nicht in kürze wieder neu aufbereitet werden müssen.
Eine Lösung für den Datenaustausch von Projektinformationen in Bezug auf Entwicklungsprojekte
wird momentan in Form eines XML Schemas ausgearbeitet [IDML 01]. Dieses Schema ist auch
Grundlage dieser Arbeit. Wie in Abbildung 1 zu sehen ist hat das AIDA Projekt hat schon eine WebApplikation entwickelt um weltweit nach Entwicklungsprojekten zu suchen.
Ein noch ungelöstes Problem ist auch die Speicherung von (XML-) Projektdaten in einer (schon vorhandenen) Datenbank und das Auslesen der Datensätze um das Austauchformat zu erhalten. Eine
mögliche Lösung ist das Programmieren eines Filters, der die richtigen Daten automatisch aus der
Datenbank auslesen und in das gewünschte XML Schema umwandeln oder vorhandene XML Daten
in die Datenbank aufnehmen kann. Besser wäre es ein generisches Werkzeug zu haben, das zwischen Datenbank und XML Schema vermitteln kann.
Autor: Thomas Schädler
1
1 Einleitung
Abbildung 1
: AIDA Projects Development Gateway Website
Es gibt drei Grundlegende Szenarien:
1.
Es ist keine Datenbank vorhanden (Die XML Daten werden in einer neu angelegten Datenbank gespeichert.)
2.
Es ist kein XML Schema vorhanden (Die Daten aus der Datenbank werden in einem neu generierten XML Format ausgegeben.)
3.
Datenbank und Schema sind vorhanden, aber die Abbildung in beide Richtungen ist noch
nicht erledigt.)
Am häufigsten wird wohl der dritte Fall vorkommen, da alle Stakeholder normalerweise schon Datenbanken besitzen und nur die Daten nach einem ebenfalls schon vorhandenen XM L Schema ex - bzw.
importieren wollen. Diese Arbeit benötigt genau Kenntnisse der Datenbank und des zu verwendenden
XML Schemas. Beim ersten und zweiten Fall gibt es Möglichkeiten automatisch aus der Datenbank
ein XML Schema zu generieren oder umgekehrt.
1.2
Zielsetzung
Die Zielsetzung dieser Diplomarbeit ist es ein Werkzeug zu entwickeln, das beliebige Datenbanken
auf beliebige XML Schemas abbilden kann, vorausgesetzt natürlich die Datenbank stellt alle Informationen zur Verfügung die benötigt werden. Primär ist jedoch die Funktion um XML Daten aus beliebigen Datenbanken auszulesen und in das IDML Schema zu konvertieren, um damit die schnelle Anbindung vieler neuer Datenbanken für das AIDA Projekt zu ermöglichen [AIDA 01]. Einmal für die
Autor: Thomas Schädler
2
1 Einleitung
jeweilige Datenbank und das benutzte XML Schema konfiguriert, vermittelt dieses Werkzeug automatisch zwischen Datenbank und XML Schema. Es ist nachher möglich, Daten aus der Datenbank als
gültige XML Datei auszulesen, die nachher verschickt oder bearbeitet werden können. Auch die Aufnahme einer XML Datei in die Datenbank ist möglich. Dies würde auch bei Änderungen in der Anordnung (Datenbank oder XML Schema) eine einfache Möglichkeit darstellen auf die neue Situation zu
reagieren.
1.3
Vorgehensweise
In einem ersten Teil der Arbeit werden grundsätzliche Fragen zu XML (Extendend Markup Language)
geklärt. Vor- und Nachteile von XML werden analysiert und ein Überblick über die momentan verwendeten Technologien zum Austausch von Informationen über das Internet wird verschafft. Hauptaugenmerk liegt dabei auf den verwendeten Standards (XML allgemein, XML Schema, DOM und SAX),
da diese Standards im weiteren Verlauf dieser Arbeit exzessiv verwendet und analysiert werden. An
einem kleinen Beispiel wird die Verwendung von XML und XML Schema erklärt.
In einem zweiten Teil wird auf die Anforderungen an die zu verwendenden Datenbanken eingegangen. Da es Ziel der Arbeit ist mit möglichst vielen verschiedenen Datenbanken zusammenzuarbeiten
ist eine Suche nach der offensten Programmierschnittstelle (API: Application Programming Interface)
nötig. Dieses Kriterium schränkt schon früh ein, welche Programmiersprache sich für die künftige
Implementation verwenden lässt.
Nach der Festlegung der Grundlagen wird in einem dritten Teil ein Modell aufgestellt, dass dann für
die Implementation als Grundlage dienen wird. Alle bisher gesammelten Anforderungen müssen in
dem Modell vereinigt werden und werden detailliert beschrieben. Die Anforderungen an die Benutzerschnittstelle müssen auch abgeklärt werden.
Es gibt eine Unmenge an möglichen Standards, Sprachen und Softwarekomponenten, mit dem so ein
Modell implementiert werden kann. Im vierten Teil werden diese Möglichkeiten und Kombinationen
kurz analysiert und bewertet.
Im fünften Teil dieser Arbeit wird das aufgestellte Modell mit der am besten bewerteten Software implementiert und die dabei auftretenden positiven und negativen Erfahrungen erläutert. Die Basis für die
Implementation wird mit Hilfe von UML Klassen-Diagrammen erstellt. Das daraus erstellte CodeGerüst wird anschliessen nach dem Top-Down-Verfahren implementiert und je nach Notwendigkeit
erweitert.
Im sechsten und letzten Teil dieser Arbeit wird die Arbeit mit der nun erstellten Software für den zukünftigen Anwender in der Art eines Handbuchs erklärt um ein produktives Arbeiten zu erleichtern.
Autor: Thomas Schädler
3
2 Datenaustausch mit XML
2
Datenaustausch mit XML
2.1
Grundlagen von XML
Das WWW (World Wide Web) bietet heute mehr als nur statische Inhalte. Leider ist HTML (Hypertext
Markup Language) nur bedingt nützlich um neue Anwendungen im Internet abrufbar zu machen.
HTML wurde als Auszeichnungssprache konzipiert und beschreibt wie ein Dokument in einem Webbrowser darzustellen ist. Bei HTML ist die Semantik der Auszeichnungselemente (engl.: tag) fest definiert und die Menge an Auszeichnungselementen ist genau definiert und somit limitiert. Diese Einschränkung ist genau das Problem, wenn man Daten über das Internet austauschen oder eigene
Strukturen definieren möchte.
2.1.1 XML allgemein
XML (Extended Markup Language) ist keine Markupsprache wie HTML, sondern eine Metasprache
1
zur Definition von Markupsprachen. XML wurde vom W3C (World Wide Web Consortium ) definiert
welches auch HTML definierte. HTML ist eine Untermenge von XML, und XML ist wiederum eine Untermenge von SGML (Standard Generalized Markup Language) welches schon 1986 vom W3C als
ISO-Standard (ISO 8879) definiert wurde. Da SGML nicht direkt für das WWW definiert wurde und
eine sehr komplexe Sprache ist wurde XML entwickelt um diese Lücke zu schliessen.
Um die Syntax von XML besser zu verstehen folgt ein kurzes Beispieldokument. In der erste Zeile
jedes XML Dokuments muss der Prolog stehen. Im Prolog stehen Versionsnummer, Codierung und
eine Anweisung ob das Dokument auf eine externe DTD (Document Type Definition) oder ein XML
Schema (Alternative einer DTD) verweist oder ohne auskommt. Im Wurzelelement (<garage>) werden
die benötigten Namensräume definiert. Leere Elemente darf man in XML auch wie im Beispiel das
Optionen-Element abkürzen (<option/>), es kann aber auch weiterhin die aus HTML bekannte Form
(<option></option>) verwendet werden.
<?xml version="1.0" encoding="ISO8859-1" standalone="no"?>
Prolog
<!-- Dies ist ein Kommentar -->
<garage xmlns="http://www.e-freak.ch/xml/garage"
xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
Namens-
xsi:schemaLocation="http://www.e-freak.ch/xml/garage garage.xsd">
raum
<motorrad>
definitionen
<marke>Yamaha</marke>
<typ herstellungsjahr="1984" zylinder="1">XT 550</typ>
<farbe>Schwarz</farbe>
<option/>
MotorradElement
</motorrad>
</garage>
Abbildung 2
1
: Beispieldokument garage.xml (XML Dokument)
World Wide Web Consortium http://www.w3.org/
Autor: Thomas Schädler
4
2 Datenaustausch mit XML
Auszeichnungselement können auch Attribute verwenden, um zusätzliche Daten aufzunehmen. Im
konkreten Beispiel hat das Auszeichnungselement «typ» ein Attribut «herstellungsjahr» und ein Attribut «zylinder». Ob man ein Attribut oder ein neues Auszeichnungselement benutzt hängt von der Art
der Daten ab. Es gibt keine allgemeingültigen Regeln, aber als Faustregeln kann man folgende Hinweise zu Rate ziehen [XMLS 01]:
•
Daten die wiederum in Unterkategorien gegliedert werden, die andere Auszeichnungselemente enthalten, müssen als eigenes Auszeichnungselement definiert werden (in Attributen kann
man keine Auszeichnungselemente speichern, sondern nur simplen Text).
•
Wenn Daten mehrere Zeilen lang sein können, muss auch ein eigenes Auszeichnungselement verwendet werden. (Man könnte auch ein Attribut verwenden, allerdings wird der Code
dann sehr unleserlich.)
•
Wenn Daten oft ändern sollte man auch eigene Auszeichnungselemente definieren. (Mit heutigen XML-Editoren sind Auszeichnungselemente einfacher zu finden und zu ändern als
Attribute).
•
Kurze und kaum zu ändernde Daten werden bevorzugt als Attribut gespeichert.
•
Sind bei den Daten eine limitierte Anzahl von Möglichkeiten vorgesehen (Auswahl), dann benutzt man bevorzugt Attribute (XML Editoren können dann z.B. die Auswahl das DropdownListe anzeigen und es können dann nur die Daten eingetragen werden die dafür in dem XML
Schema definiert wurden).
Damit ein XML Dokument syntaktisch korrekt ist (engl.: well-formed) muss sich ein XML Dokument
strikt an folgende Regeln halten (ein komplette Liste aller Regeln und damit verbundne Fragen kann
man bei [UUC 01] nachlesen):
•
ein XML Dokument muss mindestens ein Element enthalten
•
es darf nur ein Wurzel-Element enthalten, welches alle anderen Elemente umschliesst
•
Elemente müssen sich immer komplett umschliessen und dürfen sich nicht überlappen
Durch das Einhalten aller Regeln wird der Austausch von XML Dokumenten erst möglich und es müssen keine speziellen Programme geschrieben werden um Fehler zu erkennen. Ein XML Dokument
alleine hat aber noch keine Aussagekraft (für eine Maschine). Das Dokument kann zwar von einem
Menschen gelesen und verstanden werden, eine Maschine braucht aber mehr Informationen zu den
benutzten Auszeichnungselementen, da diese ja frei erfunden wurden. Damit ein XML Dokument gültig (engl.: valid) ist muss es eine DTD oder ein XML Schema assoziiert haben.
2.1.2 XML Schema und Namensräume
Im folgenden wird nur auf den XML Schema Standard eingegangen, da die DTD’s in Zukunft von XML
Schema abgelöst werden sollten. Am 3. Mai 2001 hat das World Wide Web Consortium XML Schema
als «Recommendation» herausgegeben und dieser Standard wird jetzt als stabil bezeichnet [W3CS
01]. XML Schema bietet im Vergleich zu einer DTD bessere Lesbarkeit (XML Syntax), über 40 vordefinierte Datentypen, Möglichkeit der Gruppierung von Elementen, Möglichkeit der objektorientierten
Autor: Thomas Schädler
5
2 Datenaustausch mit XML
Programmierung (Vererbung, Erweiterbarkeit und Restriktion), Gebrauch von Namensräumen und
Reguläre Ausdrücke um eigene Typen genau zu definieren.
Ein XML Dokument kann in unterschiedlichen Anwendungsgebieten verwendet werden. Namensräume (engl.: namespaces) werden definiert, damit die es keine Konflikte zwischen den Elementnamen
verschiedener XML Schemas geben kann. Namensräume werden mittels einer einmaligen, fiktiven
URI (Uniform Resource Identifier) oder URN (Universal Resource Name) voneinander unterschieden.
Das XML Schema muss also nicht – kann aber – unter dieser URI erreichbar sein. Nach [Castro 00]
wurden URI's gewählt, da die Namensgebung von URI's von Natur aus einmalig ist (jeder Domainnamen kann nur einmal ve rgeben werden). Jedes Schema hat seinen eigenen Namensraum, kann aber
auch zu einem bestehenden Namensraum hinzugefügt werden, falls es keine Kollisionen der verwendeten Element- und Attributnamen geben kann (engl.: sharing). Abbildung 3 verdeutlicht die Wichtigkeit von Namensräumen und zeigt auf, in welcher Verbindung die verschiedenen Namensräume stehen.
...
...
schemaLocation="A
xmlns:xsd="B"
garage.xsd"
...
B: «schema-of-schemas»
targetNamespace="A"
(definiert die Elemente
...
des Namensraumes B,
um damit eigene Schemen zu definieren)
garage.xml
garage.xsd
XMLSchema.xsd
Ÿ benutzt Elemente aus
Ÿ definiert Elemente des
Ÿ benutzt Elemente aus
dem Namensraum A
Namensraumes A
dem Namensraum B
Ÿ benutzt Elemente des
(URL des Schemas der
Namensraumes B
Schemen: W3C-Vorgabe)
...validiert das Ausgangsdokument nach den Regeln des übergeordneten Dokuments
Abbildung 3
: Bedeutung der Namensräume in XML
Definiert man für die Namensräume ein Präfix (z.B. «xmlns:xsd» mit Präfix «xsd»), muss man bei
Gebrauch eines Elementes aus diesem Namensraum das Präfix verwenden. Der Bezeichner «xmlns»
für Namensräume ist reserviert, wie alle Bezeichner, die mit «xml» beginnen. Ohne Präfix sind die
Elemente global definiert und dürfen daher ohne Präfix verwendet werden. Es gibt daher drei unterschiedliche Varianten um mit Namensräumen zu arbeiten:
•
Man definiert den Namensraum des Schemas der Schemen global und die eigenen Elemente
müssen mit einem Präfix gekennzeichnet werden.
•
Man definiert den eigenen Namensraum global und den Namensraum des Schemas der
Schemen mit einem Präfix oder
•
man kann auch beiden Namensräumen ein Präfix vergeben.
Autor: Thomas Schädler
6
2 Datenaustausch mit XML
Im folgenden wird die zweite - besser lesbare - Variante verwendet: Alle Elemente aus dem Namensraum des Schemas der Schemen müssen also mit Präfix deklariert werden, eigene Elemente nicht.
Ein XML Schema ist ein Dokument das die erlaubte Syntax eines XML Dokuments definiert. Um XML
Schema besser zu verstehen, folgt ein kurzes Beispieldokument, dass ein XML Schema für das in
Abbildung 2 verwendete XML Dokument sein könnte. Wie schon erwähnt, steht im Prolog des XML
Dokuments aus Abbildung 2 «standalone=no» und in der sechsten Zeile wird auf eine Datei «garage.xsd» verwiesen. Dieses bedeutet, das dem XML Dokument ein XML Schema zugeordnet werden
kann und das XML Dokument also nur zusammen mit diesem XML Schema gültig sein kann.
In der ersten Zeile in Abbildung 4 steht wiederum der bekannte XML Prolog, da es sich um ein normales XML Dokument handelt. Als Wurzelelement jedes XML Schemas steht das schema-Element, welches das ganze Schema umschliesst. In ihm werden auch die Namensräume definiert. Die erste Zeile
dient dazu, die im Dokument definierten Elemente (garage, marke, type etc.) einem eigenen Zielnamensraum zuzuordnen (engl.: targetNamespace). Zeile zwei importiert die benötigten Elemente um
ein Schema aufzubauen aus dem Namensraum des Schemas der Schemen (z.B. element, complexType, simpleType, restriction, string, integer etc.) und definiert gleichzeitig das Präfix, das benötigt
wird um auf Elemente aus dessen Namensraum zuzugreifen («xsd»). Die nächste Zeile definiert den
Standard-Namensraum für dieses Dokument - in diesem Beispiel den Zielnamensraum.
Autor: Thomas Schädler
7
2 Datenaustausch mit XML
<?xml version="1.0"?>
<xsd:schema targetNamespace="http://www.e-freak.ch/xml/garage"
xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
xmlns="http://www.e-freak.ch/xml/garage"
Das Garagen-Element enthält
elementFormDefault="qualified">
eine Sequenz von Motorrad-
<xsd:element name="garage">
Elementen (0 bis unendlich)
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="motorrad" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
Das Typ-Element besteht
<xsd:element name="motorrad">
aus einem komplexen Typ,
<xsd:complexType>
der lokal definiert ist (eng.
<xsd:sequence>
anonymous type):
<xsd:element name="marke" type="xsd:string"/>
Inhalt ist ein String (Typ-
<xsd:element name="typ">
Bezeichnung) und zwei
<xsd:complexType>
Attribute (herstellungsjahr
<xsd:simpleContent>
und zylinder)
<xsd:extension base="xsd:string">
<xsd:attribute name="herstellungsjahr" type="xsd:year" use="optional"/>
<xsd:attribute name="zylinder" type="zylinderType" use="required"/>
</xsd:extension>
</xsd:simpleContent>
Das Zylinder-Attribut hat
</xsd:complexType>
einen weiter unten selbst
</xsd:element>
definierten Typ (engl.
<xsd:element name="farbe" type="xsd:string"/>
named type)
<xsd:element name="option"
type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
minOccurs und maxOccurs
</xsd:complexType>
sind standardmässig immer
</xsd:element>
<xsd:simpleType name="zylinderType">
auf 1 gesetzt.
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="1"/>
Definition des Types für das
<xsd:maxInclusive value="8"/>
Zylinder-Element:
</xsd:restriction>
</xsd:simpleType>
Basistyp: Integer
akzeptiert als Min. 1, Max. 8
</xsd:schema>
Abbildung 4
: Beispieldokument garage.xsd (XML Schema)
Wie schon erwähnt, müssen Elemente aus dem Standard-Namensraum nicht mit einem Präfix qualifiziert werden. Die letzte Zeile im schema-Element bedeutet, dass Instanzen die dieses Schema benut zen, den Namensraum der in «targetNamespace» angegeben ist deklarieren müssen, damit sie die
neu definierten Elemente benutzen können. Ausserdem fügt es lokal deklarierte Elemente und Attribute zum Zielnamensraum hinzu.
Wie in Abbildung 5 zu sehen ist, definiert das in Abbildung 4 aufgeführte XML Schema einen Baum,
der die Struktur der XML Dokumente festlegt, die sich an dieses XML Schema halten. Die Wurzel des
Baumes ist das Garagen-Element. Innerhalb dieses Elementes kann es eine unbestimmte Anzahl an
Autor: Thomas Schädler
8
2 Datenaustausch mit XML
Motorrad-Elementen haben - keines bis unendlich viele. Ein Motorrad-Element wiederum besteht aus
einem Marken-Element, einem Typ-Element, einem Farben-Element und einem oder mehreren, optionalen Optionen-Elementen. Unten sind noch die Attribute des Typ-Elements aufgeführt. Jedes TypElement muss also ein Zylinder-Attribut haben, das Herstellungsjahr-Attribut ist jedoch optional.
Abbildung 5
: Baumstruktur des Beispielschemas [XMLSPY 01]
2.1.3 DOM und SAX
Um XML Dokumente weiterzuverarbeiten, muss eine einfache, standardisierte Schnittstelle vorhanden
sein, um auf die interne Struktur eines XML Dokuments zugreifen zu können. Dazu wurde vom World
Wide Web Consortium DOM (Document Object Model) und SAX (Simple API for XML) entworfen.
DOM uns SAX sind plattformunabhängige Schnittstellen die den Zugriff auf XML Dokumente standardisieren.
Abbildung 6 verdeutlicht das Konzept von DOM. Um mit DOM auf ein XML Dokument zuzugreifen,
muss das XML Dokument zuerst geparst werden. Sind keine syntaktischen Fehler vorhanden, wird
das XML Dokument gegen das XML Schema validiert. Ist das XML Dokument korrekt, wird das Dokument auf eine Baumstruktur (siehe Abbildung 5) abgebildet. DOM definiert nun verschiedene Methoden, mit denen man diesen Baum komfortabel bearbeiten kann. Es besteht die Möglichkeit, den
<tag></tag>
«ta
...
DOM
A
Parser
P
Programme
I
beispiel.xml
DOM Baum
Abbildung 6
Autor: Thomas Schädler
: Konzeption von DOM (Document Object Model)
9
2 Datenaustausch mit XML
Baum zu ändern, im Baum zu suchen, Elemente (Blätter des Baumes) zu ändern, löschen und hinzufügen etc. Eine genaue Beschreibung des Standards findet man in [W3CD 01] oder in [Morrison 00].
Obwohl DOM noch als junger Standard bezeichnet werden kann, finden sich eine Menge verschiedener Implementation. Eine der bekanntesten, weil auch schon früh verfügbaren DOM Implementationen
ist die Microsoft DOM Engine. Dadurch ist auch der Microsoft Internet Explorer (ab Version 5) der
einzige verbreitete Browser mit einer DOM Anbindung. Nach [Morrison 00] ist die MS DOM Engine
recht gut implementiert, hat aber ein paar nicht dem Standard entsprechende Ausnahmen. IBM hat
auch eine eigene DOM Implementation (in Java oder C). Viele Programmiersprachen bringen aber
heute schon ihre eigene DOM Implementation mit, oder mindestens eine Schnittstelle zu einer frei
verfügbaren DOM Implementation. Unter anderem Java, C++, VisualBasic, ASP, PHP, Perl, etc.
Einen etwas anderen Weg um XML Dokumente weiterzuverarbeiten ist SAX (Simple API for XML, API
= Application Programming Interface (deutsch: Programmierschnittstelle). SAX ist kein Standard des
World Wide Web Consortiums, sondern ein sog. De-facto-Standard. Wie der Name schon sagt, ist
SAX nicht so komplex wie DOM. Allerdings kann man SAX nur begrenzt einsetzen. Ein SAX Parser
kann nur Daten aus XML Dokumenten auslesen, nicht aber die Struktur verändern. Dadurch ist ein
SAX Parser schnell, flexibel und leichter zu implementieren und zu benutzen. SAX ist im Gegensatz
zu DOM ereignisbasiert (engl.: event-based). Beim parsen eines XML Dokuments werden beim Antreffen eines bestimmten Elements (Anfangs-Tag, End-Tag, etc.) die Daten an die Anwendung weitergeleitet und dort verarbeitet. Verfügbare SAX Implementationen gibt es zur Zeit für Java, Python, Perl
und PHP.
Autor: Thomas Schädler
10
2 Datenaustausch mit XML
DOM (Document Object Model):
Ÿ
für komplexe Dokumente
Ÿ
für Dokumente die von verschiedenen Datenquellen stammen
Ÿ
bildet eine Baumstruktur des Dokumentes
Ÿ
für Dokumente die komplexe Bearbeitung benötigen
Ÿ
objektbasiert
Ÿ
freier Zugriff (engl.: random-access) auf die Elemente eines Dokuments
Ÿ
Lese- und Schreibzugriff möglich
SAX (Simple API for XML):
Ÿ
für einfache Dokumente
Ÿ
für grosse Dokumente (physikalische Dateigrösse)
Ÿ
Ereignisbasierte Programmierung
Ÿ
für Dokumente die keine Änderung der Dokumentenstruktur benötigen
Ÿ
sequentieller Zugriff auf die Elemente eines Dokuments
Ÿ
nur Lesezugriff möglich
Abbildung 7
: Gegenüberstellung von DOM und SAX
Ob DOM oder SAX in einer Anwendung verwendet wird (oder häufig eine Kombination davon), hängt
von der Art der Anwendung ab. Abbildung 7 soll dabei helfen, die Entscheidung ob DOM oder SAX
verwendet wird zu erleichtern (aus [Vanoirbeek/Aboukhaled 00]).
Das hier aufgeführte Beispiel wurde mit Hilfe von XMLSpy [XMLSPY 01] entworfen und validiert.
XMLSpy ist ein kommerzielles Produkt, das praktisch alle Aspekte rund um XML berücksichtigt und
übersichtliches Arbeiten mit XML, XML Schema, DTD's, XSL und weiteren XML Dialekten erlaubt.
2.2
Vor- und Nachteile von XML
Die Bedeutung von XML nimmt immer mehr zu. Der wichtigste Grund dürfte sein, dass es ein offener
und plattformunabhängiger Standard ist. Dies sind auch die grossen Vorteile von XML gegenüber
ähnlichen Lösungen. Ein offener Standard hat aber noch mehr Vorteile: Er ist absolut lizenzfrei und
wird durch immer neue Applikationen und Erweiterungen weltweit weiterentwickelt. Allerdings kann
das auch als Nachteil gewertet werden, da viel Entwicklungswerkzeuge noch nicht fertiggestellt sind
und sich in der Entwicklung befinden. Ein weiterer grosser Vorteil von XML ist, dass ein XML Dok ument ein normales Textdokument darstellt, das ganz einfach weiterverarbeitet werden kann und ausserdem noch für einen Menschen lesbar ist (engl.: human-readable). Damit kann eine Information
über längere Zeit ohne Konvertierungsprobleme gespeichert werden und auch in der schnelllebigen
Softwareindustrie (alle paar Jahre eine neuer Standard) bleibt die Aussagekraft eines XML Dokuments
immer gleich. [Bellanet 01]
Autor: Thomas Schädler
11
2 Datenaustausch mit XML
Weitere Vorteile sind auch die einfache Kommunikationsinfrastruktur. Um XML Dokumente zu verschicken kann jedes herkömmliche Netzwerk verwendet werden, wobei hauptsächlich auf HTTP (Hypertext Transfer Protocol) über TCP/IP (Transmission Control Protocol / Internet Protocol) zurückgegriffen wird – dem Standard im Internet. Die dabei verwendete Bandbreite ist relativ klein, kann aber
durch speziellere Protokolle (vgl. EDI) noch kleiner gehalten werden. Als negativ wird dabei der grosse
Overhead von XML angesehen – ein grosser Teil eines XML Dokuments nimmt allein die Tag-Struktur
ein, die Daten eher den kleineren Teil. Konkrete Zahlen sind schwer zu bekommen und hängen von
dem verwendeten Schema (oder DTD) ab. Dies ist jedoch auf der anderen Seite wieder ein Vorteil: die
XML Dokumente sind besser lesbar. Ausserdem kann ein XML Dokument beim Austausch komprimiert werden um die Bandbreite bei der Übertragung zu schonen.
Als Nachteile sind aufzuführen, dass es nicht immer leicht ist ein passendes XML Schema oder eine
DTD zu entwerfen. Auch das gesamte String-Handling (XML Daten sind ja nur Textdateien) in der
Entwicklung von XML Applikationen wird als negativ erachtet. Jedoch ist es jedem Entwickler selbst
überlassen, welche Programmiersprachen er verwendet um XML Dokumente zu verarbeiten. Es sollte
also eine passende Verarbeitungssprache gesucht werden, die die Verarbeitung von Strings gut unterstützt.
2.3
Alternative Möglichkeiten zum Datenaustausch
Bisher benutzen die meisten Applikationen kein spezielles Format um Daten auszutauschen, da keine
Notwendigkeit gesehen wurde, diese Daten anderswo zu benutzen als in eigenen Applikationen die
untereinander natürlich das Austauschformat kannten, und somit kein Problem mit der Kodierung und
Entkodierung dieser Daten hatten. Durch die heutigen Möglichkeiten der Kommunikation wurde es
aber immer interessanter Daten auch mit Geschäftspartnern auszutauschen die nicht die gleichen
technischen Voraussetzungen erfüllten. Diese also z.B. eine andere Software einsetzten, eine andere
Plattform (Hardware, Betriebssystem), oder auch nur ein anderes Datenbank Management System.
Mit der Zeit wurden für viele Standardapplikationen und Programmiersprachen Schnittstellen und Protokolle geschaffen, mit denen es möglich ist, trotz allem miteinander zu kommunizieren. Dies löst aber
noch nicht das Problem des Datenformates.
Eine Lösung verspricht EDI [EDI 01]. Electronic Data Interchange ist eine Lösung für Business-toBusiness Kommunikation, entwickelt durch das "EDIFACT Standard Messages Directory" der Vereinten Nationen (Electronic Data Interchange for Administration, Commerce and Transport) [UNEDI 01].
EDI hat ein paar Fähigkeiten die jetzt auch mit XML möglich wären und wird deshalb auch als
XML/EDI weiterentwickelt. Als Hauptpunkt sind die hohen Kosten zu vermerken die EDI bei der Einführung verursacht. Da EDI hauptsächlich für den betriebswirtschaftlichen und organisatorischen Datenverkehr innerhalb einer Unternehmung oder zwischen einzelnen Unternehmen entwickelt worden
ist, benutzt man häufig ein eigenes VAN (Value Added Network), für welches Benutzungsgebühren
entstehen. Ausserdem muss immer noch die benutzte Datenbank eine EDI-Schnittstelle besitzen, da
man sonst mit weiteren Softwarekosten rechnen muss. [EDIAT 01]
Autor: Thomas Schädler
12
2 Datenaustausch mit XML
2.4
IDML Schema
Das IDML Schema ist ein speziell entwickeltes XML Schema um Daten über Entwicklungsprojekte zu
speichern und auszutauschen. Da dieses Schema noch dauernd geändert wird sind die hier erklärten
Sachverhalte mit Vorsicht zu geniessen. Die Grundstruktur wird sich aber nicht mehr gross ändern, da
das IDML Schema schon bei Version 0.9 angelangt ist. Die Grundlagen um mit Hilfe von IDML Schema Daten bereitzustellen sollen hier aufgezeigt werden. Das Vermittlungswerkzeug muss sich genau
an dieses Schema halten, da die Daten sonst beim weiterverarbeiten nicht validiert werden können
und für ungültig erklärt werden müssen.
Es werden mindestens zwei Dateien benötigt:
•
idmlInfo.xml Æ die Beschreibung (engl: site description) basiert auf dem «Site Description
Schema»
•
activities.xml Æ die Daten (engl: activity information) Æ basiert auf dem «Core Activity Schema» und dem «Extended Schema»
Die Beschreibung kann statisch generiert werden, da dieses XML Dokument nur wenige Daten beinhalten muss und erst auf die eigentlichen Projektdaten verweist. Die Beschreibung muss immer im
root-Verzeichnis (Oberste Ebene: /) des Webserver stehen, auf dem auch die Daten abgelegt sind
(oder zumindest auf dem die Daten auch gezogen werden können). Es beinhaltet die Version des
verwendeten IDML Schemas, das Datum der letzten Änderung, eine Kontaktadresse (Email) dessen
der sich bei dieser Organisation um die Bereitstellung der IDML Daten kümmert und einen Link auf die
Daten selbst (Beispiel siehe Abbildung 8). Dieser Link kann auf eine statische XML Datei ve rweisen
<?xml version="1.0"?>
IDML Versionsnummer
<idmlInfo>
<idmlVersion>0.9</idmlVersion>
<dataLink>
URL zu den Aktivitäten, kann
auch ein Skript sein. (dyna-
<dataType>activity</dataType>
misch oder statisch)
<url>http://www.some.org/activities.xml</url>
<format>xml</format>
<updated>2001-01-01</updated>
Datum des letzten updates
</dataLink>
<contactEmail>[email protected]</contactEmail>
</idmlInfo>
Kontaktadresse des
Datenpflegers
</xml>
Abbildung 8
: Site Description Schema: Beispiel von idmlInfo.xml
oder aber auf ein Skript, das die Daten dort dynamisch zur Verfügung stellt. Momentan wird zu Testzwecken häufig die statische Variante bevorzugt, da die Daten noch nicht dynamisch generiert werden
können.
Autor: Thomas Schädler
13
2 Datenaustausch mit XML
Abbildung 9
Autor: Thomas Schädler
: IDML Core Activity Schema (Baum) [XMLSPY 01]
14
2 Datenaustausch mit XML
Der Vorteil dieses geteilten Ansatzes ist ganz eindeutig die Möglichkeit eine Standarddatei (idmlInfo.xml) zu konsultieren, in der dann steht, wo genau die Daten bezogen werden können und welche
Version des IDML Schemas zu verwenden ist. Dadurch ist der Datenteil völlig unabhängig von der
Infrastruktur des Servers und dessen Möglichkeiten. Jede auf dem Server verfügbare Schnittstelle
kann verwendet werden um die Daten bereitzustellen.
Das IDML Schema besteht aus drei getrennten - aber nicht unabhängigen - Schemas:
•
Site Description Schema
Æ Beschreibung der angebotenen Informationen
•
Core Activity Schema
Æ Enthält die Daten (Aktivitäten)
•
Extended Schema
Æ Erweitertes «Core Activity Schema»
Wie schon erwähnt wir das «Site Description Schema» nur benötigt um eine Verknüpfung mit den
Aktivitäten über eine Standarddatei (gleicher Name und Zugriffspfad) zu gewährleisten. Deshalb ist
dieses Schema klein und hat keinen komplizierten Aufbau. Das «Core Activity Schema» beinhaltet die
Aktivitäten selbst und ist eine Teilmenge des «Extended Schemas». Der Unterschied der beiden letzt
genannten Schemas liegt darin, dass das «Core Activity Schema» alle unbedingt benötigten Daten
enthält. Das «Extended Schema» bietet die Möglichkeit noch weitere (nicht unmittelbar benötigte)
Informationen zur Verfügung zu stellen. [IDMLDraft 01]
Eine Übersicht über die Elemente des «Core Activity Schema» bietet Abbildung 9. Allerdings sind in
dieser Abbildung nur die Elemente aufgeführt und keine Attribute. Die einzelnen «activities» sind untereinander aufgelistet (Sequenz) und jede «activity» selbst beinhaltet weiterführende Informationen.
Abbildung 10 zeigt ein Beispiel einer gültigen XML Datei im «Core Activity Schema»-Format. Um das
Beispiel zu verkürzen enthält diese Datei nur eine Aktivität. Diese muss durch einen eindeutigen
Schlüssel (dbkey) gekennzeichnet sein und sollte mit dem Datum der letzten Änderung versehen sein
um alle Aktivitäten garantiert unterscheiden zu können. Jede weitere Referenz auf diese Aktivität
muss dann diesen Schlüssel benutzen. Mit Ausnahme des Datums, der URL und des Schlüssels sind
die Formate der eingegebenen Daten nicht vorgegeben (jeder Text ist erlaubt).
Damit in diesem offenen System aber die kein Chaos entsteht, da jede Organisation z.B. im «location»-Element ihre eigenen Länderkürzel verwendet, werden von der AIDA [AIDAAuth 02] sogenannte
«Authority»-Dateien zur Verfügung gestellt welche nichts anderes als Tabellen mit gültigen Werten für
bestimmte Elemente sind. Somit wird gewährleistet, dass die Daten konsistent und für die automatische Weiterverarbeitung verständlich bleiben.
Auch an Mehrsprachigkeit wurde gedacht und es ist bei den meisten beschreibenden Elementen möglich ein «lang»-Attribut hinzuzufügen. Im angegebenen Beispiel kommt das «sector»-Element zweifach vor: einmal in englisch (en) und einmal in französisch (fr).
Autor: Thomas Schädler
15
2 Datenaustausch mit XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<activities>
<activity dbKey="1-0-745001" date="1996-02-09">
<ID>
<assigningOrg refKey="OECD DAC"/>
<uniqID>1-0-745001</uniqID>
</ID>
<title lang="en">AGRICULTURAL WATER RESOURCES</title>
<location locationCode="CUB"/>
<startDate>0</startDate>
<status statusCode="6"/>
<sector lang="en">AGRICULTURAL WATER RESOURCES</sector>
<sector lang="fr">Ressources en eau à usage agricole</sector>
<notes>IRRIGATION PUMPS</notes>
<funding>
<fundingOrg>XAUT</fundingOrg>
<yearly>
<yearStarting date="1974-01-01"/>
<amount amount="3745338.4" currency="usd"/>
</yearly>
<termsAssist terms="2"/>
<total amount="3745338.4" currency="usd"/>
</funding>
<relatedLink>
<label>OECD DAC Creditor Reporting System</label>
<url>http://www.oecd.org/dac/htm/crs.htm</url>
</relatedLink>
<forMoreInfo>[email protected]</forMoreInfo>
</activity>
</activities>
Abbildung 10
: Core Activity Schema: Beispiel von activities.xml
Da solche Projektdaten auch zwischen verschiedenen Stakeholdern ausgetauscht werden können ist
es wichtig verfolgen zu können, welche Organisation welche Änderungen an den Daten vornimmt.
Das «Extended Schema» erlaubt es zusätzliche Informationen hinzuzufügen, welche die Herkunft der
enthaltenen Daten genau verfolgen lassen (welche Information wurde wo von wem hinzugefügt oder
geändert (engl.: audit trail)). Diese Informationen sind für Daten-Aggregatoren (engl.: data aggregators) allerdings auch zwingend anzugeben. Ausserdem erweitert das «Extended Schema» einige
Elemente dahingehend, dass diese auch ausserhalb einer «activity» Gültigkeit besitzen und als eigenständige Elemente bestehen können.
In Abbildung 11 ist schematisch die Standardprozedur aufgezeigt, die angewendet wird um die IDML
Daten auszutauschen. Es sind zwei HTTP (Hypertext Transfer Protocol) Anfragen an den Webserver
nötig. In der Standardprozedur wird angenommen, dass entweder die Datenbank als Resultat XML
Daten liefert oder aber der Webserver die Daten vor der Endauslieferung konvertiert.
Autor: Thomas Schädler
16
2 Datenaustausch mit XML
2.5
Client/Server- oder Dreischichtenarchitektur
Wie schon erwähnt, erfolgt der Dokumentenaustausch durch zwei HTTP Anfragen. Das Vermittlungswerkzeug sollte sich in eine solche Architektur gut einfügen lassen und nicht zuviel Mehraufwand verlangen. Dies wird wie in Abbildung 12 dargestellt mit einem einfachen Umleiten der zweiten HTTP
Anfrage erreicht. Diese wird jetzt nicht mehr an den Webserver geschickt, sondern direkt auf einen 2.
Rechner, der dann die Abfrage der Datenbank und die Konvertierung in XML übernimmt und somit
den Webserver entlastet.
(1)
(4)
Data
Data
START
(2)
Data
(3)
(5)
(6)
END
Webserver
Internet
(1) HTTP Anfrage (GET /IdmlInfo.xml)
(2) HTTP Resultat => IdmlInfo.xml
(3) HTTP Anfrage (GET /<link_to_idml> [und event. weitere Daten: Query])
(4) SQL Anfrage(n)
(5) DB Resultat
- wenn XML (XML-DB, XML-enabled-DB) => weiter
- wenn SQL Resultat, dann Konvertierung in XML (meist Skriptsprache)
(6) HTTP Antwort (IDML XML)
Abbildung 11
: IDML Datenaustausch (Standardprozedur)
Natürlich kann das Vermittlungswerkzeug auch auf dem selben Rechner laufen, und muss nicht physikalisch vom Webserver getrennt sein. Dies kann je nach Hard- und Softwareausstattung aber durchaus sinnvoll sein und muss für jeden Einsatzort einzeln abgeklärt werden.
Die Umleitung der zweiten HTTP Anfrage kann wie in Kapitel 2.4 erklärt einfach durch ersetzen des
url-Eintrages in der "IdmlInfo.xml" Datei erzwungen werden.
Diese Änderung der Architektur bringt aber keinen Mehraufwand (engl.: overhead) beim Transport und
der Abfrage der Daten.
Durch das Einfügen einer weiteren Abstraktionsebene (Vermittlungswerkzeug), ändert die traditionelle
Client/Server Architektur in eine Dreischichtenarchitektur (Vergleiche Abbildung 11 und Abbildung 12).
Anstelle einer Standardabfrage von der Applikation direkt auf die Datenbank wird die Abfrage von
einer Middleware (Vermittlungswerkzeug) verarbeitet, die die Logik beinhaltet um das Resultat der
Datenbankabfrage in eine für die Applikation verständliche Form zu bringen.
Autor: Thomas Schädler
17
2 Datenaustausch mit XML
(1)
Data
Data
START
(2)
Data
END
Webserver
(4)
(3)
(6)
(5)
Internet
Vermittlungswerkzeug
(1) HTTP Anfrage (GET /IdmlInfo.xml)
(2) HTTP Resultat => IdmlInfo.xml
(3) HTTP Anfrage (GET /<link_to_idml> [und event. weitere Daten: Query])
(4) SQL Anfrage(n)
- Generiert aus der Konfigurationsdatei
(5) DB Resultat (SQL Resultat)
- Konvertierung nach den definierten Regeln (Konfigurationsdatei)
(6) HTTP Antwort (IDML XML)
Abbildung 12
Autor: Thomas Schädler
: IDML Datenaustausch (mit Vermittlungswerkzeug)
18
3 Datenbanken
3
Datenbanken
3.1
Grundlegende Anforderungen
In unserem Falle sind die grundlegenden Anforderungen an die Datenbanken nicht sehr gross. Wichtig ist vor allem, dass das Vermittlungswerkzeug mit einer Vielzahl von Datenbanken zuverlässig arbeiten kann, da ja im Voraus nicht bekannt ist, wo welche Datenbank verwendet wird. Heute bieten
viele Programmiersprachen eine grosse Fülle an verschiedenen Schnittstellen. Allen gemeinsam ist
dabei, dass nur relationale Datenbanken unterstützt werden. Diese Einschränkung ist aber nicht weiter
wichtig, da eigentlich alle heute verwendeten Datenbank Management Systeme (DBMS) relational
DBMS sind. Die wichtigsten sind wohl ODBC und JDBC.
Die Architektur beider Schnittstellen wurden aus der SQL Call Level Interface (CLI) Spezifikation von
der Open Group abgeleitet [SCLS 01]. Diese Spezifikation regelt wie man standardisiert mittels SQL
auf eine Vielzahl von Datenbanken zugreifen kann und bildet somit eine Abstraktionsschicht zwischen
den Programmiersprachen und den Datenbanken. Diese werden im Folgenden Abschnitt genauer
erläutert. Weiterhin wird im zweiten und dritten Teil auf die Konvertierung der Daten von einer Datenbank in XML und umgekehrt eingegangen.
3.2
Schnittstellen
ODBC (Open Database Connectivity) wurde von Microsoft entwickelt und etablierte sich schnell als
De-facto-Standard, da von Anfang an eine Menge Datenbanksysteme unterstützt wurden. Die gute
Treiberversorgung und Marktabdeckung von ODBC ist der grösste Vorteil. Ein Nachteil ist, dass der
Treibermanager und die Treiber bei jedem Client installiert werden müssen.
JDBC (Java Database Connectivity) wurde etwas später - mit der Notwendigkeit einer Datenbankschnittstelle für Java – umgesetzt. Die Architektur wurde im Grossen und Ganzen von ODBC übernommen, allerdings wurde JDBC natürlich objektorientiert entwickelt. ODBC dagegen in C. Einer der
Unterschiede beider Schnittstellen ist z.B., dass JDBC als Resultat ein Resultat-Objekt liefert, wohingegen ODBC nur einen Pointer zurückgibt. Vor allem in Blickpunkt für eine Migration wurde für JDBC
auch eine JDBC-ODBC Bridge entwickelt die es ermöglicht vorhandene ODBC Treiber weiter zu verwenden. Wenn also eine Datenbank keine JDBC Schnittstelle hat, kann man mit der JDBC-ODBC
Bridge trotzdem mit dieser Datenbank arbeiten.
Wie schon erwähnt ist die Architektur bei beiden Schnittstellen (ungefähr) die gleiche. Ein Treibermanager kümmert sich um die Verbindungen und deren Verwaltung. Der Datenbanktreiber selbst kümmert sich dann um die (herstellerabhängige) Kommunikation mit der Datenbank und liefert auf Anfragen das Resultat.
Autor: Thomas Schädler
19
3 Datenbanken
3.3
Beziehung zwischen Datenbanken und XML
Das Vermittlungswerkzeug wird ja eine Verbindung zwischen einer Datenbank und einem XML Dokument herstellen. Wie in Abschnitt 1.1 auf Seite 1 erwähnt, gibt es folgende drei grundlegenden Szenarien:
1.
Es ist keine Datenbank vorhanden (Die XML Daten werden in einer neu angelegten Datenbank gespeichert.)
2.
Es ist kein XML Schema vorhanden (Die Daten aus der Datenbank werden in einem neu generierten XML Format ausgegeben.)
3.
Datenbank und Schema sind vorhanden, aber die Abbildung in beide Richtungen ist noch
nicht erledigt.)
Das erste Szenario ist interessant wenn man daran interessiert ist XML Daten von anderen Stakeholdern in einer eigenen Datenbank zu speichern. Dies ist im Falle von IDML nicht das Hauptinteresse,
da dort ja keine zentrale Datenbank verwendet wird und die Daten ja auch immer auf dem aktuellen
Stand gehalten werden müssen. Es ist aber nicht auszuschliessen, dass andere Anwendungen auf
dieses Problem stossen.
Auch das zweite Szenario ist nicht sehr häufig zu finden, da die Daten meist in einem fest definierten
Format (z.B. einem XML Schema) ausgegeben werden müssen und nicht einfach in einem automatisch generierten Format, dass sich an dem Datenbanklayout orientiert.
Richtig interessant wird erst das dritte Szenario, in welchem die Daten nach festen Regeln abgebildet
werden müssen, da ja die Datenbank und das Ausgabeformat (XML Schema) fixiert sind. Hierzu gibt
es aber keine automatischen Konvertierungen und somit muss hier von Hand eine Abbildung vorgenommen werden, die dann aber automatisch wiederholt werden kann.
Um ein XML Dokument, das einem XML Schema genügt, also ein gültiges (engl.: valid) XML Dok ument darstellt, in einer noch nicht vorhandenen Datenbank zu speichern, muss man erst einmal die
Strukturen des verwendeten XML Dokuments kennen.
XML Dokumente kann man in zwei Lager einteilen. Erstens sind dies Daten-zentrische (engl.: datacentric) Dokumente die vereinfacht einen Datencontainer darstellen. Zweitens sind dies Dokumentenzentrische Dokumente, welche hauptsächlich für den Menschen lesbar sein sollten. Es ist nicht immer
einfach zwischen diesen Kategorien zu unterscheiden, das es viele Dokumente gibt, die Merkmale
beider Kategorien vereinen. Als Faustregel wird aber vorgeschlagen, dass man Daten-zentrische Dokumente in einer normalen (relationalen) Datenbank abspeichert und Dokumenten-zentrische Dokumente in einer nativen XML Datenbank um die Vorteile von XML nicht zu verlieren. Ausserdem ist es
nicht ganz trivial Dokumenten-zentrische Daten in einer relationalen Datenbank zu speichern.
Autor: Thomas Schädler
20
3 Datenbanken
Im Folgenden werden nun diese drei Szenarien genauer untersucht, damit im darauf folgenden
Schritt das Modell festgelegt werden kann und der theoretische Hintergrund für die Implementation
schon gegeben ist. Welche dieser drei Szenarien schliesslich verwendet wird ist noch nicht genau
abgeklärt. Das primäre Ziel – Projektdaten über das World Wide Web in IDML zur Verfügung zu stellen – bedeutet allerdings, dass zumindest eine Abbildung von der Datenbank in XML (IDML Schema)
erfolgen muss. Da diese Szenarien sich teilweise in der Theorie überschneiden werden im nächsten
Abschnitt zuerst die verschiedenen Mapping-Methoden genauer untersucht. Weitere Bedürfnisse werden in einem späteren Teil abgeklärt.
3.4
Mapping
Es gibt zwei unterschiedliche Ansätze um ein Mapping vorzunehmen. Die erste ist das Vorlagengesteuerte (engl.: template-driven) Mapping und die zweite das Modell-gesteuerte (engl.: modeldriven) Mapping. Das Vorlagen-gesteuerte Mapping wird vorzugsweise für die Abbildung von der Datenbank in ein XML Dokument verwendet, kann aber auch für den umgekehrten Weg benutzt werden.
Beim Modell-gesteuerten Mapping gibt es zwei Ansätze: Tabellen-basiertes (engl.: table-based) und
Objekt-relationales (engl. object-relational) Mapping. Das Tabellen-basierte Mapping ist der einfachste
Fall, kann aber nur angewendet werden, wenn die Daten in einem festegelegten Format vorliegen. So
wird es vorzugsweise für die Serialisierung von Daten aus einer Datenbank verwendet. Das Objektrelationale Mapping ist immer anwendbar, aber auch komplizierter zu verwenden. Dabei werden die
Daten in einem XML Dokument als Baumstruktur aus Objekten beschrieben. Diese Struktur ist aber
nicht zu verwechseln mit einem DOM-Baum. Die Baumstruktur kann für jedes Dokument unterschiedlich sein. Die einzelnen Objekte werden als Klassen modelliert uns somit entsteht ein objektorientiertes Modell. Dieses Modell wird anschliessend auf die Datenbank abgebildet. [Bourret 02]
3.4.1 Tabellen-basiertes Mapping
Tabellen-basiertes Mapping kann nur auf wenige XML Schemas angewendet werden, da eine bestimmte Struktur vorausgesetzt wird. Häufig wird Tabellen-basiertes Mapping verwendet um das Resultat einer Abfrage an eine relationale Datenbank in XML umzuwandeln oder um Daten zwischen
zwei relationalen Datenbanken auszutauschen. Der Aufbau beim Tabellen-basierten Mapping ist sehr
einfach. Das XML Dokument bildet einfach die Tabellenstruktur der Datenbank ab (siehe Abbildung
13).
Diese Operation kann ohne Mehraufwand in beide Richtungen durchgeführt werden. Da in den meisten Fällen das XML Dokument aber keine solche Struktur aufweist, wird von einer genaueren Untersuchung abgesehen. Sollte diese Funktionalität dennoch in diesem Projekt verwendet werden ist es
dank des einfachen Aufbaus kein Problem einen solchen Datenimport bzw. –export dennoch zu implementieren, da nur eine Seite angepasst werden muss (die andere ist fixiert).
Autor: Thomas Schädler
21
3 Datenbanken
<?xml version="1.0"?>
database
<database>
<tables>
<table_1>
<row>
table
<column_1>...</column_1>
row
</row>
</table_1>
<table_2>
column
...
</table_2>
</tables>
</database>
Abbildung 13
: Beispiel für Tabellen-basiertes Mapping [Bourret 02]
3.4.2 Vorlagen-gesteuertes Mapping
Vorlagen-gesteuertes Mapping wird vorwiegend benutzt um Daten aus Datenbanken in ein XML Format zu konvertieren. Dabei werden SQL Statements in eine XML Vorlage eingebettet, die dann von
der verarbeitenden Middleware ausgeführt und in den angegeben Stellen in der XML Datei eingefügt
(substituiert) werden. Diese Variante eignet sich auch sehr gut für den IDML-Export, da kein komplexes objekt-rationales Mapping ausgeführt werden muss und alle anderen Voraussetzungen zur Genüge erfüllt werden. Es ist in der Verarbeitung ähnlich dem Tabellen-basierten Mapping mit dem grossen
Unterschied, dass der Output sehr flexibel angepasst werden kann. Abbildung 14 zeigt ein Beispiel für
Vorlagen-gesteuertes Mapping. Dieses Beispiel zeigt nur die Idee die dahintersteckt und eine
Implementation kann davon abweichen.
<?xml version="1.0"?>
<garage>
<select>SELECT marke, jahr, zylinder, typ, farbe FROM bikes</select>
<motorrad>
substituiert
<marke>$marke</marke>
<typ herstellungsjahr="$jahr" zylinder="$zylinder">$typ</typ>
<farbe>$farbe</farbe>
</motorrad>
</garage>
Abbildung 14
: Beispiel für Vorlagen-gesteuertes Mapping
3.4.3 Objekt-relationales Mapping
Objekt-relationales Mapping wird in zwei Schritten ausgeführt. XML Schemas werden über ein ObjektSchema in ein relationales Schema abgebildet. Die umgekehrte Richtung ist auch möglich, wird aber
nicht weiter berücksichtigt, da in den meisten Fällen ein XML Schema schon vorhanden ist. Damit ist
das zweite Szenario (siehe oben) aber nicht ausgeschlossen, da in einem solchen Fall für die Serialisierung der Daten ein einfacher Export mit Tabellen-basiertem Mapping gewählt werden kann.
Autor: Thomas Schädler
22
3 Datenbanken
Ein XML Dokument wird erst in ein Objekt-Schema abgebildet, welches wiederum in DatenbankTabellen gemappt werden kann. Abbildung 15 zeigt das Objekt-Schema für das Beispiel-Dokument
aus Abbildung 2.
objekt garage {
objekt motorrad {
motorrad = Æmotorrad
}
Legende:
marke = "Yamaha",
typ = "XT 550",
typ = Ætyp,
herst.jahr = "1984",
farbe = "schwarz",
zylinder = "1"
option = ""
Æ = Zeiger auf Objekt
objekt typ {
}
}
Abbildung 15
: XML Dokument aus Abbildung 2 als Objekt-Schema
Da dieses Objekt-Schema nun alle benötigten Informationen enthält, kann es auf Datenbank-Tabellen
abgebildet werden. Aus jedem Objekt wird eine Tabelle und die Eigenschaften ergeben die benötigten
Spalten. Im Beispiel aus Abbildung 15 werden also drei Tabellen benötigt.
Dieses Mapping kann jetzt auch auf XML Schemas (nicht auf einzelne XML Dokumente) oder DTD's
angewendet werden. Dabei werden die verschiedenen XML Schema-Komponenten (Sequenz, Auswahl, etc.) nach bestimmten Regeln in Klassen abgebildet (Details folgen weiter unten).
Den ersten Schritt – vom XML Schema zum Objekt-Schema – nennt man auch XML Daten-Bindung
(engl.: XML data binding). Wie schon erwähnt, haben Objekt-Schemas zwar auch eine Baumstruktur,
sind aber grundlegend anders ausgelegt als DOM-Bäume. DOM-Bäume modellieren das Dokument
und ein Objekt-Schema (oder Objekt-Baum) modelliert die Daten in dem Dokument. Abbildung 16
erklärt anhand eines Beispiels den Unterschied zwischen einem Objekt-Baum und einem DOM-Baum.
Für ein bestimmtes XML Schema haben alle davon abgeleiteten XML Dokumente den gleichen DOMBaum. Objekt-Schemas dagegen sind bei jedem XML Dokument unterschiedlich.
Das Objekt-Schema lässt sich leicht nachvollziehen, wenn man das XML Dokument durchliest und
seine Struktur betrachtet. Als Resultat erhält man einen einfachen Baum, der die Struktur der Auszeichnungselemente (engl.: tags) aufzeigt. Der DOM-Baum hingegen modelliert einen anderen Baum,
der jedoch für alle Instanzen eines XML Schemas gleich ist. Dieser Baum stellt die Struktur des XML
Dokumentes anhand der XML Elemente dar. Die Knoten des Baumes sind Elemente oder Attribute,
welche wiederum Text beinhalten (die Daten). Die Wurzel eines DOM-Baumes ist immer das Dokument. Objekt-Schemas werden aber normalerweise nicht als Baum gezeichnet, sondern in einer abstrahierten – an Klassen (für Java-Programmierer) oder Strukturen (für C-Programmierer) erinnernde –
Schreibweise (siehe Abbildung 15).
Eine zweite Darstellungsmöglichkeit für Objekt-Schemas ist eine Klassenhierarchie, welche dann auf
eine relationale Datenbank abgebildet werden kann. Die Klassen haben verschiedene Eigenschaften,
aber keine Methoden. Die Eigenschaften selbst können weiter eingeschränkt werden. Beispielsweise
Autor: Thomas Schädler
23
3 Datenbanken
kann eine Eigenschaft mehrfach vorkommen oder auch das NULL-Element beinhalten (im Beispiel die
Auszeichnungselemente «motorrad», «option» und «herstellungsjahr»).
Legende:
[]
Dokument
= Array (1 und mehr)
∅ = Nullable (Null oder 1)
klasse: garage
§ motorrad [] ∅
Element
Element
garage
klasse: motorrad
Element
Text
Element
Text
§ marke
motorrad
§ typ
§ farbe
marke
typ
farbe
option
Objekt-Baum
Abbildung 16
§ option [] ∅
Element
Text
Element
Text
klasse: typ
Attribut
Text
§ typ
Attribut
Text
§ herstellungsjahr ∅
DOM-Baum
§ zylinder
Klassenhierarchie
: XML Dokument aus Abbildung 2 als Objekt-Baum, DOM-Baum und Klassenhierarchie
Autor: Thomas Schädler
24
4 Erstellung eines Modells
4
Erstellung eines Modells
In diesem Kapitel werden alle vorangegangen Konzepte vereint um schliesslich das zu implementierende Modell zu erhalten. Dabei wird abgewägt, welchen Anforderungen das Modell standhalten soll,
wie es konkret aussieht, welche Benutzerschnittstelle gewählt wird und mit welcher Software das Modell anschliessend implementiert werden soll.
4.1
Anforderungen an das Modell
Was in den vorangegangenen Kapiteln schon ausformuliert wurde soll hier noch zusammengefasst
werden um den Gesamtkatalog an Anforderungen zu erstellen. Gefordert wird ein Werkzeug welches
sich in viele Architekturen einfach einbetten lässt und welches mit möglichst vielen verschiedenen
Datenbanken zusammenarbeiten kann. Dies setzt eine offenen Architektur voraus. Da das Werkzeug
frei zur Verfügung stehen soll muss ausserdem eine Architektur und Sprache gewählt werden, die
ohne Lizenzgebühren und sonstigen Abgaben eingesetzt werden kann.
Das Werkzeug muss sich an die verwendeten Spezifikationen sehr genau halten (XML, XML Schema). Es sollte bei der Anwendung möglichst einfach zu bedienen sein und praktisch wartungsfrei seinen Dienst erfüllen. Als Minimalanforderung wird vorausgesetzt, dass das Werkzeug XML Daten aus
der eigenen Datenbank auslesen und in das IDML Format konvertieren kann.
Das Werkzeug muss drei verschiedene Aufgaben erledigen:
1.
Eine grafische Oberfläche für das Mapping bereitstellen.
2.
Mit vielen verschiedenen relationalen Datenbanken kommunizieren.
3.
Einen Service bereitstellen, um die generierten Daten abzurufen.
Durch die sehr unterschiedliche Aufgabenstellung (Desktop-Applikation und Serverkomponente) stellt
sich auch die Frage ob nicht zwei einfachere Werkzeuge diese Arbeit besser erledigen könnten. Eine
Aufteilung vermindert die Komplexität beider Anwendungen.
4.2
Konstruktion des Modells
Das Werkzeug muss die oben genannten Anforderungen erfüllen. Abbildung 12 zeigt noch mal genau
die Situation in der Übersicht. Durch eine Aufteilung in zwei oder drei Komponenten wird die Applikation besser wartbar und die Serverkomponente wird nicht unnötig aufgebläht. Allerdings findet noch
eine Kommunikation zwischen dem Server und dem Konfigurationswerkzeug statt. Dies ist aber mit
einer Konfigurationsdatei schnell erledigt. Eine mögliche dritte Komponente – ein Überwachungswerkzeug – muss auch mit der Serverkomponente kommunizieren können. Hier reichen jedoch drei oder
vier Befehle (Start, Stopp, Reload und Status).
Dabei kann man noch einmal von XML profitieren. Da die Serverkomponente sowieso mit XML umgehen kann (Datentransformation als Hauptaufgabe), kann die Konfigurationsdatei alle benötigten Daten
Autor: Thomas Schädler
25
4 Erstellung eines Modells
in einer einfachen XML Struktur beinhalten. Diese wird dann eingelesen und der Server kann seinen
Betrieb aufnehmen. Dadurch ist auch gewährleistet, das die Serverkomponente einmal in Betrieb für
Änderungen nicht mehr gestoppt werden muss. Diese Architektur ist auch von Webservern bekannt
(z.B. Apache), welcher im laufenden Betrieb einfach die Konfigurationsdatei einliest.
Dadurch dass die Mappingaufgabe für die Serverkomponente entfällt kann auch auf eine grafische
Benutzeroberfläche verzichtet werden und der Server als unabhängige Kommandozeilenapplikation
entwickelt werden. Das spart Platz und Komplexität. Damit dadurch die Kontrolle des Servers nicht zu
kompliziert wird kann in das Konfigurationswerkzeug eine Steuerungseinheit für den Server eingebaut,
ein kleines unabhängiges Steuerungs- und Überwachungsfrontend entwickelt werden oder der Server
stellt ein Web-Frontend für seine Steuerung bereit Alternativ wird der Server natürlich über die Kommandozeile gesteuert. Für die dritte Variante spricht eine nochmalige Verringerung der Komplexität,
da der Server unabhängig vom Standort gewartet werden kann und die ganze Logik der Administration im Server enthalten bleibt. Bei einer Remote-Administration darf der Sicherheitsaspekt aber nicht
vergessen werden, da eine solche Funktionalität eine grosse Angriffsfläche für allfällige Attacken darstellt.
Konfigurationsdatei
(XML)
Kommandozeile
Clients
HTTP
Administration
liest
Anfrage (HTTP)
schreibt
und
liest
Internet
Server
Antwort (HTTP)
Format: XML
JDBC/ODBC
Data
JDBC/ODBC
Data
Konfigurator
Data
Vermittlungswerkzeug
Abbildung 17
: Architektur des Vermittlungswerkzeugs in der Übersicht
Das Konfigurationswerkzeug für das Mapping – im folgenden einfach Konfigurator genannt – muss
eine grosse Konnektivität in Bezug auf Datenbanken besitzen und mit XML umgehen können. Das
heisst, der Konfigurator muss XML Schemas parsen und mit Datenbanken kommunizieren können.
Dazu muss eine Oberfläche entwickelt werden, die es erlaubt, ein Mapping zwischen der Datenbank
und dem XML Schema vorzunehmen. Die Struktur eines erstellten Mappings muss dann in einer XML
Konfigurationsdatei gesichert werden können.
Autor: Thomas Schädler
26
4 Erstellung eines Modells
Die Funktionalität um den Server zu steuern begrenzt sich auf zwei Funktionen. Ein Kommando muss
den Server dazu bringen die Konfigurationsdatei neu einzulesen und als zweite Funktion muss der
Server gestartet und gestoppt werden können. Ausserdem ist es noch von Vorteil wenn man den Status des Servers abfragen kann. Bei der Architektur des Servers kann man sich zwei verschiedene
Architekturen vorstellen. Entweder ist der Server fähig mehrere Konfigurationen gleichzeitig zu verwalten oder es wird für jede Aufgabe ein eigener Server gestartet. In der Funktionalität ist dabei kein Unterschied feststellbar, nur die Kontrolle der einzelnen Server wird dem Benutzer überlassen, wohingegen bei der ersten Variante der Server seine verschiedenen Aufgaben selbst verwaltet.
Abbildung 17 zeigt die Architektur des Vermittlungswerkzeuges in der Übersicht. Zusammenfassend
noch einmal die Funktionen der einzelnen Komponenten.
Konfigurator:
•
Datenbanken einlesen und den Zugriff darauf verwalten
•
XML Schema einlesen und grafisch darstellen
•
Kontrollansicht für generiertes XML oder die Datenbankeinträge
•
Mappingkomponenten (z.B. per Drag und Drop)
•
Speichermöglichkeit in einer Konfigurationsdatei zur Verfügung stellen
Serverkomponente:
4.3
•
Annahme von Abfragen (ähnlich einem Webserver)
•
Einlesen einer Konfigurationsdatei
•
automatisches Mapping nach den Regeln in der Konfigurationsdatei
•
Server neu starten, stoppen und die Konfigurationsdatei neu einlesen
•
Steuerung über ein Web-Frontend, eine dritte Komponente oder über die Kommandozeile
Festlegung des Modells
In diesem Abschnitt soll nun festgelegt werden wie die beiden Komponenten genau implementiert
werden. Dabei wird aus den vorangegangenen möglichen Varianten eine ausgewählt und mit allen
Details beschrieben, damit sich die Implementation auf dieses Modell stützen kann. Das Modell wird in
zwei Komponenten gegliedert die jetzt genauer untersucht werden.
4.3.1 Der Konfigurator
Der Konfigurator stellt die Benutzerschnittstelle für die Hauptaufgabe der Benutzer (Mappings vorzunehmen) dar und muss sich deshalb um die Erstellung und Speicherung der Projektdaten kümmern.
Die Projektdaten werden in einer XML Datei gesichert welche alle zum Projekt gehörenden Informationen speichert. Dies ist der Name des Projekts und das von diesem Projekt benutzte Mappingmodul.
Zusätzlich werden hier die Daten der verschiedenen Datenbankverbindungen und alle benötigten XML
Dateien (Schemas) gespeichert. Die einzelnen Module müssen natürlich ihre Daten (vom Benutzer
generierte Mappingaufgaben) auch speichern können. Diese Daten werden in der Konfigurationsdatei
Autor: Thomas Schädler
27
4 Erstellung eines Modells
als vierter Punkt – abhängig vom verwendeten Mappingmodul - gespeichert. In einem XML Schema
ist dies das Element «Mapping» welches eine Auswahl der möglichen Module zulässt. Abbildung 18
zeigt das XML Schema einer Projektkonfiguration in der Baumansicht ohne aufgeklapptes «Mapping»Element und Abbildung 19 zeigt ein Beispieldokument mit den enthaltenen Informationen.
Abbildung 18
: xmlizer.project.config.xsd (Baum, kein Mapping) [XMLSPY 01]
Solche Informationen wie in Abbildung 19 werden vom Konfigurator erzeugt, gelesen und natürlich
stellt er eine Möglichkeit zur Verfügung diese neu erzeugten Daten in einer Datei zu speichern. Mit
Hilfe dieser Daten kann dann das gewählte Modul auf die Datenbanken zugreifen und die XML Dateien öffnen und bearbeiten. Um ein neues Projekt zu erzeugen stellt der Konfigurator einen Dialog bereit, der diese Daten abfragt. Dabei ist zu beachten, dass jedes Projekt mindestens eine Datenbankverbindung benötigt. Um den Modulen die Arbeit zu vereinfachen, testet der Konfigurator jede
Datenbankverbindung auf Konnektivität und jede XML Datei auf ihre Richtigkeit (mindestens «wellformed»).
Autor: Thomas Schädler
28
4 Erstellung eines Modells
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xmlizerprojectconfig SYSTEM "xmlizer.project.config.dtd">
<xmlizerprojectconfig>
<initialsetup>
Ist mit einer DTD verknüpft,
wird beim einlesen validiert.
<inititem key="name">testproject</inititem>
<inititem key="module">Simple DB Export</inititem>
</initialsetup>
<databasesetup>
<dbitem>
<name>someconnectionname</name>
<driver>org.gjt.mm.mysql.Driver</driver>
<url>jdbc:mysql://localhost:3306/xml</url>
<timeout>20</timeout>
Beispiel: DB Konfiguration,
<username>root</username>
kann mehrmals vorkommen.
<password>20:30:71:88:</password>
</dbitem>
</databasesetup>
<schemasetup>
<xmlitem>
<name>somefilename</name>
Beispiel: XML Datei
<file>somefile.xml</file>
</xmlitem>
</schemasetup>
</xmlizerprojectconfig>
Abbildung 19
: Beispiel einer Konfigurationsdatei ohne Mappinginformationen
Ist alles korrekt startet der Konfigurator das Modul welches dann die eigentliche Mappingaufgabe erledigt und mit Hilfe der Konfigurationsinformationen sofort mit den Datenbanken und den XML Dateien
arbeiten kann.
4.3.2 Die Serverkomponente
Die Serverkomponente ist im Grunde genommen ein auf die speziellen Bedürfnisse angepasster
Webserver. Sie erledigt die in den Konfigurationsdateien gespeicherten Mappingaufgaben und liefert
die Ergebnisse nach einer Anfrage aus. Um den Server zu steuern wird die Kommandozeile benutzt,
da diese alle Anforderungen erfüllt und die einfachste Architektur darstellt (es wird keinen dritte Komponente benötigt). Um an die Daten heranzukommen ist die genaue Kenntnis der URL erforderlich.
Um dies zu vereinfachen wird ein Web-Frontend implementiert, welches die angebotenen Projekte
auflistet und einfach mit Hilfe eines Webbrowsers navigiert werden kann. Die Serverkomponente wird
so implementiert, dass sie verschiedene Mappingaufgaben parallel verwalten und verarbeiten kann.
Es können alternativ auch verschiedene Server auf verschiedenen Ports arbeiten, wobei jedem Server
ein anderes (oder auch das gleiche) Projektverzeichnis zugeteilt werden kann.
4.3.3 Die Mappingmodule
Als erstes Modul wird das in Abschnitt 3.4.1 erläuterte Tabellen-basierte Mapping implementiert. Es ist
die einfachste Variante und benutzt nur Datenbankverbindungen, aber keine Manipulation von XML
Dateien. Dieses Modul wird im folgenden als «Simple DB Export» Modul bezeichnet, was auch gleich
Autor: Thomas Schädler
29
4 Erstellung eines Modells
den Zweck dieses Moduls verdeutlicht. Der Benutzer hat keinen grossen Einfluss auf das Format der
Ausgabe und kann eventuell nur einige Variablen beeinflussen oder aus verschiedenen vorher festgelegten Outputformaten aussuchen. Da dieses Modul eher als Implementationstest gedacht ist und
nicht für den produktiven Einsatz prädestiniert ist, wird es nur in eine Richtung implementiert: eine
Datenbank als Input und XML aus Outputformat.
Das zweite Modul wird mit dem in Abschnitt 3.4.2 erklärten Vorlagen-gesteuerten Mapping implementiert und ermöglicht es dem Benutzer Daten aus verschiedenen Datenbanken in ein selbst definiertes
XML Format zu bringen. Es ersetzt somit auch gleich das erste Modul, da mit diesem Funktionsumfang auch einfach das Exportformat des ersten Moduls «nachgebaut» werden kann. Aber auch dieses
Modul beschränkt sich auf den Export aus einer Datenbank und greift nur lesend auf diese zu. Eine
gelungene Implementation dieses Moduls genügt dann auch den in Abschnitt 1.2 und 4.1 definierten
Minimalanforderungen für dieses Projekt. Dieses Modul trägt den Namen «Database to XML».
Ein drittes Modul implementiert dann eventuell das in Abschnitt 3.4.3 erläuterte Objekt-relationale
Mapping, welches dann einer Generalisierung aller möglichen Mappings gleichkommt und es ermöglichen würde Daten in beide Richtungen transparent auszutauschen. Für eine allfällige Implementation
dieses Moduls befindet sich der Autor noch immer auf der Suche nach einer (freien) Bibliothek, da der
Programmieraufwand ansonsten sehr hoch ist, da es sich um ein sehr komplexes Themengebiet handelt.
Autor: Thomas Schädler
30
5 Auswahl der Software / Programmiersprache
5
Auswahl der Software / Programmiersprache
5.1
Anforderungen
Die gestellten Anforderungen an eine Programmiersprache sind vor allem eine hohe Datenbankkonnektivität, damit das Endprodukt mit einer möglichst grossen Vielfalt von Datenbanken genutzt werden
kann (höchste Priorität). Ausserdem sollten es geeignete Bibliotheken für den Umgang mit XML vo rhanden sein. Als dritter Punkt ist sehr wichtig, dass das Endprodukt ohne Lizenzabgaben verbreitet
werden kann und es sollte auf möglichst vielen Plattformen ohne Anpassungen ausführbar sein. Allein
diese wenigen Punkte schränken die Wahl der Programmiersprache schon beträchtlich ein.
5.2
Auswahl der Programmiersprache
Möglich wäre eine Implementation mit den verschiedensten heute erhältlichen Programmiersprachen.
Der Autor entscheidet sich jedoch für Java, da Java alle Anforderungen mit Bravour erfüllt und er
schon einige Erfahrung mit dieser Programmiersprache vorweisen kann. Die Datenbankkonnektivität
ist mit JDBC (Java Database Connectivity) praktisch unbegrenzt (jeder grosse Datenbankhersteller
stellt einen Treiber bereit und viele Treiber sind selbst Open Source) und die Datenbanktreiber können
während der Laufzeit spezifiziert werden (müssen also nicht fest einprogrammiert werden), was die
Flexibilität stark erhöht. Auch gibt es eine grosse XML Unterstützung die jedoch noch immer nicht
vollständig ist, aber ständig erweitert wird. Java ist auch absolut lizenzfrei und fast als einzige Sprache
völlig plattformunabhängig [Java 02].
5.3
Auswahl der Werkzeuge
Ein weiterer Vorteil von Java ist die grosse Verfügbarkeit an freien Entwicklungsoberflächen. Der Autor hat sich nach genauerer Untersuchung für «Forte for Java» von Sun entschieden, das in einer
«Community Edition» frei erhältlich ist und hervorragend auf Java zugeschnitten wurde [Forte 02]. Als
weiterer Kandidat war noch die freie Version von Borland's «JBuilder», welche sich jedoch durch zu
grosse Eingeschränktheit der freien Version im Hinblick auf Datenbanken selbst disqualifiziert hat
[Borland 02].
Die XML Unterstützung beider IDE's (engl.: Integrated Development Environment) ist jedoch noch
sehr rudimentär und erfordert noch immer einen Menge Handarbeit. Um die DTD's und die XML
Schemas zu entwickeln verwendet der Autor XMLSpy von Altova Inc., welches jedoch nur als 30Tage-Testversion zur Verfügung steht, was aber völlig ausreicht [XMLSPY 01]. Ansonsten greift der
Autor auf konventionelle Texteditoren zurück.
Für die Architektur der Programme selbst benutzt der Autor JVision von Object-Insight. Dieses Werkzeug erlaubt es UML Diagramme (Unified Modelling Language) zu zeichnen und daraus ein JavaCodegerüst zu erzeugen. Aber auch der umgekehrte Weg ist möglich: Aus vorhandenen Java-Klassen
kann UML erzeugt werden [JVision 02]. JVision ist nicht frei verfügbar, es ist jedoch möglich eine freie
Autor: Thomas Schädler
31
5 Auswahl der Software / Programmiersprache
akademische Lizenz zu bekommen. Auch hier hat der Autor noch ein Konkurrenzprodukt ausprobiert,
das sich ausgezeichnet in «Forte for Java» integrierte, jedoch dauern Abstürze produzierte und die
gespeicherten Daten korrumpierte (Poseidon Community Edition von Gentleware).
5.4
Auswahl der Bibliotheken
Um auf Basis von Java zu programmieren werden – abgesehen von der standardisierten JavaBibliothek – noch weitere Bibliotheken (engl.: libraries, packages, oder API's) benutzt. Vor allem im
Bezug auf XML kommt man nicht darum herum externe Bibliotheken zu verwenden, da erst in der
neuesten Java-Version eine XML Bibliothek enthalten ist (ab Version 1.4). Die vom Autor verwendete
Version ist Java 1.3.1, da die benutzte IDE diese Version verlangt. Um diese Bibliotheken zu benutzen
reicht es sie in den Ordner «lib/ext» im Installationsverzeichnis der verwendeten Java Runtime (JRE)
zu kopieren oder sie alternativ im «classpath» anzugeben.
Die erste und wichtigste Bibliothek ist die «Xerces-J» vom Apache Projekt [XERCES 02]. Diese Bibliothek beinhaltet alles nötige um mit XML zu arbeiten. Das heisst Xerces implementiert die XML 1.0
Spezifikation (recommendation) vom W3C mit erweiterten Parserfunktionen. Ausserdem implementiert
diese Bibliothek noch die XML Schema recommendation 1.0, DOM Level 2 Version 1.0, SAX Version
2 und natürlich auch DOM Level 1 und SAX Version 1. Diese Bibliothek stellt also verschiedenen Parser bereit (DOM und SAX), hat aber nur wenige komfortable Methoden um XML Daten zu manipulieren. Der Zugriff auf den DOM-Baum ist z.B. recht kompliziert und benutzt eigene und nicht die von
Java propagierten Design-Patterns. Dies ist auch der grösste Schwachpunkt von «Xerces-J». (Dateien: xercesImpl.jar, xmlParserAPIs.jar).
Um diese Schwäche auszumerzen wird eine weitere Bibliothek verwendet. «JDOM» vom JDOM Projekt [JDOM 02]. Diese Bibliothek unterstützt in etwa eine vergleichbare Funktionalität wie «Xerces-J»
ist aber nicht als Aufsatz auf diese Parser-Bibliothek zu verstehen sondern sie stellt ein Java-basiertes
«Document Object Model» für XML Daten bereit. JDOM benutzt aber einen XML-Parser um dieses
Dokumenten-Modell zu erstellen (in unserem Fall «Xerces-J»). Für den weiteren Zugriff auf die Baumstruktur verwendet JDOM die von Java bekannten Design-Patterns (Iterations, Enumerations, etc.)
und erleichtert dem Programmierer dadurch die Arbeit enorm. Es müssen keine Java-Interfaces implementiert werden sondern alle Klassen können einfach instantiiert werden. (Dateien: jdom.jar)
Für die Funktionalität aus DTD's XML Schemas zu generieren wird auf die frei verfügbare Java-Klasse
«dtd2xs» von Simon Hölzer und Ralf Schweiger zurückgegriffen [DTD2XS 02]. Diese Java-Klasse
kommt mit zwei angepassten kleinen Bibliotheken und lässt sich leicht in vorhandene Projekte einbinden. Natürlich ist der Quellcode auch frei verfügbar. (Dateien: xml.jar, xt.jar)
Autor: Thomas Schädler
32
6 Implementation des Modells
6
Implementation des Modells
Als erstes wird der in Abschnitt 4.3.1 beschriebene Konfigurator implementiert, der als Grundlage für
die einzelnen Mappingmodule fungiert. Da der Konfigurator und der Server auf die gleichen Daten
zugreifen wird als erster Punkt jedoch die verwendete Speicherungshierarchie erläutert. Darauf aufbauend werden die Module aufsteigend nach Komplexität implementiert und erst anschliessend wird
die in Abschnitt 4.3.2 definierte Serverkomponente implementiert um das Projekt zu vervollständigen
und die Daten schlussendlich automatisch auf Anfrage generieren zu können.
6.1
Speicherungshierarchie der Projektdaten
Die von beiden Applikationen benutzten Projektdaten werden in einem Projektverzeichnis gespeichert.
Dieses Verzeichnis wiederum enthält verschiedene Unterverzeichnisse, welche je ein Projekt beinhalten. Der Name eines Projekts ist zugleich der Name des Unterverzeichnisses. In diesem Unterverzeichnis werden alle von diesem Projekt abhängigen Daten abgelegt. Dies ist je eine Datei mit Namen
«xmlizer.xml» welche alle für das Projekt benötigten Grunddaten und die Mappingdaten enthält. Genauere Hinweise zu diesen Daten folgen in Abschnitt 6.2. Auch die von einem Projekt verwendeten
XML Schemas werden hier als Kopie gespeichert, wobei in den Projektdaten selbst nur relative Pfade
verwendet werden. Dies hat den Vorteil, dass ein Projektverzeichnis - ohne die Abhängigkeiten zu
zerstören - verschoben werden kann.
Da die verwendeten XML Schemas nur Kopien darstellen muss sich ein Anwender keine Gedanken
um die Sicherheit seiner Daten machen, da auf die Originaldateien und die verwendeten Datenbanken
nur lesend zugegriffen wird. Ein weiterer Vorteil einer solchen Speicherungshierarchie ist, dass beim
starten einer Applikationen dieser ein Projektverzeichnis zugewiesen werden kann, mit welchem dann
gearbeitet wird. Dies bedeutet, dass z.B. verschiedene Anwender ihre eigenen Projektdaten getrennt
ablegen können.
6.2
Implementation des Konfigur ators
Eine Übersicht über die Klassen welche für die Benutzerschnittstelle (engl.: User Interface) bedeutend
sind verschafft Abbildung 20. Das Hauptfenster des Konfigurators - die Klasse «configurator» - stellt
einen Container für die Module dar und kümmert sich gleichzeitig um die Ausgaben, den Aufbau und
die Speicherung der Projektdaten. Um die Module darzustellen wurde eine «JDesktopPane» gewählt,
wobei alle weiteren Fenster als innere Fenster («JInternalFrame») dargestellt werden. Dies erhöht die
Übersichtlichkeit und stellt eine gewohnte Arbeitsoberfläche zur Verfügung. Alle inneren Fenster müssen die Klasse «MyInternalFrame» implementieren welche wiederum eine Unterklasse von «JInternalFrame» ist und um eine «update» Funktion erweitert wurde. Dies wird benötigt um den Inhalt eines
Fensters aktualisieren zu können, falls in einem anderen Fenster die zugrundeliegenden Daten geändert wurden (Feedback).
Autor: Thomas Schädler
33
6 Implementation des Modells
Um die internen Fenster zu verwalten wurde ein einfacher Fenstermanager entwickelt, welcher sich
um die Verwaltung der geöffneten Fenster kümmert. Gleichzeitig erstellt er auch die Einträge im Fenster-Menü (für den schnellen Wechsel zwischen verschiedenen Fenstern) und aktiviert oder deaktiviert
verschiedene Menü- und Toolbareinträge abhängig vom Programmzustand praktisch automatisch.
Abbildung 20
: UML Klassen-Diagramm des Konfigurators (User Interface) [JVision 02]
Das Konzept für die Ausgaben wurde zentralisiert und wird in der Klasse «logWindow» verwaltet. Diese Klasse stellt Methoden zur Verfügung um je nach Wichtigkeit Informationen, Warnungen und Fehler darzustellen. Gleichzeitig stellt diese Klasse auch ein Interface zur Verfügung um jegliche Textdateien darzustellen. Als weitere Funktion kann hier falls erwünscht auch noch der Debugoutput
angezeigt werden. Dieses zentralisierte Konzept ve reinfacht den Umgang mit verschiedenen Textdaten und ermöglicht es den ganzen Arbeitsprozess in einer Datei zu loggen.
Um die Hilfe zu Implementieren wird auf normale HTML-Seiten zurückgegriffen, welche in einem internen HTML-Browser dargestellt werden («HTMLBrowser»). An verschiedensten Stellen im Programm kann somit ein Hilfe-Knopf implementiert werden und es muss dabei nur eine neue Seite aufgerufen werden, die dann sofort dargestellt wird. Da Java alle benötigten Klassen für die schnelle
Implementation eines einfachen Webbrowsers mitliefert stellt dies keinen grossen zusätzlichen Aufwand dar. Die Hilfe («helpWindow») und der JavaDoc-Browser («javadocWindow») benutzen beide
die Klasse «HTMLBrowser».
Autor: Thomas Schädler
34
6 Implementation des Modells
Die Klasse «setupWindow» kümmert sich um die Erstellung und anschliessend auch um die Änderung
an den grundlegenden Projektdaten. Sie stellt eine Wizard-ähnliche Oberfläche bereit um Datenbankverbindungen einzugeben und zu testen sowie einen Validator für XML Schemas (well-formedness
wird überprüft und abhängige Dateien semi-automatisch eingebunden). Hier werden auch die
«dtd2xs»-Klassen verwendet um als Inputformat auch Document Type Definitions verwenden zu können (automatische Konvertierung in ein XML Schema).
Abbildung 21
: UML Klassen-Diagramm des Konfigurators (Daten) [JVision 02]
Eine Datenbankverbindung wird auf zwei Arten getestet. Zuerst wird versucht den angegeben JDBCTreiber zu laden. Ist das erfolgreich wird eine Verbindung hergestellt und der Anwender hat die Möglichkeit mit einem einfachen Datenbankbrowser diese Datenbank zu inspizieren.
Die Datenstruktur der Projektdaten spiegelt die vier unterschiedlichen Informationen wieder die darin
gespeichert werden. Abbildung 21 zeigt die damit verbundenen Klassen in der Übersicht. Sie bestehen aus einer Liste von «dbItem» (für die Datenbankverbindungen), «xmlItem» für die XML Dateien,
«dataItem» für die restlichen Daten und einer optionalen Mappingkomponente welche weiter unten
genauer analysiert wird (siehe auch Abbildung 18 und Abbildung 19). Um wenigstens minimale Sicherheit zu gewährleisten wird das Datenbankpasswort sehr einfach verschlüsselt (XOR) in einer Projektdatei gespeichert. Das Passwort ist damit zwar nicht wirklich sicher, verunmöglicht es aber durch
einfaches Lesen einer Konfigurationsdatei das Passwort zu erhalten und stellt in diesem Zusammenhang eine ausreichend grosse Sicherheit als Kompromiss zwischen Aufwand und Gefährdung dar, da
solche Dateien nur lokal gespeichert werden. Des weiteren enthält die Klasse «projectData» Methoden um die Projektdaten in XML auszugeben oder diese aus einer vorhandenen XML Datei einzulesen. Dieser Vorgang wird auch als Marshalling/Unmarshalling bezeichnet.
Beim beenden des Setups wird das ausgewählte Modul gestartet, welches dann die Kontrolle übernimmt. Beide implementierten Module bestehen wiederum aus Klassen, welche «MyInternalFrame»
Autor: Thomas Schädler
35
6 Implementation des Modells
implementieren und tragen den Namen «SMDBEmain» für das Modul «Simple DB Export», respektive
«DB2XMLmain» für das Modul «Database to XML» (siehe Abbildung 20).
Damit die ganze Oberfläche während den Berechnungen nicht blockiert, wird ein «ThreadPool» verwendet der sich um die verschiedenen Hintergrundaufgaben kümmert. Alle längeren Berechnungen
werden damit in einem eigenen Thread gestartet und der «ThreadPool» kümmert sich um deren Ausführung und Verwaltung. Dieser «Threadpool» wird sowohl für die Benutzeroberfläche als auch für
Datenberechnungen verwendet.
6.2.1 Implementation des Moduls «Simple DB Export»
Dieses erste Modul ist ein leicht umgebauter Datenbankbrowser und stellt zusätzlich zu dessen Funktion die Möglichkeit bereit einzelne Tabellen auszuwählen (um nicht immer die ganze Datenbank exportieren zu müssen) und stellt dem Anwender zwei verschiedene fixierte Ausgabeformate zur Verfügung.
<?xml version="1.0" encoding="UTF-8"?>
<database
name="Project DB"
url="jdbc:mysql://localhost:3306/projekte?useUnicode=true">
<tables>
<projekte>
<row>
<ID>1</ID>
<name>orange8</name>
<ende>2001-12-31</ende>
<status>0</status>
<anfang>2001-10-31</anfang>
</row>
<row>
<ID>2</ID>
<name>e-freak</name>
<ende>2002-06-30</ende>
<status>0</status>
<anfang>2002-03-01</anfang>
</row>
</projekte>
</tables>
</database>
Abbildung 22
: Beispielausgabe des Moduls «Simple DB Export» (simple)
Das einfachere Format («simple») basiert auf dem von Ronald Bourret vorgeschlagenen Ausgabeformat für Tabellen-basiertes Mapping (siehe Abbildung 13 und ein Beispiel in Abbildung 22) und wurde
lediglich um zwei Attribute erweitert welche weitere Informationen zu der ausgewählten Datenbank
enthalten (Name und JDBC-URL der Datenbank). Dieses Format basiert auf keiner DTD und kann
deshalb nicht validiert werden.
Autor: Thomas Schädler
36
6 Implementation des Modells
Das erweiterte Format («verbose») ist eine standardisierte Erweiterung des einfachen Formates wobei
es so abgeändert wurde, dass es in einer DTD ausgedrückt werden kann (Tabellennamen werden als
Attribute und nicht als Elementnamen ausgedrückt). Des weiteren enthält es noch den Typ der Daten.
Dies erhöht die Redundanz der Daten, dafür sind alle Informationen enthalten um aus diesen Daten
zu einem späteren Zeitpunkt eine Datenbank zu rekonstruieren (siehe Abbildung 23 für die DTD und
ein Beispiel der Ausgabe in Abbildung 24).
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT database (tables*)>
<!ATTLIST database
name CDATA #REQUIRED
url CDATA #REQUIRED
>
<!ELEMENT tables (table*)>
<!ELEMENT table (row*)>
<!ATTLIST table
name CDATA #REQUIRED
>
<!ELEMENT row (column*)>
<!ELEMENT column EMPTY>
<!ATTLIST column
name CDATA #REQUIRED
type CDATA #REQUIRED
data CDATA #REQUIRED
>
Abbildung 23
: xmlizer.smdbe.verbose.dtd
Für die Erzeugung des XML Formats, wurde auf die Verwendung von DOM verzichtet, da die Ausgabe von Datenbanktabellen sehr grosse Datenmengen erzeugen kann. DOM kann nur auf kleine XML
Dokumente angewendet werden, da der Speicherverbrauch (unabhängig von der verwendeten DOMBibliothek) sehr gross ist. Die Ausgabe von grossen Datenbanken kann daher auch sehr lange dauern. Deshalb ist es möglich die Ausgabe abzubrechen. Dazu wurde die Klasse «activityMeter» bereitgestellt, welche einen Knopf zum abbrechen und eine «JP rogressBar» enthält um den Fortschritt zu
beobachten. Diese Progressbar zeigt ausserdem die Anzahl aktuell laufender Hintergrundprozesse
an, die aber nicht gestoppt werden können. Durch die ausgiebige Verwendung von Threads ist es
auch möglich während eines laufenden Exports weitere Tabellen der Datenbank anzeigen zu lassen.
Die grafische Oberfläche diese Moduls («SMDBEmain») ist nichts weiter als ein speziell angepasster
Datenbank-Browser («dbBrowser»), da sich die Möglichkeiten dieses Moduls mit der Auswahl von
Tabellen und dem Auswählen eines Ausgabenformates erschöpfen.
Autor: Thomas Schädler
37
6 Implementation des Modells
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE database SYSTEM "xmlizer.smdbe.verbose.dtd">
<database
name="Project DB"
url="jdbc:mysql://localhost:3306/projekte?useUnicode=true">
<tables>
<table name="projekte">
<row>
<column name="ID" type="LONG" data="1"/>
<column name="name" type="VARCHAR" data="orange8"/>
<column name="ende" type="DATE" data="2001-12-31"/>
<column name="status" type="INT" data="0"/>
<column name="anfang" type="DATE" data="2001-10-31"/>
</row>
<row>
<column name="ID" type="LONG" data="2"/>
<column name="name" type="VARCHAR" data="e-freak"/>
<column name="ende" type="DATE" data="2002-06-30"/>
<column name="status" type="INT" data="0"/>
<column name="anfang" type="DATE" data="2002-03-01"/>
</row>
</table>
</tables>
</database>
Abbildung 24
: Beispielausgabe des Moduls «Simple DB Export» (verbose)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xmlizerprojectconfig SYSTEM "xmlizer.project.config.dtd">
<xmlizerprojectconfig>
<initialsetup> ...</initialsetup>
<databasesetup> ... </databasesetup>
<schemasetup> ... </schemasetup>
<mapping>
<smdbe>
<smdbe_item name="XML-DB" type="simple">
<smdbe_table>activities</smdbe_table>
</smdbe_item>
<smdbe_item name="Project-DB" type="verbose">
<smdbe_table>dateien</smdbe_table>
<smdbe_table>lesezeichen</smdbe_table>
<smdbe_table>profile</smdbe_table>
<smdbe_table>projekte</smdbe_table>
<smdbe_table>termine</smdbe_table>
</smdbe_item>
</smdbe>
</mapping>
</xmlizerprojectconfig>
Abbildung 25
: Beispiel der Mappingdaten für das Modul «Simple DB Export» (gekürzt)
Diese Daten für das Mapping werden in der Konfigurationsdatei nach einem einfachen Schema gespeichert. Abbildung 25 zeigt ein Beispiel für gültige Mappingdaten. Für jede Datenbank wird ein
Autor: Thomas Schädler
38
6 Implementation des Modells
«smdbe_item» erstellt welches einen Namen und einen Typ haben muss (der Name wird vom Anwender beim Setup selbst zugeteilt und der Typ ist wie schon erwähnt entweder «simple» oder «verbose». Diese Elemente wiederum enthalten beliebig viele Elemente «smdbe_table» welche nur den
Namen der zu exportierenden Tabelle enthält.
6.2.2 Implementation des Moduls «Database to XML»
Dieses Modul stellt ein Interface zur Verfügung, mit dem beliebige XML Schemas eingelesen, mit Daten aus einer Datenbank gefüllt und als XML Instanz wieder ausgegeben werden können. Das grosse
Problem bei diesem Modul ist, dass es momentan noch keinen (freien) XML Schema Parser oder eine
XML Schema Bibliothek gibt. Da XML Schema auch in XML spezifiziert ist, kann aber ein normaler
XML Parser verwendet werden. Man kommt allerdings nicht darum herum die Logik die hinter den
Schemas steht beim Parsvorgang auszulesen und in einer internen Struktur aufzubauen um später
daraus eine gültige Instanz abzuleiten.
Die Baumstruktur einer XML Instanz ergibt sich aus der Verschachtelung der Elemente in einem XML
Schema. Dabei muss allerdings berücksichtigt werden, dass für jedes Element viele Beschränkungen
definiert sein können und die Typenbeschreibungen können global oder lokal definiert werden oder
aber auch als Referenz auf einen schon definierten Typen angegeben werden. Bei der Implementation wird auf eine Typenüberprüfung verzichtet und alle Typen werden vereinfacht als «Strings» angesehen. Dies vereinfacht den Parsvorgang erheblich, überlässt es aber dem Anwender zu überprüfen,
ob die eingegebenen Daten wirklich zu den im XML Schema angegebenen Datentypen passen. Die
Typkorrektheit wird jedoch in ihren Grundzügen implementiert und kann (da Open Source) zu einem
späteren Zeitpunkt hinzugefügt werden. Als zwischenzeitliche Hilfe wird der zu erwartende Typ immerhin in der Benutzeroberfläche angezeigt und die genaue Typendefinition kann in der Textansicht
des XML Schemas (Text- und Baumsansicht werden beide angezeigt) nachgesehen werden.
Abbildung 26
: xmlizer.project.config.xsd (Baum, nur Mapping) [XMLSPY 01]
Beim Start diese Moduls wird das im Setup schon überprüfte XML Schema von der Klasse
«XMLSchemaParser» geparst und als «JTree» (also als Baumansicht) ausgegeben. Die einzelnen
Knoten dieses Baums sind von der Klasse «SchemaElement» und beinhalten alle benötigten Informationen über die Eigenschaften dieses Elements. Die Anzahl zulässiger Repetitionen («SchemaOccurAutor: Thomas Schädler
39
6 Implementation des Modells
rence»), die Attribute («SchemaAttribute»), ob das Element selbst Text enthalten kann («SchemaContent») und weitere Informationen. Um das ganze grafisch darzustellen wird die Klasse «SchemaElementPanel» verwendet und für das Wurzelelement analog dazu «SchemaRootPanel». Die Unterscheidung von Wurzelelement und «normalen» Elementen wird aus dem Grund gemacht, da das
Wurzelelement immer nur einmal vorkommt, also keinen Textinhalt und keine Repetition enthalten
kann. Dafür können im Wurzelelement Parameter (mit Standardwerten) definiert werden die global zur
Verfügung stehen und bei den anschliessend eingefügten SQL Abfragen Verwendung finden. Dies
ermöglicht es die Ausgabe eine XML Instanz von diesen Parametern abhängig zu machen.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xmlizerprojectconfig SYSTEM "xmlizer.project.config.dtd">
<xmlizerprojectconfig>
<initialsetup> ...</initialsetup>
<databasesetup> ... </databasesetup>
<schemasetup> ... </schemasetup>
<mapping>
<db2xml rootelement="activities">
<db2xml_parameter id="1028587364818" name="max" default="12"/>
<db2xml_element name="activities" id="/activities"/>
<db2xml_element name="activity" id="/activities/activity"
repsql="1028581249836">
<db2xml_attribute name="origin"/ mapid="1028581249836"
mapinfo="Primarykey">
<db2xml_attribute name="dbKey" mapid="1028581249836"
mapinfo="dbKey"/>
<db2xml_attribute name="date" mapid="1028581249836"
mapinfo="date"/>
<db2xml_sql id="1028581249836" db="XML-DB"
sql="SELECT * FROM activities where Primarykey< [-1028587364818:max -]">
<db2xml_sql_info name="PrimaryKey" type="LONG"/>
<db2xml_sql_info name="ForeignKey" type="LONG"/>
<db2xml_sql_info name="date" type="BLOB"/>
<db2xml_sql_info name="dbKey" type="BLOB"/>
</db2xml_sql>
</db2xml_element>
<db2xml_element name="ID" id="/activityType/ID"
repsql="1028582462540">
<db2xml_attribute name="infoStatus" />
<db2xml_sql id="1028582462540" db="XML-DB"
sql="SELECT * FROM id where primarykey= [1028581249836:PrimaryKey]">
<db2xml_sql_info name="PrimaryKey" type="LONG"/>
<db2xml_sql_info name="ForeignKey" type="LONG"/>
<db2xml_sql_info name="uniqID" type="BLOB"/>
</db2xml_sql>
</db2xml_element>
</db2xml>
</mapping>
</xmlizerprojectconfig>
Abbildung 27
Autor: Thomas Schädler
: Beispiel der Mappingdaten für das Modul «Database to XML»
40
6 Implementation des Modells
Bei diesem Parsvorgang werden schon vorhandene Informationen aus den geladenen Mappingdaten
des verwendeten Projekts (falls vorhanden) in die einzelnen Elemente eingefügt, oder wenn noch
keine Mappingdaten verfügbar sind werden diese aufgebaut. Die Struktur der Mappingdaten ist in
einer Baumansicht in Abbildung 26 ersichtlich und ein Beispiel eines solchen Mappings ist in
Abbildung 27 aufgeführt. Die verschiedenen Elemente und dazugehörigen Daten werden in den Mappingdaten nicht als Baumstruktur gespeichert. Dies ist deshalb nicht nötig, da diese Information im
verwendeten XML Schema und in der daraus aufgebauten Baumstruktur vorhanden sind und bei einer
Instanzgenerierung einfach dieser Baum durchlaufen wird.
Die Mappingstruktur im Detail
Als erstes (unterhalb des Elementes «db2xml»), werden die Parameter definiert. Jedes
«db2xml_parameter»-Element enthält zwei Attribute. Den Namen des Parameters und sein Standardwert. Der Standardwert wird verwendet, falls bei der anschliessenden Instanzgenerierung beim Server
keine Parameter übergeben werden. Andernfalls werden die Werte des übergebenen Parameters
verwendet (Genauere Informationen zum Server folgen im nächsten Abschnitt). Bei der Generierung
einer Instanz im Konfigurator können keine Parameter angegeben werden, es werden immer die
Standardwerte verwendet, was aber für den Zweck einer Testausgabe ausreicht. Alternativ kann man
die momentanen Daten speichern und die Ausgabe (mit erweiterten Parametern) mit Hilfe des Servers
überprüfen.
Als weitere Elemente folgen eine Liste von «db2xml_element»-Elementen. Diese Elemente enthalten
als eindeutiges Erkennungsmerkmal eine XPath-ähnliche Pfadangabe, die deshalb benötigt wird, da
in einem XML Schema verschiedenen Elementen mit gleichem Namen, aber verschiedenen Typen
vorkommen können. Als optionales Attribut kann ein solches Element, falls es mehrfach vorkommen
kann, das Attribut «repsql» enthalten welches eine eindeutige ID des zu verwendenden SQL Statements enthält. Des weiteren enthält jedes «db2xml_element»-Element für alle möglichen Attribute ein
«db2xml_attribute»-Element welches als Attribut «name» den Namen dieses Attributs enthält und
optional dazu noch ein Attribut «mapid» welches wiederum eine eindeutige ID eines SQL Statements
enthält und ein Attribut «mapinfo», welches sich auf die zu verwendende Datenbankspalte bezieht.
Als letztes kann jedes «db2xml_element»-Element noch ein oder mehrere «db2xml_sql»-Elemente
enthalten, welche als Attribut «id» bei der Erzeugung eine eindeutige ID zugewiesen bekommen, welche für die Zuweisung zu den Elementen und Attributen der zu erstellenden Instanz benötigt wird. Das
Attribut «db» kennzeichnet die zu verwendende Datenbankverbindung so wie sie im Setup definiert
wurde. Dies ermöglicht es eine Instanz zu generieren die aus mehreren Datenbankquellen Informationen enthält und erweitert den Einsatzbereich des Mappingtools erheblich. Des weiteren enthält jedes
«db2xml_sql»-Element für jede Datenbankspalte der Abrage ein «db2xml_info»-Element welches den
Namen und den Typ dieser Datenbankspalte als Attribut «name» respektive «type» enthält.
Autor: Thomas Schädler
41
6 Implementation des Modells
Um innerhalb eines SQL Statements auf Parameter oder auf Werte aus übergeordneten (in der
Baumstruktur auf einer höheren Ebene vorhandenen) SQL Statements zu verweisen wird eine Substitution angewendet.
Die Parameter werden im Format
"[-" + <parameterID> + ":" + <parameterName> + "-]"
(Beispiel: [-1028587364818:max -])
eingebettet und Referenzen auf andere SQL Statements im Format
"[" + <sqlID> + ":" + sqlInfoName + "]"
(Beispiel: [1028581249836:PrimaryKey]).
Bei der Instanzgenerierung werden nun diese eingebetteten Platzhalter durch die jeweils aktuell aus
der Datenbank ausgelesenen Werte ersetzt (Abhängig von der jeweiligen Datenbankreihe). Damit der
Anwender sich nicht mit diesen kryptischen Formaten auseinandersetzen muss, wird das Mapping
selbst mit Hilfe von Drag and Drop implementiert. In diesem Abschnitt wird jetzt genauer auf die technischen Details der Implementation der Oberfläche und der Instanzgenerierung für dieses Mapping
eingegangen. Genauere (weniger technische) Informationen für Anwender finden sich in Abschnitt 7.
Die Instanzgenerierung
Die am Anfang dieses Abschnitts erläuterte Baumstruktur die sich in der Klasse «DB2XMLmain» befindet ist nach dem Parsvorgang noch leer und enthält keinen Parameter und keine SQL Statements.
Eine Instanzgenerierung ist jedoch in diesem Zustand schon zulässig, ergibt aber einfach eine XML
Instanz die ein leeres Wurzelelement enthält. Der Vorgang der Instanzgenerierung läuft nach folgendem Schema ab. Der Baum wird von der Wurzel an durchlaufen und bei jedem Element wird zuerst
das Repetitionsstatement (SQL) ausgeführt. Die Anzahl Datenbankreihen des Resultates ergibt die
Häufigkeit der Wiederholung dieses Elements. Danach werden die einzelnen Daten für den Textinhalt
und die Attribute eingesetzt (je nach «mapid» und «mapinfo»). Wenn sich die Daten für den Textinhalt und die Attribute auf das Repetitionsstatement beziehen wird die aktuelle Datenbankreihe verwendet. Es ist aber auch möglich für diesen Inhalt einzelne SQL Statements zu verwenden. Diese
SQL Statements sollten immer nur einzelnen Werte (oder nur eine Datenbankreihe) zurückgeben. Als
Workaround wird jedoch - sollte das zugeordnete Statement mehrere Resultatreihen liefern - nur immer die erste Datenbankreihe verwendet.
Als Einschränkung bei der Verwendung dieser Methode ist es aber nicht Möglich «choices» - die in
einem XML Schema verwendet werden - zu generieren, da diese einen Vergleich von zwei Werten
benötigen um zu entscheiden wie weiterverfahren wird. Im jetzigen Zustand werden nur echte Schemaelemente implementiert. Die Implementation von «any» (Wildcard-Element) und anderen erweiterten XML Schemakonstrukten wird für eine spätere Erweiterung des Konfigurators aufgespart. Der
«XMLSchemaParser» erlaubt es aber auch zu diesem Zeitpunkt XML Schemas die diese Konstrukte
verwenden zu parsen, nur können diese Element zum jetzigen Zeitpunkt nicht mit Daten assoziiert
werden (sie zeigen bei der Auswahl kein «SchemaElementPanel» an).
Autor: Thomas Schädler
42
6 Implementation des Modells
Die Benutzeroberfläche mit Drag und Drop
Um die Abhängigkeiten für das Mapping grafisch darzustellen und vorzunehmen werden die in
Abbildung 20 aufgeführten Klassen «SQLChooser», «dbBrowser» und «DataChooser» benötigt. Die
einzelnen Elemente in der Baumansicht enthalten je ein «SchemaElementPanel». Dieses dient dazu
die Daten des ausgewählten Elements anzuzeigen und enthält ausserdem noch sog. Droptargets
(Ziele für den Datenaustausch). Diese ermöglichen es Daten (in unserem Fall die weiter oben definierten Platzhalter) in das «SchemaElementPanel» einzufügen, wodurch auch gleichzeitig die Mappingdaten angepasst werden.
Die Datenquelle für diese Droptargets stellt der «SQLChooser» dar, welcher zu jedem ausgewählten
Element in einem eigenen Fenster dargestellt wird. Dieses Fenster enthält alle SQL Statements die für
das Mapping benötigt werden. Man kann einfach SQL Statements durch das drücken des «Add»Knopfes hinzufügen. Dies wiederum öffnet zwei neue Fenster: einen «dbBrowser» und den «DataChooser». Diese zwei Fenster funktionieren nach dem gleichen Prinzip. Der «dbBrowser» enthält ein
Droptarget (hier das SQL Textfeld) und der «DataChooser» stellt die Datenquelle bereit. Um SQL
Statements im Datenbankbrowser von anderen Werten abhängig zu machen, kann im «DataChooser»
ein Element ausgewählt werden, welches sich auf einer höheren Ebene in der Baumstruktur befindet.
Bei der Selektion eines Elementes wird das mit diesem Element verknüpfte Repetitionsstatement angezeigt und es ist nun möglich die Datenbankspalten dieses Resultates auf das Droptarget zu ziehen.
Ausserdem ist es immer möglich die definierten Parameter zu verwenden (global verfügbar). Beim
schliessen des Datenbankbrowsers wird das aktuelle SQL Statement zum «SQLChooser» hinzugefügt.
Die Daten im «SQLChooser» können nun per Drag und Drop auf die Repetition, die Attribute und den
Textinhalt eines Elemente gezogen werden. Hier greifen jedoch einige Einschränkungen die nötig sind
um die Ausgabe sinnvoll zu gestalten. Die Droptargets des Textinhalts und der Attribute sind nur aktiv,
wenn ein Repetitionsstatement eingefügt wurde, da sonst bei der Instanzgenerierung dieses Element
gar nicht erzeugt wird (ausser das Element kommt genau einmal vor). Bei Repetitionen können nur
ganze SQL Statements eingefügt werden. Bei Attributen und dem Textinhalt kann entweder ein SQL
Statement - jedoch nicht das schon verwendete Repetitionsstatement - oder einzelnen Datenbankspalten des Repetitionsstatements oder eines übergeordneten Repetitionsstatements eingefügt werden. Beim Einfügen eines ganzen SQL Statements ist darauf zu achten, dass das Resultat dieser
Abfrage nur einen Einzelwert zurückgibt. Dies wird dadurch erreicht, dass es nicht möglich ist mehrere
SQL Statements die mehr als eine Datenbankreihe zurückgeben zum «SQLChooser» hinzuzufügen.
Enthält dieses SQL Statement jedoch auch mehrere Spalten ist eine Instanzgenerierung nicht möglich, da nicht entschieden werden kann welcher Wert nun eingefügt werden soll. Els wird dem Anwender überlassen hier eine sinnvolle Zuordnung zu machen. Das «logWindow» gibt entsprechende Hinweise als Warnung aus, die es dem Anwender vereinfachen solche mehrdeutigen Zuordnungen zu
erkennen.
Autor: Thomas Schädler
43
6 Implementation des Modells
6.3
Implementation des Servers
Die Funktion des Servers beschränkt sich auf die Ausgaben der mit dem Konfigurator vorgenommenen Mappingdaten. Die gleiche Funktionalität ist schon im Konfigurator enthalten und wird dort für die
Testausgabe verwendet. Das ganze wurde nun automatisiert und Anworten (in XML oder HTML) können auf Abruf generiert werden. Der Server nimmt HTTP Anfragen an, die im «ConnectionHander»
analysiert und bei Erkennung einer gültigen Anfrage an den «ProjectManager» weitergegeben werden. Nach erfolgreicher Generierung des Resultats wird dieses an den Webbrowser der die Anfrage
geschickt hat zurückgeschickt («Response»). Der «ConnectionHander» ist eine Implementation des
Java-Interfaces «HttpRequestListener» und liefert damit die ganze Funktion die für einen einfachen
Webserver benötigt wird. Eine Übersicht über die wichtigsten Klassen liefert Abbildung 28.
Abbildung 28
: UML Klassen-Diagramm des Servers (Komplett) [JVision 02]
Der «ProjectManager» erfüllt dabei die gleiche Funktionalität wie die Hauptklasse des Konfigurators
(die Klasse «configurator» in Abbildung 20 und Abbildung 21) und kümmert sich somit um die Erstellung einer XML Instanz aus den gespeicherten Mappingdaten und den optional als sog. «Querystring»
übergebenen Parametern.
Im folgenden ist nun der Ablauf einer Anfrage im Detail beschrieben. Der «ConnectionHander» nimmt
eine Anfrage entgegen und generiert aus dem übergebenen «Querystring» mit Hilfe der Klasse «CgiParser» einen «LookupTable». Dieser enthält nun die aufgerufenen Methode (oder Seite) und eine
Liste von Parametern. Wird eine Seite aufgerufen (z.B. index.html) wird diese direkt im «ConnectionHander» behandelt und falls diese im «html»-Verzeichnis vorhanden ist wird die entsprechende
HTML-Seite ausgeliefert. Diese Funktionalität kann auch deaktiviert werden (der sog. Steath-Mode,
bei dem nur Projektdaten ausgeliefert werden und alle anderen Anfragen stillschweigend unterdrückt
werden). Vor der Auslieferung einer HTML-Seite wird diese jedoch noch geparst und eventuell vorkommende Platzhalter werden durch die entsprechende Funktionalität ersetzt (genaueres dazu findet
Autor: Thomas Schädler
44
6 Implementation des Modells
man im Abschnitt 7.4). Dies ermöglicht es die selbe HTML-Seite mit verschiedenen Inhalten darzustellen und minimiert die Einbettung von HTML-Code im Sourcecode des Servers.
Wird als Methode im «LookupTable» jedoch «xmlizer», «htmlizer» oder «customizer» vorgefunden
handelt es sich um eine Abfrage von Projektdaten und der «ProjectManager» tritt in Aktion. Die Generierung der Projektdaten verhält sich genau wie in Abschnitt 6.2.1 und 6.2.2 beschrieben mit der Ausnahme, dass für das Module «Database to XML» die übergebenen Parameter deren Namen mit denen in den Projektdaten übereinstimmen ersetzt werden. Die Funktionalität dieser drei Methoden ist
fast die gleiche nur wird das Auslieferungsformat der generierten Projektdaten geändert. Bei «xmlizer»
wird XML zurückgegeben, bei «htmlizer» werden die gleichen Daten schön in HTML formatiert zurückgegeben und der «customizer» vereint beide Funktionen (mit Hilfe des Parameters «xmlizerformat» mit dem Wert «xmlizer» oder «htmlizer» kann gewählt werden welches Format gewünscht wird).
«customizer» ist eigentlich überflüssig und stellt nur eine Hilfsfunktion dar um mit einem Formular
beide Formate auswählen zu können ohne zwei Formulare verwenden zu müssen.
6.4
Erfahrungsbericht
Wie erwartet war das grösste Problem bei der Implementation die grafische Oberfläche des Konfigurators. Trotz vieler Hilfen durch die verwendete IDE [Forte 02], ist es noch immer nicht trivial eine gut
funktionierende Benutzeroberfläche zu erstellen. Die jetzige, brauchbare Version hat noch immer einige Eigenheiten, kann aber produktiv eingesetzt werden. Die Implementation des Servers hingegen
stellte sich als einfache Aufgabe heraus und der Zeitaufwand hielt sich sehr in Grenzen.
Die XML Unterstützung der benutzen IDE erwies sich aber sehr schnell als unnütz, da sie eher dafür
gedacht ist einen grafischen Editor für XML darzustellen als wirkliche (programmiertechnische) Unterstützung für die Einbettung von XML Funktionalität in eine Applikation darzustellen. Als Editor für die
verwendeten XML Schemas und DTD's wurde jedoch das viel mächtigere XMLSpy [XMLSpy 01] verwendet, welches sehr gute Hilfe leistete.
Für die Implementierung der XML Funktionalität erwies sich jedoch JDOM [JDOM 02 ] als sehr
brauchbar und nach einer kurzen Eingewöhnungszeit kann man damit sehr produktiv arbeiten, da
JDOM die von Java bekannten Design Patterns unterstützt. Im Gegensatz dazu würde die alleinige
Verwendung der W3C XML Bibliothek (die als Grundlage für JDOM dient) einen erheblichen Mehraufwand (an Code und Nerven) bedeuten.
Java als Programmiersprache selbst eignet sich für alle benötigten Aufgaben sehr gut (grafische
Oberfläche, Serverfunktionalität und sonstige Datenbearbeitung). Als Negativpunkt muss man die
ausgeprägte Langatmigkeit dieser Programmiersprache nennen, was sich auch in der Länge des resultierenden Sourcecodes niederschlägt (siehe Anhang A und B). Der Autor ist sich sonst etwas genügsamere Sprachen gewohnt (Perl, PHP). Alles in allem kann aber ein positives Fazit gezogen werden.
Autor: Thomas Schädler
45
7 Informationen für Anwender
7
Informationen für Anwender
7.1
Einführung
<xmlizer> configurator/server ist ein Werkzeug das aus einem grafischen Mappingtool und dem dazugehörigen Server besteht. Es ist möglich jegliche XML Schemas oder DTD's einzulesen und ein Regelwerk aufzustellen wie die Daten aus verschiedenen Datenbanken in dieses vom XML Schema
vorgegebenen Format eingefügt werden kann. Die daraus resultierenden XML Instanzen können mit
Hilfe es Servers automatisch auf Abfrage generiert werden.
Als Beispiel für eine Anwendung kann das AIDA IDML Format genannt werden. Es ist möglich nach
einer einfachen Definition mit Hilfe des Konfigurators diese Daten einem breiten Publikum zugänglich
zu machen. Ein weiteres Beispiel wäre das RDF/RSS Format um Nachrichten auszutauchen. Dieses
Format wird für die sog. «news syndication» verwendet und stellt heute fast schon einen Standard auf
diesem Gebiet dar. Mit Hilfe des Konfigurators kann nun auf einfache Weise dieses Format erzeugt
und mit Hilfe des Servers sofort der Öffentlichkeit zugänglich gemacht werden. Eine Fülle ähnlicher
Anwendungsmöglichkeiten sind denkbar.
7.2
Systemvoraussetzungen und Installation
Die Art des Betriebsystems spielt keine Rolle. Jede Plattform für die eine Java Virtual Machine verfügbar ist kann genutzt werden. Um den Konfigurator oder den Server starten zu können muss jedoch
mindestens Java 1.3 oder höher installiert sein. Ausserdem werden einige Bibliotheken benötigt:
•
jdom.jar è (http://www.jdom.org/ )
•
xercesImpl.jar èXerces XML Parser (http://xml.apache.org/xerces-j/)
•
xmlParserAPIs.jar èXerces W3C XML library(http://xml.apache.org/xerces-j/)
•
xml.jar èSun's XML Parser API (http://java.sun.com)
•
xt.jar è a fast XSLT implementation (http://www.blnz.com/xt/)
•
mm.mysql-2.0.12-bin.jar èmm.mysql database driver (http://mmmysql.sourceforge.net/)
•
… oder der für Ihre Datenbank benötigte JDBC-Treiber
Diese Bibliotheken sowie die neueste Version von <xmlizer> configurator/server sind auf folgender
Website verfügbar: http://www.e-freak.ch/xmlizer. Hier finden Sie auch zusätzliche Information, Beispiele und ein Support-Forum. Alternativ kann der Support unter folgender E-Mail angefragt werden:
[email protected]
Die oben genannten Bibliotheken können Sie einfach in das Verzeichnis «lib/ext» des verwendeten
Java Runtime Environments kopieren oder den «classpath» in dem mit der Distribution mitgelieferten
Startskript anpassen (siehe weiter unten).
Autor: Thomas Schädler
46
7 Informationen für Anwender
Die Installation ist sehr einfach. Sie müssen nur den Server und/oder den Konfigurator herunterladen
und die gezippten Dateien in ein Verzeichnis entpacken. Achten Sie aber darauf, dass die Verzeichnisstruktur erhalten bleibt. In diesem Verzeichnis befindet sich nun eine readme-Datei und eine
Batch-Datei um den Server auf Windows zu starten. Wenn sie ein anderes Betriebssystem verwenden
müssen Sie nur die Batch-Datei ausführbar machen und als erste Zeile die Shell angeben, welche
dieses Skript starten soll (z.B.#!/bin/bash). Des weiteren müssen Sie - falls Java nicht in Ihrem Pfad ist
- den vollständigen Pfad angeben (einfach «java» durch den vollständigen Pfad zu Java ersetzen) und
gegebenenfalls den «classpath» anpassen. Wenn Sie die Bibliotheken nicht ins «lib/ext»-Verzeichnis
kopiert haben müssen Sie nur alle Bibliotheken in ein Verzeichnis entzippen und diese in den
«classpath» hinzufügen (z.B. -classpath %CLASSPATH%;.;xml.jar;jdom.jar etc...). Achten Sie aber
darauf auf jeden Fall das aktuelle Verzeichnis (.) nicht zu vergessen.
7.3
Handbuch: <xmlizer> configurator
7.3.1 Startparameter
Der Konfigurator unterstützt folgende Startparameter:
•
-config <name>
Mit dieser Option können Sie den Konfigurator mit einer bestimmten Konfigurationsdatei starten. Dies ist nützlich für verschiedene Anwender oder bei der Verwendung unterschiedlicher
Projektverzeichnisse.
•
-open <pfad_zu_einer_xmlizer.xml_datei>
Mit dieser Option kann ein bestimmtes Projekt gleich nach dem Start geöffnet werden.
•
-nosplash
Diese Option unterdrückt den Splashscreen welcher beim Start kurz angezeigt wird.
•
-help
Diese Option zeigt die möglichen Startoptionen in einem Fenster.
Beim ersten Start des Konfigurator werden Sie nach zwei Verzeichnissen gefragt. Die Angabe ist
zwingend notwendig, da der Konfigurator sonst nicht fehlerlos arbeiten kann. Das erste Verzeichnis ist
das Basisverzeichnis. Dies ist normalerweise «configurator.xxx» wobei xxx für die Versionsnummer
steht. Allgemein gesagt ist es das Verzeichnis in dem sich nach dem entzippen der Dateien das Startskript und die readme-Datei befinden. Das zweite Verzeichnis ist das Verzeichnis in dem die Projektdaten gespeichert werden. Beim ersten Start ist es noch nicht vorhanden und sollte vorher erstellt
werden. In diesem Verzeichnis werden die später erstellten Projektdaten gespeichert (es sollte beim
ersten Start leer sein). Tauchen beim Benutzen des Konfigurators dauern Fehlermeldungen über nicht
gefundenen Dateien oder falsche Pfade auf, überprüfen Sie bitte ob diese Verzeichnisse wirklich richtig gesetzt sind und löschen Sie andernfalls die Konfigurationsdatei oder editieren Sie diese von Hand
(einfaches, selbsterklärendes XML). Ist der Start erfolgreich werden die Verzeichnisdaten in einer
Datei mit Namen «xmlizer.config» oder bei der Angabe einer Konfigurationsdatei mit dem Namen
«xmlizer.config.<name>» in Ihrem Home-Verzeichnis abgelegt. Wenn Sie ihr Home-Verzeichnis nicht
Autor: Thomas Schädler
47
7 Informationen für Anwender
kennen finden Sie diese und andere Angaben im Konfigurator im Menü Help à System Info unter
«USER Home».
7.3.2 Anleitung
Diese Anleitung ist nur als Leitfaden zu verstehen. Detaillierte Hilfe zu den einzelnen Fenster und
Arbeitsabläufen sind in der integrierten Hilfe der Applikation selbst zu finden. Der Arbeitsablauf ist in
zwei Teile gegliedert. Zuerst wird ein neues Projekt angelegt (Menü: Project à New). Im Setupdialog
werden die benötigten Datenbankverbindungen und das eventuell verwendete XML Schema (oder
eine DTD) hinzugefügt, und als zweiter Schritt werden diese Informationen miteinander assoziiert. Für
den zweiten Schritt wird nach beenden des Setupdialogs automatisch das entsprechende Modul gestartet. Abbildung 29 zeigt eine Übersicht des Hauptfensters (mit einem geöffneten Projekt).
Abbildung 29
: Der Konfigurator in Aktion
Projekt Setup
Die Daten für die Erstellung eines neuen Projekts sind in drei Punkte gegliedert. Als erstes wird ein
Name festgelegt und das Modul für die Art des zukünftigen Mappings ausgesucht. Der Name kann
später nicht mehr geändert werden. Benutzen Sie im Menü Project à Save As um ein Projekt mit
einem anderen Namen zu speichern. Im zweiten Schritt werden alle benötigten Datenbankverbindungen erstellt und auf eine erfolgreiche Verbindung getestet. Der dritte Schritt wird nur für das Modul
Autor: Thomas Schädler
48
7 Informationen für Anwender
«Database to XML» benötigt und legt ein XML Schema oder eine DTD fest, mit welchem gearbeitet
werden soll. Eine DTD wird semi-automatisch in ein XML Schema konvertiert.
Anleitung für das Modul «Simple DB Export»
Diese Modul erlaubt es Ihnen eine Datenbank in zwei festgelegten XML Formaten zu exportieren. Die
Einstellungsmöglichkeiten erschöpfen sich in der Auswahl des Formates («simple» oder «verbose»)
und der Auswahl der Datenbanktabellen die exportiert werden sollen. Dieses Modul besteht nur aus
einem Fenster (siehe Abbildung 30).
Abbildung 30
: Das Module «Simple DB Export» in Aktion
Legen Sie für jede im Setup hinzugefügte Datenbank die Optionen fest und speichern Sie diese Einstellungen. Die Ausgabe können Sie im log-Fenster nach betätigen des «Export»-Knopfes überprüfen.
Verwenden Sie anschliessend den Server um diese Ausgaben weiterzuverarbeiten.
Anleitung für das Modul «Database to XML»
Das im Setup festgelegte XML Schema ist der zentrale Knotenpunkt dieses Moduls. Es wird eingelesen und als Baumansicht dargestellt. Als erstes sollten Sie das Wurzelelement auswählen («schema»)
und dort die verwendeten Parameter definieren. Diese Parameter können später variiert werden um
die Ausgabe von diesen Daten abhängig zu machen (keine statische Ausgabe wie im ersten Modul).
Als weiterer Schritt können Sie die einzelnen Elemente mit Daten aus der Datenbank assoziieren. Hier
wird vorgeschlagen sich von der Wurzel an aufwärts zu arbeiten.
Beim Auswählen eines Elements öffnet sich ein zusätzliches Fenster (der sog. «SQLChooser»). Dieses beinhaltet von Ihnen erstellte SQL Abfragen. Da Sie noch keine SQL Abfragen definiert haben
müssen Sie zuerst im «SQLChooser» mit Hilfe des «Add»-Knopfes ein oder mehrere solche Abfragen
hinzufügen. Dadurch öffnen sich zwei neue Fenster: ein Datenbankbrowser und der dazugehörige
«DataChooser» (siehe Abbildung 31). Wählen Sie im Datenbankbrowser eine Datenbank und selektieAutor: Thomas Schädler
49
7 Informationen für Anwender
ren Sie eine Tabelle oder erstellen Sie ihre Abfrage von Hand. Um eine Abfrage von den Parametern
oder von übergeordneten SQL Abfragen abhängig zu machen benutzen Sie den «DataChooser».
Dort können Sie mit Hilfe von Drag und Drop Datenfelder in das Textfeld des Datenbankbrowsers
ziehen, wobei diese (kryptischen) Textausschnitte bei einer ausgeführten Abfrage durch den realen
Wert im Hintergrund automatisch substituiert werden. Beachten Sie bitte, dass diese Textauschnitte
immer mit einem Leerschlag vom Rest des Textes getrennt sind, das Sie sonst nicht erfolgreich
substituiert werden können. Das schliessen des Datenbankbrowsers fügt die erstellte Abfrage zum
«SQLChooser» hinzu.
Abbildung 31
: Das Modul «Database to XML» in Aktion : Der Datenbankbrowser
Diese SQL Abfrage (oder Teile davon) können Sie per Drag und Drop mit einem entsprechenden Feld
des ausgewählten Schemaelementes assoziieren. Dabei stehen verschiedene Optionen offen. Sie
können und müssen als erstes (falls dieses Schemaelement mehrmals vorkommen kann) zuerst eine
Abfrage mit dem (rot markierten) Repetitionsfeld verknüpfen (siehe Abbildung 32). Diese legt fest wie
oft dieses Element wiederholt wird (die Anzahl Datenbankzeilen der entsprechenden Abfrage). Des
weiteren können Sie SQL Abfragen oder einzelne Tabellenspalten (untere Hälfte des «SQL Choosers») mit den Attributen und dem Textinhalt dieses Elements verknüpfen. Der Textinhalt ist grün und
die Attribute sind blau markiert. Dabei sind jedoch folgende Einschränkungen zu beachten. Sie können eine einer Repetition zugeordnete Abfrage nicht mehrfach verwenden und Sie können je Element
nur eine Abfrage haben, die mehr als eine Datenbankzeile als Resultat zurückgibt. Es würde auch
keinen Sinn machen dem Inhalt Attributs mehr als einen Einzelwert zuzuordnen. Es ist aber durchaus
möglich ein Attribut oder den Textinhalt mit Daten aus übergeordneten Abfragen zu assoziieren. Benutzen Sie dazu die Elementauswahl des «SQLChoosers».
Autor: Thomas Schädler
50
7 Informationen für Anwender
Um die vorgenommenen Zuordnungen zu überprüfen können Sie mit dem «Export»-Knopf eine Instanz generieren. Diese XML Instanz wird im log-Fenter ausgegeben und entspricht der Ausgabe des
Servers, der später dazu eingesetzt wird solche Instanzen auf Abfrage zu generieren. Beachten Sie,
dass die Parameter im Konfigurator nicht geändert werden können. Es werden immer die definierten
Standartwerte verwendet. Beim Server dürfen Sie hingegen diese Parameter nach belieben variieren.
Abbildung 32
7.4
: Das Modul «Database to XML» in Aktion: Drag und Drop einer Abfrage
Handbuch: <xmlizer> server
7.4.1 Startparameter
Der Server unterstützt folgende Startparameter:
•
-config <name>
Mit dieser Option können Sie den Server mit einer bestimmten Konfigurationsdatei starten. Es
ist dadurch möglich verschiedenen Server auf unterschiedlichen Ports parallel zu betreiben.
•
-port <zahl>
Diese Option legt den Port fest an dem der Server erreichbar ist (Standartwert = 7777). Es
kann immer nur ein Server auf einem Port betrieben werden.
•
-base <basis_verzeichnis>
Diese Option legt das Verzeichnis fest in dem der Server installiert ist. Diese Option ist beim
ersten Start zwingend notwendig.
•
-projects <projekt_verzeichnis>
Diese Option legt das Verzeichnis fest in dem sich die Projektdaten befinden. Diese Option ist
beim ersten Start zwingend notwendig.
Autor: Thomas Schädler
51
7 Informationen für Anwender
•
-webinterface on|off
Diese Option schaltet das Webinterface ein oder aus (Standartwert = on). Wenn das Webinterface ausgeschaltet ist liefert der Server keine Fehlermeldungen an den Browser und es ist
zwingend notwendig die genaue URL zu kennen um auf die Daten zuzugreifen. Dafür können
neugierige Zeitgenossen den Server nicht so einfach orten (Stealth-mode). Dies ist die sichere
Betriebsart für den produktiven Einsatz.
•
-refresh on|off
Diese Option legt fest ob der Server bei jeder Anfrage nach neuen Projekten suchen soll
(Standartwert = off). Bei ausgeschaltetem Refresh ist es möglich beim laufenden Betrieb des
Server neue Projekte anzulegen ohne Gefahr zu laufen, dass gleichzeitig Abfragen auf ein
halbfertiges Projekt zugreifen. Für den produktiven Einsatz wird vorgeschlagen den Refresh
aus- und für Testzwecke einzuschalten.
•
-help
Diese Option gibt alle möglichen Startoptionen auf der Kommandozeile aus.
Beim ersten Start eines Servers (oder bei der Angabe einer noch nicht vorhandenen Konfigurationsdatei) müssen Sie (analog zum Konfigurator) zwingend die Optionen «-base» und «-projects» angeben. Andernfalls erhalten Sie einen Hinweis, dass Informationen fehlen und der Server so nicht startbar ist. Auch beim Server ist es so, dass das Basisverzeichnis das Installationsverzeichnis bezeichnet
(da wo die readme-Datei und das Startskript zu finden sind) und das Projektverzeichnis das Verzeichnis in dem der Server nach Projektdaten suchen soll. Bei erfolgreichem Start werden diese Angaben
und alle anderen Startparameter in einer Datei «xmlizer.server.config» oder bei der Angabe einer
Konfigurationsdatei mit dem Namen «xmlizer.server.config.<name>» in Ihrem Home-Verzeichnis abgelegt und bei einem erneuten Start genügt es die Konfigurationsdatei anzugeben, oder auch nichts
um mit der Standartkonfigurationsdatei zu arbeiten. Alle anderen, optionalen Parameter werden - falls
sie spezifiziert sind - in der verwendeten Konfigurationsdatei für weiter Starts des Servers gespeichert.
Es ist also zu einem späteren Zeitpunkt möglich einen einzelnen Parameter zu ändern, der dann für
alle weiteren Starts nicht mehr angegeben werden muss.
7.4.2 Anleitung
Es können mehrere Server auf verschiedenen Ports betrieben werden, wobei jeder Server ein Projektverzeichnis zugeordnet bekommt (über die Kommandozeile oder die angegebenen Konfigurationsdatei). Es ist auch durchaus möglich mehrere Server mit dem gleichen Projektverzeichnis parallel
zu betreiben (bessere Entlastung bei Lastbetrieb). In diesem Falle muss aber der Port geändert werden, da jeder Port immer nur einmal belegt sein darf.
Um auf die Daten zuzugreifen kann das Webinterface benutzt werden, oder direkt auf die Daten zugegriffen werden. Wenn Sie direkt auf die Daten zugreifen muss Ihnen jedoch die URL bekannt sein.
Als Grundsatz gilt, dass eine URL entweder mit «xmlizer» oder «htmlizer» beginnt, je nach gewünschtem Ausgabenformat. Bei allen Modulen wird der Name des Projektes als Parameter «xmlizerproject»
übergeben. Alle intern verwendeten Variabeln beginnen mit «xmlizer». Dies wurde so festgelegt, damit
Autor: Thomas Schädler
52
7 Informationen für Anwender
die projektbezogenen Parameter möglichst nicht mir den internen kollidieren. Beim Modul «Simple DB
Export» wird als zweiter Parameter die gewünschte Datenbank angegeben («xmlizerdb», siehe
Abbildung 33).
Abbildung 33
: Beispiel zweier URL's für das Modul «Simple DB Export»
Beim Modul «Database to XML» können zusätzlich zu der Angabe des Projektnamens noch beliebig
viele Parameter angegeben werden. Natürlich werden nur solche Parameter verarbeitet, die bei diesem Projekt auch zur Verfügung stehen. Der Rest wird stillschweigend verworfen. Abbildung 34 zeigt
ein Beispiel einer solchen URL. Natürlich ist es auch hier möglich «xmlizer» durch «htmlizer» zu ersetzen.
Abbildung 34
: Beispiel einer URL für das Modul «Database to XML»
Bei der Verwendung des Webinterfaces müssen Sie sich um den Aufbau der URL keine Gedanken
machen. Starten Sie einfach ihren Webbrowser mit dem von Ihnen beim Start des Servers angegebenen Hostnamen und der angegebenen Portnummer. Ist der Verbindungsaufbau erfolgreich werden
Sie von der in Abbildung 35 abgebildeten Seite begrüsst (je nach vorhandenen Projekten kann die
Ausgabe auch abweichen).
Abbildung 35
: Auflistung der Projekte des Servers (index.html)
Die Projekte sind verlinkt und führen direkt zu der Detailansicht eines Projektes. In der Detailansicht
sind je nach Modul verschiedene Informationen aufgelistet. Beim Module «Simple DB Export» werden
Autor: Thomas Schädler
53
7 Informationen für Anwender
für jede Datenbank zwei Links angezeigt (einer für die XML- und einer für HTML-Ausgabe). Das Modul
«Database to XML» hingegen liefert in der Detailansicht zusätzlich ein Formular mit dem sich die Parameter einfach ändern lassen (siehe Abbildung 36).
Abbildung 36
Abbildung 37
Autor: Thomas Schädler
: Projektdetails für das Modul «Database to XML»
: Beispiel einer HTML-formatierten Ausgabe der XML Daten
54
7 Informationen für Anwender
Die Ausgabe von XML im Webbrowser kann je nach verwendetem Browser unterschiedlich ausfallen.
Es kann auch vorkommen, dass Fehlermeldungen wegen mangelnder Unterstützung von verschiedenen Zeichensätzen oder Sonderzeichen erscheinen. In diesem Fall ist für die Überprüfung der Ausgabe die HTML-Ausgabe vorzuziehen (siehe Abbildung 37).
7.4.3 Anpassung an Ihre Bedürfnisse
Um den Server weiter nutzbar zu machen (nicht nur für die Ausgabe von XML Daten) ist es möglich
beliebige HTML-Seiten aufzurufen. Diese müssen sich im Verzeichnis «html» des Servers befinden
(oder in beliebigen Unterverzeichnissen dieses Verzeichnisses). Die drei vorhandenen Seiten (index.html, project.html und error.html) sollten nicht gelöscht werden. Es ist aber möglich diese Seiten
zu verändern und an Ihre Bedürfnisse anzupassen. Dabei wird folgendes Konzept angewandt. In diesen HTML-Seiten können verschiedenen Platzhalter gesetzt werden, die vor der Auslieferung dieser
Seite durch die entsprechenden Funktionen ersetzt werden:
•
%%date%% : bezeichnet das aktuelle Datum
•
%%version%% : bezeichnet die Versionsnummer des Servers
•
%%projects%% : listet alle Projekte auf (verlinkt)
•
%%details%% : listet die Details eines Projektes auf (der Name des Projektes wird als Parameter mit Namen «xmlizerproject» übergeben)
•
%%debug%% : zeigt alle übergebenen Parameter als Liste an (Name und Wert)
Achten Sie jedoch darauf, diese Platzhalter je mit einem Leerschlag oder einem Zeilenvorschub von
allem anderen Text zu trennen, da Sie sonst nicht gefunden werden.
Autor: Thomas Schädler
55
8 Schlussfolgerungen
8
Schlussfolgerungen
Die in Abschnitt 1.2 gesetzten Ziele wurden erfreulicherweise erreicht. Das im Verlaufe dieser Arbeit
entwickelte Vermittlungswerkzeug hat noch einige Eigenheiten, kann aber durchaus produktiv eingesetzt werden. Das Werkzeug kann auch - dank einer Open Source Lizenz - beliebige erweitert werden
und ist absolut lizenzfrei verwendbar. Eine entsprechende Website ist seit kurzem online und dort ist
auch die aktuellste Version und zusätzlich Information verfügbar [XMLIZER 02].
Als grösstes Problem bei der Implementation stellte sich die leider noch immer mangelhafte Verfügbarkeit von Bibliotheken für die Analyse von XML Schemas heraus. Dies ist aber nicht verwunderlich,
da XML Schemas eine sehr junge Technologie darstellen. Die Arbeit mit Java konnte hingegen durchaus überzeugen. Genauere Informationen zu den Erfahrungen bei der Implementation findet sich in
Abschnitt 6.4.
Aus der in Abschnitt 1.1 erläuterten Problemstellung in Bezug auf das AIDA IDML Schema wurde
durch eine Verallgemeinerung ein generisches Werkzeug entwickelt, welches nicht auf ein spezifisches XML Schema zugeschnitten ist. Dies erweitert den Einsatzbereich des Vermittlungswerkzeuges
enorm, dafür mussten bei der Implementation durch die erhöhte Komplexität des Themas einige Einschränkungen in Kauf genommen werden. Der ausschlaggebende Punkt dieser Diplomarbeit war
jedoch die Entwicklung eines Werkzeuges, das es erleichtert Daten im IDML Format auszutauschen.
Um den Kreis zu schliessen soll kurz erläutert werden, wie IDML Daten mit Hilfe des Vermittlungswerkzeug ausgetauscht werden können. Die Datenlieferanten können mit dem Konfigurator ein Mapping erzeugen, welches Ihre Daten aus verschiedenen Datenbanken in das IDML Format konvertiert.
Dank der relativ einfachen grafischen Oberfläche können diese Mappingregeln ohne grossen Aufwand
und ohne Expertenwissen erstellt werden. Um die Daten nun öffentlich zugänglich zu machen genügt
es die daraus resultierende Server-URL den Datennachfragern zukommen zu lassen. Diese können
dann manuell oder maschinell die immer aktuell erstellten Daten abfragen. Des weiteren kann durch
den Einsatz von verschiedenen Servern, Projekten oder auch nur Parametern (je nach Einsatzgebiet)
die Erstellung der Daten für verschiedene Datennachfrager individuell angepasst werden.
Autor: Thomas Schädler
56
9 Quellenangaben und Literaturverzeichnis
9
Quellenangaben und Literaturverzeichnis
[Abiteboul/Buneman/Suciu 00] Abiteboul Serge, Buneman Peter, Suciu Dan: Data on the Web - From
Relations to Semistructured Data and XML, Morgan Kaufmann Publishers, San Francisco 2000.
[AIDA 01] Accessible Information on Development Activities (AIDA)
available: http://developmentgateway.org/idml/ui.tcl
Zugriffsdatum: 21.02.2001
[AIDAAuth 02] AIDA Authority Files
available: http://server2.minisisinc.com/ciaflog.htm
Zugriffsdatum: 22.2.2002
[Bellanet 00] Exploring the Potential Application of IDML for the Aid Effectivenes Exchange Module of
the Global Development Gateway.
available: http://www.bellanet.org/
[Borland 02] Borland JBuilder Personal Edition
available: http://www.borland.com/jbuilder/personal/index.html
Zugriffsdatum: 02.04.2002
[Bourret 02] Ronald Bourret: "Mapping DTDs to Databases", "XML and Databases" und "Mapping
W3C Schemas to Object Schemas to Relational Schemas"
available: http://www.rpbourret.com/xml/index.htm
Zugriffsdatum: 12.01.2002
[Castro 00] Castro, Elizabeth: XML for the World Wide Web: Visual QuickStart Guide. Peachpit Press,
Berkeley 2000.
[DTD2XS 02] Lumrix XML Tools (XSBrowser und DTD2XS)
available: http://puvogel.informatik.med.uni-giessen.de/lumrix/
Zugriffsdatum: 15.05.02
[EDI 01] Electronic Data Interchange Organisation
available: http:// www.edi.org/
Zugriffsdatum: 06.10.2001
[EDIAT 01] Electronic Business Austria
available: http:// www.edi.at/
Zugriffsdatum: 12.10.2001
Autor: Thomas Schädler
57
9 Quellenangaben und Literaturverzeichnis
[Forte 02] Forte for Java Community Edition
available: http://wwws.sun.com/software/Developer-products/ffj/
Zugriffsdatum: 02.04.2002
[Java 02] Java Technology Products and APIs
available: http://java.sun.com/
Zugriffsdatum: 02.04.2002
[JDOM 02] JDOM Project
available: http://www.jdom.org
Zugriffsdatum: 02.04.2002
[JVision 02] Object-Insight's JVision
available: http://www.object-insight.com/
Zugriffsdatum: 04.05.2002
[Laudon/Laudon 00] Laudon, Kenneth. C, Laudon, Jane P.: Management Information Systems,
Prentice Hall, New Jersey 2000.
[Goldfarb/Prescot 99] Goldfarb, Charles F., Prescod Paul: XML-Handbuch. Prentice Hall,
München 1999.
[IDML 01] IDML Initiative Website
available: http:// www.idmlinitiative.org/
Zugriffsdatum: 05.10.2001
[IDMLDraft 01] Posting Development Information in IDML Format (Draft)
available: http://gateway.arsdigita.com/node/100647/post-it.doc
Zugriffsdatum: 08.9.2001
[Marchal 00] Marchal, Benôit: XML by Example, Que Publishing, Indianapolis 2000.
[McLaughlin 01] McLaughlin, Brett: XML und Java. O'Reilly Verlag, Köln 2001.
[Merz 99] Merz, Michael: Electronic Commerce, dpunkt.verlag, Heidelberg 1999.
[Morrison 00] Morrison, Michael, et al.: XML Unleashed, Sams Publishing, Indianapolis 2000.
[SCLS 01] SQL Call Level Interface Specification, The Open Group, 1995.
available: http://www.opengroup.org/products/publications/catalog/c451.htm
Zugriffsdatum: 02.12.2001
Autor: Thomas Schädler
58
9 Quellenangaben und Literaturverzeichnis
[UNEDI 01] United Nations Directories for EDIFACT
available: http://www.unece.org/trade/untdid/
Zugriffsdatum: 10.10.2001
[UUC 01] The XML FAQ ("Recommended Reading" by W3C).
available: http://www.ucc.ie/xml/ - FAQ-VALIDWF
Zugriffsdatum: 02.04.2001
[XMLS 01] Working with XML (Tutorial, that covers the basics of XML), Sun XML Solutions Spring
2001. CD-Media Sun Part Number WE276-1.
[XMLSPY 01] XMLSpy Version 3.5, Altova GmbH & Altova Inc. (30 Tage Testversion erhältlich).
available: http://www.xmlspy.com/
Zugriffsdatum: 12.04.2001
[Vanoirbeek/Aboukhaled 00] Vanoirbeek Christine, Aboukhaled Omar, DOM, SAX Gestion de doc uments XML, Vorlesungsunterlagen der Vorlesung Documents Multimedia an der Universität
Fribourg, 2000.
[W3CS 01] World Wide Web Consortium, XML Schema Recommendation.
available: http://www.w3.org/TR/xmlschema-0/
Zugriffsdatum: 04.05.2001
[W3CD 01] World Wide Web Consortium, Document Object Model.
avaliable: http://www.w3.org/DOM/
Zugriffsdatum: 03.05.2001
[XERCES 02] Xerces Java Parser
available: http://xml.apache.org/xerces-j/
Zugriffsdatum: 02.04.2002
[XMLIZER 02] <xmlizer> configurator/server website
available: http://www.e-freak.ch/xmlizer
Zugriffsdatum: 12.08.2002
Autor: Thomas Schädler
59
Anhang A: Quelltext <xmlizer> configurator
Anhang A: Quelltext <xmlizer> configurator
/*
* Start.java
*
* Usage: configurator.Start [options]
*
* Options:
* -config <name>
Use or create a custom xmlizer.config.<name>
* -open <filename>
Loads a project configuration (must conform to DTD)
* -nosplash
Switch off splash screen
* -help
Show this help screen.
*
* Created on 4. April 2002, 18:59
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
/**
* Main Class, starts the application and handels command line options
* @author [email protected]
* @version 0.4
*/
public class Start {
private static configurator conf;
/** Main constructor starts the application and processes command line arguments */
public Start() {
super();
}
/**
* Main Method: generates a new configurator object and calls its constructor
* if needed, a project file is opened automatically if specified by the command line
* @param argv Command line arguments
*/
public static void main(java.lang.String [] argv) {
String remoteOpen = null;
String homebase = null;
String projectbase = null;
String configfileaddition = null;
for (int i=0;i<argv.length ;i++) {
String arg = argv[i];
// options
if (arg.startsWith("-")) {
if (arg.equalsIgnoreCase("-open"))
//load a projectconfiguration
{
remoteOpen = argv[i+1];
}
else if (arg.equalsIgnoreCase("-nosplash"))
//switch off splashscreen
{
conf.SPLASH = false ;
}
else if (arg.equalsIgnoreCase("-config"))
//set config file name
{
configfileaddition = argv[i+1];
}
else if (arg.equalsIgnoreCase("-help"))
//show command line usage
{
printUsage(true);
System.exit(0);
}
}
}
conf = new configurator(configfileaddition);
conf.showSplashScreen();
if (projectbase != null && homebase != null) {
conf.setHomeBase (homebase);
conf.setProjectBase(projectbase);
}
else {
//check here for already exitsting xmlizer.config in the home-directory
StringBuffer configfilename = new StringBuffer(System.getProperty("user.home" ) + System.getProperty("file.separator") + "xmlizer.config");
if (configfileaddition != null) {
configfilename.append("." + configfileaddition);
}
java.io.File configfile = new java.io.File(configfilename .toString());
if (!configfile.exists ()) {
//warn user for 2 directory promts
javax.swing.JOptionPane.showMessageDialog(
null,
"A 'xmlizer.config' file could not be found in\n"
+"your home-directory. You will be prompted twice:\n\n"
Autor: Thomas Schädler
60
Anhang A: Quelltext <xmlizer> configurator
+"1: for the directory where xmlizer is running. \n"
+"2: for the directory where xmlizer will store\n"
+"
the projects. \n\n"
+"HINT: These 2 steps are NOT OPTIONAL.\n"
+"The paths will be stored in 'xmlizer.config'\n"
+"in your home-dir: "+System .getProperty("user.home"),
configurator .APPNAME + " First Run Processing",
javax.swing.JOptionPane .WARNING_MESSAGE
);
boolean homeSet = conf.setHomeBase(homebase);
boolean projectSet = conf.setProjectBase(projectbase);
if (!homeSet || !projectSet) {
printUsage(true);
System.exit(0);
}
else if (homeSet || projectSet) {
//write the xmlizer.config
pathData pd = new pathData();
if (homeSet) { pd.setHomeDir(conf.getHomeBase()); }
if (projectSet ) { pd.setProjectDir (conf.getProjectBase ()); }
//System.out.println(pd.getAsXMLText());
pd.save(configfilename.toString(),true);
}
}
else
//read existing file
{
pathData pd = new pathData();
boolean fileread = pd.readFromFile(configfilename.toString ());
if (pd.isValid()) {
conf.setHomeBase(pd.getHomeDir());
conf.setProjectBase (pd.getProjectDir());
}
else {
printUsage(true);
System.exit(0);
}
}
}
conf.show();
if (remoteOpen != null) {
conf.doRemoteOpen(remoteOpen);
}
}
/**
* Prints the usage message (on console)
*/
private static void printUsage (boolean graphic) {
if (!graphic) {
System .err.println("Usage: configurator.Start [options]");
System .err.println();
System .err.println("Options:");
System .out.println(" -config <name>
Use or create a custom xmlizer.config.<name>" );
System .err.println(" -open <filename>
Loads a project configuration (must conform to DTD)");
System .err.println(" -nosplash
Switch off splash screen");
System .err.println(" -help
Show this help screen.");
}
else {
javax.swing .JOptionPane.showMessageDialog(
null,
"Usage: configurator.Start [options]"
+"\n\nOptions:"
+"\n -config <name>
Use or create a custom xmlizer.config.<name>"
+"\n -open <filename>
Loads a project configuration (must conform to DTD)"
+"\n -nosplash
Switch off splash screen"
+"\n -help
Show this help screen.",
configurator.APPNAME + " usage",
javax.swing .JOptionPane.ERROR_MESSAGE
);
}
}
}
/*
* configurator.java
*
* + resource bundle configurator/configurator.properties
* -> java.util.ResourceBundle.getBundle("configurator/configurator").getString("<key>");
*
* Created on 4. April 2002, 15:48
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import java.io.*;
import java.awt.*;
import javax.swing .*;
Autor: Thomas Schädler
61
Anhang A: Quelltext <xmlizer> configurator
import
import
import
import
import
import
java.lang.*;
java.lang.reflect.*;
java.util.*;
org.jdom.*;
org.jdom.output.XMLOutputter;
org.jdom.input.SAXBuilder;
/**
* Class configurator represents the main window
* @author [email protected]
*/
public class configurator extends JFrame {
/** The apps name */
public static String APPNAME = "<xmlizer> configurator" ;
/** The apps version */
public static String VERSION = "0.9.0";
/** The DTD for the project-files <CODE>xmlizer.project.config.dtd</CODE> */
public static String XMLPROJECTFILEDTD = "xmlizer.project.config.dtd";
/** The name of the root node in the DTD <CODE>xmlizerprojectconfig</CODE> */
public static String XMLPROJECTFILEROOT = "xmlizerprojectconfig";
/** Show the splashscreen or not */
public static boolean SPLASH = true;
/** A Helper class <CODE>UniqueID</CODE> generates unique IDs. */
public static UniqueID uniqueID;
//The ThreadPool to do the UIThreads and other time consuming methods with
//To use the pool just add a Runnable to the pool [pool.execute(someRunnable)]
private ThreadPool pool = new ThreadPool (5);
private splashWindow sw;
private String configname;
public boolean mappingState = false ;
//CONSTRUCTOR
//----------------------------------------------------------------------------------------------/** Creates a new configurator */
public configurator (String configname) {
uniqueID = new UniqueID();
this.configname = configname;
initComponents();
getMainDesktopPane().setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
Log = new logWindow(this,uniqueID.get());
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setWindowTitle(null);
//set the name of the app
initWindowManager();
//inits the stuff to manage the windows
//center the window on the screen on startup
Dimension confSize = getSize();
if(confSize.height > screenSize .height)
{confSize.height = screenSize.height ;}
if(confSize.width > screenSize.width )
{confSize.width = screenSize.width;}
setLocation((screenSize.width - confSize.width )/2,(screenSize .height - confSize.height )/2);
setLogWindow2StandartLocation();
getMainDesktopPane().add(Log);
//show();
//show the whole thing
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
private void initComponents()//GEN-BEGIN:initComponents
{
menuBar = new javax.swing.JMenuBar();
projectMenu = new javax.swing.JMenu();
newMenuItem = new javax.swing.JMenuItem();
jSeparator1 = new javax.swing.JSeparator();
openMenuItem = new javax.swing.JMenuItem();
closeMenuItem = new javax.swing .JMenuItem ();
saveMenuItem = new javax.swing.JMenuItem();
saveAsMenuItem = new javax .swing.JMenuItem();
jSeparator4 = new javax.swing.JSeparator();
optionsMenuItem = new javax.swing.JMenuItem();
jSeparator2 = new javax.swing.JSeparator();
exitMenuItem = new javax.swing.JMenuItem();
uiMenu = new javax.swing.JMenu();
UIManager.LookAndFeelInfo[] lf = UIManager.getInstalledLookAndFeels();
for(int i=0;i<lf.length;i++)
{
String name = lf[i].getName();
String classname = lf[i].getClassName ();
JMenuItem mitem = new JMenuItem(name);
mitem.addActionListener(new LookAndFeelAction(this,classname));
uiMenu .add(mitem );
}
windowMenu = new javax.swing.JMenu();
helpMenu = new javax .swing .JMenu();
contentMenuItem = new javax.swing.JMenuItem();
javadocMenuItem = new javax.swing.JMenuItem();
infoMenuItem = new javax.swing.JMenuItem();
jSeparator3 = new javax.swing.JSeparator();
aboutMenuItem = new javax.swing .JMenuItem ();
mainToolBar = new javax.swing.JToolBar();
newButton = new javax.swing.JButton();
openButton = new javax.swing.JButton();
closeButton = new javax.swing.JButton();
saveButton = new javax.swing.JButton();
saveasButton = new javax.swing.JButton();
optionsButton = new javax.swing .JButton();
logButton = new javax.swing.JButton();
Autor: Thomas Schädler
62
Anhang A: Quelltext <xmlizer> configurator
infoButton = new javax.swing.JButton();
aboutButton = new javax.swing.JButton();
javadocButton = new javax.swing .JButton();
helpButton = new javax.swing.JButton();
desktopScrollPane = new javax.swing.JScrollPane();
mainDesktopPane = new javax.swing.JDesktopPane ();
projectMenu.setText("Project");
newMenuItem.setText(java.util.ResourceBundle.getBundle("configurator/configurator").getString("Menu_Entry_New"));
newMenuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/New16.gif")));
newMenuItem.addActio nListener(new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
newMenuItemActionPerformed(evt);
}
});
projectMenu.add(newMenuItem);
projectMenu.add(jSeparator1);
openMenuItem.setText(java.util.ResourceBundle.getBundle("configurator/configurator").getString("Menu_Entry_Open" ));
openMenuItem.setIcon(new javax.swing .ImageIcon (getClass().getResource("/configurator/icons/Open16.gif" )));
openMenuItem.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
openMenuItemActionPerformed(evt);
}
});
projectMenu.add(openMenuItem);
closeMenuItem.setText(java.util.ResourceBundle .getBundle ("configurator/configurator").getString("Menu_Entry_Close"));
closeMenuItem.setIcon(new javax .swing.ImageIcon(getClass().getResource("/configurator/icons/Close16.gif")));
closeMenuItem.setEnabled(false);
closeMenuItem.addActionListener (new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
closeMenuItemActionPerformed (evt);
}
});
projectMenu.add(closeMenuItem);
saveMenuItem.setText(java.util.ResourceBundle.getBundle("configurator/configurator").getString("Menu_Entry_Save"));
saveMenuItem.setIcon(new javax.swing .ImageIcon (getClass().getResource("/configurator/icons/Save16.gif" )));
saveMenuItem.setEnabled(false);
saveMenuItem.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
saveMenuItemActionPerformed(evt);
}
});
projectMenu.add(saveMenuItem);
saveAsMenuItem .setText(java.util.ResourceBundle.getBundle("configurator/configurator" ).getString("Menu_Entry_SaveAs" ));
saveAsMenuItem.setIcon(new javax.swing.ImageIcon(getClass().getResource ("/configurator/icons/SaveAs16.gif")));
saveAsMenuItem.setEnabled(false );
saveAsMenuItem.addActionListener(new java.awt.event .ActionListener ()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
saveAsMenuItemActionPerformed(evt);
}
});
projectMenu.add(saveAsMenuItem);
projectMenu.add(jSeparator4);
optionsMenuItem .setToolTipText("Show and Edit the Project Options" );
optionsMenuItem .setText(java.util.ResourceBundle.getBundle("configurator/configurator" ).getString("Menu_Entry_Prefs"));
optionsMenuItem .setIcon(new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/Preferences16.gif" )));
optionsMenuItem .setEnabled (false);
optionsMenuItem .addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
optionsMenuItemActionPerformed(evt);
}
});
projectMenu.add(optionsMenuItem );
projectMenu.add(jSeparator2);
exitMenuItem.setText(java.util.ResourceBundle.getBundle("configurator/configurator").getString("Menu_Entry_Exit" ));
exitMenuItem.setIcon(new javax.swing .ImageIcon (""));
exitMenuItem.addActionListener(new java.awt.event.Action Listener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
exitMenuItemActionPerformed(evt);
}
});
projectMenu.add(exitMenuItem);
menuBar.add(projectMenu);
uiMenu.setText("Look&Feel" );
menuBar.add(uiMenu);
windowMenu .setText("View");
menuBar.add(windowMenu);
helpMenu.setText("Help");
contentMenuItem .setText(java.util.ResourceBundle.getBundle("configurator/configurator" ).getString("Menu_Entry_Contents"));
contentMenuItem .setIcon(new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/Help16.gif")));
contentMenuItem .addActionListener(new java.awt.event.ActionListener()
Autor: Thomas Schädler
63
Anhang A: Quelltext <xmlizer> configurator
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
contentMenuItemActionPerformed(evt);
}
});
helpMenu.add(contentMenuItem);
javadocMenuItem.setText(java.util.ResourceBundle .getBundle ("configurator/configurator").getString("Menu_Entry_JavaDoc"));
javadocMenuItem .setIcon(new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/WebComponent16.gif")));
javadocMenuItem .addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
javadocMenuItemActionPerformed(evt);
}
});
helpMenu.add(javadocMenuIt em);
infoMenuItem .setText(java.util.ResourceBundle.getBundle("configurator/configurator" ).getString("Menu_Entry_SysInfo"));
infoMenuItem.setIcon(new javax.swing .ImageIcon (getClass().getResource("/configurator/icons/Information16.gif")));
infoMenuItem.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
infoMenuItemActionPerformed(evt);
}
});
helpMenu.add(infoMenuItem);
helpMenu.add(jSeparator3);
aboutMenuItem.setText(java.util.ResourceBundle .getBundle ("configurator/configurator").getString("Menu_Entry_About"));
aboutMenuItem.setIcon(new javax .swing.ImageIcon(getClass().getResource("/configurator/icons/About16.gif")));
aboutMenuItem.addActionListener (new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
aboutMenuIte mActionPerformed (evt);
}
});
helpMenu.add(aboutMenuItem );
menuBar.add(helpMenu );
setDefaultCloseOperation(javax.swing .WindowConstants.DO_NOTHING_ON_CLOSE);
setName("xmlizer configurator");
addWindowListener(new java.awt.event .WindowAdapter()
{
public void windowClosing(java.awt.event.WindowEvent evt)
{
exitForm(evt);
}
});
mainToolBar.setToolTipText("Project Toolbar");
newButton.setIcon(new javax.swing.ImageIcon(getClass().getResource ("/configurator/icons/New24.gif")));
newButton.setToolTipText("Create a new project...");
newButton.addActionListener(new java.awt.event .ActionListener ()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
newButtonActionPerformed(evt);
}
});
mainToolBar.add(newButton);
mainToolBar.addSeparator();
openButton .setIcon(new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/Open24.gif")));
openButton .setToolTipText("Open an existing project...");
openButton .addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
openButtonActionPerformed(evt);
}
});
mainToolBar.add(openButton );
closeButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/Close24.gif" )));
closeButton.setToolTipText ("Close this project");
closeButton.setEnabled(false);
closeButton.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
closeButtonActionPerformed(evt);
}
});
mainToolBar.add(closeButton);
saveButton .setIcon(new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/Save24.gif")));
saveButton .setToolTipText("Save this project at current state");
saveButton .setEnabled(false);
saveButton .addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
saveButtonActionPerformed(evt);
}
});
Autor: Thomas Schädler
64
Anhang A: Quelltext <xmlizer> configurator
mainToolBar.add(saveButton );
saveasButton.setIcon(new javax.swing .ImageIcon (getClass().getResource("/configurator/icons/SaveAs24.gif")));
saveasButton.setToolTipText("Save this project with with another name...");
saveasButton.setEnabled(false);
saveasButton.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
saveasButtonActionPerformed(evt);
}
});
mainToolBar.add(saveasButton);
mainToolBar.addSeparator();
optionsButton.setIcon(new javax .swing.ImageIcon(getClass ().getResource("/configurator/icons/Preferences24.gif")));
optionsButton.setToolTipText("Opens the Setup Editor");
optionsButton.setEnabled(false);
optionsButton.addActionListener (new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
optionsButtonActionPerformed (evt);
}
});
mainToolBar.add(optionsButton);
logButton.setIcon(new javax.swing.ImageIcon(getClass().getResource ("/configurator/icons/History24.gif" )));
logButton.setToolTipText("Toggle the log window");
logButton.addActionListener(new java.awt.event .ActionListener ()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
logButtonActionPerformed(evt);
}
});
mainToolBar.add(logButton);
mainToolBar.addSeparator();
infoButton .setIcon(new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/Information24.gif" )));
infoButton .setToolTipText("Show system information...");
infoButton .addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
infoButtonActionPerformed(evt);
}
});
mainToolBar.add(infoButton );
aboutButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/About24.gif" )));
aboutButton.setToolTipText ("Show application information...");
aboutButton.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
aboutButtonActionPerformed(evt);
}
});
mainToolBar.add(aboutButton);
javadocButton.setIcon(new javax .swing.ImageIcon(getClass ().getResource("/configurator/icons/WebComponent24.gif")));
javadocButton.setToolTipText("Open the JavaDoc Browser");
javadocButton.addActionListener (new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
javadocButtonActionPerformed (evt);
}
});
mainToolBar.add(javadocButton);
mainToolBar.addSeparator();
helpButton .setIcon(new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/Help24.gif")));
helpButton .setToolTipText("Open the help browser...");
helpButton .addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
helpButtonActionPerformed(evt);
}
});
mainToolBar.add(helpButton );
getContentPane().add(mainToolBar, java.awt.BorderLayout.NORTH );
getContentPane().add(desktopScrollPane, java.awt.BorderLayout .CENTER);
mainDesktopPane .setPreferredSize(new java.awt.Dimension(800, 550));
getContentPane().add(mainDesktopPane , java.awt.BorderLayout.CENTER );
setJMenuBar(menuBar);
pack();
}//GEN-END:initComponents
private void logButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_logButtonActionPerformed
{//GEN-HEADEREND:event_logButtonActionPerformed
Autor: Thomas Schädler
65
Anhang A: Quelltext <xmlizer> configurator
// Add your handling code here:
if (getLog ().isVisible()) {
getLog ().setVisible(false);
}
else {
getLog ().show();
}
JInternalFrame LogIF = (JInternalFrame)getLog();
try {
LogIF.setSelected(true);
}
catch(Exception e) {
System .out.println(e.getLocalizedMessage());
}
if (LogIF.isIcon()) {
getMainDesktopPane().getDesktopManager().deiconifyFrame(LogIF);
}
getLog().update (this);
}//GEN-LAST:event_logButtonActionPerformed
private void optionsMenuItemActionPerformed(java.awt.event.ActionEvent evt)//GEN FIRST:event_optionsMenuItemActionPerformed
{//GEN-HEADEREND:event_optionsMenuItemActionPerformed
// Add your handling code here:
if (data != null) {
doOptions();
}
}//GEN-LAST:event_optionsMenuItemActionPerformed
private void optionsButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_optionsButtonActionPerformed
{//GEN-HEADEREND:event_optionsButtonActionPerformed
// Add your handling code here:
if (data != null) {
doOptions();
}
}//GEN-LAST:event_optionsButtonActionPerformed
private void javadocButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_javadocButtonActionPerformed
{//GEN-HEADEREND:event_javadocButtonActionPerformed
// Add your handling code here:
doJavaDoc();
}//GEN-LAST:event_javadocButtonActionPerformed
private void javadocMenuItemActionPerformed(java.awt.event.ActionEvent evt)//GEN FIRST:event_javadocMenuItemActionPerformed
{//GEN-HEADEREND:event_javadocMenuItemActionPerformed
// Add your handling code here:
doJavaDoc();
}//GEN-LAST:event_javadocMenuItemActionPerformed
private void closeButtonActionPerformed(java.awt.event.ActionEvent evt )//GEN-FIRST:event_closeButtonActionPerformed
{//GEN-HEADEREND:event_closeButtonActionPerformed
// Add your handling code here:
doClose();
}//GEN-LAST:event_closeButtonActionPerformed
private void saveAsMenuItemActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_saveAsMenuItemActionPerformed
{//GEN-HEADEREND:event_saveAsMenuItemActionPerformed
// Add your handling code here:
doSaveAs();
}//GEN-LAST:event_saveAsMenuItemActionPerformed
private void openMenuItemActionPerformed (java.awt.event .ActionEvent evt)//GEN-FIRST:event_openMenuItemActionPerformed
{//GEN-HEADEREND:event_openMenuItemActionPerformed
// Add your handling code here:
doOpen();
}//GEN-LAST:event_openMenuItemActionPerformed
private void newMenuItemActionPerformed(java.awt.event.ActionEvent evt )//GEN-FIRST:event_newMenuItemActionPerformed
{//GEN-HEADEREND:event_newMenuItemActionPerformed
// Add your handling code here:
doNew();
}//GEN-LAST:event_newMenuItemActionPerformed
private void contentMenuItemActionPerformed(java.awt.event.ActionEvent evt)//GEN FIRST:event_contentMenuItemActionPerformed
{//GEN-HEADEREND:event_contentMenuItemActionPerformed
// Add you r handling code here:
doHelp();
}//GEN-LAST:event_contentMenuItemActionPerformed
private void helpButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN -FIRST:event_helpButtonActionPerformed
{//GEN-HEADEREND:event_helpButtonActionPerformed
// Add your handling code here:
doHelp();
}//GEN-LAST:event_helpButtonActionPerformed
private void infoButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN -FIRST:event_infoButtonActionPerformed
{//GEN-HEADEREND:event_infoButtonActionPerformed
// Add your handling code here:
doInfo();
}//GEN-LAST:event_infoButtonActionPerformed
private void aboutButtonActionPerformed(java.awt.event.ActionEvent evt )//GEN-FIRST:event_aboutButtonActionPerformed
{//GEN-HEADEREND:event_aboutButtonActionPerformed
// Add your handling code here:
doAbout();
}//GEN-LAST:event_aboutButtonActionPerformed
private void saveasButtonActionPerformed (java.awt.event .ActionEvent evt)//GEN-FIRST:event_saveasButtonActionPerformed
{//GEN-HEADEREND:event_saveasButtonActionPerformed
// Add your handling code here:
doSaveAs();
}//GEN-LAST:event_saveasButtonActionPerformed
Autor: Thomas Schädler
66
Anhang A: Quelltext <xmlizer> configurator
private void openButtonActionPerfor med(java.awt.event.ActionEvent evt)//GEN -FIRST:event_openButtonActionPerformed
{//GEN-HEADEREND:event_openButtonActionPerformed
// Add your handling code here:
doOpen();
}//GEN-LAST:event_openButtonActionPerformed
private void newButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_newButtonActionPerformed
{//GEN-HEADEREND:event_newButtonActionPerformed
// Add your handling code here:
doNew();
}//GEN-LAST:event_newButtonActionPerform ed
private void saveButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN -FIRST:event_saveButtonActionPerformed
{//GEN-HEADEREND:event_saveButtonActionPerformed
// Add your handling code here:
doSave();
}//GEN-LAST:event_saveButtonActionPerformed
private void infoMenuItemActionPerformed (java.awt.event .ActionEvent evt) {//GEN-FIRST:event_infoMenuItemActionPerformed
// Add your handling code here:
doInfo();
}//GEN-LAST:event_infoMenuItemActionPerformed
private void aboutMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN -FIRST:event_aboutMenuItemActionPerformed
// Add your handling code here:
doAbout();
}//GEN-LAST:event_aboutMenuItemActionPerformed
private void saveMenuItemActionPerformed (java.awt.event .ActionEvent evt) {//GEN-FIRST:event_saveMenuItemActionPerformed
// Add your handling code here:
doSave();
}//GEN-LAST:event_saveMenuItemActionPerformed
private void closeMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN -FIRST:event_closeMenuItemActionPerformed
// Add your handling code here:
doClose();
}//GEN-LAST:event_closeMenuItemActionPerformed
private void exitMenuItemActio nPerformed (java.awt.event .ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
// Add your handling code here:
doExit();
}//GEN-LAST:event_exitMenuItemActionPerformed
/** Exit the Application */
private void exitForm(java.awt.event.WindowEvent evt) {//GEN -FIRST:event_exitForm
// Add your handling code here:
doExit();
}//GEN-LAST:event_exitForm
// Variables declaration - do not modify//GEN -BEGIN:variables
private javax.swing .JMenuBar menuBar;
private javax.swing .JMenu projectMenu;
private javax.swing .JMenuItem newMenuItem;
private javax.swing .JSeparator jSeparator1;
private javax.swing .JMenuItem openMenuItem;
private javax.swing .JMenuItem closeMenuItem;
private javax.swing .JMenuItem saveMenuItem;
private javax.swing .JMenuItem saveAsMenuItem;
private javax.swing .JSeparator jSeparator4;
private javax.swing .JMenuItem optionsMenuItem ;
private javax.swing .JSeparator jSeparator2;
private javax.swing.JMenuItem exitMenuItem;
private javax.swing .JMenu uiMenu;
private javax.swing .JMenu windowMenu;
private javax.swing .JMenu helpMenu;
private javax.swing .JMenuItem contentMenuItem ;
private javax.swing .JMenuItem javadocMenuItem ;
private javax.swing .JMenuItem infoMenuItem;
private javax.swing .JSeparator jSeparator3;
private javax.swing .JMenuItem aboutMenuItem;
private javax.swing .JToolBar mainToolBar ;
private javax.swing .JButton newButton;
private javax.swing .JButton openButton;
private javax.swing .JButton closeButton;
private javax.swing .JButton saveButton;
private javax.swing .JButton saveasButton ;
private javax.swing .JButton optionsButton;
private javax.swing .JButton logButton;
private javax.swing .JButton infoButton;
private javax.swing .JButton aboutButton;
private javax.swing .JButton javadocButton;
private javax.swing .JButton helpButton;
private javax.swing .JScrollPane desktopScrollPane;
private javax.swing .JDesktopPane mainDesktopPane;
// End of variables declaration//GEN-END:variables
//UI RELATED STUFF
//----------------------------------------------------------------------------------------------/**
* Places the logwindow smart on the screen (half hight and full width)
*/
public void setLogWindow2StandartLocation() {
//set the log initially to a good location and size
Dimension paneSize = getMainDesktopPane().getSize();
Log.setSize(paneSize .width ,(paneSize.height/2));
Log.setLocation (0,paneSize .height-Log.getHeight());
}
/**
* Returns the mainDesktopPane (usefull for adding components etc.)
* @return JDesktopPane of the main window to add JInternalFrames (all sub-windows)
*/
public JDesktopPane getMainDesktopPane() {
Autor: Thomas Schädler
67
Anhang A: Quelltext <xmlizer> configurator
return mainDesktopPane;
}
/**
* Set the current open project name in the mainwindow-titelbar or only the name if there are no open projects
*
* @param text The name of the open project
*/
public void setWindowTitle(String text) {
if (text == null || text == new String()) {
getLog ().addDebug("SET WindowTITLE: " + APPNAME);
if (this.configname != null) {
setTitle(APPNAME + " [ configuration: " + this.configname + " ] ");
}
else {
setTitle(APPNAME);
}
}
else {
getLog ().addDebug("SET WindowTITLE: " + APPNAME + " -> " + text);
if (this.configname != null) {
setTitle(APPNAME + " [ configuration: " + this.configname + " ] " + " -> " + text);
}
else {
setTitle(APPNAME + " -> " + text);
}
}
}
/**
* Returns the windowmenu (of the open windows) to switch em through the menu
* @return JMenu containing all open sub -windows (JInternalFrames)
*/
public JMenu getWindowMenu() {
return windowMenu;
}
//USER RESPOND METHODS [ doXXX() ]
//----------------------------------------------------------------------------------------------/**
* Starts a new project
*/
private void doNew() {
//start a new project and a setup window
Runnable r = new Runnable() {
public void run() {
makeNewProjectData ();
open("setup");
}
};
try
{ pool.execute(r); }catch(InterruptedException ie)
{ getLog().addError(ie);}
}
/**
* Starts the options-browser (Tree)
*/
private void doOptions() {
Runnable r = new Runnable() {
public void run() {
//open the setup window
//start a new project and a setup window
open("setup");
}
};
try
{ pool.execute(r); }catch(InterruptedException ie)
{ getLog().addError(ie);}
}
/**
* Starts the help -browser (Swing HTML)
*/
private void doHelp () {
Runnable r = new Runnable() {
public void run() {
//open the help-browser (Swing HTML)
//start a new project and a setup window
helpWindow help = (helpWindow)open("help");
help.loadPage("/configurator/help/index.html");
}
};
try
{ pool.execute(r); }catch(InterruptedException ie)
{ getLog().addError(ie);}
}
/**
* Starts the javadoc-browser (Swing HTML)
*/
private void doJavaDoc() {
Runnable r = new Runnable() {
public void run() {
//open the browser with javadoc
javadocWindow javadoc = (javadocWindow )open("javadoc" );
javadoc.loadPage("/configurator/javadoc/index.html");
}
};
try
{ pool.execute(r); }catch(InterruptedException ie)
{ getLog().addError(ie);}
}
Autor: Thomas Schädler
68
Anhang A: Quelltext <xmlizer> configurator
/**
* The path to the homedirectory
*/
private String projectbase = null;
/**
* Set the path to the homedirectory
*/
public boolean setProjectBase(String prodir) {
if(prodir == null)
//ask for projectbase
{
projectbase = showDirectoryChooser("<xmlizer>-Project Directory");
if (projectbase != null) {
return true;
}
else {
return false ;
}
}
else {
projectbase = prodir;
return true;
}
}
/**
* Get the path to the homedirectory
*/
public String getProjectBase() {
return projectbase;
}
/**
* The path to the homedirectory
*/
private String homebase = null;
/**
* Set the path to the homedirectory
*/
public boolean setHomeBase(String homedir) {
if(homedir == null)
//ask for homebase
{
homebase = showDirectoryChooser("<xmlizer> -Home directory");
if (homebase != null) {
return true;
}
else {
return false ;
}
}
else {
homebase = homedir;
return true;
}
}
/**
* Get the path to the homedirectory
*/
public String getHomeBase() {
return homebase ;
}
private String showDirectoryChooser (String Title) {
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(new java.io.File("."));
chooser.setDialogTitle(Title);
chooser.setFileSelectionMode(JFileChooser .DIRECTORIES_ONLY);
int returnVal = chooser.showOpenDialog(this);
if(returnVal == JFileChooser.APPROVE_OPTION) {
//System.out.println("getCurrentDirectory(): " + chooser.getCurrentDirectory());
//System.out.println("getSelectedFile() : " + chooser.getSelectedFile());
return chooser.getSelectedFile().toString();
}
else return null;
}
/**
* Opens a project - loads a projectdata.xml file and starts with the selected Module
* <CODE>
* related FILE: some/dir/my.projectdata.file.i.saved.5.minutes.ago.xml
* related FILE: some/dir/xmlizer.project.config.dtd
* </CODE>
* @param filename The filename as String
*/
public void doRemoteOpen (String filename ) {
final String the_filename = filename ;
makeNewProjectData();
Runnable r = new Runnable() {
public void run() {
boolean readSuccessfull = getProjectData().readFromFile(the_filename ,getLog());
if (readSuccessfull)//if all was successful, start the project workspace
{
boolean startupOK = startupProjectWorkspace();
if(startupOK) {
getProjectData().save();
//clean the new data (not dirty, because we just read it)
//if that was successful, do the rest
setWindowTitle((String)((dataItem)getProjectData().getInitialByKey("name")).getValue());
getLog().addInformation("Open operation successful: loaded project data.");
showProjectLoadedMessage(
Autor: Thomas Schädler
69
Anhang A: Quelltext <xmlizer> configurator
"Project\n\n[" + ((dataItem)getProjectData().getInitialByKey ("name")).getValue() + "]\n\n"
+ "using Module \n\n[" + ((dataItem)getProjectData().getInitialByKey("module" )).getValue() + "]\n\n"
+ "loaded successfully."
);
}
}
else {
nullifyProjectData();
getLog().addWarning ("Opening Project failed - resetting UI to default.");
}
}
};
try
{ pool.execute(r); }catch(InterruptedException ie)
{ getLog().addError(ie);}
}
/**
* Opens a project - jfilechooser to load a projectdata.xml file and starts with the selec ted Module
*
* FILE: some/dir/my.projectdata.file.i.saved.5.minutes.ago.xml
* FILE: some/dir/xmlizer.project.config.dtd
*
*/
private void doOpen () {
if (data != null) {
getLog ().addWarning("There is already an open project. Save or close the current project first.");
return ;
}
else {
//check for already open project and
// -> open a new project
// -> or close current project and then open an existing project
makeNewProjectData();
JFileChooser chooser = new JFileChooser();
String pbase = getProjectBase();
if (pbase != null) {
chooser.setCurrentDirectory(new File(getProjectBase()));
}
chooser.setDialogType(JFileChooser.OPEN_DIALOG);
simpleFileFilter filter = new simpleFileFilter();
filter .addExtension("xml");
filter .setDescription("XML Only");
chooser.setFileFilter(filter);
final int returnVal = chooser.showOpenDialog(this);
if(returnVal == JFileChooser.APPROVE_OPTION) {
final String chooserSelectedFilePath = chooser.getSelectedFile().getPath();
Runnable r = new Runnable() {
public void run() {
boolean readSuccessfull = getProjectData ().readFromFile (chooserSelectedFilePath,getLog ());
if (readSuccessfull)//if all was successful, start the project workspace
{
getProjectData().save();
//clean the new data (not dirty, because we just read it)
//start the project workspace
boolean startupOK = startupProjectWorkspace();
if (startupOK) {
//if that was successful, do the rest
setWindowTit le((String )((dataItem)getProjectData().getInitialByKey("name" )).getValue());
getLog().addInformation("Open operation successful: loaded project data." );
showProjectLoadedMessage(
"Project\n\n[" + ((dataItem )getProjectData ().getInitialByKey("name")).getValue () + "]\n\n"
+ "using Module\n\n[" + ((dataItem)getProjectData().getInitialByKey("module")).getValue() +
"]\n\n"
+ "loaded successfully."
);
}
}
else {
nullifyProjectData();
getLog ().addWarning("Opening Project failed - resetting UI to default.");
}
}
};
try
{ pool.execute(r); }catch(InterruptedException ie)
{ getLog().addError(ie);}
}
else {
nullifyProjectData ();
getLog().addInformation ("Open Project cancelled.");
}
}
}
/**
* Saves the current project
*/
private synchronized void doSave() {
String location = new String();
//save the data if dirty
if (getProjectData().isDirty()) {
//save project
getProjectData().save();
}
location = getProjectBase() + getProjectData().getSaveLocation();
final String thelocation = location;
Autor: Thomas Schädler
70
Anhang A: Quelltext <xmlizer> configurator
Runnable r = new Runnable() {
public void run() {
//get the doc, xmlize it and save it under current location
if (!thelocation.equals (new String())) {
//save the stuff there
Document xmldata = getProjectData().getAsXMLDocumentJDOM();
XMLOutputter fmt = new XMLOutputter("
",true);
try {
//file stuff
getLog().addDebug("Encoding used for save: " + System.getProperty ("file.encoding" ));
File outputFile = new File(thelocation+configurator.getFileSeparator()+"xmlizer.xml");
File path = new File(thelocation);
if (!path.exists()) {
path.mkdirs ();
}
copyProjectDTD(path.toString());
FileOutputStream outputStream = new FileOutputStream(outputFile);
OutputStreamWriter out = new OutputStreamWriter(outputStream ,"UTF8");
fmt.output (xmldata,out);
out.close();
}
catch (IOException ex) {
JOptionPane.showMessageDialog(
getContentPane(),
"I/O Error, could not save the \ndata correctly!"
+ "\n ERROR:\n------ \n" + ex.toString(),
APPNAME + " save error",
JOptionPane.ERROR_MESSAGE
);
getProjectData().setDirty ();
//not saved, so mark it
getLog().addError(ex);
return;
}
}
else {
//aborted
getProjectData ().setDirty();
//not saved, so mark it
getLog().addError("Project save error, empty filename provided!" );
return;
}
getLog().addInformation ("Project successfully saved: " + thelocation + "xmlizer.xml" );
}
};
try
{ pool.execute(r); }catch(InterruptedException ie)
{ getLog().addError(ie);}
}
/**
* Saves the current project under a new name/file
*/
private void doSaveAs() {
String location = new String();
//show name chooser box
String new_name = null;
boolean aborted = false;
while(new_name == null && !aborted) {
String selected = JOptionPane.showInputDialog("Please enter a new directory name:" );
if (selected == null) {
aborted = true;
}
else {
if(configurator.isValidPath(selected)) {
new_name = selected ;
}
}
}
if (!aborted) {
//change the initial("name") and save it
String old_one = getProjectData().getSaveLocation();
getProjectData().setSaveLocation (new_name);
//save the data if dirty
if (getProjectData().isDirty()) {
//save project
getProjectData().save();
}
final String old_one_f = old_one;
final String new_one_f = new_name;
final String thelocation = getProjectBase() + getProjectData().getSaveLocation();
Runnable r = new Runnable() {
public void run() {
if (!thelocation.equals(new String ())) {
//save the stuff there
Document xmldata = getProjectData().getAsXMLDocumentJDOM();
XMLOutputter fmt = new XMLOutputter ("
",true);
try {
//file stuff
getLog ().addDebug("Encoding used for save: " + System.getProperty("file.encoding"));
File outputFile = new File(thelocation + configurator.getFileSeparator() + "xmlizer.xml");
File path = new File(thelocation);
if (!path.exists ()) {
path.mkdirs();
}
copyProjectDTD(path.toString());
copyXMLFiles(new_one_f,old_one_f);
FileOutputStream outputStream = new FileOutputStream(outputFile);
OutputStreamWriter out = new OutputStreamWriter(outputStream,"UTF8");
Autor: Thomas Schädler
71
Anhang A: Quelltext <xmlizer> configurator
fmt.output(xmldata,out);
out.close();
}
catch (IOException ex) {
JOptionPane .showMessageDialog(
getContentPane(),
"I/O Error, could not save the\ndata correctly!"
+ "\n ERROR:\n------\n" + ex.toString(),
APPNAME + " save error",
JOptionPane .ERROR_MESSAGE
);
getProjectData().setDirty();
//not saved, so mark it
getLog ().addError(ex);
return ;
}
}
else {
//aborted
getProjectData().setDirty ();
//not saved, so mark it
getLog().addError("Project save error, empty filename given!");
return;
}
//getProjectData().setSaveLocation(thelocation);
getLog().addInformation("Project successfully saved: " + thelocation + "xmlizer.xml");
}
};
try
{ pool.execute(r); }catch(InterruptedException ie)
{ getLog().addError(ie);}
}
}
/**
* Closes the current project and returns to startup state of the application
*/
private void doClose() //OK
{
if (data == null)
//no data to save, just reset
{
//reset to default startup state
resetToDefault();
//reset the WindowManager
}
else if (!getProjectData().isDirty())
//data has not changed
{
resetToDefault();
}
else if (getProjectData().isDirty()) //data has changed
{
//ask for discard (ok) or cancel (cancel)
int result = JOptionPane.showConfirmDialog (
getContentPane(),
"Current Project is not saved!\nDiscard this project?",
"<xmlizer> project close",
JOptionPane .OK_CANCEL_OPTION,
JOptionPane .WARNING_MESSAGE
);
if (result == JOptionPane.OK_OPT ION)
//discard
{
//reset to default startup state
resetToDefault();
//reset the WindowManager
setWindowTitle(null);
}
else
//set status and return
{
getLog().addWarning("Close aborted: Current Project is not saved! (Use Menu: Project ->Save)");
return;
}
}
}
/**
* Shows the about dialog
*/
private void doAbout() //OK
{
JOptionPane.showMessageDialog(
getContentPane(),
APPNAME + " ver. " + VERSION + "\n\n-----\nThis software is open source (GPL).\nAbsolutely no warranty at all.\nUse
at own risk.\n-----\n\nby [email protected]\nfor University of Fribourg\n",
"About " + APPNAME,
JOptionPane.INFORMATION_MESSAGE ,
new javax.swing .ImageIcon(getClass().getResource("/configurator/pics/vertical.gif"))
);
}
/**
* Shows the system information dialog
*/
private void doInfo ()
//OK
{
Properties p = new Properties(this);
JOptionPane.showMessageDialog(
getContentPane(),
p.getProps (),
"System Information" ,
JOptionPane.INFORMATION_MESSAGE ,
new javax.swing .ImageIcon(getClass().getResource("/configurator/pics/vertical.gif"))
);
}
/**
* Exits the application after ensuring that the current project is saved or can be discarted
*/
private void doExit ()
//OK
Autor: Thomas Schädler
72
Anhang A: Quelltext <xmlizer> configurator
{
if (data == null || (!getProjectData ().isDirty()))
//no unsaved preferences
{
pool.stopRequestAllWorkers();
dispose();
System .exit(0);
}
else {
//ask for discard (ok) or cancel (cancel)
int result = JOptionPane.showConfirmDialog (
getContentPane(),
"Current Project is not saved!\nDiscard and exit?",
APPNAME + " exit",
JOptionPane .OK_CANCEL_OPTION,
JOptionPane .WARNING_MESSAGE
);
if (result == JOptionPane.OK_OPTION)
//discard end exit
{
pool.stopRequestAllWorkers();
getProjectData().finalize();
dispose();
System.exit(0);
}
else
//set status and return
{
getLog().addWarning("Exit aborted: Current Project is not saved! (Use Menu: Project->Save)");
}
}
}
//MODULE IMPLEMENTATIONS
//----------------------------------------------------------------------------------------------/**
* Main Method for the behaviour of the Simple DB Export Module
* Note: Runs in a pooled Thread
*/
private void startModuleSimpleDBExport() {
Runnable r = new Runnable() {
public void run() {
//do stuff here
getLog().addDebug("Simple Module DB Export starting...");
open("SMDBEmain");
}
};
try
{ pool.execute(r); }catch(InterruptedException ie)
{ getLog().addError(ie);}
}
/**
* Main Method for the behaviour of the DB2XML Module
* Note: Runs in a pooled Thread
*/
private void startModuleDB2XML () {
Runnable r = new Runnable() {
public void run() {
//do stuff here
getLog().addDebug("Database to XML Module starting...");
open("DB2XMLmain");
}
};
try
{ pool.execute(r); }catch(InterruptedException ie)
{ getLog().addError(ie);}
}
//MODULE LOADING METHODS
//----------------------------------------------------------------------------------------------/**
* Shows a message, indicating a successfull project load operation
*/
private void showProjectLoadedMessage(String message) {
JOptionPane.showMessageDialog(
getMainDesktopPane(),
message,
APPNAME + " project loaded successfully",
JOptionPane.INFORMATION_MESSAGE ,
new javax.swing .ImageIcon(getClass().getResource("/configurator/pics/projectloadok.gif"))
);
}
/** Updates the currently open project with the new projectData and calls <PRE>update()</PRE> on them.
* All internal sub -windows must implement <CODE>MyInternalFrame</CODE> and implment its <PRE>update()</PRE> method.
*/
synchronized public void updateCurrentProject () {
if (currentOpenProject != null) {
//System.out.println(currentOpenProject);
//if there is already an instance running and only one allowed return that instance for manipulation
if (openlist.containsKey(currentOpenProject) && !multiple .contains(currentOpenProject)) {
//System.out.println("already running and only one instance allowed");
//gets the unique ID of the given windowtype
String theUID = (String )single.get(currentOpenProject );
//return this instance
Object target = wmwindows.get(theUID);
//get it
MyInternalFrame targetCompIF = (MyInternalFrame)target;
//System.out.println(this.getProjectData().getDB());
targetCompIF.update(this);
}
}
}
private String currentOpenProject = null;
Autor: Thomas Schädler
73
Anhang A: Quelltext <xmlizer> configurator
/**
* Start the selected project module (selected in the current projectData)
* @return Returns true if start was OK, otherwise false.
*/
public boolean startupProjectWorkspace() {
//Start the selected project module and init the menus and toolbars
//check if the module is in the module-list (modules) as a hashtable per module
// with [("name",name),("class",classname),("description",short description)]
dataItem mod = getProjectData().getInitialByKey("module" );
String modname = mod.getValue();
//eg: Simple DB Export
if (modules.contains (modname)) {
if (modname.equalsIgnoreCase("")) {
getLog().addError("Modul not defined (key was empty)!");
return false ;
}
if (modname.equalsIgnoreCase("Simple DB Export" )) {
startModuleSimpleDBExport();
currentOpenProject = "SMDBEmain";
doStartProjectState();
return true;
}
else if (modname.equalsIgnoreCase("Database to XML")) {
startModuleDB2XML();
currentOpenProject = "DB2XMLmain" ;
doStartProjectState();
return true;
}
else {
return false ;
}
}
else {
JOptionPane .showMessageDial og(
getContentPane(),
niceFormat("Your configuration contains a module currently not loaded. Install this module first: [" + modname +
"] and try again later."),
APPNAME + " project load error",
JOptionPane .ERROR_MESSAGE,
new javax.swing.ImageIcon(getClass().getResource("/configurator/pics/projectloaderror.gif"))
);
resetToDefault();
return false;
}
}
/**
* Shows a splashscreen for 3 secs if <code>SPLASH=true</code>
*
*/
public void showSplashScreen() {
if (SPLASH ) {
sw = new splashWindow();
sw.start(3000L);
}
}
//XML HELPERS
//---------------------------- ------------------------------------------------------------------public Document getFileAsXMLDOM(String filename,boolean validating) {
try {
SAXBuilder builder = new SAXBuilder(validating); //true -> validating against dtd
Document jdoc = builder.build(filename);
return jdoc;
}
catch (JDOMException e) {
String the_error_message = new String (
"An ERROR occured while processing a file! \n"
+ "Make sure your your file is valid\n"
+ "and has no other errors. If it has a reference\n"
+ "to a DTD, make sure it is really there! \n\n"
+ "Original Error Message:\n");
String the_error_string = e.toString();
the_error_string = niceFormat(the_error_string);
JOptionPane .showMessageDialog(
getContentPane(),
the_error_message + the_error_string,
APPNAME + " file error",
JOptionPane .ERROR_MESSAGE
);
}
return null;
}
public org.w3c.dom.Document getFileAsXMLW3C(String filename,boolean validating) {
Document jdoc = getFileAsXMLDOM (filename,validating );
if (jdoc != null) {
try {
org.jdom.output.DOMOutputter outp = new org.jdom.output.DOMOutputter ();
return outp.output (jdoc);
}
catch (JDOMException e ) {
String the_error_message = new String(
"An ERROR occured while processing a file!\n"
+ "Make sure your your file is valid\n"
+ "and has no other errors. If it has a reference\n"
Autor: Thomas Schädler
74
Anhang A: Quelltext <xmlizer> configurator
+ "to a DTD, make sure it is really there!\n\n"
+ "Original Error Message:\n");
String the_error_string = e.toString();
the_error_string = niceFormat(the_error_string);
JOptionPane.showMessageDialog(
getContentPane(),
the_error_message + the_error_string,
APPNAME + " file error" ,
JOptionPane.ERROR_MESSAGE
);
}
return null;
}
else {
return null;
}
}
//WINDOW & MODULE MANAGEMENT
//----------------------------------------------------------------------------------------------/** Hashtable key="winid", value=Dimension */
private Hashtable winPlace = new Hashtable();
/**
* Holds all neccessary data for the modules
* system: each Module is a Hashtable with the three items
*
- "name" simple name
*
- "class" classname
*
- "description" description for module
*/
private Vector modules = new Vector ();
/**
* Holds a Vector of dbItems to browse with the databaseBrowser
*/
public Vector nextDBToBrowse = new Vector(0);
/**
* Holds all menuitems and (toolbar)buttons
*/
private Hashtable allmenuitems = new Hashtable();
private Hashtable allbuttons = new Hashtable();
//hash of JMenuItems
//hash of JButtons
/**
* Returns the Hashtable allmenuitems
* @return Hashtable containing all menuitems which have to be informed for changes in the apps state.
*/
public Hashtable getAllMenuItems() {
return allmenuitems;
}
/**
* Returns the Hashtable allbuttons
* @return Hashtable containing all Buttons which have to be informed for changes in the apps state.
*/
public Hashtable getAllButtons () {
return allbuttons;
}
/**
* Returns the module-list as Vector of Strings
* @return Vector containing the names of all selectable modules.
*/
public Vector getAvailableModules() {
return modules;
}
/**
* Holds all open windows (=internal frames)
* format: id = String
: UniqueID of the window after creation
*
value = Object : the window as object
*/
public Hashtable wmwindows = new Hashtable();
/**
* Holds the windows which depend on a project module (id's only)
*/
private Vector userwindow_types = new Vector();
private Vector userwindow_ids = new Vector();
/**
* Holds all open windows (=internal frames) which allow multiple instances
* format: type = String
: "typename"
*/
private Vector multiple = new Vector();
/**
* Holds all open
* format: key =
*
value
*/
private Hashtable
windows (=internal frames) which are only once allowed
String : the window's typekey
= String
: UniqueID of the window
single = new Hashtable ();
/**
* Holds all open windowtypes and the number of instances currently open
* format: type = String
: "typename"
*
value = Integer : Integer (#) of open instances
*/
private Hashtable openlist = new Hashtable();
/**
Autor: Thomas Schädler
75
Anhang A: Quelltext <xmlizer> configurator
* Holds all open windowIDs and a String marking i's type
* format: id = String
: "uniqueID"
*
value = String : "typekey"
*/
private Hashtable id2type = new Hashtable();
/**
* Holds all possible wi ndows
* format: key = String
:
*
value = String :
*/
private Hashtable types = new
/**
* Holds all possible windows
* format: key = String
:
*
value = String :
*/
private Hashtable names = new
types (register the here, all you use!)
"keyname"
"exact name of type" eg: configurator.HTMLFrame
Hashtable();
names (register the here, all you use!)
"keyname"
"name as in window menu"
Hashtable();
/**
* Holds all possible windows names (register them here, all you use!)
* format: key = String
: "keyname"
*
value = JMenuItem : JMenuitem use: setTitle(names.name) or the constructor for the Title
*/
private Hashtable menu = new Hashtable();
/**
* Holds the enable/disable-restrictions for the different windows while opening
* (same for closing such a frame, but vice-versa
*/
private Hashtable openEnable = new Hashtable();
private Hashtable openDisable = new Hashtable();
private Hashtable closeEnable = new Hashtable ();
private Hashtable closeDisable = new Hashtable();
private String setupUID = new String();
/**
* a logWindow
*/
private static logWindow Log = null;
/**
* Return the logWindow object
*/
public static logWindow getLog () {
return Log;
}
/**
* Creates new WindowManager and initiates the types
*/
private void initWindowManager () {
//fill the hashtables to register the windows:
// types -> String key, String FQClassname
// names -> String key, String Description
// openEnable -> String key, String[] keys
=> Items to enable if opened & disabled if closed
// openDisable -> String key, String[] keys => Items to disable if opened & enabled if closed
//fix internal windows
//helpWindow
types.put("help","configurator.helpWindow");
names.put("help","Help Browser" );
//setupWindow
types.put("setup","configurator.setupWindow");
names.put("setup","Project Setup");
openEnable .put("setup",new String[]
{"options"});
openDisable.put("setup",new String[]
{"open","new"});
//closeEnable.put("setup",new String[]{"new"});
//javadocWindow
types.put("javadoc","configurator.javadocWindow");
names.put("javadoc","JavaDoc Browser");
//sdbBrowser
userwindow_types.add("sdatabaseBrowser");
types.put("sdatabaseBrowser","configurator.sdbBrowser");
names.put("sdatabaseBrowser","Simple Database Browser");
//openEnable.put("projectdata",new String[]{"options"});
//openDisable.put("projectdata",new String[]{"open","new"});
//dbBrowser
userwindow_types.add("databaseBrowser");
types.put("databaseBrowser","configurator.dbBrowser");
names.put("databaseBrowser","Database Browser" );
//openEnable.put("projectdata",new String[]{"options"});
//openDisable.put("projectdata",new String[]{"open","new"});
//DataChooser
userwindow_types.add("DataChooser");
types.put("DataChooser","configurator.DataChooser");
names.put("DataChooser","Data Chooser");
//SQLChooser
userwindow_types.add("SQLChooser");
types.put("SQLChooser","configurator.SQLChooser");
names.put("SQLChooser","SQL Chooser" );
//openEnable.put("projectdata",new String[]{"options"});
//openDisable.put("projectdata",new String[]{"open","new"});
Autor: Thomas Schädler
76
Anhang A: Quelltext <xmlizer> configurator
//logWindow
userwindow_types.add("log" );
types.put("log" ,"configurator.logWindow");
names.put("log" ,"Log Window");
//Module stuff
//moduleSimpleDBExport
userwindow_types.add("SMDBEmain");
types.put("SMDBEmain","configurator.SMDBEmain" );
names.put("SMDBEmain","DB Export");
//genericxmlWindow
userwindow _types.add("DB2XMLmain");
types.put("DB2XMLmain","configurator.DB2XMLmain");
names.put("DB2XMLmain","XML Window");
//add the modules
modules.add("Simple DB Export");
modules.add("Database to XML");
//Button and menu stuff
//initiate the list for all menuentries and toolbarbuttons
//(only those who will always be enables, can be left aside)
allbuttons .put("new" ,newButton);
allbuttons .put("open",openButton);
allbuttons .put("close",closeButton);
allbuttons .put("save",saveButton);
allbuttons .put("saveas",saveasButton );
allbuttons .put("options",optionsButton);
allmenuitems.put("new",newMenuItem);
allmenuitems.put("open",openMenuItem );
allmenuitems.put("close",closeMenuItem);
allmenuitems.put("save",saveMenuItem );
allmenuitems.put("saveas",saveAsMenuItem);
allmenuitems.put("options" ,optionsMenuItem);
}
/**
* Switch to UI in Project State
*/
public void doStartProjectState() {
//enable stuff
doEnable("close");
doEnable("save" );
doEnable("saveas");
doEnable("options");
//disable stuff
doDisable("open");
doDisable("new" );
}
/**
* Switch back to UI in xmlizer state (all projects closed)
*/
public void doEndProjectState() {
//disable stuff
doDisable("close");
doDisable("save");
doDisable("saveas");
doDisable("options");
//enable stuff
doEnable("open" );
doEnable("new");
}
/**
* Resets the UI to startup state
*/
public void resetToDefault() {
currentOpenProject = null;
//close all open windows (which are depending on workspace) -> userwindow_ids
closeUserWindows();
close(setupUID);
doEndProjectState();
//update the menu and toolbar
String[] enableIT = new String[]
{"new","open"};
String[] disableIT = new String []
{"close","options","save","saveas"};
for(int i=0;i<enableIT.length;i++) {
JButton button = (JButton)getAllButtons().get(enableIT[i]);
if (button != null) {
button.setEnabled(true);
}
JMenuItem mitem = (JMenuItem)getAllMenuItems().get(enableIT[i]);
if (mitem != null) {
mitem.setEnabled(true);
}
}
for(int i=0;i<disableIT.length;i++) {
JButton button = (JButton)getAllButtons().get(disableIT[i]);
if (button != null) {
button.setEnabled(false );
}
JMenuItem m item = (JMenuItem)getAllMenuItems().get(disableIT[i]);
if (mitem != null) {
Autor: Thomas Schädler
77
Anhang A: Quelltext <xmlizer> configurator
mitem.setEnabled(false);
}
}
getMainDesktopPane().updateUI();
nullifyProjectData();
getLog().addInformation("Welcome to " + APPNAME + " ver. " + VERSION);
}
/**
* Enables the toolbar and menuitems of the specified windowtype
* @param key The <CODE>key</CODE> of the Menuitem or Button to enable.
*/
public void doEnable(String key) {
JButton button = (JButton)getAllButtons().get(key);
if (button != null) {
button .setEnabled(true);
}
JMenuItem mitem = (JMenuItem)getAllMenuItems().get(key);
if (mitem != null) {
mitem.setEn abled (true);
}
}
/**
* Disables the toolbar and menuitems of the specified windowtype
* @param key The <CODE>key</CODE> of the Menuitem or Button to enable.
*/
public void doDisable(String key) {
JButton button = (JButton)getAllButtons().get(key);
if (button != null) {
button .setEnabled(false);
}
JMenuItem mitem = (JMenuItem)getAllMenuItems().get(key);
if (mitem != null) {
mitem.setEnabled (false );
}
}
/** Closes all userwindows (means internal sub-windows) opened by a module.
* @return True if OK, false otherwise.
*/
public void closeUserWindows() {
while(userwindow_ids .size()>0) {
//getLog().addDebug("LISTSIZE = " + userwindow_ids.size() + " LIST "
String current = (String)userwindow_ids.firstElement ();
close(current);
}
}
+ userwindow_ids.toString());
/**
* Returns a specified (look types-list for keys) window, where the key is the type
* @return Object which represents a <PRE>JInternalFrame</PRE> or a <PRE>MyInternalFrame</PRE>. Both is castable.
* @param key The <CODE>key</CODE> of the Window to enable.
*/
synchronized public Object open(String key) {
//if there is already an instance running and only one allowed return that instance for manipulation
if (openlist.containsKey(key) && !multiple.contains (key)) {
//gets the unique ID of the given windowtype
String theUID = (String)single.get(key);
//return this instance
Object target = wmwindows.get(theUID);
//get it
MyInternalFrame targetCompIF = (MyInternalFrame )target;
try {
targetCompIF .update(this);
targetCompIF .setVisible (true);
targetCompIF .setSelected(true);
if (targetCompIF.isIcon ()) {
getMainDesktopPane().getDesktopManager().deiconifyFrame(targetCompIF);
}
getLog().addDebug("Opening already open Window -> " + theUID + "[" + key + "]");
}
catch (Exception ex) {
getLog().addDebug(ex);
}
return target;
}
else
//open a new instance of this window and update all internal lists!
{
if (types.containsKey(key)) //if the type is known -> get new object of that type
{
String type = (String)types.get(key);
//returns the required type as String
String uid = uniqueID.get(); //generates a unique id
Object target; //is the newly created target object to be returned
Class targetDefinition; //its definition
Class[] objectArgsClass = new Class[]
{configurator.class,String.class}; //its argument-class
Constructor objectConstructor; //and its constructor
Object[] objectArgs = new Object[]
{this,uid}; //its arguments
try {
targetDefinition = Class .forName(type); //get a definition for the target type
objectConstructor = targetDefinition.getConstructor(objectArgsClass);
//get an object constructor
target = createObject(objectConstructor , objectArgs);
//get an object, finally
//put it not with the key, but with it's UniqueNumber and update all lists
if (target == null) {
getLog().addError("WindowManager failed to create window: " + key + " -> " + type);
return null;
}
wmwindows.put(uid,target );
//System.out.println("WMWINDOWS PUT: " + uid);
Autor: Thomas Schädler
78
Anhang A: Quelltext <xmlizer> configurator
id2type.put(uid,key);
boolean added = add2openlist(key);
getLog().addDebug("Opening Window -> " + uid + "[" + key + "]");
if (!multiple.contains(key)) // only once allowed
{
getLog().addDebug(" --------> is Single: " + uid + "[" + key + "]");
single.put(key,uid);
}
if (key.equalsIgnoreCase ("setup")) {
setupUID = uid;
}
if (userwindow_types.contains (key)) // add the id to the userwindow_ids table
{
getLog().addDebug(" --------> is Userwindow: " + uid + "[" + key + "]");
userwindow_ids.add(uid);
//getLog().addDebug("USERWINDOW " + uid + " ADDED TO LIST !!! LIST: " + userwindow_ids.toString());
}
JDesktopPane pane = getMainDesktopPane();
Component targetComp = (Component)target;
MyInternalFrame targetCompIF = (MyInternalFrame)targetComp;
targetCompIF.setIdentifier(key);
pane.add(targetComp );
if (this.winPl ace.containsKey (key)) {
getLog().addDebug("READING BOUNDS FOR " + key);
targetCompIF.setBounds((Rectangle)winPlace.get(key));
}
else {
getLog().addDebug("NO BOUNDS FOR " + key);
}
targetComp.setVisible(true);
String compName = (String)names.get(key);
JMenuItem compMenuItem = new JMenuItem(compName,targetCompIF.getFrameIcon());
compMenuItem.addActionListener(new WindowChangeAction(this,uid));
menu.put(uid,compMenuItem);
getWindowMenu().add(compMenuItem);
try {
targetCompIF.setVisible(true);
targetCompIF.setSelected(true);
}
catch (Exception ex ) {
getLog().addDebug(ex);
}
if (added) //if the window is the first instance, then update the toolbar and menuentries
{
if (openEnable.containsKey(key)) // = enable on open
{
String [] enables = (String [])openEnable.get(key);
for(int i=0;i<enables.length;i++) {
JButton button = (JButton)getAllButtons().get(enables[i]);
if (button != null) {
button.setEnabled(true);
}
JMenuItem mitem = (JMenuItem)getAllMenuItems().get(enables[i]);
if (mitem != null) {
mitem.setEnabled(true);
}
}
}
if (openDisable .containsKey(key)) // = enable on close
{
String [] disables = (String[])openDisable .get(key);
for(int i=0;i<disables.length;i++) {
JButton button = (JButton)getAllButtons().get(disables[i]);
if (button != null) {
button.setEnabled(false );
}
JMenuItem mitem = (JMenuItem)getAllMenuItems().get(disables[i]);
if (mitem != null) {
mitem.setEnabled(false);
}
}
}
getWindowMenu().repaint();
}
return target;
}
catch(ClassNotFoundException e) {
System.err.println(e);
return null;
}
catch (NoSuchMethodException e) {
System.err.println(e);
return null;
}
}
else {
getLog().addDebug("Opening w indow failed, unknown key -> " +
return null;
}
key);
}
}
Autor: Thomas Schädler
79
Anhang A: Quelltext <xmlizer> configurator
/**
* Removes a window from the list where the key is the unique key of the window
* note: this must be called in every used type in the exitForm-method
* (normally right before a every dispose which is not needed anymore)
* @param id The <CODE>ID</CODE> of the Window. The ID is generated on window birth and known by the window itself and it
is also contained in a list.
*/
synchronized public void close (String id ) {
if (id != null && !id.equals(new String()) && wmwindows.containsKey(id))
//if the id exists, else do nothing
{
Object obj = wmwindows .get(id);
Component objComp = (Component)obj;
MyInternalFrame objCompIF = (MyInternalFrame)obj;
Rectangle lastBounds = objCompIF .getBounds ();
String lastKey = objCompIF.getIdentifier();
this.winPlace.put(lastKey,lastBounds);
getLog ().addDebug("SETTING BOUNDS FOR " + lastKey + " TO " + lastBounds.toString());
getMainDesktopPane().getDesktopManager().closeFrame(objCompIF);
wmwindows.remove (id);
//System.out.println("WMWINDOWS REMOVED: " + id);
String winType = (String)id2type.get(id);
id2type.remove(id);
if (!multiple.contains (winType)) // only once allowed
{
single.remove(winType);
}
if (winType.equalsIgnoreCase("projectdata" )) {
setupUID = new String();
}
if (userwindow_ids.contains (id)) // delete from the userwindow_ids table
{
userwindow_ids.remove(id);
//getLog().addDebug("USERWINDOW " + id + " REMOVED FROM LIST.!" + userwindow_ids.toString());
}
JMenuItem compMenuItem = (JMenuItem)menu.get(id);
if (compMenuItem != null) {
getWindowMenu().remove(compMenuItem);
getWindowMenu().repaint();
}
menu.remove (id);
boolean removed = remove2openlist(winType);
if (removed) //was the last instance
{
getLog().addDebug("Closing Window -> " + id + "[" + winType + "]");
if (closeDisable.containsKey (winType)) // = disable on close
{
String[] disables = (String[])closeDisable.get(winType);
for(int i=0;i<disables.length ;i++) {
JButton button = (JButton)getAllButtons().get(disables[i]);
if (button != null) {
button .setEnabled(false);
}
JMenuItem mitem = (JMenuItem)getAllMenuItems().get(disables[i]);
if (mitem != null) {
mitem.setEnabled (false);
}
}
}
if (closeEnable.containsKey(winType)) // = enable on close
{
String[] enables = (String[])closeEnable.get(winType);
for(int i=0;i<enables.length;i++) {
JButton button = (JButton)getAllButtons().get(enables[i]);
if (button != null) {
button .setEnabled(true);
}
JMenuItem mitem = (JMenuItem)getAllMenuItems().get(enables[i]);
if (mitem != null) {
mitem.setEnabled (true);
}
}
}
}
}
else {
getLog ().addDebug("Closing failed -> no such window: " + id);
}
}
/**
* Adds an entry to the openlist or updates the count of open instances of the given windowtype
* returns true if added
*
false if modified
*/
private boolean add2openlist(String key) {
if (openlist.containsKey(key)) //increment the number of open instances
{
Integer openCountInteger = (Integer)openlist.get(key);
int openCount = openCountInteger .intValue();
openCount++;
openlist.remove(key);
openlist.put(key,new Integer(openCount));
return false;
}
else //add a new item
Autor: Thomas Schädler
80
Anhang A: Quelltext <xmlizer> configurator
{
openlist.put(key,new Integer(1));
return true;
}
}
/**
* Removes an entry from the openlist or updates the count of open instances of the given windowtype
* returns true if removed (last instance)
*
false if modified
*/
private boolean remove2openlist(String key) {
//System.out.println("remove2openlist " + key);
if (openlist.containsKey(key)) {
Integer openCountInteger = (Integer)openlist.get(key);
int openCount = openCountInteger .intValue();
//System.out.println("remove2openlist " + openCount);
if (openCount > 1) //there are more of these suckers
{
openCount--;
openlist.remove(key);
openlist.put(key,new Integer(openCount ));
return false ;
}
else if (openCount <= 1)
//this is the last one
{
openlist.remove(key);
return true;
}
else {
return true;
}
}
else {
return true;
}
}
//PROJECTDATA
//----------------------------------------------------------------------------------------------/**
* Holds all neccessary data for the current project
* Note: use getProjectData().isDirty() to determine if it changed since the last save()
*/
private projectData data = null;
/**
* Returns the current open <CODE>projectData</CODE>
* @return projectData of the current open project.
*/
public projectData getProjectData() {
if (data == null) {
getLog ().addDebug("PROJECTDATA == NULL -> automatically made fresh data");
makeNewProjectData();
return data;
}
else {
return data;
}
}
/**
* Destroys the old data -set (be carefull) and creates an empty projectdata item
*/
public void makeNewProjectData () {
if (data != null) {
data.finalize();
}
getLog().addDebug("PROJECTDATA RENEWED!");
data = new projectData();
}
/**
* Destroys the current project and sets it to null
*/
public void nullifyProjectData () {
if (data != null) {
data.finalize();
getLog ().addDebug("PROJECTDATA SET TO NULL!");
data = null;
}
}
/**
* Copies the xmlizer.project.config.dtd to the indicated directory
* Neccessary to open a project-file (must be in same dir)
*/
public void copyXMLFiles (String newone, String oldone) {
String sep = configurator.getFileSeparator();
String base = getProjectBase() + sep;
String oldbase = base + oldone + sep;
String newbase = base + newone + sep;
Vector xml = getProjectData().getXML ();
for (Enumeration e = xml.elements(); e.hasMoreElements();) {
xmlItem item = (xmlItem)e.nextElement ();
String filename = item.getFile();
File outputFile = new File(newbase + filename);
File inputFile = new File(oldbase + filename);
try {
FileReader in = new FileRead er(inputFile);
Autor: Thomas Schädler
81
Anhang A: Quelltext <xmlizer> configurator
FileWriter out = new FileWriter(outputFile);
int c;
while ((c = in.read()) != -1)
out.write(c);
in.close();
out.close();
}
catch (Exception ex) {
getLog().addWarning(ex.getLocalizedMessage());
}
}
}
/**
* Copies the xmlizer.project.config.dtd to the indicated directory
* Neccessary to open a project-file (must be in same dir)
*/
public void copyProjectDTD(String dir) {
String sep = configurator.getFileSeparator();
File outputFile = new File(dir + sep + "xmlizer.project.config.dtd");
if (!outputFile .exists()) {
StringBuffer dtdstr = new StringBuffer((getClass().getResource("/configurator/xml/xmlizer.project.config/xmlizer.project.config.dtd" )).toString());
dtdstr .delete(0,5);
File inputFile = new File(dtdstr.toString());
try {
FileReader in = new FileReader(inputFile);
FileWriter out = new FileWriter(outputFile);
int c;
while ((c = in.read()) != -1)
out.write(c);
in.close();
out.close();
}
catch (Exception ex) {
getLog().addWarning(ex.getLocalizedMessage());
}
}
}
//STATIC STUFF
//----------------------------------------------------------------------------------------------/**
* Return a string containing the systems file separator
*/
public static String getFileSeparator() {
return System.getProperty("file.separator");
}
/** Nice-formats a <I>loooooooooong</I> string and breaks it after 30 chars. Not very smart, but it doesn't break between
words.
* @param s String to break apart.
* @return String - newly formated.
*/
public static String niceFormat(String s ) {
String newline = new String("\n");
int makeBreak = 30;
boolean setNow = false;
StringBuffer b = new StringBuffer(s);
for(int i=0;i<b.length();i++) {
if(i%makeBreak == 0) {
setNow = true; //mark for newline break (but wait till word-end)
}
if (setNow && (b.charAt(i) == ' ')) {
b.insert(i,newline );
setNow = false;
}
}
return b.toString();
}
/**
* Returns an array of bytes representing the input-string
*/
public static byte[] String2byteArray(String s,String encoding) {
if (encoding == null) {
return s.getBytes();
}
else {
try {
return s.getBytes(encoding);
}
catch(UnsupportedEncodingException ex ) {
getLog().addError(ex);
return new byte[0];
}
}
}
/**
* Converts a File-String to an URL
*/
public static java.net.URL fileToURL(String sfile) {
File file = new File(sfile );
String path = file.getAbsolutePath();
Autor: Thomas Schädler
82
Anhang A: Quelltext <xmlizer> configurator
String fSep = configurator .getFileSeparator();
if (fSep != null && fSep.length () == 1)
path = path.replace(fSep.charAt(0), '/');
if (path.length () > 0 && path.charAt (0) != '/')
path = '/' + path;
try {
return new java.net.URL("file", null, path);
}
catch (java.net.MalformedURLException e) {
// According to the spec this could only happen if the file
// protocol were not recognized.
throw new Error("unexpected MalformedURLException");
}
}
/**
* Returns an HTML rendition of the given <code>String</code>. This was
* written by <a href=mailto:[email protected]>Kimbo Mundy</a>.
* @param text A <code>String</code> to be used in an HTML page.
* @return A <code>String</code> that quotes any HTML markup
* characters. If no quoting is needed, this will be
* the same as <code>text</code>.
*/
public static String htmlEncode(String text) {
if (text == null) {
return "";
}
StringBuffer results = null;
char[] orig = null;
int beg = 0, len = text.length();
for (int i = 0; i < len; ++i) {
char c = text.charAt(i);
switch (c) {
case 0:
case '&':
case '<':
case '>':
case '"':
if (results == null) {
orig = text.toCharArray();
results = new StringBuffer(len+10);
}
if (i > beg)
results.append(orig, beg, i-beg);
beg = i + 1;
switch (c) {
default: // case 0:
continue;
case '&':
results.append("&");
break;
case '<':
results.append("<" );
break;
case '>':
results.append(">" );
break;
case '"':
results.append(""");
break;
}
break;
}
}
if (results == null)
return text;
results.append(orig, beg, len-beg);
return results.toString();
}
/**
* Debug output for an XML Document (org.w3c.dom.Document)
* @param doc org.w3c.dom.Document to output as a string.
*/
synchronized public static void debugOutput(org.w3c.dom.Document doc) {
if (doc != null) {
//xml stuff
org.apache.xml.serialize.OutputFormat format = new org.apache .xml.serialize.OutputFormat(doc); //Serialize DOM
//format it
format .setLineWidth(65);
format .setIndenting(true);
format .setIndent (4);
StringWriter stringOut = new StringWriter();
//Writer will be a String
org.apache.xml.serialize.XMLSerializer serial = new org.apache .xml.serialize.XMLSerializer(stringOut,format);
//serialize it
try {
serial.asDOMSerializer();
// As a DOM Serializer
serial.serialize(doc.getDocumentElement());
System.out.println ("---------------- XML DEBUG START ----------------");
System.out.print(stringOut);
System.out.println ("---------------- XML DEBUG END ------------------");
}
catch (IOException e) {
System.out.println ("DOM Serializer error for debug output!");
}
}
}
/**
* Debug output for an XML Document (org.jdom.Document)
* @param doc org.jdom.Document to output as a string.
*/
Autor: Thomas Schädler
83
Anhang A: Quelltext <xmlizer> configurator
synchronized public static void debugOutput(Document doc) {
//xml stuff
XMLOutputter fmt = new XMLOutputter("
",true);
//serialize it
try {
System .out.println("---------------- XML DEBUG START ----------------");
fmt.output(doc,System.out);
System .out.println("---------------- XML DEBUG END ------------------");
}
catch (IOException e ) {
System .out.println("DOM Serializer error for debug output!");
}
}
/*
* creates a new object
*/
/** Creates an object from scratch.
* @param constructor The Constructor of the class.
* @param arguments The arguments of the class.
* @return Object just created.
*/
public static Object createObject(Constructor constructor, Object[] arguments) {
Object object = null;
try {
object = constructor.newInstance (arguments );
return object;
}
catch (InstantiationException e ) {
getLog ().addError(e);
}
catch (IllegalAccessException e ) {
getLog ().addError(e);
}
catch (IllegalArgumentException e) {
getLog ().addError(e);
}
catch (InvocationTargetException e) {
getLog ().addError(e);
}
return object;
}
/**
* Checks a name if it is a valid path name (no special chars)
* -> overall: a-z,A-Z
* -> !@ begin: 0-9,-,_
*/
public static boolean isValidPath(String path ) {
String chars = new String("abcdefhgijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
String nums = new String("0123456789");
String special = new String("_-");
if (path.length ()>=1) {
char first = path.charAt(0);
if (!containsChar(chars,first)) {
return false ;
}
}
else {
return false;
}
for(int i=0;i<path.length();i++) {
char current = path.charAt(i);
if (!containsChar(chars,current) && !containsChar(nums,current) && !containsChar(special ,current)) {
//System.out.println(" FALSE: " + path + " --> " + current + " [" + i + "]");
return false ;
}
}
return true;
}
private static boolean containsChar (String stack,char needle ) {
for(int i=0;i<stack.length ();i++) {
char current = stack.charAt (i);
if (current == needle) {
return true;
}
}
return false;
}
//INTERNAL CLASSES
//----------------------------------------------------------------------------------------------/**
* Window Change Action for choosing the window in the WindowMenu
*/
class WindowChangeAction extends AbstractAction {
String uid ;
configurator conf;
protected WindowChangeAction(configurator config, String uid) {
this.conf = config;
this.uid = uid;
}
public void actionPerformed(java.awt.event.ActionEvent e ) {
Runnable r = new Runnable() {
public void run() {
if (conf.wmwindows.containsKey(uid))
//if there is already an instance
Autor: Thomas Schädler
84
Anhang A: Quelltext <xmlizer> configurator
{
Object target = conf.wmwindows .get(uid);
//get it
JInternalFrame targetCompIF = (JInternalFrame )target;
try {
targetCompIF.setVisible(true);
targetCompIF.setSelected(true);
if (targetCompIF .isIcon()) {
conf.getMainDesktopPane().getDesktopManager().deiconifyFrame(targetCompIF );
}
conf.getMainDesktopPane().updateUI();
}
catch (Exception ex) {
//
}
}
}
};
SwingUtilities.invokeLater(r);
}
}
/**
* Look and Feel Action for choosing in the L&FMenu
*/
class LookAndFeelAction extends AbstractAction {
String laf ;
configurator conf;
/** This action is attached to Menuentries for the Look&Feel change of the UI.
* @param config The <PRE>configurator</PRE> (normally <CODE>this</CODE>).
* @param laf String for the Look&Feel (its name)
*/
protected LookAndFeelAction(configurator config, String laf) {
this.conf = config;
this.laf = laf;
}
/** The action
*/
public void actionPerformed(java.awt.event.ActionEvent e ) {
Runnable r = new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(laf);
SwingUtilities.updateComponentTreeUI(conf);
}
catch(java.lang.Exception ex) {
//error handling Vetoable Exception!
}
}
};
SwingUtilities.invokeLater(r);
}
}
}
/*
* TableMap.java
*
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------* @(#)TableMap.java
1.7 99/04/23
*
* Copyright (c) 1997-1999 by Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTI CULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
/**
Autor: Thomas Schädler
85
Anhang A: Quelltext <xmlizer> configurator
* In a chain of data manipulators some behaviour is common. TableMap
* provides most of this behavour and can be subclassed by filters
* that only need to override a handful of specific methods. TableMap
* implements TableModel by routing all requests to its model, and
* TableModelListener by routing all events to its listeners. Inserting
* a TableMap which has not been subclassed into a chain of table filters
* should have no effect.
*
* @version 1.7 04/23/99
* @author Philip Milne
*/
package configurator;
import javax.swing .table.*;
import javax.swing .event.TableModelListener;
import javax.swing .event.TableModelEvent;
public class TableMap extends AbstractTableModel implements TableModelListener {
protected TableModel model;
public TableModel
return model;
}
getModel() {
public void setModel(TableModel model) {
this.model = model;
model.addTableModelListener(this);
}
// By default, Implement TableModel by forwarding all messages
// to the model.
public Object getValueAt (int aRow, int aColumn) {
return model.getValueAt(aRow, aColumn);
}
public void setValueAt(Object aValue, int aRow, int aColumn) {
model.setValueAt(aValue, aRow, aColumn);
}
public int getRowCount() {
return (model == null) ? 0 : model.getRowCount ();
}
public int getColumnCount() {
return (model == null) ? 0 : model.getColumnCount();
}
public String getColumnName(int aColumn) {
return model.getColumnName (aColumn);
}
public Class getColumnClass(int aColumn) {
return model.getColumnClass(aColumn);
}
public boolean isCellEditable(int row, int column) {
return model.isCellEditable(row, column);
}
//
// Implementation of the TableModelListener interf ace,
//
// By default forward all events to all the listeners.
public void tableChanged (TableModelEvent e) {
fireTableChanged(e);
}
}/*
* TableSorter.java
*
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------* @(#)TableSorter.java 1.8 99/04/23
*
* Copyright (c) 1997-1999 by Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
Autor: Thomas Schädler
86
Anhang A: Quelltext <xmlizer> configurator
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
/**
* A sorter for TableModels. The sorter has a model (conforming to TableModel)
* and itself implements TableModel. TableSorter does not store or copy
* the data in the TableModel, instead it maintains an array of
* integers which it keeps the same size as the number of rows in its
* model. When the model changes it notifies the sorter that something
* has c hanged eg. "rowsAdded" so that its internal array of integers
* can be reallocated. As requests are made of the sorter (like
* getValueAt(row, col) it redirects them to its model via the mapping
* array. That way the TableSorter appears to hold another copy of the table
* with the rows in a different order. The sorting algorthm used is stable
* which means that it does not move around rows when its comparison
* function returns 0 to denote that they are equivalent.
*
* @version 1.8 04/23/99
* @auth or Philip Milne
*/
package configurator;
import java.util.*;
import javax.swing .table.TableModel;
import javax.swing .event.TableModelEvent;
// Imports for picking up mouse events from the JTable.
import java.awt.event.MouseAdapter ;
import java.awt.event.MouseEvent;
import java.awt.event.InputEvent;
import javax.swing .JTable;
import javax.swing .table.JTableHeader;
import javax.swing .table.TableColumn;
import javax.swing .table.TableColumnModel;
public class TableSorter extends TableMap {
int
indexes[];
Vector
sortingColumns = new Vector();
boolean
ascending = true;
int compares;
public TableSorter() {
indexes = new int[0]; // For consistency.
}
public TableSorter(TableModel model ) {
setModel(model);
}
public void setModel(TableModel model) {
super.setModel(model );
reallocateIndexes();
}
public int compareRowsByColumn (int row1, int row2, int column) {
Class type = model.getColumnClass(column);
TableModel data = model;
// Check for nulls
Object o1 = data.getValueAt(row1, column);
Object o2 = data.getValueAt(row2, column);
// If both values are null return 0
if (o1 == null && o2 == null) {
return 0;
}
else if (o1 == null) { // Define null less than everything.
return -1;
}
else if (o2 == null) {
return 1;
}
/* We copy all ret urned values from the getValue call in case
an optimised model is reusing one object to return many values.
The Number subclasses in the JDK are immutable and so will not be used in
this way but other subclasses of Number might want to do this to save
space and avoid unnecessary heap allocation.
*/
if (type.getSuperclass() == java.lang.Number.class) {
Number n1 = (Number)data.getValueAt(row1, column);
double d1 = n1.doubleValue();
Number n2 = (Number)data.getValueAt(row2, column);
double d2 = n2.doubleValue();
if (d1 < d2)
return -1;
else if (d1 > d2)
return 1;
else
return 0;
}
else if (type
Date d1 =
long n1 =
Date d2 =
long n2 =
== java.util.Date.class) {
(Date)data.getValueAt(row1, column);
d1.getTime();
(Date)data.getValueAt(row2, column);
d2.getTime();
Autor: Thomas Schädler
87
Anhang A: Quelltext <xmlizer> configurator
if (n1 < n2)
return -1;
else if (n1 > n2)
return 1;
else return 0;
}
else if (type == String.class) {
String s1 = (String)data.getValueAt(row1, column);
String s2
= (String)data.getValueAt(row2, column);
int result = s1.compareTo(s2);
if (result < 0)
return -1;
else if (result > 0)
return 1;
else return 0;
}
else if (type == Boolean.class) {
Boolean bool1 = (Boolean)data.getValueAt(row1, column);
boolean b1 = bool1.booleanValue();
Boolean bool2 = (Boolean)data.getValueAt(row2, column);
boolean b2 = bool2.booleanValue();
if (b1 == b2)
return 0;
else if (b1) // Define false < true
return 1;
else
return -1;
}
else {
Object v1 = data.getValueAt (row1, column);
String s1 = v1.toString();
Object v2 = data.getValueAt (row2, column);
String s2 = v2.toString();
int result = s1.compareTo(s2);
if (result < 0)
return -1;
else if (result > 0)
return 1;
else return 0;
}
}
public int compare(int row1, int row2) {
compares++;
for(int level = 0; level < sortingColumns .size(); level++) {
Integer column = (Integer)sortingColumns.elementAt(level);
int result = compareRowsByColumn (row1, row2, column.intValue());
if (result != 0)
return ascending ? result : -result;
}
return 0;
}
public void reallocateIndexes () {
int rowCount = model .getRowCount();
// Set up a new array of indexes with the right number of elements
// for the new data model.
indexes = new int[rowCount ];
// Initialise with the identity mapping.
for(int row = 0; row < rowCount ; row++)
indexes[row] = row;
}
public void tableChanged (TableModelEvent e) {
reallocateIndexes();
super.tableChanged(e);
}
public void checkModel() {
if (indexes.length != model.getRowCount()) {
System .err.println("Sorter not informed of a change in model." );
}
}
public void sort(Object sender) {
checkModel ();
compares = 0;
// n2sort();
// qsort(0, indexes.length -1);
shuttlesort((int[])indexes .clone(), indexes, 0, indexes.length);
}
public void n2sort() {
for(int i = 0; i < getRowCount(); i++) {
for(int j = i+1; j < getRowCount (); j++) {
if (compare(indexes[i], indexes[j]) == -1) {
swap(i, j);
}
}
}
}
//
//
//
//
//
//
//
This is a home-grown implementation which we have not had time
to research - it may perform poorly in some circumstances. It
requires twice the space of an in-place algorithm and makes
NlogN assigments shuttling the values between the two
arrays. The number of compares appears to vary between N-1 and
NlogN depending on the initial order but the main reason for
using it here is that, unlike qsort, it is stable.
Autor: Thomas Schädler
88
Anhang A: Quelltext <xmlizer> configurator
public void shuttlesort(int from[], int to[], int low, int high) {
if (high - low < 2) {
return ;
}
int middle = (low + high)/2;
shuttlesort(to, from, low, middle);
shuttlesort(to, from, middle, high);
int p = low;
int q = middle;
/* This is an optional short-cut; at each recursive call,
check to see if the elements in this subset are already
ordered. If so, no further comparisons are needed; the
sub-array can just be copied. The array must be copied rather
than assigned otherwise sister calls in the recursion might
get out of sinc. When the number of elements is three they
are partitioned so that the first set, [low, mid), has one
element and and the second, [mid, high), has two. We skip the
optimisation when the number of elements is three or less as
the first compare in the normal merge will produce the same
sequence of steps. This optimisation seems to be worthwhile
for partially ordered lists but some analysis is needed to
find out how the performan ce drops to Nlog(N) as the initial
order diminishes - it may drop very quickly. */
if (high - low >= 4 && compare(from[middle-1], from[middle]) <= 0) {
for (int i = low; i < high; i++) {
to[i] = from[i];
}
return ;
}
// A normal merge.
for(int i = low; i < high; i++) {
if (q >= high || (p < middle && compare(from[p], from[q]) <= 0)) {
to[i] = from[p++];
}
else {
to[i] = from[q++];
}
}
}
public void swap(int i, int j) {
int tmp = indexes[i];
indexes[i] = indexes[j];
indexes[j] = tmp;
}
// The mapping only affects the contents of the data rows.
// Pass all requests to these rows through the mapping array: "indexes".
public Object getValueAt (int aRow, int aColumn) {
checkModel ();
return model.getValueAt(indexes[aRow], aColumn);
}
public void setValueAt(Object aValue, int aRow, int aColumn) {
checkModel ();
model.setValueAt(aValue, indexes[aRow], aColumn);
}
public void sortByColumn (int column ) {
sortByColumn(column, true);
}
public void sortByColumn (int column , boolean ascending) {
this.ascending = ascending ;
sortingColumns.removeAllElements();
sortingColumns.addElement(new Integer(column));
sort(this);
super.tableChanged(new TableModelEvent(this));
}
// There is no -where else to put this.
// Add a mouse listener to the Table to trigger a table sort
// when a column heading is clicked in the JTable.
public void addMouseListenerToHeaderInTable(JTable table) {
final TableSorter sorter = this;
final JTable tableView = table;
tableView.setColumnSelectionAllowed(false );
MouseAdapter listMouseListener = new MouseAdapter() {
public void mouseClicked(MouseEvent e ) {
TableColumnModel columnModel = tableView.getColumnModel();
int viewColumn = columnModel .getColumnIndexAtX(e.getX());
int column = tableView.convertColumnIndexToModel (viewColumn);
if(e.getClickCount () == 1 && column != -1) {
int shiftPressed = e.getModifiers()&InputEvent.SHIFT_MASK;
boolean ascending = (shiftPressed == 0);
sorter.sortByColumn (column, ascending);
}
}
};
JTableHeader th = tableView.getTableHeader();
th.addMouseListener(listMouseListener);
}
}/*
* ThreadPool.java
*
* Created on 19. Mai 2002, 20:28
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
Autor: Thomas Schädler
89
Anhang A: Quelltext <xmlizer> configurator
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
/**
* A pool of threads
* @author [email protected]
*/
public class ThreadPool extends Object {
private ObjectFIFO idleWorkers ;
private ThreadPoolWorker [] workerList;
public ThreadPool(int numberOfThreads) {
// make sure that it's at least one
numberOfThreads = Math.max(1, numberOfThreads);
idleWorkers = new ObjectFIFO(numberOfThreads);
workerList = new ThreadPoolWorker[numberOfThreads];
for ( int i = 0; i < workerList .length; i++ ) {
workerList[i] = new ThreadPoolWorker(idleWorkers);
}
}
public void execute(Runnable target ) throws InterruptedException {
// block (forever) until a worker is available
ThreadPoolWorker worker = (ThreadPoolWorker) idleWorkers .remove();
worker.process(target);
}
public void stopRequestIdleWorkers() {
try {
Object [] idle = idleWorkers .removeAll ();
for ( int i = 0; i < idle.length ; i++ ) {
( (ThreadPoolWorker) idle[i] ).stopRequest();
}
}
catch ( InterruptedException x ) {
Thread .currentThread().interrupt(); // re-assert
}
}
public void stopRequestAllWorkers() {
// Stop the idle one's first since that won't interfere with anything
// productive.
stopRequestIdleWorkers();
// give the idle workers a quick chance to die
try
{ Thread.sleep(250); } catch ( InterruptedException x )
{ }
// Step through the list of ALL workers that are still alive.
for ( int i = 0; i < workerList .length; i++ ) {
if ( workerList[i].isAlive() ) {
workerList[i].stopRequest();
}
}
}
}
/*
* uniqueID.java
*
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import java.lang.*;
/**
* Builds a class returning uniqueID's (based on system time and secured through syncronisiation)
* @author [email protected]
*/
public class UniqueID {
static long current = System.currentTimeMillis();
Autor: Thomas Schädler
90
Anhang A: Quelltext <xmlizer> configurator
/**
* Returns a uniqueID as long
*/
static public synchronized long getLong() {
return current++;
}
/**
* Returns a uniqueID as String
*/
static public synchronized String get() {
String str = new String();
str = str.valueOf(current++);
return str;
}
}
/*
* HTMLBrowser.java
*
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import
import
import
import
import
import
import
import
java.awt.*;
java.net.URL;
java.net.MalformedURLException;
java.io.*;
java.util.Vector ;
javax.swing .text.*;
javax.swing .event.*;
javax.swing .*;
/**
* Is a simple HTML Browser
* @author [email protected]
*/
public class HTMLBrowser extends javax.swing .JScrollPane implements HyperlinkListener {
JEditorPane html;
class PageLoader implements Runnable {
PageLoader (URL u, Cursor c ) {
url = u;
cursor = c;
}
public void run() {
if(url == null) {
// restore the original cursor
html.setCursor(cursor);
// automatic validation is activated.
Container parent = html.getParent ();
parent.repaint();
}
else {
Document doc = html.getDocument();
try {
html.setPage(url);
}
catch(IOException ioe) {
html.setDocument(doc);
}
finally {
url = null;
SwingUtilities .invokeLater(this);
}
}
} //end run
URL url;
Cursor cursor;
} //end class pageloader
public HTMLBrowser() {
html = new JEditorPane();
html.setEditable(false);
html.addHyperlinkListener(this);
JViewport vp = getViewport ();
vp.add(html);
} //end htmlbrowser
public HTMLBrowser(URL url) {
try {
html = new JEditorPane (url);
html.setEditable (false );
html.addHyperlinkListener(this);
JViewport vp = getViewport();
vp.add(html);
}
catch(MalformedURLException e) {
System .out.println("Malformed URL: " + e);
Autor: Thomas Schädler
91
Anhang A: Quelltext <xmlizer> configurator
}
catch(IOException e) {
System .out.println("IOException: " + e);
}
} //end htmlbrowser
public void hyperlinkUpdate(HyperlinkEvent e) {
if(e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
linkActivated(e.getURL ());
}
} //end hyperlinkupdate
protected void linkActivated(URL u) {
Cursor c = html.getCursor();
Cursor waitCursor = Cursor .getPredefinedCursor (Cursor.WAIT_CURSOR);
html.setCursor(waitCursor);
SwingUtilities.invokeLater (new PageLoader (u, c));
} //end linkactivated
} //end class htmlbroser/*
* ThreadPoolWorker.java
*
* Created on 19. Mai 2002, 20:28
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
/**
* A worker thread which is in the threadpool
* @author [email protected]
*/
public class ThreadPoolWorker extends Object {
private static int nextWorkerID = 0;
private ObjectFIFO idleWorkers ;
private int workerID;
private ObjectFIFO handoffBox;
private Thread internalThread;
private volatile boolean noStopRequested ;
public ThreadPoolWorker(ObjectFIFO idleWorkers) {
this.idleWorkers = idleWorkers;
workerID = getNextWo rkerID ();
handoffBox = new ObjectFIFO(1); // only one slot
// just before returning, the thread should be created and started.
noStopRequested = true;
Runnable r = new Runnable() {
public void run() {
try {
runWork();
} catch ( Exception x ) {
// in case ANY exception slips through
x.printStackTrace();
}
}
};
internalThread = new Thread(r);
internalThread.start ();
}
public static synchronized int getNextWorkerID() {
// notice: synchronized at the class level to ensure uniqueness
int id = nextWorkerID;
nextWorkerID++;
return id;
}
public void process(Runnable target ) throws InterruptedException {
handoffBox .add(target);
}
private void runWork() {
while ( noStopRequested ) {
try {
//System.out.println("workerID=" + workerID + ", ready for work");
// Worker is ready work. This will never block since the
// idleWorker FIFO queue has enough capacity for all of
// the workers.
idleWorkers.add(this);
// wait here until the server puts a request into the box
Runnable r = (Runnable) handoffBox.remove();
//System.out.println("workerID=" + workerID + ", starting execution of new Runnable: " + r);
runIt(r); // catches all exceptions
Autor: Thomas Schädler
92
Anhang A: Quelltext <xmlizer> configurator
}
catch ( InterruptedException x ) {
Thread.currentThread().interrupt(); // re-assert
}
}
}
private void runIt(Runnable r) {
try {
r.run();
}
catch ( Exception runex ) {
// catch any and all exceptions
System .err.println("Uncaught exception fell through from run()");
runex.printStackTrace();
}
finally {
// Clear the interrupted flag (in case it comes back set)
// so that if the loop goes again, the
// handoffBox.remove() does not mistakenly throw
// an InterruptedException.
Thread .interrupted();
}
}
public void stopRequest() {
//System.out.println("workerID=" + workerID + ", stopRequest() received.");
noStopRequested = false;
internalThread.interrupt();
}
public boolean isAlive() {
return internalThread.isAlive();
}
}
/*
* Properties.java
*
* Created on 8. April 2002, 09:58
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ----------------------------------------- ----------------------------------*/
package configurator;
/**
* Just a helper class for compiling all properties in a string
* @author [email protected]
* @version
*/
public class Properties {
private String s = new String("");
private configurator config;
/**
* Default constructor
*/
public Properties(configurator conf ) {
config = conf;
}
/**
* Returns a already formated string containing all properties
*/
public String getProps() {
s = s.concat("\n<xmlizer>-Home = ");
s = s.concat(config.getHomeBase ());
s = s.concat("\n<xmlizer>-Projects = ");
s = s.concat(config.getProjectBase());
s = s.concat("\nOS Name = ");
s = s.concat(System.getPro perty ("os.name" ));
s = s.concat("\nOS Version = ");
s = s.concat(System.getProperty ("os.version"));
s = s.concat("\nOS Architecture = ");
s = s.concat(System.getProperty ("os.arch" ));
s = s.concat("\nJAVA Version = ");
s = s.concat(System.getProperty ("java.version" ));
s = s.concat("\nJAVA Vendor = " );
s = s.concat(System.getProperty ("java.vendor"));
s = s.concat("\nJAVA Vendor URL = ");
s = s.concat(System.getProperty ("java.vendor.url"));
s = s.concat("\nJAVA Home = ");
s = s.concat(System.getProperty ("java.home"));
s = s.concat("\nJAVA VM Version = ");
s = s.concat(System.getProperty ("java.vm.version"));
s = s.concat("\nJAVA VM Vendor = ");
s = s.concat(System.getProperty ("java.vm.vendor"));
s = s.concat("\nJAVA VM Name = ");
s = s.concat(System.getProperty ("java.vm.name" ));
s = s.concat("\nUSER Home = ");
s = s.concat(System.getProperty ("user.home"));
s = s.concat("\nUSER Name = ");
s = s.concat(System.getProperty ("user.name"));
Autor: Thomas Schädler
93
Anhang A: Quelltext <xmlizer> configurator
return s;
}
} //end class properties
/*
* ObjectFIFO.java
*
* Created on 19. Mai 2002, 20:28
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
/**
* Is a simple FIFO of Objects
* @author [email protected]
*/
public class ObjectFIFO extends Object {
private Object [] queue;
private int capacity;
private int size;
private int head;
private int tail;
public ObjectFIFO(int cap) {
capacity = ( cap > 0 ) ? cap : 1; // at least 1
queue = new Object[capacity];
head = 0;
tail = 0;
size = 0;
}
public int getCapacity() {
return capacity ;
}
public synchronized int getSize() {
return size;
}
public synchronized boolean isEmpty() {
return ( size == 0 );
}
public synchronized boolean isFull() {
return ( size == capacity );
}
public synchronized void add(Object obj)
throws InterruptedException {
waitWhileFull();
queue[head] = obj;
head = ( head + 1 ) % capacity;
size++;
notifyAll(); // let any waiting threads know about change
}
public synchronized void addEach(Object[] list)
throws InterruptedException {
//
// You might want to code a more efficient
// implementation here ... (see ByteFIFO.java)
//
for ( int i = 0; i < list.length; i++ ) {
add(list[i]);
}
}
public synchronized Object remove()
throws InterruptedException {
waitWhileEmpty();
Object obj = queue[tail];
// don't block GC by keeping unnecessary reference
queue[tail] = null;
tail = ( tail + 1 ) % capacity;
size--;
notifyAll(); // let any waiting threads know about change
return obj;
}
Autor: Thomas Schädler
94
Anhang A: Quelltext <xmlizer> configurator
public synchronized Object[] removeAll()
throws InterruptedException {
//
// You might want to code a more efficient
// implementation here ... (see ByteFIFO.java)
//
Object[] list = new Object [size]; // use the current size
for ( int i = 0; i < list.length; i++ ) {
list[i] = remove ();
}
// if FIFO was empty, a zero-length array is returned
return list;
}
public synchronized Object[] removeAtLeastOne ()
throws InterruptedException {
waitWhileEmpty(); // wait for a least one to be in FIFO
return removeAll();
}
public synchronized boolean waitUntilEmpty(long msTimeout)
throws InterruptedException {
if ( msTimeout == 0L ) {
waitUntilEmpty(); // use other method
return true;
}
// wait only for the specified amount of time
long endTime = System.currentTimeMillis() + msTimeout;
long msRemaining = msTimeout;
while ( !isEmpty() && ( msRemaining > 0L ) ) {
wait(msRemaining );
msRemaining = endTime - System.currentTimeMillis();
}
// May have timed out, or may have met condition,
// calc return value.
return isEmpty();
}
public synchronized void waitUntilEmpty()
throws InterruptedException {
while ( !isEmpty() ) {
wait();
}
}
public synchronized void waitWhileEmpty()
throws InterruptedException {
while ( isEmpty() ) {
wait();
}
}
public synchronized void waitUntilFull()
throws InterruptedException {
while ( !isFull () ) {
wait();
}
}
public synchronized void waitWhileFull()
throws InterruptedException {
while ( isFull() ) {
wait();
}
}
}
/*
* dataItem.java
*
* Created on 18. April 2002, 20:20
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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 lat er version.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import java.lang.*;
Autor: Thomas Schädler
95
Anhang A: Quelltext <xmlizer> configurator
/*
* This class representates a multi-purpose item consiting of the following stuff
*
* - key
(String)
* - value
(String)
* - description
(St ring)
*
* -> ... every variable has its get ans set methods
* @author [email protected]
*/
public class dataItem {
private String tkey ;
private String tdescription;
private String tvalue;
/**
* Constructors for a new projectdataItem
* -> holds:
* String key
* String value
* String description
*/
public dataItem(String key,String value,String description) {
tkey = key;
tvalue = value;
tdescription = description ;
}
public dataItem(String key,String value) {
tkey = key;
tvalue = value;
tdescription = new String();
}
public dataItem(String key) {
tkey = key;
tvalue = new String();
tdescription = new String();
}
public dataItem() {
tkey = new String();
tvalue = new String();
tdescription = new String();
}
//STRING REPRESENTATION
//----------------------------------------------------------------------------------------------/**
* By default show the key as String
*/
public String toString() {
return "\ndataItem : key
= " + tkey + "\n"
+ "
: value
= " + tvalue + "\n"
+ "
: description = " + tdescription + "\n";
}
//GET AND SET METHODS
//----------------------------------------------------------------------------------------------/**
* Returns the key of the item
*/
public String getKey() {
return tkey;
}
/**
* Get the description of the item
*/
public String getDescription() {
return tdescription;
}
/**
* Get the value of the item
*/
public String getValue() {
return tvalue;
}
/**
* Set a new key
*/
public void setKey(String s) {
tkey = s;
}
/**
* Set a new description
*/
public void setDescription(String s ) {
tdescription = s;
}
/*
* Set a new value
*/
public void setValue(String s) {
tvalue = s;
}
}
/*
*
*
*
*
*
*
dataItem.java
But more important: This class contains different methods for handling
database connections
Created on 18. April 2002, 20:20
Autor: Thomas Schädler
96
Anhang A: Quelltext <xmlizer> configurator
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import
import
import
import
java.sql.*;
java.util.*;
javax.swing .*;
javax.swing .table.*;
/**
* This class representates a database item consisting of the following stuff
* with a get and set method each
*
* String name
* String driver
* String url
* String timeout
* String username
* String password
*
* -> ... every variable has its get an s set methods
* @author [email protected]
*/
public class dbItem {
private String tname;
private String tdriver;
private String turl ;
private String ttimeout;
private int ttimeoutint;
private int tstart = 0;
private int chunkSize = 25;
private boolean hasLimit = true;
private String tusername ;
private String tpassword ;
private boolean isConnected = false ;
private Connection connection = null;
private Vector tableList = null;
private boolean stopNOW = false;
private Hashtable navigator;
private String getCountSQL = new String();
private String lastSQL = new String ();
private Vector selectedTables = new Vector();
private String outputType = "simple";
//little global helpers
private SQLStatement lastStatement = null;
//CONSTRUCTORS
//----------------------------------------------------------------------------------------------/**
* Constructors for a new dbItem
* -> holds:
* String nam e
* String driver
* String url
* String timeout
* int timeoutint
* String username
* String password
*/
public dbItem(String name,String driver,String url ,String timeout ,String username,String password) {
this.tname = name;
this.tdriver = driver;
this.turl = url;
this.ttimeout = timeout;
this.ttimeoutint = ConvertString2int (timeout);
this.tusername = username;
this.tpassword = password;
}
public dbItem(String name,String driver,String url ,String timeout ,String username) {
this.tname = name;
this.tdriver = driver;
this.turl = url;
this.ttimeout = timeout;
this.ttimeoutint = ConvertString2int (timeout);
this.tusername = username;
this.tpassword = new String();
}
public dbItem(String name,String driver,String url ,String timeout ) {
this.tname = name;
this.tdriver = driver;
this.turl = url;
this.ttimeout = timeout;
this.ttimeoutint = ConvertString2int (timeout);
this.tusername = new String();
this.tpassword = new String();
}
public dbItem(String name,String driver,String url ) {
this.tname = name;
Autor: Thomas Schädler
97
Anhang A: Quelltext <xmlizer> configurator
this.tdriver = driver;
this.turl = url;
this.ttimeout = new String ();
this.tusername = new String();
this.tpassword = new String();
}
public dbItem(String name,String driver) {
this.tname = name;
this.tdriver = driver;
this.turl = new String();
this.ttimeout = new String ();
this.tusername = new String();
this.tpassword = new String();
}
public dbItem(String name) {
this.tname = name;
this.tdriver = new String();
this.turl = new String();
this.ttimeout = new String ();
this.tusername = new String();
this.tpassword = new String();
}
public dbItem() {
this.tname = new String();
this.tdriver = new String();
this.turl = new String();
this.ttimeout = new String ();
this.tusername = new String();
this.tpassword = new String();
}
//STRING REPRESENTATION
//------------------------------------------------------------------------- ---------------------/**
* By default show the key as String
*/
public String toString() {
return tname;
}
//HELPER METHODS
//----------------------------------------------------------------------------------------------public static int ConvertString2int (String string) {
try {
Integer to = new Integer(string);
return to.intValue();
}
catch(NumberFormatException ex) {
return 25;
//failsafe
}
}
public static String Convertint2String(int integer) {
try {
Integer to = new Integer(integer);
return to.toString();
}
catch(NumberFormatException ex) {
return "25";
//failsafe
}
}
//THREAD ABORT FLAG MANAGEMENT
//----------------------------------------------------------------------------------------------public void halt() {
this.stopNOW = true;
}
private void goon() {
this.stopNOW = false ;
}
//LIMITERS
//----------------------------------------------------------------------------------------------public String getLastSQL () {
return this.lastSQL;
}
public void clearLastStatement () {
this.lastStatement = null;
}
public SQLStatement getLastStatement() {
return this.lastStatement;
}
public void updateLastSQLSQL(String s) {
if (this.lastStatement != null) {
this.lastStatement.setSQL(s);
}
}
public void nextChunk() {
setLimitStart(tstart + chunkSize);
}
public void lastChunk() {
setLimitStart(Math.max(tstart - chunkSize ,0));
}
private void setLimitStart(int i) {
this.tstart = i;
Autor: Thomas Schädler
98
Anhang A: Quelltext <xmlizer> configurator
}
public void resetLimit() {
setLimitStart(0);
}
public void setChunkSize (int i) {
this.chunkSize = i;
}
public int getChunkSize() {
return this.chunkSize;
}
/**
* Returns the limit as appendable SQL String
* e.g: " LIMIT 0,25", per default if never set
*/
private String getLimit() {
return new String(" LIMIT " + tstart + "," + chunkSize);
}
/**
* Enables/Disables the automatic limit
*/
public void setLimit(boolean bool) {
this.hasLimit = bool;
}
public boolean hasLimit() {
return hasLimit ;
}
public void setCountSQL(String s) {
this.getCountSQL = s;
}
public String getCountSQL() {
return getCountSQL;
}
//GET AND SET METHODS
//----------------------------------------------------------------------------------------------public Hashtable getNavigator() {
return navigator;
}
/**
* Get the name of the dbitem
*/
public String getName() {
return this.tname;
}
/**
* Get the driver of the dbitem
*/
public String getDriver() {
return this.tdriver;
}
/**
* Get the url of the dbitem
*/
public String getUrl() {
return this.turl;
}
/**
* Get the timeout of the dbitem
*/
public String getTimeout () {
return this.ttimeout ;
}
public int getTimeoutAsInt() {
return ttimeoutint;
}
/**
* Get the username of the dbitem
*/
public String getUsername() {
return this.tusername;
}
/**
* Get the password of the dbitem
*/
public String getPassword() {
return this.tpassword;
}
/**
* Set the name of the dbitem
*/
public void setName(String s) {
this.tname = s;
}
/**
* Set the driver of the dbitem
*/
public void setDriver(String s ) {
this.tdriver = s;
Autor: Thomas Schädler
99
Anhang A: Quelltext <xmlizer> configurator
}
/**
* Set the url of the dbitem
*/
public void setUrl(String s) {
this.turl = s;
}
/**
* Set the timeout of the dbitem
*/
public void setTimeout(String s) {
this.ttimeout = s;
this.ttimeoutint = ConvertString2int (s);
}
/**
* Set the username of the dbitem
*/
public void setUsername(String s) {
this.tusername = s;
}
/**
* Set the password of the dbitem
*/
public void setPassword(String s) {
this.tpassword = s;
}
//SELECTED TABLES FOR SMDBE MAPPING AND EXPORT AND FOR THE OUTPUT TYPE
//----------------------------------------------------------------------------------------------public void SMDBEsetSelectedTables(Vector v) {
this.selectedTables = v;
}
public Vector SMDBEgetSelectedTables() {
return this.selectedTables ;
}
public void SMDBEselectTable(String tablename ) {
if (!this.selectedTables.contains(tablename)) {
this.selectedTables.add(tablename);
}
}
public void SMDBEdeselectTable (String tablename) {
if (this.selectedTab les.contains(tablename)) {
this.selectedTables.remove(tablename);
}
}
public void SMDBEsetOutputType (String type) {
this.outputType = type;
}
public String SMDBEgetOutputType() {
return this.outputType;
}
//DATABASE CONNECTION METHODS
//----------------------------------------------------------------------------------------------public boolean isConnected() {
return isConnected;
}
public void closeConnection() {
this.tableList = null;
if (isConnected ) {
try {
isConnected = false;
connection.close();
}
catch(Exception ex) {
//ok
}
}
}
synchronized public Connection getConnection() throws Exception {
if (!isConnected) {
makeConnection();
}
while(!isConnected) {
if (stopNOW)
{ throw new Exception("Could not connect to database " + tname + "."); }
}
return connection;
}
/**
* Tries to create connection
* in the thread in order not to "hang" the application
*/
synchronized private void makeConnection () throws Exception {
try {
Class.forName(tdriver);
DriverManager.setLoginTimeout(ttimeoutint);
if(tusername.equalsIgnoreCase(new String())) {
connection = DriverManager.getConnection(turl);
isConnected = true;
Autor: Thomas Schädler
100
Anhang A: Quelltext <xmlizer> configurator
//System.out.println("Connection to database " + tname + " successful!");
}
else {
connection = DriverManager.getConnection(turl,tusername,decryptSecurePassword(tpassword));
isConnected = true;
//System.out.println("Connection to database " + tname + " successful!");
}
}
catch(Exception ex) {
//System.out.println("Connection " + tname + " not possible!");
throw new Exception("Could not establish connection " + tname + ".");
}
}
//DATABASE ACCESS METHODS
//----------------------------------------------------------------------------------------------/**
* Returns a Vectro of all tables in for this DB as listItems where
* each listItem has a name, the number or rows and a boolean flag if it should be selected
*/
public Vector getTableList() throws Exception {
if(tableList == null) {
Vector result = new Vector();
ResultSet rs = getConnection().getMetaData ().getTables(null, null, null, new String[]{"TABLE"});
Statement stmt = getConnection().createStatement();
while(rs.next()) {
//table name
String res = rs.getString("TABLE_NAME" );
//rows
int rows = 0;
ResultSet srs = stmt.executeQuery ("SELECT COUNT(*) FROM " + res);
if(srs.next()) {
rows = srs.getInt(1);
}
//mark the listitems as selected or not depending on read in data
boolean isThisSelected = false;
if (selectedTables != null && selected Tables.size() > 0) {
if (selectedTables.contains(res)) {
isThisSelected = true;
}
}
listItem item = new listItem (res,rows,isThisSelected);
result.add(item);
}
tableList = result;
}
return tableList;
}
/**
* Returns a JTable containing the data of the specified SQL statement
* The table has a sorter and a clickable header to start the sorting.
*/
public JTable getQueryAsJTable (String sqlQuery) throws Exception {
Hashtable theTable = query (sqlQuery);
final String data[][] = (String [][]) theTable.get("table");
final int rows = ((Integer )theTable.get("rows" )).intValue();
final int cols = ((Integer )theTable.get("cols" )).intValue();
final Vector columnnames = (Vector)theTable.get("columnlabels");
final Vector columntypes = (Vector)theTable.get("columntypes" );
//buid the lastStatement
Vector lastColumns = new Vector ();
for (Enumeration e = columnnames.elements (); e.hasMoreElements();) {
String curr = (String)e.nextElement();
lastColumns .add(curr);
}
//build the lastTypes -> Vector
Vector lastTypes = new Vector();
for (Enumeration e = columntypes.elements (); e.hasMoreElements();) {
String curr = (String)e.nextElement();
lastTypes.add(curr);
}
this.lastStatement = new SQLStatement(this.getName(),sqlQuery ,lastColumns,lastTypes,rows);
TableModel dataModel = new AbstractTableModel() {
public int getColumnCount() {
return cols;
}
public int getRowCount () {
return rows;
}
public Object getValueAt(int row,int col) {
return data[col][row];
}
public String getColumnName (int col) {
String label = (String)columnnames.get(col);
return label ;
}
};
TableSorter sorter = new TableSorter (dataModel );
JTable dbTable = new JTable(sorter);
sorter.addMouseListenerToHeaderInTable(dbTable);
return dbTable;
}
private String checkSQL(String sql) {
//System.out.println("Checking SQL for limit-tag in: " + sql);
StringBuffer countSQL = new StringBuffer("SELECT COUNT(*)");
boolean hadFrom = false;
Autor: Thomas Schädler
101
Anhang A: Quelltext <xmlizer> configurator
if (this.hasLimit) {
boolean theLimit = false;
//FIXME limit kann auch ein tablename sein!!! besserer SQL check
StringTokenizer tokenizer = new StringTokenizer (sql);
while (tokenizer .hasMoreTokens()) {
String currentToken = tokenizer.nextToken();
if (hadFrom || currentToken.equalsIgnoreCase(new String("from"))) {
hadFrom = true;
countSQL .append(" ");
countSQL .append(currentToken);
}
if (currentToken.equalsIgnoreCase (new String("limit"))) {
theLimit = true;
}
}
setCountSQL (countSQL.toString());
if (!theLimit) {
return sql + getLimit();
}
else {
setLimit(false);
return sql;
}
}
else {
return sql;
}
}
/**
* Runs a specified SQL Query on the DB connection
* and returns a Hashtable containing the different data to preceed
* Note: allways use this function to query the DB!
*/
synchronized public Hashtable query (String sq lQuery) throws Exception {
lastSQL = sqlQuery;
Statement stmt = getConnection().createStatement();
int MaxRowCount = 0;
if (hasLimit) {
sqlQuery = checkSQL(sqlQuery);
String countSQL = getCountSQL();
ResultSet srs = stmt.executeQuery(countSQL );
if(srs.next()) {
MaxRowCount = srs.getInt(1);
}
}
//System.out.println("DB QUERY: " + sqlQuery);
ResultSet rs = stmt.executeQuery(sqlQuery );
ResultSetMetaData rsmd = rs.getMetaData();
int cols = rsmd.getColumnCount();
int rowNumber = 0;
Vector vector = new Vector (5, 5);
Vector collables = new Vector(); //of String
Vector colltypes = new Vector(); //of String
Vector collsizes = new Vector(); //of Integer
Vector collnames = new Vector(); //of String
//build collumnvector (with the names of the columns)
for(int i=1;i<=cols;i++) {
if (stopNOW)
{ goon(); throw new Exception("Aborted by user."); }
collables.add(rsmd.getColumnLabel(i));
colltypes.add(rsmd.getColumnTypeName(i));
collsizes.add(new Integer(rsmd.getColumnDisplay Size(i)));
collnames.add(rsmd.getColumnName (i));
}
//build rowvector
while(rs.next()) {
if (stopNOW)
{ goon(); throw new Exception("Aborted by user."); }
rowNumber++;
for(int i=1;i<=cols;i++) {
if (stopNOW)
{ goon(); throw new Exception("Aborted by user." ); }
vector.add(rs.getString (i));
}
}
int rows = rowNumber ;
if (MaxRowCount == 0)
{ MaxRowCount = rows; }
String info[][] = new String[cols][rows];
vector.trimToSize();
int row = 0;
int col = 0;
for(int i=0;i<vector .size();i++) {
if (stopNOW)
{ goon(); throw new Exception("Aborted by user."); }
try {
info[col][row] = vector .get(i).toString();
}
catch(NullPointerException ex) {
info[col][row] = "";
}
if(col+1 == cols) {
col = -1;
row++;
}
col++;
Autor: Thomas Schädler
102
Anhang A: Quelltext <xmlizer> configurator
}
Hashtable navData = new Hashtable();
if (hasLimit) {
navData.put("first",Convertint2String (this.tstart+1));
if ((this.tstart + chunkSize) > this.tstart + rows) {
navData.put("last" ,Convertint2String(this.tstart + rows));
}
else {
navData.put("last" ,Convertint2String(this.tstart + chunkSize));
}
navData.put("max",Convertint2String(MaxRowCount ));
if (MaxRowCount > this.tstart + chunkSize) {
navData.put("hasNext",new Boolean(true));
}
else {
navData.put("hasNext",new Boolean (false));
}
if (this.tstart != 0) {
navData.put("hasLast",new Boolean(true));
}
else {
navData.put("hasLast",new Boolean(false));
}
}
else {
navData.put("first",Convertint2String (this.tstart+1));
navData.put("last",Convertint2String(rows));
navData.put("max",Convertint2String(rows));
navData.put("hasNext",new Boolean(false));
navData.put("hasLast",new Boolean(false));
}
this.navigator = navData;
Hashtable result = new Hashtable();
result.put("table",info);
result.put("columnname",collnames);
result.put("columnsize",collsizes);
result.put("columnlabels",collables);
result.put("columntypes",colltypes);
result.put("rows",new Integer(rows));
result.put("cols",new Integer(cols));
return result;
}
private Statement getStatement (int limit ) throws Exception {
Statement stmt = getConnection().createStatement();
if (limit != 0) {
stmt.setFetchSize(limit);
}
return stmt;
}
/**
* Runs a specified SQL Query on the DB connection but in silent mode
* Silent mode: just a clean query, no other data changed (for background and long running threads)
* Attention: no metadata and paging available in this mode and it does not care about limit checking etc...
* and returns a Hashtable containing the different data to preceed
* Note: allways use this function to query the DB in clean mode (without changing something in this class!
*/
synchronized public Hashtable querySilent(String sqlQuery) throws Exception {
return querySilentWithLimit(sqlQuery ,0);
}
/**
* Runs a specified SQL Query on the DB connection but in silent mode with rowlimit
* Silent mode: just a clean query, no other data changed (for background and long running threads)
* Attention: no metadata and paging available in this mode and it does not care about limit checking etc...
* and returns a Hashtable containing the different data to preceed
* Note: allways use this function to query the DB in clean mode (without changing something in this class!
*/
synchronized public Hashtable querySilentWithLimit (String sqlQuery,int limit) throws Exception {
Statement stmt = getStatement(limit);
//System.out.println("DB QUERY (SILENT): " + sqlQuery);
ResultSet rs = stmt.executeQuery(sqlQuery );
ResultSetMetaData rsmd = rs.getMetaData();
int cols = rsmd.getColumnCount();
int rowNumber = 0;
Vector vector = new Vector (5, 5);
Vector collables = new Vector(); //of String
Vector colltypes = new Vector(); //of String
Vector collsizes = new Vector(); //of Integer
Vector collnames = new Vector(); //of String
//build collumnvector (with the names of the columns)
for(int i=1;i<=cols;i++) {
if (stopNOW)
{ goon(); throw new Exception("Aborted by user."); }
collables.add(rsmd.getColumnLabel(i));
colltypes.add(rsmd.getColumnTypeName(i));
collsizes.add(new Integer(rsmd.getColumnDisplaySize(i)));
collnames.add(rsmd.getColumnName (i));
}
//build rowvector
while(rs.next()) {
if (stopNOW)
{ goon(); throw new Exception("Aborted by user."); }
rowNumber++;
for(int i=1;i<=cols;i++) {
if (stopNOW)
{ goon(); throw new Exception("Aborted by user." ); }
vector.add(rs.getString (i));
Autor: Thomas Schädler
103
Anhang A: Quelltext <xmlizer> configurator
}
}
int rows = rowNumber ;
String info[][] = new String[cols][rows];
vector.trimToSize();
int row = 0;
int col = 0;
for(int i=0;i<vector .size();i++) {
if (stopNOW)
{ goon(); throw new Exception("Aborted by user."); }
try {
info[col][row] = vector .get(i).toString();
}
catch(NullPointerException ex) {
info[col][row] = "";
}
if(col+1 == cols) {
col = -1;
row++;
}
col++;
}
Hashtable result = new Hashtable();
result.put("table",info);
result.put("columnname",collnames);
result.put("columnsize",collsizes);
result.put("columnlabels",collables);
result.put("columntypes",colltypes);
result.put("rows",new Integer(rows));
result.put("cols",new Integer(cols));
return result;
}
//QUASI-SECURE PASSWORD HANDLING
//----------------------------------------------------------------------------------------------public static String decryptSecurePassword(String encrypted) {
//decrpyt
StringBuffer decrypted = new StringBuffer ();
char[] sec_char = new char[]{'x','m','l','i','z','e','r'};
int inkr = 0;
char aktual;
StringBuffer current = new StringBuffer();
for (int j=0;j<encrypted.length ();j++) {
aktual = encrypted.charAt(j);
if (aktual == ':') {
if (inkr<sec_char.length-1){inkr++;}else{inkr=0;}
String gotcha = current.toString();
current = new StringBuffer(); // renew buffer
Integer goti = new Integer(gotcha );
int gotint = goti.intValue();
int decr = gotint ^ sec_char [inkr];
decrypted.append((char)decr);
}
else {
current.append(aktual);
}
}
return decrypted.toString();
}
}/*
* xmlItem.java
*
* Created on 16. May 2002, 20:20
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import java.io.*;
import java.util.*;
/**
* This class representates a xml file item consisting of the following stuff
* with a get and set method each
*
* String name
* String file
*
* -> ... every variable has its get ans set methods
*
* But more important: This class contains d ifferent methods for handling
* xml file access and manipulation
* @author [email protected]
*/
public class xmlItem {
private String tname;
Autor: Thomas Schädler
104
Anhang A: Quelltext <xmlizer> configurator
private String tfile;
//CONSTRUCTORS
//----------------------------------------------------------------------------------------------/**
* Constructors for a new xmlItem
* -> holds:
* String name
* String file
*/
public xmlItem(String name,String file) {
this.tname = name;
this.tfile = file;
}
public xmlItem(String name) {
this.tname = name;
this.tfile = new String();
}
public xmlItem() {
this.tname = new String();
this.tname = new String();
}
//STRING REPRESENTATION
//----------------------------------------------------------------------------------------------/**
* By default show the key as String
*/
public String toString() {
return this.tname;
}
//HELPER METHODS
//----------------------------------------------------------------------------------------------//GET AND SET METHODS
//----------------------------------------------------------------------------------------------/**
* Get the name of the dbitem
*/
public String getName() {
return this.tname;
}
/**
* Get the driver of the dbitem
*/
public String getFile() {
return this.tfile;
}
/**
* Set the name of the dbitem
*/
public void setName(String s) {
this.tname = s;
}
/**
* Set the driver of the dbitem
*/
public void setFile(String s) {
this.tfile = s;
}
}
/*
* setupWindow.java
*
* In your module you can easily add mo re schemas or databases,
* only the needed ones are loaded at setup
*
* Created on 11. April 2002, 00:20
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import
import
import
import
import
import
import
import
import
import
import
java.sql.*;
java.util.*;
java.lang.*;
javax.swing .*;
java.io.*;
java.lang.reflect.*;
org.jdom.*;
org.jdom.input.SAXBuilder;
org.jdom.output.XMLOutputter;
org.w3c.dom.Document;
org.xml.sax.SAXException;
Autor: Thomas Schädler
105
Anhang A: Quelltext <xmlizer> configurator
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
import org.apache.xerces.parsers.DOMParser;
/**
* The setupwindows loads all neccessary stuff:
*
* - a database connection
* - an xml schema
* - a module to load
* - a projectname
*
* and finally starts the module
* @author [email protected]
*/
public class setupWindow extends MyInternalFrame {
private configurator mother;
private String ID;
private Vector moduleList;
private Vector databaseList;
private Vector xmlList;
private boolean isNewSetup = true;
private boolean isLoading = true;
//backup vectors
private Vector oldXML;
private Vector oldDB;
//threads
private Thread connecterThread = null;
//colors
private final java.awt.Color COLOR_RED = java.awt.Color .red;
private java.awt.Color COLOR_DEFAULT = new java.awt.Color(102,102,153);
//include resolve stuff
private String temporary_name = new String();
private org.jdom.Document temporary = null;
private Vector includepaths = new Vector ();
/**
* Creates new form setupWindow
*/
public setupWindow(configurator mainProgram,String uid) {
this.mother = mainProgram;
this.ID = uid;
this.moduleList = mother.getAvailableModules();
//init
this.databaseList = mother .getProjectData ().getDB();
this.xmlList = mother.getProjectData ().getXML();
//backup
try {
this.oldXML = (Vector)((Vector)mother .getProjectData ().getXML()).clone();
this.oldDB = (Vector)((Vector)mother.getProjectData().getDB()).clone();
}
catch(Exception ex) {
this.mother .getLog().addDebug(ex);
}
initComponents();
//remove the 2 panels
databasePanel.remove (dbPanel);
//databasePanel.add(dbPanel, java.awt.BorderLayout.CENTER);
xmlPanel.remove (xmlsubPanel); //xmlPanel.add(xmlsubPanel, java.awt.BorderLayout.CENTER);
loadCurrentProjectData();
doCheck();
this.isLoading = false;
convertButton.setVisible(false);
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
private void initComponents() {//GEN-BEGIN:initComponents
backPanel = new javax.swing.JPanel();
mainTabbedPane = new javax .swing.JTabbedPane();
welcomePanel = new javax.swing.JPanel();
welcomeTextArea = new javax.swing.JTextArea();
buttonPanel = new javax.swing.JPanel ();
subPanel = new javax .swing .JPanel();
projectnameLabel = new javax.swing.JLabel ();
projectnameTextField = new javax.swing.JTextField();
mappingmoduleLabel = new javax.swing .JLabel();
mappingmoduleComboBox = new javax.swing.JComboBox(moduleList);
mappingmoduleComboBox.setSelectedIndex(0);
moduleInfoButton = new javax.swing.JButton();
sub2Panel = new javax.swing.JPanel();
dbLabel = new javax.swing.JLabel();
db2Label = new javax .swing .JLabel();
finishButton = new javax.swing.JButton();
welcome2Label = new javax.swing .JLabel();
welcomeLabel = new javax.swing.JLabel();
databasePanel = new javax.swing .JPanel();
dboutputTextArea = new javax.swing.JTextArea();
dbListPanel = new javax.swing.JPanel ();
dbListLabel = new javax.swing.JLabel ();
dbListComboBox = new javax .swing.JComboBox(databaseList);
addDBButton = new javax.swing.JButton();
removeDBButton = new javax .swing.JButton();
dbInfoButton = new javax.swing.JButton();
dbPanel = new javax.swing.JPanel();
dbdriverLabel = new javax.swing .JLabel();
dbdriverTextField = new javax.swing.JTextField ();
dburlLabel = new javax.swing.JLabel();
Autor: Thomas Schädler
106
Anhang A: Quelltext <xmlizer> configurator
dburlTextField = new javax .swing.JTextFie ld();
drivertestButton = new javax.swing.JButton();
dbtimeoutLabel = new javax .swing.JLabel();
dbusernameLabel = new javax.swing.JLabel();
dbusernameTextField = new javax .swing.JTextField();
dbpasswordLabel = new javax.swing.JLabel();
dbpasswordTextField = new javax .swing.JPasswordField();
connectButton = new javax.swing .JButton();
dbtimeoutTextField = new javax.swing .JTextField();
connameTextField = new javax.swing.JTextField();
connameLabel = new javax.swing.JLabel();
addNewDBButton = new javax .swing.JButton();
jLabel4 = new javax.swing.JLabel();
dbBrowseButton = new javax .swing.JButton();
xmlPanel = new javax .swing .JPanel();
xmlsubPanel = new javax.swing.JPanel ();
xmlchooserPanel = new javax.swing.JPanel();
filenameLabel = new javax.swing .JLabel();
filenameTextField = new javax.swing.JTextField ();
filechooserButton = new javax.swing.JButton();
fileidentifierTextField = new javax.swing .JTextField();
fileidentifierLabel = new javax .swing.JLabel();
validatePanel = new javax.swing .JPanel();
validateLabel = new javax.swing .JLabel();
validateButton = new javax .swing.JButton();
addNewXMLButton = new javax.swing.JButton();
hintXMLLabel = new javax.swing.JLabel();
convertButton = new javax.swing .JButton();
outputTextArea = new javax .swing.JTextArea();
xmlListPanel = new javax.swing.JPanel();
xmlListLabel = new javax.swing.JLabel();
xmlListComboBox = new javax.swing.JComboBox(xmlList);
addXMLButton = new javax.swing.JButton();
removeXMLButton = new javax.swing.JButton();
xmlInfoButton = new javax.swing .JButton();
setTitle("Project Setup");
setIconifiable(true);
setClosable(true);
setPreferredSize(new java.awt.Dimension(450, 500));
setMinimumSize(new java.awt.Dimension(450, 500));
addInternalFrameListener(new javax.swing.event .InternalFrameListener() {
public void internalFrameOpened(javax .swing.event.InternalFrameEvent evt ) {
}
public void internalFrameClosing (javax.swing.event.InternalFrameEvent evt) {
formInternalFrameClosing(evt);
}
public void internalFrameClosed(javax .swing.event.InternalFrameEvent evt ) {
}
public void internalFrameIconified(javax.swing.event .InternalFrameEvent evt) {
}
public void internalFrameDeiconified(javax .swing.event.InternalFrameEvent evt ) {
}
public void internalFrameActivated(javax.swing.event .InternalFrameEvent evt) {
}
public void internalFrameDeactivated(javax .swing.event.InternalFrameEvent evt ) {
}
});
backPanel.setLayout(new java.awt.BorderLayout());
backPanel.setPreferredSize (new java.awt.Dimension(450, 500));
backPanel.setMinimumSize(new java.awt.Dimension(450, 500));
mainTabbedPane.setPreferredSize (new java.awt.Dimension(450, 520));
mainTabbedPane.setMinimumSize(new java.awt.Dimension(450, 520));
welcomePanel.setLayout(new java.awt.BorderLayout(0, 10));
welcomePanel.setPreferredSize(new java.awt.Dimension(431, 387));
welcomePanel.setName("Welcome");
welcomePanel.setMinimumSize(new java.awt.Dimension(431, 387));
welcomeTextArea .setEditable(false);
welcomeTextArea .setText("Welcome to <xmlizer> configurator\n\n1. Type in a name for your new project and\nchoose a
mapping module from the list.\n\n2. Use the <<Database Setup>> Tab to set up\none or more working database connections.\n\n3.
Depending on the module you use, you can\nadd XML schemas or DTDs. DTDs have to be\nconverted to XML schema and a schema has
to\nbe well-formed. Use the <<XML Setup>> Tab.\n\n4. Come back to the <<Welcome>> Tab and \n<<Finish Setup>> if everything is
set up correctly.\n(all lightbulbs must be ON to finish)");
welcomeTextArea .setBackground(new java.awt.Color(204, 204, 204));
welcomeTextArea .setMargin(new java.awt.Insets(20, 20, 20, 20));
welcomePanel.add(welcomeTextArea, java.awt.BorderLayout.CENTER);
buttonPanel.setLayout(new java.awt.BorderLayout(30, 30));
subPanel.setLayout(new java.awt.GridBagLayout());
java.awt.GridBagConstraints gridBagConstraints1;
projectnameLabel.setText("Project Name:");
projectnameLabel.setMinimumSize (new java.awt.Dimension(90, 21));
projectnameLabel.setMaximumSize (new java.awt.Dimension(90, 21));
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 0;
gridBagConstraints1.gridy = 0;
gridBagConstraints1.ipadx = 17;
gridBagConstraints1.anchor = java.awt.GridBagConstraints .WEST;
subPanel.add(projectnameLabel, gridBagConstraints1);
projectnameTextField .setText("defaultprojectname");
projectnameTextField .setPreferredSize(new java.awt.Dimension(300, 21));
projectnameTextField .setNextFocusableComponent (mappingmoduleComboBox);
projectnameTextField .addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
projectnameTextFieldActionPerformed(evt);
}
});
gridBagConstraints1 = new java.awt.GridBagConstraints();
Autor: Thomas Schädler
107
Anhang A: Quelltext <xmlizer> configurator
gridBagConstraints1.gridx = 0;
gridBagConstraints1.gridy = 1;
gridBagConstraints1.gridwidth = 3;
gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints1.anchor = java.awt.GridBagConstraints .WEST;
subPanel.add(projectnameTextField, gridBagConstraints1);
mappingmoduleLabel.setText ("Mapping Module:");
mappingmoduleLabel.setMinimumSize(new java.awt.Dimension (90, 21));
mappingmoduleLabel.setMaximumSize(new java.awt.Dimension (90, 21));
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 0;
gridBagConstraints1.gridy = 2;
gridBagConstraints1.anchor = java.awt.GridBagConstraints .WEST;
subPanel.add(mappingmoduleLabel, gridBagConstraints1);
mappingmoduleComboBox.setPreferredSize(new java.awt.Dimension (240, 27));
mappingmoduleComboBox.setMinimumSize (new java.awt.Dimension(126, 27));
mappingmoduleComboBox.setMaximumSize (new java.awt.Dimension(32767, 27));
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 0;
gridBagConstraints1.gridy = 3;
gridBagConstraints1.gridwidth = 2;
gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints1.anchor = java.awt.GridBagConstraints .WEST;
subPanel.add(mappingmoduleComboBox, gridBagConstraints1);
moduleInfoButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/Help16.gif")));
moduleInfoButton.setToolTipText ("Open Help");
moduleInfoButton.setFont(new java.awt.Font("Dialog" , 0, 10));
moduleInfoButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
moduleInfoButtonActionPerformed(evt);
}
});
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 2;
gridBagConstraints1.gridy = 3;
gridBagConstraints1.anchor = java.awt.GridBagConstraints .EAST;
subPanel.add(moduleInfoButton, gridBagConstraints1);
buttonPanel.add(subPanel, java.awt.BorderLayout.CENTER);
sub2Panel.setLayout(new java.awt.GridBagLayout ());
java.awt.GridBagConstraints gridBagConstraints2;
dbLabel.setIcon(new javax.swing .ImageIcon (getClass().getResource("/configurator/icons/TipOfTheDay24.gif")));
dbLabel.setEnabled(false);
gridBagConstraints2 = new java.awt.GridBagConstraints();
gridBagConstraints2.gridx = 1;
gridBagConstraints2.gridy = 0;
sub2Panel.add(dbLabel, gridBagConstraints2);
db2Label.setText("Database OK");
gridBagConstraints2 = new java.awt.GridBagConstraints();
gridBagConstraints2.gridx = 1;
gridBagConstraints2.gridy = 1;
gridBagConstraints2.insets = new java.awt.Insets(0, 5, 0, 5);
sub2Panel.add(db2Label, gridBagConstraints2);
finishButton.setText("Finish Setup");
finishButton.setEnabled(false);
finishButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
finishButtonActionPerformed(evt);
}
});
gridBagConstraints2 = new java.awt.GridBagConstraints();
gridBagConstraints2.gridx = 0;
gridBagConstraints2.gridy = 2;
gridBagConstraints2.gridwidth = 2;
gridBagConstraints2.insets = new java.awt.Insets(10, 0, 10, 0);
sub2Panel.add(finishButton , gridBagConstraints2);
welcome2Label.setText("Welcome OK");
gridBagConstraints2 = new java.awt.GridBagConstraints();
gridBagConstraints2.gridx = 0;
gridBagConstraints2.gridy = 1;
gridBagConstraints2.insets = new java.awt.Insets(0, 5, 0, 5);
sub2Panel.add(welcome2Label, gridBagConstraints2);
welcomeLabel.setIcon(new javax.swing .ImageIcon (getClass().getResource("/configurator/icons/TipOfTheDay24.gif")));
welcomeLabel.setEnabled(false);
gridBagConstraints2 = new java.awt.GridBagConstraints();
gridBagConstraints2.gridx = 0;
gridBagCon straints2.gridy = 0;
sub2Panel.add(welcomeLabel , gridBagConstraints2);
buttonPanel.add(sub2Panel, java.awt.BorderLayout.SOUTH);
welcomePanel.add(buttonPanel, java.awt.BorderLayout .SOUTH);
mainTabbedPane.addTab("Welcome" , welcomePanel);
databasePanel.setLayout(new java.awt.BorderLayout());
databasePanel.setPreferredSize(new java.awt.Dimension(431, 387));
dboutputTextArea.setWrapStyleWord(true);
dboutputTextArea.setToolTipText ("Shows messages");
dboutputTextArea.setLineWrap(true);
dboutputTextArea.setEditable(false);
dboutputTextArea.setTabSize(4);
dboutputTextArea.setRows(3);
Autor: Thomas Schädler
108
Anhang A: Quelltext <xmlizer> configurator
dboutputTextArea.setForeground(java.awt.Color.red);
dboutputTextArea.setBackground(new java.awt.Color(204, 204, 204));
dboutputTextArea.setPreferredSize(new java.awt.Dimension (10, 51));
dboutputTextArea.setMargin (new java.awt.Insets (10, 5, 5, 10));
dboutputTextArea.setMinimumSize (new java.awt.Dimension(10, 80));
databasePanel.add(dboutputTextArea, java.awt.BorderLayout.SOUTH);
dbListPanel.setLayout(new java.awt.GridBagLayout());
java.awt.GridBagConstraints gridBagConstraints3;
dbListLabel.setText("Connection List:");
gridBagConstraints3 = new java.awt.GridBagConstraints();
dbListPanel.add(dbListLabel, gridBagConstraints3);
dbListComboBox.setPreferredSize (new java.awt.Dimension(240, 27));
dbListComboBox.setMinimumSize(new java.awt.Dimension(126, 27));
dbListComboBox.setMaximumSize(new java.awt.Dimension(32767, 27));
dbListComboBox.addActionListener(new java.awt.event .ActionListener () {
public void actionPerformed (java.awt.event .ActionEvent evt) {
dbListComboBoxActionPerformed(evt);
}
});
gridBagConstraints3 = new java.awt.GridBagConstraints();
gridBagConstraints3.gridwidth = 4;
gridBagConstraints3.insets = new java.awt.Insets(0, 0, 4, 0);
dbListPanel.add(dbListComboBox, gridBagConstraints3 );
addDBButton.setToolTipText ("Add a new connection");
addDBButton.setText("Add");
addDBButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
addDBButtonActionPerformed(evt);
}
});
gridBagConstraints3 = new java.awt.GridBagConstraints();
gridBagConstraints3.gridx = 1;
gridBagConstraints3.gridy = 1;
gridBagConstraints3.insets = new java.awt.Insets(0, 0, 0, 4);
dbListPanel.add(addDBButton, gridBagConstraints3);
removeDBButton.setToolTipText("Removes the currently selected connection");
removeDBButton.setText("Remove" );
removeDBButton.setEnabled(false );
removeDBButton.addActionListener(new java.awt.event .ActionListener () {
public void actionPerformed(java.awt.event .ActionEvent evt) {
removeDBButtonActionPerformed(evt);
}
});
gridBagConstraints3 = new java.awt.GridBagConstraints();
gridBagConstraints3.gridx = 2;
gridBagConstraints3.gridy = 1;
gridBagConstraints3.insets = new java.awt.Insets(0, 4, 0, 0);
dbListPanel.add(removeDBButton, gridBagConstraints3 );
dbInfoButton.setIcon(new javax.swing .ImageIcon (getClass().getResource("/configurator/icons/Help16.gif")));
dbInfoButton.setToolTipText("Open Help");
dbInfoButton.setFont(new java.awt.Font("Dialog", 0, 10));
dbInfoButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event.ActionEvent evt) {
dbInfoButtonActionPerformed(evt);
}
});
gridBagConstraints3 = new java.awt.GridBagConstraints();
gridBagConstraints3.gridx = 4;
gridBagConstraints3.gridy = 1;
gridBagConstraints3.anchor = java.awt.GridBagConstraints .EAST;
dbListPanel.add(dbInfoButton, gridBagConstraints3);
databasePanel.add(dbListPanel, java.awt.BorderLayout.NORTH);
dbPanel.setLayout(new java.awt.GridBagLayout());
java.awt.GridBagConstraints gridBagConstraints4;
dbdriverLabel.setText("Driver Name:" );
gridBagConstraints4 = new java.awt.GridBagConstraints();
gridBagConstraints4.gridx = 0;
gridBagConstraints4.gridy = 2;
gridBagConstraints4.anchor = java.awt.GridBagConstraints .WEST;
dbPanel.add(dbdriverLabel, gridBagConstraints4 );
dbdriverTextField.setPreferredSize(new java.awt.Dimension(300, 21));
dbdriverTextField.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
dbdriverTextFieldActionPerformed(evt);
}
});
gridBagConstraints4 = new java.awt.GridBagConstraints();
gridBagConstraints4.gridx = 0;
gridBagConstraints4.gridy = 3;
gridBagConstraints4.gridwidth = 3;
gridBagConstraints4.fill = java.awt.GridBagConstraints.HORIZONTAL;
dbPanel.add(dbdriverTextField, gridBagConstraints4);
dburlLabel .setText("Database URL:");
gridBagConstraints4 = new java.awt.GridBagConstraints();
gridBagConstraints4.gridx = 0;
gridBagConstraints4.gridy = 4;
gridBagConstraints4.anchor = java.awt.GridBagConstraints .WEST;
dbPanel.add(dburlLabel, gridBagConstraints4);
Autor: Thomas Schädler
109
Anhang A: Quelltext <xmlizer> configurator
dburlTextField.setPreferredSize (new java.awt.Dimension(300, 21));
dburlTextField.addActionListener(new java.awt.event .ActionListener () {
public void actionPerformed (java.awt.event .ActionEvent evt) {
dburlTextFieldActionPerformed(evt);
}
});
gridBagConstraints4 = new java.awt.GridBagConstraints();
gridBagConstraints4.gridx = 0;
gridBagConstraints4.gridy = 5;
gridBagConstraints4.gridwidth = 3;
gridBagConstraints4.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints4.anchor = java.awt.GridBagConstraints .WEST;
dbPanel.add(dburlTextField , gridBagConstraints4);
drivertestButton.setIcon(new javax.swing.ImageIcon(""));
drivertestButton.setText("Test" );
drivertestButton.setPreferredSize(new java.awt.Dimension (79, 27));
drivertestButton.setMaximumSize (new java.awt.Dimension(79, 27));
drivertestButton.setMargin (new java.awt.Insets (0, 0, 0, 0));
drivertestButton.setMinimumSize (new java.awt.Dimension(79, 27));
drivertestButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
drivertestButtonActionPerformed(evt);
}
});
gridBagConstraints4 = new java.awt.GridBagConstraints();
gridBagConstraints4.gridx = 2;
gridBagConstraints4.gridy = 4;
gridBagConstraints4.anchor = java.awt.GridBagConstraints .EAST;
dbPanel.add(drivertestButton, gridBagConstraints4);
dbtimeoutLabel.setText("Timeout (s):");
gridBagConstraints4 = new java.awt.GridBagConstraints();
gridBagConstraints4.gridx = 0;
gridBagConstraints4.gridy = 6;
gridBagConstraints4.anchor = java.awt.GridBagConstraints .WEST;
dbPanel.add(dbtimeoutLabel , gridBagConstraints4);
dbusernameLabel .setText("Username:");
gridBagConstraints4 = new java.awt.GridBagConstraints();
gridBagConstraints4.gridx = 0;
gridBagConstraints4.gridy = 8;
gridBagConstraints4.anchor = java.awt.GridBagConstraints .WEST;
dbPanel.add(dbusernameLabel, gridBagConstraints4);
dbusernameTextField.setPreferredSize (new java.awt.Dimension(300, 21));
dbusernameTextField.addActionListener(new java.awt.event .ActionListener () {
public void actionPerformed (java.awt.event .ActionEvent evt) {
dbusernameTextFieldActionPerformed(evt);
}
});
gridBagConstraints4 = new java.awt.GridBagConstraints();
gridBagConstraints4.gridx = 0;
gridBagConstraints4.gridy = 9;
gridBagConstraints4.gridwidth = 3;
gridBagConstraints4.fill = java.awt.GridBagConstraints.HORIZONTAL;
dbPanel.add(dbusernameTextField , gridBagConstraints4);
dbpasswordLabel .setText("Password:");
gridBagConstraints4 = new java.awt.GridBagConstraints();
gridBagConstraints4.gridx = 0;
gridBagConstraints4.gridy = 10;
gridBagConstraints4.anchor = java.awt.GridBagConstraints .WEST;
dbPanel.add(dbpasswordLabel, gridBagConstraints4);
dbpasswordTextField.setPreferredSize (new java.awt.Dimension(300, 21));
gridBagConstraints4 = new java.awt.GridBagConstraints();
gridBagConstraints4.gridx = 0;
gridBagConstraints4.gridy = 11;
gridBagConstraints4.gridwidth = 3;
gridBagConstraints4.fill = java.awt.GridBagConstraints.HORIZONTAL;
dbPanel.add(dbpasswordTextField , gridBagConstraints4);
connectButton.setIcon(new javax .swing.ImageIcon(""));
connectButton.setToolTipText("Try to connect to selected Database" );
connectButton.setText("Connect" );
connectButton.setPreferredSize(new java.awt.Dimension(79, 27));
connectButton.setMaximumSize(new java.awt.Dimension (79, 27));
connectButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
connectButton.setMinimumSize(new java.awt.Dimension (79, 27));
connectButton.setEnabled(false);
connectButton.addActionListener (new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
connectButtonActionPerformed (evt);
}
});
gridBagConstraints4 = new java.awt.GridBagConstraints();
gridBagConstraints4.gridx = 1;
gridBagConstraints4.gridy = 13;
gridBagConstraints4.anchor = java.awt.GridBagConstraints .EAST;
dbPanel.add(connectButton, gridBagConstraints4 );
dbtimeoutTextField.setPreferredSize(new java.awt.Dimension(300, 21));
dbtimeoutTextField.addActionListener (new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
dbtimeoutTextFieldActionPerformed (evt);
}
});
gridBagConstraints4 = new java.awt.GridBagConstraints();
gridBagConstraints4.gridx = 0;
Autor: Thomas Schädler
110
Anhang A: Quelltext <xmlizer> configurator
gridBagConstraints4.gridy = 7;
gridBagConstraints4.gridwidth = 3;
gridBagConstraints4.fill = java.awt.GridBagConstraints.HORIZONTAL;
dbPanel.add(dbtimeoutTextField, gridBagConstraints4 );
connameTextField.setPreferredSize(new java.awt.Dimension (300, 21));
connameTextField.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
connameTextFieldActionPerformed(evt);
}
});
gridBagConstraints4 = new java.awt.GridBagConstraints();
gridBagConstraints4.gridx = 0;
gridBagConstraints4.gridy = 1;
gridBagConstraints4.gridwidth = 3;
gridBagConstraints4.fill = java.awt.GridBagConstraints.HORIZONTAL;
dbPanel.add(connameTextField, gridBagConstraints4);
connameLabel.setText("Connection Name:");
gridBagConstraints4 = new java.awt.GridBagConstraints();
gridBagConstraints4.gridx = 0;
gridBagConstraints4.gridy = 0;
gridBagConstraints4.anchor = java.awt.GridBagConstraints .WEST;
dbPanel.add(connameLabel, gridBagConstraints4);
addNewDBButton.setToolTipText("Adds this connection to the connection list");
addNewDBButton.setText("Save");
addNewDBButton.setPreferredSize (new java.awt.Dimension(79, 27));
addNewDBButton.setMaximumSize(new java.awt.Dimension(79, 27));
addNewDBButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
addNewDBButton.setMinimumSize(new java.awt.Dimension(79, 27));
addNewDBButton.setEnabled(false );
addNewDBButton.addActionListener(new java.awt.event .ActionListener () {
public void actionPerformed (java.awt.event .ActionEvent evt) {
addNewDBButtonActionPerformed(evt);
}
});
gridBagConstraints4 = new java.awt.GridBagConstraints();
gridBagConstraints4.gridx = 2;
gridBagConstraints4.gridy = 14;
gridBagConstraints4.anchor = java.awt.GridBagConstraints .EAST;
dbPanel.add(addNewDBButton , gridBagConstraints4);
jLabel4.setText("Add the Connection to the List >> ");
gridBagConstraints4 = new java.awt.GridBagConstraints();
gridBagConstraints4.gridx = 0;
gridBagConstraints4.gridy = 14;
gridBagConstraints4.gridwidth = 2;
gridBagConstraints4.anchor = java.awt.GridBagConstraints .EAST;
dbPanel.add(jLabel4, gridBagConstraints4);
dbBrowseButton.setToolTipText("Open a database browser");
dbBrowseButton.setText("Browse" );
dbBrowseBu tton.setPreferredSize (new java.awt.Dimension(79, 27));
dbBrowseButton.setMaximumSize(new java.awt.Dimension(79, 27));
dbBrowseButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
dbBrowseButton.setMinimumSize(new java.awt.Dimension(79, 27));
dbBrowseButton.setEnabled(false );
dbBrowseButton.addActionListener(new java.awt.event .ActionListener () {
public void actionPerformed (java.awt.event .ActionEvent evt) {
dbBrowseButtonActionPerformed(evt);
}
});
gridBagConstraints4 = new java.awt.GridBagConstraints();
gridBagConstraints4.gridx = 2;
gridBagConstraints4.gridy = 13;
gridBagConstraints4.anchor = java.awt.GridBagConstraints .EAST;
dbPanel.add(dbBrowseButton , gridBagConstraints4);
databasePanel.add(dbPanel, java.awt.BorderLayout.CENTER);
mainTabbedPane.addTab("Database Setup", databasePanel);
xmlPanel.setLayout(new java.awt.BorderLayout());
xmlsubPanel.setLayout(new java.awt.GridLayout(2, 1));
xmlchooserPanel .setLayout(new java.awt.GridBagLayout());
java.awt.GridBagConstraints gridBagConstraints5;
filenameLabel.setText("Load XML Schema or a DTD: " );
gridBagConstraints5 = new java.awt.GridBagConstraints();
gridBagConstraints5.gridx = 0;
gridBagConstraints5.gridy = 0;
gridBagConstraints5.anchor = java.awt.GridBagConstraints .WEST;
xmlchooserPanel.add(filenameLabel, gridBagConstraints5);
filenameTextField.setPreferredSize(new java.awt.Dimension(300, 21));
filenameTextField.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
filenameTextFieldActionPerformed(evt);
}
});
gridBagConstraints5 = new java.awt.GridBagConstraints();
gridBagConstraints5.gridx = 0;
gridBagConstraints5.gridy = 1;
gridBagConstraints5.gridwidth = 2;
gridBagConstraints5.fill = java.awt.GridBagConstraints.HORIZONTAL;
xmlchooserPanel .add(filenameTextField, gridBagConstraints5);
filechooserButton.setText("Choose...");
Autor: Thomas Schädler
111
Anhang A: Quelltext <xmlizer> configurator
filechooserButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
filechooserButtonActionPerformed(evt);
}
});
gridBagConstraints5 = new java.awt.GridBagConstraints();
gridBagConstraints5.gridx = 1;
gridBagConstraints5.gridy = 0;
gridBagConstraints5.anchor = java.awt.GridBagConstraints .EAST;
xmlchooserPanel .add(filechooserButton, gridBagConstraints5);
fileidentifierTextField.setPreferredSize(new java.awt.Dimension(300, 21));
fileidentifierTextField.addActionListener (new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
fileidentifierTextFieldActionPerformed (evt);
}
});
gridBagConstraints5 = new java.awt.GridBagConstraints();
gridBagConstraints5.gridx = 0;
gridBagConstraints5.gridy = 3;
gridBagConstraints5.gridwidth = 2;
gridBagConstraints5.fill = java.awt.GridBagConstraints.HORIZONTAL;
xmlchooserPanel .add(fileidentifierTextField, gridBagConstraints5);
fileidentifierLabel.setText("File Name:");
gridBagConstraints5 = new java.awt.GridBagConstraints();
gridBagConstraints5.gridx = 0;
gridBagConstraints5.gridy = 2;
gridBagConstraints5.anchor = java.awt.GridBagConstraints .WEST;
xmlchooserPanel .add(fileidentifierLabel, gridBagConstraints5);
xmlsubPanel.add(xmlchooserPanel );
validatePanel.setLayout(new java.awt.GridBagLayout());
java.awt.GridBagConstraints gridBagConstraints6;
validateLabel.setText("Check the XML Schema : ");
gridBagConstraints6 = new java.awt.GridBagConstraints();
gridBagConstraints6.gridx = 0;
gridBagConstraints6.gridy = 1;
validatePanel.add(validateLabel , gridBagConstraints6);
validateButton.setText("Check");
validateButton.setEnabled(false );
validateButton.addActionListener(new java.awt.event .ActionListener () {
public void actionPerformed (java.awt.event .ActionEvent evt) {
validateButtonActionPerformed(evt);
}
});
gridBagConstraints6 = new java.awt.GridBagConstraints();
gridBagConstraints6.gridx = 1;
gridBagConstraints6.gridy = 1;
validatePanel.add(validateButton, gridBagConstraints6);
addNewXMLButton .setToolTipText("Adds this file to the file list");
addNewXMLButton .setText("Save");
addNewXMLButton .setEnabled (false);
addNewXMLButton .addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
addNewXMLButtonActionPerformed(evt);
}
});
gridBagConstraints6 = new java.awt.GridBagConstraints();
gridBagConstraints6.gridx = 1;
gridBagConstraints6.gridy = 2;
gridBagConstraints6.fill = java.awt.GridBagConstraints.HORIZONTAL;
validatePanel.add(addNewXMLButton, gridBagConstraints6);
hintXMLLabel.setText("Add the File to the List >> " );
gridBagConstraints6 = new java.awt.GridBagConstraints();
gridBagConstraints6.gridx = 0;
gridBagConstraints6.gridy = 2;
validatePanel.add(hintXMLLabel, gridBagConstraints6 );
convertButton.setText("Convert DTD to XML Sche ma");
convertButton.addActionListener (new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
convertButtonActionPerformed (evt);
}
});
gridBagConstraints6 = new java.awt.GridBagConstraints();
gridBagConstraints6.gridx = 0;
gridBagConstraints6.gridy = 0;
gridBagConstraints6.gridwidth = 2;
validatePanel.add(convertButton , gridBagConstraints6);
xmlsubPanel.add(validatePanel);
xmlPanel.add(xmlsubPanel, java.awt.BorderLayout.CENTER);
outputTextArea.setWrapStyleWord (true);
outputTextArea.setToolTipText("Shows messages" );
outputTextArea.setLineWrap (true);
outputTextArea.setEditable (false);
outputTextArea.setTabSize(4);
outputTextArea.setRows(3);
outputTextArea.setForeground(java.awt.Color.red);
outputTextArea.setBackground(new java.awt.Color(204, 204, 204));
outputTextArea.setPreferredSize (new java.awt.Dimension(10, 51));
outputTextArea.setMargin(new java.awt.Insets(10, 5, 5, 10));
Autor: Thomas Schädler
112
Anhang A: Quelltext <xmlizer> configurator
outputTextArea.setMinimumSize(new java.awt.Dimension(10, 80));
xmlPanel.add(outputTextArea, java.awt.BorderLayout.SOUTH );
xmlListPanel.setLayout(new java.awt.GridBagLayout());
java.awt.GridBagConstraints gridBagConstraints7;
xmlListLabel.setText("File List:");
gridBagConstraints7 = new java.awt.GridBagConstraints();
xmlListPanel.add(xmlListLabel, gridBagConstraints7);
xmlListComboBox .setPreferredSize(new java.awt.Dimension(240, 27));
xmlListComboBox .setMinimumSize(new java.awt.Dimension(126, 27));
xmlListComboBox .setMaximumSize(new java.awt.Dimension(32767, 27));
xmlListComboBox .addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
xmlListComboBoxActionPerformed(evt);
}
});
gridBagConstraints7 = new java.awt.GridBagConstraints();
gridBagConstraints7.gridwidth = 3;
gridBagConstraints7.insets = new java.awt.Insets(0, 0, 4, 0);
xmlListPanel.add(xmlListComboBox, gridBagConstraints7);
addXMLButton.setToolTipText("Add a new file to the list" );
addXMLButton.setText("Add" );
addXMLButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
addXMLButtonActionPerformed(evt);
}
});
gridBagConstraints7 = new java.awt.GridBagConstraints();
gridBagConstraints7.gridx = 1;
gridBagConstraints7.gridy = 1;
gridBagConstraints7.insets = new java.awt.Insets(0, 0, 0, 4);
xmlListPanel.add(addXMLButton, gridBagConstraints7);
removeXMLButton .setToolTipText("Removes the currently selected file");
removeXMLButton .setText("Remove");
removeXMLButton .setEnabled (false);
removeXMLButton .addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
removeXMLButtonActionPerformed(evt);
}
});
gridBagConstraints7 = new java.awt.GridBagConstraints();
gridBagConstraints7.gridx = 2;
gridBagConstraints7.gridy = 1;
gridBagConstraints7.insets = new java.awt.Insets(0, 4, 0, 4);
xmlListPanel.add(removeXMLButton, gridBagConstraints7);
xmlInfoButton.setIcon(new javax .swing.ImageIcon(getClass ().getResource("/configurator/icons/Help16.gif")));
xmlInfoButton.setToolTipText("Open Help");
xmlInfoButton.setFont(new java.awt.Font("Dialog", 0, 10));
xmlInfoButton.addActionListener (new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
xmlInfoButtonActionPerformed (evt);
}
});
gridBagConstraints7 = new java.awt.GridBagConstraints();
gridBagConstraints7.gridx = 3;
gridBagConstraints7.gridy = 1;
gridBagConstraints7.anchor = java.awt.GridBagConstraints .EAST;
xmlListPanel.add(xmlInfoButton, gridBagConstraints7 );
xmlPanel.add(xmlListPanel, java.awt.BorderLayout.NORTH);
mainTabbedPane.addTab("XML Setup", xmlPanel);
backPanel.add(mainTabbedPane, java.awt.BorderLayout .CENTER);
getContentPane().add(backPanel, java.awt.BorderLayout.CENTER);
pack();
}//GEN-END:initComponents
private void convertButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_convertButtonActionP erformed
{//GEN-HEADEREND:event_convertButtonActionPerformed
// Add your handling code here:
ConvertDTD2XMLSchema ();
}//GEN-LAST:event_convertButtonActionPerformed
private void formInternalFrameClosing(javax.swing.event .InternalFrameEvent evt)//GEN-FIRST:event_formInternalFrameClosing
{//GEN-HEADEREND:event_formInternalFrameClosing
// Add your handling code here:
if (isNewSetup) {
mother .close(this.ID);
mother .resetToDefault();
}
else {
//redo
mother .getProjectData().setDB(oldDB);
mother .getProjectData().setXML(oldXML );
mother .getProjectData().save(); //clean the dirty bit
//exit
doExit ();
}
}//GEN-LAST:event_formInternalFrameClosing
private void dbBrowseButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_dbBrowseButtonActionPerformed
Autor: Thomas Schädler
113
Anhang A: Quelltext <xmlizer> configurator
{//GEN-HEADEREND:event_dbBrowseButtonActionPerformed
// Add your handling code here:
dbItem thisDB = new dbItem ();
thisDB.setName(connameTextField .getText());
thisDB.setDriver(dbdriverTextField.getText());
thisDB.setUrl(dburlTextField.getText());
thisDB.setTimeout(dbtimeoutTextField .getText());
thisDB.setUsername(dbusernameTextField.getText());
thisDB.setPassword(getSecurePassword ()); //secure pw handling
mother.nextDBToBrowse.removeAllElements();
mother.nextDBToBrowse.add(thisDB);
mother.open("sdatabaseBrowser");
}//GEN-LAST:event_dbBrowseButtonActionPerformed
private void fileidentifierTextFieldActionPerformed(java.awt.event.ActionEvent evt)//GENFIRST:event_fileidentifierTextFieldActionPerformed
{//GEN-HEADEREND:event_fileidentifierTextFieldActionPerformed
// Add your handling code here:
doXMLCheck ();
}//GEN-LAST:event_fileidentifierTextFieldActionPerformed
private void xmlInfoButtonActionPerformed(java.awt.event.ActionEv ent evt)//GEN-FIRST:event_xmlInfoButtonActionPerformed
{//GEN-HEADEREND:event_xmlInfoButtonActionPerformed
// Add your handling code here:
helpWindow help = (helpWindow)mother .open("help");
help.loadPage("/configurator/help/setup_xml.html");
}//GEN-LAST:event_xmlInfoButtonActionPerformed
private void dbInfoButtonActionPerformed (java.awt.event .ActionEvent evt)//GEN-FIRST:event_dbInfoButtonActionPerformed
{//GEN-HEADEREND:event_dbInfoButtonActionPerformed
// Add your handling code here:
helpWindow help = (helpWindow)mother .open("help");
help.loadPage("/configurator/help/setup_database.html");
}//GEN-LAST:event_dbInfoButtonActionPerformed
private void moduleInfoButtonActionPerformed(java.awt.event.ActionEvent evt )//GENFIRST:event_moduleInfoButtonActionPerformed
{//GEN-HEADEREND:event_moduleInfoButtonActionPerformed
// Add your handling code here:
String helpinfo = null;
String selected = (String)mappingmoduleComboBox.getSelectedItem();
if (selected.equalsIgnoreCase("Simple DB Export")) {
helpinfo = "smdbe";
}
else if (selected.equalsIgnoreCase("Database to XML")) {
helpinfo = "db2xml";
}
if (helpinfo != null) {
//open the help-browser (Swing HTML)
helpWindow help = (helpWindow)mother.open("help");
help.loadPage("/configurator/help/module_" + helpinfo + ".html");
}
}//GEN-LAST:event_moduleInfoButtonActionPerformed
private void filenameTextFieldActionPerformed (java.awt.event .ActionEvent evt)//GENFIRST:event_filenameTextFieldActionPerformed
{//GEN-HEADEREND:event_filenameTextFieldActionPerformed
// Add your handling code here:
doXMLCheck ();
}//GEN-LAST:event_filenameTextFieldActionPerformed
private void removeDBButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_removeDBButtonActionPerformed
{//GEN-HEADEREND:event_removeDBButtonActionPerformed
// Add your handling code here:
dbItem toRemove = (dbItem)dbListComboBox.getSelectedItem ();
if (toRemove != null) {
dbListComboBox.removeItem(toRemove);
databasePanel.remove(dbPanel);
//databasePanel.add(dbPanel, java.awt.BorderLayout.CENTER);
dboutputTextArea .setText(toRemove + " removed!" );
mother .getProjectData().setDirty ();
mainTabbedPane.repaint ();
doCheck();
}
}//GEN-LAST:event_removeDBButtonActionPerformed
private void removeXMLButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN FIRST:event_removeXMLButtonActionPerformed
{//GEN-HEADEREND:event_removeXMLButtonActionPerformed
// Add your handling code here:
xmlItem toRemove = (xmlItem)xmlListComboBox.getSelectedItem();
if (toRemove != null) {
xmlListComboBox.removeItem(toRemove);
xmlPanel.remove(xmlsubPanel ); //xmlPanel.add(xmlsubPanel, java.awt.BorderLayout.CENTER);
java.io.File temp = new File(mother.getProjectBase() + mother.getFileSeparator() + projectnameTextField .getText()
+ mother .getFileSeparator() + toRemove.getFile());
if (temp.exists()) {
temp.delete();
}
outputTextArea.setText (toRemove + " removed!");
mother .getProjectData().setDirty ();
mainTabbedPane.repaint ();
doCheck();
}
}//GEN-LAST:event_removeXMLButtonActionPerformed
private void connameTextFieldActionPerformed(java.awt.event.ActionEvent evt )//GENFIRST:event_connameTextFieldActionPerformed
{//GEN-HEADEREND:event_connameTextFieldActionPerformed
// Add your handling code here:
doDatabaseCheck ();
}//GEN-LAST:event_connameTextFieldActionPerformed
Autor: Thomas Schädler
114
Anhang A: Quelltext <xmlizer> configurator
private void xmlListComboBoxActionPerformed(java.awt.event.ActionEvent evt)//GEN FIRST:event_xmlListComboBoxActionPerformed
{//GEN-HEADEREND:event_xmlListComboBoxActionPerformed
// Add your handling code here:
if (!isLoading) {
JComboBox cb = (JComboBox)evt.getSource();
//String selectedXML = (String)cb.getSelectedItem();
xmlItem selectedXML = (xmlItem)cb.getSelectedItem();
if (selectedXML != null) {
showXML(selectedXML);
removeXMLButton.setEnabled(true);
}
}
}//GEN-LAST:event_xmlListComboBoxActionPerformed
private void dbListComboBoxActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_dbListComboBoxActionPerformed
{//GEN-HEADEREND:event_dbListComboBoxActionPerformed
// Add your handling code here:
if (!isLoading) {
JComboBox cb = (JComboBox)evt.getSource();
//String selectedDB = (String)cb.getSelectedItem();
dbItem selectedDB = (dbItem )cb.getSelectedItem();
if (selectedDB != null) {
showDB(selectedDB);
removeDBButton.setEnabled(true);
}
}
}//GEN-LAST:event_dbListComboBoxActionPerformed
private void addNewXMLButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN FIRST:event_addNewXMLButtonActionPerformed
{//GEN-HEADEREND:event_addNewXMLButtonActionPerformed
// Add your handling code here:
doXMLSave();
}//GEN-LAST:event_addNewXMLButtonActionPerformed
private void addNewDBButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_addNewDBButtonActionPerformed
{//GEN-HEADEREND:event_addNewDBButtonActionPerformed
// Add your handling code here:
doDBSave();
}//GEN-LAST:event_addNewDBButtonActionPerformed
private void addXMLButtonActionPerformed (java.awt.event .ActionEvent evt)//GEN-FIRST:event_addXMLButtonActionPerformed
{//GEN-HEADEREND:event_addXMLButtonActionPerformed
// Add your handling code here:
String selected = (String)mappingmoduleComboBox.getSelectedItem();
if (selected.equalsIgnoreCase("Database to XML") && xmlList.size() > 0) {
outputTextArea.setText ("In this module (currently) only one file is allowed!" );
}
else if (selected.equalsIgnoreCase("Simple DB Export")) {
outputTextArea.setText ("In this module no files are needed, only database connections!");
}
else {
filenameTextField.setText(new String());
fileidentifierTextField.setText(new String ());
doCheck();
xmlPanel.add(xmlsubPanel, java.awt.BorderLayout .CENTER);
//addXMLButton.setEnabled(false);
removeXMLButton.setEnabled(false );
}
mainTabbedPane.repaint();
}//GEN-LAST:event_addXMLButtonActionPerformed
private void addDBButtonActionPerformed(java.awt.event.ActionEvent evt )//GEN-FIRST:event_addDBButtonActionPerformed
{//GEN-HEADEREND:event_addDBButtonActionPerformed
// Add your handling code here:
connameTextField.setText(new String());
//dbdriverTextField.setText("org.gjt.mm.mysql.Driver");
//dburlTextField.setText("jdbc:mysql://localhost:3306/xml");
dbdriverTextField.setText("org.gjt.mm.mysql.Driver" );
dburlTextField.setText(new String());
dbtimeoutTextField.setText ("30");
dbpasswordTextField.setText(new String());
doCheck();
databasePanel.add(dbPanel, java.awt.BorderLayout.CENTER);
//addDBButton.setEnabled(false);
removeDBButton.setEnabled(false );
mainTabbedPane.repaint();
}//GEN-LAST:event_addDBButtonActionPerformed
private void dbdriverTextFieldActionPerformed (java.awt.event .ActionEvent evt)//GENFIRST:event_dbdriverTextFieldActionPerformed
{//GEN-HEADEREND:event_dbdriverTextFieldActionPerformed
// Add your handling code here:
doDatabaseCheck ();
}//GEN-LAST:event_dbdriverTextFieldActionPerformed
private void validateButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_validateButtonActionPerformed
{//GEN-HEADEREND:event_validateButtonActionPerformed
// Add your handling code here:
if(this.selectedFile != null) {
try {
DOMParser parser = new DOMParser();
parser.setFeature("http://xml.org/sax/features/validation" , false);
parser.setProperty ("http://apache.org/xml/properties/schema/external noNamespaceSchemaLocation",filenameTextField .getText());
ErrorChecker errors = new ErrorChecker ();
parser.setErrorHandler(errors);
parser.parse (filenameTextField.getText());
outputTextArea.setText("The selected file is well-formed!\nResolving includes...");
try {
SAXBuilder builder = new SAXBuilder(false); //true -> validating against dtd
this.temporary = builder.build(filenameTextField.getText());
Autor: Thomas Schädler
115
Anhang A: Quelltext <xmlizer> configurator
File tempfile = new File(filenameTextField.getText());
this.temporary_name = tempfile.getName();
Element loaded_root = this.temporary.getRootElement();
Vector incs2del = new Vector(); //of Elements
List elems = loaded_root .getChildren(); //"element",namespace
Iterator elems_iter = elems.iterator();
while (elems_iter.hasNext()) {
Element xmlelem = (Element)elems_iter.next();
String currName = xmlelem.getName().trim();
//System.out.println("Element name: " + currName);
if(currName.equalsIgnoreCase("include")) {
String path = JDOMgetIncludePath(xmlelem);
//System.out.println("Include path: " + path);
String newpath = null;
File testinclude = new File(path);
if(testinclude.exists ())
//read it automatically, on error go on
{
newpath = path;
}
else {
newpath = getIncludeFromUser(path);
if (newpath == null) {
//FIXME aborted include resolver dialog!
}
}
//add the path to the list and delete the include
this.includepaths.add(newpath);
incs2del.add(xmlelem);
}
}
for (Enumeration e = incs2del .elements(); e.hasMoreElements ();) {
Element item = (Element)e.nextElement();
loaded_root.removeContent (item);
}
}
catch (Exception ex) {
//show errors of current xml operation
mother.getLog().addDebug (ex);
}
resolveIncludes();
this.XMLvalidated = true;
doCheck();
}
catch (SAXException e) {
outputTextArea.setText("The selected file is NOT well -formed!");
this.XMLvalidated = false;
doCheck();
}
catch (java.io.IOException ex) {
outputTextArea.setText("IO Exception: " + ex.toString());
this.XMLvalidated = false;
doCheck();
}
}
else {
outputTextArea.setText ("No XML File selected!");
this.XMLvalidated = false;
doCheck();
}
}//GEN-LAST:event_validateButtonActionPerformed
private void resolveIncludes() {
SAXBuilder builder = new SAXBuilder(false );
//true -> validating against dtd
for (Enumeration e = this.includepaths.elements(); e.hasMoreElemen ts();) {
String currentpath = (String)e.nextElement ();
//System.out.println("CURR PATH: " + currentpath);
if (currentpath != null) {
Element inc_root = this.temporary .getRootElement ();
try {
org.jdom.Document loaded = builder.build(currentpath);
Element loaded_root = loaded.getRootElement();
if (loaded_root != null) {
List elems = loaded_root.getChildren(); //"element",namespace
Iterator elems_iter = elems.iterator();
while (elems_iter.hasNext()) {
Element xmlelem = (Element)elems_iter.next();
try {
//System.out.println("INCLUDED ELEMENT ADDED: " + xmlelem.toString());
inc_root.addContent((Element)xmlelem.clone ());
}
catch(Exception exc) {
mother.getLog().addWarning(exc.getLocalizedMessage());
}
}
}
else {
mother.getLog().addWarning("No root element found in include: " + currentpath);
}
}
catch (Exception ex) {
mother.getLog().addDebug (ex);
}
}
}
outputTextArea.setText("The selected file is well-formed!\nResolving includes...done." );
}
private File lastInclude = null;
Autor: Thomas Schädler
116
Anhang A: Quelltext <xmlizer> configurator
/**
* Asks for the include path from the user
*/
private String getIncludeFromUser(String filepath) {
//Show inf o on file to search
JOptionPane.showMessageDialog(
getContentPane(),
"Included file could not be found:\n"
+ filepath ,
configurator.APPNAME + " include resolver",
JOptionPane.INFORMATION_MESSAGE
);
JFileChooser chooser = new JFileChooser();
chooser.setDialogType(JFileChooser.OPEN_DIALOG );
if (lastInclude != null) {
chooser.setCurrentDirectory (lastInclude);
}
int returnVal = chooser.showOpenDialog(this);
if(returnVal == JFileChooser.APPROVE_OPTION) {
File selectedFile = chooser.getSelectedFile();
this.lastInclude = selectedFile;
return selectedFile.toString();
}
else {
return null;
}
}
private String JDOMgetIncludePath(Element el) {
Attribute attr = el.getAttribute("schemaLocation");
if (attr != null) {
return attr.getValue().trim();
}
else //just to be sure, should not happen though...
{
return "empty";
}
}
private void filechooserButtonActionPerformed (java.awt.event .ActionEvent evt)//GENFIRST:event_filechooserButtonActionPerformed
{//GEN-HEADEREND:event_filechooserButtonActionPerformed
// Add your handling code here:
JFileChooser chooser = new JFileChooser();
chooser.setDialogType(JFileChooser.OPEN_DIALOG );
simpleFileFilter filter = new simpleFileFilter ();
filter.addExtension("xsd");
filter.addExtension("dtd");
filter.setDescription("XSD & DTD Only");
chooser.setFileFilter(filter);
int returnVal = chooser.showOpenDialog(this);
if(returnVal == JFileChooser.APPROVE_OPTION) {
this.selectedFile = chooser.getSelectedFile();
filenameTextField.setText(chooser.getSelectedFile().getPath());
fileidentifierTextField.setText(chooser.getSelectedFile().getName());
doCheck();
}
else {
doCheck();
}
}//GEN-LAST:event_filechooserButtonActionPerformed
private void finishButtonActionPerformed (java.awt.event .ActionEvent evt)//GEN-FIRST:event_finishButtonActionPerformed
{//GEN-HEADEREND:event_finishButtonActionPerformed
// Add your handling code here:
doWelcomeSave();
doExit();
}//GEN-LAST:event_finishButtonActionPerformed
private void projectnameTextFieldActionPerformed(java.awt.event.ActionEvent evt)//GEN FIRST:event_projectnameTextFieldActionPerformed
{//GEN-HEADEREND:event_projectnameTextFieldActionPerformed
// Add your handling code here:
doWelcomeCheck();
}//GEN-LAST:event_projectnameTextFieldActionPerformed
private void dbusernameTextFieldActionPerformed(java.awt.event.ActionEvent evt)//GENFIRST:event_dbusernameTextFieldActionPerformed
{//GEN-HEADEREND:event_dbusernameTextFieldActionPerformed
// Add your handling code here:
doDatabaseCheck ();
}//GEN-LAST:event_dbusernameTextFieldActionPerformed
private void dbtimeoutTextFieldActionPerformed(java.awt.event.ActionEvent evt)//GENFIRST:event_dbtimeoutTextFieldActionPerformed
{//GEN-HEADEREND:event_dbtimeoutTextFieldActionPerformed
// Add your handling code here:
doDatabaseCheck ();
}//GEN-LAST:event_dbtimeoutTextFieldActionPerformed
private void dburlTextFieldActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_dburlTextFieldActionPerformed
{//GEN-HEADEREND:event_d burlTextFieldActionPerformed
// Add your handling code here:
doDatabaseCheck ();
}//GEN-LAST:event_dburlTextFieldActionPerformed
private void connectButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_connectButtonActionPerformed
{//GEN-HEADEREND:event_connectButtonActionPerformed
// Add your handling code here:
doConnect();
}//GEN-LAST:event_connectButtonActionPerformed
private void drivertestButtonActionPerformed(java.awt.event.ActionEvent evt )//GENFIRST:event_drivertestButtonActionPerformed
Autor: Thomas Schädler
117
Anhang A: Quelltext <xmlizer> configurator
{//GEN-HEADEREND:event_drivertestButtonActionPerformed
// Add your handling code here:
if (!dbdriverTextField.getText().equals(new String())) {
try {
Class.forName(dbdriverTextField.getText());
dboutputTextArea.setText("Driver successfully loaded: " + dbdriverTextField.getText());
dbdriverLabel.setForeground(COLOR_DEFAULT);
dbdriverTested = true;
doDatabaseCheck();
}
catch(ClassNotFoundException ee) {
dbdriverLabel.setForeground(COLOR_RED);
dbdriverTested = false;
dboutputTextArea.setText("The selected Driver could not be loaded, make sure it is in the classpath!");
}
}
else {
dbdriverLabel.setForeground (COLOR_RED );
dbdriverTested = false ;
dboutputTextArea .setText("Enter a valid driver class. Must be in the classpath!");
}
}//GEN-LAST:event_drivertestButtonActionPerformed
// Variables declaration - do not modify//GEN -BEGIN:variables
private javax.swing .JPanel backPanel;
private javax.swing .JTabbedPane mainTabbedPane;
private javax.swing .JPanel welcomePanel;
private javax.swing .JTextArea welcomeTextArea ;
private javax.swing .JPanel buttonPanel;
private javax.swing .JPanel subPanel ;
private javax.swing .JLabel projectnameLabel;
private javax.swing .JTextField projectnameTextField;
private javax.swing .JLabel mappingmoduleLabel ;
private javax.swing .JComboBox mappingmoduleComboBox;
private javax.swing .JButton moduleInfoButton;
private javax.swing .JPanel sub2Panel;
private javax.swing .JLabel dbLabel;
private javax.swing .JLabel db2Label ;
private javax.swing .JButton finishButton ;
private javax.swing .JLabel welcome2Label ;
private javax.swing .JLabel welcomeLabel;
private javax.swing .JPanel databasePanel ;
private javax.swing .JTextArea dboutputTextArea;
private javax.swing .JPanel dbListPanel;
private javax.swing .JLabel dbListLabel;
private javax.swing .JComboBox dbListComboBox;
private javax.swing .JButton addDBButton;
private javax.swing .JButton removeDBButton;
private javax.swing .JButton dbInfoButton ;
private javax.swing .JPanel dbPanel;
private javax.swing .JLabel dbdriverLabel ;
private javax.swing .JTextField dbdriverTextField;
private javax.swing .JLabel dburlLabel;
private javax.swing .JTextField dburlTextField ;
private javax.swing .JButton drivertestButton;
private javax.swing .JLabel dbtimeoutLabel;
private javax.swing .JLabel dbusernameLabel;
private javax.swing .JTextField dbusernameTextField ;
private javax.swing.JLabel dbpasswordLabel;
private javax.swing .JPasswordField dbpasswordTextField;
private javax.swing .JButton connectButton;
private javax.swing .JTextField dbtimeoutTextField;
private javax.swing .JTextField connameTextField;
private javax.swing .JLabel connameLabel;
private javax.swing .JButton addNewDBButton;
private javax.swing .JLabel jLabel4;
private javax.swing .JButton dbBrowseButton;
private javax.swing .JPanel xmlPanel ;
private javax.swing .JPanel xmlsubPanel;
private javax.swing .JPanel xmlchooserPanel;
private javax.swing .JLabel filenameLabel ;
private javax.swing .JTextField filenameTextField;
private javax.swing .JButton filechooserButton ;
private javax.swing .JTextField fileidentifierTextField;
private javax.swing .JLabel fileidentifierLabel;
private javax.swing .JPanel validatePanel ;
private javax.swing .JLabel validateLabel ;
private javax.swing .JButton validateButton;
private javax.swing .JButton addNewXMLButton;
private javax.swing .JLabel hintXMLLabel;
private javax.swing .JButton convertButton;
private javax.swing .JTextArea outputTextArea;
private javax.swing .JPanel xmlListPanel;
private javax.swing .JLabel xmlListLabel;
private javax.swing .JComboBox xmlLi stComboBox ;
private javax.swing .JButton addXMLButton ;
private javax.swing .JButton removeXMLButton;
private javax.swing .JButton xmlInfoButton;
// End of variables declaration//GEN-END:variables
private
private
private
private
boolean dbdriverTested = false;
boolean dbdriverLoaded = false;
boolean XMLvalidated = false;
java.io.File selectedFile;
private void doExit () {
mother.close(this.ID);
mother.doDisable("new");
mother.doEnable ("close");
mother.doEnable ("save");
mother.doEnable ("saveas");
if (isNewSetup) {
mother .startupProjectWorkspace();
Autor: Thomas Schädler
118
Anhang A: Quelltext <xmlizer> configurator
mother .getLog().addInformation("Go on with the mapping or save your settings and continue..." );
}
else {
mother .updateCurrentProject ();
}
}
private void doConnect() {
Runnable r = new Runnable() {
public void run() {
//check the fields (comboboxes) and connect
boolean isok = doDatabaseCheck();
if(isok) {
//connect to database
String theURL = new String(dburlTextField.getText());
dboutputTextArea.setText("Connecting to Database: " + theURL);
try {
Class.forName(dbdriverTextField.getText());
String to_string = dbtimeoutTextField.getText();
Integer to _integer = new Integer(to_string);
int to_int = to_integer.intValue();
DriverManager.setLoginTimeout(to_int);
if(dbusernameTextField.getText().equalsIgnoreCase(new String ())) {
Connection con = DriverManager.getConnection(theURL );
}
else {
Connection con = DriverManager.getConnection (theURL,dbusernameTextField.getText(),dbItem.decryptSecurePassword (getSecurePassword()));
}
dboutputTextArea.setText("DB Connection established!");
dbdriverLoaded = true;
doCheck();
}
catch (ClassNotFoundException classex) {
dbdriverLoaded = false;
doCheck();
dboutputTextArea.setText(classex.toString());
}
catch (SQLException sqlex) {
dbdriverLoaded = false;
doCheck();
dboutputTextArea.setText(sqlex .toString());
}
}
else {
doCheck();
dboutputTextArea.setText("Please fill in ALL neccessary fields!" );
}
}
};
connecterThread = new Thread(r);
connecterThread .setDaemon(true);
connecterThread .start();
}
private void doWelcomeSave() {
//initialize projectdata from options for manual edited options
projectData data = mother.getProjectData();
if (isNewSetup) {
dataItem initial_name = new dataItem();
dataItem initial_module = new dataItem();
if (!projectnameTextField.getText().equals (new String())) {
initial_name .setKey("name");
initial_name .setValue(projectnameTextField.getText());
}
if (!((String)mappingmoduleComboBox.getSelectedItem()).equals(new String ())) {
initial_module.setKey("module");
initial_modu le.setValue ((String)mappingmoduleComboBox .getSelectedItem());
}
data.addInitial(initial_name);
data.addInitial(initial_module);
}
else {
if (!projectnameTextField.getText().equals (new String())) {
dataItem item = data.getInitialByKey("name" );
item.setValue(projectnameTextField.getText());
}
}
}
private void copyFile2ProjectDir() {
String sep = configurator.getFileSeparator();
//File inputFile = new File(orig);
//String inputFileName = inputFile.getName();
File outputPath = new File(mother.getProjectBase() + sep + projectnameTextField.getText());
outputPath .mkdirs();
File outputFile = new File(outputPath.toString () + sep + this.temporary_name );
try {
XMLOutputter fmt = new XMLOutputter("
",true);
FileOutputStream outputStream = new FileOutputStream (outputFile);
OutputStreamWriter outsw = new OutputStreamWriter(outputStream ,"UTF8");
fmt.output(this.temporary,outsw);
outsw.close ();
}
catch(Exception exx) {
Autor: Thomas Schädler
119
Anhang A: Quelltext <xmlizer> configurator
mother .getLog().addError(exx);
}
}
private void doXMLSave() {
boolean isUpdated = false;
this.projectnameTextField.setEnabled (false);
for (Enumeration e = xmlList.elements(); e.hasMoreElements();) {
xmlItem iteritem = (xmlItem)e.nextElement();
if (iteritem.getName().equalsIgnoreCase(fileidentifierTextField.getText())) {
//update
if (!fileidentifierTextField .getText().equalsIgnoreCase(iteritem.getName())) {
iteritem .setName(fileidentifierTextField.getText());
}
if (!filenameTextField.getText().equalsIgnoreCase(iteritem .getFile())) {
//copy the file to the projectdir and save the filename-only!
//String original = filenameTextField.getText();
copyFile2ProjectDir ();
iteritem .setFile(this.temporary_name);
}
xmlListComboBox.setSelectedItem(iteritem);
outputTextArea.setText("XML file data successfully updated.");
mother.getProjectData().setDirty();
isUpdated = true;
break;
}
}
if (!isUpdated) {
//add new item
xmlItem xml = new xmlItem();
if (!fileidentifierTextField.getText().equals(new String())) {
xml.setName(fileidentifierTextField.getText());
}
if (!filenameTextField .getText().equals(new String())) {
//copy the file to the projectdir and save the filename-only!
//String original = filenameTextField.getText();
copyFile2ProjectDir();
xml.setFile(this.temporary_name);
}
//remove the Panel and update the combobox (list)
xmlList.add(xml);
xmlListComboBox.setSelectedItem(xml);
dboutputTextArea .setText("XML File data successfully added.");
mother .getProjectData().setDirty ();
}
xmlPanel.remove (xmlsubPanel);
mainTabbedPane.repaint();
doCheck();
addXMLButton.setEnabled(true);
validateButton.setEnabled(false );
addNewXMLButton .setEnabled (false);
XMLvalidated = false ;
}
private void showXML(xmlItem item) {
filenameTextField.setText(mother.getProjectBase() + mother.getFileSeparator() + projectnameTextField.getText() +
mother.getFileSeparator () + item.getFile());
fileidentifierTextField.setText(item.getName());
this.selectedFile = new File(item.getFile());
validateButton.setEnabled(false );
addNewXMLButton .setEnabled (false);
xmlPanel.add(xmlsubPanel, java.awt.BorderLayout.CENTER);
mainTabbedPane.repaint();
doXMLCheck ();
}
private void doDBSave() {
boolean isUpdated = false;
this.projectnameTextField.setEnabled (false);
for (Enumeration e = databaseList.elements(); e.hasMoreElements();) {
dbItem iteritem = (dbItem)e.nextElement();
if (iteritem.getName().equalsIgnoreCase(connameTextField.getText())) {
//update
if (!dbdriverTextField.getText().equal sIgnoreCase(iteritem .getDriver ())) {
iteritem .setDriver(dbdriverTextField.getText());
}
if (!dburlTextField.getText().equalsIgnoreCase(iteritem.getUrl())) {
iteritem .setUrl(dburlTextField.getText());
}
if (!dbtimeoutTextField .getText().equalsIgnoreCase(iteritem.getTimeout())) {
iteritem .setTimeout (dbtimeoutTextField.getText());
}
if (!dbusernameTextField.getText().equalsIgnoreCase(iteritem.getUsername())) {
iteritem .setUsername(dbusernameTextField.getText());
}
if (!getSecurePassword().equalsIgnoreCase(iteritem.getPassword())) {
iteritem.setPassword(getSecurePassword());
}
dbListComboBox.setSelectedItem(iteritem);
dboutputTextArea.setText("Connection successfully updated.");
mother.getProjectData().setDirty();
isUpdated = true;
break;
}
Autor: Thomas Schädler
120
Anhang A: Quelltext <xmlizer> configurator
}
if (!isUpdated) {
//add new item
dbItem db = new dbItem ();
if (!connameTextField.getText().equals(new String())) {
db.setName(connameTextField.getText());
}
if (!dbdriverTextField .getText().equals(new String())) {
db.setDriver (dbdriverTextField.getText());
}
if (!dburlTextField.getText ().equals(new String ())) {
db.setUrl(dburlTextField.getText());
}
if (!dbtimeoutTextField.getText().equals(new String())) {
db.setTimeout(dbtimeoutTextField.getText());
}
if (!dbusernameTextField.getText().equals(new String ())) {
db.setUsername(dbusernameTextField.getText());
}
if (!getSecurePassword ().equals(new String ())) {
db.setPassword(getSecurePassword());
}
databaseList.add(db);
dbListComboBox.setSelectedItem(db);
dboutputTextArea .setText("Connection successfully added." );
mother .getProjectData().setDirty ();
}
//remove the Panel and update the combobox (list)
databasePanel.remove (dbPanel);
mainTabbedPane.repaint();
doCheck();
addDBButton.setEnabled(true);
connectButton.setEnabled(false);
addNewDBButton.setEnabled(false );
dbdriverTested = false;
dbdriverLoaded = false;
}
private void showDB (dbItem item) {
connameTextField.setText(item.getName());
dbdriverTextField.setText(item.getDriver());
dburlTextField.setText(item.getUrl());
dbtimeoutTextField.setText (item.getTimeout());
dbusernameTextField.setText(item.getUsername());
dbpasswordTextField.setText(dbItem.decryptSecurePassword (item.getPassword()));
drivertestButton.setEnabled(true);
connectButton.setEnabled(false);
addNewDBButton.setEnabled(false );
dbBrowseButton.setEnabled(false );
databasePanel.add(dbPanel, java.awt.BorderLayout.CENTER);
mainTabbedPane.repaint();
doDatabaseCheck();
}
/**
* Checks all the neccessary fields on the welcome tab
*/
private boolean doWelcomeCheck () {
boolean result = true;
//!projectnameTextField.getText().equals(new String())
if (configurator.isValidPath(projectnameTextField.getText())) {
//projectnameCheckBox.setSelected(true);
projectnameLabel .setForeground(COLOR_DEFAULT);
}
else {
result = false;
//projectnameCheckBox.setSelected(false);
projectnameLabel .setForeground(COLOR_RED);
}
if(result)
{ welcomeLabel.setEnabled(true); } else
{ welcomeLabel.setEnabled(false ); }
return result;
}
/**
* Checks for all neccessary fields on the database tab
*/
private boolean doDatabaseCheck() {
boolean result = true;
if (!connameTextField.getText().equals(new String()))
{connameLabel.setForeground(COLOR_DEFAULT );}
else
{result = false ; connameLabel.setForeground(COLOR_RED);}
if (!dbdriverTextField.getText().equals(new String()))
{dbdriverLabel.setForeground(COLOR_DEFAULT);}
else
{result = false ; dbdriverLabel.setForeground(COLOR_RED);}
if (!dburlTextField.getText().equals (new String()))
{dburlLabel.setForeground(COLOR_DEFAULT);}
else
{result = false ; dburlLabel.setForeground (COLOR_RED );}
if (!dbtimeoutTextField.getText().equals(new String ())) {
dbtimeoutLabel.setForeground(COLOR_DEFAULT );
try {
Autor: Thomas Schädler
121
Anhang A: Quelltext <xmlizer> configurator
Integer intvalue = new Integer(dbtimeoutTextField.getText());
}
catch(NumberFormatException nfe) {
dbtimeoutLabel.setForeground (COLOR_RED );
dbtimeoutTextField .setText("30");
}
}
else
{result = false ; dbtimeoutLabel .setForeground(COLOR_RED);}
if ((connameLabel.getForeground () == COLOR_DEFAULT) && (dbdriverLabel.getForeground() == COLOR_DEFAULT ))
{ drivertestButton.setEnabled(true); }
else
{ drivertestButton.setEnabled(false); }
if (result && dbdriverTested) {
connectButton.setEnabled(true);
}
else {
connectButton.setEnabled(false);
}
return result;
}
/**
* Checks for all the neccessary fields on the xml tab
*/
private boolean doXMLCheck() {
boolean chosen = false;
boolean validated = false;
boolean result = false;
if (!fileidentifierTextField.getText().equals(new String ()))
{result = true; fileidentifierLabel.setForeground(COLOR_DEFAULT);}
else
{result = false ; fileidentifierLabel .setForeground(COLOR_RED);}
if (!filenameTextField.getText().equals(new String()))
{result = true; filenameLabel.setForeground(COLOR_DEFAULT);}
else
{result = false ; filenameLabel.setForeground(COLOR_RED);}
if (result ) {
chosen = true;
}
if (this.XMLvalidated) {
validated = true;
}
//check here
if (chosen ) {
if (filenameText Field.getText().endsWith(".dtd" )) {
convertButton.setVisible(true);
validateButton.setEnabled(false);
}
else if (filenameTextField.getText().endsWith(".xsd" )) {
convertButton.setVisibl e(false);
validateButton.setEnabled(true);
}
}
else {
convertButton.setVisible(false);
validateButton.setEnabled(false);
}
return (chosen && validated);
}
/**
* Checks all fields on all tabs
*/
private void doCheck() {
boolean wcResult = doWelcomeCheck();
boolean dbResult = doDatabaseCheck();
boolean xmResult = doXMLCheck();
if (wcResult)
{ welcomeLabel.setEnabled(true); }
else
{ welcomeLabel.setEnabled(false ); }
if (dbResult && dbdriverLoaded) {
addNewDBButton.setEnabled(true);
dbBrowseButton.setEnabled(true);
}
else {
addNewDBButton.setEnabled(false);
dbBrowseButton.setEnabled(false);
}
if (xmResult) {
addNewXMLButton.setEnabled(true);
}
else {
addNewXMLButton.setEnabled(false );
}
if (databaseList.size() > 0) {
dbLabel.setEnabled(true);
dbListComboBox.setEnabled(true);
removeDBButton.setEnabled(true);
}
else {
dbLabel.setEnabled(false);
Autor: Thomas Schädler
122
Anhang A: Quelltext <xmlizer> configurator
dbListComboBox.setEnabled(false);
removeDBButton.setEnabled(false);
addDBButton .setEnabled (true);
}
if (xmlList.size() > 0) {
xmlListComboBox.setEnabled(true);
removeXMLButton.setEnabled(true);
}
else {
xmlListComboBox.setEnabled(false );
removeXMLButton.setEnabled(false );
addXMLButton.setEnabled(true);
}
if (welcomeLabel.isEnabled () && dbLabel.isEnabled()) {
finishButton.setEnabled(true);
}
else {
finishButton.setEnabled(false);
}
}
private void ConvertDTD2XMLSchema() {
//convert the currently selected DTD
String theDTD = filenameTextField.getText().trim();
StringBuffer convLog = new StringBuffer();
dtd2xs translator = new dtd2xs(convLog);
dtd2xsdOptions opt = new dtd2xsdOptions(mother ,true);
Hashtable options = opt.getOptions();
boolean resolveEntity = ((Boolean)options.get("entities" )).booleanValue ();
boolean ignoreComment = ((Boolean)options.get("comments" )).booleanValue ();;
int commentLength = dbItem .ConvertString2int((String)options.get("commentLength"));
String commentLanguage = (String)options.get("commentLanguage");
String conceptRelation = (String)options.get("conceptRelations");
int conceptHighlight = dbItem.ConvertString2int((String)options.get("conceptHighlight" ));
int conceptOccurrence = dbItem.ConvertString2int((String )options.get("minOccur"));
//go for it
File dtd = new File(theDTD );
//String filename = new String("e:\\forte \\configurator\\xml\\dtd2xsd\\complextype.xsl");
String filename = mother.getHomeBase () + "/xml/dtd2xsd/complextype.xsl" ;
File xslt = new File(filename);
String xsd = null;
xsd = translator.translate
(
"file:///" + dtd.getAbsolutePath(),
"file:///" + xslt.getAbsolutePath(),
resolveEntity,
ignoreComment,
commentLength,
commentLanguage ,
conceptRelation ,
conceptHighlight,
conceptOccurrence
);
//output it in the logWindow
if (xsd != null) {
dtd2xsdReport rept = new dtd2xsdReport(mother,true,"CONVERSION SUCCESSFULL\n\n"+convLog.toString(),xsd);
//show save warning
Object [] toptions = {"Yes","No"} ;
int warn = JOptionPane .showOptionDialog(
getContentPane(),
"Do you want to save the newly\ngenerated XML Schema!",
mother .APPNAME + " save new XSD" ,
JOptionPane .YES_NO_OPTION,
JOptionPane .QUESTION_MESSAGE,
null,
toptions,
toptions[1]
);
if (warn == JOptionPane.YES_OPTION) {
//open filechooser
File file = null;
String location = null;
JFileChooser chooser = new JFileChooser();
/* NO GOOD IDEA - FORBIDDEN TO STORE FILES IN THE PROJECT DIRS BY THE USER
chooser.setCurrentDirectory(
new File(
mother.getProjectBase()
+ mother.getFileSeparator()
+ ((dataItem)mother.getProjectData().getInitialByKey("name")).getValue()
+ mother.getFileSeparator()
));
**/
chooser.setDialogType(javax.swing .JFileChooser.SAVE_DIALOG );
simpleFileFilter filter = new simpleFileFilter();
filter.addExtension("xsd");
filter.setDescription("XSD Only");
chooser.setFileFilter(filter );
int returnVal = chooser.showSaveDialog (this);
if(returnVal == JFileChooser .APPROVE_OPTION ) {
file = chooser .getSelectedFile();
location = chooser.getSelectedFile ().getPath();
try {
FileWriter writer = new FileWriter(location);
writer.write(xsd);
Autor: Thomas Schädler
123
Anhang A: Quelltext <xmlizer> configurator
writer.close();
fileidentifierTextField.setText(file.getName());
filenameTextField.setText(location);
doCheck();
}
catch(Exception ex) {
mother.getLog().addError(ex);
return;
}
}
else {
//aborted
return;
}
}
//mother.getLog().addNewTab("DTD2XSD",xsd,"DTD2 XSD Conversion");
//mother.getLog().addNewTab("DTD2XSD Report",convLog.toString(),"DTD2XSD Conversion Report");
}
else {
dtd2xsdReport rept = new dtd2xsdReport(mother,true,"CONVERSION FAILED\n\n"+convLog.toString(),xsd);
//mother.getLog().addNewTab("DTD2XSD Error",convLog.toString(),"DTD2XSD Error Report");
}
}
public synchronized void update(configurator conf) {
this.mother = conf;
this.databaseList = conf.getProjectData().getDB(); //update the DBList
this.xmlList = conf.getProjectData().getXML(); //update the DBList
this.repaint();
}
/**
* Loads the current project data to display
*/
private void loadCurrentProjec tData () {
projectData theData = this.mother.getProjectData();
Vector theInitial = theData.getInitial();
Vector theDB
= theData.getDB();
Vector theXML
= theData.getXML();
//check for new setup or configuration change -> start the project or not after finishing setup
if (theInitial.size() == 0 && theDB.size() == 0 && theXML.size() == 0) {
isNewSetup = true;
}
else {
isNewSetup = false;
//disable change of module (only for new modules!)
mappingmoduleComboBox.setEnabled (false);
projectnameTextField.setEnabled(false );
//no new setup, so init the components
String projectName = ((dataItem)theData.getInitialByKey("name" )).getValue();
String projectModule = ((dataItem)theData.getInitialByKey ("module")).getValue ();
projectnameTextField.setText(projectName);
mappingmoduleComboBox.setSelectedItem (projectModule);
if (xmlList.size() > 0) {
xmlListComboBox.setSelectedIndex(0);
}
if (databaseList .size() > 0) {
dbListComboBox.setSelectedIndex(0);
}
}
}
/**
* Returns the password from the JPasswordField as lightly encrypted code
* (just to minimize time of unecrypted password in memory and to store it in a file)
*/
private String getSecurePassword() {
char[] pw = dbpasswordTextField .getPassword();
StringBuffer result = new StringBuffer();
char[] sec_char = new char[]{'x','m','l','i','z','e','r'};
int incr = 0;
char actual;
for (int i=0;i<pw.length;i++) {
if (incr<sec_char.length-1){incr++;}else{incr=0;}
actual = pw[i];
result .append(actual ^ sec_char[incr]);
result .append(':');
pw[i] = 0; //for security reasons
}
return result.toString();
}
/**
* DOM Parsers ErrorHandler
*/
public class ErrorChecker extends DefaultHandler {
public ErrorChecker() {
}
public void error(SAXParseException e) {
outputTextArea.setText ("Parsing error: "+e.getMessage());
}
public void warning(SAXParseException e) {
outputTextArea.setText ("Parsing problem: " +e.getMessage());
}
public void fatalError(SAXParseException e) {
Autor: Thomas Schädler
124
Anhang A: Quelltext <xmlizer> configurator
outputTextArea.setText ("Parsing error: "+e.getMessage());
outputTextArea.setText ("Cannot continue.");
}
}
}
/*
* dbBrowser.java
*
* Created on 17. Mai 2002, 20:28
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
java.io.*;
java.sql.*;
java.util.*;
org.jdom.*;
org.jdom.output.XMLOutputter;
java.awt.event.*;
javax.swing .*;
javax.swing .table.*;
javax.swing .tree.*;
java.util.Vector ;
java.util.Enumeration ;
java.awt.*;
java.awt.dnd.*;
java.awt.event.*;
java.awt.datatransfer .*;
/**
* The databrowser (a simple browser for database-connections
* with methods for the module DB2XML
* @author [email protected]
*/
public class dbBrowser extends MyInternalFrame {
private configurator mother;
private String ID;
private JPopupMenu popup = new JPopupMenu();
private JMenu mnuAutoresize = new JMenu();
private JMenuItem nextMI ;
private JMenuItem lastMI ;
private JMenuItem setChunk;
private JRadioButtonMenuItem mniOn = new JRadioButtonMenuItem("on");
private JRadioButtonMenuItem mniOff = new JRadioButtonMenuItem("off");
private int autoresize = JTable.AUTO_RESIZE_ALL_COLUMNS ;
private projectData theData;
private Vector dbList = new Vector();
private Vector tableList = new Vector();
private boolean isLoading = true;
private boolean isUpdating = false;
private String currentlySelectedTable = new String ();
private DataChooser dataChooser = null;
//Thread related
private activityMeter activity ;
private volatile Thread updateThread = null;
private volatile Thread workerThread = null;
private volatile Thread controllerThread = null;
private boolean StopAllThreads = false; //flag used to stop long tasks (but not the controller thread)
//TakeoverMode
private SchemaElement takeoverelement = null;
private boolean takeovermode = false;
private String lastSQLStatement = new String();
/** Creates new form dbBrowser */
public dbBrowser(configurator mainProgram,String uid) {
this.mother = mainProgram;
this.ID = uid;
this.theData = mainProgram .getProjectData ();
if (mainProgram .nextDBToBrowse.size() > 0) {
this.dbList = mainProgram.nextDBToBrowse;
}
else {
this.dbList = mainProgram.getProjectData().getDB();
}
initComponents();
activity = new activityMeter(stopButton,theProgressBar);
//add the popupmenu
//add data browser
nextMI = new JMenuItem("Next");
lastMI = new JMenuItem("Last");
nextMI.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (ActionEvent e) {
nextMI_actionPerformed(e);
}
Autor: Thomas Schädler
125
Anhang A: Quelltext <xmlizer> configurator
});
lastMI.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (ActionEvent e) {
lastMI_actionPerformed(e);
}
});
popup.add(nextMI);
popup.add(lastMI);
popup.addSeparator();
//add the entry to set the chunksize
setChunk = new JMenuItem("Set Rows ("+getActiveDB().getChunkSize()+")");
setChunk.addActionListener (new java.awt.event.ActionListener() {
public void actionPerformed (ActionEvent e) {
setChunk_actionPerformed(e);
}
});
popup.add(setChunk);
//add autoresize toggle
mnuAutoresize.setText("Autoresize");
mnuAutoresize.add(mniOn);
mnuAutoresize.add(mniOff);
mniOn.setSelected(true);
mniOn.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (ActionEvent e) {
mniOn_actionPerformed(e);
}
});
mniOff.setSelected(false);
mniOff.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (ActionEvent e) {
mniOff_actionPerformed(e);
}
});
popup.add(mnuAutoresize);
//init other stuff
if (dbList .size() > 0) {
dbComboBox.setSelectedIndex (0);
}
upperPanel .repaint();
isLoading = false;
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
private void initComponents()//GEN-BEGIN:initComponents
{
upperPanel = new javax.swing.JPanel();
dbLabel = new javax.swing.JLabel();
dbComboBox = new javax.swing.JComboBox(dbList);
sqlButton = new javax.swing.JButton();
helpButton = new javax.swing.JButton();
sqlLabel = new javax .swing .JLabel();
sqlScrollPane = new javax.swing .JScrollPane();
sqlTextArea = new DNDTextArea();
stopButton = new javax.swing.JButton();
theProgressBar = new javax .swing.JProgressBar();
limitCheckBox = new javax.swing .JCheckBox ();
obenPanel = new javax.swing.JPanel();
jSplitPane2 = new javax.swing.JSplitPane();
jPanel4 = new javax.swing.JPanel();
listScrollPane = new javax .swing.JScrollPane();
dbtableList = new javax.swing.JList(tableList);
jPanel5 = new javax.swing.JPanel();
jLabel2 = new javax.swing.JLabel();
tableScrollPane = new javax.swing.JScrollPane();
dbTable = new javax.swing.JTable();
setMaximizable(true);
setTitle("Database Browser");
setIconifiable(true);
setResizable(true);
setClosable(true);
addInternalFrameListener(new javax.swing.event .InternalFrameListener()
{
public void internalFrameOpened(javax .swing.event.InternalFrameEvent evt )
{
}
public void internalFrameClosing (javax.swing.event.InternalFrameEvent evt)
{
formInternalFrameClosing(evt);
}
public void internalFrameClosed(javax .swing.event.InternalFrameEvent evt )
{
}
public void internalFrameIconified(javax.swing.event .InternalFrameEvent evt)
{
}
public void internalFrameDeiconified(javax .swing.event.InternalFrameEvent evt )
{
}
public void internalFrameActivated(javax.swing.event .InternalFrameEvent evt)
{
}
public void internalFrameDeactivated(javax .swing.event.InternalFrameEvent evt )
{
}
});
upperPanel .setLayout (new java.awt.GridBagLayout());
Autor: Thomas Schädler
126
Anhang A: Quelltext <xmlizer> configurator
java.awt.GridBagConstraints gridBagConstraints1;
dbLabel.setText("Database:");
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints1.insets = new java.awt.Insets(0, 2, 0, 0);
upperPanel .add(dbLabel, gridBagConstraints1);
dbComboBox .setPreferredSize(new java.awt.Dimension(240, 27));
dbComboBox .setMinimumSize(new java.awt.Dimension(126, 27));
dbComboBox .setMaximumSize(new java.awt.Dimension(32767, 27));
dbComboBox .addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
dbComboBoxActionPerformed(evt);
}
});
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.insets = new java.awt.Insets(2, 0, 2, 0);
gridBagConstraints1.anchor = java.awt.GridBagConstraints .WEST;
upperPanel .add(dbComboBox, gridBagConstraints1 );
sqlButton.setIcon(new javax.swing.ImageIcon(getClass().getResource ("/configurator/icons/actions/execute.gif")));
sqlButton.setToolTipText("Query the database with your SQL");
sqlButton.setPreferredSize (new java.awt.Dimension(51, 51));
sqlButton.setMaximumSize(new java.awt.Dimension(51, 51));
sqlButton.setSelected(true);
sqlButton.setMinimumSize(new java.awt.Dimension(51, 51));
sqlButton.addActionListener(new java.awt.event .ActionListener ()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
sqlButtonAct ionPerformed(evt);
}
});
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 3;
gridBagConstraints1.gridy = 1;
gridBagConstraints1.insets = new java.awt.Insets(0, 2, 0, 2);
gridBagConstraints1.anchor = java.awt.GridBagConstraints .WEST;
upperPanel .add(sqlButton, gridBagConstraints1);
helpButton .setIcon(new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/Help16.gif")));
helpButton .setToolTipText("Open Help");
helpButton .setFont(new java.awt.Font("Dialog", 0, 10));
helpButton .addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
helpButtonActionPerformed(evt);
}
});
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 4;
gridBagConstraints1.gridy = 0;
gridBagConstraints1.insets = new java.awt.Insets(0, 0, 0, 2);
gridBagConstraints1.anchor = java.awt.GridBagConstraints .EAST;
upperPanel .add(helpButton, gridBagConstraints1 );
sqlLabel.setText("SQL Query:");
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 0;
gridBagConstraints1.gridy = 1;
gridBagConstraints1.insets = new java.awt.Insets(0, 2, 0, 0);
upperPanel .add(sqlLabel, gridBagConstraints1);
sqlTextArea.setLineWrap(true);
sqlTextArea.setColumns(45);
sqlTextArea.setRows(3);
sqlScrollPane.setViewportView(sqlTextArea );
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 1;
gridBagConstraints1.gridy = 1;
gridBagConstraints1.gridwidth = 2;
gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
upperPanel .add(sqlScrollPane, gridBagConstraints1);
stopButton .setIcon(new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/Stop16.gif")));
stopButton .setToolTipText("Stop background activity.");
stopButton .setEnabled(false);
stopButton .addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
stopButtonActionPerformed(evt);
}
});
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 3;
gridBagConstraints1.gridy = 0;
gridBagConstraints1.insets = new java.awt.Insets(0, 2, 0, 2);
gridBagConstraints1.anchor = java.awt.GridBagConstraints .WEST;
upperPanel .add(stopButton, gridBagConstraints1 );
theProgressBar.setToolTipText("Shows the progress for longer tasks");
theProgressBar.setPreferredSize (new java.awt.Dimension(148, 21));
theProgressBar.setMinimumSize(new java.awt.Dimension(10, 21));
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 2;
Autor: Thomas Schädler
127
Anhang A: Quelltext <xmlizer> configurator
gridBagConstraints1.gridy = 0;
gridBagConstraints1.insets = new java.awt.Insets(0, 0, 0, 2);
gridBagConstraints1.anchor = java.awt.GridBagConstraints .EAST;
upperPanel .add(theProgressBar, gridBagConstraints1);
limitCheckBox.setToolTipText("If selected, the results are diplayed in browsable chunks, not as one large table.");
limitCheckBox.setText("limit");
limitCheckBox.addItemListener(new java.awt.event.ItemListener ()
{
public void itemStateChanged(java.awt.event.ItemEvent evt )
{
limitCheckBoxItemStateChanged(evt);
}
});
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 4;
gridBagConstraints1.gridy = 1;
gridBagConstraints1.insets = new java.awt.Insets(0, 0, 0, 2);
gridBagConstraints1.anchor = java.awt.GridBagConstraints .EAST;
upperPanel .add(limitCheckBox, gridBagConstraints1);
getContentPane().add(upperPanel , java.awt.BorderLayout.NORTH);
obenPanel.setLayout(new java.awt.BorderLayout());
jSplitPane2.setDividerLocation(120);
jSplitPane2.setOneTouchExpandable(true);
jPanel4.setLayout(new java.awt.BorderLayout());
listScrollPane.setViewportView(dbtableList);
jPanel4.add(listScrollPane, java.awt.BorderLayout.CENTER );
jPanel5.setLayout(new java.awt.GridBagLayout());
java.awt.GridBagConstraints gridBagConstraints2;
jLabel2.setText("Tables");
jLabel2.setHorizontalAlignment(javax .swing.SwingConstants.CENTER);
gridBagConstraints2 = new java.awt.GridBagConstraints();
gridBagConstraints2.insets = new java.awt.Insets(0, 0, 0, 2);
jPanel5.add(jLabel2, gridBagConstraints2);
jPanel4.add(jPanel5, java.awt.BorderLayout.NORTH);
jSplitPane2.setLeftComponent(jPanel4);
tableScrollPane .setPreferredSize(new java.awt.Dimension(400, 320));
dbTable.setPreferredScrollableViewportSize(new java.awt.Dimension(400, 350));
tableScrollPane .setViewportView (dbTable);
jSplitPane2.setRightComponent(tableScrollPane);
obenPanel.add(jSplitPane2, java.awt.BorderLayout.CENTER);
getContentPane().add(obenPanel, java.awt.BorderLayout.CENTER);
pack();
}//GEN-END:initComponents
private void limitCheckBoxItemStateChanged(java.awt.event.ItemEvent evt)//GEN-FIRST:event_limitCheckBoxItemStateChanged
{//GEN-HEADEREND:event_limitCheckBoxItemStateChanged
// Add your handling code here:
if (!isUpdating ) {
getActiveDB ().setLimit (!getActiveDB().hasLimit());
}
}//GEN-LAST:event_limitCheckBoxItemStateChanged
private void stopButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN -FIRST:event_stopButtonActionPerformed
{//GEN-HEADEREND:event_stopButtonActionPerformed
// Add your handling code here:
Runnable r = new Runnable() {
public void run() {
stopButton.setEnabled(false);
sqlButton.setEnabled(true);
activity.init();
StopAllThreads = true;
mother.getLog().addInformation("Background activity stopping...");
}
};
controllerThread = new Thread(r);
controllerThread.start();
}//GEN-LAST:event_stopButtonActionPerformed
private void dbComboBoxActionPerformed(java.awt.event.ActionEvent evt)//GEN -FIRST:event_dbComboBoxActionPerformed
{//GEN-HEADEREND:event_dbComboBoxActionPerformed
// Add your handling code here:
if (!isLoading) {
updateDB(); //updates the DB Browser
}
}//GEN-LAST:event_dbComboBoxActionPerformed
public void setDataChooser(DataChooser data) {
this.dataChooser = data;
}
private void formInternalFrameClosing(javax.swing.event .InternalFrameEvent evt)//GEN-FIRST:event_formInternalFrameClosing
{//GEN-HEADEREND:event_formInternalFrameClosing
// Add your handling code here:
if (this.takeovermode && this.takeoverelement != null) {
dbItem dbitem = this.getActiveDB ();
if (dbitem != null) {
if (dbitem.getLastStatement() != null) {
if (this.takeoverelement .getRepetition() == null) {
Autor: Thomas Schädler
128
Anhang A: Quelltext <xmlizer> configurator
this.takeoverelement .addSQLStatement(dbitem.getLastStatement ());
}
else if (dbitem.getLastStatement().getRowNumber() == 1) {
this.takeoverelement.addSQLStatement(dbitem.getLastStatement ());
}
else {
mother.getLog().addWarning("You can only have one SQL query with more than one result-row (repet ition)!");
}
dbitem.clearLastStatement(); //clear the dbitem's sql cache
}
}
mother .getProjectData().setDirty ();
if (this.dataChooser != null) {
mother.close (this.dataChooser.getWinID ());
mother.mappingState = true;
}
SQLChooser ch = (SQLChooser )mother.open("SQLChooser" );
ch.updateView(this.takeoverelement);
}
mother.nextDBToBrowse.removeAllElements();
mother.close(this.ID);
}//GEN-LAST:event_formInternalFrameClosing
private void helpButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN -FIRST:event_helpButtonActionPerformed
{//GEN-HEADEREND:event_helpButtonActionPerformed
// Add your handling code here:
helpWindow help = (helpWindow)mother .open("help");
help.loadPage("/configurator/help/module_db2xml_databrowser.html");
}//GEN-LAST:event_helpButtonActionPerformed
private void sqlButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_sqlButtonActionPerformed
{//GEN-HEADEREND:event_sqlButtonActionPerformed
// Add your handling code here:
if (!(sqlTextArea.getText().trim().equalsIgnoreCase (new String()))) {
try {
doSQL(sqlTextArea.getText().trim(),true);
}
catch(Exception sqlex) {
mother.getLog().addError(sqlex);
}
}
else {
sqlTextArea .setText(this.lastSQLStatement);
}
}//GEN-LAST:event_sqlButtonActionPerformed
// Variables declaration - do not modify//GEN -BEGIN:variables
private javax.swing .JPanel upperPanel;
private javax.swing .JLabel dbLabel;
private javax.swing .JComboBox dbComboBox ;
private javax.swing .JButton sqlButton;
private javax.swing .JButton helpButton;
private javax.swing .JLabel sqlLabel ;
private javax.swing .JScrollPane sqlScrollPane ;
private javax.swing .JTextArea sqlTextArea;
private javax.swing .JButton stopButton;
private javax.swing .JProgressBar theProgressBar;
private javax.swing .JCheckBox limitCheckBox;
private javax.swing .JPanel obenPanel;
private javax.swing .JSplitPane jSplitPane2;
private javax.swing .JPanel jPanel4;
private javax.swing .JScrollPane listScrollPane;
private javax.swing .JList dbtableList;
private javax.swing .JPanel jPanel5;
private javax.swing .JLabel jLabel2;
private javax.swing .JScrollPane tableScrollPane;
private javax.swing .JTable dbTable;
// End of variables declaration//GEN-END:variables
/**
* Updated the TreeView of the Database
*/
synchronized private void updateDB() {
mother.getLog().addInformation("Retrieving tables from selected database..." );
final dbItem theDB = getActiveDB();
final dbBrowser This = this;
if (theDB != null) {
Runnable r = new Runnable() {
public void run() {
activity .start (false);
dbtableList.setEnabled(false);
isUpdating = true;
limitCheckBox.setSelected(theDB.hasLimit());
isUpdating = false;
try {
tableList = theDB.getTableList ();
}
catch(Exception e) {
activity.stop(false);
mother.getLog().addError(e);
return;
}
//make the new list
dbtableList = new JList(tableList);
//make the list functional
dbtableList.getSelectionModel ().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
//add the mouselistener
Autor: Thomas Schädler
129
Anhang A: Quelltext <xmlizer> configurator
ItemListener ilst = new ItemListener(This);
dbtableList.addMouseListener(ilst);
//show the new list
listScrollPane .getViewport().add(dbtableList );
dbtableList.setEnabled(true);
setChunk .setText("Set Rows (" +theDB.getChunkSize()+")");
mother.getLog().addInformation("Tablelist updated.");
activity .stop(false );
}
};
updateThread = new Thread(r);
StopAllThreads = false ;
updateThread.start();
}
}
synchronized public void chooseDB(String dbkey) {
int counter = 0;
for (Enumeration e = this.dbList.elements (); e.hasMoreElements();) {
dbItem item = (dbItem)e.nextElement();
//System.out.println("SEARC HING: " + dbkey + " >> " + item.getName());
if (item.getName().equalsIgnoreCase(dbkey)) {
this.dbtableList.setSelectedIndex (counter);
this.dbComboBox.setSelectedIndex(counter);
//System.out.println(" >> MATCH >> " + counter);
}
else counter++;
}
}
public synchronized void inspect(SQLStatement stat ) {
chooseDB(stat.getDB());
sqlTextArea.setText(stat.getSQL ());
doSQL(stat.getSQL(),true);
}
/** Returns xxx from xxx:yyy */
private String getFirst(String s,int cutter) {
int doublepoint = s.indexOf(":");
if (doublepoint != 0) {
return s.substring(cutter,doublepoint );
}
else return s;
}
/** Returns yyy from xxx:yyy */
private String getSecond (String s,int cutter) {
int doublepoint = s.indexOf(":");
if (doublepoint != 0) {
return s.substring(++doublepoint ,s.length()-cutter);
}
else return s;
}
private String getSubstitution (String query) {
StringBuffer result = new StringBuffer();
int counter = 0;
StringTokenizer st = new StringTokenizer(query );
while (st.hasMoreTokens()) {
String token = st.nextToken ();
//parameter substitution
if (token.startsWith("[-") && token.endsWith("-]")) {
StringBuffer newToken = new StringBuffer();
String mapid = getFirst (token,2);
String mapinfo = getSecond(token,2);
ParameterInfo thisinfo = mother.getProjectData().DB2XMLgetmapping().getParameterByMapID(mapid);
newToken.append(thisinfo.getValue ());
result.append(newToken.toString());
}
//sql substitution
else if (token.startsWith("[") && token.endsWith("]")) {
StringBuffer newToken = new StringBuffer();
// [mapid:mapinfo]
// evaluierungsschritte:
// 1. SQLStatment holen für den angegebenen key
String mapid = getFirst (token,1);
String mapinfo = getSecond(token,1);
//newToken.append("**" + mapid + "=" + mapinfo + "**");
// 2. dbItem holen für das angegebene SQLStatement (siehe XMLSchemaParser)
SQLStatement stat = mother.getProjectData().DB2XMLgetmapping().getSQLStatementByMapID(mapid);
//newToken.append(stat.toString());
dbItem used_db_item = mother .getProjectData ().getDBByName(stat.getDB ());
Hashtable sql_result;
// 3. SQL auf dieser datenbank ausführen:
try {
String s ub_query = getSubstitution (stat.getSQL());
sql_result = used_db_item.querySilentWithLimit(sub_query,1);
// -- bei nur einem resultat -> dieses aus der übereinstimmenden namen (z.B. dbKey) ersetzen
// -- bei mehreren resultaten -> einfach das erste nehemn (alternativ oben das limit gleich ändern)
// 4. das ganze noch richtig ersetzen (Stringmässig) und dann ab damit zurück nach Hause
Vector colnames = (Vector)sql_result.get("columnname");
int col = 0;
for (Enumeration en = colnames.elements (); en.hasMoreElements();) {
String currname = (String )en.nextElement ();
if (currname.equalsIgnoreCase(mapinfo)) {
break;
}
col++;
}
String info[][] = (String[][])sql_result.get("table");
Autor: Thomas Schädler
130
Anhang A: Quelltext <xmlizer> configurator
String resultString = info[col][0];
newToken .append(" ");
newToken .append(resultString);
result.append(newToken.toString());
counter++;
}
catch (Exception ex) {
mother.getLog().addError (ex);
}
}
else {
result.append(" ");
result.append(token);
}
}
return result.toString();
}
private String resolveQuery(String query ) {
//do all data operations on the embedded queries and replace them internally!
StringBuffer result = new StringBuffer();
//parse the query and substitute the SQLColumnInfo-Strings
//with the real value from the following new statement: (example)
result.append(getSubstitution(query));
//achtung! "[..] "könnte probleme machen - format suchen!!
return result.toString();
}
/**
* Shows the specified queries' resultset in a JTable
*/
synchronized private void doSQL(String sqlQuery,boolean reset) {
//finalize for runnable
final String ThesqlQuery = sqlQuery;
final dbItem theDB = getActiveDB();
if (reset) { theDB.resetLimit(); }
this.lastSQLStatement = sqlQuery;
Runnable r = new Runnable() {
public void run() {
String resolvedQuery = resolveQuery(ThesqlQuery);
mother.getLog().addInformation("Resolved Query: " +
resolvedQuery);
Hashtable navData = new Hashtable ();
activity.start(false);
try {
dbTable = theDB.getQueryAsJTable(resolvedQuery);
theDB.updateLastSQLSQL(ThesqlQuery );
navData = theDB.getNavigator();
}
catch(Exception ex ) {
activity .stop(false );
mother.getLog().addError (ex);
return;
}
dbTable.addMouseListener(new java.awt.event .MouseAdapter() {
public void mouseClicked (MouseEvent e) {
dbTable_mouseClicked (e);
}
});
dbTable.setAutoResizeMode(autoresize);
tableScrollPane.getViewport().add(dbTable);
tableScrollPane.setBorder(BorderFactory.createTitledBorder (theDB.getName() + " >> SQL Query Result : Rows " +
navData.get("first") + "-" + navData.get("last") + " of " + navData.get("max")));
boolean hasNext = ((Boolean)navData.get("hasNext")).booleanValue();
boolean hasLast = ((Boolean)navData.get("hasLast")).booleanValue();
if (hasNext)
{ nextMI.setEnabled(true); }
else
{ nextMI.setEnabled(false); }
if (hasLast)
{ lastMI.setEnabled(true); }
else
{ lastMI.setEnabled(false); }
mother.getLog().addInformation("SQL Query returned a valid ResultSet.");
activity.stop(false);
}
};
workerThread = new Thread(r);
StopAllThreads = false;
workerThread.start();
}
private void dbTable_mouseClicked(MouseEvent e) {
if(SwingUtilities.isRightMouseButton (e)) {
popup.show(dbTable,e.getX(),e.getY());
}
}
private void nextMI_actionPerformed (ActionEvent e) {
getActiveDB().nextChunk();
try {
doSQL(getActiveDB().getLastSQL(),false);
}
catch(Exception ex) {
mother .getLog().addError(ex);
}
}
Autor: Thomas Schädler
131
Anhang A: Quelltext <xmlizer> configurator
private void lastMI_actionPerformed (ActionEvent e) {
getActiveDB().lastChunk();
try {
doSQL(getActiveDB().getLastSQL(),false);
}
catch(Exception ex) {
mother .getLog().addError(ex);
}
}
private void mniOff_actionPerformed (ActionEvent e) {
autoresize = JTable.AUTO_RESIZE_OFF;
dbTable.setAutoResizeMode(autoresize );
mniOff.setSelected(true);
mniOn.setSelected(false);
}
private void mniOn_actionPerformed(ActionEvent e) {
autoresize = JTable.AUTO_RESIZE_ALL_COLUMNS;
dbTable.setAutoResizeMode(autoresize );
mniOff.setSelected(false);
mniOn.setSelected(true);
}
/**
* Sets the number of rows to display per DB retrieve
*/
private void setChunk_actionPerformed(ActionEvent e) {
String input = dbItem.Convertint2String(getActiveDB ().getChunkSize ());
String before = new String (input);
input = JOptionPane.showInputDialog("Enter the number of rows to show:" );
if ((input != null) && (!input.equalsIgnoreCase(new String())) && (!input.equalsIgnoreCase(before ))) {
int newvalue = dbItem.ConvertString2int(input);
getActiveDB ().setChunkSize(newvalue);
setChunk.setText("Set Rows ("+newvalue+")");
mother .getLog().addInformation("Changed number of rows to display to " + newvalue + ".");
}
}
/**
* This method updates the UI if the setupwindow is closed
* (and a change in the setup component occured)
*/
public synchronized void update(configurator conf) {
isLoading = true;
dbtableList.setEnabled(false);
this.mother = conf;
this.theData = conf.getProjectData();
if (conf.nextDBToBrowse.size() > 0) {
this.dbList = conf.nextDBToBrowse;
}
else {
this.dbList = conf.getProjectData().getDB();
}
if (dbList .size() > 0) {
dbComboBox.setSelectedIndex (0);
}
this.repaint();
isLoading = false;
}
public void enableTakeover(SchemaElement el) {
this.takeoverelement = el;
this.takeovermode = true;
}
/**
* Returns the currently selected dbItem
*/
synchronized private dbItem getActiveDB() {
return (dbItem)dbComboBox.getSelectedItem ();
}
/**
* Drop-Enabled JTextArea
*/
class DNDTextArea extends JTextArea implements DropTargetListener {
// Constructor
public DNDTextArea() {
super();
// create a drop target for this component
DropTarget dt = new DropTarget(this, this);
//this.setForeground(java.awt.Color.red);
}
/** Returns true if the string contains NO : */
private boolean isValidData(String s ) {
int doublepoint = s.indexOf(":");
if (doublepoint < 0) {
return true;
}
else return false;
}
// DropTargetListener interface implementation
public void drop(DropTargetDropEvent event) {
/*System.out.println("END > drop");*/
try {
Transferable transferable = event .getTransferable();
// we accept only Strings
if (transferable.isDataFlavorSupported (DataFlavor.stringFlavor)) {
event.acceptDrop(DnDConstants .ACTION_COPY);
String s = (String)transferable.getTransferData(DataFlavor.stringFlavor);
//System.out.println("DROP >>>>>" + s);
Autor: Thomas Schädler
132
Anhang A: Quelltext <xmlizer> configurator
if (s != null /*&& isValidData(s)*/) {
append(" ");
append(s);
this.repaint();
}
else {
mother.getLog().addWarning("You can only drop table results from the Data Chooser!");
}
event.getDropTargetContext().dropComplete(true);
}
else {
event.rejectDrop();
}
}
catch (java.io.IOException exception) {
System.err.println ( "Exception" + exception.getMessage());
event.rejectDrop();
}
catch (UnsupportedFlavorException ufException ) {
System.err.println ( "Exception" + ufException.getMessage());
event.rejectDrop();
}
}
//REST UNUSED
public void dragEnter(DropTargetDragEvent dtde )
{ /*System.out.println("END > dragEnter");*/ }
public void dragExit (DropTargetEvent dte)
{ /*System.out.println("END > dragExit");*/ }
public void dragOver (DropTargetDragEvent dtde)
{ /*System.out.println("END > dragOver");*/ }
public void dropActionChanged(DropTargetDragEvent dtde)
{ /*System.out.println("END > dropActionChanged");*/ }
}
/**
* Listens for listItem-(Mouse)-Events on the dbtableList
* -> For database queries
*/
class ItemListener implements MouseListener {
protected dbBrowser m_parent;
protected JList m_list;
public ItemListener(dbBrowser parent ) {
m_parent = parent;
m_list = parent.dbtableList ;
}
public void mouseClicked(MouseEvent e) {
doAction();
}
public
{}
public
{}
public
{}
public
{}
void mousePressed(MouseEvent e)
void mouseReleased(MouseEvent e)
void mouseEntered(MouseEvent e)
void mouseExited(MouseEvent e )
protected void doAction() {
int index = m_list.getSelectedIndex();
if (index < 0) {
return;
}
listItem data = (listItem)m_list .getModel().getElementAt(index );
mother .getLog().addInformation("Retrieving table " + data.getName() + "...");
getActiveDB ().resetLimit();
doSQL("SELECT * FROM " + data.getName(),true);
}
}
}/*
* SMDBEmain.java
*
* Created on 13. Mai 2009, 16:31
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import
import
import
import
import
import
import
import
import
import
java.io.*;
java.sql.*;
java.util.*;
org.jdom.*;
org.jdom.output.XMLOutputter;
java.awt.event.*;
javax.swing .event.*;
javax.swing .border.*;
javax.swing .*;
javax.swing .table.*;
Autor: Thomas Schädler
133
Anhang A: Quelltext <xmlizer> configurator
import
import
import
import
import
import
javax.swing .tree.*;
javax.swing .text.*;
java.util.Vector ;
java.util.Enumeration ;
org.xml.sax.*;
org.xml.sax.helpers.AttributesImpl;
/**
* The main class/internalframe of the module SMDBE
* @author [email protected]
*/
public class SMDBEmain extends MyInternalFrame {
private configurator mother;
private String ID;
private JPopupMenu popup = new JPopupMenu();
private JMenu mnuAutoresize = new JMenu();
private JRadioButtonMenuItem mniOn = new JRadioButtonMenuItem("on");
private JRadioButtonMenuItem mniOff = new JRadioButtonMenuItem("off");
private int autoresize = JTable.AUTO_RESIZE_ALL_COLUMNS ;
private JMenuItem nextMI ;
private JMenuItem lastMI ;
private JMenuItem setChunk;
private projectData theData;
private Vector dbList = new Vector();
private Vector tableList = new Vector();
private Vector levelList = new Vector();
private boolean isLoading = true;
private boolean isUpdating = false;
private String SPACER = new String("
");
//Thread related
private activityMeter activity ;
private volatile Thread updateThread = null;
private volatile Thread workerThread = null;
private volatile Thread controllerThread = null;
private boolean StopAllThreads = false; //flag used to stop long tasks (but not the controller thread)
public static String XMLSMDBEFILEDTD = "xmlizer.smdbe.verbose.dtd";
public static String XMLSMDBEFILEROOT = "database" ;
/** Creates new form SMDBEmain */
public SMDBEmain(configurator mainProgram, String uid) {
this.mother = mainProgram;
this.ID = uid;
this.theData = mainProgram.getProjectData ();
this.dbList = this.theData .getDB(); //update the DBList
levelList.add("simple");
levelList.add("verbose");
initComponents();
levelComboBox.setSelectedIndex(0);
activity = new activityMeter(stopButton,exportProgressBar);
//add the popupmenu
//add data browser
nextMI = new JMenuItem("Next");
lastMI = new JMenuItem("Last");
nextMI.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (ActionEvent e) {
nextMI_actionPerformed(e);
}
});
lastMI.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (ActionEve nt e) {
lastMI_actionPerformed(e);
}
});
popup.add(nextMI);
popup.add(lastMI);
popup.addSeparator();
//add the entry to set the chunksize
setChunk = new JMenuItem("Set Rows ("+getActiveDB().getChunkSize()+")");
setChunk.addActionListener (new java.awt.event.ActionListener() {
public void actionPerformed (ActionEvent e) {
setChunk_actionPerformed(e);
}
});
popup.add(setChunk);
//add autoresize toggle
mnuAutoresize.setText("Autoresize");
mnuAutoresize.add(mniOn);
mnuAutoresize.add(mniOff);
mniOn.setSelected(true);
mniOn.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (ActionEvent e) {
mniOn_actionPerformed(e);
}
});
mniOff.setSelected(false);
mniOff.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (ActionEvent e) {
mniOff_actionPerformed(e);
}
});
popup.add(mnuAutoresize);
//init other stuff
if (dbList .size() > 0) {
dbComboBox.setSelectedIndex(0);
}
upperPanel .repaint();
Autor: Thomas Schädler
134
Anhang A: Quelltext <xmlizer> configurator
isLoading = false;
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
private void initComponents() {//GEN-BEGIN:initComponents
upperPanel = new javax.swing.JPanel();
dbLabel = new javax.swing.JLabel();
dbComboBox = new javax.swing.JComboBox(dbList);
levelComboBox = new javax.swing .JComboBox (levelList );
exportButton = new javax.swing.JButton();
exportProgressBar = new javax.swing.JProgressBar();
stopButton = new javax.swing.JButton();
limitCheckBox = new javax.swing .JCheckBox ();
helpButton = new javax.swing.JButton();
obenPanel = new javax.swing.JPanel();
verSplitPane = new javax.swing.JSplitPane ();
dbtablePanel = new javax.swing.JPanel();
listScrollPane = new javax .swing.JScrollPane();
dbtableList = new javax.swing.JList(tableList);
buttonPanel = new javax.swing.JPanel ();
dbTablesLabel = new javax.swing .JLabel();
selectAllButton = new javax.swing.JButton();
tableScrollPane = new javax.swing.JScrollPane();
dbTable = new javax.swing.JTable();
setMaximizable(true);
setTitle("Simple Module DB Export");
setIconifiable(true);
setResizable(true);
dbLabel.setText("Database:");
upperPanel.add(dbLabel);
dbComboBox .addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
dbComboBoxActionPerformed(evt);
}
});
upperPanel .add(dbComboBox);
levelComboBox.setToolTipText("Output Level");
levelComboBox.addActionListener (new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
levelComboBoxActionPerformed (evt);
}
});
upperPanel .add(levelComboBox);
exportButton.setToolTipText("Exports the selected Tables as XML");
exportButton.setText("Export");
exportButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
exportButtonActionPerformed(evt);
}
});
upperPanel .add(expor tButton);
exportProgressBar.setToolTipText("Shows the progress for the export thread and DB queries.");
exportProgressBar.setPreferredSize(new java.awt.Dimension(148, 21));
exportProgressBar.setMinimumSize(new java.awt.Dimension(10, 21));
upperPanel .add(exportProgressBar);
stopButton .setIcon(new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/Stop16.gif")));
stopButton .setToolTipText("Stop background activity...");
stopButton .setEnabled(false);
stopButton .addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
stopButtonActionPerformed(evt);
}
});
upperPanel .add(stopButton);
limitCheckBox.setToolTipText("If selected, the results are diplayed in browsable chunks, not as one large table.");
limitCheckBox.setText("limit");
limitCheckBox.addItemListener(new java.awt.event.ItemListener () {
public void itemStateChanged(java.awt.event.ItemEvent evt ) {
limitCheckBoxItemStateChanged(evt);
}
});
upperPanel .add(limitCheckBox);
helpButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/Help16.gif")));
helpButton .setToolTipText("Open Help");
helpButton .setFont(new java.awt.Font("Dialog", 0, 10));
helpButton .addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
helpButtonActionPerformed(evt);
}
});
upperPanel .add(helpButton);
getContentPane().add(upperPanel , java.awt.BorderLayout.NORTH);
obenPanel.setLayout(new java.awt.BorderLayout());
verSplitPane.setDividerLocation (120);
Autor: Thomas Schädler
135
Anhang A: Quelltext <xmlizer> configurator
verSplitPane.setOneTouchExpandable(true);
dbtablePanel.setLayout(new java.awt.BorderLayout());
listScrollPane.setViewportView(dbtableList);
dbtablePanel.add(listScrollPane , java.awt.BorderLayout.CENTER );
buttonPanel.setLayout(new java.awt.GridBagLayout());
java.awt.GridBagConstraints gridBagConstraints1;
dbTablesLabel.setText("Tables");
dbTablesLabel.setHorizontalAlignment (javax.swing.SwingConstants.CENTER);
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 0;
gridBagConstraints1.gridy = 0;
gridBagConstraints1.gridwidth = 2;
buttonPanel.add(dbTablesLabel, gridBagConstraints1);
selectAllButton .setToolTipText("Select all tables");
selectAllButton .setText("invert selection");
selectAllButton .setMargin(new java.awt.Insets(1, 1, 1, 1));
selectAllButton .addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
selectAllButtonActionPerformed(evt);
}
});
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 0;
gridBagConstraints1.gridy = 1;
buttonPanel.add(selectAllB utton , gridBagConstraints1);
dbtablePanel.add(buttonPanel, java.awt.BorderLayout .NORTH);
verSplitPane.setLeftComponent(dbtablePanel);
tableScrollPane .setPreferredSize(new java.awt.Dimension(400, 300));
tableScrollPane .setViewportView (dbTable);
verSplitPane.setRightComponent(tableScrollPane );
obenPanel.add(verSplitPane , java.awt.BorderLayout.CENTER );
getContentPane().add(obenPanel, java.awt.BorderLayout.CENTER);
pack();
}//GEN-END:initComponents
private void levelComboBoxActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_levelComboBoxActionPerformed
{//GEN-HEADEREND:event_levelComboBoxActionPerformed
// Add your handling code here:
if (!isUpdating && !isLoading) {
if (levelComboBox.getSelectedItem() != null) {
String newLevel = (String)levelComboBox.getSelectedItem();
//System.out.println("SETTIN G LEVEL: "+newLevel);
getActiveDB().SMDBEsetOutputType(newLevel);
theData.setDirty();
}
}
}//GEN-LAST:event_levelComboBoxActionPerformed
private void limitCheckBoxItemStateChanged(java.awt.event.ItemEvent evt)//GEN-FIRST:event_limitCheckBoxItemStateChanged
{//GEN-HEADEREND:event_limitCheckBoxItemStateChanged
// Add your handling code here:
if (!isUpdating ) {
getActiveDB ().setLimit (!getActiveDB().hasLimit());
}
}//GEN-LAST:event_limitCheckBoxItemStateChanged
private void stopButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN -FIRST:event_stopButtonActionPerformed
{//GEN-HEADEREND:event_stopButtonActionPerformed
// Add your handling code here:
Runnable r = new Runnable() {
public void run() {
stopButton.setEnabled(false);
exportButton .setEnabled (true);
activity.init();
StopAllThreads = true;
getActiveDB().halt();
mother.getLog().addInformation("Sending stop request...");
}
};
controllerThread = new Thread(r);
controllerThread.start();
}//GEN-LAST:event_stopButtonActionPerformed
private void selectAllButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN FIRST:event_selectAllButtonActionPerformed
{//GEN-HEADEREND:event_selectAllButtonActionPerformed
// Add your handling code here:
for(int i = 0;i<tableList.size();i++) {
listItem data = (listItem)dbtableList .getModel().
getElementAt(i);
data.toggleSelection();
dbtableList .repaint();
if (data.isSelected()) {
getActiveDB().SMDBEselectTable(data.getName());
theData.setDirty();
}
else {
getActiveDB().SMDBEdeselectTable(data.getName());
theData.setDirty();
Autor: Thomas Schädler
136
Anhang A: Quelltext <xmlizer> configurator
}
}
}//GEN-LAST:event_selectAllButtonActionPerformed
private void helpButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN -FIRST:event_helpButtonActionPerformed
{//GEN-HEADEREND:event_helpButtonActionPerformed
// Add your handling code here:
helpWindow help = (helpWindow)mother .open("help");
help.loadPage("/configurator/help/module_smdbe_main.html");
}//GEN-LAST:event_helpButtonActionPerformed
private void dbComboBoxActionPerformed(java.awt.event.ActionEvent evt)//GEN -FIRST:event_dbComboBoxActionPerformed
{//GEN-HEADEREND:event_dbComboBoxActionPerformed
// Add your handling code here:
if (!isLoading) {
updateDB(); //updates the DB Browser
}
}//GEN-LAST:event_dbComboBoxActionPerformed
private void exportButtonActionPerformed (java.awt.event .ActionEvent evt)//GEN-FIRST:event_exportButtonActionPerformed
{//GEN-HEADEREND:event_exportButtonActionPerformed
// Add your handling code here:
doExport();
}//GEN-LAST:event_exportButtonActionPerformed
// Variables declaration - do not modify//GEN -BEGIN:variables
private javax.swing .JPanel upperPanel;
private javax.swing .JLabel dbLabel;
private javax.swing.JComboBox dbComboBox ;
private javax.swing .JComboBox levelComboBox;
private javax.swing .JButton exportButton ;
private javax.swing .JProgressBar exportProgressBar ;
private javax.swing .JButton stopButton;
private javax.swing .JCheckBox limitCheckBox;
private javax.swing .JButton helpButton;
private javax.swing .JPanel obenPanel;
private javax.swing .JSplitPane verSplitPane;
private javax.swing .JPanel dbtablePanel;
private javax.swing .JScrollPane listScrollPane;
private javax.swing .JList dbtableList;
private javax.swing .JPanel buttonPanel;
private javax.swing .JLabel dbTablesLabel ;
private javax.swing .JButton selectAllButton;
private javax.swing .JScrollPane tableScrollPane;
private javax.swing .JTable dbTable;
// End of variables declaration//GEN-END:variables
/**
* Updated the List of the Database -Tables
*/
synchronized private void updateDB() {
mother.getLog().addInformation("Retrieving tables from selected database...");
final dbItem theDB = getActiveDB();
final SMDBEmain This = this;
if (theDB != null) {
Runnable r = new Runnable() {
public void run() {
activity .start (false);
dbtableList.setEnabled(false);
//set limit and level
isUpdating = true;
limitCheckBox.setSelected(theDB.hasLimit());
levelComboBox.setSelectedItem (theDB.SMDBEgetOutputType ());
isUpdating = false;
try {
tableList = theDB.getTableList (); //vector of listItems
}
catch(Exception e) {
activity.stop(false);
mother.getLog().addError(e);
return;
}
//make the new list and set the renderer
dbtableList = new JList(tableList);
CheckListCellRenderer renderer = new CheckListCellRenderer();
dbtableList.setCellRenderer(renderer);
CheckListener lst = new CheckListener(This);
dbtableList.addMouseListener(lst);
ItemListener ilst = new ItemListener(This);
dbtableList.addMouseListener(ilst);
//set the selectionModel for the JList
dbtableList.getSelectionModel ().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
//show the new list
listScrollPane .getViewport().add(dbtableList );
dbtableList.setEnabled(true);
setChunk .setText("Set Rows (" +theDB.getChunkSize()+")");
mother.getLog().addInformation("Tablelist updated.");
activity .stop(false );
}
};
updateThread = new Thread(r);
StopAllThreads = false ;
updateThread.start();
}
}
Autor: Thomas Schädler
137
Anhang A: Quelltext <xmlizer> configurator
/**
* Shows the indicated table of the curr ent database
*/
private void doSQL(String sqlQuery) {
//finalize for runnable
final String ThesqlQuery = sqlQuery;
final dbItem theDB = getActiveDB();
Runnable r = new Runnable() {
public void run() {
Hashtable navData = new Hashtable ();
activity.start(false);
try {
dbTable = theDB.getQueryAsJTable(ThesqlQuery );
navData = theDB.getNavigator();
}
catch(Exception ex ) {
activity .stop(false );
mother.getLog().addError (ex);
return;
}
dbTable.addMouseListener(new java.awt.event .MouseAdapter() {
public void mouseClicked (MouseEvent e) {
dbTable_mouseClicked (e);
}
});
dbTable.setAutoResizeMode(autoresize);
tableScrollPane.getViewport().add(dbTable);
tableScrollPane.setBorder(BorderFactory.createTitledBorder (theDB.getName() + " >> SQL Query Result : Rows " +
navData.get("first") + "-" + navData.get("last") + " of " + navData.get("max")));
boolean hasNext = ((Boolean)navData.get("hasNext")).booleanValue();
boolean hasLast = ((Boolean)navData.get("hasLast")).booleanValue();
if (hasNext)
{ nextMI.setEnabled(true); }
else
{ nextMI.setEnabled(false); }
if (hasLast)
{ lastMI.setEnabled(true); }
else
{ lastMI.setEnabled(false); }
mother.getLog().addInformation("SQL Query returned a valid ResultSet.");
activity.stop(false);
}
};
workerThread = new Thread(r);
StopAllThreads = false;
workerThread.start();
}
/**
* Exports the selected Tables to the outputwindow (editorpane)
* and sets the selected tables in the dbItem (mapping info)
*/
private void doExport() {
//get the selected tables for this DB
final dbItem theDB = getActiveDB();
final Vector selectedTables = getSelectedTables();
//do sample/preview export in a new stoppable thread
Runnable r = new Runnable() {
public void run() {
activity.start(true);
dbComboBox.setEnabled(false);
exportButton .setEnabled (false);
levelComboBox.setEnabled(false);
mother.getLog().addInformation("Exporting selected tables as XML..." );
//export the data from the selected db and output the xml to the editorpane
try {
//NEW STYLE outputXMLResult(theDB,selectedTables,out);
String level = (String)levelComboBox.getSelectedItem();
File file = null;
if (level == null || level.equalsIgnoreCase(new String ())) {
level = "simple";
}
if (level.equalsIgnoreCase("simple")) {
file = outputXMLResultSimple(theDB,selectedTables);
}
else if (level .equalsIgnoreCase("verbose")) {
file = outputXMLResultVerbose(theDB ,selectedTables );
}
mother.getLog().addNewTab("DB Export:"+theDB .getName(),file,"DB Export Preview for DB: " +
theDB.getName());
}
catch (Exception ex) {
mother.getLog().addError (ex);
}
dbComboBox.setEnabled(true);
levelComboBox.setEnabled(true);
if (StopAllThreads ) {
mother.getLog().addWarning("Export aborted by user ... preview output may me incomplete!");
}
else {
mother.getLog().addInformation("XML Export successful terminated.");
}
exportButton .setEnabled (true);
activity.stop(true);
}
};
Autor: Thomas Schädler
138
Anhang A: Quelltext <xmlizer> configurator
workerThread = new Thread(r);
workerThread.setDaemon(true);
StopAllThreads = false;
workerThread.start();
}
/**
* Generates Simple DB Export XML from a selected DB and writes it to a temporary file
* Therfore it uses no DTD and writes just plain XML without any extra data
* @return a temprary file filled with XML
*/
private File outputXMLResultSimple(dbItem theDB,Vector tables) throws Exception {
File temp = File.createTempFile ("xmlizer" ,null);
temp.deleteOnExit();
FileOutputStream out = new FileOutputStream(temp);
//add the header and doctype
out.write(configurator.String2byteArray("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",null));
//add the <database name="dbname" url="dburl"> tag
out.write(configurator.String2byteArray("<database name= \""
+configurator.htmlEncode(theDB.getName())
+"\" url=\""
+configurator.htmlEncode(theDB.getUrl())
+"\">\n",null));
//monitor progress of export per table
final int maxi = tables.size();
activity.setMax (maxi);
int counter = 0;
//tables setup
out.write(configurator.String2byteArray(SPACER +"<tables> \n",null));
//for all tables
Runnable r ;
for (Enumeration e = tables.elements (); e.hasMoreElements();) {
if (StopAllThreads) {
out.close();
return temp;
}
counter++;
final int rcounter = counter;
r = new Runnable () {
public void run() {
activity .setValue(rcounter);
activity .setString(rcounter + " / " + maxi);
}
};
SwingUtilities.invokeLater(r);
//add the <table name="tablename"> tag
String this_table = (String )e.nextElement();
out.write(configurator .String2byteArray(SPACER+SPACER+"<"+this_table+">\n",null));
try {
Hashtable theTable = theDB.querySilent ("SELECT * FROM " + this_table );
final String data[][] = (String[][])theTable.get("table");
final int rows = ((Integer)theTable.get("rows")).intValue();
final int cols = ((Integer)theTable.get("cols")).intValue();
final Vector columnnames = (Vector)theTable .get("columnlabels");
//for each row of this table
for(int i=0;i<rows;i++) {
out.write(configurator.String2byteArray (SPACER+SPACER+SPACER+"<row>\n",null));
//for each column of the row
String encoded ;
String colname ;
for(int j=0;j<cols;j++) {
colname = configurator.htmlEncode((String)columnnames.get(j));
out.write(configurator.String2byteArray(SPACER+SPACER+SPACER +SPACER+"<"+colname+">",null));
encoded = configurator.htmlEncode((String)data[j][i]);
out.write(configurator.String2byteArray(encoded,null));
out.write(configurator.String2byteArray("</"+colname+">\n",null));
}
out.write(configurator.String2byteArray (SPACER+SPACER+SPACER+"</row>\n",null));
}
out.write(configurator.String2byteArray(SPACER+SPACER +"</"+this_table+">\n",null));
}
catch (Exception eq) {
mother.getLog().addError(eq);
}
}
out.write(configurator.String2byteArray(SPACER +"</tables>\n",null));
out.write(configurator.String2byteArray("</database>\n",null));
out.close();
return temp;
}
/**
* Generates Simple DB Export XML from a selected DB and writes it to a temporary file
* @return a temprary file filled with XML
*/
private File outputXMLResultVerbose (dbItem theDB,Vector tables) throws Exception {
File temp = File.createTempFile ("xmlizer" ,null);
temp.deleteOnExit();
FileOutputStream out = new FileOutputStream(temp);
//add the header and doctype
out.write(configurator.String2byteArray("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",null));
out.write(configurator.String2byteArray("<!DOCTYPE database SYSTEM \""+XMLSMDBEFILEDTD +"\">\n",null));
//add the <database name="dbname" url="dburl"> tag
out.write(configurator.String2byteArray("<database name= \""
+configurator.htmlEncode(theDB.getName())
Autor: Thomas Schädler
139
Anhang A: Quelltext <xmlizer> configurator
+"\" url=\""
+configurator.htmlEncode(theDB.getUrl())
+"\">\n",null));
//monitor progress of export per table
final int maxi = tables.size();
activity.setMax (maxi);
int counter = 0;
//tables setup
out.write(configurator.String2byteArray(SPACER +"<tables> \n",null));
//for all tables
Runnable r ;
for (Enumeration e = tables.elements (); e.hasMoreElements();) {
if (StopAllThreads) {
out.close();
return temp;
}
counter++;
final int rcounter = counter;
r = new Runnable () {
public void run() {
activity .setValue(rcounter);
activity .setString(rcounter + " / " + maxi);
}
};
SwingUtilities.invokeLater(r);
//add the <table name="tablename"> tag
String this_table = (String )e.nextElement();
out.write(configurator .String2byteArray(SPACER+SPACER+"<table name= \""+this_table+"\">\n",null));
try {
Hashtable theTable = theDB.querySilent ("SELECT * FROM " + this_table );
final String data[][] = (String[][])theTable.get("table");
final int rows = ((Integer)theTable.get("rows")).intValue();
final int cols = ((Integer)theTable.get("cols")).intValue();
final Vector columnnames = (Vector)theTable .get("columnlabels");
final Vector columntypes = (Vector)theTable .get("columntypes");
//for each row of this table
for(int i=0;i<rows;i++) {
out.write(configurator.String2byteArray (SPACER+SPACER+SPACER+"<row>\n",null));
//for each column of the row
String encoded ;
for(int j=0;j<cols;j++) {
out.write(configurator.String2byteArray(SPACER+SPACER+SPACER +SPACER+"<column",null));
encoded = configurator.htmlEncode((String)columnnames.get(j));
out.write(configurator.String2byteArray(" name=\""+encoded+"\"",null));
encoded = configurator.htmlEncode((String)columntypes.get(j));
out.write(configurator.String2byteArray(" type=\""+encoded+"\"",null));
encoded = configurator.htmlEncode((String)data[j][i]);
out.write(configurator.String2byteArray(" data=\""+encoded+"\"/>\n",null));
}
out.write(configurator.String2byteArray (SPACER+SPACER+SPACER+"</row>\n",null));
}
out.write(configurator.String2byteArray(SPACER+SPACER +"</table> \n",null));
}
catch (Exception eq) {
mother.getLog().addError(eq);
}
}
out.write(configurator.String2byteArray(SPACER +"</tables>\n",null));
out.write(configurator.String2byteArray("</database>\n",null));
out.close();
return temp;
}
/**
* Returns a vector containing all selected tables as string (tablename)
*/
synchronized public Vector getSelectedTables() {
Vector result = new Vector ();
for(int i = 0;i<tableList.size();i++) {
listItem data = (listItem)dbtableList .getModel().
getElementAt(i);
if (data.isSelected()) {
result.add(data.getName());
}
}
return result;
}
private void dbTable_mouseClicked(MouseEvent e) {
if(SwingUtilities.isRightMouseButton (e)) {
popup.show(dbTable,e.getX(),e.getY());
}
}
private void nextMI_actionPerformed (ActionEvent e) {
getActiveDB().nextChunk();
try {
doSQL(getActiveDB().getLastSQL());
}
catch(Exception ex) {
mother .getLog().addError(ex);
}
}
private void lastMI_actionPerformed (ActionEvent e) {
getActiveDB().lastChunk();
try {
doSQL(getActiveDB().getLastSQL());
Autor: Thomas Schädler
140
Anhang A: Quelltext <xmlizer> configurator
}
catch(Exception ex) {
mother .getLog().addError(ex);
}
}
private void mniOff_actionPerformed (ActionEvent e) {
autoresize = JTable.AUTO_RESIZE_OFF;
dbTable.setAutoResizeMode(autoresize );
mniOff.setSelected(true);
mniOn.setSelected(false);
}
private void mniOn_actionPerformed(ActionEvent e) {
autoresize = JTable.AUTO_RESIZE_ALL_COLUMNS;
dbTable.setAutoResizeMode(autoresize );
mniOff.setSelected(false);
mniOn.setSelected(true);
}
/**
* Sets the number of rows to display per DB retrieve
*/
private void setChunk_actionPerformed(ActionEvent e) {
String input = dbItem.Convertint2String(getActiveDB ().getChunkSize ());
String before = new String (input);
input = JOptionPane.showInputDialog("Enter the number of rows to show:" );
if ((input != null) && (!input.equalsIgnoreCase(new String())) && (!input.equalsIgnoreCase(before ))) {
int newvalue = dbItem.ConvertString2int(input);
getActiveDB ().setChunkSize(newvalue);
setChunk.setText("Set Rows ("+newvalue+")");
mother .getLog().addInformation("Changed number of rows to display to " + newvalue + ".");
}
}
/**
* This method updates the UI if the setupwindow is closed
* (and a change in the setup component occured)
*/
public synchronized void update(configurator conf) {
isLoading = true;
dbtableLis t.setEnabled(false); //be sure, perhaps the db got deleted!? who knows!
this.mother = conf;
this.theData = conf.getProjectData();
this.dbList = conf.getProjectData().getDB (); //update the DBList
//System.out.println (dbList.toString());
this.dbComboBox .setModel(new DefaultComboBoxModel(this.dbList ));
if (this.dbList .size() > 0) {
this.dbComboBox.setSelectedIndex (0);
}
this.repaint();
isLoading = false;
}
/**
* Returns the currently selected dbItem
*/
synchronized private dbItem getActiveDB() {
return (dbItem)dbComboBox.getSelectedItem ();
}
/**
* Listens for listItem-(Mouse)-Events on the dbtableList
* -> For database queries
*/
class ItemListener implements MouseListener {
protected SMDBEmain m_parent;
protected JList m_list;
public ItemListener(SMDBEmain parent ) {
m_parent = parent;
m_list = parent.dbtableList ;
}
public void mouseClicked(MouseEvent e) {
if (e.getX() > 20) {
doAction();
}
}
public
{}
public
{}
public
{}
public
{}
void mousePressed(MouseEvent e)
void mouseReleased(MouseEvent e)
void mouseEntered(MouseEvent e)
void mouseExited(MouseEvent e )
protected void doAction() {
int index = m_list.getSelectedIndex();
if (index < 0) {
return;
}
listItem data = (listItem)m_list .getModel().getElementAt(index );
mother .getLog().addInformation("Retrieving table " + data.getName() + "...");
getActiveDB().resetLimit();
doSQL("SELECT * FROM " + data.getName());
}
}
/**
Autor: Thomas Schädler
141
Anhang A: Quelltext <xmlizer> configurator
* Listens for CheckBox-(Mouse)-Events on the dbtableList
* -> For table-selection
*/
class CheckListener implements MouseListener {
protected SMDBEmain m_parent;
protected JList m_list;
public CheckListener (SMDBEmain parent) {
m_parent = parent;
m_list = parent.dbtableList ;
}
public void mouseClicked(MouseEvent e) {
if (e.getX() < 20) {
doCheck();
}
}
public
{}
public
{}
public
{}
public
{}
void mousePressed(MouseEvent e)
void mouseReleased(MouseEvent e)
void mouseEntered(MouseEvent e)
void mouseExited(MouseEvent e )
protected void doCheck() {
int index = m_list.getSelectedIndex();
if (index < 0) {
return;
}
listItem data = (listItem)m_list .getModel().getElementAt(index );
data.toggleSelection();
m_list .repaint();
if (data.isSelected()) {
getActiveDB().SMDBEselectTable(data.getName());
m_parent.theData.setDirty();
}
else {
getActiveDB().SMDBEdeselectTable(data.getName());
m_parent.theData.setDirty();
}
}
}
/**
* Renders the cells for the dbtableList (JList) with CheckBoxes etc.
*/
class CheckListCellRenderer extends JCheckBox implements ListCellRenderer {
protected final Border m_noFocusBorder = new EmptyBorder (1, 1, 1, 1);
public CheckListCellRenderer() {
super();
setOpaque(true);
setBorder(m_noFocusBorder);
}
public java.awt.Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
setText(value.toString ());
setBackground(isSelected ? list.getSelectionBackground() : list.getBackground ());
setForeground(isSelected ? list.getSelectionForeground() : list.getForeground ());
listItem data = (listItem)value;
setSelected (data.isSelected ());
setFont(list.getFont());
setBorder((cellHasFocus) ? UIManager.getBorder("List.focusCellHighlightBorder") : m_noFocusBorder);
return this;
}
}
}
/*
* projectData.java
*
* This projectData container contains all neccessary methods to deal
* with the projectData management
*
* Created on 5. April 2002, 16:30
* ------------------------------------------------------------------ ---------* This file is part of <xmlizer>.
*
* <xmlizer> 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 Licens e, or
* (at your option) any later version.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import
import
import
import
java.io.*;
java.util.*;
java.lang.*;
javax.swing .*;
Autor: Thomas Schädler
142
Anhang A: Quelltext <xmlizer> configurator
import org.jdom.*;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
/**
* Represents the data for a project with all methods to change and add
* @author [email protected]
* @version 0.7
*/
public class projectData {
public static String XMLPROJECTFILEDTD = "xmlizer.project.config.dtd";
public static String XMLPROJECTFILEROOT = "xmlizerprojectconfig";
private
private
private
private
private
boolean dirty = true;
//set initially on true because never saved
Vector initial = new Vector (0);
//holds dataItems
Vector xml = new Vector(0);
//holds xmlItems
Vector dbs = new Vector(0);
//holds dbItems
DB2XMLmapping mapping = new DB2XMLmapping();
//holds the mapping-info for the DB2XML-Module
//CONSTRUCTOR
//----------------- -----------------------------------------------------------------------------/**
* Creates new projectData (Constructor)
*/
public projectData() {
//init here if neccessary
}
//DIRTY MANAGEMENT
//----------------------------------------------------------------------------------------------/**
* Shows us if the data has changed scince the last save operation
*/
public boolean isDirty() {
return dirty;
}
/**
* Mark the data as dirty
*/
public void setDirty() {
this.dirty = true;
}
/**
* Reset dirty state
*/
public void save() {
dirty = false;
}
//SAVE LOCATION == initial_dataitem("name")
//----------------------------------------------------------------------------------------------public void setSaveLocation(String loc) {
setInitialByKey ("name",loc);
}
public String getSaveLocation() {
dataItem item = getInitialByKey ("name");
String pro_name = item.getValue ();
return System.getProperty("file.separator") + pro_name + System.getProperty("file.separator" );
}
//INITIAL MANAGEMENT
//----------------------------------------------------------------------------------------------/**
* Returns a Vector -> project variables as dataItems
*/
public Vector getInitial () {
return initial;
}
public void addInitial(dataItem dataitem ) {
initial.add(dataitem );
dirty = true;
}
public dataItem getInitialByKey(String key) {
for (Enumeration e = this.initial.elements(); e.hasMoreElements();) {
dataItem item = (dataItem)e.nextElement();
if (item.getKey().equalsIgnoreCase(key)) {
return item;
}
}
return null;
}
public void setInitialByKey(String key,String new_value ) {
for (Enumeration e = this.initial.elements(); e.hasMoreElements();) {
dataItem item = (dataI tem)e.nextElement();
if (item.getKey().equalsIgnoreCase(key)) {
item.setValue(new_value );
return;
}
}
dataItem newitem = new dataItem ();
newitem.setKey(key);
newitem.setValue(new_value );
addInitial (newitem);
//System.out.println("Added new Item: " + key + " [" + new_value + "]");
}
//XML FILES MANAGEMENT
//----------------------------------------------------------------------------------- -----------/**
* Returns a Vector -> XML-Files as String (whole path or url)
*/
public Vector getXML() {
return xml;
Autor: Thomas Schädler
143
Anhang A: Quelltext <xmlizer> configurator
}
public void addXML(xmlItem xmlitem) {
xml.add(xmlitem);
dirty = true;
}
synchronized public void removeXML(String identifier) {
for (Enumeration e = xml.elements(); e.hasMoreElements();) {
xmlItem xmlitem = (xmlItem)e.nextElement();
if (xmlitem.getName().equalsIgnoreCase(identifier)) {
xml.remove(xmlitem );
dirty = true;
break;
}
}
}
public void setXML(Vector newXML) {
xml = newXML;
dirty = true;
}
//DATABASE MANAGEMENT
//----------------------------------------------------------------------------------------------/**
* Returns a Vector -> databases as dbItem
*/
public Vector getDB () {
return dbs;
}
public void addDB(dbItem dbitem) {
dbs.add(dbitem);
dirty = true;
}
synchronized public void removeDB(String identifier) {
for (Enumeration e = dbs.elements(); e.hasMoreElements();) {
dbItem dbitem = (dbItem)e.nextElement ();
if (dbitem.getName().equalsIgnoreCase (identifier)) {
dbitem.closeConnection();
dbs.remove(dbitem);
dirty = true;
break;
}
}
}
synchronized public void setDB (Vector newDB) {
dbs = newDB;
dirty = true;
}
public dbItem getDBByName(String name) {
for (Enumeration e = this.dbs.elements(); e.hasMoreElements();) {
dbItem item = (dbItem)e.nextElement();
if (item.getName().equalsIgnoreCase(name)) {
return item;
}
}
return null;
}
//OBJECT FINALIZATION (CLEANUP)
//----------------------------------------------------------------------------------------------/**
* Do the cleanup before diposing
*/
public void finalize() {
//close all connections
for (Enumeration e = dbs.elements(); e.hasMoreElements();) {
dbItem dbitem = (dbItem)e.nextElement ();
dbitem .closeConnection ();
}
}
//STRING REPRESENTATION
//----------------------------------------------------------------------------------------------public String toString() {
StringBuffer result = new StringBuffer("FULL PROJECTDATA >>\n");
for (Enumeration e = this.initial.elements(); e.hasMoreElements();) {
dataItem item = (dataItem)e.nextElement();
result .append(item);
}
for (Enumeration e = this.xml.elements(); e.hasMoreElements();) {
result .append("\nXML >> " + e.nextElement());
}
for (Enumeration e = this.dbs.elements(); e.hasMoreElements();) {
dbItem item = (dbItem)e.nextElement();
result .append(item);
}
return result.toString();
}
//XML REPRESENTATION
//----------------------------------------------------------------------------------------------/**
* Checks the doctype of the XML-File (just to be sure to read the right information)
*/
private boolean checkDocType(DocType dt,String rootelement,String systemdtd ,logWindow log) {
if (dt.getElementName().equalsIgnoreCase(rootelement) && dt.getSystemID ().equalsIgnoreCase(systemdtd)) {
log.addDebug("docType OK: " + dt.getElementName () + " : " + dt.getSystemID());
return true;
}
else {
log.addDebug("docType NOT OK: " + dt.getElementName() + " : " + dt.getSystemID());
JOptionPane .showMessageDialog(
null,
Autor: Thomas Schädler
144
Anhang A: Quelltext <xmlizer> configurator
configurator.niceFormat("The DocumentType of this document does not match the requirements. This file must conform to this DTD [" + systemdtd + "] and start with this RootElement [" + rootelement + "]."),
configurator.APPNAME + " project dtd error",
JOptionPane .INFORMATION_MESSAGE,
new javax.swing.ImageIcon(getClass().getResource("/configurator/pics/projectloaderror.gif"))
);
return false;
}
}
/*
* Reads an XML file (wh ich must be of type xmlizer.project.config.dtd) and
* fills all information in the projectdata
*
* @param The filename as String
* @param The logWindow (to indicate errors etc...)
*/
synchronized public boolean readFromFile (String filename,logWindow log ) {
boolean docOK = false;
try {
SAXBuilder builder = new SAXBuilder(true);
Document jdoc = builder.build(filename);
//true -> validating against dtd
DocType docType = jdoc.getDocType();
docOK = checkDocType(docType,XMLPROJECTFILEROOT ,XMLPROJECTFILEDTD,log);
String mappingModule = null;
if (docOK) {
//get the root
Element root = jdoc.getRootElement();
//get the initialsetup
Element initsetup = root.getChild ("initialsetup" );
java.util.List initlist = initsetup.getChildren("inititem" );
Iterator init_iter = initlist.iterator ();
while (init_iter.hasNext()) {
Element init_item = (Element) init_iter .next();
dataItem initialdataitem = new dataItem ();
if (init_item.getAttributeValue("key").equalsIgnoreCase("module" )) {
mappingModule = init_item .getTextTrim();
//save the mapping module info
}
initialdataitem.setKey(init_item.getAttributeValue("key"));
initialdataitem.setValue (init_item .getTextTrim());
addInitial(initialdataitem);
}
//get the databasesetup
Element dbsetup = root.getChild("databasesetup");
java.util.List dblist = dbsetup.getChildren ("dbitem");
Iterator db_iter = dblist.iterator();
while (db_iter.hasNext()) {
Element db_item = (Element) db_iter.next();
dbItem initialdbitem = new dbItem();
initialdbitem.setName(db_item.getChild("name").getTextTrim());
initialdbitem.setDriver(db_item.getChild("driver" ).getTextTrim());
initialdbitem.setUrl(db_item.getChild("url").getTextTrim());
initialdbitem.setTimeout (db_item.getChild("timeout").getTextTrim ());
initialdbitem.setUsername(db_item.getChild("username").getTextTrim());
initialdbitem.setPassword(db_item.getChild("password").getTextTrim());
addDB(initialdbitem );
}
//get the schemasetup
Element xmlsetup = root.getChild("schemasetup");
java.util.List xmllist = xmlsetup .getChildren("xmlitem");
Iterator xml_iter = xmllist.iterator();
while (xml_iter.hasNext()) {
Element xml_item = (Element) xml_iter.next();
xmlItem xmlitem = new xmlItem();
xmlitem.setName(xml_item .getChild("name").getTextTrim());
xmlitem.setFile(xml_item .getChild("file").getTextTrim());
addXML(xmlitem );
}
//get the mapping infor mation depending on mappingModule
if(mappingModule != null) {
Element maproot = root.getChild("mapping");
if (maproot != null) {
if (mappingModule.equalsIgnoreCase("Simple DB Export")) {
Element smdberoot = maproot.getChild ("smdbe");
java.util.List smdbeitemlist = smdberoot.getChildren("smdbe_item");
Iterator smdbe_iter = smdbeitemlist.iterator();
String dbName = null;
String level = null;
while (smdbe_iter.hasNext()) {
Element smdbe_item = (Element) smdbe_iter.next();
dbName = smdbe_item.getAttributeValue ("name");
level = smdbe_item.getAttributeValue("type");
Autor: Thomas Schädler
//<smdbe_item name="dbname">
145
Anhang A: Quelltext <xmlizer> configurator
java.util.List smdbetablelist = smdbe_item .getChildren("smdbe_table" );
Iterator smdbetable_iter = smdbetablelist.iterator();
Vector selTab = new Vector();
while (smdbetable_iter .hasNext()) {
Element smdbe_table_item = (Element) smdbetable_iter.next();
selTab.add(smdbe_table_item.getTextTrim());
}
if (selTab.size()>0 && dbName != null && level != null) {
dbItem selDB = getDBByName(dbName );
selDB.SMDBEsetSelectedTables (selTab);
selDB.SMDBEsetOutputType(level);
//System.out.println(dbName + " : " + selTab.toString());
}
}
}
else if (mappingModule.equalsIgnoreCase("Database to XML")) {
Element db2xmlroot = maproot.getChild("db2xml" );
String elementRoot = db2xmlroot .getAttributeValue("rootelement");
if (elementRoot != null) {
mapping.setRootElement (elementRoot);
}
//parameter s
java.util.List para_list = db2xmlroot.getChildren("db2xml_parameter");
Iterator para_iter = para_list.iterator();
while (para_iter .hasNext()) //for all db2xml_element tag s
{
Element p_item = (Element) para_iter.next();
String parID = p_item.getAttributeValue("id");
String parName = p_item.getAttributeValue("name");
String parValue = p_item.getAttributeValue ("default" );
//mark this element as loaded -> no dirty check while parsing.
mapping.addParameterFromLoa d(parID,parName,parValue);
}
//elements
java.util.List element_list = db2xmlroot.getChildren("db2xml_element");
Iterator element_iter = element_list.iterator();
String el_name = null;
String el_rep = null;
String el_id = null;
while (element_iter.hasNext()) //for all db2xml_element tags
{
Element el_item = (Element) element_iter.next();
//<db2xml_element id="id" name="el_name">
el_name = el_item.getAttributeValue("name");
el_id = el_item.getAttributeValue("id");
//mark this element as loaded -> no dirty check while parsing.
mapping.addElementFromLoad(el_name,el_id);
//build repetition
el_rep = el_item.getAttributeValue("repsql");
if (el_rep != null) {
mapping.addElementRepFromLoad(el_id,el_rep);
}
//build content
Element content_el = el_item.getChild ("db2xml_content");
if (content_el != null) {
String temp_mapid = content_el.getAttributeValue ("mapid");
String temp_mapinfo = content_el.getAttributeValue("mapinfo");
SchemaContent temp_cont = new SchemaContent (el_id,temp_mapid,temp_mapinfo);
mapping.addContentFromLoad(el_id,temp_cont);
//System.out.println("Added content: " + temp_cont.toString());
}
//build attributes
java.util.List attr_list = el_item.getChildren("db2xml_attribute");
Iterator attr_iter = attr_list.iterator();
while (attr_iter.hasNext()) //for all db2xml_attribute tags
{
Element attr_item = (Element) attr_iter.next();
String temp_attr_name = attr_item .getAttributeValue("name" );
String temp_mapid = attr_item.getAttributeValue("mapid");
String temp_mapinfo = attr_item.getAttributeValue("mapinfo");
SchemaAttribute temp_attr = new SchemaAttribute(temp_attr_name,temp_mapid,temp_mapinfo);
mapping.addAttributeFromLoad (el_id,temp_attr);
//System.out.println("Added attr: " + temp_attr.toString());
}
//build sql
java.util.List sql_list = el_item.getChildren("db2xml_sql");
Iterator sql_iter = sql_list.iterator ();
while (sql_iter.hasNext()) //for all db2xml_sql tags
{
Element sql_item = (Element) sql_iter.next();
String temp_db_name = sql_item.getAttributeValue ("db");
String temp_sql = sql_item.getAttributeValue("sql");
String temp_id = sql_item.getAttributeValue ("id");
SQLStatement temp_stat = new SQLStatement(temp_db_name,temp_sql,temp_id);
//System.out.println("Added: " + temp_stat.toString());
java.util.List tsql_list = sql_item.getChildren("db2xml_sql_info");
Iterator tsql_iter = tsql_list.iterator();
while (tsql_iter.hasNext()) //for all db2xml_sql_info tags
{
Element tsql_item = (Element) tsql_iter .next();
String temp_col_name= tsql_item.getAttributeValue ("name");
String temp_col_type = tsql_item.getAttributeValue("type");
Autor: Thomas Schädler
146
Anhang A: Quelltext <xmlizer> configurator
temp_stat .addColName(temp_col_name );
temp_stat .addColType(temp_col_type );
//System.out.println("NAME="+temp_col_name+" >> TYPE="+temp_col_type);
}
mapping.addSQLFromLoad(el_id ,temp_stat );
//System.out.println("READ FROM FILE: " + el_id + " > " + temp_stat.toString());
}
}
}
}
}
return true;
}
else {
log.addError ("The docType is not OK, " + XMLPROJECTFILEDTD + " is needed!");
return false ;
}
}
catch (JDOMException e) {
String the_error_message = new String (
"An ERROR occured while processing the projectconfig file!\n"
+ "Make sure your configuration [" + filename + "]\n"
+ "and the according DTD [" + XMLPROJECTFILEDTD + "]\n"
+ "is located in THE SAME DIRECTORY.\n\n"
+ "Original Error Message:\n");
String the_error_string = e.toString();
the_error_string = configurator.niceFormat (the_error_string);
JOptionPane .showMessageDialog(
null,
the_error_message + the_error_string,
configurator.APPNAME + " project loader error",
JOptionPane .ERROR_MESSAGE,
new javax.swing.ImageIcon(getClass().getResource("/configurator/pics/projectloaderror.gif"))
);
return false;
}
}
/**
* Return the data as String
*/
public String getAsXMLText() {
Document jdoc = this.getAsXMLDocumentJDOM ();
org.jdom.output .DOMOutputter outp = new org.jdom.output.DOMOutputter();
XMLOutputter fmt = new XMLOutputter("
return fmt.outputString(jdoc);
",true);
}
/**
* Return the data as XML Document (org.w3c.dom.Document)
*/
public org.w3c.dom.Document getAsXMLDocumentW3C() {
Document jdoc = this.getAsXMLDocumentJDOM ();
org.jdom.output .DOMOutputter outp = new org.jdom.output.DOMOutputter();
try {
org.w3c.dom.Document result = outp.output(jdoc);
return result; //and return the result
}
catch (JDOMException e) {
System .out.println("DOM Serializer error for debug output!");
return null;
}
}
/**
* Return the data as XML Document org.jdom.Document
*/
public synchronized Document getAsXMLDocumentJDOM() {
//MAKE DOCTYPE
DocType docType = new DocType(XMLPROJECTFILEROOT,XMLPROJECTFILEDTD );
Element root = new Element (XMLPROJECTFILEROOT);
//initialsetup
Element init = new Element ("initialsetup" );
for (Enumeration e = this.initial.elements(); e.hasMoreElements();) {
dataItem ditem = (dataItem)e.nextElement();
Element init_item = new Element("inititem" ).setText(ditem .getValue());
init_item.setAttribute ("key",ditem.getKey());
init.addContent(init_item);
}
root.addContent (init);
//db setup
Element dbitems = new Element("databasesetup");
for (Enumeration e = this.dbs.elements(); e.hasMoreElements();) {
dbItem dbitem = (dbItem)e.nextElement ();
Element db_item = new Element("dbitem");
db_item.addContent(new
db_item.addContent(new
db_item.addContent(new
db_item.addContent(new
db_item.addContent(new
db_item.addContent(new
Element("name" ).setText(dbitem.getName()));
Element("driver").setText(dbitem.getDriver()));
Element("url").setText(dbitem .getUrl()));
Element("timeout").setText(dbitem.getTimeout ()));
Element("username").setText(dbitem .getUsername()));
Element("password").setText(dbitem .getPassword()));
dbitems.addContent(db_item);
}
Autor: Thomas Schädler
147
Anhang A: Quelltext <xmlizer> configurator
root.addContent (dbitems);
//schema setup
Element schms = new Element("schemasetup" );
for (Enumeration e = this.xml.elements(); e.hasMoreElements();) {
xmlItem sitem = (xmlItem)e.nextE lement();
Element schms_item = new Element("xmlitem" );
schms_item.addContent(new Element("name").setText(sitem.getName()));
schms_item.addContent(new Element("file").setText(sitem.getFile()));
schms.addContent (schms_item );
}
root.addContent (schms);
//module mapping setup
Element mapping = null;
try {
mapping = getMapping();
}
catch(Exception ex) {
System .out.println("getMapping() in projectData == NULL, should only happen if there is an error in the DB2XML
Mapping.");
mapping = null;
}
if (mapping != null) {
root.addContent(mapping);
}
Document doc = new Document(root,docType);
return doc; //and return the doc
}
/**
* Get the DB2XML-Mapping
*/
public DB2XMLmapping DB2XMLgetmapping() {
return this.mapping;
}
/** Resets the whole mapping info (handle with care) */
synchronized public void DB2XMLclearmapping() {
this.mapping = new DB2XMLmapping();
}
/**
* Returns the mapping element filled with the xml -mapping-data
* for the currently selected module
*/
private Element getMapping() {
dataItem datitem = (dataItem)getInitialByKey("module");
String mappingName = datitem.getValue();
if (mappingName .equalsIgnoreCase("Simple DB Export" )) {
//Simple DB Export Mapping buildup
Element wrapper = new Element("mapping");
Element smdbe_wrapper = new Element("smdbe");
boolean NONempty = false; //set true for not null output
for (Enumeration e = this.dbs.elements(); e.hasMoreElements();) {
dbItem dbitem = (dbItem )e.nextElement();
Vector selTab = (Vector )dbitem.SMDBEgetSelectedTables ();
if (selTab.size()>0) {
Element curr_db = new Element("smdbe_item");
curr_db.setAttribute("name",dbitem .getName());
curr_db.setAttribute("type",dbitem .SMDBEgetOutputType());
for (Enumeration enum = selTa b.elements (); enum.hasMoreElements();) {
NONempty = true;
curr_db.addContent(new Element("smdbe_table").setText((String)enum.nextElement()));
}
smdbe_wrapper.addContent (curr_db);
}
}
wrapper.addContent(smdbe_wrapper );
if (NONempty) {
return wrapper;
}
else {
return null;
}
}
else if (mappingName .equalsIgnoreCase("Database to XML")) {
//Database to XML buildup
return this.mapping.getMapping();
}
else {
//failsafe only, should NEVER happen, though
return null;
}
}
/**
* Cleans all SchemaElements which are associated to the specified SQLStatement
* but cleans only the content and attribute-mapping (not repet.) = new repet. set
*/
synchronized public void cleanSchemaElementDataDependencies(SQLStatement toclean ) {
if (toclean != null) {
//System.out.println("Statement ====> " + toclean);
Vector elms = this.DB2XMLgetmapping().getElements();
if(elms != null) {
Autor: Thomas Schädler
148
Anhang A: Quelltext <xmlizer> configurator
for(Enumeration e = elms.elements ();e.hasMoreElements ();) {
SchemaElement el = (SchemaElement)e.nextElement();
el.cleanMapData(toclean);
//System.out.println("Cleaning: " + el);
}
}
}
}
/**
* Cleans all SchemaElements which are associated to the specified SQLStatement
* cleans the content,the attributes and the repetition mapping = total-remove
*/
synchronized public void cleanSchemaElementFullDependencies(SQLStatement toclean ) {
if (toclean != null) {
//System.out.println("Statement ====> " + toclean);
Vector elms = this.DB2XMLgetmapping().getElements();
if(elms != null) {
for(Enumerat ion e = elms.elements ();e.hasMoreElements ();) {
SchemaElement el = (SchemaElement)e.nextElement();
el.removeSQLStatement(toclean);
setDirty ();
//System.out.println("Cleaning: " + el);
}
}
}
}
}
/*
* helpWindow.java
*
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 Li cense
* along with <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import
import
import
import
import
import
import
java.awt.*;
java.net.*;
java.lang.*;
java.io.*;
javax.swing .*;
javax.swing .event.*;
java.util.*;
/**
* Represents a helpwindow (just another browser)
* @author [email protected]
*/
public class helpW indow extends MyInternalFrame {
String initialPage = new String("/configurator/help/index.html");
HTMLBrowser html = new HTMLBrowser(getClass().getResource(initialPage));
JPanel p = new JPanel();
private configurator mother;
private String ID;
//constructor
public helpWindow(configurator mainProgram,String uid) {
this.mother = mainProgram;
this.ID = uid;
setIconifiable(true);
setClosable(true);
setResizable(true);
setMaximizable(true);
setTitle("Help Browser");
setSize(580,450);
setFrameIcon(new ImageIcon (getClass().getResource("/configurator/icons/Help16.gif")));
p.setLayout(new BorderLayout());
p.add("Center", html);
getContentPane().add(p);
this.addInternalFrameListener(new InternalFrameAdapter() {
public void internalFrameClosing (InternalFrameEvent evt) {
exitForm(evt);
}
});
}
/**
* Exit the Help Browser
*/
private void exitForm(InternalFrameEvent evt) {
mother.close(this.ID);
}
/**
* Loads a new html page (give full path)
*/
public void loadPage(String url) {
URL theURL = getClass().getResource(url);
Autor: Thomas Schädler
149
Anhang A: Quelltext <xmlizer> configurator
html.linkActivated(theURL);
}
}
/*
* simpleFileFilter.java
*
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------* @(#)ExampleFileFilter.java
1.9 99/04/23
*
* Copyright (c) 1998, 1999 by Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
package configurator;
import
import
import
import
import
java.io.File;
java.util.Hashtable;
java.util.Enumeration ;
javax.swing .*;
javax.swing .filechooser.*;
/**
* A convenience implementation of FileFilter that filters out
* all files except for those type extensions that it knows about.
*
* Extensions are of the type ".foo", which is typically found on
* Windows and Unix boxes, but not on Macinthosh. Case is ignored.
*
* Example - create a new fi lter that filerts out all files
* but gif and jpg image files:
*
*
JFileChooser chooser = new JFileChooser();
*
ExampleFileFilter filter = new ExampleFileFilter(
*
new String{"gif", "jpg"}, "JPEG & GIF Images")
*
chooser.addChoosableFileFilter(filter);
*
chooser.showOpenDialog(this);
*
* @version 1.9 04/23/99
* @author Jeff Dinkins
*/
public class simpleFileFilter extends FileFilter {
private static String TYPE_UNKNOWN = "Type Unknown";
private static String HIDDEN_FILE = "Hidden File";
private
private
private
private
Hashtable filters = null;
String description = null;
String fullDescription = null;
boolean useExtensionsInDescription = true;
/**
* Creates a file filter. If no filters are added, then all
* files are accepted.
*
* @see #addExtension
*/
public simpleFileFilter() {
this.filters = new Hashtable();
}
/**
* Creates a file filter that accepts files with the given extension.
* Example: new ExampleFileFilter("jpg");
*
* @see #addExtension
*/
public simpleFileFilter(String extension ) {
Autor: Thomas Schädler
150
Anhang A: Quelltext <xmlizer> configurator
this(extension,null);
}
/**
* Creates a file filter that accepts the given file type.
* Example: new ExampleFileFilter("jpg", "JPEG Image Images");
*
* Note that the "." before the extension is not needed. If
* provided, it will be ignored.
*
* @see #addExtension
*/
public simpleFileFilter(String extension , String description ) {
this();
if(extension!=null) addExtension(extension);
if(description!=null) setDescription (description);
}
/**
* Creates a file filter from the given string array.
* Example: new ExampleFileFilter(String {"gif", "jpg"});
*
* Note that the "." before the extension is not needed adn
* will be ignored.
*
* @see #addExtension
*/
public simpleFileFilter(String [] filters) {
this(filters, null);
}
/**
* Creates a file filter from the given string array and description.
* Example: new ExampleFileFilter(String {"gif", "jpg"}, "Gif and JPG Images");
*
* Note that the "." before the extension is not needed and will be ignored.
*
* @see #addExtension
*/
public simpleFileFilter(String [] filters, String description ) {
this();
for (int i = 0; i < filters.length; i++) {
// add filters one by one
addExtension(filters[i]);
}
if(description!=null) setDescription (description);
}
/**
* Return true if this file should be shown in the directory pane,
* false if it shouldn't.
*
* Files that begin with "." are ignored.
*
* @see #getExtension
* @see FileFilter#accepts
*/
public boolean accept(File f) {
if(f != null) {
if(f.isDirectory ()) {
return true;
}
String extension = getExtension(f);
if(extension != null && filters.get(getExtension(f)) != null) {
return true;
};
}
return false;
}
/**
* Return the extension portion of the file's name .
*
* @see #getExtension
* @see FileFilter#accept
*/
public String getExtension(File f) {
if(f != null) {
String filename = f.getName();
int i = filename .lastIndexOf('.');
if(i>0 && i<filename.length ()-1) {
return filename.substring(i+1).toLowerCase();
};
}
return null;
}
/**
* Adds a filetype "dot" extension to filter against.
*
* For example: the following code will create a filter that filters
* out all files except those that end in ".jpg" and ".tif":
*
*
ExampleFileFilter filter = new ExampleFileFilter();
*
filter.addExtension("jpg");
*
filter.addExtension("tif");
*
* Note that the "." before the extension is not needed and will be ignored.
*/
public void addExtension (String extension) {
if(filters == null) {
filters = new Hashtable(5);
}
filters.put(extension.toLowerCase(), this);
fullDescription = null;
Autor: Thomas Schädler
151
Anhang A: Quelltext <xmlizer> configurator
}
/**
* Returns the human readable description of this filter. For
* example: "JPEG and GIF Image Files (*.jpg, *.gif)"
*
* @see setDescription
* @see setExtensionListInDescription
* @see isExtensionListInDescription
* @see FileFilter#getDescription
*/
public String getDescription() {
if(fullDescription == null) {
if(description == null || isExtensionListInDescription()) {
fullDescription = description==null ? "(" : description + " (";
// build the description from the extension list
Enumeration extensions = filters.keys();
if(extensions != null) {
fullDescription += "." + (String) extensions .nextElement();
while (extensions.hasMoreElements()) {
fullDescription += ", " + (String) extensions .nextElement();
}
}
fullDescription += ")";
} else {
fullDescription = description;
}
}
return fullDescription;
}
/**
* Sets the human readable description of this filter. For
* example: filter.setDescription("Gif and JPG Images");
*
* @see setDescription
* @see setExtensionListInDescription
* @see isExtensionListInDescription
*/
public void setDescription(String description ) {
this.description = description;
fullDescription = null;
}
/**
* Determines whether the extension list (.jpg, .gif, etc) should
* show up in the human readable description.
*
* Only relevent if a description was provided in the constructor
* or using setDescription();
*
* @see getDescription
* @see setDescription
* @see isExtensionListInDescription
*/
public void setExtensionListInDescription(boolean b) {
useExtensionsInDescription = b;
fullDescription = null;
}
/**
* Returns whether the extension list (.jpg, .gif, etc) should
* show up in the human readable description.
*
* Only relevent if a description was provided in the constructor
* or using setDescription();
*
* @see getDescription
* @see s etDescription
* @see setExtensionListInDescription
*/
public boolean isExtensionListInDescription() {
return useExtensionsInDescription;
}
}
/*
* splashWindow.java
*
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import java.awt.*;
import javax.swing .*;
/**
* Shows a simple Splashwindow before starting the configurator
* @author [email protected]
Autor: Thomas Schädler
152
Anhang A: Quelltext <xmlizer> configurator
*/
public class splashWindow extends JWindow {
ImageIcon splash = new ImageIcon(getClass().getResource ("/configurator/pics/splash.jpg"));
JLabel pic = new JLabel(splash );
JLabel txt = new JLabel();
splashWindow s ;
/**
* Builds the splash screen
*/
public splashWindow () {
txt.setText(configurator.APPNAME + " ver. " + configurator.VERSION);
txt.setForeground(new Color(255,255,255));
txt.setHorizontalAlignment (JLabel.CENTER);
this.getContentPane().setBackground(new Color(0,54,100));
this.getContentPane().add(pic, BorderLayout.NORTH);
this.getContentPane().add(txt, BorderLayout.CENTER);
s = this;
}
/**
* Shows the splash screen for a specified time in ms
*/
public void start(long time) {
//get the screen size
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
//place in center of screen
s.pack();
Dimension splashScreenSize = s.getSize();
if(splashScreenSize.height > screenSize.height ) {
splashScreenSize .height = screenSize.height;
}
if(splashScreenSize.width > screenSize.width) {
splashScreenSize .width = screenSize.width;
}
s.setLocation((screenSize.width - splashScreenSize.width ) / 2, (screenSize.height - splashScreenSize.height ) / 2);
s.setVisible(true);
try {
Thread .sleep(time);
}
catch(InterruptedException ie) {
System .err.print ("Thread.sleep: " + ie);
}
s.dispose();
}
}/*
* MyInternalFrame.java
*
* Created on 15. Mai 2002, 16:08
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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 ver sion.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
/**
* The superclass of all internalframes (update())
* @author [email protected]
* @version 1.0
*/
public class MyInternalFrame extends javax.swing.JInternalFrame {
private configurator mother;
private projectData theData;
private String identifier;
public void setIdentifier(String id ) {
this.identifier = id;
}
public String getIdentifier() {
return this.identifier;
}
/**
* Must be overwritten to update the component if the setup changes
* and the component relies on that kind of information (setup info)
*/
public synchronized void update(configurator conf) {
this.mother = conf;
this.theData = conf.getProjectData();
}
}/*
* SQLColumnInfo.java
*
* Created on 25. Juli 2002, 02:47
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> is free software; you can redistribute it and/or modify
Autor: Thomas Schädler
153
Anhang A: Quelltext <xmlizer> configurator
* 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
/**
* Represents the ColumnInfo of a SQLStatement
* @author [email protected]
*/
class SQLColumnInfo {
protected String id ;
protected String name;
protected String type;
public SQLColumnInfo(String id ,String name,String type) {
this.id = id;
this.name = name;
this.type = type;
}
public String getID () {
return this.id;
}
public String getName() {
return this.name;
}
public String getType() {
return this.type;
}
public String toString() {
return this.name + " [" + this.type + "]";
}
}
/*
* javadocWindow.java
*
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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 optio n) any later version.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import
import
import
import
import
import
import
java.awt.*;
java.net.*;
java.lang.*;
java.io.*;
javax.swing .*;
javax.swing .event.*;
java.util.*;
/**
* Is a browser (containing the javadoc)
* @author [email protected]
*/
public class javadocWindow extends MyInternalFrame {
String initialPage = new String("/configurator/javadoc/index.html");
HTMLBrowser html = new HTMLBrowser(getClass().getResource(initialPage));
JPanel p = new JPanel();
private static configurator mother;
private String ID;
//constructor
public javadocWindow(configurator mainProgram ,String uid) {
this.mother = mainProgram;
this.ID = uid;
setIconifiable(true);
setClosable(true);
setResizable(true);
setMaximizable(true);
setTitle("JavaDoc Browser" );
setSize(580,450);
setFrameIcon(new ImageIcon (getClass().getResource("/configurator/icons/WebComponent16.gif")));
p.setLayout(new BorderLayout());
p.add("Center", html);
getContentPane().add(p);
Autor: Thomas Schädler
154
Anhang A: Quelltext <xmlizer> configurator
this.addInternalFrameListener(new InternalFrameAdapter() {
public void internalFrameClosing (InternalFrameEvent evt) {
exitForm(evt);
}
});
}
/**
* Exit the Help Browser
*/
private void exitForm(InternalFrameEvent evt) {
mother.close(this.ID);
}
/**
* Loads a new html page (give full path)
*/
public void loadPage(String url) {
URL theURL = getClass().getResource(url);
html.linkActivated(theURL);
}
}/*
* SchemaElementPanel.java
*
* This class representates a Schema Element Panel for showing its content
*
* Created on 2. August 2002, 19:02
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import org.jdom.*;
import java.util.*;
import javax.swing .*;
/**
* A special panel for the root-element holding methods to set the parameters
* @author [email protected]
*/
public class SchemaRootPanel extends javax.swing.JPanel {
private configurator mother;
private SchemaElement element;
private Vector params = new Vector();
private boolean isEmpty = true;
/** Creates new form SchemaRootPanel */
public SchemaRootPanel(configurator config,SchemaElement element) {
this.mother = config ;
this.element = element;
initComponents();
fillLabels ();
fillData();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
private void initComponents()//GEN-BEGIN:initComponents
{
mainPanel = new javax.swing.JPanel();
infoPanel = new javax.swing.JPanel();
jLabel1 = new javax.swing.JLabel();
afdLabel = new javax .swing .JLabel();
jLabel3 = new javax.swing.JLabel();
efdLabel = new javax .swing .JLabel();
jLabel4 = new javax.swing.JLabel();
tnsLabel = new javax .swing .JLabel();
jLabel5 = new javax.swing.JLabel();
verLabel = new javax .swing .JLabel();
jLabel6 = new javax.swing.JLabel();
langLabel = new javax.swing.JLabel();
parameterPanel = new javax .swing.JPanel();
workPanel = new javax.swing.JPanel();
jPanel7 = new javax.swing.JPanel();
jPanel9 = new javax.swing.JPanel();
jLabel14 = new javax .swing .JLabel();
nameTextField = new javax.swing .JTextField();
jPanel10 = new javax .swing .JPanel();
jLabel15 = new javax .swing .JLabel();
valueTextField = new javax .swing.JTextField();
jPanel8 = new javax.swing.JPanel();
addButton = new javax.swing.JButton();
removeButton = new javax.swing.JButton();
jScrollPane1 = new javax.swing.JScrollPan e();
paramList = new JList(params);
setLayout(new java.awt.BorderLayout());
Autor: Thomas Schädler
155
Anhang A: Quelltext <xmlizer> configurator
mainPanel.setLayout(new java.awt.BorderLayout());
infoPanel.setLayout(new java.awt.GridLayout(5, 2, 10, 10));
infoPanel.setBorder(new javax.swing.border.TitledBorder("Schema Root Information:"));
infoPanel.setMinimumSize(new java.awt.Dimension(0, 0));
jLabel1.setText("Attribute Form Default:" );
jLabel1.setForeground(java.awt.Color .darkGray);
infoPanel.add(jLabel1);
infoPanel.add(afdLabel);
jLabel3.setText("Element From Default:");
jLabel3.setForeground(java.awt.Color .darkGray);
infoPanel.add(jLabel3);
infoPanel.add(efdLabel);
jLabel4.setText("Target Namespace:");
jLabel4.setForeground(java.awt.Color .darkGray);
infoPanel.add(jLabel4);
infoPanel.add(tnsLabel);
jLabel5.setText("Version:" );
jLabel5.setForeground(java.awt.Color .darkGray);
infoPanel.add(jLabel5);
infoPanel.add(verLabel);
jLabel6.setText("Language:");
jLabel6.setForeground(java.awt.Color .darkGray);
infoPanel.add(jLabel6);
infoPanel.add(langLabel);
mainPanel.add(infoPanel, java.awt.BorderLayout .NORTH);
parameterPanel.setLayout(new java.awt.BorderLayout());
parameterPanel.setBorder(new javax.swing.border.TitledBorder("Query parameters:"));
workPanel.setLayout(new java.awt.BorderLayout());
jPanel7.setLayout(new javax.swing.BoxLayout(jPanel7, javax.swing.BoxLayout.Y_AXIS ));
jPanel9.setLayout(new javax.swing.BoxLayout(jPanel9, javax.swing.BoxLayout.X_AXIS ));
jLabel14.setText("Name:
jPanel9.add(jLabel14 );
" );
nameTextField.setPreferredSize(new java.awt.Dimension(100, 27));
nameTextField.setMinimumSize(new java.awt.Dimension (60, 27));
jPanel9.add(nameTextField);
jPanel7.add(jPanel9);
jPanel10.setLayout(new javax.swing.BoxLayout(jPanel10, javax.swing .BoxLayout .X_AXIS));
jLabel15.setText("Default Value:
jPanel10.add(jLabel15);
");
valueTextField.setPreferredSize (new java.awt.Dimension(100, 27));
valueTextField.setMinimumSize(new java.awt.Dimension(60, 27));
jPanel10.add(valueTextField);
jPanel7.add(jPanel10 );
workPanel.add(jPanel7, java.awt.BorderLayout.CENTER );
jPanel8.setLayout(new javax.swing.BoxLayout(jPanel8, javax.swing.BoxLayout.Y_AXIS ));
addButton.setIcon(new javax.swing.ImageIcon(getClass().getResource ("/configurator/icons/Plus16.gif")));
addButton.addActionListener(new java.awt.event .ActionListener ()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
addButtonActionPerformed(evt);
}
});
jPanel8.add(addButton);
removeButton.setIcon(new javax.swing .ImageIcon (getClass().getResource("/configurator/icons/Minus16.gif")));
removeButton.setEnabled(false);
removeButton.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
removeButtonActionPerformed(evt);
}
});
jPanel8.add(removeButton);
workPanel.add(jPanel8, java.awt.BorderLayout.EAST);
parameterPanel.add(workPanel, java.awt.BorderLayout .NORTH);
paramList.addMouseListener (new java.awt.event.MouseAdapter()
{
public void mouseClicked(java.awt.event.MouseEvent evt)
{
paramListMouseClicked(evt);
}
Autor: Thomas Schädler
156
Anhang A: Quelltext <xmlizer> configurator
});
jScrollPane1.setViewportView(paramList);
parameterPanel.add(jScrollPane1 , java.awt.BorderLayout.CENTER );
mainPanel.add(parameterPanel, java.awt.BorderLayout .CENTER);
add(mainPanel, java.awt.BorderLayout .CENTER);
}//GEN-END:initComponents
private void paramListMouseClicked(java.awt.event.MouseEvent evt)//GEN -FIRST:event_paramListMouseClicked
{//GEN-HEADEREND:event_paramListMouseClicked
// Add your handling code here:
int index = paramList.getSelectedIndex();
if (index < 0) {
removeButton.setEnabled(false);
return ;
}
if (paramList.getModel().getSize() > index) {
ParameterInfo data = (ParameterInfo)paramList.getModel().getElementAt(index);
setDisplay(data);
removeButton.setEnabled(true);
}
}//GEN-LAST:event_paramListMouseClicked
private void removeButtonActionPerformed (java.awt.event .ActionEvent evt)//GEN-FIRST:event_removeButtonActionPerformed
{//GEN-HEADEREND:event_removeButtonActionPerformed
// Add your handling code here:
int index = paramList.getSelectedIndex();
if (index < 0) {
removeButton.setEnabled(false);
return ;
}
if (paramList.getModel().getSize() > index) {
ParameterInfo data = (ParameterInfo)paramList.getModel().getElementAt(index);
boolean success = mother.getProjectData().DB2XMLgetmapping().removeParameter(data.getName());
if (success) {
mother.getProjectData().setDirty();
removeButton .setEnabled (false);
if (this.params.size() < 1) { this.isEmpty = true; }
this.params.remove (data);
this.paramList.repaint();
}
}
}//GEN-LAST:event_removeButtonActionPerformed
private void addButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_addButtonActionPerformed
{//GEN-HEADEREND:event_addButtonActionPerformed
// Add your handling code here:
String name = nameTextField.getText();
String value = valueTextField.getText();
if (!name.equalsIgnoreCase (new String()) && !value.equalsIgnoreCase(new String())) {
String id = mother.uniqueID .get();
boolean success = mother.getProjectData().DB2XMLgetmapping().addParameterFromLoad(id,name,value);
if (success) {
mother.getProjectData().setDirty();
if (this.isEmpty) { this.isEmpty = false; }
this.params.add(new ParameterInfo (id,name,value));
this.paramList.setListData(this.params );
this.paramList.repaint();
}
}
}//GEN-LAST:event_addButtonActionPerformed
//Initialization of the data
//----------------------------------------------------------------------------------------------private void fillLabels() {
afdLabel.setText(this.element.SCHEMAattributeFormDefault );
afdLabel.setToolTipText(this.element.SCHEMAattributeFormDefault);
efdLabel.setText(this.element.SCHEMAelementFormDefault);
efdLabel.setToolTipText(this.element.SCHEMAelementFormDefault );
tnsLabel.setText(this.element.SCHEMAtargetNameSpace );
tnsLabel.setToolTipText(this.element.SCHEMAtargetNameSpace);
verLabel.setText(this.element.SCHEMAversion);
verLabel.setToolTipText(this.element.SCHEMAversion);
langLabel.setText(this.element.SCHEMAlanguage);
langLabel.setToolTipText(this.element.SCHEMAlanguage);
}
private void fillData() {
//add the ParameterInfos to the params-vector
Hashtable paraHash = mother.getProjectData().DB2XMLgetmapping ().getParameters();
for (Enumeration e = paraHash.elements(); e.hasMoreElements();) {
ParameterInfo item = (ParameterInfo)e.nextElement();
this.params .add(item);
this.isEmpty = false;
}
}
private void setDisplay(ParameterInfo current ) {
nameTextField.setText(current.getName());
valueTextField.setText(current.getValue());
}
// Variables declaration private javax.swing .JPanel
private javax.swing .JPanel
private javax.swing .JLabel
private javax.swing .JLabel
private javax.swing .JLabel
private javax.swing .JLabel
private javax.swing .JLabel
private javax.swing .JLabel
Autor: Thomas Schädler
do not modify//GEN -BEGIN:variables
mainPanel;
infoPanel;
jLabel1;
afdLabel;
jLabel3;
efdLabel ;
jLabel4;
tnsLabel ;
157
Anhang A: Quelltext <xmlizer> configurator
private javax.swing .JLabel jLabel5;
private javax.swing .JLabel verLabel ;
private javax.swing .JLabel jLabel6;
private javax.swing .JLabel langLabel;
private javax.swing .JPanel parameterPanel;
private javax.swing .JPanel workPanel;
private javax.swing .JPanel jPanel7;
private javax.swing .JPanel jPanel9;
private javax.swing .JLabel jLabel14 ;
private javax.swing .JTextField nameTextField;
private javax.swing .JPanel jPanel10 ;
private javax.swing .JLabel jLabel15 ;
private javax.swing .JTextField valueTextField ;
private javax.swing .JPanel jPanel8;
private javax.swing .JButton addButton;
private javax.swing .JButton removeButton ;
private javax.swing .JScrollPane jScrollPane1;
private javax.swing .JList paramList ;
// End of variables declaration//GEN-END:variables
}
/*
* SchemaType.java
*
* Created on 24. Juli 2002, 11:59
*
* This represents the neccessary info for a type of a SchemaElement
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import org.jdom.*;
import java.util.*;
import javax.swing .*;
/**
* Hold the information for the type of the SchemaElement
* (currently unused)
* @author [email protected]
*/
public class SchemaType {
private String tname = null; //name=
//CONSTRUCTORS
public SchemaType() {
//none for now
}
public void setName(String name) {
this.tname = name;
}
public String getName() {
return this.tname;
}
//TYPE PROCESSING
public void processType(Element typeElement) {
//name
Attribute attr = null;
attr = typeElement.getAttribute ("name");
if (attr != null) {
this.tname = attr.getValue().trim();
}
//System.out.println("TYPE: " + typeElement.getName());
List kids = typeElement.getChildren(); //"element",namespace
Iterator kids_iter = kids.iterator();
while (kids_iter.hasNext()) {
Element xmlelem = (Element) kids_iter .next();
if (xmlelem.getName().equalsIgnoreCase("complexType" )) //can conatain new elements
{
List subkids = xmlelem.getChildren(); //"element",namespace
Iterator subkids_iter = subkids.iterator();
while (subkids_iter.hasNext()) {
Element dxmlelem = (Element) subkids_iter.next();
if (dxmlelem.getName().equalsIgnoreCase ("simpleContent")) {
List dsubkids = dxmlelem.getChildren(); //"element",namespace
Iterator dsubkids_iter = dsubkids.iterator();
while (dsubkids_iter .hasNext()) {
}
}
else if
else if
else if
else if
else if
(dxmlelem.getName().equalsIgnoreCase ("complexContent")) { }
(dxmlelem.getName().equalsIgnoreCase ("group")) { }
(dxmlelem.getName().equalsIgnoreCase ("all")) { }
(dxmlelem.getName().equalsIgnoreCase ("choice")) { }
(dxmlelem.getName().equalsIgnoreCase ("sequence")) { }
Autor: Thomas Schädler
158
Anhang A: Quelltext <xmlizer> configurator
else if (dxmlelem.getName().equalsIgnoreCase ("attribute")) { }
}
}
else if (xmlelem.getName().equalsIgnoreCase("simpleType")) //no more deeper elements
{
List subkids = xmlelem.getChildren(); //"element",namespace
Iterator subkids_iter = subkids.iterator();
while (subkids_iter.hasNext()) {
Element dxmlelem = (Element) subkids_iter.next();
if (dxmlelem.getName().equalsIgnoreCase ("restriction")) {
}
else if (dxmlelem.getName().equalsIgnoreCase ("list")) {
}
else if (dxmlelem.getName().equalsIgnoreCase ("union")) {
}
}
}
}
}
public void processTypeRef(Element typeElement) {
//System.out.println("TREF:" + typeElement.getName());
}
public void processInternalType(Element typeElement) {
//System.out.println("ITYP: " + typeElement.getName());
}
//STRING REPRESENTATION
/**
* By default show the key as String
*/
public String toString() {
return this.tname;
/*
if (this.ttype == null && this.ttyperef != null)
//has a typeref
{
return this.tname + " - " + this.ttyperef + " [" + this.tuse + "]";
}
else if (this.ttype != null && this.ttyperef == null)
//has a type
{
return this.tname + " - " + this.ttype + " [" + this.tuse + "]";
}
else
//has nothing of both (should not happen -> invalid)
{
return this.tname + " - !noType! [" + this.tuse + "]";
}*/
}
}/*
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 P URPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------****************************************************************************
* xuri
****************************************************************************
* Copyright (C) 05/2001 Ralf Schweiger
*
* This program 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.
*
* This program 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.
*
* Contact the Author:
*
* University of Giessen
* c/o Ralf Schweiger
* Heinrich-Buff-Ring 44
* 35392 Giessen
* Germany
*
* tel.:
+49-641-9941370
* fax.:
+49-641-9941359
* mailto: [email protected] -giessen.de
*
***************************************************************************/
package configurator;
import java.net.*;
import java.io.*;
Autor: Thomas Schädler
159
Anhang A: Quelltext <xmlizer> configurator
import java.util.Date;
// import javax.servlet.*;
class xurl {
private final String defaultEncoding = "ISO-8859-1";
private String charset;
private StringBuffer toSend;
private PrintStream psLog; // application
private StringBuffer sbLog; // applet
private void log(Object item) {
if (psLog != null) psLog.print(item);
if (sbLog != null) sbLog.append (item);
}
public xurl()
{ charset = defaultEncoding; psLog = null; sbLog = null; toSend = new StringBuffer(""); }
public xurl(String charset)
{ this.charset = charset; psLog = null; sbLog = null; toSend = new StringBuffer(""); }
public xurl(StringBuffer sbLog )
{ charset = defaultEncoding; psLog = null; this.sbLog = sbLog; toSend = new StringBuffer(""); }
public xurl(String charset, StringBuffer sbLog)
{ this.charset = charset; psLog = null; this.sbLog = sbLog; toSend = new StringBuffer (""); }
public void setCharset(String charset)
{ this.charset = charset; }
public void send(String name, Object value) {
if (toSend .length() > 0)
toSend .append("&");
toSend.append(name).append ("=").append(URLEncoder.encode (value.toString ()));
}
public String communicate(String url) { // send & receive
Date date0 = new Date();
log("<xurl:communicate>" + url + "\n<xurl:send charset=" + charset + ">" + toSend );
try {
URL u = new URL(url);
URLConnection uc = u.openConnection();
uc.setDoInput(true);
uc.setUseCaches(false);
uc.setRequestProperty("content-type", "application/x -www-form-urlencoded");
uc.setRequestProperty("charset", charset);
if (toSend.toString().length() > 0) {
uc.setDoOutput(true);
PrintWriter pw = new PrintWriter(uc.getOutputStream());
pw.print(toSend);
toSend = new StringBuffer("");
pw.close();
}
StringBuffer receive = new StringBuffer("");
String enc = uc.getContentEncoding(); // equals to charset if xurl is used for communication
InputStreamReader isr = new InputStreamReader(uc.getInputStream(), enc != null ? enc : charset);
int c;
while ((c = isr.read()) != -1) receive.append((char) c);
isr.close();
log("</xurl:send>\n<xurl:receive charset=" + enc + ">" + receive + "</xurl:receive>\n" + ((new Date()).getTime()
- date0.getTime()) + " ms</xurl:communicate>");
return receive.toString();
}
catch (Exception x)
{ log(x); return null; }
}
/*******************************************
*
* public String receive(ServletRequest req) {
* Date date0 = new Date();
* if (log != null) log.put("<xurl:receive charset=" + req.getCharacterEncoding() + ">");
* try {
* StringBuffer content = new StringBuffer("");
* BufferedReader br = req.getReader();
* int c;
* while ((c = br.read()) != -1) content.append((char) c);
* br.close();
* if (log != null) log.put(((new Date()).getTime() - date0.getTime()) + " ms</xurl:receive>");
* return content.toString();
* }
* catch (Exception x) { if (log != null) log.put(x); return null; }
* }
*
* public void send(ServletResponse res, Object content) {
* Date date0 = new Date();
* if (log != null) log.put("<xurl:send charset=" + charset + ">" + content);
* try {
* res.setContentType("text/plain; charset=" + charset);
* PrintWriter pw = res.getWriter();
* pw.print(content);
* pw.close();
* if (log != null) log.put(((new Date()).getTime() - date0.getTime()) + " ms</xurl:send>");
* }
* catch (Exception x) { if (log != null) log.put(x); }
* }
*
************************************************/
}
/*
* sdbBrowser.java
*
* Created on 17. Mai 2002, 20:28
* ----------------------------------------------------------------------------
Autor: Thomas Schädler
160
Anhang A: Quelltext <xmlizer> configurator
* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import
import
import
import
import
import
import
import
import
import
import
java.io.*;
java.sql.*;
java.util.*;
org.jdom.*;
org.jdom.output.XMLOutputter;
java.awt.event.*;
javax.swing .*;
javax.swing .table.*;
javax.swing .tree.*;
java.util.Vector ;
java.util.Enumeration ;
/**
* A simple database browser without any specail stuff used for testing db's in the setup
* @author [email protected]
*/
public class sdbBrowser extends MyInternalFrame {
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
private
configurator mother;
String ID;
JPopupMenu popup = new JPopupMenu();
JMenu mnuAutoresize = new JMenu();
JMenuItem nextMI ;
JMenuItem lastMI ;
JMenuItem setChunk;
JRadioButtonMenuItem mniOn = new JRadioButtonMenuItem("on");
JRadioButtonMenuItem mniOff = new JRadioButtonMenuItem("off");
int autoresize = JTable.AUTO_RESIZE_ALL_COLUMNS ;
projectData theData;
Vector dbList = new Vector();
Vector tableList = new Vector();
boolean isLoading = true;
boolean isUpdating = false;
String currentlySelectedTable = new String ();
DataChooser dataChooser = null;
//Thread related
private activityMeter activity ;
private volatile Thread updateThread = null;
private volatile Thread workerThread = null;
private volatile Thread controllerThread = null;
private boolean StopAllThreads = false; //flag used to stop long tasks (but not the controller thread)
private String lastSQLStatement = new String();
/** Creates new form dbBrowser */
public sdbBrowser(configurator mainProgram,String uid) {
this.mother = mainProgram;
this.ID = uid;
this.theData = mainProgram .getProjectData ();
if (mainPr ogram .nextDBToBrowse.size() > 0) {
this.dbList = mainProgram.nextDBToBrowse;
}
else {
this.dbList = mainProgram.getProjectData().getDB();
}
initComponents();
activity = new activityMeter(stopButton,theProgressBar);
//add the popupmenu
//add data browser
nextMI = new JMenuItem("Next");
lastMI = new JMenuItem("Last");
nextMI.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (ActionEvent e) {
nextMI_actionPerformed(e);
}
});
lastMI.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (ActionEvent e) {
lastMI_actionPerformed(e);
}
});
popup.add(nextMI);
popup.add(lastMI);
popup.addSeparator();
//add the entry to set the chunksize
setChunk = new JMenuItem("Set Rows ("+getActiveDB().getChunkSize()+")");
setChunk.addActionListener (new java.awt.event.ActionListener() {
public void actionPerformed (ActionEvent e) {
setChunk_actionPerformed(e);
}
});
Autor: Thomas Schädler
161
Anhang A: Quelltext <xmlizer> configurator
popup.add(setChunk);
//add autoresize toggle
mnuAutoresize.setText("Autoresize");
mnuAutoresize.add(mniOn);
mnuAutoresize.add(mniOff);
mniOn.setSelected(true);
mniOn.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (ActionEvent e) {
mniOn_actionPerformed(e);
}
});
mniOff.setSelected(false);
mniOff.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (ActionEvent e) {
mniOff_actionPerformed(e);
}
});
popup.add(mnuAutoresize);
//init other stuff
if (dbList .size() > 0) {
dbComboBox.setSelectedIndex (0);
}
upperPanel .repaint();
isLoading = false;
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
private void initComponents() {
upperPanel = new javax.swing.JPanel();
dbLabel = new javax.swing.JLabel();
dbComboBox = new javax.swing.JComboBox(dbList);
sqlButton = new javax.swing.JButton();
helpButton = new javax.swing.JButton();
sqlLabel = new javax .swing .JLabel();
sqlScrollPane = new javax.swing .JScrollPane();
sqlTextArea = new javax.swing.JTextArea();
stopButton = new javax.swing.JButton();
theProgressBar = new javax .swing.JProgressBar();
limitCheckBox = new javax.swing .JCheckBox ();
obenPanel = new javax.swing.JPanel();
jSplitPane2 = new javax.swing.JSplitPane();
jPanel4 = new javax.swing.JPanel();
listScrollPane = new javax .swing.JScrollPane();
dbtableList = new javax.swing.JList(tableList);
jPanel5 = new javax.swing.JPanel();
jLabel2 = new javax.swing.JLabel();
tableScrollPane = new javax.swing.JScrollPane();
dbTable = new javax.swing.JTable();
setMaximizable(true);
setTitle("Database Browser");
setIconifiable(true);
setResizable(true);
setClosable(true);
addInternalFrameListener(new javax.swing.event .InternalFrameListener() {
public void internalFrameOpened(javax .swing.event.InternalFrameEvent evt ) {
}
public void internalFrameClosing (javax.swing.event.InternalFrameEvent evt) {
formInternalFrameClosing(evt);
}
public void internalFrameClosed(javax .swing.event.InternalFrameEvent evt ) {
}
public void internalFrameIconified(javax.swing.event .InternalFrameEvent evt) {
}
public void internalFrameDeiconified(javax .swing.event.InternalFrameEvent evt ) {
}
public void internalFrameActivated(javax.swing.event .InternalFrameEvent evt) {
}
public void internalFrameDeactivated(javax .swing.event.InternalFram eEvent evt ) {
}
});
upperPanel .setLayout (new java.awt.GridBagLayout());
java.awt.GridBagConstraints gridBagConstraints1;
dbLabel.setText("Database:");
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints1.insets = new java.awt.Insets(0, 2, 0, 0);
upperPanel .add(dbLabel, gridBagConstraints1);
dbComboBox .setPreferredSize(new java.awt.Dimension(240, 27));
dbComboBox .setMinimumSize(new java.awt.Dimension(126, 27));
dbComboBox .setMaximumSize(new java.awt.Dimension(32767, 27));
dbComboBox .addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
dbComboBoxActionPerformed(evt);
}
});
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.insets = new java.awt.Insets(2, 0, 2, 0);
gridBagConstraints1.anchor = java.awt.GridBagConstraints .WEST;
upperPanel .add(dbComboBox, gridBagConstraints1 );
sqlButton.setIcon(new javax.swing.ImageIcon(getClass().getResource ("/configurator/icons/actions/execute.gif")));
sqlButton.setToolTipText("Query the database with your SQL");
sqlButton.setPreferredSize (new java.awt.Dimension(51, 51));
sqlButton.setMaximumSize(new java.awt.Dimension(51, 51));
Autor: Thomas Schädler
162
Anhang A: Quelltext <xmlizer> configurator
sqlButton.setSelected(true);
sqlButton.setMinimumSize(new java.awt.Dimension(51, 51));
sqlButton.addActionListener(new java.awt.event .ActionListener () {
public void actionPerformed (java.awt.event .ActionEvent evt) {
sqlButtonActionPerformed(evt);
}
});
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 3;
gridBagConstraints1.gridy = 1;
gridBagConstraints1.insets = new java.awt.Insets(0, 2, 0, 2);
gridBagConstraints1.anchor = java.awt.GridBagConstraints .WEST;
upperPanel .add(sqlButton, gridBagConstraints1);
helpButton .setIcon(new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/Help16.gif")));
helpButton .setToolTipText("Open Help");
helpButton .setFont(new java.awt.Font("Dialog", 0, 10));
helpButton .addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
helpButtonActionPerformed(evt);
}
});
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 4;
gridBagConstraints1.gridy = 0;
gridBagConstraints1.insets = new java.awt.Insets(0, 0, 0, 2);
gridBagConstraints1.anchor = java.awt.GridBagConstraints .EAST;
upperPanel .add(helpButton, gridBagConstraints1 );
sqlLabel.setText("SQL Query:");
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 0;
gridBagConstraints1.gridy = 1;
gridBagConstraints1.insets = new java.awt.Insets(0, 2, 0, 0);
upperPanel .add(sqlLabel, gridBagConstraints1);
sqlTextArea.setLineWrap(true);
sqlTextArea.setColumns(45);
sqlTextArea.setRows(3);
sqlScrollPane.setViewportView(sqlTextArea );
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 1;
gridBagConstraints1.gridy = 1;
gridBagConstraints1.gridwidth = 2;
gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
upperPanel .add(sqlScrollPane, gridBagConstraints1);
stopButton .setIcon(new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/Stop16.gif")));
stopButton .setToolTipText("Stop background activity.");
stopButton .setEnabled(false);
stopButton .addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
stopButtonActionPerformed(evt);
}
});
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 3;
gridBagConstraints1.gridy = 0;
gridBagConstraints1.insets = new java.awt.Insets(0, 2, 0, 2);
gridBagConstraints1.anchor = java.awt.GridBagConstraints .WEST;
upperPanel .add(stopButton, gridBagConstraints1);
theProgressBar.setToolTipText("Shows the progress for longer tasks");
theProgressBar.setPreferredSize (new java.awt.Dimension(148, 21));
theProgressBar.setMinimumSize(new java.awt.Dimension(10, 21));
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 2;
gridBagConstraints1.gridy = 0;
gridBagConstraints1.insets = new java.awt.Insets(0, 0, 0, 2);
gridBagConstraints1.anchor = java.awt.GridBagConstraints.EAST;
upperPanel .add(theProgressBar, gridBagConstraints1);
limitCheckBox.setToolTipText("If selected, the results are diplayed in browsable chunks, not as one large table.");
limitCheckBox.setText("limit");
limitCheckBox.addItemListener(new java.awt.event.ItemListener () {
public void itemStateChanged(java.awt.event.ItemEvent evt ) {
limitCheckBoxItemStateChanged(evt);
}
});
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 4;
gridBagConstraints1.gridy = 1;
gridBagConstraints1.insets = new java.awt.Insets(0, 0, 0, 2);
gridBagConstraints1.anchor = java.awt.GridBagConstraints .EAST;
upperPanel .add(limitCheckBox, gridBagConstraints1);
getContentPane().add(upperPanel , java.awt.BorderLayout.NORTH);
obenPanel.setLayout(new java.awt.BorderLayout());
jSplitPane2.setDividerLocation(120);
jSplitPane2.setOneTouchExpandable(true);
jPanel4.setLayout(new java.awt.BorderLayout());
listScrollPane.setViewportView(dbtableList);
jPanel4.add(listScrollPane , java.awt.BorderLayout.CENTER );
jPanel5.setLayout(new java.awt.GridBagLayout());
java.awt.GridBagConstraints gridBagConstraints2;
Autor: Thomas Schädler
163
Anhang A: Quelltext <xmlizer> configurator
jLabel2.setText("Tables");
jLabel2.setHorizontalAlignment(javax .swing.SwingConstants.CENTER);
gridBagConstraints2 = new java.awt.GridBagConstraints();
gridBagConstraints2.insets = new java.awt.Insets(0, 0, 0, 2);
jPanel5.add(jLabel2, gridBagConstraints2);
jPanel4.add(jPanel5, java.awt.BorderLayout.NORTH);
jSplitPane2.setLeftComponent(jPanel4);
tableScrollPane .setPreferredSize(new java.awt.Dimension(400, 320));
dbTable.setPreferredScrollableViewportSize(new java.awt.Dimension(400, 350));
tableScrollPane .setViewportView (dbTable);
jSplitPane2.setRightComponent(tableScrollPane);
obenPanel.add(jSplitPane2, java.awt.BorderLayout.CENTER);
getContentPane().add(obenPanel, java.awt.BorderLayout.CENTER);
pack();
}
private void limitCheckBoxItemStateChanged(java.awt.event.ItemEvent evt) {
// Add your handling code here:
if (!isUpdating ) {
getActiveDB ().setLimit (!getActiveDB().hasLimit());
}
}
private void stopButtonActionP erformed(java.awt.event.ActionEvent evt) {
// Add your handling code here:
Runnable r = new Runnable() {
public void run() {
stopButton.setEnabled(false);
sqlButton.setEnabled(true);
activity.init();
StopAllThreads = true;
mother.getLog().addInformation("Background activity stopping...");
}
};
controllerThread = new Thread(r);
controllerThread.start();
}
private void dbComboBoxActionPerformed(java.awt.event.ActionEvent evt) {
// Add your handling code here:
if (!isLoading) {
updateDB(); //updates the DB Browser
}
}
public void setDataChooser(DataChooser data) {
this.dataChooser = data;
}
private void formInternalFrameClosing(javax.swing.event .InternalFrameEvent evt) {
// Add your handling code here:
boolean update = false;
mother.nextDBToBrowse.removeAllElements();
mother.close(this.ID);
}
private void helpButtonActionPerformed(java.awt.event.ActionEvent evt) {
// Add your handling code here:
helpWindow help = (helpWindow)mother .open("help");
help.loadPage("/configurator/help/tools_dbbrowser.html");
}
private void sqlButtonActionPerformed(java.awt.event.ActionEvent evt) {
// Add your handling code here:
if (!(sqlTextArea.getText().trim().equalsIgnoreCase (new String()))) {
try {
doSQL(sqlTextArea.getText().trim(),true);
}
catch(Exception sqlex) {
mother.getLog().addError(sqlex);
}
}
else {
sqlTextArea .setText(this.lastSQLStatement);
}
}
// Variables declaration - do not modify
private javax.swing .JPanel upperPanel;
private javax.swing .JLabel dbLabel;
private javax.swing .JComboBox dbComboBox ;
private javax.swing .JButton sqlButton;
private javax.swing .JButton helpButton;
private javax.swing .JLabel sqlLabel ;
private javax.swing .JScrollPane sqlScrollPane ;
private javax.swing .JTextArea sqlTextArea;
private javax.swing .JButton stopButton;
private javax.swing .JProgressBar theProgressBar;
private javax.swing .JCheckBox limitCheckBox;
private javax.swing .JPanel obenPanel;
private javax.swing .JSplitPane jSplitPane2;
private javax.swing .JPanel jPanel4;
private javax.swing .JScrollPane listScrollPane;
private javax.swing.JList dbtableList;
private javax.swing .JPanel jPanel5;
private javax.swing .JLabel jLabel2;
Autor: Thomas Schädler
164
Anhang A: Quelltext <xmlizer> configurator
private javax.swing .JScrollPane tableScrollPane;
private javax.swing .JTable dbTable;
// End of variables declaration
/**
* Updated the TreeView of the Database
*/
synchronized private void updateDB() {
mother.getLog().addInformation("Retrieving tables from selected database..." );
final dbItem theDB = getActiveDB();
final sdbBrowser This = this;
if (theDB != null) {
Runnable r = new Runnable() {
public void run() {
activity .start (false);
dbtableList.setEnabled(false);
isUpdating = true;
limitCheckBox.setSelected(theDB.hasLimit());
isUpdating = false;
try {
tableList = theDB.getTableList ();
}
catch(Exception e) {
activity.stop(false);
mother.getLog().addError(e);
return;
}
//make the new list
dbtableList = new JList(tableList);
//make the list functional
dbtableList.getSelectionModel ().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
//add the mouselistener
ItemListener ilst = new ItemListener(This);
dbtableList.addMouseListener(ilst);
//show the new list
listScrollPane .getViewport().add(dbtableList );
dbtableList.setEnabled(true);
setChunk .setText("Set Rows (" +theDB.getChunkSize()+")");
mother.getLog().addInformation("Tablelist updated.");
activity .stop(false);
}
};
updateThread = new Thread(r);
StopAllThreads = false ;
updateThread.start();
}
}
public void chooseDB(String dbkey) {
int counter = 0;
for (Enume ration e = this.dbList.elements (); e.hasMoreElements();) {
dbItem item = (dbItem)e.nextElement();
//System.out.println("SEARCHING: " + dbkey + " >> " + item.getName());
if (item.getName().equalsIgnoreCase(dbkey)) {
this.dbtableList.setSelectedIndex (counter);
this.dbComboBox.setSelectedIndex(counter);
//System.out.println(" >> MATCH >> " + counter);
}
else counter++;
}
}
public synchronized void inspect(SQLStatement stat ) {
chooseDB(stat.getDB());
sqlTextArea.setText(stat.getSQL ());
doSQL(stat.getSQL(),true);
}
/**
* Shows the specified queries' resultset in a JTable
*/
private void doSQL(String sqlQuery,boolean reset) {
//finalize for runnable
final String ThesqlQuery = sqlQuery;
final dbItem theDB = getActiveDB();
if (reset) { theDB.resetLimit(); }
this.lastSQLStatement = sqlQuery;
Runnable r = new Runnable() {
public void run() {
Hashtable navData = new Hashtable ();
activity.start(false);
try {
dbTable = theDB.getQueryAsJTable(ThesqlQuery );
navData = theDB.getNavigator();
}
catch(Exception ex ) {
activity .stop(false );
mother.getLog().addError (ex);
return;
}
dbTable.addMouseListener(new java.awt.event .MouseAdapter() {
public void mouseClicked (MouseEvent e) {
dbTable_mouseClicked (e);
}
});
dbTable.setAutoResizeMode(autoresize);
tableScrollPane.getViewport().add(dbTable);
Autor: Thomas Schädler
165
Anhang A: Quelltext <xmlizer> configurator
tableScrollPane.setBorder(BorderFactory.createTitledBorder (theDB.getName() + " >> SQL Query Result : Rows " +
navData.get("first") + "-" + navData.get("last") + " of " + navData.get("max")));
boolean hasNext = ((Boolean)navData.get("hasNext")).booleanValue();
boolean hasLast = ((Boolean)navData.get("hasLast")).booleanValue();
if (hasNext) { nextMI.setEnabled(true); }
else { nextMI.setEnabled(false); }
if (hasLast) { lastMI.setEnabled(true); }
else { lastMI.setEnabled(false); }
mother.getLog().addInformation("SQL Query returned a valid ResultSet.");
activity.stop(false);
}
};
workerThread = new Thread(r);
StopAllThreads = false;
workerThread.start();
}
private void dbTable_mouseClicked(MouseEvent e) {
if(SwingUtilities.isRightMouseButton (e)) {
popup.show(dbTable,e.getX(),e.getY());
}
}
private void nextMI_actionPerformed (ActionEvent e) {
getActiveDB().nextChunk();
try {
doSQL(getActiveDB().getLastSQL(),false);
}
catch(Exception ex) {
mother .getLog().addError(ex);
}
}
private void lastMI_actionPerformed (ActionEvent e) {
getActiveDB().lastChunk();
try {
doSQL(getActiveDB().getLastSQL(),false);
}
catch(Exception ex) {
mother .getLog().addError(ex);
}
}
private void mniOff_actionPerformed (ActionEvent e) {
autoresize = JTable.AUTO_RESIZE_OFF;
dbTable.setAutoResizeMode(autoresize );
mniOff.setSelected(true);
mniOn.setSelected(false);
}
private void mniOn_actionPerformed(ActionEvent e) {
autoresize = JTable.AUTO_RESIZE_ALL_COLUMNS;
dbTable.setAutoResizeMode(autoresize );
mniOff.setSelected(false);
mniOn.setSelected(true);
}
/**
* Sets the number of rows to display per DB retrieve
*/
private void setChunk_actionPerformed(ActionEvent e) {
String input = dbItem.Convertint2String(getActiveDB ().getChunkSize ());
String before = new String (input);
input = JOptionPane.showInputDialog("Enter the number of rows to show:" );
if ((input != null) && (!input.equalsIgnoreCase(new String())) && (!input.equalsIgnoreCase(before ))) {
int newvalue = dbItem.ConvertString2int(input);
getActiveDB ().setChunkSize(newvalue);
setChunk.setText("Set Rows ("+newvalue+")");
mother .getLog().addInformation("Changed number of ro ws to display to " + newvalue + ".");
}
}
/**
* This method updates the UI if the setupwindow is closed
* (and a change in the setup component occured)
*/
public synchronized void update(configurator conf) {
isLoading = true;
dbtableList.setEnabled(false);
this.mother = conf;
this.theData = conf.getProjectData();
if (conf.nextDBToBrowse.size() > 0) {
this.dbList = conf.nextDBToBrowse;
}
else {
this.dbList = conf.getProjectData().getDB();
}
if (dbList .size() > 0) {
dbComboBox.setSelectedIndex (0);
}
this.repaint();
isLoading = false;
}
/**
* Returns the currently selected d bItem
*/
synchronized private dbItem getActiveDB() {
return (dbItem)dbComboBox.getSelectedItem ();
}
/**
Autor: Thomas Schädler
166
Anhang A: Quelltext <xmlizer> configurator
* Listens for listItem-(Mouse)-Events on the dbtableList
* -> For database queries
*/
class ItemListener implements MouseListener {
protected sdbBrowser m_parent;
protected JList m_list;
public ItemListener(sdbBrowser parent) {
m_parent = parent;
m_list = parent.dbtableList ;
}
public void mouseClicked(MouseEvent e) {
doAction();
}
public
{}
public
{}
public
{}
public
{}
void mousePressed(MouseEvent e)
void mouseReleased(MouseEvent e)
void mouseEntered(MouseEvent e)
void mouseExited(MouseEvent e )
protected void doAction() {
int index = m_list.getSelectedIndex();
if (index < 0) {
return;
}
listItem data = (listItem)m_list .getModel().getElementAt(index );
mother .getLog().addInformation("Retrieving table " + data.getName() + "...");
getActiveDB ().resetLimit();
doSQL("SELECT * FROM " + data.getName(),true);
}
}
}/*
* dtd2xs.java
*
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------****************************************************************************
* dtd2xs: Translates XML 1.0 DTD to REC-xmlschema-1-20010502
****************************************************************************
* Copyright (C) 07/2001 Ralf Schweiger
*
* This program 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.
*
* This program 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.
*
* Contact the Author:
*
* University of Giessen
* c/o Ralf Schweiger
* Heinrich-Buff-Ring 44
* 35392 Giessen
* Germany
*
* tel.:
+49-641-9941370
* fax.:
+49-641-9941359
* mailto: [email protected] -giessen.de
*
***************************************************************************/
package configurator;
import
import
import
import
import
import
java.io.*;
java.util.*;
com.sun.xml.tree.XmlDocument;
org.w3c.dom.*;
org.xml.sax.InputSource;
com.jclark.xsl.dom.*;
/**
* DTD => REC -xmlschema -1-20010502
* @author Ralf Schweiger
* @version 1.00, 06/12/01
*/
public class dtd2xs {
Autor: Thomas Schädler
167
Anhang A: Quelltext <xmlizer> configurator
private String [] delimiter = { ",|", ";/" };
private
private
private
private
private
final
final
final
final
final
int
int
int
int
int
meaninglessEntity = -1; // no meaningful entity
enumerationEntity = 0;
contentModelEntity = 1;
attributeListEntity = 2;
unusedEntity = 3;
private final String schemaPrefix = "xs";
private final String [] builtInSimpleType =
{ "string", "normalizedString" , "token", "byte", "unsignedByte", "base64Binary", "hexBinary", "integer", "positiveInteger", "negativeInteger" , "nonNegativeInteger", "nonPositiveInteger", "int" , "unsignedInt" , "long", "unsignedLong", "short",
"unsignedShort", "decimal", "float", "double", "boolean", "time" , "dateTime", "duration", "date", "gMonth", "gYear", "gYearMonth", "gDay", "gMonthDay", "Name", "QName", "NCName" , "anyURI" , "language", "ID", "IDREF", "IDREFS", "ENTITY", "ENTITIES",
"NOTATION", "NMTOKEN", "NMTOKENS" };
private
private
private
private
private
private
private
private
private
final int maxNumComments = 1000;
int numComments;
String [] comment;
boolean ignoreComments ;
String commentLanguage ;
int conceptHighlight;
int conceptOccurrence;
int commentLength;
String conceptRelation ;
/**
* Logging information.
*/
private PrintStream psLog; // application
private StringBuffer sbLog; // applet
private void log(Object item) {
if (psLog != null) psLog.print(item);
else if (sbLog != null) sbLog.append (item);
}
/**
* Create a DTD to REC-xmlschema-1-20010502 translator.
* @param log Where to put logging information.
*/
public dtd2xs(Object log ) {
comment = new String [maxNumComments ];
psLog = null;
sbLog = null;
if (log instanceof PrintStream) psLog = (PrintStream) log;
else if (log instanceof StringBuffer ) sbLog = (StringBuffer) log;
}
private Element simpleType(Document schema, String name , String content) {
Element simpleType = schema.createElement ("simpleType");
if (name != null) {
schema .getDocumentElement().appendChild(simpleType);
simpleType.setAttribute("name", name);
annotate(schema, simpleType );
}
Element restriction = schema.createElement("restriction" );
simpleType .appendChild(restriction);
if (content.startsWith("(")) {
restriction .setAttribute("base", "string");
StringTokenizer contentTokenizer = new StringTokenizer(content, "(|)");
while (contentTokenizer.hasMoreTokens ()) {
Element enumeration = schema .createElement("enumeration");
restriction.appendChild (enumeration);
enumeration.setAttribute("value", contentTokenizer.nextToken().trim());
annotate(schema, enumeration );
}
}
else restriction.setAttribute("base" , content);
return simpleType; // enumeration
}
private void attributeGroup(Document schema, Element group, String content) {
StringTokenizer contentTokenizer = new StringTokenizer(content);
String lookahead, name = null;
while (contentTokenizer.hasMoreTokens()) {
if (name == null) name = contentTokenizer.nextToken(" \t\n\r\f");
if (name.startsWith("%") && name.endsWith(";")) {
Element attributeGroupRef = schema.createElement ("attributeGroup");
group.appendChild(attributeGroupRef);
attributeGroupRef.setAttribute("ref", name.substring(1, name.length() - 1));
name = null;
continue;
}
Element attribute = schema.createElement("attribute" );
group.appendChild(attribute );
String type = contentTokenizer.nextToken(" \t\n\r\f");
if (type.startsWith("(") && ! type.endsWith(")")) type += contentTokenizer.nextToken(")");
String use = contentTokenizer.nextToken(") \t\n\r\f");
String value = null;
if ("#IMPLIED #REQUIRED #FIXED".indexOf(use.toUpperCase()) < 0) {
value = use;
use = "#IMPLIED";
}
else if (contentTokenizer.hasMoreTokens())
value = contentTokenizer.nextToken(" \t\n\r\f");
String quote = null;
if (value != null && -1 < "\"'".indexOf(value.charAt (0)))
quote = String.valueOf(value .charAt(0));
if (quote != null) {
if (! value.endsWith(quote) || value.equals (quote))
value = value.substring(1, value.length ()) + contentTokenizer.nextToken(quote);
else
value = value.substring(1, value.length () - 1);
Autor: Thomas Schädler
168
Anhang A: Quelltext <xmlizer> configurator
lookahead = null;
}
else {
lookahead = value;
value = null;
}
// log("\ndtd2xs: attribute[" + name + "][" + type + "][" + use + "][" + value + "]");
if (name.indexOf(':') < 0) { // non-colonized name (NCName)
attribute.setAttribute("name", name);
if (type.startsWith("%"))
attribute.setAttribute("type" , type.substring(1, type.length() - 1));
else if (type.startsWith("("))
attribute.appendChild(simpleType(schema , null, type));
else if (type.toUpperCase().equals("CDATA")) // no valid simpleType
attribute.setAttribute("type" , "string" );
else
attribute.setAttribute("type" , type);
}
else attribute.setAttribute ("ref", name); // colonized name (QName)
annotate(schema, attribute);
use = use.toUpperCase();
if (use.equals("#REQUIRED"))
attribute.setAttribute("use" , "required");
if (use.equals("#FIXED"))
attribute.setAttribute("fixed", value);
else if (value != null)
attribute.setAttribute("default", value);
name = lookahead ;
}
}
private int occurs(Element el, String content ) {
int length = content.length();
if (content.endsWith ("?"))
{ el.setAttribute("minOccurs", "0"); -- length ; }
else if (content.endsWith("+"))
{ el.setAttribute("maxOccurs", "unbounded"); -- length; }
else if (content.endsWith("*"))
{ el.setAttribute("minOccurs", "0"); el.setAttribute("maxOccurs", "unbounded"); -- length; }
return length;
}
private Element createGroup(Document schema, String type, StringTokenizer content, int delimiterIndex ) {
Element groupType = schema .createElement(type);
while (content.hasMoreTokens()) {
String item = content.nextToken().trim();
if (item.startsWith("("))
groupType.appendChild(anonymousGroup(schema , item, delimiterIndex));
else if (item.startsWith("%")) { // reference to dtd entity respectively xs group
Element groupRef = schema.createElement("group");
groupType.appendChild(groupRef);
groupRef.setAttribute("ref", item.substring (1, occurs (groupRef, item) - 1)); // remove semicolon
}
else if (item.startsWith("#"))
groupType.setAttribute("_dtd2xs_mixed_", "true"); // later moved to complexType!!!
else {
Element elRef = schema.createElement("element");
groupType.appendChild(elRef);
elRef.setAttribute ("ref", item.substring(0, occurs(elRef, item)));
}
}
return groupType;
}
private String hideDepth (String content, int delimiterIndex) { // ((a, b), (x, y)) => ((a; b), (x; y)) for correct parsing
StringBuffer newContent = new StringBuffer("");
int depth = 0;
for (int i = 0; i < content.length(); ++ i) {
char c = content.charAt(i);
if (c == '(')
{ newContent.append(c); ++ depth ; }
else if (c == ')')
{ newContent.append(c); -- depth ; }
else if (depth > 0 && c == delimiter[delimiterIndex].charAt(0)) // comma
newContent.append(delimiter[1 - delimiterIndex].charAt(0));
else if (depth > 0 && c == delimiter[delimiterIndex].charAt(1)) // bar
newContent.append(delimiter[1 - delimiterIndex].charAt(1));
else
newContent.append(c);
}
return newContent.toString ();
}
private void element(Document schema, String name, String content, int delimiterIndex ) {
Element el = schema.createElement("element");
schema.getDocumentElement().appendChild(el);
el.setAttribute ("name", name);
annotate(schema , el);
StringTokenizer contentTokenizer = new StringTokenizer(content, "(,;|/?+* \t\n\r\f)");
if (contentTokenizer .countTokens() == 1 && contentTokenizer.nextToken().toUpperCase().equals ("#PCDATA" )) // simpleType
el.setAttribute("type" , "string" );
else {
Element complexType = schema.createElement ("complexType");
el.appendChild(complexType);
Element group = anonymousGroup(schema , content, delimiterIndex );
complexType .appendChild(group);
/* done by xslt
if (group.getAttribute("_dtd2xs_mixed_").equals("true")) {
group.removeAttribute("_dtd2xs_mixed_");
complexType.setAttribute("mixed", "true");
}
*/
}
Autor: Thomas Schädler
169
Anhang A: Quelltext <xmlizer> configurator
}
private void group(Document schema, String name, String content, int delimiterIndex) {
Element namedGroup = schema.createElement ("group");
schema.getDocumentElement().appendChild(namedGroup);
namedGroup .setAttribute("name", name);
annotate(schema , namedGroup);
namedGroup.appendChild(anonymousGroup(schema, content, delimiterIndex));
}
private Element anonymousGroup (Document schema, String content, int delimiterIndex) {
Element group, atHolder = schema.createElement ("atHolder");
if (content.startsWith("("))
content = content.substring (1, occurs (atHolder, content) - 1); // remove parentheses
else
content = content.substring (0, occurs (atHolder, content));
content = hideDepth(content, delimiterIndex);
StringTokenizer contentTokenizer = new StringTokenizer(content, delimiter[delimiterIndex].substring(1, 2)); // BAR
if (contentTokenizer .countTokens() > 1)
group = createGroup(schema, "choice", contentTokenizer, 1 - delimiterIndex);
else if (content.trim().toUpperCase().equals("EMPTY"))
group = schema.createElement("_dtd2xs_empty_");
else if (content.trim().toUpperCase().equals("ANY"))
group = schema.createElement("_dtd2xs_any_");
else // default
group = createGroup(schema, "sequence", new StringTokenizer(content, delimiter[delimiterIndex ]), 1 - delimiterIndex); // COMMA SEPARATION
// optimize
if (atHolder.getAttribute("minOccurs").length() > 0) group.setAttribute("minOccurs", atHolder.getAttribute("minOccurs" ));
if (atHolder.getAttribute("maxOccurs").length() > 0) group.setAttribute ("maxOccurs", atHolder.getAttribute("maxOccurs" ));
return group;
}
private Document transform(Document xml, String xsltURI ) {
try {
Document xslt = XmlDocument .createXmlDocument(xsltURI);
Document result = new XmlDocument();
(new XSLTransformEngine()).createTransform (xslt).transform(xml, result);
result .getDocumentElement().removeAttribute("xmlns"); // added by xt
return result;
}
catch (Exception x)
{ log("\ndtd2xs: " + x); return null; }
}
private void minusAtplusNs(Document schema) {
schema.replaceChild(minusAtplusNs(schema, schema.getDocumentElement()), schema.getDocumentElement ());
schema.getDocumentElement().setAttribute("xmlns:" + schemaPrefix, "http://www.w3.org/2001/XMLSchema");
}
private boolean isBuiltInSimpleType (String type) {
for (int i = 0; i < builtInSimpleType.length; ++ i)
if (type.equals(builtInSimpleType[i]))
return true;
return false;
}
private Node minusAtplusNs(Document schema, Element e) {
Element ee = schema.createElement(schemaPrefix + ':' + e.getTagName());
// attributes
NamedNodeMap ats = e.getAttributes();
for (int i = 0; i < ats.getLength(); ++ i) {
String name = ats.item(i).getNodeName ();
String value = ats.item(i).getNodeValue();
if (! name.equals("xmlns") && ! name.equals("_dtd2xs_mixed_")) // remove these attributes
if ((name.equals("type" ) || name.equals("base")) && isBuiltInSimpleType(value))
ee.setAttribute(name, schemaPrefix + ':' + value);
else
ee.setAttribute(name, value);
}
// elements
for (Node x = e.getFirstChild(); x != null; x = x.getNextSibling())
if (x.getNo deType() == Node.ELEMENT_NODE)
ee.appendChild(minusAtplusNs (schema, (Element) x));
else
ee.appendChild(x.cloneNode(true));
return ee;
}
/*
private String replace(String source, String from, String to) {
StringBuffer goal = new StringBuffer("");
int i = 0, j = source.indexOf(from);
while (j >= 0) {
goal.append(source.substring(i, j));
goal.append(to);
i = j + from.length();
j = source.indexOf(from, i);
}
goal.append(source.substring(i));
return goal.toString();
}
*/
private String removeComments(String dtd ) {
StringBuffer dtdWithoutComments = new StringBuffer("");
int commentStart, commentEnd = 0, from = 0;
while ((commentStart = dtd.indexOf("<!--", commentEnd)) >= 0) {
commentEnd = dtd.indexOf("-->", commentStart) + 3;
dtdWithoutComments.append(dtd.substring(from, commentStart));
if (! ignoreComments) {
comment[numComments] = dtd.substring(commentStart + "<!--".length(), commentEnd - "-->".length ());
if (comment[numComments ].length() <= commentLength) ++ numComments;
Autor: Thomas Schädler
170
Anhang A: Quelltext <xmlizer> configurator
}
from = commentEnd;
}
return dtdWithoutComments + dtd.substring (from, dtd.length());
}
private int weightOf(char c, boolean prefix) {
if ("\n\t:".indexOf(c) >= 0)
return 10;
else if (prefix && "<[{(\"'".indexOf(c) >=0 || ! prefix && ">]})\"'".indexOf(c) >= 0)
return 100;
else
return 1;
}
private boolean related(String comment, String concept) {
int occurrence = 0;
boolean highlighted = false;
int conceptStart, conceptEnd = 0;
while ((conceptStart = comment.indexOf(concept, conceptEnd)) >= 0) {
conceptEnd = conceptStart + concept.length ();
++ occurrence;
int highlightPrefix = 0;
for (int i = conceptStart; i > 0 && ! Character .isLetterOrDigit(comment.charAt(i - 1)); -- i) {
highlightPrefix += weightOf(comment.charAt(i - 1), true);
if (comment.charAt (i - 1) == '\n') break;
}
int highlightPostfix = 0;
for (int i = conceptEnd; i < comment.length() && ! Character.isLetterOrDigit(comment.charAt(i)); ++ i) {
highlightPostfix += weightOf (comment.charAt (i), false );
if (comment.charAt (i) == '\n') break;
}
if (highlightPrefix > 0 && highlightPostfix > 0)
highlighted |= (highlightPrefix + highlightPostfix >= conceptHighlight);
}
return (highlighted && occurrence >= conceptOccurrence);
}
private void annotate(Document schema, Element construct) {
if (ignoreComments || conceptRelation.indexOf(construct.getTagName ()) < 0)
return ;
Element annotation = schema.createElement ("annotation");
String concept;
if (! construct .getAttribute("name").equals(""))
concept = construct.getAttribute ("name");
else if (! construct .getAttribute("ref").equals(""))
concept = construct.getAttribute ("ref");
else if (! construct .getAttribute("value").equals(""))
concept = construct.getAttribute ("value");
else
return ;
int numDocumentation = 0;
for (int i = 0; i < numComments ; ++ i)
if (related(comment[i], concept)) {
log("\ndtd2xs: relate(" + concept + ", \"" + comment[i] + "\")");
Element documentation = schema.createElement("documentation");
annotation.appendChild(documentation);
if (commentLanguage != null && ! commentLanguage .equals(""))
documentation.setAttribute("xml:lang", commentLanguage );
documentation.appendChild(schema.createTextNode(comment[i]));
++ numDocumentation;
}
if (numDocumentation > 0) construct.appendChild(annotation);
}
private boolean isLexicalUnit(char first , char last) {
if (Character.isWhitespace (first) && ! Character.isWhitespace (last)) return false ;
if (! Character .isWhitespace(first) && Character.isWhitespace (last)) return false ;
if (first == '(' && last != ')') return false;
if (first != '(' && last == ')') return false;
return true;
}
private int useOf(String entityName , String entityContent, String dtd, boolean resolveEntity) {
// log("\ndtd2xs: <useOf entityName= \"" + entityName + " \" entityContent=\"" + entityContent + "\">\n");
if (resolveEntity || entityContent.length () < 2 || ! isLexicalUnit (entityContent.charAt(0), entit yContent.charAt(entityContent .lengt h() - 1)))
return meaninglessEntity;
/* does the entity represent a meaningful unit? */
String entityUse = "%" + entityName + ";";
int entityUseStart, entityUseEnd = 0, entityIndex = -1, elementIndex = -1, attlistIndex = -1;
boolean entityUsed = false ;
while ((entityUseStart = dtd.indexOf(entityUse , entityUseEnd)) >= 0) {
entityUsed = true;
entityUseEnd = entityUseStart + entityUse.length();
if (entityIndex < 0) {
entityIndex = dtd.lastIndexOf("<!ENTITY", entityUseStart);
if (-1 < entityIndex && dtd.indexOf(">", entityIndex) < entityUseStart)
entityIndex = -1;
}
if (elementIndex < 0) {
elementIndex = dtd.lastIndexOf("<!ELEMENT", entityUseStart );
if (-1 < elementIndex && dtd.indexOf(">", elementIndex) < entityUseStart)
elementIndex = -1;
}
if (attlistIndex < 0) {
attlistIndex = dtd.lastIndexOf("<!ATTLIST", entityUseStart );
if (-1 < attlistIndex && dtd.indexOf(">", attlistIndex) < entityUseStart)
attlistIndex = -1;
}
}
if (! entityUsed) return unused Entity;
// if (entityIndex >= 0) return meaninglessEntity; // comment out for CDA because of null.code.set
// -1 < elementIndex means that entity is used in element declaration ...
int entityMeaning = meaninglessEntity;
Autor: Thomas Schädler
171
Anhang A: Quelltext <xmlizer> configurator
if (elementIndex >= 0 && attlistIndex < 0 || -1 < entityContent.indexOf("#PCDATA" ) || -1 < entityContent.indexOf('*')
|| -1 < entityContent.indexOf('?') || -1 < entityContent.indexOf(',') || -1 < entityContent.indexOf('+'))
entityMeaning = contentModelEntity;
else if (-1 < "CDATA".indexOf(entityContent) || entityContent .startsWith("(") && entityContent.endsWith(")"))
entityMeaning = enumerationEntity;
else if (attlistIndex >= 0 && elementIndex < 0 && (new StringTokenizer(entityContent)).countTokens() >= 2)
entityMeaning = attributeListEntity;
return entityMeaning ;
}
private String resolveEntity(String name , String content, String dtd) {
StringBuffer resolved = new StringBuffer("");
int endUse = 0, startUse;
while (-1 < (startUse = dtd.indexOf("%" + name + ";", endUse))) {
resolved.append(dtd.substring(endUse, startUse));
resolved.append(content);
endUse = startUse + name.length() + 2;
}
resolved.append (dtd.substring(endUse , dtd.length()));
return resolved .toString();
}
/**
* Translate DTD to REC-xmlschema-1-20010502.<P>
* @param dtdURL Location of the DTD resource.<P>
* @param resolveEntities Resolve DTD entities. Unused DTD entities are ignored. Map meaningful DTD entities onto named,
i.e. reusable XML Schema concepts such as group, attributeGroup and simpleType.<P>
* @param preserveComments Preserve DTD comments. Map DTD comments onto XML Schema documentation. Locates DTD comments at
/schema/annotation[1]/documentation[<I>i</I>] referred to by <BR><documentation source="#xpointer(/schema/annotation[1]/documentation[<I>i</I>]/text())"/>.<P>
* @param commentLanguage Examples: "en", "de" ... Result: <documentation xml:lang="en"/>.<P>
* @param commentLength Ignore DTD comments with length greater than <code>commentLength</code>.<P>
* @param conceptRelation Relate DTD comments to model concepts. Ignore comments without concept relation.<P>
* @param schemaConcepts Example: "element enumeration" relates DTD comments to the model concepts valueof(element/@name), value-of(enumeration/@value).<P>
* @param minRelation Minimum relation between DTD comment and model concept. Heuristics <BR>{ relation = 0; for (concept
occurs in comment) relation += highlight(concept); return relation >= minRelation; }<P>
* @return XML Schema<P>
*/
public String translate(
String dtdURI,
String xsltURI ,
boolean resolveEntities,
boolean ignoreComments,
int commentLength,
String commentLanguage,
String conceptRelation,
int conceptHighlight,
int conceptOccurrence) {
try {
log("\ndtd2xs: dtdURI " + dtdURI );
log("\ndtd2xs: resolveEntities " + resolveEntities);
log("\ndtd2xs: ignoreComments " + ignoreComments);
log("\ndtd2xs: commentLength " + commentLength);
log("\ndtd2xs: commentLanguage " + commentLanguage);
log("\ndtd2xs: conceptHighlight " + conceptHighlight );
log("\ndtd2xs: conceptOccurrence " + conceptOccurrence);
log("\ndtd2xs: conceptRelation " + conceptRelation);
Document schema = new XmlDocument();
schema .appendChild(schema.createElement("schema"));
log("\ndtd2xs: load DTD ... ");
String dtd = (new xurl()).communicate (dtdURI);
log("done");
log("\ndtd2xs: remove comments from DTD ... ");
this.ignoreComments = ignoreComments;
this.commentLength = commentLength;
this.commentLanguage = commentLanguage;
this.conceptRelation = conceptRelation;
this.conceptHighlight = conceptHighlight;
this.conceptOccurrence = conceptOccurrence ;
numComments = 0;
dtd = removeComments(dtd);
log("done");
log("\ndtd2xs: DOM translation ...");
StringTokenizer dtdTokenizer = new StringTokenizer(dtd, "<>");
while (dtdTokenizer.hasMoreTokens()) {
String decl = dtdTokenizer.nextToken();
if (decl.startsWith("!ENTITY")) {
StringTokenizer entTokenizer = new StringTokenizer(decl, " \t\n\r\f%");
entTokenizer.nextToken();
String name = entTokenizer.nextToken();
String content = entTokenizer .nextToken ("").trim();
content = content.substring(1, content.length() - 1); // remove quotes
switch (useOf(name, content, dtd, resolveEntities )) {
case enumerationEntity:
log("\ndtd2xs: simpleType[" + name + "][" + content + "]");
simpleType(schema, name, content);
break;
case contentModelEntity:
log("\ndtd2xs: group[" + name + "][" + content + "]");
group(schema, name, content, 0);
break;
case attributeListEntity:
log("\ndtd2xs: attributeGroup[" + name + "]");
Element atGroup = schema.createElement("attributeGroup");
schema .getDocumentElement().appendChild(atGroup);
atGroup.setAttribute("name", name);
annotate(schema, atGroup);
attributeGroup(schema , atGroup, content);
break;
case meaninglessEntity: // resolve entity that must be declared before used !!!
log("\ndtd2xs: resolve[" + name + "][" + content + "]");
dtd = resolveEntity(name, content, dtd);
dtd = dtd.substring(dtd.indexOf(decl) + decl.length (), dtd.length()); // entity is processed and
can be redefined!
Autor: Thomas Schädler
172
Anhang A: Quelltext <xmlizer> configurator
dtdTokenizer = new StringTokenizer(dtd, "<>");
// ignore unusedEntity
}
}
else if (decl.startsWith("!ELEMENT")) {
StringTokenizer elTokenizer = new StringTokenizer (decl);
elTokenizer.nextToken();
String name = elTokenizer.nextToken();
String content = elTokenizer.nextToken("").trim();
// log("\ndtd2xs: element[" + name + "][" + content + "]");
element(schema , name, content, 0);
}
else if (decl.startsWith("!ATTLIST")) {
StringTokenizer atTokenizer = new StringTokenizer (decl);
atTokenizer.nextToken();
String complexTypeRef = atTokenizer.nextToken();
String content = atTokenizer.nextToken("").trim();
// attached to element by xsl
Element attributes = schema.createElement("_dtd2xs_attributes_");
schema.getDocumentElement().appendChild (attributes);
attributes.setAttribute("of", complexTypeRef );
// log("\ndtd2xs: attributeGroup[" + content + "]");
attributeGroup(schema, attributes, content);
}
}
log("\n... done" );
log("\ndtd2xs: complextype.xsl ... ");
schema = transform(schema, xsltURI); // move mixed attribute, attach attributes to element, remove redundant
groups
log("done");
log("\ndtd2xs: add namespace ... ");
minusAtplusNs(schema); // remove crap attributes, add xml schema namespace
log("done");
// further optimization possible
StringWriter sw = new StringWriter();
((XmlDocument) schema).write(sw);
return sw.toString();
}
catch (Exception x)
{ log("\ndtd2xs: " + x); return null; }
}
}
/*
* SchemaElement.java
*
* This class representates a Schema Element
*
* Created on 18. April 2002, 20:20
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import
import
import
import
org.jdom.*;
java.util.*;
javax.swing .*;
javax.swing .tree.*;
/**
* Represents a SchemaElement <element name="..." ...>
* @author [email protected]
*/
public class SchemaElement {
private String tname;
private String id;
private String trealname ;
private Element telement ;
private Vector attributes = new Vector(); //of SchemaAttributes
private SchemaContent content;
private Vector children = new Vector();
private JPanel tpanel = null;
private String type = null;
private String typeRef = null;
private boolean hasInternalType = false;
private SchemaSimpleConstraint simpleConstraint = null;
private SchemaOccurrence occurrence = null;
private String documentation = null;
private Vector parents = new Vector (); //of SchemaElements
private DefaultMutableTreeNode node = null;
private configurator mother = null;
//schemaElement-Data
public String SCHEMAattributeFormDefault = new String("unqualified");
public String SCHEMAelementFormDefault = new String("unqualified" );
public String SCHEMAtargetNameSpace = new String("");
public String SCHEMAversion = new String ("");
public String SCHEMAlanguage = new String("");
Autor: Thomas Schädler
173
Anhang A: Quelltext <xmlizer> configurator
//type handling
private SchemaType theType = null;
//SQL
private Vector SQLStatements = new Vector(); //of SQLStatement
private String repetitionStatement = null;
//CONSTRUCTORS
//----------------------------------------------------------------------------------------------/**
* Document node-like constructor
**/
public SchemaElement(configurator conf,DefaultMutableTreeNode node,String name,Element element) {
this.mother = conf;
this.tname = name;
this.node = node;
this.telement = element;
if (name.equalsIgnoreCase("<schema>" )) //special treatment
{
this.tpanel = new JPanel(new java.awt.GridLayout(7,1));
this.tpanel .add(new JLabel("XML Schema root element"));
this.tpanel .add(new JLabel("-----------------------"));
this.trealname = "schema root";
//disableRefresh();
}
else if (name.equalsIgnoreCase("-=sequence=-")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("Sequence of elements:"));
this.trealname = "sequence" ;
disableRefresh();
}
else if (name.equalsIgnoreCase("-=choice= -")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("Choice of elements:"));
this.trealname = "choice";
disableRefresh();
}
else if (name.equalsIgnoreCase("-=all=-")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("All elements:" ));
this.trealname = "all" ;
disableRefresh();
}
else if (name.equalsIgnoreCase("-=group=-")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("Group of elements:"));
this.trealname = "group";
disableRefresh();
}
else if (name.equalsIgnoreCase("<any>")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("Any elements):"));
this.trealname = "any" ;
disableRefresh();
}
process();
}
/**
* XMLSchemaParser-like constructor
*/
public SchemaElement(configurator conf,DefaultMutableTreeNode node,Element element,String idpath ) {
this.mother = conf;
this.id = idpath;
this.tname = null;
this.node = node;
this.telement = element;
}
/**
* Constructor for special elements (no precessing, just showing the right name)
*/
public SchemaElement(configurator conf,DefaultMutableTreeNode node,String name) {
this.mother = conf;
this.tname = name;
this.node = node;
this.telement = null;
if (name.equalsIgnoreCase("<schema>" )) //special treatment
{
this.tpanel = new JPanel(new java.awt.GridLayout(7,1));
this.tpanel .add(new JLabel("XML Schema root element" ));
this.tpanel .add(new JLabel("-----------------------"));
this.trealname = "schema root";
//disableRefresh();
}
else if (name.equalsIgnoreCase("-=sequence=-")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("Sequence of elements..." ));
this.trealname = "sequence" ;
disableRefresh();
}
else if (name.equalsIgnoreCase("-=choice= -")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("Choice of elements..."));
this.trealname = "choice";
disableRefresh();
}
else if (name.equalsIgnoreCase("-=all=-")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("All elements..."));
this.trealname = "all" ;
disableRefresh();
}
Autor: Thomas Schädler
174
Anhang A: Quelltext <xmlizer> configurator
else if (name.equalsIgnoreCase("-=group=-")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("Group of elements..."));
this.trealname = "group";
disableRefresh();
}
else if (name.equalsIgnoreCase("<any>")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("Wildcard Component (any)"));
this.trealname = "any" ;
disableRefresh();
}
}
//Initialization of the data
//----------------------------------------------------------------------------------------------private void process() {
if (this.tname != null && this.tname .equalsIgnoreCase("<schema>")) {
Attribute attr = null;
attr = this.telement.getAttribute("attributeFormDefault");
if (attr != null) {
SCHEMAattributeFormDefault = attr.getValue().trim();
}
this.tpanel .add(new JLabel("attributeFormDefault : " + SCHEMAattributeFormDefault));
attr = this.telement.getAttribute("elementFormDefault");
if (attr != null) {
SCHEMAelementFormDefault = attr.getValue().trim();
}
this.tpanel .add(new JLabel("elementFormDefault : " + SCHEMAelementFormDefault ));
attr = this.telement.getAttribute("targetNamespace");
if (attr != null) {
SCHEMAtargetNameSpace = attr.getValue().trim();
}
this.tpanel .add(new JLabel("targetNamespace : " + SCHEMAtargetNameSpace));
attr = this.telement.getAttribute("version");
if (attr != null) {
SCHEMAversion = attr.getValue().trim();
}
this.tpanel.add(new JLabel("version : " + SCHEMAversion));
attr = this.telement.getAttribute("xml:lang");
if (attr != null) {
SCHEMAlanguage = attr.getValue().trim();
}
this.tpanel .add(new JLabel("xml:lang : " + SCHEMAlanguage ));
}
}
//FIXME - Process the types correctly or delete it
//or leave it here for next (type aware) version
public void processType(Element typeElement) {
this.theType = new SchemaType();
//theType.processType(typeElement);
}
public void processTypeRef(Element typeElement) {
this.theType = new SchemaType();
//theType.processTypeRef(typeElement);
}
public void processInternalType() {
this.theType = new SchemaType();
//theType.processInternalType(this.telement);
}
private StringBuffer addOccurrenceString (StringBuffer name) {
if (getOccurrence() == null) {
return name;
}
else {
name.append (this.occurrence .getShortOcc());
return name;
}
}
public void addDocumentation(String doc) {
if(!doc.equalsIgnoreCase("")) {
this.documentation = doc;
}
}
public String getDocumentation () {
return this.documentation;
}
public void addAttribute (Element attr,Hashtable loadedAttribs) {
SchemaAttribute newattr = new SchemaAttribute(attr);
//System.out.print("IN ELEMENT " + this.trealname);
if (loadedAttribs.containsKey(this.id + newattr.getName())) //an element of this name loaded
{
//add a new attribute, but fill it with the loaded info
SchemaAttribute loaded = (SchemaAttribute)loadedAttribs.get(this.id + newattr.getName());
newattr.setMapID (loaded.getMapID ());
newattr.setMapInfo(loaded.getMapInfo());
this.attributes.add(newattr);
//System.out.println("ADDED ATTR: " + newattr.getName() + " >> " + newattr.getMapID() + " >> " + n ewattr.getMapInfo());
//System.out.print(" ADDED WITH LOAD:" + newattr.getName() + " \n");
}
else //add a new (clean) attribute
Autor: Thomas Schädler
175
Anhang A: Quelltext <xmlizer> configurator
{
this.attributes.add(newattr);
//System.out.print(" ADDED CLEAR: "
+ newattr.getName() + "\n");
}
}
public boolean hasContent() {
if (this.content != null) {
return true;
}
else return false;
}
public SchemaContent getContent() {
return this.content;
}
public void setContent(SchemaContent cont) {
if (cont != null) {
this.content = cont;
//System.out.println(cont);
}
}
public Vector getAttributes() {
return this.attributes;
}
public boolean hasType() {
if (this.type != null) {
return true;
}
else {
return false;
}
}
public boolean hasTypeRef() {
if (this.typeRef != null) {
return true;
}
else {
return false;
}
}
public void setInternalType() {
this.hasInternalType = true;
}
public boolean hasInternalType () {
return this.hasInternalType;
}
/**
* Add a name to the parent-vector: holds names of parent SchemaElements
*/
public void addParent(SchemaElement parent) {
this.parents.add(parent);
}
public Vector getParents() {
return this.parents;
}
//SQL STATEMENTS
//----------------------------------------------------------------------------------------------//for the (linked) repetition
public void setRepetition(String sqlid) {
this.repetitionStatement = sqlid;
}
public String getRepetition() {
return this.repetitionStatement ;
}
public SQLStatement getRepetitionStatement() {
if (this.repetitionStatement != null) {
return mother.getProjectData().DB2XMLgetmapping ().getSQLStatementByMapID (this.repetitionStatement);
}
else return null;
}
//for the statments of the element
public void addSQLStatement(SQLStatement stat ) {
if (stat != null) {
this.SQLStatements.add(stat);
this.updateList();
}
}
public Vector getSQLStatements () {
return this.SQLStatements;
}
public void removeSQLStatement (SQLStatement st) {
if (st != null) {
for (Enumeration e = this.SQLStatements.elements(); e.hasMoreElements();) {
SQLStatement temp = (SQLStatement )e.nextElement();
if (temp.equals(st)) {
//remove the statement
String id = st.getID();
this.SQLStatements.remove(temp);
//clean the repetitions for this id
if (this.getRepetitionStatement() != null) {
Autor: Thomas Schädler
176
Anhang A: Quelltext <xmlizer> configurator
if (this.getRepetitionStatement().equals (st)) {
this.repetitionStatement = null;
}
}
//clean the content for this id
if (this.hasContent ()) {
this.getContent ().cleanMapping ();
}
//clean the attributes for this id
cleanAttributeByID(id);
mother.getLog().addDebug ("Removed SQL Statement: " + temp.toString());
break;
}
}
}
}
/**
* Clears all mappings of all attributes, but only the data, not the rep.
* which are dependent on the specified SQLStatement
*/
public void cleanMapData(SQLStatement stat) {
String id = stat.getID();
//clean the content
if (this.hasContent()) {
this.getContent().cleanMapping();
}
//clean the attributes
for (Enumeration ee = this.attributes.elements (); ee.hasMoreElements();) {
SchemaAttribute attr = (SchemaAttribute)ee.nextElement();
if (attr.getMapID() != null) {
if (attr.getMapID().equalsIgnoreCase(id)) {
attr.cleanMapping();
}
}
}
}
/**
* Clears the mapping of the specified attribute (via ID) of this element
*/
public void cleanAttributeByID (String id ) {
for (Enumeration ee = this.attributes.elements(); ee.hasMoreElements();) {
SchemaAttribute attr = (SchemaAttribute)ee.nextElement();
if (attr.getMapID() != null) {
if (attr.getMapID().equalsIgnoreCase(id)) {
attr.cleanMapping();
}
}
}
}
//STRING REPRESENTATION
//----------------------------------------------------------------------------------------------/**
* By default show the key as String
*/
public String toString() {
return this.tname;
}
//GET AND SET METHODS
//----------------------------------------------------------------------------------------------public void setElement(Element element) {
this.telement = element;
process();
}
public Element getElement() {
return this.telement ;
}
public void setRealName(String n) {
this.trealname = n;
}
public String getRealName() {
return this.trealname;
}
public void setID(String n) {
this.id = n;
}
public String getID () {
return this.id;
}
public void setName(String name) {
StringBuffer buff = new StringBuffer (name);
buff = addOccurrenceString (buff);
this.tname = buff.toString ();
}
public String getName() {
return this.tname;
}
public void setType(String type) {
if (!type.equalsIgnoreCase ("")); {
this.type = type;
}
Autor: Thomas Schädler
177
Anhang A: Quelltext <xmlizer> configurator
}
public void setTypeRef(String typeref) {
if (!typeref.equalsIgnoreCase("")) {
this.typeRef = typeref ;
}
}
public String getType() {
return this.type;
}
public String getTypeRef () {
return this.typeRef;
}
public SchemaOccurrence getOccurrence() {
return this.occurrence;
}
public void setOccurrence(SchemaOccurrence occ) {
this.occurrence = occ;
}
//GRAPHIC REPRESENTATION
//----------------------------------------------------------------------------------------------private boolean refresh = true;
private void enableRefresh() {
this.refresh = true;
}
private void disableRefresh() {
this.refresh = false ;
}
public boolean isRefresh () {
return this.refresh;
}
private void updateList() {
//the database-lister window updater
SQLChooser sqlch = (SQLChooser)mother.open("SQLChooser");
//make it's combobox not enabled->only the current element is shown
sqlch.updateView(this);
}
private JLabel getDragTargetForRepetition(String rep_short_name) {
return new JLabel("Repetition: " + rep_short_name);
}
/**
* Returns the Element Info Panel
* Can also be called Refresh or something because it does exactly that, not only creating the panel
*/
public JPanel getElementPanel() {
//the database-lister window updater
if(this.refresh && this.trealname.equalsIgnoreCase("schema root")) {
this.tpanel = new SchemaRootPanel(this.mother,this);
}
else if (this.refresh) {
this.tpanel = new SchemaElementPanel(this.mother,this);
}
SQLChooser sqlch = (SQLChooser)mother.open("SQLChooser");
sqlch.updateView(this);
return this.tpanel;
}
private void dataButtonActionPerformed(java.awt.event.ActionEvent evt) {
dbBrowser browser = (dbBrowser)this.mothe r.open("databaseBrowser");
browser.enableTakeover(this);
}
}/*
* listItem.java
*
* Created on 22. Mai 2002, 12:44
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 hav e received a copy of the GNU General Public License
* along with <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
/**
* Represents the metadata of a table
*
* @author [email protected]
* @version 0.3
*/
class listItem {
private String name ;
Autor: Thomas Schädler
178
Anhang A: Quelltext <xmlizer> configurator
private int rowcount;
private boolean selected = false;
public listItem(String name,int rowcount ) {
this.name = name;
this.rowcount = rowcount;
}
public listItem(String name,int rowcount ,boolean marked ) {
this.name = name;
this.rowcount = rowcount;
this.selected = marked;
}
public String toString() {
return this.name + " (" + this.rowcount + ")";
}
public String getName() {
return this.name;
}
public int getRowCount() {
return this.rowcount ;
}
public boolean isSelected() {
return this.selected ;
}
public void toggleSelection() {
if (this.selected) {
this.selected = false;
}
else {
this.selected = true;
}
//System.out.println("ListItem " + name + " is now " + selected);
}
}/*
* activityMeter.java
*
* Created on 21. Mai 2002, 21:54
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import javax.swing .JButton;
import javax.swing .JProgressBar;
/**
* All neccessary information for showing the current background activity
* as well as STOP -Button
* @author [email protected]
* @version 0.3
*/
public class activityMeter {
private int running = 0;
private String meter = new String();
private JButton thebutton;
private JProgressBar theprogressbar ;
/**
* Constructor:
* @param JButton
* @param JProgressBar
*/
public activityMeter(JButton b , JProgressBar p) {
this.thebutton = b;
this.theprogressbar = p;
}
synchronized public void start (boolean stoppable) {
running++;
if (stoppable) {
thebutton.setEnabled(true);
theprogressbar.setValue(0);
}
ensure();
}
synchronized public void stop(boolean stoppable) {
if (running >= 1)
//no negative numbers at all
{
if (stoppable) {
thebutton.setEnabled(false);
meter = new String ();
theprogressbar.setValue (0);
}
Autor: Thomas Schädler
179
Anhang A: Quelltext <xmlizer> configurator
running--;
}
ensure();
}
synchronized public void setMax(int max) {
theprogressbar.setMaximum(max);
}
synchronized public void setValue(int value) {
theprogressbar.setValue(value);
}
synchronized public void setString(String string) {
meter = string;
ensure();
}
synchronized public void init() {
running = 0;
meter = new String();
theprogressbar.setValue(0);
ensure();
}
private void ensure () {
if (running > 0) {
theprogressbar.setStringPai nted(true);
if (meter.equalsIgnoreCase(new String ())) {
theprogressbar.setString("[" + new Integer(running).toString() + "]");
}
else {
theprogressbar.setString(meter + " : [" + new Integer(running).toString() + "] ");
}
}
else if (running <= 0) {
theprogressbar.setStringPainted(false );
}
}
}
/*
* logWindow.java
*
* Created on 24. Mai 2002, 16:19
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import java.io.*;
import java.awt.*;
import java.lang.*;
import java.util.*;
import javax.swing .*;
import java.awt.event.*;
import javax.swing .text.*;
/**
* The logwindow is the interface to output files, information and debug-info
* in one centralized window
* @author [email protected]
* @version 0.3
*/
public class logWindow extends MyInternalFrame {
private configurator mother;
private String ID;
private boolean isDebugEnabled = false;
private java.awt.Component selectedTab = null;
private StyleContext styles;
private Style errorStyle ;
private Style warnStyle;
private Style infoStyle;
private Style debugStyle ;
private Style defaultStyle;
private Style errorStyleIcon;
private Style warnStyleIcon;
private Style infoStyleIcon;
private Style debugStyleIcon;
private DefaultStyledDocument logDoc;
private DefaultStyledDocument debugDoc;
private JPopupMenu popup = new JPopupMenu();
private JMenuItem saveThis;
private JMenuItem placeWindow;
private JMenuItem clearThis;
private JMenuItem clearAll;
private JMenuItem removeThis;
private JMenuItem removeAll;
private JCheckBoxMenuItem debug;
private boolean isUpdating = false;
Autor: Thomas Schädler
180
Anhang A: Quelltext <xmlizer> configurator
/** Creates new form logWindow
* @param mainProgram The configurator
* @param uid The unique ID for this window
*/
public logWindow(configurator mainProgram,String uid) {
this.mother = mainProgram;
this.ID = uid;
initStyles ();
initLog();
initDebug();
initComponents();
initLogComp();
initPopupMenu();
show();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
private void initComponents()//GEN-BEGIN:initComponents
{
backPanel = new javax.swing.JPanel();
theTabbedPane = new javax.swing .JTabbedPane();
setMaximizable(true);
setTitle("Log Window");
setIconifiable(true);
setResizable(true);
setClosable(true);
try
{
setIcon(true);
} catch (java.beans.PropertyVetoException e)
{
e.printStackTrace();
}
setFrameIcon(new javax.swing.ImageIcon(getClass().getResource ("/configurator/icons/History16.gif" )));
setDefaultCloseOperation(javax.swing .WindowConstants.HIDE_ON_CLOSE );
backPanel.setLayout(new java.awt.BorderLayout());
theTabbedPane.setTabPlacement(javax.swing .JTabbedPane.BOTTOM);
theTabbedPane.setPreferredSize(new java.awt.Dimension(600, 200));
theTabbedPane.addKeyListener(new java.awt.event.KeyAdapter()
{
public void keyReleased(java.awt.event.KeyEvent evt)
{
theTabbedPaneKeyReleased(evt);
}
});
theTabbedPane.addMouseListener(new java.awt.event.MouseAdapter()
{
public void mouseClicked(java.awt.event.MouseEvent evt)
{
theTabbedPaneMouseClicked(evt);
}
});
backPanel.add(theTabbedPane, java.awt.BorderLayout.CENTER);
getContentPane().add(backPanel, java.awt.BorderLayout.CENTER);
pack();
}//GEN-END:initComponents
private void theTabbedPaneKeyReleased(java.awt.event.KeyEvent evt )//GEN-FIRST:event_theTabbedPaneKeyReleased
{//GEN-HEADEREND:event_theTabbedPaneKeyReleased
// Add your handling code here:
logWindow log = (logWindow)mother.open("log");
log.setVisible(true);
}//GEN-LAST:event_theTabbedPaneKeyReleased
private void theTabbedPaneMouseClicked(java.awt.event.MouseEvent evt)//GEN-FIRST:event_theTabbedPaneMouseClicked
{//GEN-HEADEREND:event_theTabbedPaneMouseClicked
// Add your handling code here:
if(SwingUtilities.isRightMouseButton (evt)) {
checkPopup();
popup.show(evt.getComponent (),evt.getX(),evt.getY());
}
}//GEN-LAST:event_theTabbedPaneMouseClicked
private JTextPane getSelectedTextPane() {
JScrollPane selected = (JScrollPane)theTabbedPane.getSelectedComponent();
if (selected == debugScrollPane ) {
return debugTextPane;
}
else if (selected == logScrollPane) {
return logTextPane;
}
else {
JTextPane custom = null;
int position = 0;
for (Enumeration e = filetabs.elements(); e.hasMoreElements();) {
JScrollPane item = (JScrollPane)e.nextElement();
if (item == selected) {
position = filetabs .lastIndexOf(item);
break;
}
}
return (JTextPane)tabtexts.get(position);
}
Autor: Thomas Schädler
181
Anhang A: Quelltext <xmlizer> configurator
}
// Variables declaration - do not modify//GEN -BEGIN:variables
private javax.swing .JPanel backPanel;
private javax.swing .JTabbedPane theTabbedPane ;
// End of variables declaration//GEN-END:variables
private
private
private
private
private
private
Vector filetabs = new Vector(); //holds all file tabs (JScrollPanes)
Vector tabtexts = new Vector(); //holds all text components in the JScrollPanes
JScrollPane debugScrollPane = null;
JTextPane debugTextPane = null;
JScrollPane logScrollPane = null;
JTextPane logTextPane = null;
private void clearLog() {
if (logTextPane != null) {
try {
logDoc.remove(0,logDoc.getLength());
}
catch(Exception ex) {
addDebug(ex);
}
}
}
private void clearDebug() {
if (debugTextPane != null) {
try {
debugDoc.remove(0,debugDoc.getLength());
}
catch(Exception ex) {
addDebug(ex);
}
}
}
private void saveThis_actionPerformed(java.awt.event.ActionEvent evt) {
// Add your handling code here:
JTextPane selected = getSelectedTextPane();
Document doc = selected.getDocument();
try {
final String message = doc.getText(0,doc.getLength());
if (!message.equals(new String())) {
String location = new String ();
//open filechooser
JFileChooser chooser = new JFileChooser();
chooser.setDialogType(javax.swing .JFileChooser.SAVE_DIALOG );
simpleFileFilter filter = new simpleFileFilter();
filter.addExtension("xml");
filter.addExtension("txt");
filter.addExtension("log");
filter.setDescription("xml;txt;log");
chooser.setFileFilter(filter );
int returnVal = chooser.showSaveDialog (this);
if(returnVal == JFileChooser .APPROVE_OPTION ) {
location = chooser.getSelectedFile ().getPath();
}
else {
//aborted
mother.getLog().addInformation("Custom Output save aborted!");
return;
}
final String thelocation = location;
if (!thelocation.equals (new String())) {
Runnable r = new Runnable() {
public void run() {
//save the stuff there
try {
//file stuff
File outputFile = new File(thelocation);
FileOutputStream outputStream = new FileOutputStream (outputFile);
OutputStreamWriter out = new OutputStreamWriter (outputStream,"UTF8");
out.write(message);
out.close();
}
catch (IOException ex ) {
mother.getLog().addError(ex);
return;
}
}
};
Thread saver = new Thread(r);
saver.start();
}
}
else {
mother.getLog().addInformation("Nothing to save. Preview XML Output is empty!" );
}
}
catch(Exception ex) {
mother .getLog().addError(ex);
}
}
private void clearAll_actionPerformed(java.awt.event.ActionEvent evt) {
clearLog();
clearDebug ();
for (Enumeration e = tabtexts.elements(); e.hasMoreElements();) {
Document doc = ((JTextPane)e.nextElement()).getDocument();
Autor: Thomas Schädler
182
Anhang A: Quelltext <xmlizer> configurator
try {
doc.remove(0,doc.getLength());
}
catch(Exception ex) {
mother.getLog().addError(ex);
}
}
}
private void clearThis_actionPerformed(java.awt.event.ActionEvent evt) {
JTextPane selected = getSelectedTextPane();
if (selected == debugTextPane) {
clearDebug();
}
else if (selected == logTextPane) {
clearLog();
}
else {
Document doc = selected.getDocument();
try {
doc.remove(0,doc.getLength());
}
catch(Exception ex) {
mother.getLog().addError(ex);
}
}
//saveButton.setEnabled(false);
mother.getLog().addInformation("Output cleared .");
}
private void removeThis_actionPerformed(java.awt.event.ActionEvent evt ) {
JScrollPane selected = (JScrollPane)theTabbedPane.getSelectedComponent();
if ((selected != debugScrollPane) && (selected != logScrollPane)) {
int sel = filetabs.indexOf(selected);
filetabs.remove(sel);
tabtexts.remove(sel);
theTabbedPane.remove(selected);
}
}
private void removeAll_actionPerformed(java.awt.event.ActionEvent evt) {
for (Enumeration e = filetabs.elements(); e.hasMoreElements();) {
theTabbedPane.remove((JScrollPane)e.nextElement ());
}
filetabs.removeAllElements ();
tabtexts.removeAllElements ();
}
private void placeWindow_actionPerformed (java.awt.event .ActionEvent evt) {
mother.setLogWindow2StandartLocation ();
}
private void debug_actionPerformed(java.awt.event.ActionEvent evt ) {
if(!isDebugEnabled) //create new tab and enable
{
//create new components
debugScrollPane = new JScrollPane();
debugTextPane = new JTextPane(debugDoc);
debugTextPane.setEditable(false);
//add the textpane to the scrollpane --> scroll
debugScrollPane.setViewportView(debugTextPane);
//add the new tab to theTabbedPane
theTabbedPane.addTab("Debug", new javax.swing.ImageIcon(getClass ().getResource("/configurator/icons/actions/startDebugger.gif")),debugScrollPane,"Debug log" );
theTabbedPane.setSelectedComponent(debugScrollPane);
debugTextPane.addMouseListener(new java.awt.event.MouseAdapter () {
public void mouseClicked(java.awt.event.MouseEvent evt) {
theTabbedPaneMouseClicked(evt);
}
});
ensureIsOnTop(debugScrollPane);
//toggle
isDebugEnabled = true;
}
else {
//toggle
isDebugEnabled = false ;
//remove the tab
theTabbedPane.remove(debugScrollPane);
//to be sure
debugScrollPane = null;
debugTextPane = null;
}
}
private void initPopupMenu() {
saveThis = new JMenuItem("Save" );
placeWindow = new JMenuItem("Smart Layout");
clearThis = new JMenuItem("Clear");
clearAll = new JMenuItem("Clear all" );
removeThis = new JMenuItem ("Close");
removeAll = new JMenuItem("Close all");
debug = new JCheckBoxMenuItem("Debug");
debug.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (ActionEvent e) {
debug_actionPerformed(e);
Autor: Thomas Schädler
183
Anhang A: Quelltext <xmlizer> configurator
}
});
saveThis.addActionListener (new java.awt.event.ActionListener() {
public void actionPerformed (ActionEvent e) {
saveThis_actionPerformed(e);
}
});
placeWindow.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (ActionEvent e) {
placeWindow_actionPerformed(e);
}
});
clearThis.addActionListener(new java.awt.event.ActionListener () {
public void actionPerformed (ActionEvent e) {
clearThis_actionPerformed(e);
}
});
clearAll.addActionListener (new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
clearAll_actionPerformed(e);
}
});
removeThis .addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (ActionEvent e) {
removeThis_a ctionPerformed(e);
}
});
removeAll.addActionListener(new java.awt.event .ActionListener () {
public void actionPerformed (ActionEvent e) {
removeAll_actionPerformed(e);
}
});
popup.add(saveThis);
popup.addSeparator();
popup.add(clearThis);
popup.add(clearAll);
popup.addSeparator();
popup.add(removeThis );
popup.add(removeAll);
popup.addSeparator();
popup.add(debug );
popup.addSeparator();
popup.add(placeWindow);
}
/**
* Checks the popupmenu for enabled/disabled items before popping up
*/
private void checkPopup() {
if (isUpdating) {
removeAll.setEnabled(false);
removeThis.setEnabled(false );
clearThis.setEnabled(false);
clearAll.setEnabled(false);
}
else {
//saveThis & clearThis
if (getSelectedTextPane().getDocument ().getLength() > 0) {
clearThis.setEnabled(true);
saveThis.setEnabled(true);
}
else {
clearThis.setEnabled(false);
saveThis.setEnabled(false);
}
//removeThis & removeAll
if(tabtexts .size() > 0) {
removeThis.setEnabled(true);
removeAll.setEnabled(true);
}
else {
removeThis.setEnabled(false);
removeAll.setEnabled(false);
}
//clearAll and debug is always on
}
}
private void initLogComp () {
//create new components
logScrollPane = new JScrollPane ();
logTextPane = new JTextPane(logDoc);
logTextPane.setEditable(false);
//add the textpane to the scrollpane --> scroll
logScrollPane.setViewportView(logTextPane );
//add the new tab to theTabbedPane
theTabbedPane.addTab ("Log" , new javax.swing.ImageIcon(getClass ().getResource("/configurator/icons/History16.gif")),logScrollPane ,"Event log");
theTabbedPane.setSelectedComponent(logScrollPane);
logTextPane.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
theTabbedPaneMouseClicked(evt);
}
});
}
private void initDebug() {
debugDoc = new DefaultStyledDocument (styles);
debugDoc.setLogicalStyle(0,debugStyle);
}
Autor: Thomas Schädler
184
Anhang A: Quelltext <xmlizer> configurator
private void initLog() {
logDoc = new DefaultStyledDocument(styles );
logDoc.setLogicalStyle(0,errorStyle);
}
private void initStyles() {
styles = new StyleContext();
defaultStyle = styles.addStyle("defaultStyle", null);
StyleConstants.setForeground(defaultStyle , Color.black);
StyleConstants.setFontFamily(defaultStyle , "Dialog" );
errorStyle = styles.addStyle("errorStyle" , null);
StyleConstants.setForeground(errorStyle, Color .red);
StyleConstants.setFontFamily(errorStyle, "Dialog");
errorStyleIcon = styles.addStyle("errorStyleIcon", null);
StyleConstants.setIcon(errorStyleIcon,new javax.swing.ImageIcon(getClass ().getResource("/configurator/icons/list/red.gif")));
warnStyle = styles.addStyle("warnStyle", null);
StyleConstants.setForeground(warnStyle, Color.blue);
StyleConstants.setFontFamily(warnStyle, "Dialog");
warnStyleIcon = styles.addStyle ("warnStyleIcon", null);
StyleConstants.setIcon(warnStyleIcon ,new javax.swing.ImageIcon(getClass ().getResource("/configurator/icons/list/blue.gif")));
infoStyle = styles.addStyle("infoStyle", null);
StyleConstants.setForeground(infoStyle, Color.black );
StyleConstants.setFontFamily(infoStyle, "Dialog");
infoStyleIcon = styles.addStyle ("infoStyleIcon", null);
StyleConstants.setIcon(infoStyleIcon ,new javax.swing.ImageIcon(getClass ().getResource("/configurator/icons/list/green.gif" )));
debugStyle = styles.addStyle("debugStyle" , null);
StyleConstants.setForeground(debugStyle, Color .black);
StyleConstants.setFontFamily(debugStyle, "Dialog");
debugStyleIcon = styles.addStyle("debugStyleIcon", null);
StyleConstants.setIcon(debugStyleIcon,new javax.swing.ImageIcon(getClass ().getResource("/configurator/icons/list/gray.gif")));
}
/**
* Adds an error message to the log (log tab)
* @param text The error message to display
*/
public void addError(String text) {
if (!(text == null) || !text.equals(new String ())) {
this.addMessage(logDoc ,errorStyle,errorStyleIcon,"[E] ",text);
}
ensureIsOnTop(logScrollPane);
}
/**
* Adds an exception as error message to the log (log tab)
* @param ex The Exception
*/
public void addError(Exception ex) {
this.addMessage (logDoc,errorStyle,errorStyleIcon,"[E] ",ex.getLocalizedMessage());
ensureIsOnTop(logScrollPane);
}
/**
* Adds a warning message to the log (log tab)
* @param text The warning message to display
*/
public void addWarning(String text) {
if (!(text == null) || !text.equals(new String ())) {
this.addMessage(logDoc ,warnStyle ,warnStyleIcon,"[W] ",text);
}
}
/**
* Adds an information message to the log (log tab)
* @param text The information message to display
*/
public void addInformation(String text) {
if (!(text == null) || !text.equals(new String ())) {
this.addMessage(logDoc ,infoStyle ,infoStyleIcon,"[I] ",text);
}
}
/**
* Adds a debug message to the debuglog (debug tab)
* @param text The debug message to display
*/
public void addDebug(String text) {
if (!(text == null) || !text.equals(new String ())) {
if (isDebugEnabled) {
this.addMessage(debugDoc,debugStyle,debugStyleIcon,"[D] ",text);
}
}
}
/**
* Adds an exception as debug message to the debuglog (debug tab)
* @param extends Exception to show
*/
public void addDebug(Exception ex) {
if (isDebugEnabled) {
this.addMessage(debugDoc,debugStyle,debugStyleIcon,"[D] " ,ex.getLocalizedMessage());
}
}
Autor: Thomas Schädler
185
Anhang A: Quelltext <xmlizer> configurator
/**
* Adds a debug message to the debuglog (debug tab) and includes the caller -method
* @param caller The debug messages caller method
* @param text The debug message to display
*/
public void addDebug(String caller,String text) {
if (!(text == null) || !text.equals(new String ())) {
if (isDebugEnabled) {
this.addMessage(debugDoc,debugStyle,debugStyleIcon,"[D] ",text+"\n -------> From: "+caller);
}
}
}
/**
* Adds a file to a newly created Tab (always a seperate tab)
* @param tabname The name of the new Tab
* @param file The file to read in
* @param tooltip The tooltip to display while hovering over this tab
*/
public void addNewTab(String thetabname,File file,String thetooltip) {
if (file != null) {
//make new Components
final JScrollPane newScrollPane = new JScrollPane();
final JTextPane newTextPane = new JTextPane();
final Document doc = new DefaultStyledDocument();
FileInputStream instr = null;
try {
instr = new FileInputStream(file);
}
catch(FileNotFoundException ex) {
mother.getLog().addError(ex);
}
BufferedReader reader = new BufferedReader (new InputStreamReader(instr));
StringWriter writer = new StringWriter();
PrintWriter out = new PrintWriter(writer);
String line ;
try {
while ((line = reader.readLine()) != null) {
out.println(line);
}
}
catch(IOException ioe) {
mother.getLog().addError(ioe);
}
out.flush();
newTextPane .setDocument(doc);
newTextPane .setEditable(false);
if (thetabname == null || thetabname.equals(new String())) {
thetabname = "output";
}
if (thetooltip == null) {
thetooltip = "";
}
final String tabname = thetabname;
final String text = writer.toString();
final String tooltip = thetooltip;
Runnable r = new Runnable() {
public void run() {
//set text
if (text != null && (!text.equals(new String ()))) {
try {
doc.insertString (0,text,defaultStyle );
}
catch(BadLocationException ble ) {
mother .getLog().addError(ble);
}
}
newTextPane.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
theTabbedPaneMouseClicked(evt);
}
});
//add the textpane to the scrollpane --> scroll
newScrollPane.setViewportView (newTextPane);
//add the new tab to theTabbedPane
theTabbedPane.addTab(tabname,new javax.swing.ImageIcon(getClass ().getResource("/configurator/icons/openide/xmlObject.gif")),newScrollPane,tooltip);
ensureIsOnTop(newScrollPane);
//add the to the list and synch their positions
filetabs .add(newScrollPane);
int position = filetabs.lastIndexOf(newScrollPane );
tabtexts .add(position,newTextPane);
}
};
Thread runner = new Thread(r);
runner .start();
}
}
/**
* Adds a custom string (message) to a newly created Tab (always a seperate tab)
* @param tabname The name of the new Tab
* @param text The text to display in new tab
* @param tooltip The tooltip to display while hovering over this tab
*/
public void addNewTab(String thetabname,String thetext,String thetooltip) {
//make new Components
final JScrollPane newScrollPane = new JScrollPane();
Autor: Thomas Schädler
186
Anhang A: Quelltext <xmlizer> configurator
final JTextPane newTextPane = new JTextPane();
final Document doc = new DefaultStyledDocument ();
newTextPane.setDocument(doc);
newTextPane.setEditable(false);
if (thetabname == null || thetabname .equals(new String())) {
thetabname = "output";
}
if (thetooltip == null) {
thetooltip = "";
}
final String tabname = thetabname;
final String text = thetext;
final String tooltip = thetooltip;
Runnable r = new Runnable() {
public void run() {
//set text
if (text != null && (!text.equals (new String()))) {
try {
doc.insertString(0,text,defaultStyle);
}
catch(BadLocationException ble) {
mother.getLog().addError(ble);
}
}
newTextPane.addMouseListener (new java.awt.event.MouseAdapter() {
public void mouseClicked (java.awt.event .MouseEvent evt ) {
theTabbedPaneMouseClicked (evt);
}
});
//add the textpane to the scrollpane --> scroll
newScrollPane.setViewportView(newTextPane);
//add the new tab to theTabbedPane
theTabbedPane.addTab(tabname,new javax.swing.ImageIcon(getClass ().getResource("/configurator/icons/openide/xmlObject.gif")),newScrollPane,tooltip);
ensureIsOnTop(newScrollPane);
//add the to the list and synch their positions
filetabs.add(newScrollPane);
int position = filetabs .lastIndexOf(newScrollPane);
tabtexts.add(position,newTextPane );
}
};
Thread runner = new Thread (r);
runner.start();
}
public void isUpdating(boolean bool) {
//System.out.println(bool);
this.isUpdating = bool;
}
/**
* Creates a new Tab (always a seperate tab) and returns a PipedOutputStream to fill it
* @return PipedOutputStream
* @param tabname The name of the new Tab
* @param tooltip The tooltip to display while hovering over this tab
*/
public PipedOutputStream addNewTab(String tabname,String tooltip) {
//make new Components
JScrollPane newScrollPane = new JScrollPane();
JTextPane newTextPane = new JTextPane();
final EditorKit editor = new StyledEditorKit();
final Document doc = editor.createDefaultDocument();
final PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream();
newTextPane.setEditorKit(editor );
newTextPane.setDocument(doc);
newTextPane.setEditable(false);
try {
out.connect(in);
Runnable reader = new Runnable() {
public void run() {
mother.getLog().isUpdating(true);
try {
editor.read(in,doc,0);
in.close();
//mother.getLog().isUpdating(false);
}
catch(Exception ex) {
mother.getLog().addError(ex);
//mother.getLog().isUpdating(false);
return;
}
}
};
Thread readerthread = new Thread (reader);
readerthread.setDaemon (true);
readerthread.start();
}
catch (IOException e ) {
mother .getLog().addError(e);
}
//set tabname
if (tabname == null || tabname.equals(new String())) {
tabname = new String("output");
}
//set tooltip
Autor: Thomas Schädler
187
Anhang A: Quelltext <xmlizer> configurator
if (tooltip == null) {
tooltip = new String();
}
newTextPane.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
theTabbedPaneMouseClicked(evt);
}
});
//add the textpane to the scrollpane --> scroll
newScrollPane.setViewportView(newTextPane );
//add the new tab to theTabbedPane
theTabbedPane.addTab (tabname,new javax.swing.ImageIcon(getClass ().getResource("/configurator/icons/openide/xm lObject.gif")),newScrollPane,tooltip);
ensureIsOnTop(newScrollPane);
//add the to the list and synch their positions
filetabs.add(newScrollPane );
int position = filetabs.lastIndexOf(newScrollPane);
tabtexts.add(position,newTextPane);
return out;
}
private String getDate() {
return java.text.DateFormat.getDateInstance().format(new java.util.Date());
}
private String getTime() {
return java.text.DateFormat.getTimeInstance().format(new java.util.Date());
}
private synchronized void addMessage(DefaultStyledDocument doc,Style style,Style iconStyle ,String iconreplacer,String
message) {
String datetime = getDate() + " : " + getTime() + " >> " ;
try {
doc.insertString (doc.getLength(),iconreplacer,iconStyle);
doc.insertString (doc.getLength(),datetime,style );
doc.insertString (doc.getLength(),message,style);
doc.insertString (doc.getLength(),"\n",style);
theTabbedPane.repaint();
}
catch(BadLocationException ex) {
mother .getLog().addError(ex);
}
if (doc == logDoc) {
logTextPane .setCaretPosition(logDoc.getLength());
}
if (doc == debugDoc) {
debugTextPane.setCaretPosition(debugDoc.getLength());
}
}
synchronized private void ensureIsOnTop(JScrollPane pane) {
if(!this.isVisible())
{ this.setVisible(true); }
if (this.isIcon ()) {
mother .getMainDesktopPane().getDesktopManager().deiconifyFrame (this);
}
//mother.getMainDesktopPane().getDesktopManager().activateFrame(this);
theTabbedPane.repaint();
}
/**
* This m ethod updates the UI if the setupwindow is closed
* (and a change in the setup component occured)
* Not used in this context!
* @param conf The configurator
*/
public void update(configurator conf) {
this.mother = conf;
}
}
/*
* DB2XMLmain.java
*
* Created on 9. April 2002, 20:43
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 wit h <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import
import
import
import
import
import
import
java.io.*;
java.awt.*;
java.util.*;
java.lang.*;
javax.swing .*;
javax.swing .tree.*;
org.jdom.*;
Autor: Thomas Schädler
188
Anhang A: Quelltext <xmlizer> configurator
import org.jdom.output.XMLOutputter;
/**
* The main class/internalframe of the module DB2XML
* @author [email protected]
*/
public class DB2XMLmain extends MyInternalFrame {
private static configurator mother;
private String ID;
private projectData theData;
private Vector fileList = new Vector();
private Vector dbList = new Vector();
static int WARNING = 0;
static int ERROR=1;
static int FATAL_ERROR=2;
private boolean isLoading = true;
private static JTree theTree = null;
private String xmlFile = new String ();
private XMLSchemaParser schemaparser = null;
//To use the pool just add a Runnable to the pool [pool.execute(someRunnable)]
private ThreadPool pool = new ThreadPool (3);
/** Creates new form projectdataWindow */
public DB2XMLmain(configurator mainProgram, String uid) {
this.mother = mainProgram;
this.ID = uid;
this.theData = mainProgram .getProjectData ();
this.fileList = this.theData.getXML(); //update the DBList
initComponents();
if (fileList.size()>0) {
//setFile(((xmlItem)((Vector)this.theData.getXML()).get(0)).getFile());
fileComboBox.setSelectedItem(fileList .get(0));
}
isLoading = false;
doFileSelect();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
private void initComponents() {//GEN-BEGIN:initComponents
toolPanel = new javax.swing.JPanel();
fileLabel = new javax.swing.JLabel();
fileComboBox = new javax.swing.JComboBox(fileList);
buildButton = new javax.swing.JButton();
clearButton = new javax.swing.JButton();
jButton1 = new javax .swing .JButton();
theSplitPane = new javax.swing.JSplitPane ();
rightPanel = new javax.swing.JPanel();
leftPanel = new javax.swing.JPanel();
mainPanel = new javax.swing.JPanel();
theTabbedPane = new javax.swing .JTabbedPane();
treePanel = new javax.swing.JPanel();
treeScrollPane = new javax .swing.JScrollPane();
textPanel = new javax.swing.JPanel();
sourceScrollPane = new javax.swing.JScrollPane ();
sourceTextArea = new javax .swing.JTextArea();
setMaximizable(true);
setTitle("Database to XML Module");
setIconifiable(true);
setResizable(true);
toolPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));
toolPanel.setPreferredSize (new java.awt.Dimension(300, 37));
fileLabel.setText("File:");
toolPanel.add(fileLabel);
fileComboBox.setPreferredSize(new java.awt.Dimension(240, 27));
fileComboBox.setMinimumSize(new java.awt.Dimension(126, 27));
fileComboBox.setMaximumSize(new java.awt.Dimension(32767 , 27));
fileComboBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
fileComboBoxActionPerformed(evt);
}
});
toolPanel.add(fileComboBox );
buildButton.setText("Build");
buildButton.setEnabled(false);
buildButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event .ActionEvent evt) {
buildButtonActionPerformed(evt);
}
});
toolPanel.add(buildButton);
clearButton.setToolTipText ("Clears the whole mapping-information");
clearButton.setText("Clear");
clearButton.setEnabled(false);
clearButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
clearButtonActionPerformed(evt);
}
});
toolPanel.add(clearButton);
jButton1.setIcon(new javax .swing.ImageIcon(getClass ().getResource("/configurator/icons/Help16.gif")));
jButton1.setToolTipText("Open Help");
jButton1.setFont(new java.awt.Font("Dialog", 0, 10));
Autor: Thomas Schädler
189
Anhang A: Quelltext <xmlizer> configurator
jButton1.addActionListener (new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
jButton1ActionPerformed (evt);
}
});
toolPanel.add(jButton1);
getContentPane().add(toolPanel, java.awt.BorderLayout.NORTH);
theSplitPane.setDividerLocation (300);
theSplitPane.setPreferredSize(new java.awt.Dimension(500, 302));
theSplitPane.setOneTouchExpandable(true);
rightPanel .setLayout (new java.awt.BorderLayout ());
theSplitPane.setRightComponent(rightPanel );
leftPanel.setLayout(new java.awt.BorderLayout());
mainPanel.setLayout(new java.awt.BorderLayout());
theTabbedPane.setPreferredSize(new java.awt.Dimension(200, 300));
treePanel.setLayout(new java.awt.BorderLayout());
treeScrollPane.setPreferredSize (new java.awt.Dimension(400, 250));
treePanel.add(treeScrollPane, java.awt.BorderLayout .CENTER);
theTabbedPane.addTab ("DOM Tree" , treePanel);
textPanel.setLayout(new java.awt.BorderLayout());
sourceTextArea.setTa bSize(4);
sourceScrollPane.setViewportView(sourceTextArea);
textPanel.add(sourceScrollPane, java.awt.BorderLayout.CENTER);
theTabbedPane.addTab ("Text View", textPanel);
mainPanel.add(theTabbedPane, java.awt.BorderLayout.CENTER);
leftPanel.add(mainPanel, java.awt.BorderLayout .CENTER);
theSplitPane.setLeftComponent(leftPanel);
getContentPane().add(theSplitPane, java.awt.BorderLayout .CENTER);
pack();
}//GEN-END:initComponents
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN -FIRST:event_jButton1ActionPerformed
// Add your handling code here:
helpWindow help = (helpWindow)mother .open("help");
help.loadPage("/configurator/help/module_db2xml_main.html");
}//GEN-LAST:event_jButton1ActionPerformed
private void clearButtonActionPerformed(java.awt.event.ActionEvent evt )//GEN-FIRST:event_clearButtonActionPerformed
{//GEN-HEADEREND:event_clearButtonActionPerformed
// Add your handling code here:
//ask for discard (ok) or cancel (cancel)
int result = JOptionPane.showConfirmDialog(
mother.getContentPane(),
"This operation removes ALL mapping\ninformation and SQL queries. Are you sure?",
"<xmlizer> clear mapping",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE
);
if (result == JOptionPane.OK_OPTION)
//discard
{
mother .getProjectData().DB2XMLclearmapping ();
doFileSelect();
mother .getLog().addInformation("All mapping information and SQL queries removed.");
}
else
//set status and return
{
mother .getLog().addWarning("Clear aborted: Current mapping is is not altered.");
return ;
}
}//GEN-LAST:event_clearButtonActionPerformed
private void buildButtonActionPerformed(java.awt.event.ActionEvent evt )//GEN-FIRST:event_buildButtonActionPerformed
{//GEN-HEADEREND:event_buildButtonActionPerformed
// Add your handling code here:
if (this.schemaparser != null) {
//start a new project and a setup window
Runnable r = new Runnable() {
public void run() {
schemaparser.buildInstance();
Document doc = schemaparser.getInstance ();
if (doc != null) {
//mother.debugOutput(doc);
PipedOutputStream outstr = mother.getLog ().addNewTab("DB2XML Output","Preview output for current
DB2XML Mapping");
XMLOutputter fmt = new XMLOutputter ("
",true);
try {
fmt.output(doc,outstr );
mother .getLog().isUpdating (false);
}
catch(IOException ioex) {
mother .getLog().isUpdating (false);
mother .getLog().addError(ioex);
}
}
else {
mother.getLog().addWarning("Instance Generation failed.");
Autor: Thomas Schädler
190
Anhang A: Quelltext <xmlizer> configurator
}
}
};
try
{ pool.execute(r); }catch(InterruptedException ie)
{ mother.getLog().addError(ie);}
}
}//GEN-LAST:event_buildButtonActionPerformed
private void fileComboBoxActionPerformed (java.awt.event .ActionEvent evt)//GEN-FIRST:event_fileComboBoxActionPerformed
{//GEN-HEADEREND:event_fileComboBoxActionPerformed
// Add your handling code here:
doFileSelect();
}//GEN-LAST:event_fileComboBoxActionPerformed
private void selectedTextFieldKeyReleased(java.awt.event.KeyEvent evt)//GEN -FIRST:event_selectedTextFieldKeyReleased
{//GEN-HEADEREND:event_selectedTextFieldKeyReleased
// Add your handling code here:
if(evt.getKeyCode() == 10) //press enter
{
doItemUpdate();
}
}//GEN-LAST:event_selectedTextFieldKeyReleased
/**
* Is called if a new file is selected
*/
private void doFileSelect() {
if (!isLoading) {
final xmlItem item = (xmlItem)fileComboBox .getSelectedItem();
if (item != null) {
//start a new project and a setup window
Runnable r = new Runnable() {
public void run() {
dataItem it = mother .getProjectData ().getInitialByKey("name" );
String pro_name = it.getValue();
setFile(mother.getProjectBase() + mother .getFileSeparator() + pro_name + mother.getFileSeparator () +
item.getFile()); //updates the selected file
}
};
try
{ pool.execute(r); }catch(InterruptedException ie)
{ mother.getLog().addError(ie);}
}
}
}
/**
* Do an Item-change Update
*/
public void doItemUpdate () {
MutableTreeNode node = (MutableTreeNode)theTree.getLastSelectedPathComponent ();
if (node == null) return;
}
/**
* Set a file and diplay (call update automatically)
* @param String indicat ing the full path to the file
*/
private void setFile(String fullfilenameandpath) {
this.xmlFile = fullfilenameandpath;
Runnable r = new Runnable() {
public void run() {
updateCurrentSelection();
}
};
try
{ pool.execute(r); }catch(InterruptedException ie)
{ mother.getLog ().addError (ie);}
}
/**
* Do the update on the tree
*/
private void updateCurrentSelection () {
//update the tree
if (theTree != null) {
treeScrollPane.remove(theTree);
theTree = null;
}
boolean wasSuccessfull = initTree();
if (wasSuccessfull) {
treeScrollPane.setViewportView(theTree);
toolPanel.repaint();
treeScrollPane.repaint ();
fileComboBox.repaint();
//update the text
initText();
}
}
public synchronized void update(configurator conf) {
isLoading = true;
this.mother = conf;
this.theData = conf.getProjectData();
this.fileList = conf.getProjectData().getXML(); //update the dbList
this.dbList = conf.getProjectData().getDB (); //update the fileList
this.fileComboBox.setModel (new DefaultComboBoxModel (this.fileList));
if (this.fileList.size()>0) {
this.fileComboBox.setSelectedIndex(0);
}
this.repaint();
isLoading = false;
Autor: Thomas Schädler
191
Anhang A: Quelltext <xmlizer> configurator
}
private void expandTree() {
int rows = 0;
for (int levels =0; levels <= 4; levels++) {
rows=theTree.getRowCount();
for (int i = 0; i < rows; i++) {
theTree.expandRow(i);
}
}
}
private void initText() {
//file stuff
StringBuffer the_source = new StringBuffer();
File inputFile = new File(xmlFile);
FileInputStream inputStream = null;
InputStreamReader in = null;
try {
inputStream = new FileInputStream(xmlFile);
in = new InputStreamReader(inputStream,"UTF8");
if (in != null) {
int c;
while ((c = in.read()) != -1) {
the_source.append((char)c);
}
in.close();
sourceTextArea.setText(the_source .toString());
}
}
catch(Exception ex) {
mother .getLog().addError(ex.getMessage());
}
}
private boolean initTree () {
Document thedoc = mother.getFileAsXMLDOM(xmlFile,false);
if (thedoc != null) {
this.schemaparser = new XMLSchemaParser(mother);
boolean parsing_is_ok = schemaparser.parse (thedoc);
if (parsing_is_ok) {
//get the tree (visual)
theTree = schemaparser.getTree();
theTree.addTreeSelectionListener(new javax.swing .event.TreeSelectionListener() {
public void valueChanged (javax.swing.event.TreeSelectionEvent evt) {
//respond to tree-node selection and show the according interface (for db-entries)
optionsTreeValueChanged(evt);
}
});
theTree.putClientProperty("JTree.lineStyle" , "Angled" );
expandTree();
buildButton.setEnabled(true);
clearButton.setEnabled(true);
return true;
}
else { clearButton.setEnabled(true); buildButton.setEnabled(false); return false; }
}
else
{ clearButton.setEnabled(true); buildButton.setEnabled(false); return false; }
}
// Variables declaration - do not modify//GEN -BEGIN:variables
private javax.swing .JPanel toolPanel;
private javax.swing .JLabel fileLabel;
private javax.swing .JComboBox fileComboBox;
private javax.swing .JButton buildButton;
private javax.swing .JButton clearButton;
private javax.swing .JButton jButton1;
private javax.swing .JSplitPane theSplitPane;
private javax.swing .JPanel rightPanel;
private javax.swing .JPanel leftPanel;
private javax.swing .JPanel mainPanel;
private javax.swing .JTabbedPane theTabbedPane ;
private javax.swing .JPanel treePanel;
private javax.swing .JScrollPane treeScrollPane;
private javax.swing .JPanel textPanel;
private javax.swing .JScrollPane sourceScrollPane;
private javax.swing .JTextArea sourceTextArea;
// End of variables declaration//GEN-END:variables
/**
* Customizes a selection of a tree node
*/
private void optionsTreeValueChanged(javax.swing.event.TreeSelectionEvent evt) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)theTree.getLastSelectedPathComponent();
if (node == null) return;
//GET THE SchemaElement
SchemaElement schemel = (SchemaElement)node.getUserObject();
if (schemel != null) {
JPanel thisPanel = schemel.getElementPanel ();
if (thisPanel != null) {
rightPanel.removeAll();
this.repaint();
rightPanel.add(thisPanel,java.awt.BorderLayout.CENTER );
this.validate();
}
}
}
}/*
* pathData.java
*
* This projectData contain er contains all neccessary methods to deal
* with the projectData management
Autor: Thomas Schädler
192
Anhang A: Quelltext <xmlizer> configurator
*
* Created on 5. April 2002, 16:30
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import
import
import
import
import
import
import
java.io.*;
java.util.*;
java.lang.*;
javax.swing .*;
org.jdom.*;
org.jdom.input.SAXBuilder;
org.jdom.output.XMLOutputter;
/**
* Represents the pathdata (absolutley neccessary for running xmlizer)
* [email protected]
* @version 0.5
*/
public class pathData {
public static String XMLFILEROOT = "xmlizerconfig" ;
private String homedir = null;
private String projectdir = null;
//CONSTRUCTOR
//----------------------------------------------------------------------------------------------/**
* Creates new projectData (Constructor)
*/
public pathData() {
//init here if neccessary
}
//GET AND SET
//----------------------------------------------------------------------------------------------public String getHomeDir () {
return homedir;
}
public void setHomeDir(String dir) {
this.homedir = dir;
}
public String getPr ojectDir() {
return projectdir;
}
public void setProjectDir(String dir) {
this.projectdir = dir;
}
//STRING REPRESENTATION
//----------------------------------------------------------------------------------------------public String toString() {
StringBuffer result = new StringBuffer("FULL PATHDATA >>");
result.append("\nHOME-DIR
>> " + this.homedir);
result.append("\nPROJECT-DIR >> " + this.projectdir );
return result.toString();
}
//XML REPRESENTATION
//----------------------------------------------------------------------------------------------public boolean isValid() {
if ((this.homedir != null) && (this.projectdir != null)) {
return true;
}
else return false;
}
/**
* Checks the doctype of the XML-File (just to be sure to read the right information)
*/
private boolean checkDocType(DocType dt,String rootelement) {
if (dt.getElementName().equalsIgnoreCase(rootelement)) {
return true;
}
else {
return false;
}
}
/*
* Reads an XML file (which must be of type xmlizer.project.config.dtd) and
* fills all information in the projectdata
*
* @param The filename as String
* @param The logWindow (to indicate errors etc...)
*/
synchronized public boolean readFromFile (String filename) {
Autor: Thomas Schädler
193
Anhang A: Quelltext <xmlizer> configurator
boolean docOK = false;
try {
SAXBuilder builder = new SAXBuilder(false);
Document jdoc = builder.build(filename);
//true -> validating against dtd
DocType docType = jdoc.getDocType();
docOK = checkDocType(docType,XMLFILEROOT);
if (docOK) {
//get the root
Element root = jdoc.getRootElement();
java.util.List itemlist = root.getChildren("path");
Iterator item_iter = itemlist.iterator ();
while (item_iter.hasNext()) {
Element path_item = (Element) item_iter .next();
if (path_item.getAttributeValue("description").equalsIgnoreCase("home")) {
this.homedir = path_item.getTextTrim();
//System.out.println("HOME: " + path_item.getTextTrim());
}
else if (path_item.getAttributeValue("description").equalsIgnoreCase("project")) {
this.projectdir = path_item.getTextTrim();
//System.out.println("PROJECT: " + path_item.getTextTrim());
}
}
return true;
}
else {
//System.out.println("DOC NOT OK");
return false ;
}
}
catch (JDOMException e) {
//System.out.println("JDOM Exception: " + e.getMessage());
return false;
}
}
/**
* Return the data as String
*/
public String getAsXMLText() {
Document jdoc = this.getAsXMLDocumentJDOM ();
org.jdom.output .DOMOutputter outp = new org.jdom.output.DOMOutputter();
XMLOutputter fmt = new XMLOutputter("
return fmt.outputString(jdoc);
",true);
}
/**
* Return the data as XML Document (org.w3c.dom.Document)
*/
public org.w3c.dom.Document getAsXMLDocumentW3C() {
Document jdoc = this.getAsXMLDocumentJDOM ();
org.jdom.output .DOMOutputter outp = new org.jdom.output.DOMOutputter();
try {
org.w3c.dom.Document result = outp.output(jdoc);
return result; //and return the result
}
catch (JDOMException e) {
System .out.println("DOM Serializer error for debug output!");
return null;
}
}
/**
* Return the data as XML Document org.jdom.Document
*/
public Document getAsXMLDocumentJDOM() {
//MAKE DOCTYPE
DocType docType = new DocType(XMLFILEROOT ,null);
Element root = new Element (XMLFILEROOT);
Element init_item1 = new Element("path").setText(this.homedir);
init_item1 .setAttribute("description","home");
root.addContent (init_item1 );
Element init_item2 = new Element("path").setText(this.projectdir);
init_item2 .setAttribute("description","project");
root.addContent (init_item2 );
Document doc = new Document(root,docType);
return doc; //and return the doc
}
/**
* save the config in the user home directory as xmlizer.config
*/
public void save(String path,boolean ui) {
org.jdom.Document xmldata = getAsXMLDocumentJDOM();
org.jdom.output.XMLOutputter fmt = new org.jdom.output.XMLOutputter("
",true);
try {
//file stuff
java.io.File outputFile = new java.io.File(path);
java.io.FileOutputStream outputStream = new java.io.FileOutputStream(outputFile);
java.io.OutputStreamWriter out = new java.io.OutputStreamWriter(outputStream,"UTF8");
fmt.output(xmldata,out);
out.close();
}
catch (java.io.IOException ex) {
if (ui) {
javax.swing.JOptionPane .showMessageDialog(
null,
Autor: Thomas Schädler
194
Anhang A: Quelltext <xmlizer> configurator
"I/O Error, could not save the\ndata correctly!"
+ "\n ERROR: \n------\n" + ex.toString(),
configurator .APPNAME + " save error",
javax.swing.JOptionPane .ERROR_MESSAGE
);
}
else {
System.out.println ("SAVE ERROR: " + ex.toString());
}
}
}
}
/*
* dtd2xsdOptions.java
*
* Created on 7. Juni 2002, 01:31
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import java.awt.*;
import java.util.*;
import javax.swing .*;
/**
* An options dialog for the dtd2xs - package
* @author [email protected]
*/
public class dtd2xsdOptions extends javax.swing.JDialog {
private Hashtable options = new Hashtable();
/** Creates new form dtd2xsdOptions */
public dtd2xsdOptions(java.awt.Frame parent, boolean modal) {
super(parent, modal);
initComponents();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension mySize = getSize ();
if(mySize.height > screenSize.height ) {
mySize .height = screenSize.height;
}
if(mySize.width > screenSize.width) {
mySize .width = screenSize.width;
}
setLocation((screenSize.width - mySize.width) / 2, (screenSize.height - mySize.height) / 2);
show();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
private void initComponents()//GEN-BEGIN:initComponents
{
thePanel = new javax .swing .JPanel();
mapDTDentitiesLabel = new javax .swing.JLabel();
mapDTDentitiesCheckBox = new javax.swing.JCheckBox();
mapDTDcommentsLabel = new javax .swing.JLabel();
mapDTDcommentsCheckBox = new javax.swing.JCheckBox();
maxCommLenghtLabel = new javax.swing .JLabel();
commLangLabel = new javax.swing .JLabel();
commLangComboBox = new javax.swing.JComboBox();
annotationLabel = new javax.swing.JLabel();
annotationList = new javax .swing.JList();
conceptHighllightLabel = new javax.swing.JLabel();
conceptHighlightComboBox = new javax .swing.JComboBox();
minOccLabel = new javax.swing.JLabel ();
minOccComboBox = new javax .swing.JComboBox();
maxCommLengthComboBox = new javax.swing.JComboBox();
buttonPanel = new javax.swing.JPanel ();
okButton = new javax .swing .JButton();
cancelButton = new javax.swing.JButton();
setTitle("DTD 2 XSD Options");
setDefaultCloseOperation(javax.swing .WindowConstants.DISPOSE_ON_CLOSE);
setModal(true);
addWindowListener(new java.awt.event .WindowAdapter()
{
public void windowClosing(java.awt.event.WindowEvent evt)
{
closeDialog(evt);
}
});
thePanel.setLayout(new java.awt.GridBagLayout());
java.awt.GridBagConstraints gridBagConstraints 1;
Autor: Thomas Schädler
195
Anhang A: Quelltext <xmlizer> configurator
thePanel.setBorder(new javax.swing.border .TitledBorder("DTD to XML Schema Transform options:"));
mapDTDentitiesLabel.setText("Map DTD entities" );
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 0;
gridBagConstraints1.gridy = 0;
gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints1.insets = new java.awt.Insets(0, 5, 0, 2);
thePanel.add(mapDTDentitiesLabel, gridBagConstraints1);
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 1;
gridBagConstraints1.gridy = 0;
gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints1.insets = new java.awt.Insets(0, 2, 0, 5);
gridBagConstraints1.anchor = java.awt.GridBagConstraints .WEST;
thePanel.add(mapDTDentitiesCheckBox, gridBagConstraints1 );
mapDTDcommentsLabel.setText("Map DTD comments" );
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 0;
gridBagConstraints1.gridy = 1;
gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints1.insets = new java.awt.Insets(0, 5, 0, 2);
thePanel.add(mapDTDcommentsLabel, gridBagConstraints1);
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 1;
gridBagConstraints1.gridy = 1;
gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints1.insets = new java.awt.Insets(0, 2, 0, 5);
gridBagConstraints1.anchor = java.awt.GridBagConstraints .WEST;
thePanel.add(mapDTDcommentsCheckBox, gridBagConstraints1 );
maxCommLenghtLabel.setText ("Max. length comment");
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 0;
gridBagConstraints1.gridy = 2;
gridBagConstrai nts1.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints1.insets = new java.awt.Insets(0, 5, 0, 2);
thePanel.add(maxCommLenghtLabel , gridBagConstraints1);
commLangLabel.setText("Comment language");
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 0;
gridBagConstraints1.gridy = 3;
gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints1.insets = new java.awt.Insets(0, 5, 0, 2);
thePanel.add(commLangLabel , gridBagConstraints1);
commLangComboBox.setModel(new javax.swing .DefaultComboBoxModel(new String[]
{ "undefined", "English", "German", "French" }));
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 1;
gridBagConstraints1.gridy = 3;
gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints1.insets = new java.awt.Insets(0, 2, 0, 5);
gridBagConstraints1.anchor = java.awt.GridBagConstraints .WEST;
thePanel.add(commLangComboBox, gridBagConstraints1);
annotationLabel .setText("Annotation of");
gridBagConstraints1 = new java.awt.GridBagConstrain ts();
gridBagConstraints1.gridx = 0;
gridBagConstraints1.gridy = 6;
gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints1.insets = new java.awt.Insets(0, 5, 0, 2);
thePanel.add(annotationLabel, gridBagConstraints1);
annotationList.setToolTipText("Select all that apply");
annotationList.setModel(new javax.swing.AbstractListModel()
{
String [] strings =
{ "element" , "attribute", "group", "attributeGroup", "simpleType", "enumeration" };
public int getSize()
{ return strings.length; }
public Object getElementAt(int i)
{ return strings[i]; }
});
annotationList.setVisibleRowCount(3);
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 1;
gridBagConstraints1.gridy = 6;
gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints1.insets = new java.awt.Insets(0, 2, 0, 5);
gridBagConstraints1.anchor = java.awt.GridBagConstraints .WEST;
thePanel.add(annotationList, gridBagConstraints1);
conceptHighllightLabel.setText("Concept highlight");
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 0;
gridBagConstraints1.gridy = 7;
gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints1.insets = new java.awt.Insets(0, 5, 0, 2);
thePanel.add(conceptHighllightLabel, gridBagConstraints1 );
conceptHighlightComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String []
{ "no", "by space", "embraced" }));
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 1;
gridBagConstraints1.gridy = 7;
gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints1.insets = new java.awt.Insets(0, 2, 0, 5);
gridBagConstraints1.anchor = java.awt.GridBagConstraints .WEST;
thePanel.add(conceptHighlightComboBox, gridBagConstraints1);
minOccLabel.setText("Min. concept occurence");
Autor: Thomas Schädler
196
Anhang A: Quelltext <xmlizer> configurator
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 0;
gridBagConstraints1.gridy = 8;
gridBagConstraints1.insets = new java.awt.Insets(0, 5, 0, 2);
thePanel.add(minOccLabel, gridBagConstraints1);
minOccComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String []
{ "1", "2", "3", "4", "5" }));
gridBagConstraints1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 1;
gridBagConstraints1.gridy = 8;
gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints1.insets = new java.awt.Insets(0, 2, 0, 5);
gridBagConstraints1.anchor = java.awt.GridBagConstraints .WEST;
thePanel.add(minOccComboBox, gridBagConstraints1);
maxCommLengthComboBox.setModel(new javax.swing .DefaultComboBoxModel(new String[]
{ "1", "10", "25", "50", "100", "500", "1000", "10000", "50000" }));
maxCommLengthComboBox.setSelectedItem("1000");
gridBagConstrai nts1 = new java.awt.GridBagConstraints();
gridBagConstraints1.gridx = 1;
gridBagConstraints1.gridy = 2;
gridBagConstraints1.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints1.insets = new java.awt.Insets(0, 2, 0, 5);
gridBagConstraints1.anchor = java.awt.GridBagConstraints .WEST;
thePanel.add(maxCommLengthComboBox, gridBagConstraints1);
getContentPane().add(thePanel, java.awt.BorderLayout.CENTER);
okButton.setText("OK");
okButton.setPreferredSize(new java.awt.Dimension(73, 27));
okButton.setMaximumSize(new java.awt.Dimension (73, 27));
okButton.setMinimumSize(new java.awt.Dimension (73, 27));
okButton.addActionListener (new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
okButtonActionPerformed (evt);
}
});
buttonPanel.add(okButton);
cancelButton.setText("Cancel");
cancelButton.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
cancelButtonActionPerformed(evt);
}
});
buttonPanel.add(cancelButton);
getContentPane().add(buttonPanel, java.awt.BorderLayout.SOUTH );
pack();
}//GEN-END:initComponents
private void cancelButtonActionPerformed (java.awt.event .ActionEvent evt)//GEN-FIRST:event_cancelButtonActionPerformed
{//GEN-HEADEREND:event_cancelButtonActionPerformed
// Add your handling code here:
doExit();
}//GEN-LAST:event_cancelButtonActionPerformed
private void okButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_okButtonActionPerformed
{//GEN-HEADEREND:event_okButtonActionPerformed
// Add your handling code here:
doExit();
}//GEN-LAST:event_okButtonActionPerformed
/** Closes the dialog */
private void closeDialog (java.awt.event.WindowEvent evt ) {//GEN-FIRST:event_closeDialog
doExit();
}//GEN-LAST:event_closeDialog
// Variables declaration - do not modify//GEN -BEGIN:variables
private javax.swing .JPanel thePanel ;
private javax.swing .JLabel mapDTDentitiesLabel;
private javax.swing .JCheckBox mapDTDentitiesCheckBox;
private javax.swing .JLabel mapDTDcommentsLabel;
private javax.swing .JCheckBox mapDTDcommentsCheckBox;
private javax.swing .JLabel maxCommLenghtLabel ;
private javax.swing .JLabel commLangLabel ;
private javax.swing .JComboBox commLangComboBox;
private javax.swing .JLabel annotationLabel;
private javax.swing .JList annotationList ;
private javax.swing .JLabel conceptHighllightLabel;
private javax.swing .JComboBox conceptHighlightComboBox;
private javax.swing .JLabel minOccLabel;
private javax.swing .JComboBox minOccComboBox;
private javax.swing .JComboBox maxCommLengthComboBox;
private javax.swing .JPanel buttonPanel;
private javax.swing .JButton okButton;
private javax.swing .JButton cancelButton ;
// End of variables declaration//GEN-END:variables
public void doExit() {
options = new Hashtable();
//mapDTDentitiesCheckBox
if (mapDTDentitiesCheckBox .isSelected()) {
options.put("entities" ,new Boolean(true));
}
Autor: Thomas Schädler
197
Anhang A: Quelltext <xmlizer> configurator
else {
options.put("entities" ,new Boolean(false));
}
//mapDTDcommentsCheckBox
if (mapDTDcommentsCheckBox .isSelected()) {
options.put("comments" ,new Boolean(true));
}
else {
options.put("comments" ,new Boolean(false));
}
//maxCommLengthComboBox
options.put("commentLength",(String)maxCommLengthComboBox.getSelectedItem());
//commLangComboBox
options.put("commentLanguage",(String)commLangComboBox.getSelectedItem());
StringBuffer allRelations = new StringBuffer();
Object sel [] = annotationList.getSelectedValues();
if (sel.length > 0) {
boolean first = true;
for(int i=0;i<sel.length;i++) {
if (!first) {
allRelations.append (" ");
}
allRelations .append(sel[i]);
first = false;
}
}
options.put("conceptRelations",allRelations.toString());
//conceptHighlightComboBox
String this_val_str = new String("2");
String this_val = (String)conceptHighlightComboBox.getSelectedItem ();
if (this_val.equalsIgnoreCase("no")) {
this_val_str = "2";
}
else if (this_val.equalsIgnoreCase("by space")) {
this_val_str = "12";
}
else if (this_val.equalsIgnoreCase("embraced")) {
this_val_str = "200";
}
options.put("conceptHighlight",this_val_str);
//minOccComboBox
options.put("minOccur",(String)minOccComboBox.getSelectedItem ());
setVisible (false);
dispose();
}
public Hashtable getOptions() {
return this.options;
}
}
/*
* dtd2xsdReport.java
*
* Created on 7. Juni 2002, 11:19
* ---------- -----------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import java.awt.*;
import java.util.*;
import javax.swing .*;
/**
* Shows the output of a conversion dtd2xs
* @author [email protected]
*/
public class dtd2xsdReport extends javax.swing.JDialog {
/** Creates new form dtd2xsdReport */
public dtd2xsdReport(java.awt.Frame parent, boolean modal, String report, String schema) {
super(parent, modal);
initComponents();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension mySize = getSize ();
if(mySize.height > screenSize.height ) {
mySize .height = screenSize.height;
}
if(mySize.width > screenSize.width) {
mySize .width = screenSize.width;
}
setLocation((screenSize.width - mySize.width) / 2, (screenSize.height - mySize.height) / 2);
Autor: Thomas Schädler
198
Anhang A: Quelltext <xmlizer> configurator
reportTextField.setText(report);
if (schema == null) {
theTabbedPane.remove(outputPanel );
this.repaint();
}
else {
outputTextField.setText(schema);
this.repaint();
}
pack();
show();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
private void initComponents()//GEN-BEGIN:initComponents
{
buttonPanel = new javax.swing.JPanel ();
okButton = new javax .swing .JButton();
cancelButton = new javax.swing.JButton();
mainPanel = new javax.swing.JPanel();
theTabbedPane = new javax.swing .JTabbedPane();
reportPanel = new javax.swing.JPanel ();
reportScrollPane = new javax.swing.JScrollPane ();
reportTextField = new javax.swing.JTextField();
outputPanel = new javax.swing.JPanel ();
outputScrollPane = new javax.swing.JScrollPane ();
outputTextField = new javax.swing.JTextField();
addWindowListener(new java.awt.event .WindowAdapter()
{
public void windowClosing(java.awt.event.WindowEvent evt)
{
closeDialog(evt);
}
});
okButton.setText("OK");
okButton.setPreferredSize(new java.awt.Dimension(73, 27));
okButton.setMaximumSize(new java.awt.Dimension (73, 27));
okButton.setMinimumSize(new java.awt.Dimension (73, 27));
okButton.addActionListener (new java.awt.event.ActionListener()
{
public void actionPerformed (java.awt.event .ActionEvent evt)
{
okButtonActionPerformed (evt);
}
});
buttonPanel.add(okButton);
cancelButton.setText("Cancel");
cancelButton.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event .ActionEvent evt)
{
cancelButtonActionPerformed(evt);
}
});
buttonPanel.add(cancelButton);
getContentPane().add(buttonPanel, java.awt.BorderLayout.SOUTH );
mainPanel.setLayout(new java.awt.BorderLayout());
theTabbedPane.setTabPlacement(javax.swing .JTabbedPane.BOTTOM);
theTabbedPane.setPreferredSize(new java.awt.Dimension(300, 350));
reportPanel.setLayout(new java.awt.BorderLayout());
reportScrollPane.setAutoscrolls (true);
reportTextField .setToolTipText("Conversion Report");
reportScrollPane.setViewportView(reportTextField);
reportPanel.add(reportScrollPane, java.awt.BorderLayout.CENTER);
theTabbedPane.addTab ("Report", reportPanel);
outputPanel.setLayout(new java.awt.BorderLayout());
outputScrollPane.setAutoscrolls (true);
outputTextField .setToolTipText("Conversion Report");
outputScrollPane.setViewportView(outputTextField);
outputPanel.add(outputScrollPane, java.awt.BorderLayout.CENTER);
theTabbedPane.addTab ("Generated XML Schema", outputPanel );
mainPanel.add(theTabbedPane, java.awt.BorderLayout.CENTER);
getContentPane().add(mainPanel, java.awt.BorderLayout.CENTER);
pack();
}//GEN-END:initComponents
private void cancelButtonActionPerformed (java.awt.event .ActionEvent evt)//GEN-FIRST:event_cancelButtonActionPerformed
{//GEN-HEADEREND:event_cancelButtonActionPerformed
// Add your handling code here:
doExit();
}//GEN-LAST:event_cancelButtonActionPerformed
Autor: Thomas Schädler
199
Anhang A: Quelltext <xmlizer> configurator
private void okButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_okButtonActionPerformed
{//GEN-HEADEREND:event_okButtonActionPerformed
// Add your handling code here:
doExit();
}//GEN-LAST:event_okButtonActionPerformed
/** Closes the dialog */
private void closeDialog (java.awt.event.WindowEvent evt ) {//GEN-FIRST:event_closeDialog
doExit();
}//GEN-LAST:event_closeDialog
// Variables declaration - do not modify//GEN -BEGIN:variables
private javax.swing.JPanel buttonPanel;
private javax.swing .JButton okButton;
private javax.swing .JButton cancelButton ;
private javax.swing .JPanel mainPanel;
private javax.swing .JTabbedPane theTabbedPane ;
private javax.swing .JPanel reportPanel;
private javax.swing .JScrollPane reportScrollPane;
private javax.swing .JTextField reportTextField;
private javax.swing .JPanel outputPanel;
private javax.swing .JScrollPane outputScrollPane;
private javax.swing .JTextField outputTextField;
// End of variables declaration//GEN-END:variables
private void doExit () {
setVisible (false);
dispose();
}
}
/*
* SchemaAttribute.java
*
* This class representates a Schema Attribute
*
* Created on 18. Mai 2002, 20:52
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import org.jdom.*;
import java.util.*;
import javax.swing .*;
/**
* Represents a SchemaAttribute and all related info
* @author [email protected]
*/
public class SchemaAttribute {
private String tname = null; //name=
private String ttype = null; //type=
private String ttyperef = null; //ref=
private String tuse = new String("optional"); //use=
private String mapid = null;
private String mapinfo = null;
private Element tattribute;
private String tannotation = null;
//CONSTRUCTORS
//--------------------------------------------------------------- -------------------------------public SchemaAttribute(Element attribute ) {
this.tattribute = attribute;
process();
}
public
if
if
if
}
SchemaAttribute(String name,String mapid,String mapinfo) {
(name != null) { this.tname = name; }
(mapid != null) { this.mapid = mapid; }
(mapinfo != null) { this.mapinfo = mapinfo; }
//Initialization of the data
//----------------------------------------------------------------------------------------------private void process() {
if (this.tattribute != null) {
Attribute attr = null;
//name
attr = this.tattribute .getAttribute("name" );
if (attr != null) {
this.tname = attr.getValue().trim();
}
//type
attr = this.tattribute .getAttribute("type" );
if (attr != null) {
this.ttype = attr.getValue().trim();
}
//ref
Autor: Thomas Schädler
200
Anhang A: Quelltext <xmlizer> configurator
attr = this.tattribute .getAttribute("ref");
if (attr != null) {
this.ttyperef = attr.getValue().trim();
}
//use
attr = this.tattribute .getAttribute("use");
if (attr != null) {
this.tuse = attr.getValue().trim();
}
}
}
/** Cleans the mapinfo of this attribute */
public void cleanMapping () {
this.mapid = null;
this.mapinfo = null;
//System.out.println(this.tname);
}
//SETTERS
public void setMapID(String id ) {
if (id != null) {
this.mapid = id;
}
}
public void setMapInfo(String info) {
if (info != null) {
this.mapinfo = info;
}
}
//GETTERS
public String getMapID() {
return this.mapid;
}
public String getMapInfo () {
return this.mapinfo;
}
public Element getAttribute() {
return this.tattribute;
}
public String getType() {
return this.ttype;
}
public String getTypeTef () {
return this.ttyperef ;
}
public String getUse() {
return this.tuse;
}
public String getName() {
return this.tname;
}
//STRING REPRESENTATION
//----------------------------------------------------------------------------------------------/**
* By default show the key as String
*/
public String toString() {
StringBuffer result = new StringBuffer();
//display the name
if (this.ttype == null && this.ttyperef != null)
//has a typeref
{
result .append(this.tname + " - " + this.ttyperef + " [" + this.tuse + "]");
}
else if (this.ttype != null && this.ttyperef == null)
//has a type
{
result .append(this.tname + " - " + this.ttype + " [" + this.tuse + "]");
}
else
//has nothing of both (should not happen -> invalid)
{
result .append(this.tname + " - !noType! [" + this.tuse + "]");
}
//display the mapid if there is one
if (this.mapid != null) {
result .append(" > " + this.mapid);
}
if (this.mapinfo != null) {
result .append(" : " + this.mapinfo);
}
return result.toString();
}
public Element getAsJDOMElement() {
if (this.tname == null)
//check for validity
{
return null;
}
else {
Element curr = new Element("db2xml_attribute");
curr.setAttribute("name",this.tname);
if (this.mapid != null) {
curr.setAttribute("mapid",this.mapid);
Autor: Thomas Schädler
201
Anhang A: Quelltext <xmlizer> configurator
}
if (this.mapinfo != null) {
curr.setAttribute("mapinfo",this.mapinfo);
}
return curr;
}
}
}/*
* SchemaSimpleConstraint.java
*
* Created on 4. April 2002, 15:48
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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 Founda tion; either version 2 of the License, or
* (at your option) any later version.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import java.util.List;
import java.util.LinkedList;
/**
* <p>
* The <code>SchemaSimpleConstraint</code> class represents a single data constraint,
*
including the data type, allowed values, and required ranges.
* </p>
* @author [email protected]
*/
public class SchemaSimpleConstraint {
/** The identifier for this constraint */
private String identifier;
/** The Java data type for this constraint */
private String dataType;
/** Minimum inclusive value allowed */
private double minInclusive;
/** Minimum exclusive value allowed */
private double minExclusive;
/** Maximum inclusive value allowed */
private double maxInclusive;
/** Maximum exclusive value allowed */
private double maxExclusive;
/** Allowed values */
private List allowedValues;
/**
* <p>
* This will create a new <code>SPConstraint</code> with the specified
*
identifier as the "name".
* </p>
*
* @param identifier <code>String</code> identifier for <code>SPConstraint</code>.
*/
public SchemaSimpleConstraint(String identifier) {
this.identifier = identifier;
// Null out values
minInclusive = Double.NaN;
minExclusive = Double.NaN;
maxInclusive = Double.NaN;
maxExclusive = Double.NaN;
// Allocate storage for allowed values
allowedValues = new LinkedList();
}
/**
* <p>
* This will return the identifier for this <code>SPConstraint</code>.
* </p>
*
* @return <code>String</code> - identifier for this constraint.
*/
public String getIdentifier() {
return identifier;
}
/**
* <p>
* This will allow the data type for the constraint to be set. The type is specified
*
as a Java <code>String</code>.
* </p>
*
* @param dataType <code>String</code> that is the Java data type for this constraint.
*/
public void setDataType(String dataType) {
Autor: Thomas Schädler
202
Anhang A: Quelltext <xmlizer> configurator
this.dataType = dataType;
}
/**
* <p>
* This will return the <code>String</code> version of the Java data type for this
*
constraint.
* </p>
*
* @return <code>String</code> - the data type for this constraint.
*/
public String getDataType() {
return dataType ;
}
/**
* <p>
* This will set the minimum allowed value for this data type (inclusive).
* </p>
*
* @param minInclusive minimum allowed value (inclusive)
*/
public void setMinInclusive(double minInclusive) {
this.minInclusive = minInclusive;
}
/**
* <p>
* This will return the minimum allowed value for this data type (inclusive).
* </p>
*
* @return <code>double</code> - minimum value allowed (inclusive)
*/
public double getMinInclusive() {
return minInclusive;
}
/**
* <p>
* This will return <code>true</code> if a minimum value (inclusive) constraint
*
exists.
* </p>
*
* @return <code>boolean</code> - whether there is a constraint for the
*
minimum value (inclusive)
*/
public boolean hasMinInclusive () {
return (!(new Double (minInclusive)).isNaN ());
}
/**
* <p>
* This will set the minimum allowed value for this data type (exclusive).
* </p>
*
* @param minInclusive minimum allowed value (exclusive)
*/
public void setMinExclusive(double minExclusive) {
this.minExclusive = minExclusive;
}
/**
* <p>
* This will return the minimum allowed value for this data type (exclusive).
* </p>
*
* @return <code>double</code> - minimum value allowed (exclusive)
*/
public double getMinExclusive() {
return minExclusive;
}
/**
* <p>
* This will return <code>true</code> if a minimum value (exclusive) constraint
*
exists.
* </p>
*
* @return <code>boolean</code> - whether there is a constraint for the
*
minimum value (exclusive)
*/
public boolean hasMinExclusive () {
return (!(new Double (minExclusive)).isNaN ());
}
/**
* <p>
* This will set the maximum allowed value for this data type (inclusive).
* </p>
*
* @param maxInclusive maximum allowed value (inclusive)
*/
public void setMaxInclusive(double maxInclusive) {
this.maxInclusive = maxInclusive;
}
/**
* <p>
* This will return the maximum allowed value for this data type (inclusive).
* </p>
*
* @return <code>double</code> - maximum value allowed (inclusive)
*/
public double getMaxInclusive() {
return maxInclusive;
Autor: Thomas Schädler
203
Anhang A: Quelltext <xmlizer> configurator
}
/**
* <p>
* This will return <code>true</code> if a maximum value (inclusive) constraint
*
exists.
* </p>
*
* @return <code>boolean</code> - whether there is a constraint for the
*
maximum value (inclusive)
*/
public boolean hasMaxInclusive () {
return (!(new Double (maxInclusive)).isNaN ());
}
/**
* <p>
* This will set the maximum allowed value for this data type (exclusive).
* </p>
*
* @param maxInclusive maximum allowed value (exclusive)
*/
public void setMaxExclusive(double maxExclusive) {
this.maxExclusive = maxExclusive;
}
/**
* <p>
* This will return the maximum allowed value for this data type (exclusive).
* </p>
*
* @return <code>double</code> - maximum value allowed (exclusive)
*/
public double getMaxExclusive() {
return maxExclusive;
}
/**
* <p>
* This will return <code>true</code> if a maximum value (exclusive) constraint
*
exists.
* </p>
*
* @return <code>boolean</code> - whether there is a constraint for the
*
maximum value (exclusive)
*/
public boolean hasMaxExclusive () {
return (!(new Double (maxExclusive)).isNaN ());
}
/**
* <p>
* This will add another value to the list of allowed values for this data type.
* </p>
*
* @param value <code>String</code> value to add.
*/
public void addAllowedValue(String value ) {
allowedValues.add(value);
}
/**
* <p>
* This will return the list of allowed values for this data type.
* </p>
*
* @return <code>List</code> - allowed values for this <code>SPConstraint</code>.
*/
public List getAllowedValues() {
return allowedValues ;
}
/**
* <p>
* This will indicate if there are a set of allowed values for this data type.
* </p>
*
* @return <code>boolean</code> - whether there are allowed values for this type.
*/
public boolean hasAllowedValues() {
return (allowedValues.size() > 0);
}
}/*
* SchemaOccurrence.java
*
* Created on 4. April 2002, 15:48
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 Publ ic License
* along with <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
Autor: Thomas Schädler
204
Anhang A: Quelltext <xmlizer> configurator
package configurator;
import java.lang.Integer;
/**
* Holds all neccessary info for XML Schema occurrences (repetition)
* @author [email protected]
*/
public class SchemaOccurrence {
/** The identifier for this constraint */
private String identifier;
/** Minimum inclusive value allowed */
private Integer minOccurs;
/** Maximum exclusive value allowed */
private Integer maxOccurs;
private boolean maxUnbounded = false;
/**
* <p>
* This will create a new <code>SPConstraint</code> with the specified
*
identifier as the "name".
* </p>
*
* @param identifier <code>String</code> identifier for <code>SPConstraint</code>.
*/
public SchemaOccurrence(String identifier) {
this.identifier = identifier;
//init values to default
this.minOccurs = new Integer(1);
this.maxOccurs = new Integer(1);
}
/**
* <p>
* This will return the identifier for this <code>SPConstraint</code>.
* </p>
*
* @return <code>String</code> - identifier for this constraint.
*/
public String getIdentifier() {
return identifier;
}
/**
* <p>
* This will set the minimum allowed value for this data type (inclusive).
* </p>
*
* @param minInclusive minimum allowed value (inclusive)
*/
public void setMinOccurs (String min ) {
if (min != null) {
Integer min_int = Integer.valueOf(min);
this.minOccurs = min_i nt;
}
}
/**
* <p>
* This will return the minimum allowed value for this data type (inclusive).
* </p>
*
* @return <code>double</code> - minimum value allowed (inclusive)
*/
public Integer getMinOccurs() {
return this.minOccurs;
}
/**
* <p>
* This will set the maximum allowed value for this data type (inclusive).
* In case of unbounded the value shall be Integer.MAX_VALUE
* </p>
*
* @param minInclusive minimum allowed value (inclusive)
*/
public void setMaxOccurs (String max ) {
if (max != null) {
if (max.equalsIgnoreCase("unbounded")) {
this.maxUnbounded = true;
this.maxOccurs = new Integer(Integer.MAX_VALUE);
}
else {
Integer max_int = Integer.getInteger(max);
this.maxOccurs = max_int;
}
}
}
/**
* Return true if this element can be repeated more than once
*/
public boolean hasRepeat () {
if ((getMinOccurs().intValue() == 1) && (getMaxOccurs().intValue() == 1)) {
return false;
}
else if (getMaxOccurs().intValue() > 1) {
return true;
}
else {
return false;
}
Autor: Thomas Schädler
205
Anhang A: Quelltext <xmlizer> configurator
}
/**
* <p>
* This will return the minimum allowed value for this data type (inclusive).
* </p>
*
* @return <code>double</code> - minimum value allowed (inclusive)
*/
public Integer getMaxOccurs() {
return maxOccurs;
}
/**
* Returns a short occurrence description as String
*/
public String getShortOcc() {
if ((getMinOccurs().intValue() == 1) && (getMaxOccurs().intValue() == 1)) {
return " [1]";
}
else {
StringBuffer buff = new StringBuffer(" [");
buff.append (getMinOccurs());
buff.append ("..");
if (this.maxUnbounded == true) {
//buff.append("\u221E"); //means "infinite symbol" in unicode
buff.append("max"); //unicode is font dependant! no good idea
}
else {
buff.append(getMaxOccurs());
}
buff.append ("]");
return buff.toString();
}
}
}/*
* DB2XMLmapping.java
*
* This class contains all neccessary information on the mapping of the module
* DB2XML (for building it and getting it for save)
*
* Created on 15. Juni 2002, 13:38
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public Licen se as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import java.util.*;
import org.jdom.*;
/**
*
* @author [email protected]
*/
public class DB2XMLmapping {
private String rootElement = null;
private Vector otherElements = new Vector(); //of SchemaElements
private Hashtable loadedElementNames = new Hashtable(); //of key=id,value=name(ambigous)
private Hashtable loadedAttributes = new Hashtable (); //of SchemaAttributes
private Hashtable loadedSQL = new Hashtable(); //of SQLStatements
private Hashtable loadedReps = new Hashtable(); //of Strings key=elementid,value=sqlid
private Hashtable loadedContent = new Hashtable(); //of SchemaContent
private Hashtable loadedParameters = new Hashtable (); //of ParameterInfo
/** Creates new DB2XMLmapping */
public DB2XMLmapping(){}
public DB2XMLmapping(String rootElementName) {
this.rootElement = rootElementName;
}
/*
* Set the root element
*/
public void setRootElement(String rootElementName) {
this.rootElement = rootElementName;
}
/**
* Adds a repetition info for the specified element to the list
* a Hashtable with key=elementname,value=sqlid/mapid
*/
public void addElementRepFromLoad(String elementid ,String sqlid) {
this.loadedReps .put(elementid,sqlid);
}
public Hashtable getLoadedReps () {
return this.loadedReps;
Autor: Thomas Schädler
206
Anhang A: Quelltext <xmlizer> configurator
}
/**
* Adds an element name to the list of known elements
*/
public void addElementFromLoad (String name,String id) {
if (id!= null && name != null) {
this.loadedElementNames.put(id,name);
}
}
/**
* Adds an Element to the list and returns true if new (not loaded from xmlizer.xml) else false
*/
public boolean addElement(SchemaElement el) {
if (el != null) {
if (this.loadedElementNames .containsKey(el.getID())) {
this.otherElements .add(el);
return false ;
}
else {
this.otherElements .add(el);
return true;
}
}
else return false;
}
public Vector getElements() {
return this.otherElements;
}
/*
* Set the root element
*/
public String getRootElement() {
return rootElement;
}
/**
* adds a SQLStatement to the list
*/
public void addSQLFromLoad(String id, SQLStatement statement ) {
if (this.loadedSQL.containsKey(id)) //add to Vector
{
Vector temp_vec = (Vector)this.loadedSQL.get(id);
temp_vec.add(statement );
//System.out.println("addSQLFromLoad NEW: " + statement.toString());
}
else //add new Vector with current SQLStatement as first one
{
Vector temp_vec = new Vector();
temp_vec.add(statement );
this.loadedSQL.put(id,temp_vec);
//System.out.println("addSQLFromLoad ADD: " + statement.toString());
}
}
/**
* Return a Hashtable full of happy SQLStatements
* key: elementname (to attach to) + attributename (combined key)
* value: SQLStatement
*/
public Hashtable getLoadedSQL() {
return this.loadedSQL;
}
/**
* Returns the appropriate SQLStatement for a mapid
*/
public SQLStatement getSQLStat ementByMapID(String mapid ) {
for (Enumeration e = this.loadedSQL.elements(); e.hasMoreElements();) {
Vector element = (Vector)e.nextElement();
for (Enumeration ee = element.elements(); ee.hasMoreElements();) {
SQLStatement item = (SQLStatement )ee.nextElement ();
if (item.getID().equalsIgnoreCase (mapid)) {
return item;
}
}
}
return null;
}
/**
* adds a SchemaAttribute to the list
*/
public void addAttributeFromLoad(String id, SchemaAttribute attr) {
this.loadedAttributes.put(id + attr.getName(),attr);
}
/**
* returns the parameters (hashtabel key=id,value=ParameterInfo
*/
public Hashtable getParameters () {
return this.loadedParameters;
}
/**
* Returns the appropriate SQLStatement for a mapid
*/
public ParameterInfo getParameterByMapID (String mapid) {
for (Enumeration e = this.loadedParameters.elements (); e.hasMoreElements();) {
Autor: Thomas Schädler
207
Anhang A: Quelltext <xmlizer> configurator
ParameterInfo item = (ParameterInfo)e.nextElement();
if (item.getID().equalsIgnoreCase(mapid)) {
return item;
}
}
return null;
}
/**
* adds a ParameterInfo to the list
* returns true if add was successfull
* else false (= no insert)
*/
public boolean addParameterFromLoad (String id , String name, String value) {
if (!this.loadedParameters .containsKey(name)) {
//System.out.println("NOT FOUND - ADDING");
this.loadedParameters.put(name,new ParameterInfo(id,name,value ));
return true;
}
else { /*System.out.println("FOUND - DO NOTHING");*/ return false; }
}
/**
* Removes the specified (name) parameter
*/
public boolean removeParameter (String name_to_remove) {
if (this.loadedParameters.containsKey(name_to_remove)) {
this.loadedParameters.remove(name_to_remove);
return true;
}
else return false;
}
/**
* adds a SchemaContent to the list
*/
public void addContentFromLoad (String id , SchemaContent cont ) {
this.loade dContent.put(id,cont);
}
/**
* Return a Hashtable full of happy SchemaAttributes
* key: elementname (which it belongs to) + attributename
* value: SchemaAttribute
*/
public Hashtable getLoadedAttributes() {
return this.loadedAttributes;
}
/**
* Return a Hashtable full of happy SchemaContent
* key: elementname (which it belongs to)
* value: SchemaContent
*/
public Hashtable getLoadedContent() {
return this.loadedContent;
}
public Element getMapping() {
if (this.rootElement == null)
//check for validity
{
return null;
}
else {
//DB2XML Mapping buildup
Element wrapper = new Element("mapping");
Element db2xml_wrapper = new Element("db2xml");
//root element
db2xml_wrapper.setAttribute ("rootelement",this.rootElement);
wrapper.addContent(db2xml_wrapper);
//add the parameters
for (Enumeration e = this.loadedParameters .elements(); e.hasMoreElements ();) {
ParameterInfo item = (ParameterInfo)e.nextElement();
Element curr = new Element("db2xml_parameter");
curr.setAttribute("id",item.getID ());
curr.setAttribute("name",item.getName());
curr.setAttribute("default",item.getValue());
db2xml_wrapper.addContent(curr);
}
//add the elements
for (Enumeration e = this.otherElements.elements(); e.hasMoreElements();) {
SchemaElement item = (SchemaElement)e.nextElement();
Element curr = new Element("db2xml_element" );
curr.setAttribute("name",item.getRealName());
curr.setAttribute("id",item.getID ());
//build content
if (item.hasContent()) {
SchemaContent cont = item.getContent();
curr.addContent(cont.getAsJDOMElement());
}
//build repetition info (attribute repsql)
if (item.getRepetition() != null) {
curr.setAttribute("repsql",item.getRepetition());
}
//build attributes
for (Enumeration enum = item.getAttributes().elements (); enum.hasMoreElements();) {
SchemaAttribute attr = (SchemaAttribute )enum.nextElement();
curr.addContent(attr.getAsJDOMElement());
Autor: Thomas Schädler
208
Anhang A: Quelltext <xmlizer> configurator
}
//build sql
for (Enumeration enum = item.getSQLStatements().elements(); enum.hasMoreElements();) {
SQLStatement stat = (SQLStatement)enum.nextElement();
curr.addContent(stat.getAsJDOMElement());
}
//add the element
db2xml_wrapper.addContent(curr);
}
return wrapper;
}
}
}/*
* XMLSchemaParser.java
*
* This class parsers a XML Schema and generates all neccessary info for
* using this XML Schema (instance generator, tree-view and element info)
*
* Created on 17. Juni 2002, 09:02
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 PURPOS E. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import
import
import
import
java.util.*;
javax.swing .*;
javax.swing .tree.*;
org.jdom.*;
/**
* Parses a XML Schema and builds an in ternal representation (tree) and
* can generate instances
* @author [email protected]
*/
public class XMLSchemaParser {
private configurator mother;
private Document doc;
private JTree tree = null;
//Hashtable for saving info-lists
private Hashtable xml_elements = new Hashtable();
private Hashtable xml_types = new Hashtable();
//little global helpers
private String rootelement = null;
private DefaultMutableTreeNode topNode = null;
private Hashtable loadedSQL = null;
private Hashtable loadedReps = null;
private Hashtable loadedContent = null;
/** Creates new XMLSchemaParser */
public XMLSchemaParser(configurator conf ) {
this.mother = conf;
}
/**
* Returns a JTree representing this XML Schema as browsable tree
*/
public JTree getTree() {
return tree;
}
/**
* Returns an instance document (test-output)
*/
public Document getInstance() {
return this.instance ; //and return the doc
}
//INSTANCE GENERATION
//----------------------------------------------------------------------------------------------private Document instance;
private Element DocumentRoot;
private boolean rootSet;
private Hashtable madeSQLs; //key = sqlid, value = SQLStatement
private Hashtable madeSQLsCurrentRow; //key = sqlid, value = currentRow
//private Vector all_current_ids; //holds all currently known ids
public void buildInstance() {
instance = null;
DocumentRoot = null;
rootSet = false ;
madeSQLs = new Hashtable(); //key = sqlid, value = SQLStatement
//all_current_ids = new Vector();
madeSQLsCurrentRow = new Hashtable(); //key = sqlid, value = currentRow
for (Enumeration e = this.topNode.children(); e.hasMoreElements();) {
DefaultMutableTreeNode dmtr = (DefaultMutableTreeNode)e.nextElement ();
try {
makeInstance (DocumentRoot,null,dmtr);
}
catch(Exception ex) {
Autor: Thomas Schädler
209
Anhang A: Quelltext <xmlizer> configurator
//mother.getLog().addError(ex);
return;
}
}
if (DocumentRoot != null) {
instance = new Document(DocumentRoot);
}
}
// parent=JDOM Element, lastParentElement=parental_SchemaElement, current=current_DefaultMutableTreeNode
private void makeInstance(Element parent ,SchemaElement lastParentElement,DefaultMutableTreeNode current) throws Exception
{
if (current == null) { return; } //failsafe
//get the schemaelement of the current node -> curse
SchemaElement curse = (SchemaElement )current.getUserObject();
//check for the root -element (as defined in the mapping - do something only if found)
if (!rootSet && curse.getRealName().equalsIgnoreCase(mother.getProjectData().DB2XMLgetmapping().getRootElement())) {
//insert the document root as indicated, can have no repetition (root!)
DocumentRoot = new Element(curse .getRealName());
prepareSQLStatements(curse.getSQLStatements());
processCurrentElement(DocumentRoot,null,curse);
rootSet = true;
}
//if the current schemaelement is valid and the root -> start buil ding
if (curse.isRefresh() && rootSet && curse .getID() != null) {
prepareSQLStatements(curse.getSQLStatements());
//process this element (builds it)
if (curse.getRepetition() != null) //if this element has a repetition sql statement
{
//get the maximum allowed repetition value (maxOccurs for this Element)
int max = ((Integer)curse.getOccurrence().getMaxOccurs()).intValue();
//get the data assocciated with the element's repetition
String mapid_for_rep = curse .getRepetition();
mother.getLog().addDebug("MAPID: " + mapid_for_rep);
Hashtable sql_result = (Hashtable )madeSQLs.get(mapid_for_rep);
//mother.getLog().addDebug("SQLRESULT: " + sql_result + " ROWS = " + ((Integer)sql_result.get("rows")).intValue());
//check for the maximum, if more then just cut it there so it will be valid
int sqlmax = ((Integer)sql_result .get("rows")).intValue();
if (sqlmax < max) { max = sqlmax; } //adjust the max for maxOccurs
//finally do it for each DB-row
for (int i=0;i<max;i++) {
Element this_element = new Element(curse.getRealName());
processCurrentElement(this_element ,parent,curse);
if (parent == null) //root set, but no parent -> this is the root element!
{
parent = DocumentRoot;
//do the same for all children
for (Enumeration e = current.children(); e.hasMoreElements();) {
makeInstance(parent,curse,(DefaultMutableTreeNode)e.nextElement());
}
}
else // this is a normal element (sub-node (or more sub-sub-...) of the rootelement)
{
parent.addContent(this_element );
//do the same for all children
for (Enumeration e = current.children(); e.hasMoreElements();) {
makeInstance(this_element,curse ,(DefaultMutableTreeNode)e.nextElement());
}
}
//update the row_counter for other statements of this element
int row_counter = ((Integer)madeSQLsCurrentRow.get(mapid_for_rep )).intValue() + 1;
//System.out.println(curse.getRealName() + " >>" + row_counter);
madeSQLsCurrentRow.put(mapid_for_rep,new Integer(row_counter));
}
}
else //no repetition statement a nd no minimum, so skip it (if it is not the root)
{
/* special treatment for the root node! */
if (curse.getRealName().equalsIgnoreCase(mother.getProjectData().DB2XMLgetmapping().getRootElement())) {
Element this_element = new Element(curse.getRealName());
processCurrentElement(this_element ,parent,curse);
if (parent == null) //root set, but no parent -> this ist the root element!
{
parent = DocumentRoot;
//do the same for all children
for (Enumeration e = current.children(); e.hasMoreElements();) {
makeInstance(parent,curse,(DefaultMutableTreeNode)e.nextElement());
}
}
else // this is a normal element (sub-node (or more sub-sub-...) of the rootelement)
{
parent.addContent(this_element );
//do the same for all children
for (Enumeration e = current.children(); e.hasMoreElements();) {
makeInstance(this_element,curse ,(DefaultMutableTreeNode)e.nextElement());
}
}
}
// has a minOccurence of more than 0 but no repetition -> make it at least an empty element
else if (curse.getOccurrence ().getMinOccurs ().intValue() > 0) {
Element this_element = new Element(curse.getRealName());
processCurrentElement(this_element ,parent,curse);
parent.addContent(this_element);
//do the same for all children
for (Enumeration e = current.children(); e.hasMoreElements();) {
makeInstance(this_element ,curse,(DefaultMutableTreeNode )e.nextElement());
Autor: Thomas Schädler
210
Anhang A: Quelltext <xmlizer> configurator
}
}
}
}
else //just go on without doing something (no buildup for those elements)
{
//do the same for all children
for (Enumeration e = current.children (); e.hasMoreElements();) {
makeInstance (parent,curse,(DefaultMutableTreeNode)e.nextElement ());
}
}
}
private void processCurrentElement(Element el ,Element parent ,SchemaElement sch) {
//fill in the content
if (sch.getContent() != null && sch.getContent ().getMapID() != null) //has content
{
SchemaContent cont = sch.getContent();
if (cont.getMapID() != null && cont.getMapInfo() != null) {
//get the data and fill the attribute
String mapid = cont.getMapID ();
//the ID
String mapinfo = cont.getMapInfo(); //the tableName
int currentRow = ((Integer)madeSQLsCurrentRow.get(mapid)).intValue();
Hashtable data = (Hashtable)madeSQLs.get(mapid);
//get the hash-data from the list
if (data == null) { mother.getLog ().addError("No data for referenced sql with id="+mapid+" found!"); }
Vector colnames = (Vector)data.get("columnname");
int col = 0;
for (Enumeration en = colnames.elements(); en.hasMoreElements();) {
String currname = (String)en.nextElement();
if (currname.equalsIgnoreCase (mapinfo)) {
break;
}
col++;
}
String info[][] = (String[][])data.get("table");
String result = info[col][currentRow];
//mother.getLog().addDebug("GOT Content: " + result + " [" +col+"]["+currentRow+"]");
//System.out.println("COL: " + col + " <> " + "ROW:" + row);
//System.out.println(madeSQLsCurrentRow.toString());
el.setText(result);
}
else if (cont.getMapID() != null && cont.getMapInfo() == null) {
//here comes the result of a simple statement
//which has only a mapid
//get the data and fill the attribute
String mapid = cont.getMapID ();
//the ID
int currentRow = ((Integer)madeSQLsCurrentRow.get(mapid)).intValue();
Hashtable data = (Hashtable)madeSQLs.get(mapid);
//get the hash-data from the list
if (data == null) { mother.getLog().addError("No data for referenced sql with id="+mapid+" found!"); }
String info[][] = (String[][])data.get("table");
String result = info[0][0];
//mother.getLog().addDebug("GOT Content: " + result + " ["+0+"]["+0+"]");
//System.out.println("COL: " + col + " <> " + "ROW:" + row);
//System.out.println(madeSQLsCurrentRow.toString());
el.setText(result);
}
else { /*/dev/null*/}
}
//fill the attributes with the apropriate values
for (Enumeration e = sch.getAttributes().elements(); e.hasMoreElements();) {
SchemaAttribute att = (SchemaAttribute)e.nextElement ();
//System.out.println(att.getName() + " >>> " + att.getUse() + " >>>" + att.getMapID());
if (att.getUse().equalsIgnoreCase("prohibited")) {
mother.getLog().addWarning("In element <" + sch.getRealName() + "> an attribute " + att.getName() + " is
PROHIBITED but has a value! Skipping...");
}
else if (att.getMapID() == null && att.getUse().equalsIgnoreCase("required")) //req. but not there -> tell the
user
{
mother.getLog().addWarning("In element <" + sch.getRealName() + "> an attribute " + att.getName() + " is
REQUIRED but has no value.");
}
else if (att.getMapID() != null && att.getMapInfo() != null) {
//get the data and fill the attribute
String mapid = att.getMapID();
//the ID
String mapinfo = att.getMapInfo(); //the tableName
mother.getLog().addDebug("Query: "+ mapid+":"+mapinfo);
int currentRow = ((Integer)madeSQLsCurrentRow.get(mapid)).intValue();
Hashtable data = (Hashtable)madeSQLs.get(mapid);
//get the hash-data from the list
if (data == null) { mother.getLog ().addError("No data for id="+mapid +" found!" ); }
Vector colnames = (Vector)data.get("columnname");
int col = 0;
for (Enumeration en = colnames.elements(); en.hasMoreElements();) {
String currname = (String)en.nextElement();
if (currname.equalsIgnoreCase (mapinfo)) {
break;
}
col++;
}
String info[][] = (String[][])data.get("table");
String result = info[col][currentRow];
//mother.getLog().addDebug("GOT Attribute Value: " + result + " ["+col+"]["+currentRow+"]");
//System.out.println("COL: " + col + " <> " + "ROW:" + row);
//System.out.println(madeSQLsCurrentRow.toString());
el.setAttribute(att.getName(),result);
}
else if (att.getMapID() != null && att.getMapInfo() == null) {
//here comes the result of a simple statement
Autor: Thomas Schädler
211
Anhang A: Quelltext <xmlizer> configurator
//which has only a mapid
//get the data and fill the attribute
String mapid = att.getMapID();
//the ID
mother.getLog().addDebug("Query: "+ mapid);
int currentRow = ((Integer)madeSQLsCurrentRow.get(mapid)).intValue();
Hashtable data = (Hashtable)madeSQLs.get(mapid);
//get the hash-data from the list
if (data == null) { mother.getLog ().addError("No data for id="+mapid +" found!" ); }
String info[][] = (String[][])data.get("table");
String result = info[0][0];
//mother.getLog().addDebug("GOT Attribute Value: " + result + " ["+0+"]["+0+"]");
//System.out.println("COL: " + col + " <> " + "ROW:" + row);
//System.out.println(madeSQLsCurrentRow.toString());
el.setAttribute(att.getName(),result);
}
else { /*/dev/null*/}
}
}
private Vector prepareSQLStatements (Vector vec) throws Exception {
if (vec == null) { return new Vector (0); } //check for fail
Vector res = new Vector();
for (Enumeration e = vec.elements(); e.hasMoreElements();) {
SQLStatement current = (SQLStatement)e.nextElement();
String current_id = current.getID();
//System.out.println("MAKING : " + current_id);
dbItem used_db_item = mother.getProjectData().getDBByName (current.getDB());
//System.out.println("
dbItem -> " + used_db_item);
Hashtable sql_result = null;
try {
//System.out.println("
Query -> " + current.getSQL());
String resolvedQuery = resolveQuery(current.getSQL());
//System.out.println("
Resol -> " + resolvedQuery);
sql_result = used_db_item.querySilent(resolvedQuery);
this.madeSQLs.put(current_id ,sql_result); //add them to the list
this.madeSQLsCurrentRow .put(current_id ,new Integer(0));
res.add(current_id );
//System.out.println("
SUCCESS !!");
}
catch (Exception ex) {
mother.getLog().addError(ex);
}
}
//System.out.println(res.toString());
//System.out.println(madeSQLsCurrentRow.toString());
return res;
}
/** Returns xxx from xxx:yyy */
private String getFirst(String s,int cutter) {
int doublepoint = s.indexOf(":");
if (double point != 0) {
return s.substring(cutter,doublepoint );
}
else return s;
}
/** Returns yyy from xxx:yyy */
private String getSecond (String s,int cutter) {
int doublepoint = s.indexOf(":");
if (doublepoint != 0) {
return s.substring(++doublepoint ,s.length()-cutter);
}
else return s;
}
private String getSubstitution (String query) {
StringBuffer result = new StringBuffer();
int counter = 0;
StringTokenizer st = new StringTokenizer(query );
while (st.hasMoreTokens()) {
String token = st.nextToken ();
//parameter substitution
if (token.startsWith("[-") && token.endsWith("-]")) //parameter substitution
{
StringBuffer newToken = new StringBuffer();
String mapid = getFirst (token,2);
String mapinfo = getSecond(token,2);
ParameterInfo thisinfo = mother.getProjectData().DB2XMLgetmapping().getParameterByMapID(mapid);
newToken.append(thisinfo.getValue ());
result.append(newToken.toString());
}
//sql substitution
else if (token.startsWith("[") && token.endsWith("]")) //sql substitution
{
StringBuffer newToken = new StringBuffer();
// [mapid:mapinfo]
// evaluierungsschritte:
// 1. SQLStatment holen für den angegebenen key
String mapid = getFirst (token,1);
String mapinfo = getSecond(token,1);
//newToken.append("**" + mapid + "=" + mapinfo + "**");
// 2. dbItem holen für das angegebene SQLStatement (siehe XMLSchemaParser)
SQLStatement stat = mother.getProjectData().DB2XMLgetmapping().getSQLStatementByMapID(mapid);
//newToken.append(stat.toString());
dbItem used_db_item = mother .getProjectData ().getDBByName(stat.getDB ());
Hashtable sql_result;
// 3. SQL auf dieser datenbank ausführen:
try {
String sub_query = getSubstitution (stat.getSQL());
sql_result = used_db_item.querySil ent(sub_query);
Autor: Thomas Schädler
212
Anhang A: Quelltext <xmlizer> configurator
// -- bei nur einem resultat -> dieses aus der übereinstimmenden namen (z.B. dbKey) ersetzen
// -- bei mehreren resultaten -> einfach das erste nehemn (alternativ oben das limit gleich ändern)
// 4. das ganze noch richtig ersetzen (Stringmässig) und dann ab damit zurück nach Hause
Vector colnames = (Vector)sql_result.get("columnname");
int col = 0;
for (Enumeration en = colnames.elements (); en.hasMoreElements();) {
String currname = (String )en.nextElement ();
if (currname.equalsIgnoreCase(mapinfo)) {
break;
}
col++;
}
String info[][] = (String[][])sql_result.get("table");
int row = ((Integer)madeSQLsCurrentRow.get(mapid)).intValue (); //get the current row
String resultString = info[col][row];
newToken .append(" ");
newToken .append(resultString);
result.append(newToken.toString());
counter++;
}
catch (Exception ex) {
mother.getLog().addError (ex);
}
}
else {
result.append(" ");
result.append(token);
}
}
return result.toString();
}
private String resolveQuery(String query ) {
//do all data operations on the embedded queries and replace them internally!
StringBuffer result = new StringBuffer();
//parse the query and substitute the SQLColumnInfo-Strings
//with the real value from the following new statement: (example)
result.append(getSubstitution(query));
//achtung! "[..] "könnte probleme machen - format suchen!!
return result.toString();
}
//PARSING
//----------------------------------------------------------------------------------------------/**
* Parse an XML Schema
*/
public boolean parse(Document doc) {
this.doc = doc;
//parse it and make everything ok, then
try {
doParse();
return true;
}
catch (Exception ex) {
//mother.getLog().addError(ex);
//System.out.println(ex.toString());
return false;
}
}
private void doParse() throws Exception {
//parse the xml schema
Element xmlroot = doc.getRootElement ();
//get the xml root
Namespace namespace = xmlroot.getNamespace();
//get the namespac e
topNode = insertDocumentNode(xmlroot); //insert the doc root in the tree
// iterate over children of the root node
List elems = xmlroot.getChildren(); //"element",namespace
Iterator elems_iter = elems.iterator ();
int item_count = elems.size();
Object[] rootElems = new Object [item_count];
int counter = 0;
while (elems_iter.hasNext()) {
Element xmlelem = (Element) elems_iter.next();
if (this.JDOMisElement (xmlelem)) {
rootElems[counter] = this.JDOMgetElementName(xmlelem);
this.xml_elements.put(this.JDOMgetElementName(xmlelem),xmlelem);
counter++;
}
else if (this.JDOMisType(xmlelem))
//build type-lib for simpleTypes
{
this.xml_types.put(this.JDOMgetElementName(xmlelem),xmlelem);
}
}
//load the Content to add them to the elements
this.loadedContent = mother.getProjectData().DB2XMLgetmapping ().getLoadedContent();
//load the Repetitions to add them to the elements
this.loadedReps = mother.getProjectData().DB2XMLgetmapping().getLoadedReps();
//load the SQLStatements from xmlizer.xml
this.loadedSQL = mother.getProjectData().DB2XMLgetmapping().getLoadedSQL();
//check for saved root-element, else choose one
rootelement = mother .getProjectData().DB2XMLgetmapping().getRootElement ();
//check if the saved root element is available, else choose new
if (rootelement != null) {
if (!this.xml_elements .containsKey(rootelement)) {
rootelement = null;
}
}
Autor: Thomas Schädler
213
Anhang A: Quelltext <xmlizer> configurator
//else choose a new root (auto or manual)
if (rootelement == null) {
if (counter > 1)
//has at least two or more elements
{
//Ask for the root element to start with and build up the logical semi-resolved tree
rootelement = (String)JOptionPane .showInputDialog
(
null,
"Ambigous root elements detected. \nSelect one of the following as your root element" ,
"Root selection",
JOptionPane.INFORMATION_MESSAGE,
null,
rootElems,
rootElems[0]
);
}
else if (counter == 1) {
rootelement = (String)rootElems[0];
}
else {
JOptionPane.showMessageDialog(
null,
"The selected XML Schema has no root\n element(s) and is therfore not usable.\nCheck the schema and try
again.",
configurator .APPNAME + " schema error" ,
JOptionPane.ERROR_MESSAGE
);
}
//save it in config
mother .getProjectData().DB2XMLgetmapping().setRootElement (rootelement);
mother .getProjectData().setDirty (); //mark dirty
}
Element current = (Element )this.xml_elements.get(rootelement);
recursiveTreeBuilder (topNode,current);
//make the tree
tree = new JTree(topNode);
tree.setRootVisible(true);
tree.getSelectionModel().setSelectionMode (TreeSelectionModel.SINGLE_TREE_SELECTION);
tree.setShowsRootHandles(true);
tree.setCellRenderer (new XMLTreeCellRenderer());
}
//------------------------------------------------------ PARSE HELPERS
/**
* Walks the JDOM Path to the root and build a xpath-like (unique string)
* which identifies a element for sure
*/
private String walkJDOMPath(Element element) {
StringBuffer buff = new StringBuffer ();
Element current = element;
do {
if (current.getAttribute("name") != null) {
buff.insert(0,"/" + current.getAttribute("name").getValue());
}
current = current.getParent ();
} while (!current.isRootElement ());
return buff.toString();
}
/**
* Walks the tree-path of the jtree and adds all parent -nodes(=elements)
* to the list of the element's parents
*/
private SchemaElement walkTreePath(Object[] path,SchemaElement elem) {
//add all parent ele ments to this element and return it
//System.out.println(elem.getName() + " --> " + path.length);
for(int i=0;i<path.length;i++) {
DefaultMutableTreeNode curr = (DefaultMutableTreeNode)path[i];
SchemaElement currse = (SchemaElement )curr.getUserObject();
if (currse.isRefresh() && currse .getID() != null) //is a real element (xml)
{
//System.out.println(currse.getID());
elem.addParent(currse);
}
}
return elem;
}
private DefaultMutableTreeNode lastParent = null;
private SchemaElement lastSchemaElement = null;
private void recursiveTreeBuilder(DefaultMutableTreeNode parentNode,Element current) {
//inspect this element and recurse for child-elements with current as new parentNode
if (current == null) { return; } //failsafe
DefaultMutableTreeNode treeNode = null;
SchemaElement schemel = null;
if (current.getName().equalsIgnoreCase("element")) {
treeNode = new DefaultMutableTreeNode (current);
String uniquePath = walkJDOMPath (current);
schemel = new SchemaElement (this.mother,treeNode,current,uniquePath );
StringBuffer name = new StringBuffer();
Attribute attr = null;
SchemaOccurrence occurrence = new SchemaOccurrence(current.getName().trim());
//name
attr = current.getAttribute ("name");
if (attr != null) {
Autor: Thomas Schädler
214
Anhang A: Quelltext <xmlizer> configurator
//System.out.println(attr.getValue());
schemel.setRealName(attr.getValue ().trim());
name.append("<" + attr.getValue().trim() + ">");
//get the current elementname
//add the Repetition if available
if (this.loadedReps.containsKey(uniquePath)) {
schemel.setRepetition((String )this.loadedReps.get(uniquePath));
}
//add the SQLStatements according to the elementName in loadedSQL
if (this.loadedSQL .containsKey(uniquePath)) {
//System.out.println(uniquePath + " has a SQLStatement attached");
Vector this_sqls = (Vector)this.loadedSQL.get(uniquePath);
for (Enumeration e = this_sqls.elements (); e.hasMoreElements();) {
SQLStatement this_stat = (SQLStatement)e.nextElement();
//System.out.println("ADDING SQL WHILE PARSING: " + this_stat);
schemel.addSQLStatement(this_stat);
}
}
}
//type
attr = current.getAttribute ("type");
if (attr != null) {
schemel.setType(attr.getValue().trim());
name.append(" - " + attr.getValue ().trim());
}
//ref
attr = current.getAttribute ("ref");
if (attr != null) {
schemel.setTypeRef (attr.getValue().trim());
name.append(" => " +attr.getValue ().trim());
}
//minOccurs
attr = current.getAttribute ("minOccurs");
if (attr != null) {
String min = attr.getValue().trim();
if (min != null) {
occurrence.setMinOccurs(min);
}
//System.out.println("MIN: " + min);
}
//maxOccurs
attr = current.getAttribute ("maxOccurs");
if (attr != null) {
String max = attr.getValue().trim();
if (max != null) {
occurrence.setMaxOccurs(max);
}
//System.out.println("MAX: " + max);
}
schemel.setOccurrence(occurrence );
schemel.setName(name.toString());
if (schemel.hasTypeRef ())
//typ dereferencing
{
String typeRef = schemel.getTypeRef();
//System.out.println("TypeRef: " + typeRef);
typeRef = removeNamespacePrefix(typeRef);
Element newcurrent = (Element)this.xml_elements.get(typeRef);
if (newcurrent != null) {
recursiveTreeBuilder(parentNode,newcurrent);
}
}
else if (schemel.hasType()) //type buildup
{
//add the stuff
treeNode.setUserObject(schemel);
parentNode.add(treeNode );
lastParent = treeNode; //set last to current
//System.out.println(schemel.getID() + " >> " + schemel.getName());
boolean isnew = mother.getProjectData().DB2XMLgetmapping().addElement(schemel);
if (isnew) { mother.getProjectData().setDirty(); }//mark dirty
//add the stuff
//end should be reached because of having a simple type
String typeR = schemel.getType();
//System.out.println("Type: " + typeR);
typeR = removeNamespacePrefix(typeR);
Element newcurrent = (Element)this.xml_types.get(typeR);
if (newcurrent != null) {
//System.out.println(schemel);
schemel.processType (newcurrent);
lookForAttributes(schemel,newcurrent);
lookForContent (schemel,newcurrent);
recursiveTreeBuilder(treeNode ,newcurrent);
}
else //must be an internal type (per default just take it for now)
{
//could also be an invalid type!
if (this.loadedContent.containsKey (schemel.getID())) {
schemel.setContent((SchemaContent)this.loadedContent.get(schemel.getID ()));
}
else {
schemel.setContent(new SchemaContent(schemel.getID ()));
}
}
//fill in parents
schemel = walkTreePath(treeNode.getPath(),schemel);
//make age change here
lastSchemaElement = schemel;
Autor: Thomas Schädler
215
Anhang A: Quelltext <xmlizer> configurator
}
else
{
//must have an internal type -> buildup
//add the stuff
treeNode.setUserObject(schemel);
parentNode.add(treeNode );
lastParent = treeNode; //set last to current
boolean isnew = mother.getProjectData().DB2XMLgetmapping().addElement(schemel);
if (isnew) { mother.getProjectData().setDirty(); }//mark dirty
//add the stuff
schemel.setInternalType (); //mark that it has an internal type def.
schemel.processInternalType();
//fill in parents
schemel = walkTreePath(treeNode.getPath(),schemel);
//make age change here
lastSchemaElement = schemel;
}
}
else if (current.getName().equalsIgnoreCase("any")) {
treeNode = new DefaultMutableTreeNode ();
schemel = new SchemaElement (this.mother,treeNode,"<any>");
treeNode.setUserObject (schemel);
parentNode.add(treeNode);
lastParent = treeNode;
}
else if (current.getName().equalsIgnoreCase("all")) {
treeNode = new DefaultMutableTreeNode ();
schemel = new SchemaElement (this.mother,treeNode,"-=all=-");
treeNode.setUserObject (schemel);
parentNode.add(treeNode);
lastParent = treeNode;
}
else if (current.getName().equalsIgnoreCase("group")) {
treeNode = new DefaultMutableTreeNode ();
schemel = new SchemaElement (this.mother,treeNode,"-=group=-");
treeNode.setUserObject (schemel);
parentNode.add(treeNode);
lastParent = treeNode;
}
else if (current.getName().equalsIgnoreCase("sequence")) {
treeNode = new DefaultMutableTreeNode ();
schemel = new SchemaElement (this.mother,treeNode,"-=sequence=-");
treeNode.setUserObject (schemel);
parentNode.add(treeNode);
lastParent = treeNode;
}
else if (current.getName().equalsIgnoreCase("choice")) {
treeNode = new DefaultMutableTreeNode ();
schemel = new SchemaElement (this.mother,treeNode,"-=choice=-");
treeNode.setUserObject (schemel);
parentNode.add(treeNode);
lastParent = treeNode;
}
else if (current.getName().equalsIgnoreCase("documentation")) {
lastSchemaElement.addDocumentation(current.getText());
}
else {
treeNode = lastParent;
}
//look for complexType
// iterate over children of the this element node
List elems = current.getChildren(); //"elements",namespace
Iterator elems_iter = elems.iterator ();
while (elems_iter.hasNext()) {
Element xmlelem = (Element) elems_iter.next();
recursiveTreeBuilder(treeNode,xmlelem);
}
}
/**
* Recursive search for simpleContent in type -Elements (simple and complex)
*/
private void lookForContent(SchemaElement attachHere,Element typeElement) {
if (typeElement == null) { return; } //failsafe
if (typeElement .getName().equalsIgnoreCase("simpleContent")) {
if (this.loadedContent .containsKey(attachHere.getID())) {
attachHere.setContent((SchemaContent)this.loadedContent.get(attachHere.getID()));
return;
}
else {
attachHere.setContent(new SchemaContent(attachHere.getID()));
return;
}
}
// iterate over children of the this element node
List elems = typeElement.getChildren (); //"elements",namespace
Iterator elems_iter = elems.iterator ();
while (elems_iter.hasNext()) {
Element xmlelem = (Element) elems_iter.next();
lookForContent(attachHere,xmlelem);
}
}
/**
* Recursive search for attributes in type-Elements (si mple and complex)
*/
private void lookForAttributes (SchemaElement attachHere ,Element typeElement ) {
if (typeElement == null) { return; } //failsafe
if (typeElement .getName().equalsIgnoreCase("attribute")) {
attachHere.addAttribute(typeElement,mother .getProjectData ().DB2XMLgetmapping().getLoadedAttributes ());
Autor: Thomas Schädler
216
Anhang A: Quelltext <xmlizer> configurator
}
// iterate over children of the this element node
List elems = typeElement.getChildren (); //"elements",namespace
Iterator elems_iter = elems.iterator ();
while (elems_iter.hasNext()) {
Element xmlelem = (Element) elems_iter.next();
lookForAttributes(attachHere,xmlelem);
}
}
/**
* Returns the name of this JDOMElement (attribute name of <element name="asdf"...>
* else returns "anonymous"
*/
private String JDOMgetElementName(Element el) {
Attribute attr = el.getAttribute("name");
if (attr != null) {
return attr.getValue().trim();
}
else //just to be sure, should not happen though...
{
return "anonymous";
}
}
/**
* Returns true if this JDOMElement is an <element ...> -tag
*/
private boolean JDOMisType(Element el) {
if (el.getName().equalsIgnoreCase("simpleType" ) || el.getName().equalsIgnoreCase("complexType"))
return true;
return false;
}
/**
* Tests if the JDOMElement is of indicated type or not
*/
private boolean JDOMisOfType(String type ,Element el) {
if (el.getName().equalsIgnoreCase(type))
return true;
else return false;
}
/**
* Returns true if this JDOMElement is an <element ...> -tag
*/
private boolean JDOMisElement(Element el ) {
if (el.getName().equalsIgnoreCase("element"))
return true;
return false;
}
private DefaultMutableTreeNode insertDocumentNode(Element what) {
DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode();
SchemaElement schemel = new SchemaElement (this.mother,treeNode,"<schema>",what);
treeNode.setUserObject(schemel);
return treeNode ;
}
//------------------------------------------------------ TREE HELPERS
private class XMLTreeCellRenderer extends DefaultTreeCellRenderer {
ImageIcon mainImg;
ImageIcon leafImg;
ImageIcon openImg;
ImageIcon closeImg;
public XMLTreeCellRenderer (){}
public java.awt.Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded,
boolean leaf, int row,
boolean hasFocus) {
mainImg = new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/openide/xmlObject.gif"));
leafImg = new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/list/blue.gif"));
closeImg = new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/openide/defaultFolder.gif"));
openImg = new javax.swing.ImageIcon(getClass().getResource("/configurator/icons/openide/defaultFolderOpen.gif"));
java.awt.Component comp = super.getTreeCellRendererComponent(tree,value,selected,expanded,leaf,row,hasFocus);
if(row==0) {
setIcon(mainImg);
}
else if (leaf) {
setIcon(leafImg);
}
else if (expanded) {
setIcon(openImg);
}
else {
setIcon(closeImg);
}
return comp;
}
}
private static String removeNamespacePrefix(String s) {
int doublepoint = s.indexOf(":");
if (doublepoint != 0) {
return s.substring(++doublepoint );
}
else return s;
}
}
/*
Autor: Thomas Schädler
217
Anhang A: Quelltext <xmlizer> configurator
* SQLStatement.java
*
* This class contains all neccessary info for SQL Statements
*
* Created on 24. Juli 2002, 14:35
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import java.util.*;
import org.jdom.*;
/**
* A SQL Statement with all related methods
* @author thomas.schae [email protected]
* @version 0.3
*/
public class SQLStatement {
private
private
private
private
private
private
String db = null;
String sql = null;
String id = null;
int rowNumber = 0;
Vector colnames = new Vector();
Vector colt ypes = new Vector();
/** Creates new SQLStatement */
/**
* Creats a new Statement with the given id
*/
public SQLStatement (String db,String sql ,String id ) {
this.db = db;
this.sql = sql;
this.id = id;
}
/**
* Creates a new Statement with a generated (unique) id
*/
public SQLStatement (String db,String sql ,Vector cols,Vector types ,int rows) {
UniqueID ID = new UniqueID ();
this.id = ID.get();
this.db = db;
this.sql = sql;
this.colnames = cols;
this.coltypes = types;
this.rowNumber = rows;
//System.out.println("ROWNUMBER: " + rows);
}
/**
* Creates a new Statement with the given id and given vectors
*/
public SQLStatement (String db,String sql ,String id ,Vector cols,Vector types ) {
this.id = id;
this.db = db;
this.sql = sql;
this.colnames = cols;
this.coltypes = types;
}
/*
* Set the db
*/
public void setDB(String name) {
this.db = name;
}
/*
* Set the sql statement
*/
public void setSQL(String sql) {
this.sql = sql;
}
/*
* Set the sql statement
*/
public void setCols(Vector hash) {
this.colnames = hash;
}
/*
* Set the sql statement
*/
public void setColTypes(Vector hash ) {
this.coltypes = hash;
}
Autor: Thomas Schädler
218
Anhang A: Quelltext <xmlizer> configurator
/*
* Get the db
*/
public String getDB () {
return this.db;
}
/*
* Get the sql statement
*/
public String getSQL() {
return this.sql;
}
public void setRowNumber (int r) {
//System.out.println("SETROWNUMBER: " + this.rowNumber);
this.rowNumber = r;
}
public int getRowNumber() {
//System.out.println("GETROWNUMBER: " + this.rowNumber);
return this.rowNumber;
}
public Vector getCols() {
return this.colnames ;
}
/**
* Returns the columns as Vector of SQLColumnInfo (ad hoc type)
*/
public Vector getColsAsSQLColumnInfo() {
Vector itemcols = new Vector();
int counter = 0;
for (Enumeration e = this.colnames.elements(); e.hasMoreElements();) {
String this_col_name = (String)e.nextElement();
String this_col_type = (String)this.coltypes.get(counter);
itemcols.add(new SQLColumnInfo(this.id,this_col_name ,this_col_type));
counter++;
}
return itemcols ;
}
/**
* Returns the columns as Vector of ColumnItems (ad hoc type)
*/
public Vector getColsAsColumnInfo() {
Vector itemcols = new Vector();
int counter = 0;
for (Enumeration e = this.colnames.elements(); e.hasMoreElements();) {
String this_col_name = (String)e.nextElement();
String this_col_type = (String)this.coltypes.get(counter);
itemcols.add(new ColumnInfo (this.id,this_col_name,this_col_type));
counter++;
}
return itemcols ;
}
public Vector getColTypes() {
return this.coltypes ;
}
/**
* Add a name to the colname-vector
*/
public void addColName(String name) {
if (name != null) {
this.colnames.add(name);
}
}
/**
* Add a name to the coltype-vector
*/
public void addColType(String type) {
if (type != null) {
this.coltypes.add(type);
}
}
/**
* Returns the mapid
*/
public String getID () {
return this.id;
}
public String toString() {
return this.db + " -> " + this.sql + " [" + this.colnames.size() + "]";
}
public Element getAsJDOMElement() {
if (this.db == null || this.id == null || this.sql == null || this.colnames == null || this.coltypes == null)
//check for validity
{
return null;
}
else {
Element curr = new Element("db2xml_sql");
curr.setAttribute("id",this.id);
curr.setAttribute("db",this.db);
curr.setAttribute("sql",this.sql);
if (this.colnames.size() > 0 && this.colnames.size() == this.coltypes.size()) {
Autor: Thomas Schädler
219
Anhang A: Quelltext <xmlizer> configurator
int counter = 0;
for (Enumeration e = this.colnames.elements (); e.hasMoreElements();) {
Element sub = new Element("db2xml_sql_info");
String item = (String)e.nextElement();
sub.setAttribute("name",item);
sub.setAttribute("type",(String)this.coltypes.get(counter));
counter++;
curr.addContent(sub);
}
}
return curr;
}
}
}/*
* SQLChooser.java
*
* Created on 24. Juli 2002, 18:53
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar is distributed in the hope that it will be useful,
* but WITHOUT AN Y 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import
import
import
import
import
import
java.awt.*;
java.util.*;
javax.swing .*;
java.awt.dnd.*;
java.awt.event.*;
java.awt.datatransfer .*;
/**
* Is the SQLChooser, used to drop queries and columninfos to the module DB2XML
* @author [email protected]
*/
public class SQLCh ooser extends MyInternalFrame {
private configurator mother;
private String ID;
private boolean isLoading = true;
private String title = new String();
private SQLStatement lastSQL = null;
private SchemaElement currentElement = null;
private Vector allSchemaElements = new Vector ();
//To use the pool just add a Runnable to the pool [pool.execute(someRunnable)]
private ThreadPool pool = new ThreadPool (2);
/** Creates new form SQLChooser */
public SQLChooser(configurator mainProgram,String uid) {
this.mother = mainProgram;
this.ID = uid;
initComponents();
theSplitPane.setDividerLocation (180);
//make the list functional
sqlList.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
tableList.getSelectionModel().setSelectionMode (ListSelectionModel.SINGLE_SELECTION);
//add the mouselistener
ItemListener ilst = new ItemListener (this);
sqlList.addMouseListener(ilst);
this.setTitleElementName("");
}
public void setLastSQL(SQLStatement stat ) {
this.lastSQL = stat;
}
/**
* Listens for listItem-(Mouse)-Events on the dbtableList
* -> For database queries
*/
class ItemListener implements java.awt.event.MouseListener {
protected SQLChooser m_parent;
protected JList m_list;
public ItemListener(SQLChooser parent) {
m_parent = parent;
m_list = parent.sqlList;
}
public void mouseClicked(java.awt.event.MouseEvent e) {
if(SwingUtilities.isRightMouseButton(e)) {
m_parent.getPopup().show(m_list,e.getX(),e.getY());
}
else {
doAction();
}
}
Autor: Thomas Schädler
220
Anhang A: Quelltext <xmlizer> configurator
public
public
public
public
void
void
void
void
mousePressed(java.awt.event.MouseEvent e){}
mouseReleased(java.awt.event.MouseEvent e){}
mouseEntered(java.awt.event.MouseE vent e){}
mouseExited(java.awt.event.MouseEvent e ){}
protected void doAction() {
int index = m_list.getSelectedIndex();
if (index < 0) {
return;
}
if (m_list.getModel().getSize() > index) {
SQLStatement data = (SQLStatement )m_list.getModel().getElementAt(index);
if (data != null) {
m_parent .setLastSQL (data);
m_parent .updateTables(data.getColsAsColumnInfo());
}
}
}
}
private void setTitleElementName(String name) {
StringBuffer buff = new StringBuffer ("SQL Chooser");
if (name != null) {
buff.append (" @ " + name);
this.setTitle(buff.toString ());
}
this.repaint();
}
public JPopupMenu getPopup() {
return this.sqlPopupMenu;
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
private void initComponents() {//GEN-BEGIN:initComponents
sqlPopupMenu = new javax.swing.JPopupMenu ();
testMenuItem = new javax.swing.JMenuItem();
jSeparator1 = new javax.swing.JSeparator();
deleteMenuItem = new javax .swing.JMenuItem();
theSplitPane = new javax.swing.JSplitPane ();
upperPanel = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
sqlList = new DNDListSQL();
lowerPanel = new javax.swing.JPanel();
jScrollPane2 = new javax.swing.JScrollPane();
tableList = new DNDListInfo();
jPanel1 = new javax.swing.JPane l();
elementComboBox = new javax.swing.JComboBox();
jPanel2 = new javax.swing.JPanel();
addButton = new javax.swing.JButton();
jButton1 = new javax .swing .JButton();
testMenuItem.setToolTipText("Test this SQL Query");
testMenuItem.setText("Inspect Query" );
testMenuItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
testMenuItemActionPerformed(evt);
}
});
sqlPopupMenu.add(testMenuItem);
sqlPopupMenu.add(jSeparator1);
deleteMenuItem.setToolTipText("Remove/Delete this SQL Query");
deleteMenuItem.setText("Remove Query");
deleteMenuItem.addActionListener(new java.awt.event .ActionListener () {
public void actionPerformed (java.awt.event .ActionEvent evt) {
deleteMenuItemActionPerformed(evt);
}
});
sqlPopupMenu.add(deleteMenuItem);
setMaximizable(true);
setTitle("SQL Chooser");
setIconifiable(true);
setResizable(true);
setClosable(true);
setPreferredSize(new java.awt.Dimension(300, 400));
addInternalFrameListener(new javax.swing.event .InternalFrameListener() {
public void internalFrameOpened(javax .swing.event.InternalFrameEvent evt ) {
}
public void internalFrameClosing (javax.swing.event.InternalFrameEvent evt) {
formInternalFrameClosing(evt);
}
public void internalFrameClosed(javax .swing.event.InternalFrameEvent evt ) {
}
public void internalFrameIconified(javax.swing.event .InternalFrameEvent evt) {
}
public void internalFrameDeiconified(javax .swing.event.InternalFrameEvent evt ) {
}
public void internalFrameActivated(javax.swing.event .InternalFrameEvent evt) {
}
public void internalFrameDeactivated(javax.swing.event.InternalFrameEvent evt ) {
}
});
theSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
theSplitPane.setOneTouchExpandable(true);
upperPanel .setLayout (new java.awt.BorderLayout());
Autor: Thomas Schädler
221
Anhang A: Quelltext <xmlizer> configurator
sqlList.setBorder(new javax.swing.border.TitledBorder(null, "SQL Queries:", javax .swing.border.TitledBorder .LEFT,
javax.swing.border .TitledBorder.DEFAULT_POSITION));
jScrollPane1.setViewportView(sqlList);
upperPanel .add(jScrollPane1, java.awt.BorderLayout.CENTER);
theSplitPane.setLeftComponent(upperPanel);
lowerPanel .setLayout (new java.awt.BorderLayout ());
tableList.setBorder(new javax.swing.border.TitledBorder(null, "Result Table Columns of selected Query:", javax.swing.border.TitledBorder.LEFT, javax.swing.border .TitledBorder.DEFAULT_POSITION ));
jScrollPane2.setViewportView(tableList);
lowerPanel .add(jScrollPane2, java.awt.BorderLayout.CENTER);
theSplitPane.setRightComponent(lowerPanel );
getContentPane().add(theSplitPane, java.awt.BorderLayout .CENTER);
jPanel1.setLayout(new java.awt.BorderLayout());
elementComboBox .addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
elementComboBoxActionPerformed(evt);
}
});
jPanel1.add(elementComboBox, java.awt.BorderLayout.CENTER);
jPanel2.setLayout(new java.awt.FlowLayout (java.awt.FlowLayout .CENTER, 0, 0));
addButton.setIcon(new javax.swing.ImageIcon(getClass().getResource ("/configurator/icons/html/refresh.gif")));
addButton.setText("Add");
addButton.addActionListener(new java.awt.event .ActionListener () {
public void actionPerformed (java.awt.event .ActionEvent evt) {
addButtonActionPerformed(evt);
}
});
jPanel2.add(addButton);
jButton1.setIcon(new javax .swing.ImageIcon(getClass ().getResource("/configurator/icons/Help16.gif")));
jButton1.setToolTipText("Open Help");
jButton1.setFont(new java.awt.Font("Dialog", 0, 10));
jButton1.addActionListener (new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
jButton1ActionPerformed (evt);
}
});
jPanel2.add(jButton1 );
jPanel1.add(jPanel2, java.awt.BorderLayout.EAST);
getContentPane().add(jPanel1, java.awt.BorderLayout .NORTH);
pack();
}//GEN-END:initComponents
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN -FIRST:event_jButton1ActionPerformed
// Add your handling code here:
helpWindow help = (helpWindow)mother .open("help");
help.loadPage("/configurator/help/module_db2xml_sqlchooser.html");
}//GEN-LAST:event_jButton1ActionPerformed
private void addButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_addButtonActionPerformed
{//GEN-HEADEREND:event_addButtonActionPerformed
// Add your handling code here:
final SchemaElement currsel = getActiveElement ();
final configurator tmother = this.mother;
final String tid = this.ID;
if (currsel != null) {
this.addButton.setEnabled(false);
Runnable r = new Runnable() {
public void run() {
tmother.mappingState = false;
//opening the DataChooser
DataChooser dch = (DataChooser)tmother.open("DataChooser");
dch.setSchemaElement(currsel);
//opening the dbBrowser
dbBrowser browser = (dbBrowser)tmother.open("databaseBrowser");
browser.setDataChooser(dch);
browser.enableTakeover(currsel);
tmother.close(tid);
}
};
try
{ pool.execute(r); }catch(InterruptedException ie)
{ tmother.getLog ().addError (ie);}
}
/*
SchemaElement currsel = getActiveElement();
mother.mappingState = false;
dbBrowser browser = (dbBrowser)mother.open("databaseBrowser");
DataChooser dch = (DataChooser)mother.open("DataChooser");
dch.setSchemaElement(currsel);
browser.setDataChooser(dch);
mother.close(this.ID);
browser.enableTakeover(currsel);
**/
Autor: Thomas Schädler
222
Anhang A: Quelltext <xmlizer> configurator
}//GEN-LAST:event_addButtonActionPerformed
private void deleteMenuItemActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_deleteMenuItemActionPerformed
{//GEN-HEADEREND:event_deleteMenuItemActionPerformed
// Add your handling code here:
SchemaElement currsel = getActiveElement();
if (currsel != null) {
//currsel.removeSQLStatement(this.lastSQL);
//mother.getProjectData().DB2XMLgetmapping().cleanElements(this.lastSQL);
mother .getProjectData().cleanSchemaElementFullDependencies(this.lastSQL);
sqlList.repaint();
}
}//GEN-LAST:event_deleteMenuItemActionPerformed
private void testMenuItemActionPerformed (java.awt.event .ActionEvent evt)//GEN-FIRST:event_testMenuItemActionPerformed
{//GEN-HEADEREND:event_testMenuItemActionPerformed
// Add your handling code here:
if (this.lastSQL != null) {
dbBrowser browser = (dbBrowser)this.mother .open("databaseBrowser");
browser.inspect(this.lastSQL);
}
}//GEN-LAST:event_testMenuItemActionPerformed
private void elementComboBoxActionPerformed(java.awt.event.ActionEvent evt)//GEN FIRST:event_elementComboBoxActionPerformed
{//GEN-HEADEREND:event_elementComboBoxActionPerformed
// Add your handling code here:
showActiveElement();
}//GEN-LAST:event_elementComboBoxActionPerformed
private void formInternalFrameClosing(javax.swing.event .InternalFrameEvent evt)//GEN-FIRST:event_formInternalFrameClosing
{//GEN-HEADEREND:event_formInternalFrameClosing
// Add your handling code here:
mother.close(this.ID);
}//GEN-LAST:event_formInternalFrameClosing
// Variables declaration - do not modify//GEN -BEGIN:variables
private javax.swing .JPopupMenu sqlPopupMenu;
private javax.swing .JMenuItem testMenuItem;
private javax.swing .JSeparator jSeparator1;
private javax.swing .JMenuItem deleteMenuItem;
private javax.swing .JSplitPane theSplitPane;
private javax.swing .JPanel upperPanel;
private javax.swing .JScrollPane jScrollPane1;
private javax.swing .JList sqlList;
private javax.swing .JPanel lowerPanel;
private javax.swing .JScrollPane jScrollPane2;
private javax.swing .JList tableList ;
private javax.swing .JPanel jPanel1;
private javax.swing .JComboBox elementComboBox ;
private javax.swing .JPanel jPanel2;
private javax.swing .JButton addButton;
private javax.swing .JButton jButton1;
// End of variables declaration//GEN-END:variables
/**
* Shows the db-entries for the active Element
*/
private void showActiveE lement () {
if (this.getActiveElement() != null) {
sqlList.setEnabled(false);
this.updateTables(new Vector());
sqlList.setListData(this.getActiveElement().getSQLStatements());
sqlList.setEnabled(true);
sqlList.repaint();
}
}
/**
* Returns the currently selected dbItem
*/
synchronized private SchemaElement getActiveElement() {
return (SchemaElement)elementComboBox.getSelectedItem();
}
/**
* Gets the new data and fills the lists
*/
synchronized public void updateView (SchemaElement el) {
mother.mappingState = true;
this.currentElement = el;
//build element comboBox
elementComboBox .setVisible (false);
elementComboBox .removeAllItems();
int counter = 0;
int selected = -1;
for (Enumeration e = el.getParents().elements(); e.hasMoreElements ();) {
SchemaElement curr_el = (SchemaElement)e.nextElement ();
//determine the selected element by comparing the ids
if (curr_el.getID().equalsIgnoreCase(el.getID())) {
selected = counter ;
}
elementComboBox.addItem(curr_el);
counter++;
}
if (selected > 0) {
elementComboBox.setSelectedIndex (selected);
}
if (counter <= 0) {
//elementComboBox.setEnabled(false);
sqlList.setEnabled(false);
tableList.setEnabled(false);
Autor: Thomas Schädler
223
Anhang A: Quelltext <xmlizer> configurator
}
else {
//elementComboBox.setEnabled(true);
sqlList.setEnabled(true);
tableList.setEnabled(true);
}
elementComboBox .setVisible (true);
setTitleElementName(el.getRealName());
elementComboBox .repaint();
}
/**
* Gets the new data and fills the lists
*/
synchronized private void updateTables(Vector tab) {
tableList.setEnabled (false );
tableList.setListData(tab);
tableList.setEnabled (true);
tableList.repaint();
}
/**
* This method updates the UI if the setupwindow is closed
* (and a change in the setup component occured)
*/
public synchronized void update(configurator conf) {
isLoading = true;
this.mother = conf;
isLoading = false;
}
/**
* A draggabel List of SQLStatements
* -> sends a SQLStatment.id (as String)
*/
class DNDListSQL extends JList implements DragSourceListener, DragGestureListener {
DragSource dragSource = null;
/**constructor - initializes the DragSource */
public DNDListSQL() {
dragSource = new DragSource ();
dragSource.createDefaultDragGestureRecogni zer(this,DnDConstants.ACTION_COPY,this);
}
/** a drag gesture has been initiated */
public void dragGestureRecognized(DragGestureEvent event ) {
//System.out.println("START > dragGestureRecognized");
SQLStatement selected = (SQLStatement )getSelectedValue();
if (selected != null) {
StringSelection text = new StringSelection(selected.getID());
// as the name suggests, starts the dragging
dragSource.startDrag(event,DragSource.DefaultMoveDrop ,text,this);
}
}
//REST UNUSED
/**this message goes to DragSourceListener, informing it that the dragging has ended */
public void dragDropEnd(DragSourceDropEvent event)
{ /*System.out.println("START > dragDropEnd");*/ }
/** this message goes to DragSourceListener, informing it that the dragging has entered the DropSite */
public void dragEnter(DragSourceDragEvent event)
{ /*System.out.println("START > dragEnter");*/ }
/** this message goes to DragSourceListener, informing it that the dragging has exited the DropSite */
public void dragExit (DragSourceEvent event)
{ /*System.out.println("START > dragExit");*/ }
/**this message goes to DragSourceListener, informing it that the dragging is currently ocurring over the DropSite */
public void dragOver (DragSourceDragEvent event )
{ /*System.out.println("START > dragOver");*/ }
/** is invoked when the user changes the dropAction */
public void dropActionChanged(DragSourceDragEvent event)
{ /*System.out.println("START > dragActionChanged");*/ }
}
/**
* A draggable list of Columninfos
* -> Sends a String-Combination of ColumnInfo.getID:ColumnInfo.getName (as String)
*/
class DNDListInfo extends JList implements DragSourceListener, DragGestureListener {
DragSource dragSource = null;
/**constructor - initializes the DragSource */
public DNDListInfo() {
dragSource = new DragSource ();
dragSource.createDefaultDragGestureRecognizer(this,DnDConstants.ACTION_COPY,this);
}
/** a drag gesture has been initiated */
public void dragGestureRecognized(DragGestureEvent event ) {
//System.out.println("START > dragGestureRecognized");
ColumnInfo selected = (ColumnInfo)getSelectedValue();
if (selected != null) {
StringSelection text = new StringSelection(selected.getID() + ":" + selected.getName ());
// as the name suggests, starts the dragging
dragSource.startDrag(event,DragSource.DefaultMoveDrop ,text,this);
}
}
//REST UNUSED
/**this message goes to DragSourceListener, informing it that the dragging has ended */
public void dragDropEnd(DragSourceDropEvent event)
{ /*System.out.println("START > dragDropEnd");*/ }
/** this message goes to DragSourceListener, informing it that the dragging has entered the DropSite */
public void dragEnter(DragSourceDragEvent event)
{ /*System.out.println("START > dragEnter");*/ }
/** this message goes to DragSourceListener, informing it that the dragging has exited the DropSite */
public void dragExit (DragSourceEvent event)
Autor: Thomas Schädler
224
Anhang A: Quelltext <xmlizer> configurator
{ /*System.out.println("START > dragExit");*/ }
/**this message goes to DragSourceListener, informing it that the dragging is currently ocurring over the DropSite */
public void dragOver (DragSourceDragEvent event )
{ /*System.out.println("START > dragOver");*/ }
/** is invoked when the user changes the dropAction */
public void dropActionChanged(DragSourceDragEvent event)
{ /*System.out.println("START > dragActionChanged");*/ }
}
}/*
* SchemaElementPanel.java
*
* This class representates a Schema Element Panel for showing its content
*
* Created on 20. Juli 2002, 10:22
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import
import
import
import
import
import
java.awt.*;
java.util.*;
javax.swing .*;
java.awt.dnd.*;
java.awt.event.*;
java.awt.datatransfer .*;
/**
* The panel for the SchemaElement (used to drop queries here from the SQLChooser)
* @author [email protected]
*/
public class SchemaElementPanel extends javax.swing.JPanel {
private configurator mother;
private SchemaElement element;
private Vector attLabels = new Vector();
private DNDLabelRep dndl ;
private DNDLabelCont clab;
/** Creates new form SchemaElementPanel */
public SchemaElementPanel(configurator config ,SchemaElement element) {
this.mother = config ;
this.element = element;
initComponents();
fillPanel();
checkDropEnables();
}
private void fillPanel() {
//set the elements name
elementLabel.setText(this.element.getRealName());
String temp_srr = this.element.getType();
if (temp_srr == null || temp_srr.equalsIgnoreCase("")) {
typeLabel.setText("anonymous");
}
else typeLabel.setText(temp_srr );
//set the repetition
//add a droptarget for controlling how many (SQL to iterate over)
//only if occurrence is good for that (more than one element allowed!
repPanel.setLayout(new java.awt.GridLayout(1,3));
String temp_str = this.element.getOccurrence().getShortOcc();
repPanel.add(new JLabel(temp_str));
StringBuffer temp_rep = new StringBuffer();
if (this.element.getRepetition() != null) {
temp_rep.append(this.element.getRepetition ());
}
dndl = new DNDLabelRep(this,temp_rep .toString(),this.element,mother);
repPanel.add(dndl);
JButton tempbutt1 = new RepButton(this.element,dndl);
tempbutt1.setIcon(new javax.swing.ImageIcon(getClass().getResource ("/configurator/icons/Delete16.gif")));
tempbutt1.addActionListener(new java.awt.event .ActionListener () {
public void actionPerformed (java.awt.event .ActionEvent evt) {
repdelButtonActionPerformed(evt);
}
});
repPanel.add(tempbutt1);
//set the content
contentPanel.setLayout(new java.awt.GridLayout (1,3));
if (this.element.hasContent()) {
SchemaContent cont = this.element.getContent();
String temp_str1 = this.element.getType();
contentPanel.add(new JLabel (temp_str1 ));
StringBuffer cbuff = new StringBuffer ();
if (cont.getMapID() != null) {
cbuff.append (cont.getMapID());
if (cont.getMapInfo() != null) {
Autor: Thomas Schädler
225
Anhang A: Quelltext <xmlizer> configurator
cbuff.append(":" + cont.getMapInfo ());
}
}
clab = new DNDLabelCont(cbuff.toString(),cont,mother ,this.element);
//System.out.println("ADDED cont: " + cont.toString());
contentPanel.add(clab);
JButton ctempbutt = new ContButton(cont,clab);
ctempbutt.setIcon(new javax .swing.ImageIcon(getClass ().getResource("/configurator/icons/Delete16.gif")));
ctempbutt.addActionListener (new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt ) {
contdelButtonActionPerformed(evt);
}
});
contentPanel.add(ctempbutt);
}
else {
contentPanel.add(new JLabel ("Has no text." ));
}
//set the attributes
int numrows = //calculate the number of used rows to display all data
+ this.element.getAttributes().size()
+ 0 //additional output
;
attributePanel.setLayout(new java.awt.GridLayout(numrows,4));
for (Enumeration e = this.element.getAttributes().elements(); e.hasMoreElements();) {
SchemaAttribute att = (SchemaAttribute)e.nextElement ();
//JLabel temp_lab = new JLabel("Attribute:");
//temp_lab.setForeground(java.awt.Color.darkGray);
//attributePanel.add(temp_lab);
attrib utePanel.add(new JLabel(att.getName()));
attributePanel.add(new JLabel(att.getUse()));
StringBuffer dndtext = new StringBuffer();
SQLStatement usedsql = mother.getProjectData().DB2XMLgetmapping().getSQLState mentByMapID (att.getMapID());
if (usedsql != null) {
//FIXME
//usedsql.getDB()
//usedsql.getSQL()
StringBuffer buff = new StringBuffer(att.getMapID());
if (att.getMapInfo () != null) {
buff.append(":" + att.getMapInfo());
}
dndtext.append(buff.toString ());
}
DNDLabelAtt lab = new DNDLabelAtt(dndtext.toString(),att,mother,this.element);
this.attLabels.add(lab);
//System.out.println("ADDED attr: " + lab.toString());
attributePanel.add(lab);
JButton tempbutt = new AttButton (att,lab);
tempbutt.setIcon(new javax.swing .ImageIcon (getClass().getResource("/configurator/icons/Delete16.gif")));
tempbutt.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt ) {
deleteButtonActionP erformed(evt);
}
});
attributePanel.add(tempbutt );
}
}
/**
* enable the drop for the content and attributes
* only if the repetition-label is set!
*/
public void checkDropEnables() {
if (this.dndl != null) {
String id = this.dndl.getID ();
if (id != null && !id.equalsIgnoreCase(new String())) {
if (clab != null) { clab.setEnabled(true); }
setAttributesDroppable(true);
}
else if (this.element.getOccurrence().getMinOccurs().intValue() > 0) {
if (clab != null) { clab.setEnabled(true); }
setAttributesDroppable(true);
}
else {
if (clab != null) { clab.setEnabled(false); }
setAttributesDroppable(false );
}
}
}
public void setAttributesDroppable(boolean bool) {
for (Enumeration e = this.getAttLabels().elements(); e.hasMoreElements();) {
DNDLabelAtt curat = (DNDLabelAtt )e.nextElement();
curat.setEnabled (bool);
}
}
class ContButton extends JButton {
private SchemaContent cont ;
private DNDLabelCont lab;
public ContButton(SchemaContent cont ,DNDLabelCont lab) {
this.cont = cont;
this.lab = lab;
//setSize(31,31);
}
public DNDLabelCont getDNDLabel () {
Autor: Thomas Schädler
226
Anhang A: Quelltext <xmlizer> configurator
return this.lab;
}
public SchemaContent getContent () {
return this.cont;
}
}
class RepButton extends JButton {
private SchemaElement elm;
private DNDLabelRep lab;
public RepButton(SchemaElement elm,DNDLabelRep lab) {
this.elm = elm;
this.lab = lab;
//setSize(31,31);
}
public DNDLabelRep getDNDLabel() {
return this.lab;
}
public SchemaElement getElement () {
return this.elm;
}
}
class AttButton extends JButton {
private SchemaAttribute att;
private DNDLabelAtt lab;
public AttButton(SchemaAttribute att ,DNDLabelAtt lab) {
this.att = att;
this.lab = lab;
//setSize(31,31);
}
public DNDLabelAtt getDNDLabel() {
return this.lab;
}
public SchemaAttribute getAttribute() {
return this.att;
}
}
/** handels the delete action for the attlabels */
private void deleteButtonActionPerformed (java.awt.event .ActionEvent evt) {
AttButton but = (AttButton )evt.getSource();
SchemaAttribute att = but.getAttribu te();
DNDLabelAtt lab = but.getDNDLabel();
att.cleanMapping();
lab.setText("");
lab.setToolTipText("");
checkDropEnables();
mother.getProjectData().setDirty();
}
/** handels the delete action for the content*/
private void contdelButtonActionPerformed(java.awt.event.ActionEvent evt) {
ContButton but = (ContButton)evt.getSource();
SchemaContent cont = but.getContent();
DNDLabelCont lab = but.getDNDLabel();
cont.cleanMapping();
lab.setText("");
lab.setToolTipText("");
checkDropEnables();
this.repaint();
mother.getProjectData().setDirty();
}
/** handels the delete action for the repetition -> sideeffect-clearing of dependencies */
private void repdelButtonActionPerformed (java.awt.event .ActionEvent evt) {
RepButton but = (RepButton )evt.getSource();
SchemaElement elm = but.getElement();
DNDLabelRep lab = but.getDNDLabel();
SQLStatement oldStat = elm.getRepetitionStatement();
if (oldStat != null) {
mother .getProjectData().cleanSchemaElementDataDependencies(oldStat);
updateAttributeLabels();
}
elm.setRepetition(null);
lab.setText("");
lab.setToolTipText("");
checkDropEnables();
this.repaint();
mother.getProjectData().setDirty();
}
public void updateAttributeLabels() {
if (clab != null) { clab.setToolTipText(""); clab.setText(""); }
for (Enumeration e = this.getAttLabels().elements(); e.hasMoreElements();) {
DNDLabelAtt curat = (DNDLabelAtt )e.nextElement();
curat.setText("");
curat.setToolTipText("");
curat.repaint();
}
}
public void updateAttributeLabels(String id) {
//System.out.println("LABELS: " + this.getAttLabels());
for (Enumeration e = this.getAttLabels().elements(); e.hasMoreElements();) {
DNDLabelAtt curat = (DNDLabelAtt )e.nextElement();
//System.out.print(">>> " + curat.getText());
Autor: Thomas Schädler
227
Anhang A: Quelltext <xmlizer> configurator
if (curat.getID().equalsIgnoreCase(id)) {
curat.setText("");
curat.setToolTipText("");
curat.repaint();
//System.out.print(" deleted!");
}
//System.out.print(curat.getID() + "\n");
}
}
public void updateAttributeLabels(SQLStatement st) {
updateAttributeLabels(st.getID());
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
private void initComponents()//GEN-BEGIN:initCompo nents
{
mainPanel = new javax.swing.JPanel();
infoPanel = new javax.swing.JPanel();
fixedLabel1 = new javax.swing.JLabel ();
elementLabel = new javax.swing.JLabel();
fixedLabel2 = new javax.swing.JLabel ();
typeLabel = new javax.swing.JLabel();
repPanel = new javax .swing .JPanel();
contentPanel = new javax.swing.JPanel();
attributePanel = new javax .swing.JPanel();
setLayout(new java.awt.BorderLayout());
setBorder(new javax.swing.border.TitledBorder("Element information:"));
mainPanel.setLayout(new javax.swing.BoxLayout(mainPanel, javax.swing.BoxLayout.Y_AXIS));
mainPanel.setMinimumSize(new java.awt.Dimension(0, 0));
infoPanel.setLayout(new java.awt.GridLayout(2, 2, 1, 1));
infoPanel.setMinimumSize(new java.awt.Dimension(0, 0));
fixedLabel1.setText("Element name:");
fixedLabel1.setForeground(java.awt.Color.darkGray);
infoPanel.add(fixedLabel1);
elementLabel.setText("<element>");
infoPanel.add(elementLabel );
fixedLabel2.setText("Element type:");
fixedLabel2.setForeground(java.awt.Color.darkGray);
infoPanel.add(fixedLabel2);
typeLabel.setText("<type>" );
infoPanel.add(typeLabel);
mainPanel.add(infoPanel);
repPanel.setLayout(null);
repPanel.setBorder(new javax.swing.border .TitledBorder("Repetition:"));
mainPanel.add(repPanel);
contentPanel.setLayout(null);
contentPanel.setBorder(new javax.swing.border.TitledBorder("Content:"));
mainPanel.add(contentPanel );
attributePanel.setLayout(null);
attributePanel.setBorder(new javax.swing.border.TitledBorder("Attributes:"));
mainPanel.add(attributePanel);
add(mainPanel, java.awt.BorderLayout .CENTER);
}//GEN-END:initComponents
// Variables declaration - do not modify//GEN -BEGIN:variables
private javax.swing .JPanel mainPanel;
private javax.swing .JPanel infoPanel;
private javax.swing .JLabel fixedLabel1;
private javax.swing .JLabel elementLabel;
private javax.swing .JLabel fixedLabel2;
private javax.swing .JLabel typeLabel;
private javax.swing .JPanel repPanel ;
private javax.swing .JPanel contentPanel;
private javax.swing .JPanel attributePanel;
// End of variables declaration//GEN-END:variables
public Vector getAttLabels() {
return this.attLabels;
}
/**
* Drop-Enabled Label for the Repetition (Occurrence)
*/
class DNDLabelRep extends JLabel implements DropTargetListener {
private SchemaElement element;
private configurator mother;
private SchemaElementPanel panel;
// Constructor
public DNDLabelRep() {
super();
// create a drop target for this component
DropTarget dt = new DropTarget(this, this);
Autor: Thomas Schädler
228
Anhang A: Quelltext <xmlizer> configurator
this.setForeground(java.awt.Color.red);
this.setBorder(new javax.swing.border .LineBorder(java.awt.Color.red));
}
public DNDLabelRep(SchemaElementPanel parent,String text ,SchemaElement elem,confi gurator conf) {
super(text);
this.setToolTipText(text);
this.mother = conf;
this.element = elem;
this.panel = parent;
// create a drop target for this component
DropTarget dt = new DropTarget(this, this);
this.setForeground(java.awt.Color.red);
//System.out.println(attLabels);
this.setBorder(new javax.swing.border .LineBorder(java.awt.Color.red));
}
public String getID() {
return this.getText();
}
/** Returns true if the string contains NO : */
private boolean isValidData(String s ) {
int doublepoint = s.indexOf(":");
if (doublepoint < 0) {
return true;
}
else return false;
}
// DropTargetListener interface implementation
public void drop(DropTargetDropEvent event) {
/*System.out.println("END > drop");*/
try {
Transferable transferable = event .getTransferable();
// we accept only Strings
if (transferable.isDataFlavorSupported (DataFlavor.stringFlavor)) {
event.acceptDrop(DnDConstants .ACTION_COPY);
String s = (String)transferable.getTransferData(DataFlavor.stringFlavor);
//do the thing with the key: mapid:mapinfo
//System.out.println("DROP >>>>>" + s);
if (s != null && mother.mappingState && isValidData(s)) {
setText(s);
setToolTipText(s);
SQLStatement oldStat = this.element.getRepetitionStatement();
if (oldStat != null) {
mother .getProjectData ().cleanSchemaElementDataDependencies(oldStat);
}
this.element.setRepetition(s);
mother.getProjectData().setDirty();
this.panel .updateAttributeLabels();
this.panel .checkDropEnables();
this.repaint();
}
else if(!mother.mappingState) {
mother.getLog().addWarning("You cannot drop queries to the Mapping in Database-Mode!");
}
event.getDropTargetContext().dropComplete(true);
}
else {
event.rejectDrop();
}
}
catch (java.io.IOException exception) {
System.err.println ( "Exception" + exception .getMessage());
event.rejectDrop();
}
catch (UnsupportedFlavorException ufException ) {
System.err.println ( "Exception" + ufException.getMessage());
event.rejectDrop();
}
}
//REST UNUSED
public void dragEnter(DropTargetDragEvent dtde )
{ /*System.out.println("END > dragEnter");*/ }
public void dragExit (DropTargetEvent dte)
{ /*System.out.println("END > dragExit");*/ }
public void dragOver (DropTargetDragEvent dtde)
{ /*System.out.println("END > dragOver");*/ }
public void dropActionChanged(DropTargetDragEvent dtde)
{ /*System.out.println("END > dropActionChanged");*/ }
}
/**
* Drop-Enabled Label for the Content
*/
class DNDLabelCont extends JLabel implements DropTargetListener {
private SchemaContent content;
private configurator mother;
private SchemaElement element;
// Constructor
public DNDLabelCont() {
super();
// create a drop target for this component
DropTarget dt = new DropTarget(this, this);
this.setForeground(new java.awt.Color (33,86,130));
this.setBorder(new javax.swing.border .LineBorder(new java.awt.Color (33,86,130)));
}
public DNDLabelCont(String text ,SchemaContent cont,configurator conf,SchemaElement el) {
super(text);
this.setToolTipText(text);
this.mother = conf;
this.content = cont;
Autor: Thomas Schädler
229
Anhang A: Quelltext <xmlizer> configurator
this.element = el;
// create a drop target for this component
DropTarget dt = new DropTarget(this, this);
this.setForeground(new java.awt.Color (33,86,130));
this.setBorder(new javax.swing.border .LineBorder(new java.awt.Color (33,86,130)));
}
public String getID() {
if (!this.getText().equalsIgnoreCase(new String ())) {
return getFirst(this.getText());
} else return "";
}
/** Returns xxx from xxx:yyy */
private String getFirst(String s) {
int doublepoint = s.indexOf(":");
if (doublepoint != 0) {
return s.substring (0,doublepoint);
}
else return s;
}
/** Returns yyy from xxx:yyy */
private String getSecond(String s) {
int doublepoint = s.indexOf(":");
if (doublepoint != 0) {
return s.substring (++doublepoint);
}
else return s;
}
/** Returns true if the string contains a : */
private boolean isValidData(String s ) {
int doublepoint = s.indexOf(":");
if (doublepoint < 0) {
return false ;
}
else return true;
}
/**
* Returns true if this statement is not the repetition statement
**/
private boolean isNotRepStat(String s) {
if (this.element.getRepetition() != null) {
if (this.element.getRepetition().equalsIgnoreCase(s)) {
return false;
}
}
return true;
}
// DropTargetListener interface implementation
public void drop(DropTargetDropEvent event) {
/*System.out.println("END > drop");*/
try {
Transferable transferable = event .getTransferable();
// we accept only Strings
if (transferable.isDataFlavorSupported (DataFlavor.stringFlavor)) {
event.acceptDrop(DnDConstants .ACTION_COPY);
String s = (String)transferable.getTransferData(DataFlavor.stringFlavor);
//do the thing with the key: mapid:mapinfo
//System.out.println("DROP >>>>>" + s);
if (s != null && mother.mappingState && isValidData(s) && isNotRepStat(s)) {
String mapid = getFirst(s);
String mapinfo = getSecond(s);
if (mapid != null && mapinfo != null && isEnabled()) {
content.setMapID (mapid);
content.setMapInfo(mapinfo);
setText(mapid + ":" + mapinfo);
setToolTipText(mapid + ":" + mapinfo);
mother .getProjectData ().setDirty();
}
}
else if (s != null && mother.mappingState && !isValidData(s) && isNotRepStat(s) && isEnabled()) //
{
//System.out.print(">>>" + s);
//dropped a SQLStatement with only one possible result
content.setMapID(s);
setText(s);
setToolTipText(s);
mother.getProjectData().setDirty();
}
else {
if(!mother .mappingState) {
mother .getLog().addWarning ("You cannot drop queries to the Mapping in Database-Mode!");
}
else if(!isNotRepStat(s)) {
mother .getLog().addWarning ("This SQL Query is already assigned to the repetition!" );
}
else {
mother .getLog().addWarning ("Assign a repetition SQL query before filling the content.");
}
}
event.getDropTargetContext().dropComplete(true);
}
else {
event.rejectDrop();
}
}
catch (java.io.IOException exception) {
System.err.println ( "Exception" + exception .getMessage());
event.rejectDrop();
}
catch (UnsupportedFlavorException ufException ) {
Autor: Thomas Schädler
230
Anhang A: Quelltext <xmlizer> configurator
System.err.println ( "Exception" + ufException.getMessage());
event.rejectDrop();
}
}
//REST UNUSED
public void dragEnter(DropTargetDragEvent dtde )
{ /*System.out.println("END > dragEnter");*/ }
public void dragExit (DropTargetEvent dte)
{ /*System.out.println("END > dragExit");*/ }
public void dragOver (DropTarget DragEvent dtde)
{ /*System.out.println("END > dragOver");*/ }
public void dropActionChanged(DropTargetDragEvent dtde)
{ /*System.out.println("END > dropActionChanged");*/ }
}
/**
* Drop-Enabled Label for Attributes
*/
class DNDLabelAtt extends JLabel implements DropTargetListener {
private SchemaAttribute attribute;
private configurator mother;
private SchemaElement element;
// Constructor
public DNDLabelAtt() {
super();
// create a drop target for this component
DropTarget dt = new DropTarget(this, this);
this.setForeground(java.awt.Color.blue);
this.setBorder(new javax.swing.border .LineBorder(java.awt.Color.blue));
}
public DNDLabelAtt(String text,SchemaAttribute attr ,configurator conf,SchemaElement el ) {
super(text);
this.setToolTipText(text);
this.mother = conf;
this.attribute = attr;
this.element = el;
// create a drop target for this component
DropTarget dt = new DropTarget(this, this);
this.setForeground(java.awt.Color.blue);
this.setBorder(new javax.swing.border .LineBorder(java.awt.Color.blue));
}
public String getID() {
if (!this.getText().equalsIgnoreCase(new String ())) {
return getFirst(this.getText());
} else return "";
}
/** Returns xxx from xxx:yyy */
private String getFirst(String s) {
int doublepoint = s.indexOf(":");
if (doublepoint != 0) {
return s.substring (0,doublepoint);
}
else return s;
}
/** Returns yyy from xxx:yyy */
private String getSecond(String s) {
int doublepoint = s.indexOf(":");
if (doublepoint != 0) {
return s.substring (++doublepoint);
}
else return s;
}
/** Returns true if the string contains a : */
private boolean isValidData(String s ) {
int doublepoint = s.indexOf(":");
if (doublepoint < 0) {
return false ;
}
else return true;
}
/**
* Returns true if this statement is not the repetition statement
**/
private boolean isNotRepStat(String s) {
if (this.element.getRepetition() != null) {
if (this.element.getRepetition().equalsIgnoreCase(s)) {
return false;
}
}
return true;
}
// DropTargetListener interface implementation
public void drop(DropTargetDropEvent event) {
/*System.out.println("END > drop");*/
try {
Transferable transferable = event .getTransferable();
// we accept only Strings
if (transferable.isData FlavorSupported (DataFlavor.stringFlavor)) {
event.acceptDrop(DnDConstants .ACTION_COPY);
String s = (String)transferable.getTransferData(DataFlavor.stringFlavor);
//do the thing with the key: mapid :mapinfo
//System.out.println("DROP >>>>>" + s);
if (s != null && mother.mappingState && isValidData(s) && isNotRepStat(s)) {
String mapid = getFirst(s);
String mapinfo = getSecond(s);
if (mapid != null && mapinfo != null && isEnabled()) {
attribute.setMapID(mapid);
Autor: Thomas Schädler
231
Anhang A: Quelltext <xmlizer> configurator
attribute.setMapInfo(mapinfo);
setText(mapid + ":" + mapinfo);
setToolTipText(mapid + ":" + mapinfo);
mother .getProjectData ().setDirty();
}
}
else if (s != null && mother.mappingState && !isValidData(s) && isNotRepStat(s) && isEnabled()) //
{
//System.out.print(">>>" + s);
//dropped a SQLStatement with only one possible result
attribute.setMapID(s);
setText(s);
setToolTipText(s);
mother.getProjectData().setDirty();
}
else {
if(!mother .mappingState) {
mother .getLog().addWarning ("You cannot drop queries to the Mapping in Database-Mode!");
}
else if(!isNotRepStat(s)) {
mother .getLog().addWarning ("This SQL Query is already assigned to the repetition!" );
}
else {
mother .getLog().addWarning ("Assign a repetition SQL query before filling the attributes.");
}
}
event.getDropTargetContext().dropComplete(true);
}
else {
event.rejectDrop();
}
}
catch (java.io.IOException exception) {
System.err.println ( "Exception" + exception .getMessage());
event.rejectDrop();
}
catch (UnsupportedFlavorException ufException ) {
System.err.println ( "Exception" + ufException.getMessage());
event.rejectDrop();
}
}
//REST UNUSED
public void dragEnter(DropTargetDragEvent dtde )
{ /*System.out.println("END > dragEnter");*/ }
public void dragExit (DropTargetEvent dte)
{ /*System.out.println("END > dragExit");*/ }
public void dragOver (DropTargetDragEvent dtde)
{ /*System.out.println("END > dragOver");*/ }
public void dropActionChanged(DropTargetDragEvent dtde)
{ /*System.out.println("END > dropActionChanged");*/ }
}
}/*
* ColumnInfo.java
*
* Created on 25. Juli 2002, 02:47
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
/**
* Represents the information neccessary to show a columninfo (from the db)
* @author [email protected]
*/
class ColumnInfo {
protected String id ;
protected String name;
protected String type;
public ColumnInfo(String id,String name,String type) {
this.id = id;
this.name = name;
this.type = type;
}
public String getID () {
return this.id;
}
public String getName() {
return this.name;
}
public String getType() {
return this.type;
}
public String toString() {
return this.name + " [" + this.type + "]";
}
Autor: Thomas Schädler
232
Anhang A: Quelltext <xmlizer> configurator
}/*
* DataChooser.java
*
* Created on 30. Juli 2002, 11:03
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import
import
import
import
import
import
java.awt.*;
java.util.*;
javax.swing .*;
java.awt.dnd.*;
java.awt.event.*;
java.awt.datatransfer .*;
/**
* Represents the DataChooser (used to drop dependencies to the databaseBrowser
* @author [email protected]
*/
public class DataChooser extends MyInternalFrame {
private configurator mother;
private String ID;
private
private
private
private
boolean isLoading = true;
String title = new String();
SchemaElement currentElement = null;
Vector params = new Vector();
/** Creates new form SQLChooser */
public DataChooser(configurator mainProgram,String uid) {
this.mother = mainProgram;
this.ID = uid;
initComponents();
setClosable(false);
theSplitPane.setDividerLocation (150);
theSecondSplitPane.setDividerLocation(250);
//make the list functional
sqlList.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
tableList.getSelectionModel().setSelectionMode (ListSelectionModel.SINGLE_SELECTION);
paramList.getSelectionModel().setSelectionMode (ListSelectionM odel.SINGLE_SELECTION);
//add the ParameterInfos to the params-vector
Hashtable paraHash = mother.getProjectData().DB2XMLgetmapping ().getParameters();
for (Enumeration e = paraHash.elements(); e.hasMoreElements();) {
ParameterInfo item = (ParameterInfo)e.nextElement();
this.params .add(item);
}
paramList.setListData(this.params);
//add the mouselistener
ItemListener ilst = new ItemListener (this);
sqlList.addMouseListener(ilst);
this.setTitleElementName("");
}
/** Returns this windows uniqueID */
public String getWinID() {
return this.ID;
}
/**
* Listens for listItem-(Mouse)-Events on the dbtableList
* -> For database queries
*/
class ItemListener implements java.awt.event.MouseListener {
protected DataChooser m_parent;
protected JList m_list;
public ItemListener(DataChooser parent) {
m_parent = parent;
m_list = parent.sqlList;
}
public void mouseClicked(java.awt.event.MouseEvent e) {
doAction();
}
public
public
public
public
void
void
void
void
mousePressed(java.awt.event.MouseEvent e){}
mouseReleased(java.awt.event.MouseEvent e){}
mouseEntered(java.awt.event.MouseEvent e){}
mouseExited(java.awt.event.MouseEvent e ){}
protected void doAction() {
int index = m_list.getSelectedIndex();
if (index < 0) {
return;
}
Autor: Thomas Schädler
233
Anhang A: Quelltext <xmlizer> configurator
if (m_list.getModel().getSize() > index) {
SQLStatement data = (SQLStatement )m_list.getModel().getElementAt(index);
if (data != null) {
m_parent .updateTables(data.getColsAsSQLColumnInfo ());
}
}
}
}
private void setTitleElementName(String name) {
StringBuffer buff = new StringBuffer ("Data Chooser" );
if (name != null) {
buff.append (" @ " + name);
this.setTitle(buff.toString ());
}
this.repaint();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
private void initComponents() {
theSplitPane = new javax.swing.JSplitPane ();
upperPanel = new javax.swing.JPanel();
jScrollPane1 = new javax.swing.JScrollPane();
sqlList = new JList();
lowerPanel = new javax.swing.JPanel();
jScrollPane2 = new javax.swing.JScrollPane();
tableList = new DNDListInfo();
jPanel1 = new javax.swing.JPanel();
elementComboBox = new javax.swing.JComboBox();
jButton1 = new javax .swing .JButton();
paramList = new DNDListParam();
theSecondSplitPane = new JSplitPane();
paramPanel = new JPanel();
paramScrollPane = new javax.swing.JScrollPane();
setMaximizable(true);
setTitle("Data Chooser");
setIconifiable(true);
setResizable(true);
setClosable(true);
setPreferredSize(new java.awt.Dimension(300, 400));
addInternalFrameListener(new javax.swing.event .InternalFrameListener() {
public void internalFrameOpened(javax .swing.event.InternalFrameEvent evt ) {
}
public void internalFrameClosing (javax.swing.event.InternalFrameEvent evt) {
formInternalFrameClosing(evt);
}
public void internalFrameClosed(javax .swing.event.InternalFrameEvent evt ) {
}
public void internalFrameIconified(javax.swing.event .InternalFrameEvent evt) {
}
public void internalFrameDeiconified(javax .swing.event.InternalFrameEvent evt ) {
}
public void internalFrameActivated(javax.swing.event .InternalFrameEvent evt) {
}
public void internalFrameDeactivated(javax .swing.event.InternalFrameEvent evt ) {
}
});
theSecondSplitPane.setOrientation(javax.swing.JSplitPane .VERTICAL_SPLIT );
theSecondSplitPane.setOneTouchExpandable(true);
paramPanel .setLayout (new java.awt.BorderLayout ());
paramList.setBorder(new javax.swing.border.TitledBorder(null, "Global Parameters:", javax.swing.border.TitledBorder.LEFT, javax.swing.border .TitledBorder.DEFAULT_POSITION ));
paramScrollPane .setViewportView(paramList );
paramPanel .add(paramScrollPane, java.awt.BorderLayout.CENTER);
theSecondSplitPane.setLeftComponent(theSplitPane);
theSecondSplitPane.setRightComponent (paramPanel);
theSplitPane.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
theSplitPane.setOneTouchExpandable(true);
upperPanel .setLayout (new java.awt.BorderLayout ());
sqlList.setBorder(new javax.swing.border.TitledBorder(null, "SQL Repetition Queries:", javax.swing.border.TitledBorder.LEFT, javax.swing.border .TitledBorder.DEFAULT_POSITION ));
jScrollPane1.setViewportView(sqlList);
upperPanel .add(jScrollPane1, java.awt.BorderLayout.CENTER);
theSplitPane.setLeftComponent(upperPanel);
lowerPanel .setLayout (new java.awt.BorderLayout ());
tableList.setBorder(new javax.swing.border.TitledBorder(null, "Result Table Columns of selected Query:", javax.swing.border.TitledBorder.LEFT, javax.swing.border .TitledBorder.DEFAULT_POSITION ));
jScrollPane2.setViewportView(tableList);
lowerPanel .add(jScrollPane2, java.awt.BorderLayout.CENTER);
theSplitPane.setRightComponent(lowerPanel );
getContentPane().add(theSecondSplitPane, java.awt.BorderLayout.CENTER);
jPanel1.setLayout(new java.awt.BorderLayout());
elementComboBox .addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
elementComboBoxActionPerformed(evt);
}
});
Autor: Thomas Schädler
234
Anhang A: Quelltext <xmlizer> configurator
jPanel1.add(elementComboBox, java.awt.BorderLayout.CENTER);
jButton1.setIcon(new javax .swing.ImageIcon(getClass ().getResource("/configurator/icons/Help16.gif")));
jButton1.setToolTipText("Open Help");
jButton1.setFont(new java.awt.Font("Dialog", 0, 10));
jButton1.addActionListener (new java.awt.event.ActionListener() {
public void actionPerformed (java.awt.event .ActionEvent evt) {
jButton1ActionPerformed (evt);
}
});
jPanel1.add(jButton1 , java.awt.BorderLayout.EAST);
getContentPane().add(jPanel1, java.awt.BorderLayout .NORTH);
pack();
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// Add your handling code here:
helpWindow help = (helpWindow)mother .open("help");
help.loadPage("/configurator/help/module_db2xml_datachooser.html");
}
private void elementComboBoxActionPerformed(java.awt.event.ActionEvent evt) {
// Add your handling code here:
showActiveElement();
}
synchronized private void formInternalFrameClosing (javax.swing.event.InternalFrameEvent evt) {
// Add your handling code here:
mother.close(this.ID);
}
// Variables declaration - do not modify
private javax.swing .JSplitPane theSplitPane;
private javax.swing .JPanel upperPanel;
private javax.swing .JScrollPane jScrollPane1;
private javax.swing .JList sqlList;
private javax.swing .JPanel lowerPanel;
private javax.swing .JScrollPane jScrollPane2;
private javax.swing .JList tableList ;
private javax.swing.JPanel jPanel1;
private javax.swing .JComboBox elementComboBox ;
private javax.swing .JButton jButton1;
private JList paramList;
private JSplitPane theSecondSplitPane;
private JPanel paramPanel;
private JScrollPane paramScrollPane ;
// End of variables declaration
/**
* Shows the db-entries for the active Element
*/
private void showActiveElement () {
if (this.getActiveElement() != null) {
sqlList.setEnabled(false);
this.updateTables(new Vector());
Vector temp_vec = new Vector();
temp_vec.add(this.getActiveElement().getRepetitionStatement());
sqlList.setListData(temp_vec);
sqlList.setEnabled(true);
sqlList.repaint();
}
}
/**
* Returns the currently selected dbItem
*/
private SchemaElement getActiveElement() {
return (SchemaElement)elementComboBox.getSelectedItem();
}
/**
* Gets the new data and fills the lists
*/
synchronized public void setSchemaElement(SchemaElement el) {
this.currentElement = el;
//build element comboBox
elementComboBox .setVisible (false);
elementComboBox .removeAllItems();
int counter = 0;
int selected = -1;
for (Enumeration e = el.getParents().elements(); e.hasMoreElements ();) {
SchemaElement curr_el = (SchemaElement)e.nextElement ();
if (curr_el.getID().equalsIgnoreCase(el.getID())) {
selected = counter ;
}
elementComboBox.addItem(curr_el);
counter++;
}
if (selected > 0) {
elementComboBox.setSelectedIndex (selected);
}
if (counter <= 0) {
//elementComboBox.setEnabled(false);
sqlList.setEnabled(false);
tableList.setEnabled(false);
}
else {
//elementComboBox.setEnabled(true);
Autor: Thomas Schädler
235
Anhang A: Quelltext <xmlizer> configurator
sqlList.setEnabled(true);
tableList.setEnabled(true);
}
elementComboBox .setVisible (true);
setTitleElementName(el.getRealName());
elementComboBox .repaint();
}
/**
* Gets the new data and fills the lists
*/
private void updateTables(Vector tab) {
tableList.setEnabled (false );
tableList.setListData(tab);
tableList.setEnabled (true);
tableList.repaint();
}
/**
* This method updates the UI if the setupwindow is closed
* (and a change in the setup component occured)
*/
public synchronized void update(configurator conf) {
isLoading = true;
this.mother = conf;
isLoading = false;
}
/**
* A draggable list of ParameterInfos
* -> Sends a String-Combination of ParameterInfo.getID:ParameterInfo.getName (as String)
*/
class DNDListParam extends JList implements DragSourceListener, DragGestureListener {
DragSource dragSource = null;
/**constructor - initializes the DragSource */
public DNDListParam() {
dragSource = new DragSource ();
dragSource.createDefaultDragGestureRecognizer(this,DnDConstants.ACTION_COPY,this);
}
/** a drag gesture has been initiated */
public void dragGestureRecognized(DragGestureEvent event ) {
//System.out.println("START > dragGestureRecognized");
ParameterInfo selected = (ParameterInfo)getSelectedValue();
if (selected != null) {
StringSelection text = new StringSelection("[-" + selected .getID() + ":" + selected.getName() + "-]");
// as the name suggests, starts the dragging
dragSource.startDrag(event,DragSource.DefaultMoveDrop ,text,this);
}
}
//REST UNUSED
/**this message goes to DragSourceListener, informing it that the dragging has ended */
public void dragDropEnd(DragSourceDropEvent event)
{ /*System.out.println("START > dragDropEnd");*/ }
/** this message goes to DragSourceListener, informing it that the dragging has entered the DropSite */
public void dragEnter(DragSourceDragEvent event)
{ /*System.out.println("START > dragEnter");*/ }
/** this message goes to DragSourceListener, informing it that the dragging has exited the DropSite */
public void dragExit (DragSourceEvent event)
{ /*System.out.println("START > dragExit");*/ }
/**this message goes to DragSourceListener, informing it that the dragging is currently ocurring over the DropSite */
public void dragOver (DragSourceDragEvent event )
{ /*System.out.println("START > dragOver");*/ }
/** is invoked when the user changes the dropAction */
public void dropActionChanged(DragSourceDragEvent event)
{ /*System.out.println("START > dragActionChanged");*/ }
}
/**
* A draggable list of SQLColumninfos
* -> Sends a String-Combination of SQLColumnInfo.getID:SQLColumnInfo.getName (as String)
*/
class DNDListInfo extends JList implements DragSourceListener, DragGestureListener {
DragSource dragSource = null;
/**constructor - initializes the DragSource */
public DNDListInfo() {
dragSource = new DragSource ();
dragSource.createDefaultDragGestureRecognizer(this,DnDConstants.ACTION_COPY,this);
}
/** a drag gesture has been initiated */
public void dragGestureRecognized(DragGestureEvent event) {
//System.out.println("START > dragGestureRecognized");
SQLColumnInfo selected = (SQLColumnInfo)getSelectedValue();
if (selected != null) {
StringSelection text = new StringSelection("[" + selected.getID () + ":" + selected.getName() + "]");
// as the name suggests, starts the dragging
dragSource.startDrag(event,DragSource.DefaultMoveDrop ,text,this);
}
}
//REST UNUSED
/**this message goes to DragSourceListener, informing it that the dragging has ended */
public void dragDropEnd(DragSourceDropEvent event)
{ /*System.out.println("START > dragDropEnd");*/ }
/** this message goes to DragSourceListener, informing it that the dragging has entered the DropSite */
public void dragEnter(DragSourceDragEvent event)
{ /*System.out.println("START > dragEnter");*/ }
/** this message goes to DragSourceListener, informing it that the dragging has exited the DropSite */
public void dragExit (DragSourceEvent event)
{ /*System.out.println("START > dragExit");*/ }
/**this message goes to DragSourceListener, informing it that the dragging is currently ocurring over the DropSite */
public void dragOver (DragSourceDragEvent event )
Autor: Thomas Schädler
236
Anhang A: Quelltext <xmlizer> configurator
{ /*System.out.println("START > dragOver");*/ }
/** is invoked when the user changes the dropAction */
public void dropActionChanged(DragSourceDragEvent event)
{ /*System .out.println("START > dragActionChanged");*/ }
}
}/*
* SchemaContent.java
*
* Created on 25. Juli 2002, 02:47
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import org.jdom.*;
import java.util.*;
import javax.swing .*;
/**
* Represents the content of a SchemaElement
* @author [email protected]
*/
class SchemaContent {
protected String id ; //element id
protected String mapid;
protected String mapinfo ;
public SchemaContent(){}
public SchemaContent(String id ) {
this.id = id;
}
public SchemaContent(String id ,String mapid,String mapinfo) {
this.id = id;
this.mapid = mapid;
this.mapinfo = mapinfo;
}
public String getElementID() {
return this.id;
}
public String getMapID() {
return this.mapid;
}
public String getMapInfo () {
return this.mapinfo;
}
/** Cleans the mapinfo of this content */
public void cleanMapping () {
this.mapid = null;
this.mapinfo = null;
//System.out.println(this.tname);
}
//SETTERS
public void setMapID(String id ) {
if (id != null) {
this.mapid = id;
}
}
public void setMapInfo(String info) {
if (info != null) {
this.mapinfo = info;
}
}
public String toString() {
return "<" + this.id + ">" + this.mapid + ":" + this.mapinfo + "</" + this.id + ">";
}
public Element getAsJDOMElement() {
Element curr = new Element ("db2xml_content");
if (this.mapid != null) {
curr.setAttribute("mapid",this.mapid);
}
if (this.mapinfo != null) {
curr.setAttribute("mapinfo" ,this.mapinfo);
}
//System.out.println("<" + this.id + ">" + this.mapid + ":" + this.mapinfo + "</" + this.id + ">");
return curr;
}
}
/*
* ParameterInfo.java
*
Autor: Thomas Schädler
237
Anhang A: Quelltext <xmlizer> configurator
* Created on 25. Juli 2002, 02:47
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer >; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package configurator;
import java.util.*;
import org.jdom.*;
/**
* Represents a ParameterInfo
* @author [email protected]
*/
class ParameterInfo {
protected String id ;
protected String name;
protected String value;
public ParameterInfo(String id ,String name,String value ) {
this.id = id;
this.name = name;
this.value = value;
}
public String getID () {
return this.id;
}
public String getName() {
return this.name;
}
public String getValue() {
return this.value;
}
public String toString() {
return this.name + " (" + this.value + ")";
}
public Element getAsJDOMElement() {
if (this.name == null || this.value == null)
//check for validity
{
return null;
}
else {
Element curr = new Element("db2xml_parameter");
curr.setAttribute("name",this.name);
curr.setAttribute("default" ,this.value);
return curr;
}
}
}
Autor: Thomas Schädler
238
Anhang B: Quelltext <xmlizer> server
Anhang B: Quelltext <xmlizer> server
/*
* Start.java
*
* Usage: server.start [options]
*
* Hints:
* - if there is no config file, it will be generated
* - if port,base or projects are specifed, the config file will be updated
* - to use a custom config file (multiple server), specify its name
* - command line arguments update the indicated configfile
*
* Options:
* -config <name>
Use custom xmlizer.server.config.<name>
* -port <portnumber>
Start the server on that port (default = 7777)
* -base <dir>
Directory where the server is running
* -projects <dir>
Directory where the projects are saved
* -webinterface on|off Switch on/off webinterface (default=on)
* -refresh on|off
Switch on/off continous directory scan (default=off)
* -help
Show this help screen
*
* Created on 1. August 2002, 18:59
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 G NU General Public License
* along with <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------* http://localhost:7777/htmlizer?project=Simple_Module_DB_Export&db=XML-DB
*/
package server;
import java.util.*;
import java.net.*;
import java.io.*;
/**
* Starts the server
* @author [email protected]
* @version 0.2
*/
public class Start extends Thread {
private static Vector requests ;
private ServerSocket serverSocket;
private boolean stop;
private int port = 7777;
public static final String VERSION = "0.7.1";
public StringBuffer configfilename = new StringBuffer(System .getProperty("user.home") + System.getProperty("file.separator") + "xmlizer.server.config" );
public String homebase = null;
public String projectbase = null;
private String web = "on";
private String refresh = "off" ;
private boolean saveConfig = false;
private boolean portSet = false;
private boolean baseSet = false;
private boolean webSet = false ;
private boolean projectSet = false;
private boolean nameSet = false;
private boolean refreshSet = false;
private String customname = null;
private Hashtable data = new Hashtable();
public static void main(String [] argv) {
new Start(argv);
}
public Start(String [] argv) {
System.out.println("<xmlizer> server " + VERSION);
readCommandLine(argv);
buildConfigFileName();
if (this.projectSet || this.baseSet || this.portSet || this.webSet || this.refreshSet) //if something is set by command line
{
System .out.println(" - saving/updating command line data to configuration file");
updatePathData();
}
if (this.homebase == null || this.projectbase == null) //not all data available
{
if (hasPathData())
//read existing file
{
pathData pd = new pathData();
boolean fileread = pd.readFromFile(configfilename.toString ());
if (pd.isValid()) {
System.out.println(" - reading configuration from user home directory");
this.homebase = pd.getHomeDir ();
this.projectbase = pd.getProjectDir();
this.web = pd.getWeb();
this.refresh = pd.getRefresh();
Autor: Thomas Schädler
239
Anhang B: Quelltext <xmlizer> server
this.port = Integer.parseInt(pd.getPort());
}
else {
this.homebase = pd.getHomeDir ();
this.projectbase = pd.getProjectDir();
this.web = pd.getWeb();
this.refresh = pd.getRefresh();
this.port = Integer.parseInt(pd.getPort());
printUsage();
}
}
else //ask @ commandline + test + save OR exit
{
printUsage();
}
} //else just start the sever
startServer();
}
private void buildConfigFileName() {
if (this.nameSet) {
this.configfilename.append("." + this.customname);
}
}
private void readCommandLine(String [] argv) {
for (int i=0;i<argv.length ;i++) {
String arg = argv[i];
//System.out.println(i + " ==> " + arg);
// options
if (arg.startsWith("-")) {
if (arg.equalsIgnoreCase("-port"))
//load a projectconfiguration
{
String currarg = argv[i+1];
try {
int currport = Integer.parseInt(currarg);
this.port = currport ;
System.out.println(" - setting port by command line");
this.portSet = true;
}
catch (NumberFormatException ex) {
printUsage ();
}
}
else if (arg.equalsIgnoreCase("-base"))
//set the homebase (dir where the server is running)
{
String currarg = argv[i+1];
if(testPath(currarg)) {
this.homebase = currarg;
System.out.println(" - setting base directory by command line");
this.baseSet = true;
}
}
else if (arg.equalsIgnoreCase("-projects"))
//set the projectbase (dir where the projects are saved)
{
String currarg = argv[i+1];
if(testPath(currarg)) {
this.projectbase = currarg;
System.out.println(" - setting project directory by command line" );
this.projectSet = true;
}
}
else if (arg.equalsIgnoreCase("-config"))
//set the configname to load
{
String currarg = argv[i+1];
this.customname = currarg;
System.out.println(" - using custom configuration: xmlizer.server.config." + currarg);
this.nameSet = true;
}
else if (arg.equalsIgnoreCase("-webinterface"))
//switch webinterface off
{
String currarg = argv[i+1];
if(currarg.equalsIgnoreCase("on") || currarg.equalsIgnoreCase("off")) {
this.web = currarg;
System.out.println(" - switching webinterface " + currarg);
this.webSet = true;
}
}
else if (arg.equalsIgnoreCase("-refresh"))
//switch refresh off
{
String currarg = argv[i+1];
if(currarg.equalsIgnoreCase("on") || currarg.equalsIgnoreCase("off")) {
this.refresh = currarg;
System.out.println(" - switching refresh " + currarg);
this.refreshSet = true;
}
}
else if (arg.equalsIgnoreCase("-help"))
//show command line usage
{
printUsage();
}
}
}
}
private void startServer () {
//be sure everything is avaliable what is needed.
if (this.homebase != null
&& !this.homebase.equalsIgnoreCase("")
&& this.projectbase != null
&& !this.projectbase .equalsIgnoreCase("")) {
requests=new Vector();
try {
Autor: Thomas Schädler
240
Anhang B: Quelltext <xmlizer> server
serverSocket =new ServerSocket(this.port);
this.data.put("homebase",this.homebase );
this.data.put("projectbase",this.projectbase);
this.data.put("port",Integer.toString(this.port));
this.data.put("webinterface" ,this.web);
this.data.put("refresh" ,this.refresh);
System.out.println (" ... starting server");
if (this.port == 7777) {
System.out.println(" -> listening on default port " + serverSocket.getLocalPort() + ".");
}
else {
System.out.println(" -> listening on custom port " + serverSocket.getLocalPort() + ".");
}
System.out.println ("
System.out.println ("
System.out.println ("
System.out.println ("
->
->
->
->
webinterface switched
proj. dir refresh switched
using home directory:
using project directory:
"
"
"
"
+
+
+
+
this.web);
this.refresh);
this.homebase );
this.projectbase);
//do it at least once!
if (this.refresh.equalsIgnoreCase ("off")) {
scanProjectFiles();
}
start();
System.out.println ("ready");
}
catch(Exception e) {
System.out.println ("[E] Error creating ServerSocket: " + e.getLocalizedMessage ());
}
}
else {
printUsage();
}
}
/**
* Checks for existence of pathdata (file)
*/
private boolean hasPathData() {
java.io.File configfile = new java.io.File(configfilename.toString ());
if (configfile.exists()) {
return true;
}
else return false;
}
/**
* Updates the pathdata (or creates them if neccessary)
*/
private void updatePathData() {
if(hasPathData()) //update
{
//update the xmlizer.server.config
pathData pd = new pathData();
pd.readFromFile(configfilename.toString());
if (this.baseSet) {
pd.setHomeDir(this.homebase);
} else this.homebase = pd.getHomeDir();
if (this.projectSet) {
pd.setProjectDir(this.projectbase );
} else this.projectbase = pd.getProjectDir ();
if (this.portSet) {
String portstr = Integer.toString (this.port);
pd.setPort(portstr );
} else this.port = Integer.parseInt(pd.getPort());
if (this.webSet) {
pd.setWeb(this.web);
} else this.web = pd.getWeb ();
if (this.refreshSet) {
pd.setRefresh(this.refresh);
} else this.refresh = pd.getRefresh();
pd.save(configfilename .toString());
}
else {
//write the xmlizer.server.config[.<name>]
pathData pd = new pathData();
pd.setHomeDir(this.homebase );
pd.setProjectDir (this.projectbase);
String portstr = Integer.toString(this.port);
pd.setPort(portstr);
pd.setWeb(this.web);
pd.setRefresh(this.refresh);
pd.save(configfilename .toString());
}
}
/**
* Test if the indicated directory a valid directory
*/
private boolean testPath (String path) {
java.io.File isdir = new java.io.File(path);
if (isdir.exists()) { return isdir.isDirectory (); }
else return false;
}
/**
* Prints the usage message (on console)
*/
private void printUsage() {
System.out.println("\nUsage: server.start [options]");
System.out.println();
System.out.println("Hints:");
System.out.println(" - if there is no config file, it will be generated");
System.out.println(" - if port,base or projects are specifed, the config file will be updated");
System.out.println(" - to use a custom config file (multiple server), specify its name");
Autor: Thomas Schädler
241
Anhang B: Quelltext <xmlizer> server
System.out.println(" - command line arguments update the indicated configfile");
System.out.println();
System.out.println("Options:");
System.out.println(" -config <name>
Use custom xmlizer.server.config.<name>");
System.out.println(" -port <portnumber>
Start the server on that port (default = 7777)");
System.out.println(" -base <dir>
Directory where the server is running");
System.out.println(" -projects <dir>
Directory where the projects are saved");
System.out.println(" -webinterface on|off Switch on/off webinterface (default=on)");
System.out.println(" -refresh on|off
Switch on/off continous directory scan (default=off)" );
System.out.println(" -help
Show this help screen.");
System.out.println();
System.out.println("Warnings from this start attempt:");
if (this.homebase == null || this.homebase.equalsIgnoreCase("")) {
System .out.println(" -> base directory was not set" );
}
if (this.projectbase == null || this.projectbase.equalsIgnoreCase("")) {
System .out.println(" -> project directory was not set");
}
System.exit(0);
}
public void run() {
while(!stop) {
try {
//optional projectfilesscan for permanent updates (costs much time though)
if (this.refresh.equalsIgnoreCase ("on")) {
scanProjectFiles();
}
ConnectionHandler temp = new ConnectionHandler(this.data);
temp.connectionRequest(serverSocket.accept());
requests.add(temp);
}
catch(Exception e) {
System.out.println ("[E] Error accepting request: " + e.getLocalizedMessage());
}
}
}
public void stopListening() {
stop = true;
}
public Vector getRequests() {
return requests ;
}
public static void removeFromUserList(ConnectionHandler ch) {
requests.remove (ch);
}
/**
* Scans the project files directory and fill a list with valid dirs
*/
private void scanProjectFiles() {
Hashtable fileHash = new Hashtable();
File prodir = new File((String)this.data.get("projectbase"));
if (prodir .exists() && prodir.isDirectory ()) {
File[] prodirs = prodir.listFiles();
for(int i = 0;i<prodirs.length;i++) {
File temp = prodirs[i];
//must be a valid directory and not start with underscore
if (temp.isDirectory() && !temp.getName().startsWith("_")) {
fileData fd = new fileData();
fd.setName(temp.getName());
File[] profiles = temp.listFiles();
for(int k=0;k<profiles.length ;k++) {
File temp5 = profiles[k];
//must be a valid file
if (temp5.isFile()) {
fd.addFile(temp5 .getName(),temp5);
}
}
if (fd.hasConfig()) //is a valid project dir
{
fileHash.put(temp.getName(),fd);
}
}
}
}
this.data.put("files",fileHash);
}
/**
* Returns an HTML rendition of the given <code>String</code>. This was
* written by <a href=mailto:[email protected]>Kimbo Mundy</a>.
* @param text A <code>String</code> to be used in an HTML page.
* @return A <code>String</code> that quotes any HTML markup
* characters. If no quoting is needed, this will be
* the same as <code>text</code>.
*/
public static String htmlEncode(String text) {
if (text == null) {
return "";
}
StringBuffer results = null;
char[] orig = null;
int beg = 0, len = text.length();
for (int i = 0; i < len; ++i) {
char c = text.charAt(i);
switch (c) {
case 0:
case '&':
Autor: Thomas Schädler
242
Anhang B: Quelltext <xmlizer> server
case '<':
case '>':
case '"':
if (results == null) {
orig = text.toCharArray();
results = new StringBuffer(len+10);
}
if (i > beg)
results.append(orig, beg, i-beg);
beg = i + 1;
switch (c) {
default: // case 0:
continue;
case '&':
results.append("&");
break;
case '<':
results.append("<" );
break;
case '>':
results.append(">" );
break;
case '"':
results.append(""");
break;
}
break;
}
}
if (results == null)
return text;
results.append(orig, beg, len-beg);
return results.toString();
}
}/*
* ConnectionHandler.java
*
* Created on 1. August 2002, 18:59
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
import java.net.*;
import java.io.*;
import java.util.*;
/**
* Handles the Connection
* @author [email protected]
* @version 0.2
*/
public class ConnectionHandler extends Thread implements HttpRequestListener {
private Socket socket;
private Request request;
private Response response;
private boolean ready;
private boolean isDataRequest = false;
private Hashtable data;
private LookupTable queryString;
private ProjectManager manager ;
private boolean isXMLOutput = false ;
private boolean isDataOutput = false;
private String errorMessage = "unspecified error";
public ConnectionHandler (Hashtable data) {
this.data = data;
}
public void connectionRequest(Socket socket) {
//System.out.println("[I] New request.");
this.socket=socket;
try {
response = new Response(socket);
}
catch(Exception e) {
System .out.println("[E] Error creating Response.");
}
//System.out.println("[I] Response object created.");
request=initRequest();
System.out.println("[I] Request(" + request.getId() + ", " + request.getResource() + ") object created.");
ready=true;
start();
}
private Request initRequest() {
try {
BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line ;
while((line=in.readLine())!="") {
Autor: Thomas Schädler
243
Anhang B: Quelltext <xmlizer> server
StringTokenizer token=new StringTokenizer(line);
token.nextToken();
return new Request (token.nextToken().substring(1));
}
}
catch(Exception e) {
System .out.println("[E] Error creating Request.");
}
return null;
}
public void run() {
while(ready) {
StringBuffer buffer = new StringBuffer();
try {
buffer = dispatchRequest(request.getResource());
}
catch(Exception e) {
this.errorMessage = e.getMessage();
if (request != null) {
if (!this.errorMessage.equalsIgnoreCase ("stealth" )) {
System.out.println("[E] Error loading requested resource(" + request.getResource());
}
}
if (request != null && ((String)this.data.get("webinterface")).equalsIgnoreCase("on")) {
System.out.println("[I] Sending error response.");
try {
buffer = processFileRequest("error.html" );
}
catch (Exception ex ) {
System.out.println("[E] Error sending error request, PLEASE CHECK THE PATHs!");
}
}
ready=false;
Start.removeFromUserList(this);
}
finally {
if (((String )this.data.get("webinterface")).equalsIgnoreCase("on") || this.isDataRequest) {
if(response != null
&& !this.errorMessage.equalsIgnoreCase("stealth")
&& ((String)this.data.get("webinterface")).equalsIgnoreCase ("on")
|| (this.isDataOutput && request != null)
) {
if (this.isDataOutput) {
System .out.println("[I] Sending data output.");
}
if (this.isXMLOutput ) {
response.formatResponseXML (buffer);
}
else {
response.formatResponseHTML(buffer);
}
}
}
Start.removeFromUserList(this);
try {
socket.close();
}
catch(Exception e) {
System.out.println("[E] Error closing socket: " + e.getLocalizedMessage());
}
request=null;
response=null;
}
}
}
/**
* Returns the project details (HTML formated)
*/
private String getProjectDetails() {
String sel_pro = this.queryString.getValue("xmlizerproject");
Hashtable pro_data = (Hashtable )this.data.get("files");
fileData temp = (fileData)pro_data.get(sel_pro);
StringBuffer buff = new StringBuffer ();
// show the projct name
buff.append("<h3><font color=\"white \">project details: ");
buff.append(temp.getName());
buff.append("</font></h3><br><ul>");
if (this.manager != null) {
//checkUsedDatabases
dataItem module = this.manager.getProjectData().getInitialByKey("module" );
if (module.getValue().equalsIgnoreCase("Simple DB Export" )) {
//smdbe_items for smdbe module
buff.append("<li><font color=\"white\">");
buff.append("Mapping module: " + module.getValue ());
buff.append("</font></li>");
Vector dbs = this.manager.getProjectData().getSimpleItems();
for (Enumeration e = dbs.elements (); e.hasMoreElements();) {
dbItem currentdb = (dbItem)e.nextElement();
//link params
String params = "?xmlizerproject=" + temp.getName() + "&xmlizerdb=" + currentdb.getName() + "\">";
//output links
buff.append("<li><font color= \"white\">");
buff.append(temp.getName() + " :: " + currentdb .getName());
Autor: Thomas Schädler
244
Anhang B: Quelltext <xmlizer> server
buff.append(" [ <a href=\"xmlizer" + params + "XML</a> ] ");
buff.append(" [ <a href=\"htmlizer" + params + "HTML</a> ] ");
buff.append("</font></li>");
}
buff.append("</ul>");
}
else if (module.getValue().equalsIgnoreCase("Database to XML")) {
//project detail data (module and xsd filename
buff.append("<li><font color=\"white\">");
buff.append("Mapping module: " + module.getValue ());
buff.append("</font></li>");
//link params
String params = "?xmlizerproject=" + temp.getName() + "\">";
//output links
buff.append("<li><font color=\"white\">");
buff.append(temp.getName());
buff.append(" [ <a href=\"xmlizer" + params + "XML</a> ] " );
buff.append(" [ <a href=\"htmlizer" + params + "HTML</a> ] ");
buff.append("</font></li>");
buff.append("</ul>");
//add the parameters and stuff
Hashtable paraHash = this.manager.getProjectData ().DB2XMLgetmapping().getParameters();
//print form header if neccessary
if (paraHash .size() > 0) {
buff.append("<br><font color= \"white\">");
buff.append("<b>Custom query parameters:</b><br>" );
buff.append("</font><br>");
buff.append("<form action='customizer' method='GET'>");
buff.append("<input type='hidden' type='text' name='xm lizerproject' value='"+ temp.getName() +"'>");
buff.append("<table>");
buff.append("<tr><th>Name</th><th>Default value</th></tr>");
}
else {
buff.append("<br><font color= \"white\">");
buff.append("This project does not provide parameters.<br>No custom queries possible.");
buff.append("</font>");
}
for (Enumeration e = paraHash.elements ();e.hasMo reElements ();) {
ParameterInfo currentInfo = (ParameterInfo)e.nextElement();
buff.append("<tr><td><font color=\"white\"><b>"+ currentInfo.getName() +":</b></font></td><td><input
type='text' name='"+ currentInfo.getName() +"' size='25' maxlength='256' value='"+ currentInfo .getValue() +"'></td></tr>");
}
//print form footer & buttons if neccessary
if (paraHash .size() > 0) {
buff.append("<tr><td><b>Outpu t format:</b></td>");
buff.append("<td><input type='radio' name='xmlizerformat' checked value='xmlizer'>[ XML ]</td></tr>" );
buff.append("<tr><td> </td><td><input type='radio' name='xmlizerformat' value='htmlizer'>[ HTML
]</td></tr>");
buff.append("<tr><td> </td><td><input type='submit' value='Query'> <input type='reset'
value='Reset'></td></tr>");
buff.append("<table></form>");
}
}
}
else {
buff.append ("<li><font color=\"white\">Due to configuration problems, this project is currently unavailable.</a></font></li>");
}
return buff.toString ();
}
/**
* Returns a HTML formated lis t of all available projects
*/
private String getProjectsAsHTML() {
StringBuffer buff = new StringBuffer ();
buff.append("<h3><font color=\"white \">available projects:</font></h3><br><ul>");
Hashtable projectFiles = (Hashtable)this.data.get("files");
for(Enumeration en = projectFiles.elements();en.hasMoreElements();) {
fileData temp = (fileData)en.nextElement();
buff.append ("<li><font color=\"white\"><a href= \"index.html?xmlizerproject=");
buff.append (temp.getName());
buff.append ("\">");
buff.append (temp.getName());
buff.append ("</a></font></li>");
}
buff.append("</ul>");
return buff.toString ();
}
/**
* Parses a line and replaces the tokens (patterns) as specified in the html-files
* tokens: %%tokenname%% -> will be substituted with the output of the given method
* adding more tokens and editing (customizing) of the html output is absolutly recommended
* but always include the credits on each pages footer, thanx a lot
*/
private String parseLine (String line) {
StringBuffer result = new StringBuffer();
java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(line);
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
if (token.equalsIgnoreCase("%%date%%" )) {
token = new java.util.Date().toString(); //show the actual date and time
}
if (token.equalsIgnoreCase("%%version%%")) {
token = Start.VERSION; //show the servers version
}
if (token.equalsIgnoreCase("%%projects%%")) {
Autor: Thomas Schädler
245
Anhang B: Quelltext <xmlizer> server
token = getProjectsAsHTML(); //show a list of li nked projects ( -> detail link)
}
if (token.equalsIgnoreCase("%%details%%")) {
token = getProjectDetails(); //show the selected projects details (-> query mask)
}
if (token.equalsIgnoreCase("%%debug%%")) {
token = this.queryString.toHTML(); //add debug information (GET data)
}
if (token.equalsIgnoreCase("%%error%%")) {
token = this.errorMessage; //set the error message
}
result .append(token + " ");
}
return result.toString() + "\n";
}
/**
* Dispatches a request
*/
private StringBuffer dispatchRequest(String request) throws Exception {
//returns the method to check
//and saves the variables in global queryString (LookupTable)
String method = parseQueryString(request);
if (method .equalsIgnoreCase("xmlizer")) //return xml
{
this.isDataRequest = true;
return processXMLRequest(true);
}
else if (method .equalsIgnoreCase("htmlizer")) //return html
{
this.isDataRequest = true;
return processHTMLRequest();
}
else if (method .equalsIgnoreCase("customizer")) //return either xml or html!
{
String sel_format = this.queryString.getValue("xmlizerformat");
if (sel_format != null && sel_format.equalsIgnoreCase("xmlizer")) {
this.isDataRequest = true;
return processXMLRequest(true);
}
else if (sel_format != null && sel_format.equalsIgnoreCase("htmlizer")) {
this.isDataRequest = true;
return processHTMLRequest();
}
else {
throw new Exception("The requested format " + sel_format + "is not valid.");
}
}
else {
if (((String)this.data.get("webinterface")).equalsIgnoreCase("on")) {
//processInterfaceRequest
this.isDataRequest = false;
return processFileRequest(method);
}
else {
this.isDataRequest = true;
throw new Exception("stealth");
}
}
}
/**
* Reads the queryString and extracts all parameters not starting with xmizer
*/
private Hashtable getMappingParameters() {
Hashtable xmlParams = new Hashtable(); //key=name, value=value
String[] allNames = this.queryString .getNames();
String[] allValues = this.queryString.getValues();
for (int i=0;i<allNames.length;i++) {
String curr_name = allNames [i];
if (!curr_name.startsWith("xmlizer")) {
String curr_value = allValues[i];
xmlParams.put(curr_name ,curr_value);
}
}
return xmlParams;
}
/**
* Processes a XML Request: xmlizer...
* Sends back XML-data
*/
public StringBuffer processXMLRequest(boolean isXML) throws Exception {
//as error message, make a readFile("error.html");
StringBuffer xmloutput = null;
String sel_pro = this.queryString.getValue("xmlizerproject");
String db_pro = this.queryString.getValue ("xmlizerdb");
Hashtable pro_data = (Hashtable )this.data.get("files");
if (sel_pro != null && pro_data .containsKey(sel_pro)) {
// a project request must be called
fileData f_data = (fileData )pro_data.get(sel_pro);
boolean ok = prepareProject (f_data); //prepare the data for this project -> manager
if (ok) {
dataItem module = this.manager.getProjectData().getInitialByKey ("module");
if (module.getValue().equalsIgnoreCase ("Simple DB Export") && db_pro != null) {
xmloutput = this.manager.getXML_SMDBE(db_pro );
this.isDataOutput = true;
}
else if (module.getValue().equalsIgnoreCase ("Database to XML")) {
String base = (String)this.data.get("projectbase" ) + System .getProperty("file.separator") + sel_pro +
System.getProperty ("file.separator");
Autor: Thomas Schädler
246
Anhang B: Quelltext <xmlizer> server
Hashtable mappingParameters = getMappingParameters(); //key=name,value=value of user params (no
xmlizer...)
//System.out.println(mappingParameters.size());
xmloutput = this.manager.getXML_DB2XML(base,mappingParameters);
this.isDataOutput = true;
}
}
}
//debug info only
if (xmloutput == null) {
throw new Exception("unspecified xml processing error");
}
this.isXMLOutput = true;
return xmloutput;
}
/**
* Processes a HTML Request: htmlizer...
* (is a wrapper for XML only to output the data HTML-formated to the browser
*/
public StringBuffer processHTMLRequest() throws Exception {
StringBuffer xmloutput = processXMLRequest(false);
StringBuffer htmloutput = new StringBuffer("<html>\n<head><title>xmlizer server html output</title></head>\n\n<body
bgcolor= \"#215682\" text=\"white\" link=\"white\" vlink=\"white\" alink=\"white \"><h3><xmlizer> server html output</h3><br><pre>\n");
String htmloutputstr = Start.htmlEncode(xmloutput.toString());
htmloutput .append(htmloutputstr );
htmloutput .append("</pre><hr color=\"white\"><br><div align=\"left \"><font color= \"white\"><a
href=\"index.html\">back to the index</a></font></div><div align=\"right\"><font color=\"white \">(c) 2002 <xmlizer>
server/configurator freely available @ <a href=\"http://www.e-freak.ch/xmlizer/ \">e-freak</a> Spread the
data!</font></div></body></html>");
this.isXMLOutput = false; //set the right content-type for the output
return htmloutput;
}
/**
* prepare the data for a project
*/
private boolean prepareProject (fileData fdata ) throws Exception {
String projectpath = fdata .getConfigFile().toString (); //cannont be empty or null!
//System.out.println("PATH: " + projectpath);
this.manager = new ProjectManager(projectpath);
//System.out.println("DATA:\n" + this.manager.getProjectData().getAsXMLText());
if (this.manager != null) {
return true;
} else throw new Exception ("projectdata invalid");
}
/**
* Processes a file request: index.html?bla=bla&bla=bla
**/
public synchronized StringBuffer processFileRequest(String method ) throws Exception {
//decode the resouce string and do the right thing
//url decoding? class?
//if (method.equalsIgnoreCase("index.html") || method.equalsIgnoreCase("error.html")) {
if (method.equalsIgnoreCase ("index.html")) //check for parameters on the index
{
String sel_pro = this.queryString .getValue("xmlizerproject");
Hashtable pro_data = (Hashtable)this.data.get("files");
if (sel_pro != null && pro_data.containsKey (sel_pro)) {
// a project request must be called
fileData f_data = (fileData)pro_data.get(sel_pro);
boolean ok = prepareProject(f_data ); //prepare the data for this project
if (ok) {
method = "project.html";
}
}
}//else try to reach the called file (for custom files added by users
try {
FileReader fReader = new FileReader(
(String )this.data.get("homebase")
+ System.getProperty("file.separator")
+ "html"
+ System.getProperty("file.separator")
+ method //her comes the resolved ressource, only the filename tos substitute
);
BufferedReader reader = new BufferedReader(fReader);
StringBuffer buffer = new StringBuffer ();
String line;
while((line = reader.readLine())!=null) {
line = parseLine(line);
buffer.append(line);
}
fReader.close();
return buffer;
}
catch(Exception e) {
throw new Exception(e.getLocalizedMessage());
}
//}
//else throw new Exception("unknown command");
}
/**
* Parses the incoming querystring and extracts the parameters to the global
* queryString (LookupTable) and return the method -string (eg: xmlizer?...)=> xmlizer
*/
private String parseQueryString(String query) {
//remove the stuff before the (optional) ?
String method;
String resolvedQuery ;
int questionMark = query.indexOf("?"); {
if (questionMark < 0) //no parameters
{
Autor: Thomas Schädler
247
Anhang B: Quelltext <xmlizer> server
resolvedQuery = new String();
method = query;
}
else {
resolvedQuery = query.substring(questionMark+1,query.length());
method = query.substring(0,questionMark);
}
}
//parse the parameters and fill the queryString
CgiParser parser = new CgiParser(resolvedQuery ,"&","=");
this.queryString = parser.parse ();
return method;
}
}/*
* Response.java
*
* Created on 1. August 2002, 18:59
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
import java.io.PrintWriter;
import java.net.Socket;
/**
* Represents a Response (and the methods to print the result)
* @author [email protected]
* @version 0.2
*/
public class Response {
private PrintWriter out;
public Response(Socket socket) throws Exception {
try {
out=new PrintWriter(socket.getOutputStream ());
}
catch(Exception e) {
throw new Exception();
}
}
public void formatResponseHTML (StringBuffer data) {
String header="HTTP/1.1 200 OK\nContent-Type: text/html\n\n";
StringBuffer newResponse=new StringBuffer ();
try {
newResponse .append(header);
newResponse .append(data.toString ());
write(newResponse);
}
catch(Exception e) {
System .out.println("[E] Error sending Response: " + e.getLocalizedMessage());
}
}
public void formatResponseXML(StringBuffer data) {
String header="HTTP/1.1 200 OK\nContent-Type: text/xml\n\n";
StringBuffer newResponse=new StringBuffer ();
try {
newResponse .append(header);
newResponse .append(data.toString ());
write(newResponse);
}
catch(Exception e) {
System .out.println("[E] Error sending Response: " + e.getLocalizedMessage());
}
}
public void write(StringBuffer data ) throws Exception {
try {
out.print(data.toString());
out.flush();
}
catch(Exception e) {
throw new Exception();
}
}
}/*
* HttpRequestListener.java
*
* Created on 1. August 2002, 18:59
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
Autor: Thomas Schädler
248
Anhang B: Quelltext <xmlizer> server
* Foobar is distributed in the hope that it will be useful,
* but WITHO UT 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
import java.net.Socket;
/**
* Listents for HTTP Requests
* @author [email protected]
* @version 0.2
*/
public interface HttpRequestListener {
public void connectionRequest(Socket socket);
}/*
* Request.java
*
* Created on 1. August 2002, 18:59
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
/**
* Represents a Request (id and querystring)
* @author [email protected]
* @version 0.2
*/
public class Request {
private String id;
private String resource;
public Request(String resource ) {
id=generateId();
if (resource.equalsIgnoreCase(new String())) {
this.resource = "index.html";
}
else this.resource = resource;
}
public String generateId () {
Double id=new Double (Math.random());
return String.valueOf(id);
}
public String getId () {
return id;
}
public String getResource() {
return resource;
}
}/*
* pathData.java
*
* This projectData container contains all neccessary methods to deal
* with the projectData management
*
* Created on 5. April 2002, 16:30
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
import
import
import
import
java.io.*;
java.util.*;
java.lang.*;
org.jdom.*;
Autor: Thomas Schädler
249
Anhang B: Quelltext <xmlizer> server
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
/**
* Represents the pathData for the server and all other config-infos
* [email protected]
* @version
*/
public class pathData {
public static String XMLFILEROOT = "xmlizerconfig" ;
private
private
private
private
private
String
String
String
String
String
homedir = null;
projectdir = null;
port = new String("7777");
web = "on";
refresh = "off" ;
//CONSTRUCTOR
//----------------------------------------------------------------------------------------------/**
* Creates new pathData (Constructor)
*/
public pathData() {
//init here if neccessary
}
//GET AND SET
//----------------------------------------------------------------------------------------------//homedir
public String getHomeDir() {
return homedir;
}
public void setHomeDir(String dir) {
this.homedir = dir;
}
//port
public String getPort() {
return this.port;
}
public void setPort(String port) {
this.port = port;
}
//projectdir
public String getProjectDir() {
return this.projectdir;
}
public void setProjectDir(String dir) {
this.projectdir = dir;
}
public String getWeb() {
return this.web;
}
public void setWeb(String web) {
this.web = web;
}
public String getRefresh () {
return this.refresh;
}
public void setRefresh(String refresh) {
this.refresh = refresh;
}
//STRING REPRESENTATION
//----------------------------------------------------------------------------------------------public String toString() {
StringBuffer result = new StringBuffer("FULL PATHDATA >>");
result.append("\nWEB
>> " + this.web);
result.append("\nREFRESH
>> " + this.refresh);
result.append("\nPORT
>> " + this.port);
result.append("\nHOME-DIR
>> " + this.homedir);
result.append("\nPROJECT-DIR >> " + this.projectdir );
return result.toString();
}
//XML REPRESENTATION
//----------------------------------------------------------------------------------------------public boolean isValid() {
if (
this.homedir != null
&& !this.homedir.equalsIgnoreCase("")
&& this.projectdir != null
&& !this.projectdir.equalsIgnoreCase ("")
&& this.port != null
&& this.web != null
&& !this.web.equalsIgnoreCase("")
&& this.refresh != null
&& !this.refresh.equalsIgnoreCase("")
) {
return true;
}
else return false;
}
/**
* Checks the doctype of the XML-File (just to be sure to read the right information)
*/
private boolean checkDocType(DocType dt,String rootelement) {
if (dt.getElementName().equalsIgnoreCase(rootelement)) {
return true;
}
else {
return false;
Autor: Thomas Schädler
250
Anhang B: Quelltext <xmlizer> server
}
}
/*
* Reads an XML file (which must be of type xmlizer.project.config.dtd) and
* fills all information in the projectdata
*
* @param The filename as String
* @param The logWindow (to indicate errors etc...)
*/
synchronized public boolean readFromFile (String filename) {
boolean docOK = false;
try {
SAXBuilder builder = new SAXBuilder(false); //true -> validating against dtd
Document jdoc = builder.build(filename);
DocType docType = jdoc.getDocType();
docOK = checkDocType(docType,XMLFILEROOT);
if (docOK) {
//get the root
Element root = jdoc.getRootElement();
java.util.List itemlist = root.getChildren("path");
Iterator item_iter = itemlist.iterator ();
while (item_iter.hasNext()) {
Element path_item = (Element) item_iter .next();
if (path_item.getAttributeValue("description").equalsIgnoreCase("home")) {
this.homedir = path_item.getTextTrim();
//System.out.println("HOME: " + path_item.getTextTrim());
}
else if (path_item.getAttributeValue("description").equalsIgnoreCase("project")) {
this.projectdir = path_item.getTextTrim();
//System.out.println("PROJECT: " + path_item.getTextTrim());
}
else if (path_item.getAttributeValue("description").equalsIgnoreCase("port")) {
this.port = path_item.getTextTrim();
//System.out.println("PORT: " + path_item.getTextTrim());
}
else if (path_item.getAttributeValue("description").equalsIgnoreCase("web" )) {
this.web = path_item .getTextTrim();
//System.out.println("WEBINTERFACE: " + path_item.getTextTrim());
}
else if (path_item.getAttributeValue("description").equalsIgnoreCase("refresh")) {
this.refresh = path_item.getTextTrim();
//System.out.println("REFRESH: " + path_item.getTextTrim());
}
}
return true;
}
else {
//System.out.println("DOC NOT OK");
return false ;
}
}
catch (JDOMException e) {
//System.out.println("JDOM Exception: " + e.getMessage());
return false;
}
}
/**
* Return the data as String
*/
public String getAsXMLText() {
Document jdoc = this.getAsXMLDocumentJDOM ();
org.jdom.output .DOMOutputter outp = new org.jdom.output.DOMOutputter();
XMLOutputter fmt = new XMLOutputter("
return fmt.outputString(jdoc);
",true);
}
/**
* Return the data as XML Document (org.w3c.dom.Document)
*/
public org.w3c.dom.Document getAsXMLDocumentW3C() {
Document jdoc = this.getAsXMLDocumentJDOM ();
org.jdom.output .DOMOutputter outp = new org.jdom.output.DOMOutputter();
try {
org.w3c.dom.Document result = outp.output(jdoc);
return result; //and return the result
}
catch (JDOMException e) {
System .out.println("DOM Serializer error for debug output!");
return null;
}
}
/**
* Return the data as XML Document org.jdom.Document
*/
public Document getAsXMLDocumentJDOM() {
//MAKE DOCTYPE
DocType docType = new DocType(XMLFILEROOT,null);
Element root = new Element (XMLFILEROOT);
Element init_item1 = new Element("path").setText(this.homedir);
init_item1 .setAttribute("description","home");
root.addContent (init_item1 );
Element init_item2 = new Element("path").setText(this.projectdir);
init_item2 .setAttribute("description","project");
root.addContent (init_item2 );
Element init_item3 = new Element("path").setText(this.port);
Autor: Thomas Schädler
251
Anhang B: Quelltext <xmlizer> server
init_item3 .setAttribute("description","port");
root.addContent (init_item3 );
Element init_item4 = new Element("path").setText(this.web);
init_item4 .setAttribute("description","web");
root.addContent (init_item4 );
Element init_item5 = new Element("path").setText(this.refresh);
init_item5 .setAttribute("description","refresh");
root.addContent (init_item5 );
Document doc = new Document(root,docType);
return doc; //and return the doc
}
/**
* save the config
*/
public void save(String path) {
org.jdom.Document xmldata = getAsXMLDocumentJDOM();
org.jdom.output .XMLOutputter fmt = new org.jdom.output.XMLOutputter("
",true);
try {
//file stuff
java.io.File outputFile = new java.io.File(path);
java.io.FileOutputStream outputStream = new java.io.FileOutputStream(outputFile);
java.io.OutputStreamWriter out = new java.io.OutputStreamWriter(outputStream,"UTF8");
fmt.output(xmldata,out);
out.close();
}
catch (java.io.IOException ex) {
System .out.println("SAVE ERROR: " + ex.toString ());
}
}
}/*
* XMLSchemaParser.java
*
* This class parsers a XML Schema and generates all neccessary info for
* using this XML Schema (instance generator, tree-view and element info)
*
* Created on 17. Juni 2002, 09:02
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> is f ree 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.
*
* Foobar is dist ributed 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ----------------------------------------------------------------------- ----*/
package server;
import
import
import
import
java.util.*;
javax.swing .*;
javax.swing .tree.*;
org.jdom.*;
/**
* Parses an XML Schema
* @author [email protected]
* @version 0.2
*/
public class XMLSchemaParser {
private ProjectManager mother;
private Document doc;
private JTree tree = null;
//Hashtable for saving info-lists
private Hashtable xml_elements = new Hashtable();
private Hashtable xml_types = new Hashtable();
//little global helpers
private String rootelement = null;
private DefaultMutableTreeNode topNode = null;
private Hashtable loadedSQL = null;
private Hashtable loadedReps = null;
private Hashtable loadedContent = null;
/** Creates new XMLSchemaParser */
public XMLSchemaParser(ProjectManager conf) {
this.mother = conf;
}
/**
* Returns a JTree representing this XML Schema as browsable tree
*/
public JTree getTree() {
return tree;
}
/**
* Returns an instance document (test-output)
*/
public Document getInstance() {
return this.instance ; //and return the doc
}
//INSTANCE GENERATION
//-----------------------------------------------------------------------------------------------
Autor: Thomas Schädler
252
Anhang B: Quelltext <xmlizer> server
private
private
private
private
private
private
Document instance;
Element DocumentRoot;
boolean rootSet;
Hashtable madeSQLs; //key = sqlid, value = SQLStatement
Hashtable madeSQLsCurrentRow; //key = sqlid, value = currentRow
Hashtable userParams;
public void buildInstance(Hashtable userParams) {
instance = null;
DocumentRoot = null;
rootSet = false ;
this.userParams = userParams;
madeSQLs = new Hashtable(); //key = sqlid, value = SQLStatement
//all_current_ids = new Vector();
madeSQLsCurrentRow = new Hashtable(); //key = sqlid, value = currentRow
for (Enumeration e = this.topNode.children(); e.hasMoreElements();) {
DefaultMutableTreeNode dmtr = (DefaultMutableTreeNode)e.nextElement ();
try {
makeInstance (DocumentRoot,null,dmtr);
}
catch(Exception ex) {
return;
}
}
if (DocumentRoot != null) {
instance = new Documen t(DocumentRoot);
}
}
// parent=JDOMElement, lastParentElement=parental_SchemaElement, current=current_DefaultMutableTreeNode
private void makeInstance(Element parent ,SchemaElement lastParentElement,DefaultMutableTreeNode current) throws Exception
{
if (current == null) { return; } //failsafe
//get the schemaelement of the current node -> curse
SchemaElement curse = (SchemaElement )current.getUserObject();
//check for the root -element (as defined in the mapping - do something only if found)
if (!rootSet && curse.getRealName().equalsIgnoreCase(mother.getProjectData().DB2XMLgetmapping().getRootElement())) {
//insert the document root as indicated, can have no repetition (root!)
DocumentRoot = new Element(curse .getRealName());
prepareSQLStatements(curse.getSQLStatements());
processCurrentElement(DocumentRoot,null,curse);
rootSet = true;
}
//if the current schemaelement is valid and the root -> start building
if (curse.isRefresh() && rootSet) {
prepareSQLStatements(curse.getSQLStatements());
//process this element (builds it)
if (curse.getRepetition() != null) //if this element has a repetition sql statement
{
//get the maximum allowed repetition value (maxOccurs for this Element)
int max = ((Integer)curse.getOccurrence().getMaxOccurs()).intValue();
//get the data assocciated w ith the element's repetition
String mapid_for_rep = curse .getRepetition();
Hashtable sql_result = (Hashtable )madeSQLs.get(mapid_for_rep);
//check for the maximum, if more then just cut it there so it will b e valid
int sqlmax = ((Integer)sql_result .get("rows")).intValue();
if (sqlmax < max) { max = sqlmax; } //adjust the max for maxOccurs
//finally do it for each DB-row
for (int i=0;i<max;i++) {
Element this_element = new Element(curse.getRealName());
processCurrentElement(this_element ,parent,curse);
if (parent == null) //root set, but no parent -> this is the root element!
{
parent = DocumentRoot;
//do the same for all children
for (Enumeration e = current.children(); e.hasMoreElements();) {
makeInstance(parent,curse,(DefaultMutableTreeNode)e.nextElement());
}
}
else // this is a normal element (sub-node (or more sub-sub-...) of the rootelement)
{
parent.addContent(this_element );
//do the same for all children
for (Enumeration e = current.children(); e.hasMoreElements();) {
makeInstance(this_element,curse ,(DefaultMutableTreeNode)e.nextElement());
}
}
//update the row_counter for other statements of this element
int row_counter = ((Integer)madeSQLsCurrentRow.get(mapid_for_rep )).intValue() + 1;
//System.out.println(curse.getRealName() + " >>" + row_counter);
madeSQLsCurrentRow.put(mapid_for_rep,new Integer(row_counter));
}
}
else //no repetition statement and no minimum, so skip it (if it is not the root)
{
/* special treatment for the root node! */
if (curse.getRealName().equalsIgnoreCase(mother.getProjectData().DB2XMLgetmapping().getRootElement())) {
Element this_elemen t = new Element(curse.getRealName());
processCurrentElement(this_element ,parent,curse);
if (parent == null) //root set, but no parent -> this ist the root element!
{
parent = DocumentRoot;
//do the same for all children
for (Enumeration e = current.children(); e.hasMoreElements();) {
makeInstance(parent,curse,(DefaultMutableTreeNode)e.nextElement());
}
Autor: Thomas Schädler
253
Anhang B: Quelltext <xmlizer> server
}
else // this is a normal element (sub-node (or more sub-sub-...) of the rootelement)
{
parent.addContent(this_element );
//do the same for all children
for (Enumeration e = current.children(); e.hasMoreElements();) {
makeInstance(this_element,curse ,(DefaultMutableTreeNode)e.nextElement());
}
}
}
// has a minOccurence of more than 0 but no repetition -> make it at least an empty element
else if (curse.getOccurrence ().getMinOccurs ().intValue() > 0) {
Element this_e lement = new Element(curse.getRealName());
processCurrentElement(this_element ,parent,curse);
parent.addContent(this_element);
//do the same for all children
for (Enumeration e = current.children(); e.hasMoreElements();) {
makeInstance(this_element ,curse,(DefaultMutableTreeNode )e.nextElement());
}
}
}
}
else //just go on without doing something (no buildup for those elements)
{
//do the same for all children
for (Enumeration e = current.children (); e.hasMoreElements();) {
makeInstance (parent,curse,(DefaultMutableTreeNode)e.nextElement ());
}
}
}
private void processCurrentElement(Element el ,Element parent ,SchemaElement sch) throws Exception {
//fill in the content
if (sch.getContent() != null && sch.getContent ().getMapID() != null) //has content
{
SchemaContent cont = sch.getContent();
if (cont.getMapID() != null && cont.getMapInfo() != null) {
//get the data and fill the attribute
String mapid = cont.getMapID ();
//the ID
String mapinfo = cont.getMapInfo(); //the tableName
int currentRow = ((Integer)madeSQLsCurrentRow.get(mapid)).intValue();
Hashtable data = (Hashtable)madeSQLs.get(mapid);
//get the hash-data from the list
if (data == null) { throw new Exception("No data for referenced sql with id="+mapid+" found!"); }
Vector colnames = (Vector)data.get("columnname");
int col = 0;
for (Enumeration en = colnames.elements(); en.hasMoreElements();) {
String currname = (String)en.nextElement();
if (currname.equalsIgnoreCase (mapinfo)) {
break;
}
col++;
}
String info[][] = (String[][])data.get("table");
String result = info[col][currentRow];
el.setText(result);
}
else if (cont.getMapID () != null && cont.getMapInfo() == null) {
//FIXME
//here comes the result of a simple statement
//which has only a mapid
//get the data and fill the attribute
String mapid = cont.getMapID ();
//the ID
int currentRow = ((Integer)madeSQLsCurrentRow.get(mapid)).intValue();
Hashtable data = (Hashtable)madeSQLs.get(mapid);
//get the hash-data from the list
if (data == null) { throw new Exception("No data for referenced sql with id="+mapid+" found!"); }
String info[][] = (String[][])data.get("table");
String result = info[0][0];
el.setText(result);
}
else { /*/dev/null*/}
}
//fill the attributes with the apropriate values
for (Enumeration e = sch.getAttributes().elements(); e.hasMoreElements();) {
SchemaAttribute att = (SchemaAttribute)e.nextElement ();
//System.out.println(att.getName() + " >>> " + att.getUse() + " >>>" + att.getMapID());
if (att.getUse().equalsIgnoreCase("prohibited")) {
//mother.getLog().addWarning("In element <" + sch.getRealName() + "> an attribute " + att.getName() + " is
PROHIBITED but has a value! Skipping...");
}
else if (att.getMapID() == null && att.getUse().equalsIgnoreCase("required")) //req. but not there -> tell the
user
{
//mother.getLog().addWarning("In element <" + sch.getRealName() + "> an attribute " + att.getName() + " is
REQUIRED but has no value.");
}
else if (att.getMapID() != null && att.getMapInfo() != null) {
//get the data and fill the attribute
String mapid = att.getMapID();
//the ID
String mapinfo = att.getMapInfo(); //the tableName
//mother.getLog().addDebug("Query: "+ mapid+":"+mapinfo);
int currentRow = ((Integer)madeSQLsCurrentRow.get(mapid)).intValue();
Hashtable data = (Hashtable)madeSQLs.get(mapid);
//get the hash-data from the list
if (data == null) { throw new Exception("No data for id="+mapid +" found!" ); }
Vector colnames = (Vector)data.get("columnname");
int col = 0;
for (Enumeration en = colnames.elements(); en.hasMoreElements();) {
String currname = (String)en.nextElement();
if (currname.equalsIgnoreCase (mapinfo)) {
Autor: Thomas Schädler
254
Anhang B: Quelltext <xmlizer> server
break;
}
col++;
}
String info[][] = (String[][])data.get("table");
String result = info[col][currentRow];
el.setAttribute(att.getName(),result);
}
else if (att.getMapID() != null && att.getMapInfo() == null) {
//here comes the result of a simple statement
//which has only a mapid
//get the data and fill the attribute
String mapid = att.getMapID();
//the ID
//mother.getLog().addDebug("Query: "+ mapid);
int currentRow = ((Integer)madeSQLsCurrentRow.get(mapid)).intValue();
Hashtable data = (Hashtable)madeSQLs.get(mapid);
//get the hash-data from the list
if (data == null) { throw new Exception("No data for id="+mapid +" found!" ); }
String info[][] = (String[][])data.get("table");
String result = info[0][0];
el.setAttribute(att.getName(),result);
}
else { /*/dev/null*/}
}
}
private Vector prepareSQLStatements (Vector vec) throws Exception {
if (vec == null) { return new Vector (0); } //check for fail
Vector res = new Vector();
for (Enumeration e = vec.elements(); e.hasMoreElements();) {
SQLStatement current = (SQLStatement)e.nextElement();
String current_id = current.getID();
//System.out.println("MAKING : " + current_id);
dbItem used_db_item = mother.getProjectData().getDBByName (current.getDB());
//System.out.println("
dbItem -> " + used_db_item);
Hashtable sql_result = null;
try {
//System.out.println("
Query -> " + current.getSQL());
String resolvedQuery = resolveQuery(current.getSQL());
//System.out.println("
Resol -> " + resolvedQuery);
sql_result = used_db_item.querySilent(resolvedQuery);
this.madeSQLs.put(current_id ,sql_result); //add them to the list
this.madeSQLsCurrentRow .put(current_id ,new Integer(0));
res.add(current_id );
//System.out.println("
SUCCESS !!");
}
catch (Exception ex) {
throw new Exception(ex.getLocalizedMessage());
}
}
//System.out.println(res.toString());
//System.out.println(madeSQLsCurrentRow.toString());
return res;
}
/** Returns xxx from xxx:yyy */
private String getFirst(String s,int cutter) {
int doublepoint = s.indexOf(":");
if (doublepoint != 0) {
return s.substring(cutter,doublepoint );
}
else return s;
}
/** Retur ns yyy from xxx:yyy */
private String getSecond (String s,int cutter) {
int doublepoint = s.indexOf(":");
if (doublepoint != 0) {
return s.substring(++doublepoint ,s.length()-cutter);
}
else return s;
}
private String getSubstitution (String query) throws Exception {
StringBuffer result = new StringBuffer();
int counter = 0;
StringTokenizer st = new StringTokenizer(query );
while (st.hasMoreTokens()) {
String token = st.nextToken ();
//parameter substitution
if (token.startsWith("[-") && token.endsWith("-]")) //parameter substitution
{
StringBuffer newToken = new StringBuffer();
String mapid = getFirst (token,2);
String mapinfo = getSecond(token,2);
ParameterInfo thisinfo = mother.getProjectData().DB2XMLgetmapping().getParameterByMapID(mapid);
if (this.userParams.containsKey(thisinfo.getName())) {
newToken .append(this.userParams.get(thisinfo .getName()));
}
else //take the default value
{
newToken .append(thisinfo .getValue());
}
result.append(newToken.toString());
}
//sql substitution
else if (token.startsWith("[") && token.endsWith("]")) //sql substitution
{
StringBuffer newToken = new StringBuffer();
// [mapid:mapinfo]
Autor: Thomas Schädler
255
Anhang B: Quelltext <xmlizer> server
// evaluierungsschritte:
// 1. SQLStatment holen für den angegebenen key
String mapid = getFirst (token,1);
String mapinfo = getSecond(token,1);
//newToken.append("**" + mapid + "=" + mapinfo + "**");
// 2. dbItem holen für das angegebene SQLStatement (siehe XMLSchemaParser)
SQLStatement stat = mother.getProjectData().DB2XMLgetmapping().getSQLStatementByMapID(mapid);
//newToken.append(stat.toString());
dbItem used_db_item = mother .getProjectData ().getDBByName(stat.getDB ());
Hashtable sql_result;
// 3. SQL auf dieser datenbank ausführen:
try {
String sub_query = getSubstitution (stat.getSQL());
sql_result = used_db_item.querySilent(sub_query);
// -- bei nur einem resultat -> dieses aus der übereinstimmenden namen (z.B. dbKey) ersetzen
// -- bei mehreren resultaten -> einfach das erste nehemn (alternativ oben das limit gleich ändern)
// 4. das ganze noch richtig ersetzen (Stringmässig) und dann ab damit zurück nach Hause
Vector colnames = (Vector)sql_result.get("columnname");
int col = 0;
for (Enumeration en = colnames.elements (); en.hasMoreElements();) {
String currname = (String )en.nextElement ();
if (currname.equalsIgnoreCase(mapinfo)) {
break;
}
col++;
}
String info[][] = (String[][])sql_result.get("table");
//FIXME fix the row here until it works
int row = ((Integer)madeSQLsCurrentRow.get(mapid)).intValue (); //get the current row
String resultString = info[col][row];
newToken .append(" ");
newToken .append(resultString);
result.append(newToken.toString());
counter++;
}
catch (Exception ex) {
throw new Exception (ex.getLocalizedMessage());
}
}
else {
result.append(" ");
result.append(token);
}
}
return result.toString();
}
private String resolveQuery(String query ) throws Exception {
//do all data operations on the embedded queries and replace them internally!
StringBuffer result = new StringBuffer();
//parse the query and substitute the SQLColumnInfo-Strings
//with the real value from the following new statement: (exam ple)
result.append(getSubstitution(query));
//achtung! "[..] "könnte probleme machen - format suchen!!
return result.toString();
}
//PARSING
//----------------------------------------------------------------------------------------------/**
* Parse an XML Schema
*/
public void parse(Document doc ) throws Exception {
this.doc = doc;
//parse it and make everything ok, then
doParse();
}
private void doParse() throws Excep tion {
//parse the xml schema
Element xmlroot = doc.getRootElement ();
//get the xml root
Namespace namespace = xmlroot.getNamespace();
//get the namespace
topNode = insertDocumentNode(xmlroot); //insert the doc root in the tree
// iterate over children of the root node
List elems = xmlroot.getChildren(); //"element",namespace
Iterator elems_iter = elems.iterator ();
int item_count = elems.size();
Object[] rootElems = new Object[item_count];
int counter = 0;
while (elems_iter.hasNext()) {
Element xmlelem = (Element) elems_iter.next();
if (this.JDOMisElement (xmlelem)) {
rootElems[counter] = this.JDOMgetElementName(xmlelem);
this.xml_elements.put(this.JDOMgetElementName(xmlelem),xmlelem);
counter++;
}
else if (this.JDOMisType(xmlelem))
//build type-lib for simpleTypes
{
this.xml_types.put(this.JDOMgetElementName(xmlelem),xmlelem);
}
}
//load the Content to add them to the elements
this.loadedContent = mother.getProjectData().DB2XMLgetmapping ().getLoadedContent();
//load the Repetitions to add them to the elements
this.loadedReps = mother.getProjectData().DB2XMLgetmapping().getLoadedReps();
//load the SQLStatements from xmlizer.xml
this.loadedSQL = mother.getProjectData().DB2XMLgetmapping().getLoadedSQL();
//check for saved root-element, else choose one
Autor: Thomas Schädler
256
Anhang B: Quelltext <xmlizer> server
rootelement = mother .getProjectData().DB2XMLgetmapping().getRootElement ();
//check if the saved root element is available, else choose new
if (rootelement != null) {
if (!this.xml_elements.containsKey(rootelement)) {
rootelement = null;
}
}
if (rootelement == null) {
throw new Exception("No root element specified in mapping, aborting.");
}
Element current = (Element)this.xml_elements.get(rootelement);
recursiveTreeBuilder (topNode,current);
//make the tree
tree = new JTree(topNode);
}
//------------------------------------------------------ PARSE HELPERS
/**
* Walks the JDOM Path to the root and build a xpath-like (unique string)
* which identifies a element for sure
*/
private String walkJDOMPath(Element element) {
StringBuffer buff = new StringBuffer ();
Element current = element;
do {
if (current.getAttribute("name") != null) {
buff.insert(0,"/" + current.getAttribute("name").getValue());
}
current = current.getParent ();
} while (!current.isRootElement ());
return buff.toString ();
}
/**
* Walks the tree-path of the jtree and adds all parent -nodes(=elements)
* to the list of the element's parents
*/
private SchemaElement walkTreePath(Object[] path,SchemaElement elem) {
//add all parent elements to this element and return it
//System.out.println(elem.getName() + " --> " + path.length);
for(int i=0;i<path.length;i++) {
DefaultMutableTreeNode curr = (DefaultMutableTreeNode)path[i];
SchemaElement currse = (SchemaElement )curr.getUserObject();
//System.out.println(currse.toString());
if (currse.isRefresh()) //is a real element (xml)
{
elem.addParent(currse);
}
}
return elem;
}
private DefaultMutableTreeNode lastParent = null;
private SchemaElement lastSchemaElement = null;
private void recursiveTreeBuilder(DefaultMutableTreeNode parentNode,Element current) {
//inspect this element and recurse for child-elements with current as new parentNode
if (current == null) { return; } //failsafe
DefaultMutableTreeNode treeNode = null;
SchemaElement schemel = null;
if (current.getName().equalsIgnoreCase("element")) {
treeNode = new DefaultMutableTreeNode (current);
String uniquePath = walkJDOMPath (current);
schemel = new SchemaElement (this.mother,treeNode,current,uniquePath );
StringBuffer name = new StringBuffer();
Attribute attr = null;
SchemaOccurrence occurrence = new SchemaOccurrence(current.getName().trim());
//name
attr = current.getAttribute ("name");
if (attr != null) {
//System.out.println(attr.getValue());
schemel.setRealName(attr.getValue ().trim());
name.append("<" + attr.getValue().trim() + ">");
//add the Repetition if available
if (this.loadedReps.containsKey(uniquePath)) {
schemel.setRepetition((String )this.loadedReps.get(uniquePath));
}
//add the SQLStatements according to the elementName in loadedSQL
if (this.loadedSQL .containsKey(uniquePath)) {
//System.out.println(currentElementName + " has a SQLStatement attached");
Vector this_sqls = (Vector)this.loadedSQL.get(uniquePath);
for (Enumeration e = this_sqls.elements (); e.hasMoreElements();) {
SQLStatement this_stat = (SQLStatement)e.nextElement();
//System.out.println("ADDING SQL WHILE PARSING: " + this_stat);
schemel.addSQLStatement(this_stat);
}
}
}
//type
attr = current.getAttribute ("type");
if (attr != null) {
schemel.setType(attr.getValue().trim());
name.append(" - " + attr.getValue ().trim());
}
Autor: Thomas Schädler
257
Anhang B: Quelltext <xmlizer> server
//ref
attr = current.getAttribute ("ref");
if (attr != null) {
schemel.setTypeRef (attr.getValue().trim());
name.append(" => " +attr.getValue ().trim());
}
//minOccurs
attr = current.getAttribute ("minOccurs");
if (attr != null) {
String min = attr.getValue().trim();
if (min != null) {
occurrence.setMinOccurs(min);
}
//System.out.println("MIN: " + min);
}
//maxOccurs
attr = current.getAttribute ("maxOccurs");
if (attr != null) {
String max = attr.getValue().trim();
if (max != null) {
occurrence.setMaxOccurs(max);
}
//System.out.println("MAX: " + max);
}
schemel.setOccurrence(occurrence );
schemel.setName(name.toString());
/*
if (schemel.getRealName().equalsIgnoreCase("uniqID"))
{
System.out.println(schemel);
}
*/
if (schemel.hasTypeRef ())
//typ dereferencing
{
//FIXME
String typeRef = schemel.getTypeRef();
//System.out.println("TypeRef: " + typeRef);
typeRef = removeNamespacePrefix(typeRef);
Element newcurrent = (Element)this.xml_elements.get(typeRef);
if (newcurrent != null) {
recursiveTreeBuilder(parentNode,newcurrent);
}
}
else if (schemel.hasType()) //type buildup
{
//add the stuff
treeNode.setUserObject(schemel);
parentNode.add(treeNode );
lastParent = treeNode; //set last to current
mother.getProjectData().DB2XMLgetmapping().addElement (schemel);
//add the stuff
//end should be reached because of having a simple type
String typeR = schemel.getType();
//System.out.println("Type: " + typeR);
typeR = removeNamespacePrefix(typeR);
Element newcurrent = (Element)this.xml_types.get(typeR);
if (newcurrent != null) {
//System.out.println(schemel);
schemel.processType (newcurrent);
lookForAttributes(schemel,newcurrent);
lookForContent (schemel,newcurrent);
recursiveTreeBuilder(treeNode ,newcurrent);
}
else //must be an internal type (per default just take it for now)
{
//could also be an invalid type!
if (this.loadedContent.containsKey (schemel.getRealName ())) {
schemel.setContent((SchemaContent)this.loadedContent.get(schemel.getID ()));
}
else {
schemel.setContent(new SchemaContent(schemel.getID ()));
}
}
//fill in parents
schemel = walkTreePath(treeNode.getPath(),schemel);
//make age change here
lastSchemaElement = schemel;
}
else
{
//must have an internal type -> buildup
//add the stuff
treeNode.setUserObject(schemel);
parentNode.add(treeNode );
lastParent = treeNode; //set last to current
mother.getProjectData().DB2XMLgetmapping().addElement (schemel);
//add the stuff
schemel.setInternalType (); //mark that it has an internal type def.
schemel.processInternalType();
//fill in parents
schemel = walkTreePath(treeNode.getPath(),schemel);
//make age change here
lastSchemaElement = schemel;
}
}
else if (current.getName().equalsIgnoreCase("any")) {
treeNode = new DefaultMutableTreeNode ();
schemel = new SchemaElement (this.mother,treeNode,"<any>");
treeNode.setUserObject (schemel);
Autor: Thomas Schädler
258
Anhang B: Quelltext <xmlizer> server
parentNode.add(treeNode);
lastParent = treeNode;
}
else if (current.getName().equalsIgnoreCase("all")) {
treeNode = new DefaultMutableTreeNode ();
schemel = new SchemaElement (this.mother,treeNode,"-=all=-");
treeNode.setUserObject (schemel);
parentNode.add(treeNode);
lastParent = treeNode;
}
else if (current.getName().equalsIgnoreCase("group")) {
treeNode = new DefaultMutableTreeNode ();
schemel = new SchemaElement (this.mother,treeNode,"-=group=-");
treeNode.setUserObject (schemel);
parentNode.add(treeNode);
lastParent = treeNode;
}
else if (current.getName().equalsIgnoreCase("sequence")) {
treeNode = new DefaultMutableTreeNode();
schemel = new SchemaElement (this.mother,treeNode,"-=sequence=-");
treeNode.setUserObject (schemel);
parentNode.add(treeNode);
lastParent = treeNode;
}
else if (current.getName().equalsIgnoreCase("choice")) {
treeNode = new DefaultMutableTreeNode ();
schemel = new SchemaElement (this.mother,treeNode,"-=choice=-");
treeNode.setUserObject (schemel);
parentNode.add(treeNode);
lastParent = treeNode;
}
else if (current.getName().equalsIgnoreCase("documentation")) {
lastSchemaElement.addDocumentation(current.getText());
}
else {
treeNode = lastParent;
}
//look for complexType
// iterate over children of the this element node
List elems = current.getChildren(); //"elements",namespace
Iterator elems_iter = elems.iterator ();
while (elems_iter.hasNext()) {
Element xmlelem = (Element) elems_iter.next();
recursiveTreeBuilder(treeNode,xmlelem);
}
}
/**
* Recursive search for simpleContent in type -Elements (simple and complex)
*/
private void lookForContent(SchemaElement attachHere,Element typeElement) {
if (typeElement == null) { return; } //failsafe
if (typeElement .getName().equalsIgnoreCase("simpleContent")) {
if (this.loadedContent .containsKey(attachHere.getID())) {
attachHere.setContent((Schem aContent)this.loadedContent.get(attachHere.getID()));
return;
}
else {
attachHere.setContent(new SchemaContent(attachHere.getID()));
return;
}
}
// iterate over children of the this element node
List elems = typeElement.getChildren (); //"elements",namespace
Iterator elems_iter = elems.iterator ();
while (elems_iter.hasNext()) {
Element xmlelem = (Element) elems_iter.next();
lookForContent(attachHere,xmlelem);
}
}
/**
* Recursive search for attributes in type-Elements (simple and complex)
*/
private void lookForAttributes (SchemaElement attachHere ,Element typeElement ) {
if (typeElement == null) { return; } //failsafe
if (typeElement .getName().equalsIgnoreCase("attribute")) {
attachHere.addAttribute(typeElement,mother .getProjectData ().DB2XMLgetmapping().getLoadedAttributes ());
}
// iterate over children of the this element node
List elems = typeElement.getChildren (); //"elements",namespace
Iterator elems_iter = elems.iterator ();
while (elems_iter.hasNext()) {
Element xmlelem = (Element) elems_iter.next();
lookForAttributes(attachHere,xmlelem);
}
}
/**
* Returns the name of this JDOMElement (attribute name of <element name="asdf"...>
* else returns "anonymous"
*/
private String JDOMgetElementName(Element el) {
Attribute attr = el.getAttribute("name");
if (attr != null) {
return attr.getValue().trim();
}
else //just to be sure, should not happen though...
{
return "anonymous";
}
Autor: Thomas Schädler
259
Anhang B: Quelltext <xmlizer> server
}
/**
* Returns true if this JDOMElement is an <element ...> -tag
*/
private boolean JDOMisType(Element el) {
if (el.getName().equalsIgnoreCase("simpleType" ) || el.getName().equalsIgnoreCase("complexType"))
return true;
return false;
}
/**
* Tests if the JDOMElement is of indicated type or not
*/
private boolean JDOMisOfType(String type ,Element el) {
if (el.getName().equalsIgnoreCase(type))
return true;
else return false;
}
/**
* Returns true if this JDOMElement is an <element ...> -tag
*/
private boolean JDOMisElement(Element el ) {
if (el.getName().equalsIgnoreCase("element"))
return true;
return false;
}
private DefaultMutableTreeNode insertDocumentNode(Element what) {
DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode();
SchemaElement schemel = new SchemaElement (this.mother,treeNode,"<schema>",what);
treeNode.setUserObject(schemel);
return treeNode ;
}
private static String removeNamespacePrefix(String s) {
int doublepoint = s.indexOf(":");
if (doublepoint != 0) {
return s.substring(++doublepoint );
}
else return s;
}
}
/*
* fileData.java
*
* Created on 4. August 2002, 00:40
*
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 wit h <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
import java.io.*;
import java.util.*;
import java.lang.*;
/**
* Represents the fileData (all files belonging to a project)
* @author [email protected]
* @version 0.2
*/
public class fileData {
public static String XMLFILEROOT = "xmlizerconfig" ;
private String name;
private Hashtable files = new Hashtable(); //key = name, value = file
//CONSTRUCTOR
//----------------------------------------------------------------------------------------------/**
* Creates new fileData (Constructor)
*/
public fileData() {
//init here if neccessary
}
//GET AND SET
//----------------------------------------------------------------------------------------------//name
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//files
public Enumeration getFileEnumeration() {
Autor: Thomas Schädler
260
Anhang B: Quelltext <xmlizer> server
return this.files.elements ();
}
//REST
//----------------------------------------------------------------------------------------------/**
* adds a new filedata element to the list
*/
public void addFile(String name,File file) {
if (name != null && file != null) {
//System.out.println(name + " >> " + file.toString());
this.files.put(name,file);
}
}
/**
* returns the specified file as file
*/
public File getFile(String name) {
if (this.files.containsKey (name)) {
return (File)this.files.get(name);
}
else return null;
}
/**
* returns the main config file (xmlizer.xml) as file
*/
public File getConfigFile() {
if (this.files.containsKey ("xmlizer.xml")) {
return (File)this.files.get("xmlizer.xml");
}
else return null;
}
/**
* returns true if this filedata contains a file called xmlizer.xml
*/
public boolean hasConfig () {
return this.files.containsKey("xmlizer.xml");
}
//STRING REPRESENTATION
//----------------------------------------------------------------------------------------------public String toString() {
StringBuffer result = new StringBuffer("FILEDATA = >>");
result.append("\nNAME
>> " + this.name);
result.append("\nFILES >> " + this.files .toString());
return result.toString();
}
}
/*
* dataItem.java
*
* This class representates a multi-purpose item consiting of the following stuff
*
* - key
(String)
* - value
(String)
* - description
(String)
*
* -> ... every variable has its get ans set methods
*
* Created on 18. April 2002, 20:20
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> is f ree 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.
*
* Foobar is dist ributed 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ----------------------------------------------------------------------- ----*/
package server;
import java.lang.*;
/**
* Represents a dataItem
* @author [email protected]
* @version 0.2
*/
public class dataItem {
private String tkey ;
private String tdescription;
private String tvalue;
/**
* Constructors for a new projectdataItem
* -> holds:
* String key
* String value
* String description
*/
public dataItem(String key,String value,String description) {
Autor: Thomas Schädler
261
Anhang B: Quelltext <xmlizer> server
tkey = key;
tvalue = value;
tdescription = description ;
}
public dataItem(String key,String value) {
tkey = key;
tvalue = value;
tdescription = new String();
}
public dataItem(String key) {
tkey = key;
tvalue = new String();
tdescription = new String();
}
public dataItem() {
tkey = new String();
tvalue = new String();
tdescription = new String();
}
//STRING REPRESENTATION
//---------------------------------------------------------- ------------------------------------/**
* By default show the key as String
*/
public String toString() {
return "\ndataItem : key
= " + tkey + "\n"
+ "
: value
= " + tvalue + "\n"
+ "
: description = " + tdescription + "\n";
}
//GET AND SET METHODS
//----------------------------------------------------------------------------------------------/**
* Returns the key of the item
*/
public String getKey() {
return tkey;
}
/**
* Get the description of the item
*/
public String getDescription() {
return tdescription;
}
/**
* Get the value of the item
*/
public String getValue() {
return tvalue;
}
/**
* Set a new key
*/
public void setKey(String s) {
tkey = s;
}
/**
* Set a new description
*/
public void setDescription(String s ) {
tdescription = s;
}
/*
* Set a new v alue
*/
public void setValue(String s) {
tvalue = s;
}
}
/*
* CgiParser.java
*
* Created on 4. August 2002, 00:40
*
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------* This appears in Core Web Programming from
* Prentice Hall Publishers, and may be freely used
* or adapted. 1997 Marty Hall, [email protected].
*/
package server;
import java.net.*;
import java.util.*;
Autor: Thomas Schädler
262
Anhang B: Quelltext <xmlizer> server
/**
* Parses the CGI QueryString
* @author [email protected]
* @version 0.2
*/
public class CgiParser {
private String data , delims1, delims2;
private String [] nameArray, valueArray;
private String [][] fullValueArray;
public CgiParser(String data,String delims1,String delims2) {
this.data = data;
this.delims1 = delims1;
this.delims2 = delims2;
}
public LookupTable parse () {
Vector nameVector = new Vector();
Vector valueVector = new Vector ();
if (data == null) {
return (buildTable(nameVector,valueVector,0));
}
StringTokenizer tok = new StringTokenizer (data, delims1);
String nameValuePair , name, value;
StringTokenizer tempTok;
int index, numNames=0;
Vector values;
while(tok.hasMoreTokens()) {
nameValuePair = tok.nextToken();
tempTok = new StringTokenizer(nameValuePair,delims2);
name = URLDecoder.decode(tempTok.nextToken ());
if (tempTok.hasMoreTokens()) {
value = URLDecoder .decode(tempTok.nextToken ());
}
else {
value = "";
}
index = nameVector.indexOf(name);
if (index == -1) {
nameVector.addElement(name);
values = new Vector();
values.addElement(value );
valueVector.addElement(values);
numNames++;
}
else {
values = (Vector)valueVector.elementAt (index);
values.addElement(value );
}
}
return(buildTable(nameVector,
valueVector,
numNames));
}
private LookupTable buildTable (Vector nameVector,Vector valueVector,int numNames ) {
nameArray = new String[numNames ];
valueArray = new String[numNames];
fullValueArray = new String[numNames ][];
LookupTable table = new LookupTable(nameArray,valueArray ,fullValueArray );
String[] fullValues;
Vector values;
for(int i=0; i<nameVector.size(); i++) {
nameArray[i] = (String )nameVector.elementAt(i);
values = (Vector )valueVector.elementAt(i);
valueArray[i] = (String)values.firstElement();
fullValues = new String[values.size()];
values .copyInto(fullValues);
fullValueArray[i] = fullValues;
}
return(table);
}
}
/*
* LookupTable.java
*
* Created on 4. August 2002, 00:40
*
* -------------------- -------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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 Softw are Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------* This appears in Core Web Programming from
* Prentice Hall Publishers, and may be freely used
* or adapted. 1997 Marty Hall, [email protected].
*/
package server;
/**
* Holds the parsed Querystring
Autor: Thomas Schädler
263
Anhang B: Quelltext <xmlizer> server
* @author [email protected]
* @version 0.2
*/
public class LookupTable {
private String [] nameArray, valueArray;
private String [][] fullValueArray;
public LookupTable(String[] nameArray,
String[] valueArray ,
String[][] fullValueArray) {
this.nameArray = nameArray ;
this.valueArray = valueArray;
this.fullValueArray = fullValueArray ;
}
public String[] getNames () {
return(nameArray);
}
public String[] getValues() {
return(valueArray);
}
public String[][] getFullValues() {
return(fullValueArray);
}
// Although this is O(N) and HashTable would
// be O(1), N is typically so small that a HashTable
// is the same or slower.
// null -- no such name. Empty string -- name
// supplied with empty value.
public String getValue(String name) {
for(int i=0; i<nameArray.length ; i++)
if (nameArray[i].equals(name))
return(valueArray[i]);
return(null);
}
public String[] getFullValue(String name ) {
for(int i=0; i<nameArray.length ; i++)
if (nameArray[i].equals(name))
return(fullValueArray[i]);
return(null);
}
public int numValues(String name) {
String[] values = getFullValue(name);
if (values == null)
return (0);
else
return (values.length);
}
public String toHTML() {
StringBuffer buff = new StringBuffer ();
if (nameArray.length > 0) {
buff.append ("<H4>DEBUG: Parameter data supplied:</h4>\n" +
"<CENTER>\n" +
"<TABLE BORDER=1>\n" +
" <TR><TH>Name<TH>Value(s)");
}
else {
buff.append ("<H4>DEBUG: No Parameter data supplied.</H4>" );
}
String name, value;
for(int i=0; i<nameArray.length ; i++) {
name = nameArray [i];
buff.append (" <TR><TD>" + name);
if (numValues(name) > 1) {
String[] fullValue = getFullValue (name);
buff.append("
<TD>Multiple values supplied: \n
for(int j=0; j<fullValue.length; j++) {
buff.append("
<LI>" + fullValue[j]);
}
buff.append("
</UL>");
}
else {
value = valueArray [i];
if (value.equals("")) {
buff.append("
<TD><I>No Value Supplied</I>");
}
else {
buff.append("
<TD>" + value);
}
}
}
buff.append("</TABLE>\n</CENTER>");
return buff.toString ();
}
<UL>");
}/*
* ProjectManager.java
*
* Created on 4. August 2002, 17:41
*
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
Autor: Thomas Schädler
264
Anhang B: Quelltext <xmlizer> server
* 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
import
import
import
import
import
java.io.*;
org.jdom.*;
org.jdom.input.SAXBuilder;
org.jdom.output.XMLOutputter;
java.util.*;
/**
* Manages the projectData
* @author [email protected]
* @version 0.2
*/
public class ProjectManager {
private String path ;
private projectData data ;
private String db2xmlMapping;
private boolean hasMappingDB2XML = false ;
private boolean hasMappingSMDBE = false;
private static String SPACER = new String("
");
public static String XMLSMDBEFILEDTD = "xmlizer.smdbe.verbose.dtd";
public static String XMLSMDBEFILEROOT = "database" ;
/** Creates new ProjectManager */
public ProjectManager(String projectfilepath) throws Exception {
this.path = projectfilepath;
this.data = new projectData();
init();
}
/**
* init the data from the file xmlizer.xml
**/
private boolean init() throws Exception {
//set the data with the given path
return getProjectData().readFromFile (path);
}
public projectData getProjectData() {
return this.data;
}
//DB2XML
//---------------------------/**
* Returns the output as XML for the module DB2XML
*/
public StringBuffer getXML_DB2XML(String basedirectory,Hashtable userParams ) throws Exception {
getMappingDB2XML(basedirectory,userParams );
return new StringBuffer(db2xmlMapping);
}
private void getMappingDB2XML(String basedirectory ,Hashtable userParams) throws Exception {
if (!hasMappingDB2XML) {
Vector onexml = (Vector)this.data.getXML();
xmlItem xmlitem = (xmlItem)onexml.get(0);
String thefilename = basedirectory + xmlitem.getFile();
//System.out.println(thefilename);
Document thedoc = getFileAsXMLDOM(thefilename,false);
//make the mapping
XMLSchemaParser schemaparser = new XMLSchemaParser(this);
schemaparser.parse(thedoc);
schemaparser.buildInstance(userParams );
Document doc = schemaparser .getInstance();
if (doc != null) {
XMLOutputter fmt = new XMLOutputter("
",true);
this.db2xmlMapping = fmt.outputString(doc);
//set and return
hasMappingDB2XML = true;
}
else {
throw new Exception("unspecified xml document parsing error");
}
}
}
public Document getFileAsXMLDOM(String filename,boolean validating) throws Exception {
try {
SAXBuilder builder = new SAXBuilder(validating); //true -> validating against dtd
Document jdoc = builder.build(filename);
return jdoc;
}
catch (JDOMException e) {
throw new Exception(e.getLocalizedMessage());
}
}
//SMDBE
//---------------------------/**
* Returns the output as XML for the module SMDBE
*/
public StringBuffer getXML_SMDBE(String dbname) throws Exception {
dbItem item = this.data.getDBByName(dbname);
Autor: Thomas Schädler
265
Anhang B: Quelltext <xmlizer> server
String otype = item.SMDBEgetOutputType();
if (otype.equalsIgnoreCase ("simple")) {
return outputXMLResultSimple(item,item.SMDBEgetSelectedTables());
}
else if (otype.equalsIgnoreCase ("verbose" )) {
return outputXMLResultVerbose(item,item.SMDBEgetSelectedTables ());
}
else throw new Exception("unsupported output type in configuration: " + otype);
}
/**
* Generates Simple DB Export XML from a selected DB and writes it to a temporary file
* Therfore it uses no DTD and writes just plain XML without any extra data
* @return a stringbuffer filled with the xml output
*/
private StringBuffer outputXMLResultSimple(dbItem theDB ,Vector tables) throws Exception {
StringBuffer out = new StringBuffer();
//add the header and doctype
out.append ("<?xml version= \"1.0\" encoding=\"UTF-8\"?>\n");
//add the <database name="dbname" url="dburl"> tag
out.append (
"<database name=\""
+Start.htmlEncode(theDB.getName())
//+"\" url=\""
//+Start.htmlEncode(theDB.getUrl())
+"\">\n"
);
//tables setup
out.append (SPACER+"<tables>\n");
//for all tables
for (Enumeration e = tables.elements (); e.hasMoreElements();) {
//add the <table name="tablename"> tag
String this_table = (String )e.nextElement();
out.append(SPACER+SPACER+"<"+this_table+">\n");
try {
Hashtable theTable = theDB.querySilent ("SELECT * FROM " + this_table );
final String data[][] = (String[][])theTable.get("table");
final int rows = ((Integer)theTable.get("rows")).intValue();
final int cols = ((Integer)theTable.get("cols")).intValue();
final Vector columnnames = (Vector)theTable .get("columnlabels");
//for each row of this table
for(int i=0;i<rows;i++) {
out.append(SPACER+SPACER +SPACER+"<row>\n");
//for each column of the row
String encoded ;
String colname ;
for(int j=0;j<cols;j++) {
colname = Start .htmlEncode((String)columnnames.get(j));
out.append (SPACER+SPACER+SPACER+SPACER+"<"+colname+">");
encoded = Start .htmlEncode((String)data[j][i]);
out.append (encoded);
out.append ("</"+colname+">\n");
}
out.append(SPACER+SPACER +SPACER+"</row>\n");
}
out.append(SPACER+SPACER+"</"+this_table+">\n");
}
catch (Exception eq) {
throw new Exception(eq.getLocalizedMessage());
}
}
out.append (SPACER+"</tables>\n");
out.append ("</database>\n");
return out;
}
/**
* Generates Simple DB Export XML from a selected DB and writes it to a temporary file
* @return a temprary file filled with XML
*/
private StringBuffer outputXMLResultVerbose(dbItem theDB,Vector tables ) throws Exception {
StringBuffer out = new StringBuffer();
//add the header and doctype
out.append ("<?xml version= \"1.0\" encoding=\"UTF-8\"?>\n");
//out.append("<!DOCTYPE database SYSTEM \""+XMLSMDBEFILEDTD+" \">\n");
//add the <database name="dbname" url="dburl"> tag
out.append (
"<database name=\""
+Start.htmlEncode(theDB.getName())
//+"\" url=\""
//+Start.htmlEncode(theDB.getUrl())
+"\">\n"
);
//tables setup
out.append (SPACER+"<tables>\n");
//for all tables
for (Enumeration e = tables.elements (); e.hasMoreElements();) {
//add the <table name="tablename"> tag
String this_table = (String )e.nextElement();
out.append(SPACER+SPACER+"<table name=\""+this_table +"\">\n");
try {
Hashtable theTable = theDB.querySilent ("SELECT * FROM " + this_table );
final String data[][] = (String[][])theTable.get("table");
final int rows = ((Integer)theTable.get("rows")).intValue();
final int cols = ((Integer)theTable.get("cols")).intValue();
final Vector columnnames = (Vector)theTable .get("columnlabels");
Autor: Thomas Schädler
266
Anhang B: Quelltext <xmlizer> server
final Vector columntypes = (Vector)theTable .get("columntypes");
//for each row of this table
for(int i=0;i<rows;i++) {
out.append(SPACER+SPACER +SPACER+"<row>\n");
//for each column of the row
String encoded ;
for(int j=0;j<cols;j++) {
out.append (SPACER+SPACER+SPACER+SPACER+"<column");
encoded = Start .htmlEncode((String)columnnames.get(j));
out.append (" name=\""+encoded+"\"");
encoded = Start .htmlEncode((String)columntypes.get(j));
out.append (" type=\""+encoded+"\"");
encoded = Start .htmlEncode((String)data[j][i]);
out.append (" data=\""+encoded+"\"/>\n");
}
out.append(SPACER+SPACER +SPACER+"</row>\n");
}
out.append(SPACER+SPACER+"</table>\n");
}
catch (Exception eq) {
throw new Exception(eq.getLocalizedMessage());
}
}
out.append (SPACER+"</tables>\n");
out.append ("</database>\n");
return out;
}
}
/*
* projectData.java
*
* This projectData container contains all neccessary methods to deal
* with the projectData management
*
* Created on 5. April 2002, 16:30
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
import
import
import
import
import
import
import
java.io.*;
java.util.*;
java.lang.*;
javax.swing .*;
org.jdom.*;
org.jdom.input.SAXBuilder;
org.jdom.output.XMLOutputter;
/**
* Represents the projectData
* @author [email protected]
* @version 0.2
*/
public class projectData {
public static String XMLPROJECTFILEDTD = "xmlizer.project.config.dtd";
public static String XMLPROJECTFILEROOT = "xmlizerprojectconfig";
private
private
private
private
private
Vector initial = new Vector (0);
//holds dataItems
Vector xml = new Vector(0);
//holds xmlItems
Vector dbs = new Vector(0);
//holds dbItems
DB2XMLmapping mapping = new DB2XMLmapping();
//holds the mapping-info for the DB2XML-Module
Vector simpleItems = new Vector(); //of dbItems
//CONSTRUCTOR
//----------------------------------------------------------------------------------------------/**
* Creates new projectData (Constructor)
*/
public projectData() {
//init here if neccessary
}
//INITIAL MANAGEMENT
//----------------------------------------------------------------------------------------------/**
* Returns a Vector -> project variables as dataItems
*/
public Vector getInitial () {
return initial;
}
public void addInitial(dataItem dataitem ) {
initial.add(dataitem );
}
public dataItem getInitialByKey(String key) {
for (Enumeration e = this.initial.elements(); e.hasMoreElements();) {
dataItem item = (dataItem)e.nextElement();
if (item.getKey().equalsIgnoreCase(key)) {
return item;
Autor: Thomas Schädler
267
Anhang B: Quelltext <xmlizer> server
}
}
return null;
}
public void setInitialByKey(String key,String new_value ) {
for (Enumeration e = this.initial.elements(); e.hasMoreElements();) {
dataItem item = (dataItem)e.nextElement();
if (item.getKey().equalsIgnoreCase(key)) {
item.setValue(new_value );
return;
}
}
dataItem newitem = new dataItem ();
newitem.setKey(key);
newitem.setValue(new_value );
addInitial (newitem);
System.out.println("Added new Item: " + key + " [" + new_value + "]");
}
//XML FILES MANAGEMENT
//----------------------------------------------------------------------------------------------/**
* Returns a Vector -> XML-Files as String (whole path or url)
*/
public Vector getXML() {
return xml;
}
public void addXML(xmlItem xmlitem) {
xml.add(xmlitem);
}
public void removeXML(String identifier) {
for (Enumeration e = xml.elements(); e.hasMoreElements();) {
xmlItem xmlitem = (xmlItem)e.nextElement();
if (xmlitem.getName().equalsIgnoreCase(identifier)) {
xml.remove(xmlitem );
break;
}
}
}
public void setXML(Vector newXML) {
xml = newXML;
}
//DATABASE MANAGEMENT
//----------------------------------------------------------------------------------- -----------/**
* Returns a Vector -> databases as dbItem
*/
public Vector getDB () {
return dbs;
}
public void addDB(dbItem dbitem) {
dbs.add(dbitem);
}
public void removeDB(String identifier) {
for (Enumeration e = dbs.elements(); e.hasMoreElements();) {
dbItem dbitem = (dbItem)e.nextElement ();
if (dbitem.getName().equalsIgnoreCase (identifier)) {
dbitem.closeConnection();
dbs.remove(dbitem);
break;
}
}
}
public void setDB(Vector newDB ) {
dbs = newDB;
}
public dbItem getDBByName(String name) {
for (Enumeration e = this.dbs.elements(); e.hasMoreElements();) {
dbItem item = (dbItem)e.nextElement();
if (item.getName().equalsIgnoreCase(name)) {
return item;
}
}
return null;
}
//OBJECT FINALIZATION (CLEANUP)
//----------------------------------------------------------------------------------------------/**
* Do the cleanup before diposing
*/
public void finalize() {
//close all connections
for (Enumeration e = dbs.elements(); e.hasMoreElements();) {
dbItem dbitem = (dbItem)e.nextElement ();
dbitem .closeConnection ();
}
}
//STRING REPRESENTATION
//----------------------------------------------------------------------------------------------public String toString() {
StringBuffer result = new StringBuffer("FULL PROJECTDATA >>\n");
for (Enumeration e = this.initial.elements(); e.hasMoreElements();) {
dataItem item = (dataItem)e.nextElement();
result .append(item);
}
for (Enumeration e = this.xml.elements(); e.hasMoreElements();) {
result .append("\nXML >> " + e.nextElement());
}
for (Enumeration e = this.dbs.elements(); e.hasMoreElements();) {
dbItem item = (dbItem)e.nextElement();
result .append(item);
Autor: Thomas Schädler
268
Anhang B: Quelltext <xmlizer> server
}
return result.toString();
}
//XML REPRESENTATION
//----------------------------------------------------------------------------------------------/**
* Checks the doctype of the XML-File (just to be sure to read the right information)
*/
private boolean checkDocType(DocType dt,String rootelement,String systemdtd ) {
if (dt.getElementName().equalsIgnoreCase(rootelement) && dt.getSystemID ().equalsIgnoreCase(systemdtd)) {
return true;
}
else {
return false;
}
}
public Vector getSimpleItems() {
return this.simpleItems;
}
/*
* Reads an XML file (which must be of type xmlizer.project.config.dtd) and
* fills all information in the projectdata
*
* @param The filename as String
*/
synchronized public boolean readFromFile (String filename) throws Exception {
boolean docOK = false;
try {
SAXBuilder build er = new SAXBuilder(true);
Document jdoc = builder.build(filename);
//true -> validating against dtd
DocType docType = jdoc.getDocType();
docOK = checkDocType(docType,XMLPROJECTFILEROOT ,XMLPROJECTFILEDTD);
String mappingModule = null;
if (docOK) {
//get the root
Element root = jdoc.getRootElement();
//get the initialsetup
Element initsetup = root.getChild ("initialsetup" );
java.util.List initlist = initsetup.getChildren("inititem" );
Iterator init_iter = initlist.iterator ();
while (init_iter.hasNext()) {
Element init_item = (Element) init_iter .next();
dataItem initialdataitem = new dataItem ();
if (init_item.getAttributeValue("key").equalsIgnoreCase("module" )) {
mappingModule = init_item .getTextTrim();
//save the mapping module info
}
initialdataitem.setKey(init_item.getAttributeValue("key"));
initialdataitem.setValue (init_item .getTextTrim());
addInitial(initialdataitem);
}
//get the databasesetup
Element dbsetup = root.getChild("databasesetup");
java.util.List dblist = dbsetup.getChildren ("dbitem");
Iterator db_iter = dblist.iterator();
while (db_iter.hasNext()) {
Element db_item = (Element) db_iter.next();
dbItem initialdbitem = new dbItem();
initialdbitem.setName(db_item.getChild("name").getTextTrim());
initialdbitem.setDriver(db_item.getChild("driver" ).getTextTrim());
initialdbitem.setUrl(db_item.getChild("url").getTextTrim());
initialdbitem.setTimeout (db_item.getChild("timeout").getTextTrim ());
initialdbitem.setUsername(db_item.getChild("username").getTextTrim());
initialdbitem.setPassword(db_item.getChild("password").getTextTrim());
addDB(initialdbitem );
}
//get the schemasetup
Element xmlsetup = root.getChild("schemasetup");
java.util.List xmllist = xmlsetup .getChildren("xmlitem");
Iterator xml_iter = xmllist.iterator();
while (xml_iter.hasNext()) {
Element xml_item = (Element) xml_iter.next();
xmlItem xmlitem = new xmlItem();
xmlitem.setName(xml_item .getChild("name").getTextTrim());
xmlitem.setFile(xml_item .getChild("file").getTextTrim());
addXML(xmlitem );
}
//get the mapping information depending on mappingModule
if(mappingModule != null) {
Element maproot = root.getChild("mapping");
if (maproot != null) {
Autor: Thomas Schädler
269
Anhang B: Quelltext <xmlizer> server
if (mappingModule.equalsIgnoreCase("Simple DB Export")) {
Element smdberoot = maproot.getChild ("smdbe");
java.util.List smdbeitemlist = smdberoot.getChildren("smdbe_item");
Iterator smdbe_iter = smdbeitemlist.iterator();
String dbName = null;
String level = null;
while (smdbe_iter.hasNext()) {
Element smdbe_item = (Element) smdbe_iter.next();
dbName = smdbe_item.getAttributeValue ("name");
level = smdbe_item.getAttributeValue("type");
//<smdbe_item name="dbname">
java.util.List smdbetablelist = smdbe_item .getChildren("smdbe_table" );
Iterator smdbetable_iter = smdbetablelist.iterator();
Vector selTab = new Vector();
while (smdbetable_iter .hasNext()) {
Element smdbe_table_item = (Element) smdbetable_iter.next();
selTab.add(smdbe_table_item.getTextTrim());
}
if (selTab.size()>0 && dbName != null && level != null) {
dbItem selDB = getDBByName(dbName );
selDB.SMDBEsetSelectedTables (selTab);
selDB.SMDBEsetOutputType(level);
this.simpleItems.add(selDB);
//System.out.println(dbName + " : " + selTab.toString());
}
}
}
else if (mappingModule.equalsIgnoreCase("Database to XML")) {
Element db2xmlroot = maproot.getChild("db2xml" );
String elementRoot = db2xmlroot .getAttributeValue("rootelement");
if (elementRoot != null) {
mapping.setRootElement (elementRoot);
}
//parameters
java.util.List para_list = db2xmlroot.getChildren("db2xml_parameter");
Iterator para_iter = para_list.iterator();
while (para_iter .hasNext()) //for all db2xml_element tags
{
Element p_item = (Element) para_iter.next();
String parID = p_item.getAttributeValue("id");
String parName = p_item.getAttributeValue("name ");
String parValue = p_item.getAttributeValue ("default" );
//mark this element as loaded -> no dirty check while parsing.
mapping.addParameterFromLoad(parID,parName,parValue);
}
//elements
java.util.List element_list = db2xmlroot.getChildren("db2xml_element");
Iterator element_iter = element_list .iterator();
String el_name = null;
String el_rep = null;
String el_id = null;
while (element_iter.hasNext()) //for all db2xml_element tags
{
Element el_item = (Element) element_iter.next();
//<db2xml_element id="id" name="el_name">
el_name = el_item.getAttributeValue("name" );
el_id = el_item.getAttributeValue("id");
//mark this element as loaded -> no dirty check while parsing.
mapping.addElementFromLoad(el_name,el_id);
//build repetition
el_rep = el_item.getAttributeValue("repsql");
if (el_rep != null) {
mapping.addElementRepFromLoad(el_id,el_rep);
}
//build content
Element content_el = el_item.getChild ("db2xml_content");
if (content_el != null) {
String temp_mapid = content_ el.getAttributeValue ("mapid");
String temp_mapinfo = content_el.getAttributeValue("mapinfo");
SchemaContent temp_cont = new SchemaContent (el_id,temp_mapid,temp_mapinfo);
mapping.addContentFromLoad(el_id,temp_cont);
//System.out.println("Added content: " + temp_cont.toString());
}
//build attributes
java.util.List attr_list = el_item.getChildren("db2xml_attribute");
Iterator attr_iter = attr_list.iterator();
while (attr_iter.hasNext()) //for all db2xml_attribute tags
{
Element attr_item = (Element) attr_iter.next();
String temp_attr_name = attr_item .getAttributeValue("name" );
String temp_mapid = attr_item.getAttributeValue("mapid");
String temp_mapinfo = attr_item.getAttributeValue("mapinfo");
SchemaAttribute temp_attr = new SchemaAttribute(temp_attr_name,temp_mapid,temp_mapinfo);
mapping.addAttributeFromLoad (el_id,temp_attr);
//System.out.println("Added attr: " + temp_attr.toString());
}
//build sql
java.util.List sql_list = el_item.getChildren("db2xml_sql");
Iterator sql_iter = sql_list.iterator ();
while (sql_iter.hasNext()) //for all db2xml_sql tags
{
Element sql_item = (Element) sql_iter.next();
String temp_db_name = sql_item.getAttributeValue ("db");
Autor: Thomas Schädler
270
Anhang B: Quelltext <xmlizer> server
String temp_sql = sql_item.getAttributeValue("sql");
String temp_id = sql_item.getAttributeValue ("id");
SQLStatement temp_stat = new SQLStatement(temp_db_name,temp_sql,temp_id);
//System.out.println("Added: " + temp_stat.toString());
java.util.List tsql_list = sql_item.getChildren("db2xml_sql_info");
Iterator tsql_iter = tsql_list.iterator();
while (tsql_iter.hasNext()) //for all db2xml_sql_info tags
{
Element tsql_item = (Element) tsql_iter .next();
String temp_col_name= tsql_item.getAttributeValue ("name");
String temp_col_type = tsql_item.getAttributeValue("type");
temp_stat .addColName(temp_col_name );
temp_stat .addColType(temp_col_type );
//System.out.println("NAME="+temp_col_name+" >> TYPE="+temp_col_type);
}
mapping.addSQLFromLoad(el_id ,temp_stat );
//System.out.println("READ FROM FILE: " + el_id + " > " + temp_stat.toString());
}
}
}
}
}
return true;
}
else {
return false ;
}
}
catch (JDOMException e) {
throw new Exception(e.getLocalizedMes sage());
}
}
/**
* Return the data as String
*/
public String getAsXMLText() {
Document jdoc = this.getAsXMLDocumentJDOM ();
org.jdom.output .DOMOutputter outp = new org.jdom.output.DOMOutputter();
XMLOutputter fmt = new XMLOutputter("
return fmt.outputString(jdoc);
",true);
}
/**
* Return the data as XML Document (org.w3c.dom.Document)
*/
public org.w3c.dom.Document getAsXMLDocumentW3C() {
Document jdoc = this.getAsXMLDocumentJDOM ();
org.jdom.output .DOMOutputter outp = new org.jdom.output.DOMOutputter();
try {
org.w3c.dom.Document result = outp.output(jdoc);
return result; //and return the result
}
catch (JDOMException e) {
System .out.println("DOM Serializer error for debug output!");
return null;
}
}
/**
* Return the data as XML Document org.jdom.Document
*/
public Document getAsXMLDocumentJDOM() {
//MAKE DOCTYPE
DocType docType = new DocType(XMLPROJECTFILEROOT,XMLPROJECTFILEDTD );
Element root = new Element (XMLPROJECTFILEROOT);
//initialsetup
Element init = new Element ("initialsetup" );
for (Enumeration e = this.initial.elements(); e.hasMoreElements();) {
dataItem ditem = (dataItem)e.nextElement();
Element init_item = new Element("inititem" ).setText(ditem .getValue());
init_item.setAttribute ("key",ditem.getKey());
init.addContent(init_item);
}
root.addContent (init);
//db setup
Element dbitems = new Element("databasesetup");
for (Enumeration e = this.dbs.elements(); e.hasMoreElements();) {
dbItem dbitem = (dbItem)e.nextElement ();
Element db_item = new Element("dbitem");
db_item.addContent(new
db_item.addContent(new
db_item.addContent(new
db_item.addContent(new
db_item.addContent(new
db_item.addContent(new
Element("name" ).setText(dbitem.getName()));
Element("driver").setText(dbitem.getDriver()));
Element("url").setText(dbitem .getUrl()));
Element("timeout").setText(dbitem.getTimeout ()));
Element("username").setText(dbitem .getUsername()));
Element("password").setText(dbitem .getPassword()));
dbitems.addContent(db_item);
}
root.addContent (dbitems);
//schema setup
Element schms = new Element("schemasetup" );
Autor: Thomas Schädler
271
Anhang B: Quelltext <xmlizer> server
for (Enumeration e = this.xml.elements(); e.hasMoreElements();) {
xmlItem sitem = (xmlItem)e.nextElement();
Element schms_item = new Element("xmlitem" );
schms_item.addContent(new Element("name").setText(sitem.getName()));
schms_item.addContent(new Element("file").setText(sitem.getFile()));
schms.addContent (schms_item );
}
root.addContent (schms);
//module mapping setup
Element mapping = null;
try {
mapping = getMapping();
}
catch(Exception ex) {
System .out.println("getMapping() in projectData == NULL, should only happen if there is an error in the DB2XML
Mapping.");
mapping = null;
}
if (mapping != null) {
root.addContent(mapping);
}
Document doc = new Document(root,docType);
return doc; //and return the doc
}
/**
* Get the DB2XML-Mapping
*/
public DB2XMLmapping DB2XMLgetmapping() {
return this.mapping;
}
/** Resets the whole mapping info (handle with care) */
public void DB2XMLclearmapping () {
this.mapping = new DB2XMLmapping();
}
/**
* Returns the mapping element filled with the xml -mapping-data
* for the currently selected module
*/
private Element getMapping() {
dataItem datitem = (dataItem)getInitialByKey("module");
String mappingName = datitem.getValue();
if (mappingName .equalsIgnoreCase("Simple DB Export" )) {
//Simple DB Export Mapping buildup
Element wrapper = new Element("mapping");
Element smdbe_wrapper = new Element("smdbe");
boolean NONempty = false; //set true for not null output
for (Enumeration e = this.dbs.elements(); e.hasMoreElements();) {
dbItem dbitem = (dbItem )e.nextElement();
Vector selTab = (Vector )dbitem.SMDBEgetSelectedTables ();
if (selTab.size()>0) {
Element curr_db = new Element("smdbe_item");
curr_db.setAttribute("name",dbitem .getName());
curr_db.setAttribute("type",dbitem .SMDBEgetOutputType());
for (Enumeration enum = selTab.elements (); enum.hasMoreElements();) {
NONempty = true;
curr_db.addContent(new Element("smdbe_table").setText((String)enum.nextElement()));
}
smdbe_wrapper.addContent (curr_db);
}
}
wrapper.addContent(smdbe_wrapper );
if (NONempty) {
return wrapper;
}
else {
return null;
}
}
else if (mappingName .equalsIgnoreCase("Database to XML")) {
//Database to XML buildup
return this.mapping.getMapping();
}
else {
//failsafe only, should NEVER happen, though
return null;
}
}
}/*
* DB2XMLmapping.java - UNTOUCHED
*
* This class contains all neccessary information on the mapping of the module
* DB2XML (for building it and getting it for save)
*
* Created on 15. Juni 2002, 13:38
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
Autor: Thomas Schädler
272
Anhang B: Quelltext <xmlizer> server
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
import java.util.*;
import org.jdom.*;
/**
* Represents the projectData
* @author [email protected]
* @version 0.2
*/
public class DB2XMLmapping {
private String rootElement = null;
private Vector otherElements = new Vector(); //of SchemaElements
private Hashtable loadedElementNames = new Hashtable(); //of key=id,value=name(ambigous)
private Hashtable loadedAttributes = new Hashtable (); //of SchemaAttri butes
private Hashtable loadedSQL = new Hashtable(); //of SQLStatements
private Hashtable loadedReps = new Hashtable(); //of Strings key=elementid,value=sqlid
private Hashtable loadedContent = new Hashtable(); //of SchemaContent
private Hashtable loadedParameters = new Hashtable (); //of ParameterInfo
/** Creates new DB2XMLmapping */
public DB2XMLmapping(){}
public DB2XMLmapping(String rootElementName) {
this.rootElement = rootElementName;
}
/*
* Set the root element
*/
public void setRootElement(String rootElementName) {
this.rootElement = rootElementName;
}
/**
* Adds a repetition info for the specified element to the list
* a Hashtable with key=elementname,value=sqlid/mapid
*/
public void addElementRepFromLoad(String elementid ,String sqlid) {
this.loadedReps .put(elementid,sqlid);
}
public Hashtable getLoadedReps () {
return this.loadedReps;
}
/**
* Adds an element name to the list of known elements
*/
public void addElementFromLoad (String name,String id) {
if (id!= null && name != null) {
this.loadedElementNames.put(id,name);
}
}
/**
* Adds an Element to the list and returns true if new (not loaded from xmlizer.xml) else false
*/
public boolean addElement(SchemaElement el) {
if (el != null) {
if (this.loadedElementNames .containsKey(el.getID())) {
this.otherElements .add(el);
//System.out.println(el.getID() + " -> " + el.getRealName() + " known & added");
return false ;
}
else {
this.otherElements .add(el);
//System.out.println(el.getID() + " -> " + el.getRealName() + " added");
return true;
}
}
else return false;
}
public Vector getElements() {
return this.otherElements;
}
/*
* Set the root element
*/
public String getRootElement() {
return rootElement;
}
/**
* adds a SQLStatement to the list
*/
public void addSQLFromLoad(String id, SQLStatement statement ) {
if (this.loadedSQL.containsKey(id)) //add to Vector
{
Vector temp_vec = (Vector)this.loadedSQL.get(id);
Autor: Thomas Schädler
273
Anhang B: Quelltext <xmlizer> server
temp_vec.add(statement );
//System.out.println("addSQLFromLoad NEW: " + statement.toString());
}
else //add new Vector with current SQLStatement as first one
{
Vector temp_vec = new Vector();
temp_vec.add(statement );
this.loadedSQL.put(id,temp_vec);
//System.out.println("addSQLFromLoad ADD: " + statement.toString());
}
}
/**
* Return a Hashtable full of happy SQLStatements
* key: elementname (to attach to) + attributename (combined key)
* value: SQLStatement
*/
public Hashtable getLoadedSQL() {
return this.loadedSQL;
}
/**
* Returns the appropriate SQLStatement for a mapid
*/
public SQLStatement getSQLStatementByMapID(String mapid ) {
for (Enumeration e = this.loadedSQL.elements(); e.hasMoreElements();) {
Vector element = (Vector)e.nextElement();
for (Enumeration ee = element.elements(); ee.hasMoreElements();) {
SQLStatement item = (SQLStatement )ee.nextElement ();
if (item.getID().equalsIgnoreCase (mapid)) {
return item;
}
}
}
return null;
}
/**
* adds a SchemaAttribute to the list
*/
public void addAttributeFromLoad(String id, SchemaAttribute attr) {
this.loadedAttributes.put(id + attr.getName(),attr);
}
/**
* returns the parameters (hashtabel key=id,value=ParameterInfo
*/
public Hashtable getParameters () {
return this.loadedParameters;
}
/**
* Returns the appropriate SQLStatement for a mapid
*/
public ParameterInfo getParameterByMapID (String mapid) {
for (Enumeration e = this.loadedParameters.elements (); e.hasMoreElements();) {
ParameterInfo item = (ParameterInfo)e.nextElement();
if (item.getID().equalsIgnoreCase(mapid)) {
return item;
}
}
return null;
}
/**
* adds a ParameterInfo to the list
* returns true if add was successfull
* else false (= no insert)
*/
public boolean addParameterFromLoad (String id , String name, String value) {
if (!this.loadedParameters .containsKey(name)) {
//System.out.println("NOT FOUND - ADDING");
this.loadedParameters.put(name,new ParameterInfo(id,name,value ));
return true;
}
else { /*System.out.println("FOUND - DO NOTHING");*/ return false; }
}
/**
* Removes the specified (name) parameter
*/
public boolean removeParameter (String name_to_remove) {
if (this.loadedParameters.containsKey(name_to_remove)) {
this.loadedParameters.remove(name_to_remove);
return true;
}
else return false;
}
/**
* adds a SchemaContent to the list
*/
public void addContentFromLoad (String id , SchemaContent cont ) {
this.loadedContent.put(id,cont);
}
/**
* Return a Hashtable full of happy SchemaAttributes
* key: elementname (which it belongs to) + attributename
* value: SchemaAttribute
*/
public Hashtable getLoadedAttributes() {
Autor: Thomas Schädler
274
Anhang B: Quelltext <xmlizer> server
return this.loadedAttributes;
}
/**
* Return a Hashtable full of happy SchemaContent
* key: elementname (which it belongs to)
* value: SchemaContent
*/
public Hashtable getLoadedContent() {
return this.loadedContent;
}
public Element getMapping() {
if (this.rootElement == null)
//check for validity
{
return null;
}
else {
//DB2XML Mapping buildup
Element wrapper = new Element("mapping");
Element db2xml_wrapper = new Element("db2xml");
//root element
db2xml_wrapper.setAttribute ("rootelement",this.rootElement);
wrapper.addContent(db2xml_wrapper);
//add the parameters
for (Enumeration e = this.loadedParameters .elements(); e.hasMoreElements ();) {
ParameterInfo item = (ParameterInfo)e.nextElement();
Element curr = new Element("db2xml_parameter");
curr.setAttribute("id",item.getID ());
curr.setAttribute("name",item.getName());
curr.setAttribute("default",item.getValue());
db2xml_wrapper.addContent(curr);
}
//add the elements
for (Enumeration e = this.otherElements.elements(); e.hasMoreElements();) {
SchemaElement item = (SchemaElement)e.nextElement();
Element curr = new Element("db2xml_element" );
curr.setAttribute("name",item.getRealName());
curr.setAttribute("id",item.getID ());
//build content
if (item.hasContent()) {
SchemaContent cont = item.getContent();
curr.addContent(cont.getAsJDOMElement());
}
//build repetition info (attribute repsql)
if (item.getRepetition() != null) {
curr.setAttribute("repsql",item.getRepetition());
}
//build attributes
for (Enumeration enum = item.getAttributes().elements (); enum.hasMoreElements();) {
SchemaAttribute attr = (SchemaAttribute )enum.nextElement();
curr.addContent(attr.getAsJDOMElement());
}
//build sql
for (Enumeration enum = item.getSQLStatements().elements(); enum.hasMoreElements();) {
SQLStatement stat = (SQLStatement)enum.nextElement();
curr.addContent(stat.getAsJDOMElement());
}
//add the element
db2xml_wrapper.addContent(curr);
}
return wrapper;
}
}
}
/*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
dataItem.java
This class representates a database item consisting of the following stuff
with a get and set method each
String
String
String
String
String
String
name
driver
url
timeout
username
password
-> ... every variable has its get ans set methods
But more important: This class contains different methods for handling
database connections
Created on 18. April 2002, 20:20
---------------------------------------------------------------------------This file is part of <xmlizer>.
<xmlizer> is free software; you can redistribute i t 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.
Foobar 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 <xmlizer>; if not, write to the Free Software
Autor: Thomas Schädler
275
Anhang B: Quelltext <xmlizer> server
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
import
import
import
import
java.sql.*;
java.util.*;
javax.swing .*;
javax.swing .table.*;
/**
* Represents a dbItem
* @author [email protected]
* @version 0.2
*/
public class dbItem {
private String tname;
private String tdriver;
private String turl;
private String ttimeout;
private int ttimeoutint;
private int tstart = 0;
private int chunkSize = 25;
private boolean hasLimit = true;
private String tusername ;
private String tpassword ;
private boolean isConnected = false ;
private Connection connection = null;
private Vector tableList = null;
private boolean stopNOW = false;
private Hashtable navigator;
private String getCountSQL = new String();
private String lastSQL = new String ();
private Vector selectedTables = new Vector();
private String outputType = "simple";
//little global helpers
private SQLStatement lastStatement = null;
//CONSTRUCTORS
//----------------------------------------------------------------------------------------------/**
* Constructors for a new dbItem
* -> holds:
* String name
* String driver
* String url
* String timeout
* int timeoutint
* String username
* String password
*/
public dbItem(String name,String driver,String url ,String timeout ,String username,String password) {
this.tname = name;
this.tdriver = driver;
this.turl = url;
this.ttimeout = timeout;
this.ttimeoutint = ConvertString2int(timeout);
this.tusername = username;
this.tpassword = password;
}
public dbItem(String name,String driver,String url ,String timeout ,String username) {
this.tname = name;
this.tdriver = driver;
this.turl = url;
this.ttimeout = timeout;
this.ttimeoutint = ConvertString2int (timeout);
this.tusername = username;
this.tpassword = new String();
}
public dbItem(String name,String driver,String url ,String timeout ) {
this.tname = name;
this.tdriver = driver;
this.turl = url;
this.ttimeout = timeout;
this.ttimeoutint = ConvertString2int (timeout);
this.tusername = new String();
this.tpassword = new String();
}
public dbItem(String name,String driver,String url ) {
this.tname = name;
this.tdriver = driver;
this.turl = url;
this.ttimeout = new String ();
this.tusername = new String();
this.tpassword = new String();
}
public dbItem(String name,String driver) {
this.tname = name;
this.tdriver = driver;
this.turl = new String();
this.ttimeout = new String ();
this.tusername = new String();
this.tpassword = new String();
}
public dbItem(String name) {
this.tname = name;
this.tdriver = new String();
this.turl = new String();
this.ttimeout = new String ();
this.tusername = new String();
this.tpassword = new String();
}
public dbItem() {
this.tname = new String();
this.tdriver = new String();
Autor: Thomas Schädler
276
Anhang B: Quelltext <xmlizer> server
this.turl = new String();
this.ttimeout = new String ();
this.tusername = new String();
this.tpassword = new String();
}
//STRING REPRESENTATION
//----------------------------------------------------------------------------------------------/**
* By default show the key as String
*/
public String toString() {
return tname;
}
//HELPER METHODS
//----------------------------------------------------------------------------------------------public static int ConvertString2int (String string) {
try {
Integer to = new Integer(string);
return to.intValue();
}
catch(NumberFormatException ex) {
return 25;
//failsafe
}
}
public static String Convertint2String(int integer) {
try {
Integer to = new Integer(integer);
return to.toString();
}
catch(NumberFormatException ex) {
return "25";
//failsafe
}
}
//THREAD ABORT FLAG MANAGEMENT
//----------------------------------------------------------------------------------------------public void halt() {
this.stopNOW = true;
}
private void goon() {
this.stopNOW = false ;
}
//LIMITERS
//----------------------------------------------------------------------------------------------public String getLastSQL () {
return this.lastSQL;
}
public void clearLastStatement () {
this.lastStatement = null;
}
public SQLStatement getLastStatement() {
return this.lastStatement;
}
public void updateLastSQLSQL(String s) {
if (this.lastStatement != null) {
this.lastStatement.setSQL(s);
}
}
public void nextChunk() {
setLimitStart(tstart + chunkSize);
}
public void lastChunk() {
setLimitStart(Math.max(tstart - chunkSize ,0));
}
private void setLimitStart(int i) {
this.tstart = i;
}
public void resetLimit() {
setLimitStart(0);
}
public void setChunkSize (int i) {
this.chunkSize = i;
}
public int getChunkSize() {
return this.chunkSize;
}
/**
* Returns the limit as appendable SQL String
* e.g: " LIMIT 0,25", per default if never set
*/
private String getLimit() {
return new String(" LIMIT " + tstart + "," + chunkSize);
}
/**
* Enables/Disables the automatic limit
*/
Autor: Thomas Schädler
277
Anhang B: Quelltext <xmlizer> server
public void setLimit(boolean bool) {
this.hasLimit = bool;
}
public boolean hasLimit() {
return hasLimit ;
}
public void setCountSQL(String s) {
this.getCountSQL = s;
}
public String getCountSQL() {
return getCountSQL;
}
//GET AND SET METHODS
//----------------------------------------------------------------------------------------------public Hashtable getNavigator() {
return navigator;
}
/**
* Get the name of the dbitem
*/
public String getName() {
return this.tname;
}
/**
* Get the driver of the dbitem
*/
public String getDriver() {
return this.tdriver;
}
/**
* Get the url of the dbitem
*/
public String getUrl() {
return this.turl;
}
/**
* Get the timeout of the dbitem
*/
public String getTimeout () {
return this.ttimeout ;
}
public int getTimeoutAsInt() {
return ttimeoutint;
}
/**
* Get the username of the dbitem
*/
public String getUsername() {
return this.tusername;
}
/**
* Get the password of the dbitem
*/
public String getPassword() {
return this.tpassword;
}
/**
* Set the name of the dbitem
*/
public void setName(String s) {
this.tname = s;
}
/**
* Set the driver of the dbitem
*/
public void setDriver(String s ) {
this.tdriver = s;
}
/**
* Set the url of the dbitem
*/
public void setUrl(String s) {
this.turl = s;
}
/**
* Set the timeout of the dbitem
*/
public void setTimeout(String s) {
this.ttimeout = s;
this.ttimeoutint = ConvertString2int (s);
}
/**
* Set the username of the dbitem
*/
public void setUsername(String s) {
this.tusername = s;
}
/**
Autor: Thomas Schädler
278
Anhang B: Quelltext <xmlizer> server
* Set the password of the dbitem
*/
public void setPassword(String s) {
this.tpassword = s;
}
//SELECTED TABLES FOR SMDBE MAPPING AND EXPORT AND FOR THE OUTPUT TYPE
//----------------------------------------------------------------------------------- -----------public void SMDBEsetSelectedTables(Vector v) {
this.selectedTables = v;
}
public Vector SMDBEgetSelectedTables() {
return this.selectedTables ;
}
public void SMDBEselectTable(String tablename ) {
if (!this.selectedTables.contains(tablename)) {
this.selectedTables.add(tablename);
}
}
public void SMDBEdeselectTable (String tablename) {
if (this.selectedTables.contains(tablename)) {
this.selectedTables.remove(tablename);
}
}
public void SMDBEsetOutputType (String type) {
this.outputType = type;
}
public String SMDBEgetOutputType() {
return this.outputType;
}
//DATABASE CONNECTION METHODS
//----------------------------------------------------------------------------------------------public boolean isConnected() {
return isConnected;
}
public void closeConnection() {
this.tableList = null;
if (isConnected ) {
try {
isConnected = false;
connection.close();
}
catch(Exception ex) {
//ok
}
}
}
synchronized public Connection getConnection() throws Exception {
if (!isConnected) {
makeConnection();
}
while(!isConnected) {
if (stopNOW)
{ throw new Exception("Could not connect to database " + tname + "."); }
}
return connection;
}
/**
* Tries to create connection
* in the thread in order not to "hang" the application
*/
synchronized private void makeConnection () throws Exception {
try {
Class.forName(tdriver);
DriverManager.setLoginTimeout(ttimeoutint);
if(tusername.equalsIgnoreCase(new String())) {
connection = DriverManager.getConnection(turl);
isConnected = true;
//System.out.println("Connection to database " + tname + " successful!");
}
else {
connection = DriverManager.getConnection(turl,tusername,decryptSecurePassword(tpassword));
isConnected = true;
//System.out.println("Connection to database " + tname + " successful!");
}
}
catch(Exception ex) {
//System.out.println("Connection " + tname + " not possible!");
throw new Exception("Could not establish connection " + tname + ".");
}
}
//DATABASE ACCESS METHODS
//----------------------------------------------------------------------------------------------/**
* Returns a Vector of all tables for this DB as listItems where
* each listItem has a name, the number or rows and a boolean flag if it should be selected
*/
public Vector getTableList() throws Exception {
if(tableList == null) {
Vector result = new Vector();
ResultSet rs = getConnection().getMetaData ().getTables(null, null, null, new String[]{"TABLE"});
Autor: Thomas Schädler
279
Anhang B: Quelltext <xmlizer> server
Statement stmt = getConnection().createStatement();
while(rs.next()) {
//table name
String res = rs.getString("TABLE_NAME" );
//rows
int rows = 0;
ResultSet srs = stmt.executeQuery ("SELECT COUNT(*) FROM " + res);
if(srs.next()) {
rows = srs.getInt(1);
}
//mark the listitems as selected or not depending on read in data
boolean isThisSelected = false;
if (selectedTables != null && selectedTables.size() > 0) {
if (selectedTables.contains(res)) {
isThisSelected = true;
}
}
listItem item = new listItem (res,rows,isThisSelected);
result.add(item);
}
tableList = result;
}
return tableList;
}
private String checkSQL(String sql) {
//System.out.println("Checking SQL for limit-tag in: " + sql);
StringBuffer countSQL = new StringBuffer("SELECT COUNT(*)");
boolean hadFrom = false;
if (this.hasLimit) {
boolean theLimit = false;
//FIXME limit kann auch ein tablename sein!!! besserer SQL check
StringTokenizer tokenizer = new StringTokenizer (sql);
while (tokenizer .hasMoreTokens()) {
String currentToken = tokenizer.nextToken();
if (hadFrom || currentToken.equalsIgnoreCase(new String("from"))) {
hadFrom = true;
countSQL .append(" ");
countSQL .append(currentToken);
}
if (currentToken.equalsIgnoreCase (new String("limit"))) {
theLimit = true;
}
}
setCountSQL (countSQL.toString());
if (!theLimit) {
return sql + getLimit();
}
else {
setLimit(false);
return sql;
}
}
else {
return sql;
}
}
/**
* Runs a specified SQL Query on the DB connection
* and returns a Hashtable containing the different data to preceed
* Note: allways use this function to query the DB!
*/
synchronized public Hashtable query (String sqlQuery) throws Exception {
lastSQL = sqlQuery;
Statement stmt = getConnection().createStatement();
int MaxRowCount = 0;
if (hasLimit) {
sqlQuery = checkSQL(sqlQuery);
String countSQL = getCountSQL();
ResultSet srs = stmt.executeQuery(countSQL );
if(srs.next()) {
MaxRowCount = srs.getInt(1);
}
}
//System.out.println("DB QUERY: " + sqlQuery);
ResultSet rs = stmt.executeQuery(sqlQuery );
ResultSetMetaData rsmd = rs.getMetaData();
int cols = rsmd.getColumnCount();
int rowNumber = 0;
Vector vector = new Vector (5, 5);
Vector collables = new Vector(); //of String
Vector colltypes = new Vector(); //of String
Vector collsizes = new Vector(); //of Integer
Vector collnames = new Vector(); //of String
//build collumnvector (with the names of the columns)
for(int i=1;i<=cols;i++) {
if (stopNOW)
{ goon(); throw new Exception("Aborted by user."); }
collables.add(rsmd.getColumnLabel(i));
colltypes.add(rsmd.getColumnTypeName(i));
collsizes.add(new Integer(rsmd.getColumnDisplaySize(i)));
Autor: Thomas Schädler
280
Anhang B: Quelltext <xmlizer> server
collnames.add(rsmd.getColumnName (i));
}
//build rowvector
while(rs.next()) {
if (stopNOW)
{ goon(); throw new Exception("Aborted by user."); }
rowNumber++;
for(int i=1;i<=cols;i++) {
if (stopNOW)
{ goon(); throw new Exception("Aborted by user." ); }
//use the types here to get it right FIXME
vector.add(rs.getString (i));
}
}
int rows = rowNumber ;
if (MaxRowCount == 0)
{ MaxRowCount = rows; }
String info[][] = new String[cols][rows];
vector.trimToSize();
int row = 0;
int col = 0;
for(int i=0;i<vector .size();i++) {
if (stopNOW)
{ goon(); throw new Exception("Aborted by user."); }
try {
info[col][row] = vector .get(i).toString();
}
catch(NullPointerException ex) {
info[col][row] = "";
}
if(col+1 == cols) {
col = -1;
row++;
}
col++;
}
Hashtable navData = new Hashtable();
if (hasLimit) {
navData.put("first",Convertint2String (this.tstart+1));
if ((this.tstart + chunkSize) > this.tstart + rows) {
navData.put("last" ,Convertint2String(this.tstart + rows));
}
else {
navData.put("last" ,Convertint2String(this.tstart + chunkSize));
}
navData.put("max",Convertint2String(MaxRowCount ));
if (MaxRowCount > this.tstart + chunkSize) {
navData.put("hasNext",new Boolean(true));
}
else {
navData.put("hasNext",new Boolean(false));
}
if (this.tstart != 0) {
navData.put("hasLast",new Boolean(true));
}
else {
navData.put("hasLast",new Boolean(false));
}
}
else {
navData.put("first",Convertint2String (this.tstart+1));
navData.put("last",Convertint2String(rows));
navData.put("max",Convertint2String(rows));
navData.put("hasNext",new Boolean(false));
navData.put("hasLast",new Boolean(false));
}
this.navigator = navData;
Hashtable result = new Hashtable();
result.put("table",info);
result.put("columnname",collnames);
result.put("columnsize",collsizes);
result.put("columnlabels",collables);
result.put("columntypes",colltypes);
result.put("rows",new Integer(rows));
result.put("cols",new Integer(cols));
return result;
}
private Statement getStatement (int limit ) throws Exception {
Statement stmt = getConnection().createStatement();
if (limit != 0) {
stmt.setFetchSize(limit);
}
return stmt;
}
/**
* Runs a specified SQL Query on the DB connection but in silent mode
* Silent mode: just a clean query, no other data changed (for background and long running threads)
* Attention: no metadata and paging available in this mode and it does not care about limit checking etc...
* and returns a Hashtable containing the different data to preceed
* Note: allways use this function to query the DB in clean mode (without changing something in this class!
*/
synchronized public Hashtable querySilent(String sqlQuery) throws Exception {
return querySilentWithLimit(sqlQuery ,0);
}
/**
* Runs a specified SQL Query on the DB connection but in silent mode with rowlimit
Autor: Thomas Schädler
281
Anhang B: Quelltext <xmlizer> server
* Silent mode: just a clean query, no other data changed (for background and long running threads)
* Attention: no metadata and paging available in this mode and it does not care about limit checking etc...
* and returns a Hashtable containing the different data to preceed
* Note: allways use this function to query the DB in clean mode (without changing something in this class!
*/
synchronized public Hashtable querySilentWithLimit (String sqlQuery,int limit) throws Exception {
Statement stmt = getStatement(limit);
//System.out.println("DB QUERY (SILENT): " + sqlQuery);
ResultSet rs = stmt.executeQuery(sqlQuery );
ResultSetMetaData rsmd = rs.getMetaData();
int cols = rsmd.getColumnCount();
int rowNumber = 0;
Vector vector = new Vector (5, 5);
Vector collables = new Vector(); //of String
Vector colltypes = new Vector(); //of String
Vector collsizes = new Vector(); //of Integer
Vector collnames = new Vector(); //of String
//build collumnvector (with the names of the columns)
for(int i=1;i<=cols;i++) {
if (stopNOW)
{ goon(); throw new Exception("Aborted by user."); }
collables.add(rsmd.getColumnLabel(i));
colltypes.add(rsmd.getColumnTypeName(i));
collsizes.add(new Integer(rsmd.getColumnDisplaySize(i)));
collnames.add(rsmd.getColumnName (i));
}
//build rowvector
while(rs.next()) {
if (stopNOW)
{ goon(); throw new Exception("Aborted by user."); }
rowNumber++;
for(int i=1;i<=cols;i++) {
if (stopNOW)
{ goon(); throw new Exception("Aborted by user." ); }
//use the types here to get it right FIXME
vector.add(rs.getString (i));
}
}
int rows = rowNumber ;
String info[][] = new String[cols][rows];
vector.trimToSize();
int row = 0;
int col = 0;
for(int i=0;i<vector .size();i++) {
if (stopNOW)
{ goon(); throw new Exception("Aborted by user."); }
try {
info[col][row] = vector .get(i).toString();
}
catch(NullPointerException ex) {
info[col][row] = "";
}
if(col+1 == cols) {
col = -1;
row++;
}
col++;
}
Hashtable result = new Hashtable();
result.put("table",info);
result.put("columnname",collnames);
result.put("columnsize",collsizes);
result.put("columnlabels",collables);
result.put("columntypes",colltypes);
result.put("rows",new Integer(rows));
result.put("cols",new Integer(cols));
return result;
}
//QUASI-SECURE PASSWORD HANDLING
//----------------------------------------------------------------------------------------------public static String decryptSecurePassword(String encrypted) {
//decrpyt
StringBuffer decrypted = new StringBuffer ();
char[] sec_char = new char[]{'x','m','l','i','z','e','r'};
int inkr = 0;
char aktual;
StringBuffer current = new StringBuffer();
for (int j=0;j<encrypted.length ();j++) {
aktual = encrypted.charAt(j);
if (aktual == ':') {
if (inkr<sec_char.length-1){inkr++;}else{inkr=0;}
String gotcha = current.toString();
current = new StringBuffer(); // renew buffer
Integer goti = new Integer(gotcha );
int gotint = goti.intValue();
int decr = gotint ^ sec_char [inkr];
decrypted.append((char)decr);
}
else {
current.append(aktual);
}
}
return decrypted.toString();
}
}/*
* xmlItem.java
*
* This class representates a xml file item consisting of the following stuff
* with a get and set method each
Autor: Thomas Schädler
282
Anhang B: Quelltext <xmlizer> server
*
* String name
* String file
*
* -> ... every variable has its get ans set methods
*
* But more important: This class contains different methods for handling
* xml file access and manipulation
*
* Created on 16. May 2002, 20:20
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
import java.io.*;
import java.util.*;
/**
* Represents a xmlItem
* @author [email protected]
* @version 0.2
*/
public class xmlItem {
private String tname;
private String tfile;
//CONSTRUCTORS
//----------------------------------------------------------------------------------------------/**
* Constructors for a new xmlItem
* -> holds:
* String name
* String file
*/
public xmlItem(String name,String file) {
this.tname = name;
this.tfile = file;
}
public xmlItem(String name) {
this.tname = name;
this.tfile = new String();
}
public xmlItem() {
this.tname = new String();
this.tname = new String();
}
//STRING REPRESENTATION
//----------------------------------------------------------------------------------------------/**
* By default show the key as String
*/
public String toString() {
return this.tname;
}
//HELPER METHODS
//----------------------------------------------------------------------------------------------//GET AND SET METHODS
//----------------------------------------------------------------------------------------------/**
* Get the name of the dbitem
*/
public String getName() {
return this.tname;
}
/**
* Get the driver of the dbitem
*/
public String getFile() {
return this.tfile;
}
/**
* Set the name of the dbitem
*/
public void setName(String s) {
this.tname = s;
}
/**
* Set the driver of the dbitem
*/
public void setFile(String s) {
this.tfile = s;
}
Autor: Thomas Schädler
283
Anhang B: Quelltext <xmlizer> server
}
/*
* SQLStatement.java
*
* This class contains all neccessary info for SQL Statements
*
* Created on 24. Juli 2002, 14:35
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
import java.util.*;
import org.jdom.*;
/**
* Represents a SQL Statement
* @author [email protected]
* @version 0.2
*/
public class SQLSt atement {
private
private
private
private
private
private
String db = null;
String sql = null;
String id = null;
int rowNumber = 0;
Vector colnames = new Vector();
Vector coltypes = new Vector();
/** Creates new SQLStatement * /
/**
* Creats a new Statement with the given id
*/
public SQLStatement (String db,String sql ,String id ) {
this.db = db;
this.sql = sql;
this.id = id;
}
/**
* Creates a new Statement with a generated (unique) id
*/
public SQLStatement (String db,String sql ,Vector cols,Vector types ,int rows) {
UniqueID ID = new UniqueID ();
this.id = ID.get();
this.db = db;
this.sql = sql;
this.colnames = cols;
this.coltypes = types;
this.rowNumber = rows;
//System.out.println("ROWNUMBER: " + rows);
}
/**
* Creates a new Statement with the given id and given vectors
*/
public SQLStatement (String db,String sql ,String id ,Vector co ls,Vector types ) {
this.id = id;
this.db = db;
this.sql = sql;
this.colnames = cols;
this.coltypes = types;
}
/*
* Set the db
*/
public void setDB(String name) {
this.db = name;
}
/*
* Set the sql statement
*/
public void setSQL(String sql) {
this.sql = sql;
}
/*
* Set the sql statement
*/
public void setCols(Vector hash) {
this.colnames = hash;
}
/*
* Set the sql statement
*/
public void setColTypes(Vector hash ) {
Autor: Thomas Schädler
284
Anhang B: Quelltext <xmlizer> server
this.coltypes = hash;
}
/*
* Get the db
*/
public String getDB () {
return this.db;
}
/*
* Get the sql statement
*/
public String getSQL() {
return this.sql;
}
public void setRowNumber (int r) {
//System.out.println("SETROWNUMBER: " + this.rowNumber);
this.rowNumber = r;
}
public int getRowNumber() {
//System.out.println("GETROWNUMBER: " + this.rowNumber);
return this.rowNumber;
}
public Vector getCols() {
return this.colnames ;
}
/**
* Returns the columns as Vector of SQLColumnInfo (ad hoc type)
*/
public Vector getColsAsSQLColumnInfo() {
Vector itemcols = new Vector();
int counter = 0;
for (Enumeration e = this.colnames.elements(); e.hasMoreElements();) {
String this_col_name = (String)e.nextElement();
String this_col_type = (String)this.coltyp es.get(counter);
itemcols.add(new SQLColumnInfo(this.id,this_col_name ,this_col_type));
counter++;
}
return itemcols ;
}
/**
* Returns the columns as Vector of ColumnItems (ad hoc type)
*/
public Vector getColsAsColumnInfo() {
Vector itemcols = new Vector();
int counter = 0;
for (Enumeration e = this.colnames.elements(); e.hasMoreElements();) {
String this_col_name = (String)e.nextElement();
String this_col_type = (String)this.coltypes.get(counter);
itemcols.add(new ColumnInfo (this.id,this_col_name,this_col_type));
counter++;
}
return itemcols ;
}
public Vector getColTypes() {
return this.coltypes;
}
/**
* Add a name to the colname-vector
*/
public void addColName(String name) {
if (name != null) {
this.colnames.add(name);
}
}
/**
* Add a name to the coltype-vector
*/
public void addColType(String type) {
if (type != null) {
this.coltypes.add(type);
}
}
/**
* Returns the mapid
*/
public String getID () {
return this.id;
}
public String toString() {
return this.db + " -> " + this.sql + " [" + this.colnames.size() + "]";
}
public Element getAsJDOMElement() {
if (this.db == null || this.id == null || this.sql == null || this.colnames == null || this.coltypes == null)
//check for validity
{
return null;
}
else {
Element curr = new Element("db2xml_sql");
curr.setAttribute("id",this.id);
curr.setAttribute("db",this.db);
curr.setAttribute("sql",this.sql);
Autor: Thomas Schädler
285
Anhang B: Quelltext <xmlizer> server
if (this.colnames.size() > 0 && this.colnames.size() == this.coltypes.size()) {
int counter = 0;
for (Enumeration e = this.colnames.elements (); e.hasMoreElements();) {
Element sub = new Element("db2xml_sql_info");
String item = (String)e.nextElement();
sub.setAttribute("name",item);
sub.setAttribute("type",(String)this.coltypes.get(counter));
counter++;
curr.addContent(sub);
}
}
return curr;
}
}
}/*
* uniqueID.java
*
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ------------------------------------------------------------------ ---------*/
package server;
import java.lang.*;
/**
* Builds a class returning uniqueID's (based on system time and secured through syncronisiation)
* @author [email protected]
*/
public class UniqueID {
static long current = System.currentTimeMillis();
/**
* Returns a uniqueID as long
*/
static public synchronized long getLong() {
return current++;
}
/**
* Returns a uniqueID as String
*/
static public synchronized String get() {
String str = new String();
str = str.valueOf(current++);
return str;
}
}/*
* SQLColumnInfo.java
*
* Created on 25. Juli 2002, 02:47
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
/**
* Represents info for a column of a SQL table
* @author [email protected]
* @version 0.2
*/
class SQLColumnInfo {
protected String id ;
protected String name;
protected String type;
public SQLColumnInfo(String id ,String name,String type) {
this.id = id;
this.name = name;
this.type = type;
}
public String getID () {
return this.id;
}
Autor: Thomas Schädler
286
Anhang B: Quelltext <xmlizer> server
public String getName() {
return this.name;
}
public String getType() {
return this.type;
}
public String toString() {
return this.name + " [" + this.type + "]";
}
}
/*
* ColumnInfo.java
*
* Created on 25. Juli 2002, 02:47
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNE SS 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
/**
* Represents the columnInfo of a db table
* @author [email protected]
* @version 0.2
*/
class ColumnInfo {
protected String id ;
protected String name;
protected String type;
public ColumnInfo(String id,String name,String type) {
this.id = id;
this.name = name;
this.type = type;
}
public String getID () {
return this.id;
}
public String getName() {
return this.name;
}
public String getType() {
return this.type;
}
public String toString() {
return this.name + " [" + this.type + "]";
}
}/*
* listItem.java
*
* Created on 22. Mai 2002, 12:44
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> is free software; you can redistribute it and/or modify
* it under the t erms 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
/**
* Represents the metadata of a table
* @author [email protected]
* @version 0.2
*/
class listItem {
private String name ;
private int rowcount;
private boolean selected = false;
public listItem(String name,int rowcount ) {
this.name = name;
this.rowcount = rowcount;
Autor: Thomas Schädler
287
Anhang B: Quelltext <xmlizer> server
}
public listItem(String name,int rowcount ,boolean marked ) {
this.name = name;
this.rowcount = rowcount;
this.selected = marked;
}
public String toString() {
return this.name + " (" + this.rowcount + ")";
}
public String getName() {
return this.name;
}
public int getRowCount() {
return this.rowcount ;
}
public boolean isSelected() {
return this.selected ;
}
public void toggleSelection() {
if (this.selected) {
this.selected = false;
}
else {
this.selected = true;
}
//System.out.println("ListItem " + name + " is now " + selected);
}
}/*
* ParameterInfo.java
*
* Created on 25. Juli 2002, 02:47
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Pu blic License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
import java.util.*;
import org.jdom.*;
/**
* Represents the parameterinfo (name and value)
* @author [email protected]
* @version 0.2
*/
class ParameterInfo {
protected String id ;
protected String name;
protected String value;
public ParameterInfo(String id ,String name,String value ) {
this.id = id;
this.name = name;
this.value = value;
}
public String getID () {
return this.id;
}
public String getName() {
return this.name;
}
public String getValue() {
return this.value;
}
public String toString() {
return this.name + " (" + this.value + ")";
}
public Element getAsJDOMElement() {
if (this.name == null || this.value == null)
//check for validity
{
return null;
}
else {
Element curr = new Element("db2xml_parameter");
curr.setAttribute("name",this.name);
curr.setAttribute("default" ,this.value);
return curr;
}
}
}
Autor: Thomas Schädler
288
Anhang B: Quelltext <xmlizer> server
/*
* SchemaElement.java
*
* This class representates a Schema Element
*
* Created on 18. April 2002, 20:20
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
import
import
import
import
org.jdom.*;
java.util.*;
javax.swing .*;
javax.swing .tree.*;
/**
* Represents a SchemaElement - slightly adjusted from the configurator
* @author [email protected]
* @version 0.2
*/
public class SchemaElement {
private String id;
private String tname;
private String trealname ;
private Element telement ;
private Vector attributes = new Vector(); //of SchemaAttributes
private SchemaContent content;
private Vector children = new Vector();
private JPanel tpanel = null;
private String type = null;
private String typeRef = null;
private boolean hasInternalType = false;
private SchemaOccurrence occurrence = null;
private String documentation = null;
private Vector parents = new Vector (); //of SchemaElements
private DefaultMutableTreeNode node = null;
private ProjectManager mother = null;
//schemaElement-Data
public String SCHEMAattributeFormDefault = new String("unqualified");
public String SCHEMAelementFormDefault = new String("unqualified" );
public String SCHEMAtargetNameSpace = new String("");
public String SCHEMAversion = new String ("");
public String SCHEMAlanguage = new String("");
//type handling
private SchemaType theType = null;
//SQL
private Vector SQLStatements = new Vector(); //of SQLStatement
private String repetitionStatement = null;
//CONSTRUCTORS
//----------------------------------------------------------------------------------------------public SchemaElement(ProjectManager conf ,DefaultMutableTreeNode node,String name ,Element element ) {
this.mother = conf;
this.tname = name;
this.node = node;
this.telement = element;
if (name.equalsIgnoreCase("<schema>" )) //special treatment
{
this.tpanel = new JPanel(new java.awt.GridLayout(7,1));
this.tpanel .add(new JLabel("XML Schema root element" ));
this.tpanel .add(new JLabel("-----------------------"));
this.trealname = "schema root";
//disableRefresh();
}
else if (name.equalsIgnoreCase("-=sequence=-")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("Sequence of elements:"));
this.trealname = "sequence";
disableRefresh();
}
else if (name.equalsIgnoreCase("-=choice= -")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("Choice of elements:"));
this.trealname = "choice";
disableRefresh();
}
else if (name.equalsIgnoreCase("-=all=-")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("All elements:" ));
this.trealname = "all" ;
disableRefresh();
}
else if (name.equalsIgnoreCase("-=group=-")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("Group of elements:" ));
this.trealname = "group";
Autor: Thomas Schädler
289
Anhang B: Quelltext <xmlizer> server
disableRefresh();
}
else if (name.equalsIgnoreCase("<any>")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("Any elements):"));
this.trealname = "any" ;
disableRefresh();
}
process();
}
public SchemaElement(ProjectManager conf ,DefaultMutableTreeNode node,Element element,String idpath) {
this.id = idpath;
this.mother = conf;
this.tname = null;
this.node = node;
this.telement = element;
}
/**
* Constructor for special elements (no precessing, just showing the right name
*/
public SchemaElement(ProjectManager conf ,DefaultMutableTreeNode node,String name ) {
this.mother = conf;
this.tname = name;
this.node = node;
this.telement = null;
if (name.equalsIgnoreCase("<schema>" )) //special treatment
{
this.tpanel = new JPanel(new java.awt.GridLayout(7,1));
this.tpanel .add(new JLabel("XML Schema root element" ));
this.tpanel .add(new JLabel("-----------------------"));
this.trealname = "schema root";
//disableRefresh();
}
else if (name.equalsIgnoreCase("-=sequence=-")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("Sequence of elements..." ));
this.trealname = "sequence" ;
disableRefresh();
}
else if (name.equalsIgnoreCase("-=choice= -")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("Choice of elements..."));
this.trealname = "choice";
disableRefresh();
}
else if (name.equalsIgnoreCase("-=all=-")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("All elements..."));
this.trealname = "all" ;
disableRefresh();
}
else if (name.equalsIgnoreCase("-=group=-")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("Group of elements..."));
this.trealn ame = "group";
disableRefresh();
}
else if (name.equalsIgnoreCase("<any>")) {
this.tpanel = new JPanel();
this.tpanel .add(new JLabel("Wildcard Component (any)"));
this.trealname = "any" ;
disableRefresh();
}
}
//Initialization of the data
//----------------------------------------------------------------------------------------------private void process() {
if (this.tname != null && this.tname .equalsIgnoreCase("<schema>")) {
Attribute attr = null;
attr = this.telement.getAttribute("attributeFormDefault");
if (attr != null) {
SCHEMAattributeFormDefault = attr.getValue().trim();
}
this.tpanel .add(new JLabel("attributeFormDefault : " + SCHEMAattributeFormDefault));
attr = this.telement.getAttribute("elementFormDefault");
if (attr != null) {
SCHEMAelementFormDefault = attr.getValue().trim();
}
this.tpanel .add(new JLabel("elementFormDefault : " + SCHEMAelementFormDefault ));
attr = this.telement.getAttribute("targetNamespace");
if (attr != null) {
SCHEMAtargetNameSpace = attr.getValue().trim();
}
this.tpanel .add(new JLabel("targetNamespace : " + SCHEMAtargetNameSpace));
attr = this.telement.getAttribute("version");
if (attr != null) {
SCHEMAversion = attr.getValue().trim();
}
this.tpanel .add(new JLabel("version : " + SCHEMAversion));
attr = this.telement.getAttribute("xml:lang");
if (attr != null) {
SCHEMAlanguage = attr.getValue().trim();
}
this.tpanel .add(new JLabel("xml:lang : " + SCHEMAlanguage ));
}
}
Autor: Thomas Schädler
290
Anhang B: Quelltext <xmlizer> server
//FIXME - Process the types correctly or delete it for the fucks sacke
public void processType(Element typeElement) {
this.theType = new SchemaType();
//theType.processType(typeElement);
}
public void processTypeRef(Element typeElement) {
this.theType = new SchemaType();
//theType.processTypeRef(typeElement);
}
public void processInternalType() {
this.theType = new SchemaType();
//theType.processInternalType(this.telement);
}
private StringBuffer addOccurrenceString (StringBuffer name) {
if (getOccurrence() == null) {
return name;
}
else {
name.append (this.occurrence .getShortOcc());
return name;
}
}
public void addDocumentation(String doc) {
if(!doc.equalsIgnoreCase("")) {
this.documentation = doc;
}
}
public String getDocumen tation () {
return this.documentation;
}
public void addAttribute (Element attr,Hashtable loadedAttribs) {
SchemaAttribute newattr = new SchemaAttribute(attr);
//System.out.print("IN ELEMENT " + this.trealname);
if (loadedAttribs.containsKey(this.id + newattr.getName())) //an element of this name loaded
{
//add a new attribute, but fill it with the loaded info
SchemaAttribute loaded = (SchemaAttribute)loadedAttribs.get(this.id + newattr.getName());
newattr.setMapID (loaded.getMapID ());
newattr.setMapInfo(loaded.getMapInfo());
this.attributes.add(newattr);
//System.out.println("ADDED ATTR: " + newattr.getName() + " >> " + newattr.getMapID() + " >> " + n ewattr.getMapInfo());
//System.out.print(" ADDED WITH LOAD:" + newattr.getName() + " \n");
}
else //add a new (clean) attribute
{
this.attributes.add(newattr);
//System.out.print(" ADDED CLEAR: " + newattr.getName() + "\n");
}
}
public void setID(String n) {
this.id = n;
}
public String getID () {
return this.id;
}
public boolean hasContent() {
if (this.content != null) {
return true;
}
else return false;
}
public SchemaContent getContent() {
return this.content;
}
public void setContent(SchemaContent cont) {
if (cont != null) {
this.content = cont;
//System.out.println(cont);
}
}
public Vector getAttributes() {
return this.attributes;
}
public boolean hasType() {
if (this.type != null) {
return true;
}
else {
return false;
}
}
public boolean hasTypeRef() {
if (this.typeRef != null) {
return true;
}
else {
return false;
}
}
Autor: Thomas Schädler
291
Anhang B: Quelltext <xmlizer> server
public void setInternalType() {
this.hasInternalType = true;
}
public boolean hasInternalType () {
return this.hasInternalType;
}
public void setRealName(String n) {
this.trealname = n;
}
public String getRealName() {
return this.trealname;
}
/**
* Add a name to the parent-vector: holds names of parent SchemaElements
*/
public void addParent(SchemaElement parent) {
this.parents.add(parent);
}
public Vector getParents () {
return this.parents;
}
//SQL STATEMENTS
//----------------------------------------------------------------------------------------------//for the (linked) repetition
public void setRepetition(String sqlid) {
this.repetitionStatement = sqlid;
}
public String getRe petition() {
return this.repetitionStatement ;
}
public SQLStatement getRepetitionStatement() {
if (this.repetitionStatement != null) {
return mother.getProjectData().DB2XMLgetmapping ().getSQLStatementByMapID (this.repetitionStatement);
}
else return null;
}
//for the statments of the element
public void addSQLStatement(SQLStatement stat ) {
if (stat != null) {
this.SQLStatements.add(stat);
}
}
public Vector getSQLStatements () {
return this.SQLStatements;
}
//STRING REPRESENTATION
//----------------------------------------------------------------------------------------------/**
* By default show the key as String
*/
public String toString() {
return this.tname;
}
//GET AND SET METHODS
//----------------------------------------------------------------------------------------------public void setElement(Element element) {
this.telement = element;
process();
}
public Element getElement() {
return this.telement ;
}
public void setName(String name) {
StringBuffer buff = new StringBuffer (name);
buff = addOccurrenceString (buff);
this.tname = buff.toString ();
}
public String getName() {
return this.tname;
}
public void setType(String type) {
if (!type.equalsIgnoreCase ("")); {
this.type = type;
}
}
public void setTypeRef(String typeref) {
if (!typeref.equalsIgnoreCase("")) {
this.typeRef = typeref ;
}
}
public String getType() {
return this.type;
}
public String getTypeRef () {
return this.typeRef;
Autor: Thomas Schädler
292
Anhang B: Quelltext <xmlizer> server
}
public SchemaOccurrence getOccurrence() {
return this.occurrence;
}
public void setOccurrence(SchemaOccurrence occ) {
this.occurrence = occ;
}
//GRAPHIC REPRESENTATION
//----------------------------------------------------------------------------------------------private boolean refresh = true;
private void enableRefresh() {
this.refresh = true;
}
private void disableRefresh() {
this.refresh = false ;
}
public boolean isRefresh () {
return this.refresh;
}
private JLabel getDragTargetForRepetition(String rep_short_name) {
return new JLabel("Repetition: " + rep_short_name);
}
}/*
* SchemaType.java
*
* Created on 24. Juli 2002, 11:59
*
* This represents the neccessary info for a type of a SchemaElement
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
import org.jdom.*;
import java.util.*;
import javax.swing .*;
/**
* Represents the type of a SchemaElement (currently unused)
* @author [email protected]
* @version 0.2
*/
public class SchemaType {
private String tname = null; //name=
//CONSTRUCTORS
//----------------------------------------------------------------------------------------------public SchemaType() {
//none for now
}
public void setName(String name) {
this.tname = name;
}
public String getName() {
return this.tname;
}
//TYPE PROCESSING
//----------------------------------------------------------------------------------------------public void processType(Element typeElement) {
//name
Attribute attr = null;
attr = typeElement.getAttribute ("name");
if (attr != null) {
this.tname = attr.getValue().trim();
}
//System.out.println("TYPE: " + typeElement.getName());
List kids = typeElement.getChildren(); //"element",namespace
Iterator kids_iter = kids.iterator();
while (kids_iter.hasNext()) {
Element xmlelem = (Element) kids_iter .next();
if (xmlelem.getName().equalsIgnoreCase("complexType" )) //can conatain new elements
{
List subkids = xmlelem.getChildren(); //"element",namespace
Iterator subkids_iter = subkids.iterator();
while (subkids_iter.hasNext()) {
Element dxmlelem = (Element) subkids_iter.next();
if (dxmlelem.getName().equalsIgnoreCase ("simpleContent")) {
List dsubkids = dxmlelem.getChildren(); //"element",namespace
Autor: Thomas Schädler
293
Anhang B: Quelltext <xmlizer> server
Iterator dsubkids_iter = dsubkids.iterator();
while (dsubkids_iter.hasNext()) {
}
}
else if (dxmlelem.getName().equalsIgnoreCase ("complexContent")) {
}
else if (dxmlelem.getName().equalsIgnoreCase ("group")) {
}
else if (dxmlelem.getName().equalsIgnoreCase ("all")) {
}
else if (dxmlelem.getName().equalsIgnoreCase ("choice")) {
}
else if (dxmlelem.getName().equalsIgnoreCase ("sequence")) {
}
else if (dxmlelem.getName().equalsIgnoreCase ("attribute")) {
}
}
}
else if (xmlelem.getName().equalsIgnoreCase("simpleType")) //no more deeper elements
{
List subkids = xmlelem.getChildren(); //"element",namespace
Iterator subkids_iter = subkids.iterator();
while (subkids_iter.hasNext()) {
Element dxmlelem = (Element) subkids_iter.next();
if (dxmlelem.getName().equalsIgnoreCase ("restriction")) {
}
else if (dxmlelem.getName().equalsIgnoreCase ("list")) {
}
else if (dxmlelem.getName().equalsIgnoreCase ("union")) {
}
}
}
}
}
public void processTypeRef(Element typeElement) {
//System.out.println("TREF:" + typeElement.getName());
}
public void processInternalType(Element typeElement) {
//System.out.println("ITYP: " + typeElement.getName());
}
//STRING REPRESENTATION
//----------------------------------------------------------------------------------------------/**
* By default show the key as String
*/
public String toString() {
return this.tname;
/*
if (this.ttype == null && this.ttyperef != null)
//has a typeref
{
return this.tname + " - " + this.ttyperef + " [" + this.tuse + "]";
}
else if (this.ttype != null && this.ttyperef == null)
//has a type
{
return this.tname + " - " + this.ttype + " [" + this.tuse + "]";
}
else
//has nothing of both (should not happen -> invalid)
{
return this.tname + " - !noType! [" + this.tuse + "]";
}*/
}
}/*
* SchemaContent.java
*
* Created on 25. Juli 2002, 02:47
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
import org.jdom.*;
import java.util.*;
import javax.swing .*;
/**
* Represents the content of a SchemaElement
Autor: Thomas Schädler
294
Anhang B: Quelltext <xmlizer> server
* @author [email protected]
* @version 0.2
*/
class SchemaContent {
protected String elementname;
protected String mapid;
protected String mapinfo ;
public SchemaContent(){}
public SchemaContent(String elementname) {
this.elementname = elementname;
}
public SchemaContent(String elementname,String mapid,String mapinfo) {
this.elementname = elementname;
this.mapid = mapid;
this.mapinfo = mapinfo;
}
public String getElementName() {
return this.elementname;
}
public String getMapID() {
return this.mapid;
}
public String getMapInfo () {
return this.mapinfo;
}
/** Cleans the mapinfo of this content */
public void cleanMapping () {
this.mapid = null;
this.mapinfo = null;
//System.out.println(this.tname);
}
//SETTERS
public void setMapID(String id ) {
if (id != null) {
this.mapid = id;
}
}
public void setMapInfo(String info) {
if (info != null) {
this.mapinfo = info;
}
}
public String toString() {
return "<" + this.elementname + ">" + this.mapid + ":" + this.mapinfo + "</" + this.elementname + ">";
}
public Element getAsJDOMElement() {
Element curr = new Element ("db2xml_content");
if (this.mapid != null) {
curr.setAttribute("mapid",this.mapid);
}
if (this.mapinfo != null) {
curr.setAttribute("mapinfo" ,this.mapinfo);
}
//System.out.println("<" + this.elementname + ">" + this.mapid + ":" + this.mapinfo + "</" + this.elementname + ">");
return curr;
}
}
/*
* SchemaOccurrence.java
*
* Created on 4. April 2002, 15:48
* ------------------------------------ ---------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
import java.lang.Integer;
/**
* Represents the occurrence of a SchemaElement (repetition)
* @author [email protected]
* @version 0.2
*/
public class SchemaOccurrence {
/** The identifier for this constraint */
private String identifier;
/** Minimum inclusive value allowed */
private Integer minOccurs;
Autor: Thomas Schädler
295
Anhang B: Quelltext <xmlizer> server
/** Maximum exclusive value allowed */
private Integer maxOccurs;
private boolean maxUnbounded = false;
/**
* <p>
* This will create a new <code>SPConstraint</code> with the specified
*
identifier as the "name".
* </p>
*
* @param identifier <code>String</code> identifier for <code>SPConstraint</code>.
*/
public SchemaOccurrence(String identifier) {
this.identifier = identifier;
//init values to default
this.minOccurs = new Integer(1);
this.maxOccurs = new Integer(1);
}
/**
* <p>
* This will return the identifier for this <code>SPConstraint</code>.
* </p>
*
* @return <code>String</code> - identifier for this constraint.
*/
public String getIdentifier() {
return identifi er;
}
/**
* <p>
* This will set the minimum allowed value for this data type (inclusive).
* </p>
*
* @param minInclusive minimum allowed value (inclusive)
*/
public void setMinOccurs (String min ) {
if (min != null) {
Integer min_int = Integer.valueOf(min);
this.minOccurs = min_int;
}
}
/**
* <p>
* This will return the minimum allowed value for this data type (inclusive).
* </p>
*
* @return <code>double</code> - minimum value allowed (inclusive)
*/
public Integer getMinOccurs() {
return this.minOccurs;
}
/**
* <p>
* This will set the maximum allowed value for this data type (inclusive).
* In case of unbounded the value shall be Integer.MAX_VALUE
* </p>
*
* @param minInclusive minimum allowed value (inclusive)
*/
public void setMaxOccurs (String max ) {
if (max != null) {
if (max.equalsIgnoreCase("unbounded")) {
this.maxUnbounded = true;
this.maxOccurs = new Integer(Integer.MAX_VALUE);
}
else {
Integer max_int = Integer.getInteger(max);
this.maxOccurs = max_int;
}
}
}
/**
* Return true if this element can be repeated more than once
*/
public boolean hasRepeat () {
if ((getMinOccurs().intValue() == 1) && (getMaxOccurs().intValue() == 1)) {
return false;
}
else if (getMaxOccurs().intValue() > 1) {
return true;
}
else {
return false;
}
}
/**
* <p>
* This will return the minimum allowed value for this data type (inclusive).
* </p>
*
* @return <code>double</code> - minimum value allowed (inclusive)
*/
public Integer getMaxOccurs() {
return maxOccurs;
}
/**
* Returns a short occurrence description as String
Autor: Thomas Schädler
296
Anhang B: Quelltext <xmlizer> server
*/
public String getShortOcc() {
if ((getMinOccurs().intValue() == 1) && (getMaxOccurs().intValue() == 1)) {
return " [1]";
}
else {
StringBuffer buff = new StringBuffer(" [");
buff.append (getMinOccurs());
buff.append("..");
if (this.maxUnbounded == true) {
//buff.append("\u221E"); //means "infinite symbol" in unicode
buff.append("max"); //unicode is font dependant! no good idea
}
else {
buff.append(getMaxOccurs());
}
buff.append ("]");
return buff.toString();
}
}
}/*
* SchemaAttribute.java
*
* This class representates a Schema Attribute
*
* Created on 18. Mai 2002, 20:52
* ---------------------------------------------------------------------------* This file is part of <xmlizer>.
*
* <xmlizer> 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.
*
* Foobar 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 <xmlizer>; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------------*/
package server;
import org.jdom.*;
import java.util.*;
import javax.swing .*;
/**
* Represents a SchemaAttribute
* @author [email protected]
* @version 0.2
*/
public class SchemaAttribute {
private String tname = null; //name=
private String ttype = null; //type=
private String ttyperef = null; //ref=
private String tuse = new String("optional"); //use=
private String mapid = null;
private String mapinfo = null;
private Element tattribute;
private String tannotation = null;
//CONSTRUCTORS
//----------------------------------------------------------------------------------- -----------public SchemaAttribute(Element attribute ) {
this.tattribute = attribute;
process();
}
public
if
if
if
}
SchemaAttribute(String name,String mapid,String mapinfo) {
(name != null) { this.tname = name; }
(mapid != null) { this.mapid = mapid; }
(mapinfo != null) { this.mapinfo = mapinfo; }
//Initialization of the data
//----------------------------------------------------------------------------------------------private void process() {
if (this.tattribute != null) {
Attribute attr = null;
//name
attr = this.tattribute .getAttribute("name" );
if (attr != null) {
this.tname = attr.getValue().trim();
}
//type
attr = this.tattribute .getAttribute("type" );
if (attr != null) {
this.ttype = attr.getValue().trim();
}
//ref
attr = this.tattribute .getAttribute("ref");
if (attr != null) {
this.ttyperef = attr.getValue().trim();
}
//use
attr = this.tattribute .getAttribute("use");
Autor: Thomas Schädler
297
Anhang B: Quelltext <xmlizer> server
if (attr != null) {
this.tuse = attr.getValue().trim();
}
}
}
/** Cleans the mapinfo of this attribute */
public void cleanMapping () {
this.mapid = null;
this.mapinfo = null;
//System.out.println(this.tname);
}
//SETTERS
public void setMapID(String id ) {
if (id != null) {
this.mapid = id;
}
}
public void setMapInfo(String info) {
if (info != null) {
this.mapinfo = info;
}
}
//GETTERS
public String getMapID() {
return this.mapid;
}
public String getMapInfo () {
return this.mapinfo;
}
public Element getAttribute() {
return this.tattribute;
}
public String getType() {
return this.ttype;
}
public String getTypeTef () {
return this.ttyperef ;
}
public String getUse() {
return this.tuse;
}
public String getName() {
return this.tname;
}
//STRING REPRESENTATION
//----------------------------------------------------------------------------------------------/**
* By default show the key as String
*/
public String toString() {
StringBuffer result = new StringBuffer();
//display the name
if (this.ttype == null && this.ttyperef != null)
//has a typeref
{
result .append(this.tname + " - " + this.ttyperef + " [" + this.tuse + "]");
}
else if (this.ttype != null && this.ttyperef == null)
//has a type
{
result .append(this.tname + " - " + this.ttype + " [" + this.tuse + "]");
}
else
//has nothing of both (should not happen -> invalid)
{
result .append(this.tname + " - !noType! [" + this.tuse + "]");
}
//display the mapid if there is one
if (this.mapid != null) {
result .append(" > " + this.mapid);
}
if (this.mapinfo != null) {
result .append(" : " + this.mapinfo);
}
return result.toString();
}
public Element getAsJDOMElement() {
if (this.tname == null)
//check for validity
{
return null;
}
else {
Element curr = new Element("db2xml_attribute");
curr.setAttribute("name",this.tname);
if (this.mapid != null) {
curr.setAttribute("mapid",this.mapid);
}
if (this.mapinfo != null) {
curr.setAttribute("mapinfo",this.mapinfo);
}
return curr;
}
}
}
Autor: Thomas Schädler
298
Ehrenwörtliche Erklärung
Autor: Thomas Schädler
299
Herunterladen