You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
523 lines
17 KiB
523 lines
17 KiB
package misc;
|
|
|
|
import java.awt.Component;
|
|
import java.awt.Point;
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.net.URL;
|
|
import java.text.DecimalFormat;
|
|
import java.text.MessageFormat;
|
|
import java.util.Date;
|
|
import java.util.Locale;
|
|
import java.util.Properties;
|
|
import java.util.Vector;
|
|
import javax.swing.JComboBox;
|
|
import javax.swing.JList;
|
|
import javax.swing.JOptionPane;
|
|
import javax.swing.ListModel;
|
|
|
|
/**
|
|
Managed the persistance key/value strings association.
|
|
This class could be used to managed all constants values in a application.
|
|
The values commme from a bundle jar (mix of class and data) or a dedicated directeory.
|
|
*/
|
|
public class Config {
|
|
|
|
static public final String FS = System.getProperty ("file.separator");
|
|
|
|
static public final String
|
|
dataDirname = "data",
|
|
configDirname = "config",
|
|
textsDirname = "texts",
|
|
logDirname = "log",
|
|
imagesDirname = "images",
|
|
iconsDirname = "images",
|
|
buttonDirname = "button",
|
|
flagsDirname = "flags";
|
|
|
|
/** Path to configuration files in files system. */
|
|
static public final String
|
|
configSystemDir = dataDirname+FS+configDirname+FS,
|
|
logSystemDir = dataDirname+FS+logDirname+FS,
|
|
buttonSystemDir = dataDirname+FS+imagesDirname+FS+buttonDirname+FS;
|
|
|
|
/** Path to configuration files in jar. */
|
|
static public final String
|
|
configJarDir = dataDirname+"/"+configDirname+"/",
|
|
imagesJarDir = dataDirname+"/"+imagesDirname+"/",
|
|
textsJarDir = dataDirname+"/"+textsDirname+"/";
|
|
|
|
/** Configuration file extension. */
|
|
static public final String
|
|
configExt = ".xml",
|
|
iconsExt = ".png",
|
|
imagesExt = ".png",
|
|
htmlExt = ".html",
|
|
logExt = ".log";
|
|
|
|
|
|
/** Enconding charset for saving configuration. */
|
|
static public final String configEncoding = "UTF8";
|
|
|
|
/** Comment used as header configuration file. */
|
|
static public final String configHeaderFile =
|
|
"This file is automaticaly generated by {0} application at {1,time,short} on {1,date}.";
|
|
|
|
/** Somme postfix for constants name in configuration file. */
|
|
static public final String
|
|
checkedPostfix = "Checked",
|
|
undockedPostfix = "Undocked",
|
|
locationPostfix = "Location";
|
|
|
|
/** Message shows when trying to get string with a null key. */
|
|
static private final String configNullKeyException = "No configuration associates with null key.";
|
|
|
|
/** Message shows when trying to use configuration before load it. */
|
|
static private final String configUseException = "No configuration loaded.";
|
|
|
|
/** Message shows when load exception appears. */
|
|
static private final String configLoadException = "Configuration {0} can''t be load (corrupted file ?).";
|
|
|
|
/** Message shows when save exception appears. */
|
|
static private final String configSaveException = "Configuration {0} can''t be save.";
|
|
|
|
/** Liste of constants (key/value strings association). */
|
|
//static private Properties configuration;
|
|
static public Properties configuration;
|
|
|
|
/** True if configuration need to be saved. */
|
|
static private boolean configurationModified = false;
|
|
|
|
// ========================================
|
|
static private File PWD;
|
|
static private String[] dataPath;
|
|
static {
|
|
setPWD (Util.class);
|
|
setDataPath (".:..");
|
|
}
|
|
|
|
static public File getJarFileOrClassDir (Class<?> applicationClass) {
|
|
try {
|
|
return new File (applicationClass.getProtectionDomain ().getCodeSource ().getLocation ().toURI ());
|
|
} catch (Exception e) {
|
|
// dosn't work for applet
|
|
return null;
|
|
}
|
|
}
|
|
static public File getPWD () { return PWD; }
|
|
// XXX static public String getPWD () { return PWD.getAbsolutePath (); }
|
|
static public void setPWD (Class<?> applicationClass) {
|
|
try {
|
|
PWD = getJarFileOrClassDir (applicationClass).getParentFile ();
|
|
} catch (Exception e) {
|
|
}
|
|
}
|
|
static public void setDataPath (String path) {
|
|
dataPath = path.split (":");
|
|
}
|
|
static public File findDataDir () {
|
|
return findDataDir (false);
|
|
}
|
|
static public File findDataDir (boolean writable) {
|
|
String name = dataDirname;
|
|
try {
|
|
// search from excecution dir
|
|
File file = (new File (name));
|
|
if (file.exists () && file.isDirectory () && (!writable || file.canWrite ()))
|
|
return file;
|
|
} catch (Exception e) {
|
|
}
|
|
for (String path : dataPath) {
|
|
try {
|
|
// search in relative path from jar
|
|
File file = (new File (PWD, path+FS+name));
|
|
if (file.exists () && file.isDirectory () && (!writable || file.canWrite ()))
|
|
return file;
|
|
} catch (Exception e) {
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
static public URL getDataUrl (String... names) {
|
|
if (names.length < 1)
|
|
return null;
|
|
String name = names[names.length - 1];
|
|
String jarPath = "", systemPath = "";
|
|
for (int i = 0; i < names.length - 1; i++) {
|
|
jarPath += names[i]+"/";
|
|
systemPath += names[i]+FS;
|
|
}
|
|
try {
|
|
// search from excecution dir
|
|
File file = new File (systemPath+name);
|
|
if (file.exists ())
|
|
return file.toURI ().toURL ();
|
|
} catch (Exception e) {
|
|
}
|
|
for (String path : dataPath) {
|
|
try {
|
|
// search in relative path from jar
|
|
File file = new File (PWD, path+FS+systemPath+name);
|
|
if (file.exists ())
|
|
return file.getCanonicalFile ().toURI ().toURL ();
|
|
} catch (Exception e) {
|
|
}
|
|
}
|
|
try {
|
|
// search in jar
|
|
URL result = ClassLoader.getSystemResource (jarPath+name);
|
|
return result;
|
|
} catch (Exception e) {
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// ========================================
|
|
/**
|
|
Load XML configuration file contains constants (key/value strings association).
|
|
@param applicationName the application name use to find file.
|
|
*/
|
|
static public final void load (String applicationName) {
|
|
configuration = new Properties ();
|
|
try {
|
|
File configDir = new File (findDataDir (), configDirname);
|
|
File configFile = new File (configDir, applicationName+configExt);
|
|
FileInputStream fileInputStream = new FileInputStream (configFile);
|
|
configuration.loadFromXML (fileInputStream);
|
|
fileInputStream.close ();
|
|
configurationModified = false;
|
|
} catch (Exception e) {
|
|
try {
|
|
configuration.loadFromXML (ClassLoader.getSystemResourceAsStream
|
|
(configJarDir+applicationName+configExt));
|
|
configurationModified = false;
|
|
} catch (Exception e2) {
|
|
try {
|
|
configuration.loadFromXML (ClassLoader.getSystemResourceAsStream
|
|
(configJarDir+applicationName+configExt));
|
|
configurationModified = false;
|
|
} catch (Exception e3) {
|
|
if (JOptionPane.YES_OPTION != JOptionPane.showConfirmDialog
|
|
(null, "Would you like to continue?",
|
|
" Can't load Configuration ", JOptionPane.YES_NO_OPTION))
|
|
throw new IllegalArgumentException (MessageFormat.format (configLoadException, applicationName));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ========================================
|
|
/**
|
|
Return the loading state of the configuration.
|
|
@return true if the configuration is loaded.
|
|
*/
|
|
static public boolean isLoaded () {
|
|
return configuration != null;
|
|
}
|
|
|
|
// ========================================
|
|
/**
|
|
Save XML configuration file contains key/value strings association.
|
|
The file is not writing if no modification occure.
|
|
@param applicationName the application name use to save file.
|
|
*/
|
|
static public final void save (String applicationName) {
|
|
File configDir = new File (findDataDir (true), configDirname);
|
|
File configFile = new File (configDir, applicationName+configExt);
|
|
try {
|
|
save (applicationName, configFile);
|
|
} catch (IOException e) {
|
|
try {
|
|
e.printStackTrace ();
|
|
configDir.mkdirs ();
|
|
save (applicationName,configFile);
|
|
} catch (IOException e2) {
|
|
System.err.println (MessageFormat.format (configSaveException, applicationName));
|
|
}
|
|
} catch (NullPointerException e) {
|
|
throw new IllegalArgumentException (configUseException);
|
|
}
|
|
}
|
|
|
|
static public final void save (String applicationName, File file)
|
|
throws IOException {
|
|
if (!configurationModified && file.exists ())
|
|
return;
|
|
if (!file.exists ())
|
|
file.createNewFile ();
|
|
FileOutputStream fileOutputStream = new FileOutputStream (file);
|
|
configuration.storeToXML (fileOutputStream,
|
|
(new MessageFormat (configHeaderFile, Locale.US)).format (new Object[] {applicationName, new Date ()},
|
|
new StringBuffer(), null).toString (),
|
|
configEncoding);
|
|
fileOutputStream.close ();
|
|
configurationModified = false;
|
|
}
|
|
|
|
// ========================================
|
|
|
|
// XXX defaultValue peut être placé systématiquement (voir à null)
|
|
/**
|
|
Searches for the value with the specified key in this configuration list.
|
|
@param key the name of the configuration parameter.
|
|
@return the configuration value associated with the key or null if not found.
|
|
*/
|
|
static public final String getString (String key) {
|
|
if (key == null)
|
|
throw new IllegalArgumentException (configNullKeyException);
|
|
try {
|
|
return configuration.getProperty (key);
|
|
} catch (NullPointerException e) {
|
|
throw new IllegalArgumentException (configUseException);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Searches for the value with the specified key in this configuration list.
|
|
@param key the name of the configuration parameter.
|
|
@param defaultValue the defaultValue in case the key is not found.
|
|
@return the configuration value associated with the key or defaultValue if not found.
|
|
*/
|
|
static public final String getString (String key, String defaultValue) {
|
|
String value = configuration.getProperty (key);
|
|
if (value != null)
|
|
return value;
|
|
configuration.setProperty (key, defaultValue);
|
|
return defaultValue;
|
|
}
|
|
|
|
/**
|
|
Change the value with the specified key in this configuration list.
|
|
@param key the name of the configuration parameter.
|
|
@param value the new configuration value associated with the key.
|
|
*/
|
|
static public final void setString (String key, String value) {
|
|
try {
|
|
configuration.setProperty (key, value);
|
|
configurationModified = true;
|
|
} catch (NullPointerException e) {
|
|
throw new IllegalArgumentException (configUseException);
|
|
}
|
|
}
|
|
|
|
// ========================================
|
|
static public final File getFile (String key) {
|
|
String fileName = getString (key);
|
|
if (fileName == null)
|
|
return null;
|
|
return new File (fileName);
|
|
}
|
|
|
|
static public final void setFile (String key, File file) {
|
|
setString (key, file.getPath ());
|
|
}
|
|
|
|
// ========================================
|
|
static public final boolean getBoolean (String key) {
|
|
return Boolean.parseBoolean (getString (key));
|
|
}
|
|
|
|
static public final boolean getBoolean (String key, boolean defaultValue) {
|
|
return Boolean.parseBoolean (getString (key, ""+defaultValue));
|
|
}
|
|
|
|
static public final void setBoolean (String key, boolean value) {
|
|
setString (key, ""+value);
|
|
}
|
|
|
|
// ========================================
|
|
static public final int getInt (String key) {
|
|
return Integer.parseInt (getString (key));
|
|
}
|
|
|
|
static public final int getInt (String key, int defaultValue) {
|
|
try {
|
|
return Integer.parseInt (getString (key, ""+defaultValue));
|
|
} catch (Exception e) {
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
static public final void setInt (String key, int value) {
|
|
setString (key, ""+value);
|
|
}
|
|
|
|
// ========================================
|
|
static public final float getFloat (String key) {
|
|
return Float.parseFloat (getString (key));
|
|
}
|
|
|
|
static public final float getFloat (String key, float defaultValue) {
|
|
try {
|
|
return Float.parseFloat (getString (key, ""+defaultValue));
|
|
} catch (Exception e) {
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
static public final void setFloat (String key, float value) {
|
|
setString (key, ""+value);
|
|
}
|
|
|
|
// ========================================
|
|
static public final double getDouble (String key) {
|
|
return Double.parseDouble (getString (key));
|
|
}
|
|
|
|
static public final double getDouble (String key, double defaultValue) {
|
|
try {
|
|
return Double.parseDouble (getString (key, ""+defaultValue));
|
|
} catch (Exception e) {
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
static public final void setDouble (String key, double value) {
|
|
setString (key, ""+value);
|
|
}
|
|
|
|
// ========================================
|
|
static public final<T> T getEnum (String key, T defaultValue) {
|
|
return Util.toEnum (getString (key, ""+defaultValue), defaultValue);
|
|
}
|
|
|
|
// ========================================
|
|
static public final DecimalFormat indexFormat = new DecimalFormat ("-0000");
|
|
|
|
static public final Vector<String> getList (String key, String defaultValue) {
|
|
Vector<String> result = new Vector<String> ();
|
|
int size = Integer.parseInt (getString (key+"-size", "1"));
|
|
result.add (getString (key, defaultValue));
|
|
for (int i = 1; i < size; i++)
|
|
result.add (getString (key+indexFormat.format (i)));
|
|
return result;
|
|
}
|
|
|
|
static public final void setList (String key, Vector<String> value) {
|
|
// XXX suppression des anciennes valeurs
|
|
int size = value.size ();
|
|
int max = Integer.parseInt (getString (key+"-max", "10"));
|
|
setString (key+"-max", ""+max);
|
|
setString (key+"-size", ""+size);
|
|
setString (key, value.elementAt (0));
|
|
size = Math.min (size, max);
|
|
for (int i = 1; i < size; i++)
|
|
setString (key+indexFormat.format (i), value.elementAt (i));
|
|
}
|
|
|
|
// ========================================
|
|
// XXX faire un defaultValue en vector
|
|
static public final void loadJList (String key, JList<String> jList, String defaultValue) {
|
|
Vector<String> list = getList (key, defaultValue);
|
|
jList.setListData (list);
|
|
jList.setSelectedIndex (0);
|
|
}
|
|
|
|
static public final void saveJList (String key, JList<String> jList) {
|
|
Vector<String> result = new Vector<String> ();
|
|
ListModel<String> model = jList.getModel ();
|
|
int size = model.getSize ();
|
|
for (int i = 0; i < size; i++)
|
|
result.add (model.getElementAt (i));
|
|
int index = jList.getSelectedIndex ();
|
|
if (index >= 0) {
|
|
result.insertElementAt (result.remove (index), 0);
|
|
jList.setListData (result);
|
|
jList.setSelectedIndex (0);
|
|
}
|
|
setList (key, result);
|
|
}
|
|
|
|
// ========================================
|
|
// XXX faire un defaultValue en vector
|
|
static public final void loadJComboBox (String key, JComboBox<String> jComboBox, String defaultValue) {
|
|
Vector<String> list = getList (key, defaultValue);
|
|
jComboBox.removeAllItems ();
|
|
for (int i = 0; i < list.size (); i++)
|
|
jComboBox.addItem (list.elementAt (i));
|
|
jComboBox.setSelectedIndex (0);
|
|
}
|
|
|
|
static public final void loadJComboBoxInteger (String key, JComboBox<Integer> jComboBox, String defaultValue) {
|
|
Vector<String> list = getList (key, defaultValue);
|
|
jComboBox.removeAllItems ();
|
|
for (int i = 0; i < list.size (); i++) {
|
|
try {
|
|
jComboBox.addItem (Integer.parseInt (list.elementAt (i)));
|
|
} catch (Exception e) {
|
|
}
|
|
}
|
|
jComboBox.setSelectedIndex (0);
|
|
}
|
|
|
|
static public final void saveJComboBox (String key, JComboBox<String> jComboBox) {
|
|
// XX peut être ajouter la valeur éditer dans la liste
|
|
Vector<String> result = new Vector<String> ();
|
|
int size = jComboBox.getItemCount ();
|
|
for (int i = 0; i < size; i++)
|
|
result.add (jComboBox.getItemAt (i));
|
|
int index = jComboBox.getSelectedIndex ();
|
|
if (index < 0)
|
|
result.insertElementAt ((String) jComboBox.getSelectedItem (), 0);
|
|
else
|
|
result.insertElementAt (result.remove (index), 0);
|
|
if (index != 0) {
|
|
jComboBox.removeAllItems ();
|
|
for (int i = 0; i < result.size (); i++)
|
|
jComboBox.addItem (result.elementAt (i));
|
|
jComboBox.setSelectedIndex (0);
|
|
}
|
|
setList (key, result);
|
|
}
|
|
|
|
static public final void saveJComboBoxInteger (String key, JComboBox<Integer> jComboBox) {
|
|
// XX peut être ajouter la valeur éditer dans la liste
|
|
Vector<String> result = new Vector<String> ();
|
|
int size = jComboBox.getItemCount ();
|
|
for (int i = 0; i < size; i++)
|
|
result.add (""+jComboBox.getItemAt (i));
|
|
int index = jComboBox.getSelectedIndex ();
|
|
if (index < 0)
|
|
result.insertElementAt ((String) jComboBox.getSelectedItem (), 0);
|
|
else
|
|
result.insertElementAt (result.remove (index), 0);
|
|
setList (key, result);
|
|
}
|
|
|
|
// ========================================
|
|
/** Text format used to represent coordonates (i.e. [x=123,y=456] ). */
|
|
static public final MessageFormat coordonateFormat = new MessageFormat ("[x={0,number,integer},y={1,number,integer}]");
|
|
|
|
/**
|
|
Set component location from a constant coordonates in configuration.
|
|
@param key the name used to denoted the contant.
|
|
@param component modified by the coordonates retreived in configuration.
|
|
@param defaultLocation default coordonates used if non key present.
|
|
*/
|
|
static public final void loadLocation (String key, Component component, Point defaultLocation) {
|
|
try {
|
|
Object [] location = coordonateFormat.parse (getString (key+locationPostfix),
|
|
new java.text.ParsePosition (0));
|
|
component.setLocation (((Number) location [0]).intValue (), ((Number) location [1]).intValue ());
|
|
} catch (Exception e) {
|
|
component.setLocation (defaultLocation);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Save constant coordonates to configuration form a component location.
|
|
@param key the name used to denoted the contant.
|
|
@param component used to set the contant coordonates value.
|
|
*/
|
|
static public final void saveLocation (String key, Component component) {
|
|
Point location = component.getLocation ();
|
|
setString (key+locationPostfix,
|
|
coordonateFormat.format (new Object [] {location.x, location.y},
|
|
new StringBuffer(), null).toString ());
|
|
}
|
|
|
|
// ========================================
|
|
}
|
|
|