Index: lutinutil/src/java/org/codelutin/util/MyProperties.java diff -u lutinutil/src/java/org/codelutin/util/MyProperties.java:1.2 lutinutil/src/java/org/codelutin/util/MyProperties.java:1.3 --- lutinutil/src/java/org/codelutin/util/MyProperties.java:1.2 Mon Dec 10 02:35:41 2007 +++ lutinutil/src/java/org/codelutin/util/MyProperties.java Tue Dec 11 02:08:52 2007 @@ -28,14 +28,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; -import java.util.ArrayList; -import java.util.Collections; -import java.util.EnumSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.SortedMap; -import java.util.TreeMap; +import java.util.*; /** * This class encapsulate a {@link Properties} object with more @@ -113,6 +106,19 @@ return universe; } + protected Set universeAsKey; + + public Set getUniverseAsKey() { + if (universeAsKey == null) { + universeAsKey = new HashSet(); + for (T t : universe) { + MyPropertyKey entry = getEntry(t); + universeAsKey.add(entry.getKey()); + } + } + return universeAsKey; + } + public EnumSet getKeys() { return keys; } @@ -180,14 +186,23 @@ /** * @param key the given key - * @return true if key is legal and used - * ,false otherwise. + * @return true if key is legal and used, + * false otherwise. */ public boolean containsKey(T key) { return universe.contains(key) && keys.contains(key); } /** + * @param key the given key + * @return true if key is known as unsafe, + * false otherwise. + */ + public boolean containsUnsafeKey(Object key) { + return !isSafe() && unsafeData.containsKey(key); + } + + /** * @param key the given unsafe key, this is the original key of unsafe * property (if a load was done), this is not connected with MyPropertyKey. * @return the value of the given unsafe value, or null if there is not a @@ -202,6 +217,25 @@ return result; } + public MyPropertyKey getEntry(T def) { + return getEntry((MyPropertyDef) def); + } + + public MyPropertyKey getEntry(MyPropertyDef def) { + return getManager().getEntry(def, false); + } + + public java.util.List getUnsafeDataKeys() { + if (isSafe()) { + return Collections.emptyList(); + } + List result = new ArrayList(getUnsafeData().size()); + for (Object o : unsafeData.keySet()) { + result.add(o); + } + return result; + } + /** * Remove a unsafe property using a given unsage key, if there is a such * unsafe property. @@ -323,13 +357,13 @@ } /** - * TODO We should not save unsafe data, so perform a clearUnsafeData before all. - * Save current configuration in a simple properties file. + * Save safe current configuration in a simple properties file. + * *

* Each valid property is saved using the his key given by the method * {@link MyPropertyKey#getKey()} for his entry. *

- * Unsafe data are stored as they are. + * Unsafe data are not stored! * * @param out where to store * @param comments comment to add in file @@ -342,15 +376,17 @@ for (T key : getKeys()) { MyPropertyKey entry = getManager().getEntry((MyPropertyDef) key, false); Object val = data.get(key); + // a shame that Properties.store can only deal with String + // value tmp.put(entry.getKey(), val == null ? "" : val.toString()); } } - if (!isSafe()) { + /*if (!isSafe()) { for (Object key : getUnsafeDataKeys()) { Object val = unsafeData.get(key); tmp.put(key, val == null ? "" : val.toString()); } - } + } */ tmp.store(out, comments); } finally { tmp.clear(); @@ -481,7 +517,7 @@ // make a conversion from String Object typeValue = convert(entry.getType(), value); if (typeValue == null) { - addUnsafeData(entry.getKey(), klass, value); + addUnsafeData(entry.getKey(), value); } else { addProperty(def, typeValue); } @@ -504,7 +540,7 @@ } } if (value2 == null) { - addUnsafeData(entry.getKey(), klass, value); + addUnsafeData(entry.getKey(), value); } } @@ -527,7 +563,7 @@ if (def != null && key != null && universe.contains(def)) { setProperty(def, value, false); } else { - addUnsafeData(kStr, key == null ? null : key.getType(), value); + addUnsafeData(kStr, value); } } } finally { @@ -566,10 +602,9 @@ * Set a unsafe property. * * @param key unsafe key - * @param klass the unsafe property value's type * @param value the unsafe property value to set */ - protected void addUnsafeData(Object key, Class klass, Object value) { + protected void addUnsafeData(Object key, Object value) { getUnsafeData().put(key, value); } @@ -634,18 +669,11 @@ this.manager = MyPropertyKeyManager.getInstance(); } - public MyPropertyKey getEntry(T def) { - return getManager().getEntry((MyPropertyDef) def, false); - } - - public java.util.List getUnsafeDataKeys() { - if (isSafe()) { - return Collections.emptyList(); - } - List result = new ArrayList(getUnsafeData().size()); - for (Object o : unsafeData.keySet()) { - result.add(o); + @SuppressWarnings({"unchecked"}) + public boolean containsKey(MyPropertyDef def) { + if (!def.getClass().equals(this.keyType)) { + throw new IllegalArgumentException(_("lutinutil.error.config.unauthorized.type.key", keyType)); } - return result; + return containsKey((T) def); } } Index: lutinutil/src/java/org/codelutin/util/MyPropertiesUtil.java diff -u lutinutil/src/java/org/codelutin/util/MyPropertiesUtil.java:1.1 lutinutil/src/java/org/codelutin/util/MyPropertiesUtil.java:1.2 --- lutinutil/src/java/org/codelutin/util/MyPropertiesUtil.java:1.1 Sun Dec 9 19:11:48 2007 +++ lutinutil/src/java/org/codelutin/util/MyPropertiesUtil.java Tue Dec 11 02:08:52 2007 @@ -25,8 +25,10 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.net.URI; import java.util.Properties; +import java.util.Set; /** * Some usefull class and methods for {@link MyProperties} @@ -38,11 +40,11 @@ static private org.apache.commons.logging.Log log = getLog(MyPropertiesUtil.class); /** - * This is the contract to be realised by any key to be used in + * This is the contract to be realised by any key to be used in a * {@link MyProperties}. *

- * Concrete implementation of this class must always be an extends - * of {@link Enum}. + * Concrete implementation of this class must always be an extends + * of {@link Enum}. * * @author tony */ @@ -109,7 +111,6 @@ sb.append(")>"); return sb.toString(); } - } /** @@ -149,6 +150,91 @@ } /** + * Enregistre dans un même flux de sortie, plusieurs MyProperties, avec un + * unique message. + *

+ * + * @param stream le stream de sortie + * @param message la liste des messages à inscrire + * @param properties la liste des MyProperties à sauver dans le flux + * @throws java.io.IOException si problème lors de la sauvegarde + */ + public static void store(OutputStream stream, String message, MyProperties... properties) throws IOException { + if (properties.length == 0) { + // nothing to do + return; + } + if (message == null) { + throw new IllegalArgumentException("must have same number of message than Myroperties to save, but was not"); + } + String[] messages = new String[properties.length]; + messages[0] = message; + store(stream, messages, properties); + } + + /** + * Enregistre dans un même flux de sortie, plusieurs MyProperties, avec un + * message pour chaque MyProperties.. + *

+ * Attention, il faut définir un message pour chaque MyProperties à sauver. + * + * @param stream le stream de sortie + * @param message la liste des messages à inscrire + * @param properties la liste des MyProperties à sauver dans le flux + * @throws java.io.IOException si problème lors de la sauvegarde + */ + public static void store(OutputStream stream, String[] message, MyProperties... properties) throws IOException { + if (properties.length == 0) { + // nothing to do + return; + } + if (message == null || message.length != properties.length) { + throw new IllegalArgumentException("must have same number of message than Myroperties to save, but was not"); + } + for (int i = 0; i < properties.length; i++) { + MyProperties property = properties[i]; + property.store(stream, message[i]); + } + } + + /** + * Lit à partir d'un même flux de sortie, plusieurs MyProperties. + *

+ * L'algorithme essaye de placer au mieux les propriétés qu'il trouve. + *

+ * Au final chaque MyProperties contiendra en plus de ses propriétés valides + * l'ensemble des propriétés unsafe détectées comme n'ayant pas de clef + * valide ou ayant une clef valide dans son univers. + * + * @param stream le stream d'entrée + * @param properties la liste des MyProperties à sauver dans le flux + * @throws java.io.IOException si problème lors de la lecture + */ + public static void load(URI stream, MyProperties... properties) throws IOException { + if (properties.length == 0) { + // nothing to do + return; + } + Properties props = loadConfig(stream, false, false); + // first pass, inject properties known as valid from their key + for (MyProperties property : properties) { + Properties tmp = new Properties(); + Set univers = property.getUniverseAsKey(); + for (String key : univers) { + if (props.containsKey(key)) { + tmp.put(key, props.get(key)); + props.remove(key); + } + } + property.load(tmp); + } + // second pass inject, properties known as unsafe + for (MyProperties property : properties) { + property.load(props); + } + } + + /** * Load a properties files fro a given uri. * * @param uri the uri where to find the properties file