--- /dev/null
+// PropertyManager.java\r
+// $Id: PropertyManager.java,v 1.1 2010/06/15 12:26:35 smhuang Exp $\r
+// (c) COPYRIGHT MIT and INRIA, 1997.\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+\r
+package org.w3c.jigadm;\r
+\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+import java.util.Properties;\r
+import java.util.StringTokenizer;\r
+import java.util.Vector;\r
+\r
+import java.util.zip.ZipEntry;\r
+import java.util.zip.ZipFile;\r
+\r
+import java.io.BufferedInputStream;\r
+import java.io.File;\r
+import java.io.InputStream;\r
+import java.io.PrintStream;\r
+\r
+import org.w3c.jigsaw.admin.RemoteAccessException;\r
+import org.w3c.jigsaw.admin.RemoteResource;\r
+\r
+import org.w3c.tools.resources.Attribute;\r
+\r
+class ResourceClassProperties {\r
+\r
+ // The class we're handling the configuration for\r
+ String entryPath = null;\r
+ // The zip file this classes configuration is at\r
+ ZipFile zip = null;\r
+ // The class editor properties\r
+ Properties editorProperties = null;\r
+ // The set of registered helpers for that editor's class\r
+ String helperClasses[] = new String[0];\r
+ // The helpers properties (map help classes to properties)\r
+ Hashtable helperProperties = null;\r
+ // The attribute properties\r
+ Hashtable attributeProperties = null;\r
+\r
+ /**\r
+ * Parse | separated property value into a String array.\r
+ * @param p Properties to look into.\r
+ * @param name The property to look for and parse.\r
+ * @return A non-null but potentially zero-length string array.\r
+ */\r
+\r
+ static String[] getStringArray(Properties p, String name) {\r
+ String v = (String) p.get(name);\r
+ if ( v == null )\r
+ return new String[0];\r
+ // Parse the property value:\r
+ StringTokenizer st = new StringTokenizer(v, "|");\r
+ int len = st.countTokens();\r
+ String ret[] = new String[len];\r
+ for (int i = 0 ; i < ret.length ; i++) {\r
+ ret[i] = st.nextToken();\r
+ }\r
+ return ret;\r
+ \r
+ }\r
+\r
+ /**\r
+ * Does this class config allows for helper aggregation.\r
+ * If <strong>true</strong> this means that the GUI should instantiate\r
+ * all inherited helpers to construct the resource editor.\r
+ * @return A boolean.\r
+ */\r
+\r
+ boolean aggregateHelpers() {\r
+ if ( editorProperties == null )\r
+ return true;\r
+ String s = (String) editorProperties.get("aggregateHelpers");\r
+ return (s != null) && s.equalsIgnoreCase("true");\r
+ }\r
+\r
+ /**\r
+ * Does this class config allows for attribute aggregation.\r
+ * If <strong>true</strong> this means that the GUI should instantiate\r
+ * an editor for all inherited attributes.\r
+ * @return A boolean.\r
+ */\r
+\r
+ boolean aggregateAttributes() {\r
+ if ( editorProperties == null )\r
+ return true;\r
+ String s = (String) editorProperties.get("aggregateAttributes");\r
+ return (s != null) && s.equalsIgnoreCase("true");\r
+ }\r
+\r
+ /**\r
+ * Should the config aggregate specific attribute editor properties.\r
+ * @return A boolean.\r
+ */\r
+\r
+ boolean aggregateAttributeProperties() {\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Utility - Load a directory of prop files into given hashtable.\r
+ * @param into Hashtable to fill in with Properties instance.\r
+ * @param dir Directory to load.\r
+ */\r
+\r
+ void loadPropertyDirectory(Hashtable into, ZipFile zip, String dir) {\r
+ try {\r
+ Enumeration entries = zip.entries();\r
+ while( entries.hasMoreElements() ) {\r
+ ZipEntry entry = (ZipEntry) entries.nextElement();\r
+ String name = entry.getName();\r
+ if (name.startsWith(dir) && name.endsWith(".p")) {\r
+ Properties p = new Properties();\r
+ InputStream in = (new BufferedInputStream\r
+ (zip.getInputStream(entry)));\r
+ p.load(in);\r
+ in.close();\r
+ // Register them into the hashtable:\r
+ into.put(name.substring(dir.length()+1, name.length()-2), p);\r
+ }\r
+ }\r
+ } catch (Exception ex) {\r
+ ex.printStackTrace();\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Initialize that class config.\r
+ * This method will load the resource editor properties, than the helper\r
+ * specific properties, and finally the attribute properties.\r
+ */\r
+\r
+ void initialize() {\r
+ // Load the editor properties:\r
+ try {\r
+ ZipEntry propentry = zip.getEntry(entryPath + "properties");\r
+ if (propentry != null) {\r
+ InputStream in = (new BufferedInputStream\r
+ (zip.getInputStream(propentry)));\r
+ editorProperties = new Properties();\r
+ editorProperties.load(in);\r
+ in.close();\r
+ }\r
+ } catch (Exception ex) {\r
+ ex.printStackTrace();\r
+ }\r
+ // From the editor properties, get the set of helpers:\r
+ if ( editorProperties != null )\r
+ helperClasses = getStringArray(editorProperties, "helpers");\r
+ // Load the helpers specific properties:\r
+ helperProperties = new Hashtable(11);\r
+ loadPropertyDirectory(helperProperties, zip, entryPath + "helpers");\r
+ // Load the specific attribute editor properties:\r
+ attributeProperties = new Hashtable(11);\r
+ loadPropertyDirectory(attributeProperties, zip,entryPath + "attrs");\r
+ }\r
+\r
+ String[] getHelperClasses() {\r
+ return helperClasses;\r
+ }\r
+\r
+ \r
+ Properties getHelperProperties(String clsname) {\r
+ Properties p = (Properties) helperProperties.get(clsname);\r
+ return p;\r
+ }\r
+\r
+ Properties getAttributeProperties(String name) {\r
+ Properties p = (Properties) attributeProperties.get(name);\r
+ return p;\r
+ }\r
+\r
+ Properties getEditorProperties() {\r
+ return editorProperties;\r
+ }\r
+\r
+ ResourceClassProperties(String entryPath, ZipFile zip) {\r
+ this.entryPath = entryPath;\r
+ this.zip = zip;\r
+ initialize();\r
+ }\r
+}\r
+\r
+public class PropertyManager {\r
+\r
+ /**\r
+ * The root for the property files.\r
+ */\r
+ protected File root = null;\r
+ protected File zipfile = null;\r
+ /**\r
+ * The set of resource classes we know about.\r
+ * Maps class names to ResourceClassProperty\r
+ */\r
+ protected Hashtable classProperties = null;\r
+ /**\r
+ /**\r
+ * the mapping of icon names to icon locations\r
+ */\r
+ protected Properties iconProperties = null;\r
+\r
+ /**\r
+ * the hashtable of mime types\r
+ */\r
+ protected Hashtable mimeTypes = null;\r
+\r
+ private boolean inited = false;\r
+\r
+ protected static Properties merge(Properties into\r
+ , Properties source\r
+ , boolean overide) {\r
+ Properties p = (Properties) into.clone();\r
+ Enumeration e = source.keys();\r
+ while ( e.hasMoreElements() ) {\r
+ Object key = e.nextElement();\r
+ if ((! overide) && into.get(key) != null)\r
+ continue;\r
+ Object val = source.get(key);\r
+ p.put(key, val);\r
+ }\r
+ return p;\r
+ }\r
+\r
+ protected static Properties merge(Properties into, Properties source) {\r
+ return merge(into, source, true);\r
+ }\r
+\r
+ /**\r
+ * Load the properties from the root directory.\r
+ */\r
+\r
+ protected void initialize() {\r
+ ZipFile zip = null;\r
+ try {\r
+ zip = new ZipFile(this.zipfile);\r
+ } catch (Exception ex) {\r
+ ex.printStackTrace();\r
+ return;\r
+ }\r
+ Enumeration entries = zip.entries();\r
+ classProperties = new Hashtable(11);\r
+\r
+ while (entries.hasMoreElements()) {\r
+ ZipEntry entry = (ZipEntry) entries.nextElement();\r
+ String entry_name = entry.getName();\r
+ if (entry_name.equals( "icons"+ File.separator)) //reserved\r
+ continue;\r
+ // Skip non directory entries\r
+ if (! entry.isDirectory() )\r
+ continue;\r
+ // only first level sub directories\r
+ if (entry_name.indexOf(File.separator) == \r
+ entry_name.lastIndexOf(File.separator)) {\r
+ ResourceClassProperties rcp = null;\r
+ rcp = new ResourceClassProperties(entry_name, zip);\r
+ classProperties.put(entry_name.substring(0, entry_name.length()-1 ),\r
+ rcp);\r
+ }\r
+ }\r
+ // and now the icons mapping\r
+ try {\r
+ ZipEntry icons = zip.getEntry("icons.p");\r
+ InputStream in = (new BufferedInputStream\r
+ (zip.getInputStream(icons)));\r
+ iconProperties = new Properties();\r
+ iconProperties.load(in);\r
+ in.close();\r
+ } catch (Exception ex) {\r
+ ex.printStackTrace();\r
+ }\r
+ // and now the mime types\r
+ mimeTypes = new Hashtable(11);\r
+ try {\r
+ ZipEntry mime = zip.getEntry("mimetypes.p");\r
+ InputStream in = (new BufferedInputStream\r
+ (zip.getInputStream(mime)));\r
+ Properties p = new Properties();\r
+ p.load(in);\r
+ in.close();\r
+ String[] major = ResourceClassProperties.getStringArray(p,"Types");\r
+ String[] minor;\r
+ for(int i=0; i<major.length; i++) {\r
+ minor = ResourceClassProperties.getStringArray(p, major[i]);\r
+ mimeTypes.put(major[i], minor);\r
+ }\r
+ } catch (Exception ex) {\r
+ ex.printStackTrace();\r
+ }\r
+ try {\r
+ zip.close(); //FIXME: sure?\r
+ } catch (Exception ex) {\r
+ ex.printStackTrace();\r
+ }\r
+ inited = true;\r
+ }\r
+\r
+ /**\r
+ * Get the best matching resource class properties for given class.\r
+ * @param classes The class names we're looking a macth for.\r
+ * @return A ResourceClassProperties instance.\r
+ */\r
+\r
+ protected ResourceClassProperties \r
+ getResourceClassProperties(String names[], int from) {\r
+ // Look along the hierarchy for a class editor:\r
+ ResourceClassProperties rcp = null;\r
+ for (int i = from ; i < names.length ; i++) {\r
+ rcp = (ResourceClassProperties) classProperties.get(names[i]);\r
+ if ( rcp != null)\r
+ break;\r
+ }\r
+ if ( rcp == null )\r
+ throw new RuntimeException("configuration error, no editor for: "+\r
+ names[0]); \r
+ return rcp;\r
+ }\r
+\r
+ protected\r
+ ResourceClassProperties getResourceClassProperties(String names[]) {\r
+ return getResourceClassProperties(names, 0);\r
+ }\r
+\r
+ protected int\r
+ findResourceClassProperties(String classes[], int offset) {\r
+ // Look along the hierarchy for a class editor:\r
+ ResourceClassProperties rcp = null;\r
+ for (int i = offset ; i < classes.length ; i++) {\r
+ rcp = (ResourceClassProperties) classProperties.get(classes[i]);\r
+ if ( rcp != null )\r
+ return i;\r
+ }\r
+ return -1;\r
+ }\r
+\r
+ protected int findResourceClassProperties(String classes[]) {\r
+ return findResourceClassProperties(classes, 0);\r
+ }\r
+\r
+ protected String[] getClassHierarchy(RemoteResourceWrapper rrw) {\r
+ try {\r
+ String classes[] = rrw.getResource().getClassHierarchy();\r
+ return classes;\r
+ } catch (RemoteAccessException ex) {\r
+ ex.printStackTrace();\r
+ }\r
+ return new String[0];\r
+ }\r
+\r
+ protected Properties getDefaultHelperProperties(String clsname) {\r
+ ResourceClassProperties rcp = null;\r
+ rcp = (ResourceClassProperties) classProperties.get("defaults");\r
+ if ( rcp != null )\r
+ return rcp.getHelperProperties(clsname);\r
+ return null;\r
+ }\r
+\r
+ protected Properties getDefaultAttributeProperties(String clsname) {\r
+ ResourceClassProperties rcp = null;\r
+ rcp = (ResourceClassProperties) classProperties.get("defaults");\r
+ if ( rcp != null )\r
+ return rcp.getAttributeProperties(clsname);\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * Get any properties for the editor of the given remote resource instance.\r
+ * @return A Properties instance.\r
+ */\r
+\r
+ public Properties getEditorProperties(RemoteResourceWrapper rrw) {\r
+ String classes[] = getClassHierarchy(rrw);\r
+ return getResourceClassProperties(classes).getEditorProperties();\r
+ }\r
+\r
+ /**\r
+ * Get the list of helpers to be created for the given remote resource.\r
+ * @return A set of helper class names (as an array).\r
+ */\r
+\r
+ public String[] getHelperClasses(RemoteResourceWrapper rrw) {\r
+ String classes[] = getClassHierarchy(rrw);\r
+ // Load in the most specific helpers:\r
+ int slot = findResourceClassProperties(classes);\r
+ if ( slot < 0 )\r
+ return new String[0];\r
+ ResourceClassProperties rcp = getResourceClassProperties(classes);\r
+ Vector vhelpers = new Vector();\r
+ vhelpers.addElement(rcp.getHelperClasses());\r
+ // Look up the hierarchy, while allowed:\r
+ while ( rcp.aggregateHelpers() ) {\r
+ if ( ++slot >= classes.length )\r
+ break;\r
+ if ((slot = findResourceClassProperties(classes, slot)) < 0)\r
+ break;\r
+ rcp = getResourceClassProperties(classes, slot);\r
+ vhelpers.addElement(rcp.getHelperClasses());\r
+ }\r
+ // Convert the vector of String arrays into a single String array:\r
+ if ( vhelpers.size() == 1 ) \r
+ return (String[]) vhelpers.elementAt(0);\r
+ int sz = 0;\r
+ int n = 0;\r
+ for (int i = 0 ; i < vhelpers.size() ; i++)\r
+ sz += ((String[]) vhelpers.elementAt(i)).length;\r
+ String helpers[] = new String[sz];\r
+ for (int i = 0 ; i < vhelpers.size() ; i++) {\r
+ String s[] = (String[]) vhelpers.elementAt(i);\r
+ for (int j = 0 ; j < s.length ; j++)\r
+ helpers[n++] = s[j];\r
+ }\r
+ return helpers;\r
+ }\r
+\r
+ /**\r
+ * Get the properties for the helper of a given remote resource.\r
+ * @param rr The remote resource being edited.\r
+ * @param helperClass Class of the helper about to be created.\r
+ * @return An instance of Properties.\r
+ */\r
+\r
+ public Properties getHelperProperties(RemoteResourceWrapper rrw\r
+ , String helperClass) {\r
+ String classes[] = getClassHierarchy(rrw);\r
+ int slot = findResourceClassProperties(classes);\r
+ if ( slot < 0 )\r
+ return new Properties();\r
+ ResourceClassProperties rcp = getResourceClassProperties(classes);\r
+ // Properties p = getDefaultProperties(helperClass);\r
+ Properties p = rcp.getHelperProperties(helperClass);\r
+ while ( rcp.aggregateHelpers() ) {\r
+ if ( ++slot >= classes.length )\r
+ break;\r
+ if ((slot = findResourceClassProperties(classes, slot)) < 0)\r
+ break;\r
+ rcp = getResourceClassProperties(classes, slot);\r
+ Properties more = rcp.getHelperProperties(helperClass);\r
+ if ( more != null )\r
+ p = (p != null) ? merge(p, more, false) : more;\r
+ }\r
+ return (p == null) ? new Properties() : p;\r
+ }\r
+\r
+ /**\r
+ * Get the properties for the attribute editor of a given remote resource.\r
+ * @param rr The remote resource being edited.\r
+ * @param attr The attribute being edited.\r
+ */\r
+\r
+ public Properties getAttributeProperties(RemoteResourceWrapper rrw\r
+ , Attribute attr) {\r
+ String classes[] = getClassHierarchy(rrw);\r
+ String attrClass = attr.getClass().getName();\r
+ int slot = findResourceClassProperties(classes);\r
+ if ( slot < 0 )\r
+ return new Properties();\r
+ ResourceClassProperties rcp = getResourceClassProperties(classes);\r
+ Properties p = rcp.getAttributeProperties(attr.getName());\r
+ if ( p == null )\r
+ p = new Properties();\r
+ Properties defs = getDefaultAttributeProperties(attrClass);\r
+ if ( defs != null ) \r
+ p = merge(defs, p);\r
+ while ( rcp.aggregateAttributeProperties() ) {\r
+ if ( ++slot >= classes.length )\r
+ break;\r
+ if ((slot = findResourceClassProperties(classes, slot)) < 0 )\r
+ break;\r
+ rcp = getResourceClassProperties(classes, slot); \r
+ Properties more = rcp.getAttributeProperties(attr.getName());\r
+ if ( more != null )\r
+ p = merge(more, p);\r
+ }\r
+ return p;\r
+ }\r
+\r
+ /**\r
+ * get the icon name resolved from its description\r
+ * @param name a String \r
+ */\r
+\r
+ public String getIconLocation(String name) {\r
+ String rname = iconProperties.getProperty(name);\r
+ if (rname != null) {\r
+ boolean rel; \r
+ rel = iconProperties.getProperty("relative").equals("true");\r
+ return (rel) ? root.getAbsolutePath() +\r
+ File.separator + "icons" + File.separator + rname : rname;\r
+ }\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * get the hashtable of mimetypes\r
+ */\r
+\r
+ public Hashtable getMimeTypes() {\r
+ return mimeTypes;\r
+ }\r
+\r
+ public static String ROOT_P = "jigadmRoot";\r
+\r
+ public static PropertyManager propertyManager = null;\r
+\r
+ public static PropertyManager getPropertyManager() {\r
+ if ( propertyManager == null ) {\r
+ Properties p = System.getProperties();\r
+ String base = p.getProperty(ROOT_P);\r
+ if (base == null) {\r
+ propertyManager = new PropertyManager(\r
+ new File(p.getProperty("user.dir") + File.separator +\r
+ "config" + File.separator + "jigadm.zip"),\r
+ new File(p.getProperty("user.dir") + File.separator +\r
+ "config"));\r
+ }\r
+ else\r
+ propertyManager = new PropertyManager(\r
+ new File(base + File.separator +"config" +\r
+ File.separator + "jigadm.zip"),\r
+ new File(base + File.separator +"config"));\r
+ }\r
+ return propertyManager;\r
+ }\r
+\r
+ public PropertyManager(File zipfile, File root) {\r
+ this.root = root;\r
+ this.zipfile = zipfile;\r
+ initialize();\r
+ if ( ! this.inited ) {\r
+ // The one who wrote that code has already booked a special\r
+ // place in hell\r
+ System.out.println("PropertyManager: unable to initialize.");\r
+ System.out.println("\tCouldn't find mandatory properties in \""+\r
+ root+"\" use the \"-root\" option or run "+\r
+ "jigadmin from Jigsaw root directory.");\r
+ System.exit(1);\r
+ }\r
+ }\r
+}\r
+\r
+\r