Logiciel de gestion de plan de feu pour les troupes de théâtre amateur.
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

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 ());
}
// ========================================
}