Damit kann ein Parameter mit einem Wert jederzeit aus jeder Klasse mit 1(einer!) Programmzeile abgespeichert oder ausgelesen werden.
Wenn man ein Programm schreibt, möchte man einige Parameter dauerhaft speichern. Also so eine Art "ini"-Datei wo man unterschiedlichen Parameter mit Werten verwalten kann. Habe mich für XML entschieden weil Java schon einige fertige Klassen dafür hat.
XML-Datei sieht so aus:
<?xml version....... bla bla>
<root>
<parameter1>wert1</parmeter1>
<parameter2>wert2</parmeter2>
<parameter3>wert3</parmeter3>
<parameter4>wert4</parmeter4>
<parameter5>wert5</parmeter5>
<parameter6>wert6</parmeter6>
<parameter7>wert7</parmeter7>
usw.....
</root>
wenn ein Parameter in der Datei nicht existiert, wird er angelegt - kann auch vorbelegt werden(siehe Quelltext). Habe so gemacht, damit ich die XML-Datei nicht nach jeder Programmänderung überprüfen muss :-)
die Klasse prüft auch, ob Dateiordner und Datei existieren. Wenn nicht, werden die angelegt. Damit kann ein Parameter mit einem Wert jederzeit aus jeder Klasse mit 1(einer!) Programmzeile abgespeichert oder ausgelesen werden. Also keine extra Instanzen oder sonstige Prüfungen.
Also keine Zusatztests im Hauptprogramm, einfach:
String wert=XML.leseWert(datei, root, parameter);
oder
XML.schreibeWert(datei,root,parameter,wert);
"Starter"-Klasse ist nur zum Testen da-Parameter setzen oder auslesen
alles andere - in der Datei, habe fast jede Zeile kommentiert.
Also die XML-Klasse:
/* Lizenz: keine. Nuzt es wie ihr wollt
* Übernehme keine Haftung
* */
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.swing.JOptionPane;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartDocument;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
public class XML {
// Betriebssystemunabhängigkeit - Zeilenumbruch
private static final String eol = System.getProperty("line.separator");
// Betriebssystemunabhängigkeit - Trenner für Ordner("\"-Windows, "/"-Linux usw.)
private static final String trenner = System.getProperty("file.separator");
// Array für Optionen, um nicht jedes mal Dateizugriff zu machen
private static Map<String,String>optionen=new HashMap<String,String>();
/* Hauptfunktion zum einlesen
* Erwartet:
* datei - Dateiname mit kompletten Pfad als String
* root - Hauptabschnitt(<config>,<options> oder so) als String
* parameter - Parameter, dessen Wert man haben will als String
* Rückgabe - Wert als String
* */
public static String leseWert(String datei, String root,String parameter) {
// Rückgabewert
String rgwert=null;
// Testen, ob Datei schon existiert, wenn nicht, erstellen
dateiTest(datei,root);
// Wenn Array leer ist....
if(optionen.isEmpty()){
// ... füllen
mapFuellen(datei,root);
}
// Wert aus Array holen
rgwert=optionen.get(parameter);
// Wenn Wert nicht existiert...
if(rgwert==null){
// Vorbelegung oder "" holen
rgwert=getINIStd(parameter);
// zum Array hinzufügen
optionen.put(parameter, rgwert);
// in der Datei abspeichern
schreibeWert(datei,root,parameter,rgwert);
}
return rgwert;
}
/* Hauptfunktion zum Speichern
* Erwartet:
* datei - Dateiname mit kompletten Pfad als String
* root - Hauptabschnitt(<config>,<options> oder so) als String
* parameter - Parameter, dessen Wert man speichern will als String
* Rückgabe - keine
* */
public static void schreibeWert(String datei, String root,String parameter,String wert){
// Testen, ob Datei schon existiert, wenn nicht, erstellen
dateiTest(datei,root);
// Wenn Array leer ist....
if(optionen.isEmpty()){
// ... füllen
mapFuellen(datei,root);
}
// Wert zum Array hinzufügen oder, wenn vorhanden, überschreiben
optionen.put(parameter, wert);
try {
// Ausgabe-Instanz erstellen
XMLOutputFactory xof=XMLOutputFactory.newInstance();
// Writer erstellen
XMLEventWriter xew=xof.createXMLEventWriter(new FileOutputStream(datei));
// Factory-Instanz erstellen
XMLEventFactory xef=XMLEventFactory.newInstance();
// Zeilenumbruch als XML-Event erstellen
XMLEvent xmlEOL=xef.createDTD(eol);
// erste Zeile erstellen(<?xml version=... bla bla)
StartDocument sdoc=xef.createStartDocument();
// schreiben
xew.add(sdoc);
// Start-root Element erstellen(<config> oder so)
StartElement selem=xef.createStartElement("", "", root);
// schreiben
xew.add(selem);
// Zeilenumbruch anhängen
xew.add(xmlEOL);
// Parameter aus dem Array(Map) als Set holen
Set<String> pw=optionen.keySet();
// Iterator erstellen, um Set nacheinander abarbeiten zu können
Iterator<String> opiter=pw.iterator();
// abarbeiten, solange noch was da ist
while(opiter.hasNext()){
// Parameter holen
String itparam=opiter.next();
// <parameter>wert</parameter> erstellen und schreiben
createNode(xew,itparam,optionen.get(itparam));
}
// End-root Element erstellen(</config> oder so)
EndElement gend=xef.createEndElement("", "",root);
// End-root schreiben
xew.add(gend);
// Zeilenumbruch
xew.add(xmlEOL);
// Writer schliessen
xew.close();
} catch (FileNotFoundException fnfe) {
JOptionPane.showMessageDialog(null, fnfe.toString(), "Fehler",JOptionPane.OK_OPTION);
} catch (XMLStreamException xse) {
JOptionPane.showMessageDialog(null, xse.toString(), "Fehler",JOptionPane.OK_OPTION);
}
}
/* Interne Funktion zum erstellen von Nodes
* <parameter>wert</parameter>
* */
private static void createNode(XMLEventWriter ewriter,String parameter,String wert){
try {
// Factory erstellen
XMLEventFactory efactory=XMLEventFactory.newInstance();
// Zeilenumbruch
XMLEvent xmlEOL=efactory.createDTD(eol);
// TAB, damit es schöner aussieht :-)
XMLEvent xmlTAB=efactory.createDTD("\t");
// <parameter> erstelen
StartElement selem=efactory.createStartElement("", "", parameter);
// TAB schreiben
ewriter.add(xmlTAB);
// <parameter> schreiben
ewriter.add(selem);
// wert erstellen
Characters xwert=efactory.createCharacters(wert);
// wert schreiben
ewriter.add(xwert);
// </parameter> erstellen
EndElement eelem=efactory.createEndElement("", "", parameter);
// </parameter> schreiben
ewriter.add(eelem);
// Zeilenumbruch schreiben
ewriter.add(xmlEOL);
} catch (XMLStreamException xse) {
JOptionPane.showMessageDialog(null, xse.toString(), "Fehler",JOptionPane.OK_OPTION);
}
}
/* Interne Funktion
* XML-Dateiinhalt wird in ein Array(Map) eingelesen
* */
private static void mapFuellen(String datei,String root){
try {
// Input-Factory Instanz erstellen
XMLInputFactory xif=XMLInputFactory.newInstance();
// InputStream erstellen
InputStream istream=new FileInputStream(datei);
// Eventreader erstellen
XMLEventReader ereader=xif.createXMLEventReader(istream);
// solange noch Events da sind...
while(ereader.hasNext()){
// ... Event holen
XMLEvent xev=ereader.nextEvent();
// wenn es ein StartElement ist...
if(xev.isStartElement()){
// wenn es root ist(<config> oder so), was keine Werte enthält....
if(xev.asStartElement().getName().getLocalPart().equals(root)){
// ... ignorieren, nächsten lesen
xev=ereader.nextEvent();
}else{
// ein Start-Element aber kein root
// Parameter holen
String param=xev.asStartElement().getName().getLocalPart();
// weitergehen
xev=ereader.nextEvent();
// wert initialisieren
String wert="";
// Wenn irgendein wert da ist,
// also nicht <parameter></parameter>...
if(xev.isCharacters()){
// ... wert holen
wert=xev.asCharacters().getData();
}
// in Array(Map) schreiben
optionen.put(param, wert);
}
}
}
} catch (FileNotFoundException fnfe) {
JOptionPane.showMessageDialog(null, fnfe.toString(), "Fehler",JOptionPane.OK_OPTION);
} catch (XMLStreamException xse) {
JOptionPane.showMessageDialog(null, xse.toString(), "Fehler",JOptionPane.OK_OPTION);
}
}
/* Interne Funktion für die Vorbelegung von
* Standardwerten. Hier bitte eigene Parameter und Werte
* je nach eigenen Anforderungen erfassen. Die hier aufgeführten
* sind nur Beispiele
* */
private static String getINIStd(String parameter){
Map<String,String> inimap=new HashMap<String,String>();
inimap.put("host", "localhost");
inimap.put("username", "neu");
inimap.put("ServerPort", "80");
// ... usw. je nach bedarf
// Wert aus Array holen
String rgwert=inimap.get(parameter);
// Wenn nicht da...
if(rgwert==null){
// Standardwert "" zurückgeben
rgwert="";
}
return rgwert;
}
/* Interne Funktion. Test, ob XML-Datei existiert
* wenn nicht, wird die ohne Parameter erzeugt.
* */
private static void dateiTest(String datei, String root) {
// Dateiinhalt initialisieren
String dateiinhalt = null;
// Test, ob Ordner existiert. Wenn nicht, wird erstellt
ordnerTest(datei);
try {
// Versuch, auf Datei zuzugreifen
new FileReader(new File(datei));
} catch (FileNotFoundException e) {
// Fehler, Datei nicht gefunden, inhalt erstellen
dateiinhalt = new String("<?xml version=\"1.0\"?>");
dateiinhalt +=eol+"<"+root+">"+eol+"</"+root+">"+ eol;
try {
// Datei schreiben
FileWriter fs = new FileWriter(new File(datei));
fs.write(dateiinhalt);
fs.close();
} catch (IOException ioe) {
JOptionPane.showMessageDialog(null, ioe.toString(), "Fehler",JOptionPane.OK_OPTION);
}
}
}
/* Interne Finktion zum Testen, ob Ordner existiert
* wenn nicht, wird erstellt
* */
private static void ordnerTest(String datei){
// Pfad zu der Datei extrahieren
String nurpfad=datei.substring(0,datei.lastIndexOf(trenner));
// Pfad als File
File ordner=new File(nurpfad);
// wenn nicht existiert...
if(!ordner.exists()){
//... erstellen
ordner.mkdir();
}
}
}
Die "Starter"-Klasse:
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
/* kleine Testklasse für XML-Bibliothek
* einfach zum spielen :-)
* */
public class Starter implements ActionListener{
JFrame hfenster=new JFrame();
JPanel hpanel=new JPanel();
JButton btget=new JButton("GET");
JButton btset=new JButton("SET");
JTextField pfeld=new JTextField(20);
JTextField wfeld=new JTextField(20);
String trenner=System.getProperty("file.separator");
String fhome=System.getProperty("user.home");
String datei=fhome+trenner+"testapp"+trenner+"settings.xml";
String setroot="konfiguration";
public static void main(String[] args) {
new Starter();
}
public Starter(){
hfenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
hfenster.getContentPane().setLayout(new BorderLayout());
this.setPanel();
hfenster.getContentPane().add(hpanel,BorderLayout.CENTER);
hfenster.pack();
hfenster.setVisible(true);
}
private void setPanel(){
hpanel.setLayout(new GridBagLayout());
GridBagConstraints gbc=new GridBagConstraints();
gbc.gridx=0;gbc.gridy=0;
hpanel.add(new JLabel("Parameter"));
gbc.gridx=1;gbc.gridy=0;
hpanel.add(new JLabel("Wert"));
gbc.gridx=0;gbc.gridy=1;
hpanel.add(pfeld,gbc);
gbc.gridx=1;gbc.gridy=1;
hpanel.add(wfeld,gbc);
btget.setActionCommand("get");
btget.addActionListener(this);
gbc.gridx=0;gbc.gridy=2;
hpanel.add(btget,gbc);
btset.setActionCommand("set");
btset.addActionListener(this);
gbc.gridx=1;gbc.gridy=2;
hpanel.add(btset,gbc);
}
@Override
public void actionPerformed(ActionEvent ae) {
if(ae.getActionCommand().equals("get")){
wfeld.setText(XML.leseWert(datei, setroot, pfeld.getText()));
}else if(ae.getActionCommand().equals("set")){
XML.schreibeWert(datei,setroot,pfeld.getText(),wfeld.getText());
}
}
}
hoffe euch damit einiges an Arbeit erspart zu haben






