package jade.util; import jade.core.Specifier; import jade.util.leap.ArrayList; import jade.util.leap.Iterator; import jade.util.leap.List; import jade.util.leap.Map; import jade.util.leap.HashMap; import jade.util.leap.Properties; import java.util.Vector; //#J2ME_EXCLUDE_FILE //#APIDOC_EXCLUDE_FILE /** * Utility class to manage instances of classes with attached properties i.e. classes specified in the form<br> * foo.Bar[key1=value1;key2=value2...] * This class allows registering "Loaders" for given types of objects (e.g. agents) and successively load such * objects using them */ public class ObjectManager { public static final String CLASS_NAME = "name"; // Predefined object types /** * The constant representing the "agent" type */ public static final String AGENT_TYPE = "agent"; private static Map loaders = new HashMap(); /** * The interface to be implemented by classes that can be registered to load objects of a given type */ public static interface Loader { Object load(String className, Properties pp) throws ClassNotFoundException, IllegalAccessException, InstantiationException; } /** * Convert a class-name, possibly with attached properties, into a Properties object * The actual class-name will be available as the value of the <code>CLASS_NAME</code> property */ private static Properties getClassProperties(String str) { Properties pp = new Properties(); int index = str.indexOf('['); if (index < 0) { pp.setProperty(CLASS_NAME, str); } else { pp.setProperty(CLASS_NAME, str.substring(0, index)); int index1 = str.indexOf(']'); String propsStr = str.substring(index+1, index1); Vector propsList = Specifier.parseList(propsStr, ';'); for (int i = 0; i < propsList.size(); ++i) { String ps = (String) propsList.get(i); int k = ps.indexOf('='); if (k > 0) { String name = ps.substring(0, k); String value = ps.substring(k+1); pp.setProperty(name, value); } } } return pp; } /** * Register a <code>Loader</code> for a given type of object. Note that more than one <code>Loader</code> * can be associated to a given type of object. * @param type The type of object the registered <code>Loader</code> is associated to * @param loader The <code>Loader</code> instance. */ public synchronized static void addLoader(String type, Loader loader) { List l = (List) loaders.get(type); if (l == null) { l = new ArrayList(); loaders.put(type, l); } l.add(loader); } public synchronized static boolean removeLoader(String type, Loader loader) { List l = (List) loaders.get(type); if (l != null) { return l.remove(loader); } return false; } /** * Try to load an object of a given type by means of the loaders (if any) associated to that type. * @param extendedClassName The class of the object to load in the form foo.Bar[key1=value1;key2=value2...] * @param type The type of object to load * @return The loaded object or null if no loader is suitable to load the object. * @throws ClassNotFoundException * @throws IllegalAccessException * @throws InstantiationException */ public synchronized static Object load(String extendedClassName, String type) throws ClassNotFoundException, IllegalAccessException, InstantiationException{ if (extendedClassName == null) { throw new IllegalArgumentException("Null class name"); } List l = (List) loaders.get(type); if (l != null && !l.isEmpty()) { // If we have loaders for this type of object, try to use them Properties pp = getClassProperties(extendedClassName); String className = pp.getProperty(ObjectManager.CLASS_NAME); Iterator it = l.iterator(); while (it.hasNext()) { Loader loader = (Loader) it.next(); Object obj = loader.load(className, pp); if (obj != null) { return obj; } } } return null; } }