Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / jigsaw / src / org / w3c / tools / resources / DirectoryResource.java
diff --git a/JMCR-Stable/real-world application/jigsaw/src/org/w3c/tools/resources/DirectoryResource.java b/JMCR-Stable/real-world application/jigsaw/src/org/w3c/tools/resources/DirectoryResource.java
new file mode 100644 (file)
index 0000000..d989664
--- /dev/null
@@ -0,0 +1,693 @@
+// DirectoryResource.java\r
+// $Id: DirectoryResource.java,v 1.2 2010/06/15 17:52:59 smhuang Exp $\r
+// (c) COPYRIGHT MIT and INRIA, 1996.\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+\r
+package org.w3c.tools.resources ;\r
+\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+\r
+import java.io.File;\r
+import java.io.PrintStream;\r
+import java.io.RandomAccessFile;\r
+\r
+import org.w3c.tools.resources.indexer.IndexerModule;\r
+import org.w3c.tools.resources.indexer.ResourceIndexer;\r
+\r
+import org.w3c.tools.resources.event.StructureChangedEvent;\r
+\r
+/**\r
+ * A simple, and reasonably efficient directory resource.\r
+ */\r
+public class DirectoryResource extends ContainerResource {\r
+    /**\r
+     * Attribute index - The index for our directory attribute.\r
+     */\r
+    protected static int ATTR_DIRECTORY = -1 ;\r
+    /**\r
+     * Attribute index - The last time we physically visited the directory.\r
+     */\r
+    protected static int ATTR_DIRSTAMP = -1 ;\r
+    /**\r
+     * Attribute index - The indexer to use for that directory, if any.\r
+     */\r
+    protected static int ATTR_INDEXER = -1;\r
+    /**\r
+     * Attribute index - The index of wether we are extensible.\r
+     */\r
+    protected static int ATTR_EXTENSIBLE = -1 ;\r
+    /**\r
+     * Attribute index - The index of wether we can be shrinked.\r
+     */\r
+    protected static int ATTR_SHRINKABLE = -1 ;\r
+\r
+    static String di = "directory".intern();\r
+\r
+    static {\r
+       Attribute a   = null ;\r
+       Class     cls = null ;\r
+       // Get a pointer to our class.\r
+       try {\r
+           cls = Class.forName("org.w3c.tools.resources.DirectoryResource") ;\r
+           //Added by Jeff Huang\r
+           //TODO: FIXIT\r
+       } catch (Exception ex) {\r
+           ex.printStackTrace() ;\r
+           System.exit(1) ;\r
+       }\r
+       // The directory attribute.\r
+       a = new FileAttribute("directory"\r
+                             , null\r
+                             , Attribute.COMPUTED|Attribute.DONTSAVE);\r
+       ATTR_DIRECTORY = AttributeRegistry.registerAttribute(cls, a) ;\r
+       // The last time we visited the directory\r
+       a = new DateAttribute("dirstamp"\r
+                             , null\r
+                             , Attribute.COMPUTED) ;\r
+       ATTR_DIRSTAMP = AttributeRegistry.registerAttribute(cls, a) ;\r
+       // Our indexer name (optional).\r
+       a = new StringAttribute("indexer"\r
+                               , null\r
+                               , Attribute.EDITABLE) ;\r
+       ATTR_INDEXER = AttributeRegistry.registerAttribute(cls, a) ;\r
+       // Are we extensible (can we create resources on the fly):\r
+       a = new BooleanAttribute("extensible"\r
+                                , Boolean.TRUE\r
+                                , Attribute.EDITABLE) ;\r
+       ATTR_EXTENSIBLE = AttributeRegistry.registerAttribute(cls, a) ;\r
+       // Are we shrinkable (can we delete resources on the fly):\r
+       a = new BooleanAttribute("shrinkable"\r
+                                , Boolean.TRUE\r
+                                , Attribute.EDITABLE) ;\r
+       ATTR_SHRINKABLE = AttributeRegistry.registerAttribute(cls, a) ;\r
+    }\r
+\r
+    /**\r
+     * Get the indexer out of the given context.\r
+     * @return A ResourceIndexer instance, guaranteeed not to be <strong>\r
+     * null</strong>.\r
+     */\r
+    protected ResourceReference getIndexer(ResourceContext c) {\r
+       IndexerModule   m = (IndexerModule) c.getModule(IndexerModule.NAME);\r
+       ResourceReference rr = m.getIndexer(c);\r
+       return rr;\r
+    }\r
+\r
+    public void setValue(int idx, Object value) {\r
+       super.setValue(idx, value);\r
+       if ( idx == ATTR_INDEXER ) {\r
+           String indexer = getString(ATTR_INDEXER, null);         \r
+           if ( indexer != null ) {\r
+               ResourceContext c = null;\r
+               IndexerModule   m = null;\r
+               c = getContext();\r
+               m = (IndexerModule) c.getModule(IndexerModule.NAME);\r
+               m.registerIndexer(c, indexer);\r
+           }\r
+       }\r
+    }\r
+\r
+    /**\r
+     * Get the physical directory exported by this resource.\r
+     * @return A non-null File object giving the directory of this resource.\r
+     */\r
+\r
+    public File getDirectory() {\r
+       return (File) getValue(ATTR_DIRECTORY, null) ;\r
+    }\r
+\r
+    /**\r
+     * Get the physical directory exported by this resource.\r
+     * @return A non-null File object giving the directory of this resource.\r
+     */\r
+\r
+    public File unsafeGetDirectory() {\r
+       return (File) unsafeGetValue(ATTR_DIRECTORY, null) ;\r
+    }\r
+\r
+    /**\r
+     * Get the absolute time at which we examined the physicall directory.\r
+     * @return The date (as a long number of ms since Java epoch), or\r
+     * <strong>-1</strong> if we never examined it before.\r
+     */\r
+\r
+    public long getDirStamp() {\r
+       return getLong(ATTR_DIRSTAMP, -1) ;\r
+    }\r
+\r
+    /**\r
+     * Get the extensible flag value.\r
+     * A DirectoryResource is extensible, if it is allowed to create new\r
+     * resources out of the file system knowledge on the fly.\r
+     * <p>Setting this flag might slow down the server. It unfortunatelly\r
+     * defaults to <strong>true</strong> until I have a decent admin\r
+     * program.\r
+     * @return A boolean <strong>true</strong> if the directory is\r
+     *    extensible.\r
+     */\r
+\r
+    public boolean getExtensibleFlag() {\r
+       return getBoolean(ATTR_EXTENSIBLE, true) ;\r
+    }\r
+\r
+    /**\r
+     * Get the extensible flag value.\r
+     * A DirectoryResource is extensible, if it is allowed to create new\r
+     * resources out of the file system knowledge on the fly.\r
+     * <p>Setting this flag might slow down the server. It unfortunatelly\r
+     * defaults to <strong>true</strong> until I have a decent admin\r
+     * program.\r
+     * @return A boolean <strong>true</strong> if the directory is\r
+     *    extensible.\r
+     */\r
+\r
+    public boolean getShrinkableFlag() {\r
+       return getBoolean(ATTR_SHRINKABLE, true) ;\r
+    }\r
+\r
+    /**\r
+     * Get the extensible flag value.\r
+     * A DirectoryResource is extensible, if it is allowed to create new\r
+     * resources out of the file system knowledge on the fly.\r
+     * <p>Setting this flag might slow down the server. It unfortunatelly\r
+     * defaults to <strong>true</strong> until I have a decent admin\r
+     * program.\r
+     * @return A boolean <strong>true</strong> if the directory is\r
+     *    extensible.\r
+     */\r
+\r
+    public boolean unsafeGetShrinkableFlag() {\r
+       Object value = unsafeGetValue(ATTR_SHRINKABLE, null) ;\r
+       if (value == null) {\r
+           return true;\r
+       } else if ( value instanceof Boolean ) {\r
+           return ((Boolean) value).booleanValue() ;\r
+       } else {\r
+           throw new IllegalAttributeAccess(this\r
+                                            , attributes[ATTR_SHRINKABLE]\r
+                                            , "getBoolean") ;\r
+       }\r
+    }\r
+\r
+    /**\r
+     * A resource is about to be removed\r
+     * This handles the <code>RESOURCE_REMOVED</code> kind of events.\r
+     * @param evt The event describing the change.\r
+     */\r
+    public void resourceRemoved(StructureChangedEvent evt) {\r
+       super.resourceRemoved(evt);\r
+       if (! isUnloaded())\r
+           markModified();\r
+    }\r
+\r
+    /**\r
+     * Create a DirectoryResource and the physical directory too.\r
+     * @param name the name of the resource.\r
+     * @return A ResourceReference instance.\r
+     */\r
+    public ResourceReference createDirectoryResource(String name) {\r
+       // Create an empty file:\r
+       File    file          = new File(getDirectory(), name) ;\r
+       boolean created       = false ;\r
+       boolean exists_before = false ;\r
+\r
+       try {\r
+           if (file.exists()) {\r
+               if (! file.isDirectory())\r
+                   created = false;\r
+               else\r
+                   exists_before = true;\r
+           } else {\r
+               file.mkdir();\r
+               created = true;\r
+           }\r
+       } catch (Exception ex) {\r
+           created = false;\r
+       }\r
+\r
+       if (! created)\r
+           return null;\r
+\r
+       ResourceReference rr = createDefaultResource(name);\r
+       if (rr == null) {\r
+           if (!exists_before)\r
+               file.delete();\r
+           return null;\r
+       }\r
+\r
+       try {\r
+           Resource r = rr.lock();\r
+           if (! (r instanceof DirectoryResource)) {\r
+               try {\r
+                   r.delete();\r
+               } catch (MultipleLockException ex) {\r
+                   //OUCH!\r
+                   //manual delete\r
+               }\r
+               if (!exists_before)\r
+                   file.delete();\r
+               return null;\r
+           }\r
+       } catch (InvalidResourceException ex) {\r
+           if (!exists_before)\r
+               file.delete();\r
+           return null;\r
+       } finally {\r
+           rr.unlock();\r
+       }\r
+       return rr;\r
+    }\r
+\r
+    /**\r
+     * Create a Resource and the physical file too.\r
+     * @param name the name of the resource.\r
+     * @return A ResourceReference instance.\r
+     */\r
+    public ResourceReference createResource(String name) {\r
+       return createResource(name, null);\r
+    }\r
+\r
+    /**\r
+     * Create a Resource and the physical file too.\r
+     * @param name the name of the resource.\r
+     * @param req the protocol request.\r
+     * @return A ResourceReference instance.\r
+     */\r
+    public ResourceReference createResource(String name, \r
+                                           RequestInterface req) \r
+    {\r
+       // Create an empty file:\r
+       File    file    = new File(getDirectory(), name) ;\r
+       boolean created = false ;\r
+\r
+       if ( ! file.exists() ) {\r
+           try {\r
+               (new RandomAccessFile(file, "rw")).close() ;\r
+               created = true ;\r
+           } catch (Exception ex) {\r
+               created = false ;\r
+           }\r
+       }\r
+       if (! created) \r
+           return null;\r
+\r
+       ResourceReference rr = createDefaultResource(name, req);\r
+       //if (rr == null)\r
+       file.delete();\r
+       return rr;\r
+    }\r
+\r
+    /**\r
+     * Index a Resource. Call the indexer.\r
+     * @param name The name of the resource to index.\r
+     * @param defs The defaults attributes.\r
+     * @return A resource instance.\r
+     * @see org.w3c.tools.resources.indexer.SampleResourceIndexer\r
+     */\r
+    private Resource index(String name, Hashtable defs) {\r
+       return index(name, defs, null);\r
+    }\r
+\r
+    /**\r
+     * Index a Resource. Call the indexer.\r
+     * @param name The name of the resource to index.\r
+     * @param defs The defaults attributes.\r
+     * @param req The protocol request.\r
+     * @return A resource instance.\r
+     * @see org.w3c.tools.resources.indexer.SampleResourceIndexer\r
+     */\r
+    protected Resource index(String name, \r
+                            Hashtable defs, \r
+                            RequestInterface req) \r
+    {\r
+       // Prepare a set of default parameters for the resource:\r
+       defs.put(id, name);\r
+       updateDefaultChildAttributes(defs);\r
+       ResourceContext context = getContext();\r
+       // Try to get the indexer to create the resource:\r
+       Resource    resource = null;\r
+       ResourceReference rr_indexer  = null;\r
+       ResourceReference rr_lastidx  = null;\r
+       while ( context != null ) {\r
+           // Lookup for next indexer in hierarchy:\r
+           do {\r
+               rr_indexer = getIndexer(context);\r
+               context = context.getParent();\r
+           } while ((rr_indexer == rr_lastidx) && (context != null));\r
+           // Is this a useful indexer ?\r
+           if ((rr_lastidx = rr_indexer) != null ) {\r
+               try {\r
+                   ResourceIndexer indexer = \r
+                       (ResourceIndexer)rr_indexer.lock();\r
+                   resource = indexer.createResource(this,\r
+                                                     req,\r
+                                                     getDirectory(),\r
+                                                     name,\r
+                                                     defs) ;\r
+                   if ( resource != null ) \r
+                       break;\r
+               } catch (InvalidResourceException ex) {\r
+                   resource = null;\r
+               } finally {\r
+                   rr_indexer.unlock();\r
+               }\r
+           }\r
+       }\r
+       return resource;\r
+    }\r
+\r
+    /**\r
+     * Get the name of the resource relative to the given filename.\r
+     * @param name The name of the file.\r
+     * @return a String, the resource name.\r
+     * @see org.w3c.tools.resources.indexer.SampleResourceIndexer\r
+     */\r
+    protected String getIndexedName(String name) {\r
+       ResourceContext   context     = getContext();\r
+       String            indexed     = null;\r
+       ResourceReference rr_indexer  = null;\r
+       ResourceReference rr_lastidx  = null;\r
+       while ( context != null ) {\r
+           // Lookup for next indexer in hierarchy:\r
+           do {\r
+               rr_indexer = getIndexer(context);\r
+               context = context.getParent();\r
+           } while ((rr_indexer == rr_lastidx) && (context != null));\r
+           if ((rr_lastidx = rr_indexer) != null ) {\r
+               try {\r
+                   ResourceIndexer indexer = \r
+                       (ResourceIndexer)rr_indexer.lock();\r
+                   indexed = indexer.getIndexedName(getDirectory(), name);\r
+                   if ( indexed != null ) \r
+                       break;\r
+               } catch (InvalidResourceException ex) {\r
+                   indexed = null;\r
+               } finally {\r
+                   rr_indexer.unlock();\r
+               }\r
+           }\r
+       }\r
+       return ((indexed == null) ? name : indexed);\r
+    }\r
+\r
+    public synchronized ResourceReference createDefaultResource(String name) {\r
+       return createDefaultResource(name, null);\r
+    }\r
+    /**\r
+     * Try creating a default resource having the given name.\r
+     * This method will make its best effort to create a default resource\r
+     * having this name in the directory. If a file with this name exists,\r
+     * it will check the pre-defined admin extensions and look for a match.\r
+     * If a directory with this name exists, and admin allows to do so, it\r
+     * will create a sub-directory resource.\r
+     * @param name The name of the resource to try to create.\r
+     * @param req The incomming request\r
+     * @return A Resource instance, if possible, <strong>null</strong>\r
+     *    otherwise.\r
+     */\r
+\r
+    protected synchronized \r
+       ResourceReference createDefaultResource(String name,\r
+                                               RequestInterface req) \r
+    {\r
+       // Don't automagically create resources of name '..' or '.'\r
+       if (name.equals("..") || name.equals(".") \r
+           || (name.indexOf('\\') >= 0 )) {\r
+           return null ;\r
+       }\r
+       Hashtable defs = new Hashtable(10) ;\r
+       Resource resource = index(name, defs, req);\r
+       // Did we finally create a resource ?\r
+       ResourceReference rr = null;\r
+       if ( resource != null ) {\r
+           // Register this child in our store:\r
+           rr = addResource(resource, defs) ;\r
+           markModified() ;\r
+       }\r
+       return rr ;\r
+    }\r
+\r
+    /**\r
+     * Initialize and register a new resource into this directory.\r
+     * @param resource The uninitialized resource to be added.\r
+     */\r
+    protected ResourceContext updateDefaultChildAttributes(Hashtable attrs) {\r
+       ResourceContext context = null;\r
+       context = super.updateDefaultChildAttributes(attrs);\r
+       String name = (String) attrs.get(id);\r
+       if (( name != null ) && (getDirectory() !=  null)) {\r
+           attrs.put(di, new File(getDirectory(), name));\r
+       }\r
+       return context;\r
+    }\r
+\r
+    /**\r
+     * Reindex recursivly all the resources from this DirectoryResource.\r
+     * @param rec recursivly?\r
+     */\r
+    public synchronized void reindex(boolean rec) {\r
+       if (getExtensibleFlag()) {\r
+           Enumeration       e    = enumerateAllResourceIdentifiers();\r
+           String            name = null;\r
+           ResourceReference rr   = null;\r
+           Resource          r    = null;\r
+           while (e.hasMoreElements()) {\r
+               name = (String) e.nextElement();\r
+               rr = lookup(name);\r
+               if (rr != null) {\r
+                   try {\r
+                       r = rr.lock();\r
+                       // forbid cycles\r
+                       if (r == this)\r
+                           continue;\r
+                       if (r instanceof DirectoryResource) {\r
+                           //launch reindex\r
+                           DirectoryResource dir = (DirectoryResource) r;\r
+                           //reindex directory itself\r
+                           //the new diretory must have the same context\r
+                           Hashtable defs = new Hashtable(5);\r
+                           defs.put(co, dir.getContext());\r
+                           //indexing ...\r
+                           Resource newdir = index(name, defs);\r
+                           // do we want it to keep its indexer?\r
+                           if ((newdir == null) && rec) {\r
+                               dir.reindex(true);\r
+                           } else {\r
+                               if (! (newdir instanceof DirectoryResource)) {\r
+                                   throw new RuntimeException(\r
+                                              "Reindex Error : "+\r
+                                              name+" can't be reindexed. "+\r
+                                              "The reindexed resource is "+\r
+                                              "no more a DirectoryResource.");\r
+                               }\r
+                               DirectoryResource reindexed = \r
+                                   (DirectoryResource) newdir;\r
+                               String indexer = \r
+                                   reindexed.getString(ATTR_INDEXER, "");\r
+                               if (indexer.equals("")) {\r
+                                   if (rec) {\r
+                                       dir.reindex(true);\r
+                                   }\r
+                                   indexer = \r
+                                       dir.getString(ATTR_INDEXER, null);\r
+                                   reindexed.setValue(ATTR_INDEXER, indexer);\r
+                               } else {\r
+                                   dir.setValue(ATTR_INDEXER, indexer);\r
+                                   if (rec) {\r
+                                       dir.reindex(true);\r
+                                   }\r
+                               }\r
+                               //move children to the reindexed directory\r
+                               reindexed.setValue(ATTR_KEY, dir.getKey());\r
+                               dir.setValue(ATTR_IDENTIFIER, \r
+                                            name+"-bakindex");\r
+                               addResource(reindexed, defs);\r
+                               // Now replace the old DirectoryResource \r
+                               // by the new one\r
+                               try {\r
+                                   dir.replace(reindexed);\r
+                               } catch (MultipleLockException ex) {\r
+                                   throw new RuntimeException(\r
+                                                          "Reindex Error : "+\r
+                                                          ex.getMessage());\r
+                               }\r
+                           }\r
+                       } else if (! (r instanceof AbstractContainer)) {\r
+                           //leaf\r
+                           Hashtable resdefs = new Hashtable(10);\r
+                           Resource resource = index(name, resdefs);\r
+                           if (resource != null) {\r
+                               try {\r
+                                   r.delete();\r
+                               } catch (MultipleLockException ex) {\r
+                                   throw new RuntimeException(\r
+                                                           "Reindex Error : "+\r
+                                                           ex.getMessage());\r
+                               }\r
+                               addResource(resource, resdefs);\r
+                           }\r
+                       }\r
+                   } catch (InvalidResourceException ex) {\r
+                       System.out.println(ex.getMessage());\r
+                   } finally {\r
+                       rr.unlock();\r
+                   }\r
+               }\r
+           }\r
+           markModified();\r
+       }\r
+    }\r
+\r
+    /**\r
+     * Enumerate all available children resource identifiers. \r
+     * This method <em>requires</em> that we create all our pending resources.\r
+     * @return An enumeration of all our resources.\r
+     */\r
+    protected synchronized Enumeration enumerateAllResourceIdentifiers() {\r
+       File directory = getDirectory() ;\r
+       if ( directory != null ) {\r
+           synchronized(this) {\r
+               String lst[] = directory.list() ;\r
+               if ( lst != null ) {\r
+                   for (int i = 0 ; i < lst.length ; i++) {\r
+                       if (lst[i].equals(".") || lst[i].equals(".."))\r
+                           continue ;\r
+                       if (super.lookup(lst[i]) == null) {\r
+                           String indexed = getIndexedName(lst[i]);\r
+                           if (indexed.equals(lst[i]))\r
+                               createDefaultResource(lst[i]) ;\r
+                           else if (super.lookup(indexed) == null)\r
+                               createDefaultResource(lst[i]) ;\r
+                       }\r
+                   }\r
+               }\r
+           }\r
+       }\r
+       return super.enumerateResourceIdentifiers(true); \r
+    }\r
+\r
+    /**\r
+     * Enumerate all available children resource identifiers. \r
+     * This method <em>requires</em> that we create all our pending resources\r
+     * if we are in the extensible mode...too bad !\r
+     * @return An enumeration of all our resources.\r
+     */\r
+    public synchronized Enumeration enumerateResourceIdentifiers(boolean all) {\r
+       // If extensible, update if needed:\r
+       if (all && getExtensibleFlag() ) {\r
+           File directory = getDirectory() ;\r
+           if ( directory != null ) {\r
+               synchronized(this) {\r
+                   long dirstamp  = directory.lastModified() ;\r
+                   if ( dirstamp > getDirStamp() ) {\r
+                       String lst[] = directory.list() ;\r
+                       if ( lst != null ) {\r
+                           for (int i = 0 ; i < lst.length ; i++) {\r
+                               if (lst[i].equals(".") || lst[i].equals(".."))\r
+                                   continue ;\r
+                               if (super.lookup(lst[i]) == null) {\r
+                                   String indexed = getIndexedName(lst[i]);\r
+                                   if (indexed.equals(lst[i]))\r
+                                       createDefaultResource(lst[i]) ;\r
+                                   else if (super.lookup(indexed) == null)\r
+                                       createDefaultResource(lst[i]) ;\r
+                               }\r
+                           }\r
+                       }\r
+                       setLong(ATTR_DIRSTAMP, dirstamp) ;\r
+                   }\r
+               }\r
+           }\r
+       }\r
+       return super.enumerateResourceIdentifiers(all);\r
+    }\r
+\r
+    /**\r
+     * Lookup the resource having the given name in this directory.\r
+     * @param name The name of the resource.\r
+     * @return A resource instance, or <strong>null</strong>.\r
+     */\r
+    public ResourceReference lookup(String name) \r
+    {\r
+       ResourceReference rr = null;\r
+       // Try our store:\r
+       rr = super.lookup(name);\r
+       if (rr != null)\r
+           return rr;\r
+       // If allowed, than try a default fallback:\r
+       return getExtensibleFlag() ? createDefaultResource(name) : null ;\r
+    }\r
+\r
+    /**\r
+     * Delete this directory resource, for ever.\r
+     * This method will delete the directory resource, and its associated \r
+     * store, <strong>along</strong> with any of the sub-resources it contains.\r
+     * Deleting the root directory of your server might take sometime...\r
+     * <p>Once the resource is deleted, it isx1 removed from its inital store\r
+     * and will not be unpickleable any more.\r
+     * @exception MultipleLockException if someone has locked this resource.\r
+     */\r
+\r
+    public synchronized void delete() \r
+       throws MultipleLockException\r
+    {\r
+       disableEvent();\r
+       // Remove all the defined resources in this directory\r
+       // Set the extensible flag to false, otherwise, the directory grows\r
+       // as we shrink it :-)\r
+       setBoolean(ATTR_EXTENSIBLE, false);\r
+       super.delete();\r
+    }\r
+\r
+    /**\r
+     * Was return false (don't khow why)\r
+     */\r
+    public synchronized boolean verify() {\r
+       return getDirectory().exists();\r
+    }\r
+\r
+    /**\r
+     * Initialize this directory resource with the given set of attributes.\r
+     * @param values The attribute values.\r
+     */\r
+    public void initialize(Object values[]) {\r
+       super.initialize(values) ;\r
+       disableEvent();\r
+       // Get our parent resource and compute our directory:\r
+       File dir = null ;\r
+       if ( ! definesAttribute(ATTR_DIRECTORY) ) {\r
+           // Get our parent:\r
+           ResourceReference rr = getParent();\r
+           if (rr != null) {\r
+               try {\r
+                   Resource parent = rr.lock();\r
+                   if (parent.definesAttribute(di)) {\r
+                       File pdir = (File) parent.getValue(di, null);\r
+                       if ( pdir != null ) {\r
+                           // Compute and set our directory attribute:\r
+                           dir = new File(pdir, getIdentifier()) ;\r
+                           setValue(ATTR_DIRECTORY, dir) ;\r
+                       }\r
+                   }\r
+               } catch (InvalidResourceException ex) {\r
+         \r
+               } finally {\r
+                   rr.unlock();\r
+               }\r
+           }\r
+       } else {\r
+           dir = getDirectory();\r
+       }\r
+       // Register our specific indexer, if any:\r
+       ResourceContext c = getContext();\r
+       String indexer = getString(ATTR_INDEXER, null);\r
+\r
+       if (( indexer != null ) && (!indexer.equals(""))) {\r
+           IndexerModule   m = (IndexerModule)c.getModule(IndexerModule.NAME);\r
+           m.registerIndexer(c, indexer);\r
+       }\r
+       enableEvent();\r
+    }\r
+\r
+}\r