View Full Version : [JAVA] Usare un file di configurazione stile Unix/Linux per le nostre applicazioni
fbcyborg
06-11-2008, 10:54
Salve a tutti,
nella mia applicazione mi sono trovato ad aver bisogno di un file di configurazione, che sia accessibile in lettura/scrittura sia dalla mia interfaccia grafica, sia ovviamente editandolo con un editor di testi.
Dal momento che è la prima volta che mi capita una cosa del genere vorrei chiedervi un consiglio: uso un normalissimo file di configurazione come si fa su Linux o XML?
Nel primo caso, dovrei scrivermi una buona parte di codice che interpreti se la riga è un commento o no; dovrebbe prendere ogni singola riga e fare il parsing delle stringhe, del tipo NOME_PARAMETRO="valore", catturando solo il valore in corrispondenza di un dato parametro richiesto ecc..
Siccome ho visto che questa cosa è abbastanza elaborata ho pensato a XML che mi sembra più indicato per questo genere di cose.
Facendo qualche ricerca ho trovato questo (http://commons.apache.org/configuration/downloads.html).
Non so però, se è esattamente quello che sto cercando.
Qualcuno può illuminarmi?
banryu79
06-11-2008, 12:39
Se il tuo file di configurazione non è troppo articolato penso possa bastare un semplice file di testo senza scomodare XML e librerie varie per parserizzarlo.
Magari se fai un esempio del file di config si può capire meglio se ti serva proprio XML o se invece sia più semplice gestire tutto con un file di testo.
Considera che se devi solo riconoscere una riga commentata da una valida, e quella valida è sempre e solo strutturata come una coppia "Nome Parametro", "Valore" imho ti basta il file di testo da parserizzare da te.
In Java c'è la classe Scanner (http://java.sun.com/javase/6/docs/api/java/util/Scanner.html)che potrebbe tornarti utile.
fbcyborg
06-11-2008, 12:47
Dunque, vorrei usare il file xml in previsione di ulteriori estensioni e ora il file è molto semplice.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<server-host>localhost</server-host>
</configuration>
Non riesco a capire come tirar fuori il valore localhost usando le librerie che ho importato.
C'è anche un esempio quì (http://commons.apache.org/configuration/userguide/overview.html).
Ovvero:
ConfigurationFactory factory = new ConfigurationFactory("config.xml");
Configuration config = factory.getConfiguration();
Però poi quando vado a fare:
System.out.println(config.getString("configuration.server-host"))
Ottengo sempre NULL!!!
La cosa mi interessa parecchio, quindi opterei per questa soluzione.
banryu79
06-11-2008, 12:52
Dunque, vorrei usare il file xml in previsione di ulteriori estensioni e ora il file è molto semplice.
Nulla da ridire sulle tue scelte ma hai mai sentito parlare di YAGNI (http://c2.com/xp/YouArentGonnaNeedIt.html)?
fbcyborg
06-11-2008, 12:56
Si conosco bene questa filosofia, grazie.
Ora però sto cercando di capire come usare questo Configuration di org.apache.
Ho notato che facendo un config.setProperty("configuration.server-host", "localhost");
effettivamente poi quando vado a fare System.out.println(config.getString("configuration.server-host"))
Ottengo localhost!
Quindi in un certo senso funziona. Solo non capisco perché effettivamente il file non viene usato! E' come se usasse un file XML in memoria, e non usasse il vero file xml che ho messo nella root del progetto. Però di fatto lo vuole in input come ho scritto prima! :muro:
^TiGeRShArK^
06-11-2008, 13:03
è inutile complicarti la vita in quel modo.
usa questo:
http://java.sun.com/javase/6/docs/api/java/util/Properties.html
Volendo puoi anche scrivere le properties direttamente in XML con i metodi loadFromXML(InputStream) e storeToXML(OutputStream, String, String), ma io ti consiglio il normale file di testo.
fbcyborg
06-11-2008, 13:30
Grazie! :doh: :doh: :doh:
Porca miseria! E pensare che la classe Properties l'avevo già usata in un corso universitario per gli EJB.
Ora vedo che cosa si può fare.
EDIT: ho risolto prendendo spunto da questo (http://www.kodejava.org/examples/267.html) esempio.
Spero possa essere utile anche ad altri.
Grazie a tutti ancora.
^TiGeRShArK^
06-11-2008, 15:23
è meglio non usare il FileInputStream per accedere alle properties ma il resourcebundle o il getResourceAsStream come in questo esempio:
http://www.javaworld.com/javaworld/javaqa/2003-08/01-qa-0808-property.html?page=2
In questo modo non si è vincolati al filesystem, ma si utilizza direttamente il classloader della VM.
fbcyborg
06-11-2008, 15:30
Mi sembra un po' complicato l'esempio in fondo alla pagina.
Gentilmente, potresti mostrarmi come faresti tu, adattando il codice che ho linkato io, con quello che hai detto tu?
Grazie!
^TiGeRShArK^
06-11-2008, 15:47
Mi sembra un po' complicato l'esempio in fondo alla pagina.
Gentilmente, potresti mostrarmi come faresti tu, adattando il codice che ho linkato io, con quello che hai detto tu?
Grazie!
basta usare questo nel metodo readProperties:
properties.loadFromXML(Class.getResourceAsStream ("/some/pkg/configuration.xml"));
ovviamente mettendo al posto di some e di pkg il nome dei tuoi package in cui c'è il file di config :p
fbcyborg
06-11-2008, 16:06
Guarda, c'ho provato ma non funziona.
Da sempre problemi sul fatto che non posso chiamare un metodo statico in un contesto non statico o viceversa, ora non ricordo bene.
So bene che quanto lamenta il compilatore è corretto! Ci mancherebbe. Solo che evidentemente non riesco a rimettere bene le cose a posto nel mio contesto.
Ora il problema è un altro.
Quello che mi serve di fare è, caricare una certa proprietà in base alla chiave, mostrarla in una JLabel e dare la possibilità di modificare il valore in questione nel file di configurazione xml.
Fino a quì ci sono... Prelevo il valore in base alla chiave con:
jLabel4.setText(properties.getProperty("server-host"));
Poi do la possibilità all'utente di modificare quel valore, tramite un JButton.
Nell'actionPerformed del JButton faccio:
properties.setProperty("server-host", host);
Dove host è la variabile di tipo String che contiene il nuovo valore.
Successivamente, dovrò aggiornare il mio file config.xml e quindi ho pensato "bene" di dare la seguente istruzione:
properties.store(new FileOutputStream("config.xml"), null);
Il problema è che me lo cancella tutto e me lo riformatta come gli pare a lui, togliendo tutta la struttura del file xml, ovvero:
#Thu Nov 06 16:06:22 GMT+01:00 2008
server-host=nuovoValore
Come faccio a dirgli che invece deve modificare solo il necessario andando a modificare solo il valore e non tutto il file?
EDIT: ho trovato l'errore. Dovevo usare storeToXML() anziché store().
fbcyborg
09-11-2008, 12:24
E' normale che il mio file xml, dopo esser stato modificato via software, perda l'indentazione?
In caso, com'è possibile fare in modo che non la perda?
^TiGeRShArK^
09-11-2008, 12:34
E' normale che il mio file xml, dopo esser stato modificato via software, perda l'indentazione?
In caso, com'è possibile fare in modo che non la perda?
ehmm..
che intendi con "modificato via software"? :stordita:
con cosa l'hai modificato?
fbcyborg
09-11-2008, 12:54
Intendo quando faccio un setProperty e uno store tramite un oggetto Properties.
In questo modo vado a modificare un determinato valore in base alla chiave passata e poi applico le modifiche su file con lo store(). Proprio come ho detto un paio di post fa.
Inizialmente il mio file xml era ben indentato. Una volta che ho dato lo "store" ha perso l'indentazione.
NB: questo non mi crea problemi di funzionalità, anzi.. tutt'altro. Mi interessava solo per migliorare la leggibilità qualora ce ne fosse la necessità di modificare tale file a mano.
^TiGeRShArK^
09-11-2008, 13:14
Intendo quando faccio un setProperty e uno store tramite un oggetto Properties.
In questo modo vado a modificare un determinato valore in base alla chiave passata e poi applico le modifiche su file con lo store(). Proprio come ho detto un paio di post fa.
Inizialmente il mio file xml era ben indentato. Una volta che ho dato lo "store" ha perso l'indentazione.
NB: questo non mi crea problemi di funzionalità, anzi.. tutt'altro. Mi interessava solo per migliorare la leggibilità qualora ce ne fosse la necessità di modificare tale file a mano.
boh..
non mi pare che lo storeToXml permetta di specificare se mantenere l'indentazione come fanno i parser...
Al limite potresti leggere il file con un parser decente e riscriverlo con la formattazione corretta.
Però, secondo me, la scelta migliore in questo caso è fare uno store su un file .properties di testo e memorizzare le informazioni come coppia chiave valore che è il metodo in assoluto + leggibile :p
fbcyborg
09-11-2008, 13:20
Ok, ti ringrazio. Pazienza se non è possibile! :)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.