package hep.io.root.core; import hep.io.root.RootClass; import hep.io.root.RootClassNotFound; import hep.io.root.RootFileReader; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import java.util.Hashtable; import java.util.Properties; /* * The root class factory is used to create instances * of RootClass object. * @author Tony Johnson (tonyj@slac.stanford.edu) * @version $Id: DefaultClassFactory.java 13617 2009-04-09 22:48:46Z tonyj $ */ public class DefaultClassFactory implements RootClassFactory { private final static Class[] argc = { String.class, StreamerInfo.class }; private Hashtable classMap = new Hashtable(); private RootClassLoader loader; private RootFileReader rfr; private String[] packageList; /** * Creates a Root Class factory that looks in hep.io.root.interfaces for classes * and uses the default properties files for looking for StreamerInfo * and typedefs */ public DefaultClassFactory(RootFileReader rfr) { loader = new RootClassLoader(rfr); try { Properties typedef = new Properties(); InputStream in = getClass().getResourceAsStream("Typedef.properties"); typedef.load(in); in.close(); Properties streamerInfo = new Properties(); in = getClass().getResourceAsStream("StreamerInfo.properties"); streamerInfo.load(in); in.close(); //String[] classPackages = { "hep.io.root.reps" }; init(typedef, streamerInfo); //,classPackages,rfr); } catch (IOException x) { throw new RuntimeException("Unable to load default properties",x); } } public RootClassLoader getLoader() { return loader; } /** * Creates an instance of a RootClass object, by searching * for an appropriate class definition. */ public BasicRootClass create(String name) throws RootClassNotFound { BasicRootClass result = (BasicRootClass) classMap.get(name); if (result != null) return result; // Try to see if there is a class in the package list throw new RootClassNotFound(name); } static RootClass findClass(String name, StreamerInfo info) { try { Class c = Class.forName("hep.io.root.classes." + name); java.lang.reflect.Constructor cc = c.getConstructor(argc); Object[] args = { name, info }; return (RootClass) cc.newInstance(args); } catch (Throwable x) { return new GenericRootClass(name, info); } } private void init(Properties typedef, Properties streamerInfo) // , String[] packageList, RootFileReader rfr) { //this.packageList = packageList; try { // Convert all the typedefs to Java intrinsic classes Enumeration e = typedef.keys(); while (e.hasMoreElements()) { Object key = e.nextElement(); Object value = typedef.get(key); Class intrinsic = Class.forName("hep.io.root.core." + value); if (!IntrinsicRootClass.class.isAssignableFrom(intrinsic)) throw new RuntimeException("Typedef class is not an intrinsic: " + value); classMap.put(key, intrinsic.newInstance()); } } catch (Exception x) { throw new RuntimeException("Error interpreting typedef table",x); } try { // Convert all the streamerInfo to Root generic classes Enumeration e = streamerInfo.keys(); while (e.hasMoreElements()) { String key = (String) e.nextElement(); Object value = streamerInfo.get(key); StreamerInfo info = new StreamerInfoString((String) value); // Look to see if there is a specific implementation class classMap.put(key, findClass(key, info)); } } catch (Exception x) { throw new RuntimeException("Error interpreting typedef table",x); } // Now make sure we can resolve all the references try { Enumeration e = classMap.elements(); while (e.hasMoreElements()) { BasicRootClass info = (BasicRootClass) e.nextElement(); info.resolve(this); } } catch (RootClassNotFound x) { throw new RuntimeException("Could not resolve class " + x.getClassName(),x); } } }