Index: lutinutil/src/java/org/codelutin/util/MyPropertyKeyManager.java diff -u /dev/null lutinutil/src/java/org/codelutin/util/MyPropertyKeyManager.java:1.1 --- /dev/null Sun Dec 9 19:22:14 2007 +++ lutinutil/src/java/org/codelutin/util/MyPropertyKeyManager.java Sun Dec 9 19:22:09 2007 @@ -0,0 +1,161 @@ +/* +* ##% Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Code Lutin, +* Benjamin Poussin, Tony Chemit, and others +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* ##% */ +package org.codelutin.util; + +import org.apache.commons.beanutils.ConvertUtils; +import org.apache.commons.beanutils.Converter; +import org.apache.commons.logging.Log; +import static org.apache.commons.logging.LogFactory.getLog; +import static org.codelutin.i18n.I18n._; +import static org.codelutin.util.MyPropertiesUtil.MyPropertyDef; +import static org.codelutin.util.MyPropertiesUtil.MyPropertyKey; + +import java.util.Map; + +/** + * a simple manager of MyPropertyKey, storing a cache of {@link MyPropertyKey}. + *

+ * A MyPropertyKey corresponding extacly to an entry of a Enum + * extended by {@link MyPropertyDef}. + *

+ * The class is a singleton, use {@link #getInstance()} method to obtain the + * shared instance. + * + * @author chemit + * @see MyPropertyKey + * @see MyPropertyDef + * @see MyProperties + */ +public class MyPropertyKeyManager { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private final Log log = getLog(MyPropertyKeyManager.class); + + /** the shared instance */ + static protected MyPropertyKeyManager instance; + + /** + * Obtain the shared {@link #instance}, and instanciate it the first time. + * + * @return the shared instanciated instance + */ + static public MyPropertyKeyManager getInstance() { + if (instance == null) { + instance = new MyPropertyKeyManager(); + } + return instance; + } + + /** + * Register a MyPropertyKey in the cache. + * + * @param key the key to store + * @throws IllegalArgumentException if key is already registred or if the + * converter of key is not found, or + * key.getKey() is duplicated for the given def. + */ + static public void registerKey(MyPropertyKey key) throws IllegalArgumentException { + MyPropertyDef def = key.getDef(); + MyPropertyKey entry = getInstance().getEntry(def, false); + if (entry != null) { + throw new IllegalArgumentException(_("lutin.error.properties.already.registred", def)); + } + // check unicity of key for this type of Def + getInstance().checkUniqueKey(def.getClass(), key.getKey()); + Class type = key.getType(); + if (type.isEnum()) { + // add the generic converter + EnumConverter.registerEnumConverter(type); + } else { + // check if there is an existing converter for the required type + Converter converter = ConvertUtils.lookup(type); + if (converter == null) { + throw new IllegalArgumentException(_("lutin.error.properties.unfound.convertor", type)); + } + } + log.debug(key); + getInstance().cache.put(def, key); + } + + + /** cache of registred MyPropertyKey associated to a MyPropertyDef */ + protected java.util.Map cache; + + /** + * @param def the def to be used + * @return the class defined for the valued of a given property + */ + public Class getType(MyPropertyDef def) { + MyPropertyKey entry = getEntry(def, true); + return entry == null ? null : entry.getType(); + } + + /** + * @param def the def to be used + * @return the key (used to store property) defined for a given property + */ + public String getKey(MyPropertyDef def) { + MyPropertyKey entry = getEntry(def, true); + return entry == null ? null : entry.getKey(); + } + + /** + * Obtain an entry of the cache. + * + * @param def the def to use + * @param safe if true, will produce Exception if could not + * found entry, otherwise silent return + * @return the entry corresponding to def, or null if not found and not + * safe. + */ + protected MyPropertyKey getEntry(MyPropertyDef def, boolean safe) { + MyPropertyKey entry = cache.get(def); + if (safe && entry == null) { + throw new IllegalArgumentException(_("lutin.error.properties.cache.unfound.entry", def)); + } + return entry; + } + + /** + * restricted constructor, since we should not instanciate it directly. + *

+ * Use {@link #getInstance()} instead. + */ + protected MyPropertyKeyManager() { + cache = new java.util.HashMap(); + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + if (cache != null) { + cache.clear(); + } + } + + private void checkUniqueKey(Class type, String key) { + for (Map.Entry entry : cache.entrySet()) { + MyPropertyKey value = entry.getValue(); + if (value.getDef().getClass() == type && value.getKey().equals(key)) { + throw new IllegalArgumentException(_("lutin.error.properties.duplicated.key", key, type)); + } + } + } +} \ No newline at end of file