You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ps...@apache.org on 2005/01/03 02:29:36 UTC

svn commit: r123921 - in incubator/directory/naming/trunk: . core core/src/java/org/apache/naming factory java management/src/java/org/apache/naming resources resources/src/java/org/apache/naming/resources

Author: psteitz
Date: Sun Jan  2 17:29:34 2005
New Revision: 123921

URL: http://svn.apache.org/viewcvs?view=rev&rev=123921
Log:
Ported bugfixes and enhancements from jakarta-tomcat-catalina. 
Jira: DIRNAMING-10
Summary of changes (see DIRNAMING-10 for details):
Refactoring / Performance Improvement
--Moved the caching algorithm out of ProxyDirContext
--Changed to Java 2 Collections collections, eliminating many synchs.
  MUST now use SynchronizedContext if thread-safe context is required.
Bug Fixes
--BZ 30561 NamingService doesn't correctly start/stop 
--BZ 17690 WARDirContext - setDocBase throws confusing message
--Several changes to improve cache management in resources package
--Improve exception management in NamingContext and ContextBindings



Added:
   incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/CacheEntry.java
   incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings_es.properties
   incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/ResourceCache.java
Modified:
   incubator/directory/naming/trunk/core/project.xml
   incubator/directory/naming/trunk/core/src/java/org/apache/naming/ContextBindings.java
   incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContext.java
   incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContextBindingsEnumeration.java
   incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContextEnumeration.java
   incubator/directory/naming/trunk/factory/project.xml
   incubator/directory/naming/trunk/java/project.xml
   incubator/directory/naming/trunk/management/src/java/org/apache/naming/NamingService.java
   incubator/directory/naming/trunk/project.xml
   incubator/directory/naming/trunk/resources/project.xml
   incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/BaseDirContext.java
   incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/FileDirContext.java
   incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings.properties
   incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings_fr.properties
   incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings_ja.properties
   incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/ProxyDirContext.java
   incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/ResourceAttributes.java
   incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/WARDirContext.java

Modified: incubator/directory/naming/trunk/core/project.xml
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/core/project.xml?view=diff&rev=123921&p1=incubator/directory/naming/trunk/core/project.xml&r1=123920&p2=incubator/directory/naming/trunk/core/project.xml&r2=123921
==============================================================================
--- incubator/directory/naming/trunk/core/project.xml	(original)
+++ incubator/directory/naming/trunk/core/project.xml	Sun Jan  2 17:29:34 2005
@@ -3,5 +3,13 @@
    <extend>${basedir}/../project.xml</extend>  
    <artifactId>naming-core</artifactId>
    <name>Naming Core</name>
+   
+ <dependencies>
+   <dependency>
+       <groupId>commons-logging</groupId>
+       <artifactId>commons-logging</artifactId>
+       <version>1.0.3</version>
+     </dependency>    
+   </dependencies>
 </project>
 

Modified: incubator/directory/naming/trunk/core/src/java/org/apache/naming/ContextBindings.java
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/core/src/java/org/apache/naming/ContextBindings.java?view=diff&rev=123921&p1=incubator/directory/naming/trunk/core/src/java/org/apache/naming/ContextBindings.java&r1=123920&p2=incubator/directory/naming/trunk/core/src/java/org/apache/naming/ContextBindings.java&r2=123921
==============================================================================
--- incubator/directory/naming/trunk/core/src/java/org/apache/naming/ContextBindings.java	(original)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/naming/ContextBindings.java	Sun Jan  2 17:29:34 2005
@@ -415,7 +415,7 @@
                                          ClassLoader classLoader) {
         if (ContextAccessController.checkSecurityToken(name, token)) {
             Object n = clNameBindings.get(classLoader);
-            if (!(n.equals(name))) {
+            if ((n==null) || !(n.equals(name)))  {
                 return;
             }
             clBindings.remove(classLoader);

Modified: incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContext.java
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContext.java?view=diff&rev=123921&p1=incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContext.java&r1=123920&p2=incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContext.java&r2=123921
==============================================================================
--- incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContext.java	(original)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContext.java	Sun Jan  2 17:29:34 2005
@@ -17,6 +17,7 @@
 
 package org.apache.naming;
 
+import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.Enumeration;
 import javax.naming.Context;
@@ -28,6 +29,7 @@
 import javax.naming.Reference;
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
+import javax.naming.NameAlreadyBoundException;
 import javax.naming.NameNotFoundException;
 import javax.naming.NotContextException;
 import javax.naming.InitialContext;
@@ -53,6 +55,10 @@
     protected static final NameParser nameParser = new NameParserImpl();
 
 
+    private static org.apache.commons.logging.Log log =
+        org.apache.commons.logging.LogFactory.getLog(NamingContext.class);
+
+
     // ----------------------------------------------------------- Constructors
 
 
@@ -65,7 +71,7 @@
      */
     public NamingContext(Hashtable env, String name) 
         throws NamingException {
-        this.bindings = new Hashtable();
+        this.bindings = new HashMap();
         this.env = new Hashtable();
         // FIXME ? Could be put in the environment ?
         this.name = name;
@@ -89,7 +95,7 @@
      * @param bindings initial context bindings
      * @throws NamingException if a naming exception is encountered
      */
-    public NamingContext(Hashtable env, String name, Hashtable bindings) 
+    public NamingContext(Hashtable env, String name, HashMap bindings) 
         throws NamingException {
         this(env, name);
         this.bindings = bindings;
@@ -114,7 +120,7 @@
     /**
      * Bindings in this Context.
      */
-    protected Hashtable bindings;
+    protected HashMap bindings;
 
 
     /**
@@ -151,7 +157,7 @@
 
 
     /**
-     * Retrieves the named object.  
+     * Retrieves the named object.
      * 
      * @param name the name of the object to look up
      * @return the object bound to name
@@ -167,13 +173,10 @@
      * Binds a name to an object. All intermediate contexts and the target 
      * context (that named by all but terminal atomic component of the name) 
      * must already exist.
-     * <p>
-     * Throws <code>NameAlreadyBoundException</code> if the name is already
-     * bound in this context.  Throws <code>InvalidAttributesException</code> if the
-     * object does not supply all mandatory attributes.
      * 
      * @param name the name to bind; may not be empty
      * @param obj the object to bind; possibly null
+     * @exception NameAlreadyBoundException if name is already bound
      * @exception InvalidAttributesException if object did not supply all 
      * mandatory attributes
      * @exception NamingException if a naming exception is encountered
@@ -186,13 +189,12 @@
 
     /**
      * Binds a name to an object.
-     * <p>
-     * Throws <code>NameAlreadyBoundException</code> if the name is already
-     * bound in this context.  Throws <code>InvalidAttributesException</code> if the
-     * object does not supply all mandatory attributes.
      * 
      * @param name the name to bind; may not be empty
      * @param obj the object to bind; possibly null
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
      * @exception NamingException if a naming exception is encountered
      */
     public void bind(String name, Object obj)
@@ -209,12 +211,11 @@
      * If the object is a DirContext, any existing attributes associated with 
      * the name are replaced with those of the object. Otherwise, any 
      * existing attributes associated with the name remain unchanged.
-     * <p>
-     * Throws <code>InvalidAttributesException</code> if the  object does not 
-     * supply all mandatory attributes.
      * 
      * @param name the name to bind; may not be empty
      * @param obj the object to bind; possibly null
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
      * @exception NamingException if a naming exception is encountered
      */
     public void rebind(Name name, Object obj)
@@ -225,12 +226,11 @@
 
     /**
      * Binds a name to an object, overwriting any existing binding.
-     * <p>
-     * Throws <code>InvalidAttributesException</code> if the object does not 
-     * supply all mandatory attributes.
      * 
      * @param name the name to bind; may not be empty
      * @param obj the object to bind; possibly null
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
      * @exception NamingException if a naming exception is encountered
      */
     public void rebind(String name, Object obj)
@@ -351,7 +351,7 @@
         while ((!name.isEmpty()) && (name.get(0).length() == 0))
             name = name.getSuffix(1);
         if (name.isEmpty()) {
-            return new NamingContextEnumeration(bindings.elements());
+            return new NamingContextEnumeration(bindings.values().iterator());
         }
         
         NamingEntry entry = (NamingEntry) bindings.get(name.get(0));
@@ -403,7 +403,7 @@
         while ((!name.isEmpty()) && (name.get(0).length() == 0))
             name = name.getSuffix(1);
         if (name.isEmpty()) {
-            return new NamingContextBindingsEnumeration(bindings.elements());
+            return new NamingContextBindingsEnumeration(bindings.values().iterator());
         }
         
         NamingEntry entry = (NamingEntry) bindings.get(name.get(0));
@@ -460,7 +460,6 @@
      * exist
      * @exception NotContextException if the name is bound but does not name 
      * a context, or does not name a context of the appropriate type
-     * @exception NamingException if a naming exception is encountered
      */
     public void destroySubcontext(Name name)
         throws NamingException {
@@ -664,9 +663,9 @@
      * @exception NamingException if a naming exception is encountered
      */
     public Name composeName(Name name, Name prefix)
-        throws NamingException {
-	Name result = (Name) prefix.clone();
-	return result.addAll(name);
+    throws NamingException {
+        Name result = (Name) prefix.clone();
+        return result.addAll(name);
     }
 
 
@@ -706,8 +705,8 @@
      * 
      * @param propName the name of the environment property to remove; 
      * may not be null
-     * @return the previous value of the property, or null if the property was 
-     * not in the environment
+     * @return the previous value of the property, or null if the property 
+     * was not in the environment
      * @exception NamingException if a naming exception is encountered
      */
     public Object removeFromEnvironment(String propName)
@@ -835,6 +834,8 @@
                 } catch (NamingException e) {
                     throw e;
                 } catch (Exception e) {
+                    log.warn(sm.getString
+                             ("namingContext.failResolvingReference"), e);
                     throw new NamingException(e.getMessage());
                 }
             } else {
@@ -849,14 +850,13 @@
      * Binds a name to an object. All intermediate contexts and the target 
      * context (that named by all but terminal atomic component of the name) 
      * must already exist.
-     * <p>
-     * Throws <code>NameAlreadyBoundException</code> if the name is already
-     * bound in this context. Throws <code>InvalidAttributesException</code> if the
-     * object does not supply all mandatory attributes.
      * 
      * @param name the name to bind; may not be empty
      * @param obj the object to bind; possibly null
      * @param rebind if true, then perform a rebind (ie, overwrite)
+     * @exception NameAlreadyBoundException if name is already bound
+     * @exception InvalidAttributesException if object did not supply all 
+     * mandatory attributes
      * @exception NamingException if a naming exception is encountered
      */
     protected void bind(Name name, Object obj, boolean rebind)
@@ -889,7 +889,7 @@
             }
         } else {
             if ((!rebind) && (entry != null)) {
-                throw new NamingException
+                throw new NameAlreadyBoundException
                     (sm.getString("namingContext.alreadyBound", name.get(0)));
             } else {
                 // Getting the type of the object and wrapping it within a new
@@ -940,6 +940,7 @@
         if (!isWritable())
             throw new NamingException(sm.getString("namingContext.readOnly"));
     }
+
 
 }
 

Modified: incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContextBindingsEnumeration.java
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContextBindingsEnumeration.java?view=diff&rev=123921&p1=incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContextBindingsEnumeration.java&r1=123920&p2=incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContextBindingsEnumeration.java&r2=123921
==============================================================================
--- incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContextBindingsEnumeration.java	(original)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContextBindingsEnumeration.java	Sun Jan  2 17:29:34 2005
@@ -17,11 +17,11 @@
 
 package org.apache.naming;
 
-import java.util.Vector;
-import java.util.Enumeration;
-import javax.naming.NamingException;
-import javax.naming.NamingEnumeration;
+import java.util.Iterator;
+
 import javax.naming.Binding;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
 
 /**
  * Naming enumeration implementation.
@@ -37,13 +37,8 @@
     // ----------------------------------------------------------- Constructors
 
 
-    public NamingContextBindingsEnumeration(Vector entries) {
-        enumeration = entries.elements();
-    }
-
-
-    public NamingContextBindingsEnumeration(Enumeration enumeration) {
-        this.enumeration = enumeration;
+    public NamingContextBindingsEnumeration(Iterator entries) {
+    	iterator = entries;
     }
 
 
@@ -53,7 +48,7 @@
     /**
      * Underlying enumeration.
      */
-    protected Enumeration enumeration;
+    protected Iterator iterator;
 
 
     // --------------------------------------------------------- Public Methods
@@ -73,7 +68,7 @@
      */
     public boolean hasMore()
         throws NamingException {
-        return enumeration.hasMoreElements();
+        return iterator.hasNext();
     }
 
 
@@ -86,12 +81,12 @@
 
 
     public boolean hasMoreElements() {
-        return enumeration.hasMoreElements();
+        return iterator.hasNext();
     }
 
 
     public Object nextElement() {
-        NamingEntry entry = (NamingEntry) enumeration.nextElement();
+        NamingEntry entry = (NamingEntry) iterator.next();
         return new Binding(entry.name, entry.value.getClass().getName(), 
                            entry.value, true);
     }

Modified: incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContextEnumeration.java
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContextEnumeration.java?view=diff&rev=123921&p1=incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContextEnumeration.java&r1=123920&p2=incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContextEnumeration.java&r2=123921
==============================================================================
--- incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContextEnumeration.java	(original)
+++ incubator/directory/naming/trunk/core/src/java/org/apache/naming/NamingContextEnumeration.java	Sun Jan  2 17:29:34 2005
@@ -17,11 +17,11 @@
 
 package org.apache.naming;
 
-import java.util.Vector;
-import java.util.Enumeration;
-import javax.naming.NamingException;
-import javax.naming.NamingEnumeration;
+import java.util.Iterator;
+
 import javax.naming.NameClassPair;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
 
 /**
  * Naming enumeration implementation.
@@ -37,13 +37,8 @@
     // ----------------------------------------------------------- Constructors
 
 
-    public NamingContextEnumeration(Vector entries) {
-        enumeration = entries.elements();
-    }
-
-
-    public NamingContextEnumeration(Enumeration enumeration) {
-        this.enumeration = enumeration;
+    public NamingContextEnumeration(Iterator entries) {
+    	iterator = entries;
     }
 
 
@@ -53,7 +48,7 @@
     /**
      * Underlying enumeration.
      */
-    protected Enumeration enumeration;
+    protected Iterator iterator;
 
 
     // --------------------------------------------------------- Public Methods
@@ -73,7 +68,7 @@
      */
     public boolean hasMore()
         throws NamingException {
-        return enumeration.hasMoreElements();
+        return iterator.hasNext();
     }
 
 
@@ -86,12 +81,12 @@
 
 
     public boolean hasMoreElements() {
-        return enumeration.hasMoreElements();
+        return iterator.hasNext();
     }
 
 
     public Object nextElement() {
-        NamingEntry entry = (NamingEntry) enumeration.nextElement();
+        NamingEntry entry = (NamingEntry) iterator.next();
         return new NameClassPair(entry.name, entry.value.getClass().getName());
     }
 

Modified: incubator/directory/naming/trunk/factory/project.xml
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/factory/project.xml?view=diff&rev=123921&p1=incubator/directory/naming/trunk/factory/project.xml&r1=123920&p2=incubator/directory/naming/trunk/factory/project.xml&r2=123921
==============================================================================
--- incubator/directory/naming/trunk/factory/project.xml	(original)
+++ incubator/directory/naming/trunk/factory/project.xml	Sun Jan  2 17:29:34 2005
@@ -6,13 +6,19 @@
 
    <dependencies>
    
-     <!-- Compile time dependencies -->
+     <dependency>
+       <groupId>commons-logging</groupId>
+       <artifactId>commons-logging</artifactId>
+       <version>1.0.3</version>
+     </dependency>
+     
     <dependency>
       <groupId>${pom.groupId}</groupId>
       <artifactId>naming-core</artifactId>
       <version>${pom.currentVersion}</version>
     </dependency>
 
+     <!-- Compile time dependencies -->
     <dependency>
       <groupId>geronimo-spec</groupId>
       <artifactId>geronimo-spec-javamail</artifactId>

Modified: incubator/directory/naming/trunk/java/project.xml
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/java/project.xml?view=diff&rev=123921&p1=incubator/directory/naming/trunk/java/project.xml&r1=123920&p2=incubator/directory/naming/trunk/java/project.xml&r2=123921
==============================================================================
--- incubator/directory/naming/trunk/java/project.xml	(original)
+++ incubator/directory/naming/trunk/java/project.xml	Sun Jan  2 17:29:34 2005
@@ -9,6 +9,11 @@
       <artifactId>naming-core</artifactId>
       <version>${pom.currentVersion}</version>
     </dependency>
+    <dependency>
+       <groupId>commons-logging</groupId>
+       <artifactId>commons-logging</artifactId>
+       <version>1.0.3</version>
+     </dependency>
    </dependencies>
 </project>
 

Modified: incubator/directory/naming/trunk/management/src/java/org/apache/naming/NamingService.java
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/management/src/java/org/apache/naming/NamingService.java?view=diff&rev=123921&p1=incubator/directory/naming/trunk/management/src/java/org/apache/naming/NamingService.java&r1=123920&p2=incubator/directory/naming/trunk/management/src/java/org/apache/naming/NamingService.java&r2=123921
==============================================================================
--- incubator/directory/naming/trunk/management/src/java/org/apache/naming/NamingService.java	(original)
+++ incubator/directory/naming/trunk/management/src/java/org/apache/naming/NamingService.java	Sun Jan  2 17:29:34 2005
@@ -147,7 +147,7 @@
             System.setProperty(Context.URL_PKG_PREFIXES, value);
             
             oldValue = System.getProperty(Context.INITIAL_CONTEXT_FACTORY);
-            if (oldValue != null) {
+            if ((oldValue != null) && (oldValue.length() > 0)) {
                 oldIcValue = oldValue;
             } else {
                 System.setProperty(Context.INITIAL_CONTEXT_FACTORY,

Modified: incubator/directory/naming/trunk/project.xml
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/project.xml?view=diff&rev=123921&p1=incubator/directory/naming/trunk/project.xml&r1=123920&p2=incubator/directory/naming/trunk/project.xml&r2=123921
==============================================================================
--- incubator/directory/naming/trunk/project.xml	(original)
+++ incubator/directory/naming/trunk/project.xml	Sun Jan  2 17:29:34 2005
@@ -158,12 +158,12 @@
      <!-- <report>maven-file-activity-plugin</report> -->
      <report>maven-javadoc-plugin</report>
      <!-- <report>maven-jellydoc-plugin</report> -->
-     <report>maven-junit-report-plugin</report>
-     <report>maven-jxr-plugin</report>
+     <!-- <report>maven-junit-report-plugin</report> -->
+     <!-- <report>maven-jxr-plugin</report> -->
      <!-- <report>maven-license-plugin</report> -->
      <!-- <report>maven-linkcheck-plugin</report> -->
      <!-- <report>maven-statcvs-plugin</report> -->
-     <report>maven-tasklist-plugin</report> 
+     <!-- <report>maven-tasklist-plugin</report> --> 
   </reports>
   
 </project>

Modified: incubator/directory/naming/trunk/resources/project.xml
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/resources/project.xml?view=diff&rev=123921&p1=incubator/directory/naming/trunk/resources/project.xml&r1=123920&p2=incubator/directory/naming/trunk/resources/project.xml&r2=123921
==============================================================================
--- incubator/directory/naming/trunk/resources/project.xml	(original)
+++ incubator/directory/naming/trunk/resources/project.xml	Sun Jan  2 17:29:34 2005
@@ -12,9 +12,12 @@
      </dependency>
      
      <dependency>
-       <id>commons-collections</id>
-       <version>3.1</version>
+       <groupId>commons-logging</groupId>
+       <artifactId>commons-logging</artifactId>
+       <version>1.0.3</version>
      </dependency>
+     
    </dependencies>
+     
 </project>
 

Modified: incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/BaseDirContext.java
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/BaseDirContext.java?view=diff&rev=123921&p1=incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/BaseDirContext.java&r1=123920&p2=incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/BaseDirContext.java&r2=123921
==============================================================================
--- incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/BaseDirContext.java	(original)
+++ incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/BaseDirContext.java	Sun Jan  2 17:29:34 2005
@@ -66,12 +66,6 @@
 
 
     /**
-     * The debugging detail level for this component.
-     */
-    protected int debug = 0;
-
-
-    /**
      * The document base path.
      */
     protected String docBase = null;
@@ -110,31 +104,13 @@
     /**
      * Max size of resources which will have their content cached.
      */
-    protected int cacheObjectMaxSize = 32768; // 32 KB
+    protected int cacheMaxSize = 10240; // 10 MB
 
 
     // ------------------------------------------------------------- Properties
 
 
     /**
-     * Return the debugging detail level for this component.
-     */
-    public int getDebug() {
-	return (this.debug);
-    }
-
-
-    /**
-     * Set the debugging detail level for this component.
-     *
-     * @param debug The new debugging detail level
-     */
-    public void setDebug(int debug) {
-	this.debug = debug;
-    }
-
-
-    /**
      * Return the document root for this component.
      */
     public String getDocBase() {
@@ -198,18 +174,18 @@
 
 
     /**
-     * Set cacheObjectMaxSize.
+     * Set cacheMaxSize.
      */
-    public void setCacheObjectMaxSize(int cacheObjectMaxSize) {
-        this.cacheObjectMaxSize = cacheObjectMaxSize;
+    public void setCacheMaxSize(int cacheObjectMaxSize) {
+        this.cacheMaxSize = cacheObjectMaxSize;
     }
 
 
     /**
-     * Get cacheObjectMaxSize.
+     * Get cacheMaxSize.
      */
-    public int getCacheObjectMaxSize() {
-        return cacheObjectMaxSize;
+    public int getCacheMaxSize() {
+        return cacheMaxSize;
     }
 
 

Added: incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/CacheEntry.java
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/CacheEntry.java?view=auto&rev=123921
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/CacheEntry.java	Sun Jan  2 17:29:34 2005
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1999,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */ 
+
+package org.apache.naming.resources;
+
+import javax.naming.directory.DirContext;
+
+/**
+ * Implements a cache entry.
+ * 
+ * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
+ * @version $Revision: 1.2 $
+ */
+public class CacheEntry {
+    
+    
+    // ------------------------------------------------- Instance Variables
+
+
+    public long timestamp = -1;
+    public String name = null;
+    public ResourceAttributes attributes = null;
+    public Resource resource = null;
+    public DirContext context = null;
+    public boolean exists = true;
+    public long accessCount = 0;
+    public int size = 1;
+
+
+    // ----------------------------------------------------- Public Methods
+
+
+    public void recycle() {
+        timestamp = -1;
+        name = null;
+        attributes = null;
+        resource = null;
+        context = null;
+        exists = true;
+        accessCount = 0;
+        size = 1;
+    }
+
+
+    public String toString() {
+        return ("Cache entry: " + name + "\n"
+                + "Exists: " + exists + "\n"
+                + "Attributes: " + attributes + "\n"
+                + "Resource: " + resource + "\n"
+                + "Context: " + context);
+    }
+
+
+}

Modified: incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/FileDirContext.java
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/FileDirContext.java?view=diff&rev=123921&p1=incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/FileDirContext.java&r1=123920&p2=incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/FileDirContext.java&r2=123921
==============================================================================
--- incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/FileDirContext.java	(original)
+++ incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/FileDirContext.java	Sun Jan  2 17:29:34 2005
@@ -17,26 +17,28 @@
 
 package org.apache.naming.resources;
 
-import java.util.Arrays;
-import java.util.Hashtable;
-import java.util.Vector;
-import java.util.Date;
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.InputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Hashtable;
+
+import javax.naming.NameAlreadyBoundException;
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
 import javax.naming.OperationNotSupportedException;
-import javax.naming.NameAlreadyBoundException;
-import javax.naming.directory.DirContext;
 import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
 import javax.naming.directory.ModificationItem;
 import javax.naming.directory.SearchControls;
-import org.apache.naming.NamingEntry;
+
 import org.apache.naming.NamingContextBindingsEnumeration;
 import org.apache.naming.NamingContextEnumeration;
+import org.apache.naming.NamingEntry;
 
 /**
  * Filesystem Directory Context implementation helper class.
@@ -47,6 +49,8 @@
 
 public class FileDirContext extends BaseDirContext {
 
+    private static org.apache.commons.logging.Log log=
+        org.apache.commons.logging.LogFactory.getLog( FileDirContext.class );
 
     // -------------------------------------------------------------- Constants
 
@@ -118,23 +122,23 @@
      */
     public void setDocBase(String docBase) {
 
-	// Validate the format of the proposed document root
-	if (docBase == null)
-	    throw new IllegalArgumentException
-		(sm.getString("resources.null"));
-
-	// Calculate a File object referencing this document base directory
-	base = new File(docBase);
+        // Validate the format of the proposed document root
+        if (docBase == null)
+            throw new IllegalArgumentException
+            (sm.getString("resources.null"));
+        
+        // Calculate a File object referencing this document base directory
+        base = new File(docBase);
         try {
             base = base.getCanonicalFile();
         } catch (IOException e) {
             // Ignore
         }
-
-	// Validate that the document base is an existing directory
-	if (!base.exists() || !base.isDirectory() || !base.canRead())
-	    throw new IllegalArgumentException
-		(sm.getString("fileResources.base", docBase));
+        
+        // Validate that the document base is an existing directory
+        if (!base.exists() || !base.isDirectory() || !base.canRead())
+            throw new IllegalArgumentException
+            (sm.getString("fileResources.base", docBase));
         this.absoluteBase = base.getAbsolutePath();
         super.setDocBase(normalize(docBase));
 
@@ -204,11 +208,11 @@
         throws NamingException {
         Object result = null;
         File file = file(name);
-        
+  
         if (file == null)
             throw new NamingException
                 (sm.getString("resources.notFound", name));
-        
+  
         if (file.isDirectory()) {
             FileDirContext tempContext = new FileDirContext(env);
             tempContext.setDocBase(file.getPath());
@@ -271,11 +275,11 @@
         if (file == null)
             throw new NamingException
                 (sm.getString("resources.notFound", oldName));
-
+      
         File newFile = new File(base, newName);
         
         file.renameTo(newFile);
-        
+     
     }
 
 
@@ -301,9 +305,7 @@
             throw new NamingException
                 (sm.getString("resources.notFound", name));
 
-        Vector entries = list(file);
-
-        return new NamingContextEnumeration(entries);
+        return new NamingContextEnumeration(list(file).iterator());
 
     }
 
@@ -330,9 +332,7 @@
             throw new NamingException
                 (sm.getString("resources.notFound", name));
 
-        Vector entries = list(file);
-
-        return new NamingContextBindingsEnumeration(entries);
+        return new NamingContextBindingsEnumeration(list(file).iterator());
 
     }
 
@@ -344,7 +344,7 @@
      * <p>
      * This method is idempotent. It succeeds even if the terminal atomic 
      * name is not bound in the target context, but throws 
-     * NameNotFoundException if any of the intermediate contexts do not exist. 
+     * NameNotFoundException if any of the intermediate contexts do not exist.
      * 
      * In a federated naming system, a context from one naming system may be 
      * bound to a name in another. One can subsequently look up and perform 
@@ -412,7 +412,7 @@
 
 
     /**
-     * Retrieves selected attributes associated with a named object. 
+     * Retrieves selected attributes associated with a named object.
      * See the class description regarding attribute models, attribute type 
      * names, and operational attributes.
      * 
@@ -442,19 +442,19 @@
      * Modifies the attributes associated with a named object. The order of 
      * the modifications is not specified. Where possible, the modifications 
      * are performed atomically.
-     * 
-     * @param name the name of the object whose attributes will be updated
+     *
+     * @param name the name of the object whose attributes will be updated 
      * @param mod_op the modification operation, one of: ADD_ATTRIBUTE, 
-     * REPLACE_ATTRIBUTE, REMOVE_ATTRIBUTE
+     * REPLACE_ATTRIBUTE, REMOVE_ATTRIBUTE 
      * @param attrs the attributes to be used for the modification; may not 
      * be null
-     * @exception AttributeModificationException if the modification cannot be
+     * @exception AttributeModificationException if the modification cannot be 
      * completed successfully
      * @exception NamingException if a naming exception is encountered
      */
     public void modifyAttributes(String name, int mod_op, Attributes attrs)
         throws NamingException {
-        
+
     }
 
 
@@ -465,16 +465,16 @@
      * code and an attribute on which to operate. Where possible, the 
      * modifications are performed atomically.
      * 
-     * @param name the name of the object whose attributes will be updated
+     * @param name the name of the object whose attributes will be updated 
      * @param mods an ordered sequence of modifications to be performed; may 
      * not be null
-     * @exception AttributeModificationException if the modification cannot be
+     * @exception AttributeModificationException if the modification cannot be 
      * completed successfully
      * @exception NamingException if a naming exception is encountered
      */
     public void modifyAttributes(String name, ModificationItem[] mods)
         throws NamingException {
-        
+
     }
 
 
@@ -495,16 +495,16 @@
      */
     public void bind(String name, Object obj, Attributes attrs)
         throws NamingException {
-        
+
         // Note: No custom attributes allowed
-        
+
         File file = new File(base, name);
         if (file.exists())
             throw new NameAlreadyBoundException
                 (sm.getString("resources.alreadyBound", name));
-        
+
         rebind(name, obj, attrs);
-        
+
     }
 
 
@@ -512,7 +512,7 @@
      * Binds a name to an object, along with associated attributes, 
      * overwriting any existing binding. If attrs is null and obj is a 
      * DirContext, the attributes from obj are used. If attrs is null and obj 
-     * is not a DirContext, any existing attributes associated with the object
+     * is not a DirContext, any existing attributes associated with the object 
      * already bound in the directory remain unchanged. If attrs is non-null, 
      * any existing attributes associated with the object already bound in 
      * the directory are removed and attrs is associated with the named 
@@ -528,12 +528,12 @@
      */
     public void rebind(String name, Object obj, Attributes attrs)
         throws NamingException {
-        
+
         // Note: No custom attributes allowed
         // Check obj type
-        
+
         File file = new File(base, name);
-        
+
         InputStream is = null;
         if (obj instanceof Resource) {
             try {
@@ -555,9 +555,9 @@
         if (is == null)
             throw new NamingException
                 (sm.getString("resources.bindFailed", name));
-        
+
         // Open os
-        
+
         try {
             FileOutputStream os = null;
             byte buffer[] = new byte[BUFFER_SIZE];
@@ -579,7 +579,7 @@
             throw new NamingException
                 (sm.getString("resources.bindFailed", e));
         }
-        
+
     }
 
 
@@ -592,17 +592,17 @@
      * exist. If attrs is null, this method is equivalent to 
      * Context.createSubcontext().
      * 
-     * @param name the name of the context to create; may not be empty
-     * @param attrs the attributes to associate with the newly created context
-     * @return the newly created context
-     * @exception NameAlreadyBoundException if the name is already bound
+     * @param name the name of the context to create; may not be empty 
+     * @param attrs the attributes to associate with the newly created context 
+     * @return the newly created context 
+     * @exception NameAlreadyBoundException if the name is already bound 
      * @exception InvalidAttributesException if attrs does not contain all 
-     * the mandatory attributes required for creation
-     * @exception NamingException if a naming exception is encountered
+     * the mandatory attributes required for creation 
+     * @exception NamingException if a naming exception is encountered 
      */
     public DirContext createSubcontext(String name, Attributes attrs)
         throws NamingException {
-        
+
         File file = new File(base, name);
         if (file.exists())
             throw new NameAlreadyBoundException
@@ -611,7 +611,7 @@
             throw new NamingException
                 (sm.getString("resources.bindFailed", name));
         return (DirContext) lookup(name);
-        
+
     }
 
 
@@ -621,7 +621,7 @@
      * attributes stored within it. The schema specifies what types of 
      * objects can be added to the directory and where they can be added; 
      * what mandatory and optional attributes an object can have. The range 
-     * of support for schemas is directory-specific.
+     * of support for schemas is directory-specific. 
      * 
      * @param name the name of the object whose schema is to be retrieved
      * @return the schema associated with the context; never null
@@ -700,7 +700,7 @@
      * Searches in the named context or object for entries that satisfy the 
      * given search filter. Performs the search as specified by the search 
      * controls.
-     * 
+     *
      * @param name the name of the context or object to search
      * @param filter the filter expression to use for the search; may not be 
      * null
@@ -710,12 +710,12 @@
      * @return an enumeration of SearchResults of the objects that satisfy 
      * the filter; never null
      * @exception InvalidSearchFilterException if the search filter specified 
-     * is not supported or understood by the underlying directory
+     * is not supported or understood by the underlying directory 
      * @exception InvalidSearchControlsException if the search controls 
      * contain invalid settings
      * @exception NamingException if a naming exception is encountered
      */
-    public NamingEnumeration search(String name, String filter, 
+    public NamingEnumeration search(String name, String filter,
                                     SearchControls cons)
         throws NamingException {
         return null;
@@ -727,26 +727,26 @@
      * given search filter. Performs the search as specified by the search 
      * controls.
      * 
-     * @param name the name of the context or object to search
-     * @param filterExpr the filter expression to use for the search. 
+     * @param name the name of the context or object to search 
+     * @param filterExpr the filter expression to use for the search.
      * The expression may contain variables of the form "{i}" where i is a 
      * nonnegative integer. May not be null.
      * @param filterArgs the array of arguments to substitute for the 
      * variables in filterExpr. The value of filterArgs[i] will replace each 
-     * occurrence of "{i}". If null, equivalent to an empty array.
+     * occurrence of "{i}". If null, equivalent to an empty array. 
      * @param cons the search controls that control the search. If null, the 
-     * default search controls are used (equivalent to (new SearchControls())).
+     * default search controls are used (equivalent to (new SearchControls())). 
      * @return an enumeration of SearchResults of the objects that satisy the 
      * filter; never null
      * @exception ArrayIndexOutOfBoundsException if filterExpr contains {i} 
-     * expressions where i is outside the bounds of the array filterArgs
+     * expressions where i is outside the bounds of the array filterArgs 
      * @exception InvalidSearchControlsException if cons contains invalid 
      * settings
      * @exception InvalidSearchFilterException if filterExpr with filterArgs 
      * represents an invalid search filter
      * @exception NamingException if a naming exception is encountered
      */
-    public NamingEnumeration search(String name, String filterExpr, 
+    public NamingEnumeration search(String name, String filterExpr,
                                     Object[] filterArgs, SearchControls cons)
         throws NamingException {
         return null;
@@ -757,72 +757,75 @@
 
 
     /**
-     * Return a context-relative path, beginning with a "/", that represents
-     * the canonical version of the specified path after ".." and "." elements
-     * are resolved out.  If the specified path attempts to go outside the
-     * boundaries of the current context (i.e. too many ".." path elements
+     * Return a context-relative path, beginning with a "/", that represents 
+     * the canonical version of the specified path after ".." and "." elements 
+     * are resolved out.  If the specified path attempts to go outside the 
+     * boundaries of the current context (i.e. too many ".." path elements 
      * are present), return <code>null</code> instead.
-     *
+     * 
      * @param path Path to be normalized
      */
     protected String normalize(String path) {
-
-	String normalized = path;
-
-	// Normalize the slashes and add leading slash if necessary
-	if (normalized.indexOf('\\') >= 0)
-	    normalized = normalized.replace('\\', '/');
-	if (!normalized.startsWith("/"))
-	    normalized = "/" + normalized;
-
-	// Resolve occurrences of "//" in the normalized path
-	while (true) {
-	    int index = normalized.indexOf("//");
-	    if (index < 0)
-		break;
-	    normalized = normalized.substring(0, index) +
-		normalized.substring(index + 1);
-	}
-
-	// Resolve occurrences of "/./" in the normalized path
-	while (true) {
-	    int index = normalized.indexOf("/./");
-	    if (index < 0)
-		break;
-	    normalized = normalized.substring(0, index) +
-		normalized.substring(index + 2);
-	}
-
-	// Resolve occurrences of "/../" in the normalized path
-	while (true) {
-	    int index = normalized.indexOf("/../");
-	    if (index < 0)
-		break;
-	    if (index == 0)
-		return (null);	// Trying to go outside our context
-	    int index2 = normalized.lastIndexOf('/', index - 1);
-	    normalized = normalized.substring(0, index2) +
-		normalized.substring(index + 3);
-	}
-
-	// Return the normalized path that we have completed
-	return (normalized);
-
+        
+        String normalized = path;
+        
+        // Normalize the slashes and add leading slash if necessary
+        if (normalized.indexOf('\\') >= 0)
+            normalized = normalized.replace('\\', '/');
+        if (!normalized.startsWith("/"))
+            normalized = "/" + normalized;
+        
+        // Resolve occurrences of "//" in the normalized path
+        while (true) {
+            int index = normalized.indexOf("//");
+            if (index < 0)
+                break;
+            normalized = normalized.substring(0, index) +
+            normalized.substring(index + 1);
+        }
+        
+        // Resolve occurrences of "/./" in the normalized path
+        while (true) {
+            int index = normalized.indexOf("/./");
+            if (index < 0)
+                break;
+            normalized = normalized.substring(0, index) +
+            normalized.substring(index + 2);
+        }
+        
+        // Resolve occurrences of "/../" in the normalized path
+        while (true) {
+            int index = normalized.indexOf("/../");
+            if (index < 0)
+                break;
+            if (index == 0)
+                return (null);  // Trying to go outside our context
+            int index2 = normalized.lastIndexOf('/', index - 1);
+            normalized = normalized.substring(0, index2) +
+            normalized.substring(index + 3);
+        }
+        
+        // Return the normalized path that we have completed
+        return (normalized);
+        
     }
 
 
     /**
-     * Return a File object representing the specified normalized
+     * Return a File object representing the specified normalized 
      * context-relative path if it exists and is readable.  Otherwise,
      * return <code>null</code>.
-     *
+     * 
      * @param name Normalized context-relative path (with leading '/')
      */
     protected File file(String name) {
 
         File file = new File(base, name);
         if (file.exists() && file.canRead()) {
-
+            
+            if (allowLinking)
+                return file;
+            
             // Check that this file belongs to our root path
             String canPath = null;
             try {
@@ -831,22 +834,22 @@
             }
             if (canPath == null)
                 return null;
-
+            
             // Check to see if going outside of the web application root
-            if ((!allowLinking) && (!canPath.startsWith(absoluteBase))) {
+            if (!canPath.startsWith(absoluteBase)) {
                 return null;
             }
-
+            
             // Case sensitivity check
-            if (!allowLinking && caseSensitive) {
+            if (caseSensitive) {
                 String fileAbsPath = file.getAbsolutePath();
                 if (fileAbsPath.endsWith("."))
                     fileAbsPath = fileAbsPath + "/";
                 String absPath = normalize(fileAbsPath);
                 if (canPath != null)
                     canPath = normalize(canPath);
-                if ((absoluteBase.length() < absPath.length()) 
-                    && (absoluteBase.length() < canPath.length())) {
+                if ((absoluteBase.length() < absPath.length())
+                && (absoluteBase.length() < canPath.length())) {
                     absPath = absPath.substring(absoluteBase.length() + 1);
                     if ((canPath == null) || (absPath == null))
                         return null;
@@ -859,12 +862,12 @@
                         return null;
                 }
             }
-
+            
         } else {
             return null;
         }
         return file;
-
+        
     }
 
 
@@ -874,19 +877,27 @@
      * @param file Collection
      * @return Vector containg NamingEntry objects
      */
-    protected Vector list(File file) {
+    protected ArrayList list(File file) {
 
-        Vector entries = new Vector();
+        ArrayList entries = new ArrayList();
         if (!file.isDirectory())
             return entries;
         String[] names = file.list();
+        if (names==null) {
+            /* Some IO error occurred such as bad file permissions.
+             Prevent a NPE with Arrays.sort(names) */
+            log.warn(sm.getString("fileResources.listingNull",
+                    file.getAbsolutePath()));
+            return entries;
+        }
+        
         Arrays.sort(names);             // Sort alphabetically
         if (names == null)
             return entries;
         NamingEntry entry = null;
-
+        
         for (int i = 0; i < names.length; i++) {
-
+            
             File currentFile = new File(file, names[i]);
             Object object = null;
             if (currentFile.isDirectory()) {
@@ -897,12 +908,12 @@
                 object = new FileResource(currentFile);
             }
             entry = new NamingEntry(names[i], object, NamingEntry.ENTRY);
-            entries.addElement(entry);
-
+            entries.add(entry);
+            
         }
-
+        
         return entries;
-
+        
     }
 
 
@@ -914,37 +925,37 @@
      * to the file right away (which would put a lock on the file).
      */
     protected class FileResource extends Resource {
-        
-        
+
+
         // -------------------------------------------------------- Constructor
 
 
         public FileResource(File file) {
             this.file = file;
         }
-        
-        
+
+
         // --------------------------------------------------- Member Variables
-        
-        
+
+
         /**
          * Associated file object.
          */
         protected File file;
-        
-        
+
+
         /**
          * File length.
          */
         protected long length = -1L;
-        
-        
+
+
         // --------------------------------------------------- Resource Methods
-        
-        
+
+
         /**
          * Content accessor.
-         * 
+         *
          * @return InputStream
          */
         public InputStream streamContent()
@@ -954,8 +965,8 @@
             }
             return super.streamContent();
         }
-        
-        
+
+
     }
 
 
@@ -968,27 +979,27 @@
      * date).
      */
     protected class FileResourceAttributes extends ResourceAttributes {
-
-
+   
+  
         // -------------------------------------------------------- Constructor
-
-
+  
+  
         public FileResourceAttributes(File file) {
             this.file = file;
         }
-        
+ 
         // --------------------------------------------------- Member Variables
-        
-        
+ 
+ 
         protected File file;
-        
-        
+ 
+ 
         protected boolean accessed = false;
-        
-        
+
+
         // ----------------------------------------- ResourceAttributes Methods
-        
-        
+ 
+ 
         /**
          * Is collection.
          */
@@ -999,11 +1010,11 @@
             }
             return super.isCollection();
         }
-        
-        
+ 
+ 
         /**
          * Get content length.
-         * 
+         *
          * @return content length value
          */
         public long getContentLength() {
@@ -1012,11 +1023,11 @@
             contentLength = file.length();
             return contentLength;
         }
-        
-        
+
+
         /**
          * Get creation time.
-         * 
+         *
          * @return creation time value
          */
         public long getCreation() {
@@ -1025,11 +1036,11 @@
             creation = file.lastModified();
             return creation;
         }
-        
-        
+
+
         /**
          * Get creation date.
-         * 
+         *
          * @return Creation date value
          */
         public Date getCreationDate() {
@@ -1038,11 +1049,11 @@
             }
             return super.getCreationDate();
         }
-        
-        
+
+
         /**
          * Get last modified time.
-         * 
+         *
          * @return lastModified time value
          */
         public long getLastModified() {
@@ -1051,11 +1062,11 @@
             lastModified = file.lastModified();
             return lastModified;
         }
-        
-        
+
+
         /**
          * Get lastModified date.
-         * 
+         *
          * @return LastModified date value
          */
         public Date getLastModifiedDate() {
@@ -1064,11 +1075,11 @@
             }
             return super.getLastModifiedDate();
         }
-        
-        
+
+
         /**
          * Get name.
-         * 
+         *
          * @return Name value
          */
         public String getName() {
@@ -1076,11 +1087,11 @@
                 name = file.getName();
             return name;
         }
-        
-        
+
+
         /**
          * Get resource type.
-         * 
+         *
          * @return String resource type
          */
         public String getResourceType() {
@@ -1090,10 +1101,8 @@
             }
             return super.getResourceType();
         }
-        
-        
-    }
 
+    }
 
 }
 

Modified: incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings.properties
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings.properties?view=diff&rev=123921&p1=incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings.properties&r1=123920&p2=incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings.properties&r2=123921
==============================================================================
--- incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings.properties	(original)
+++ incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings.properties	Sun Jan  2 17:29:34 2005
@@ -1,4 +1,5 @@
 fileResources.base=Document base {0} does not exist or is not a readable directory
+fileResources.listingNull=Could not get dir listing for {0}
 warResources.notWar=Doc base must point to a WAR file
 warResources.invalidWar=Invalid or unreadable WAR file : {0}
 jarResources.syntax=Document base {0} must start with 'jar:' and end with '!/'

Added: incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings_es.properties
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings_es.properties?view=auto&rev=123921
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings_es.properties	Sun Jan  2 17:29:34 2005
@@ -0,0 +1,20 @@
+fileResources.base=El Documento base {0} no existe o no es un directorio legible
+warResources.notWar=Doc base debe de apuntar a un archivo WAR
+warResources.invalidWar=Archivo WAR inv�lido o ilegible: {0}
+jarResources.syntax=Documento base {0} debe de empezar con 'jar:' y acabar con '!/'
+resources.alreadyStarted=Ya han sido arrancados los Recursos
+resources.connect=No puedo conectar a documento base {0}
+resources.input=No puedo crear flujo (stream) de entrada para recurso {0}
+resources.notStarted=A�n no han sido arrancados los Recursos
+resources.null=El Documento base no puede ser nulo
+resources.notFound=Recurso {0} no hallado
+resources.path=Trayectoria relativa a contexto {0} debe de comenzar con '/'
+resources.alreadyBound=El Nombre {0} ya ha sido cambiado (bound) en este Contexto
+resources.bindFailed=Fall� el Cambio (Bind): {0}
+resources.unbindFailed=Fall� el Descambio (Unbind): {0}
+standardResources.alreadyStarted=Ya han sido arrancados los Recursos
+standardResources.directory=El archivo base {0} no es un directorio
+standardResources.exists=El archivo base {0} no existe
+standardResources.notStarted=A�n no han sido arrancados los Recursos
+standardResources.null=El Documento base no puede ser nulo
+standardResources.slash=El Documento base {0} no debe de terminar con una barra

Modified: incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings_fr.properties
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings_fr.properties?view=diff&rev=123921&p1=incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings_fr.properties&r1=123920&p2=incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings_fr.properties&r2=123921
==============================================================================
--- incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings_fr.properties	(original)
+++ incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings_fr.properties	Sun Jan  2 17:29:34 2005
@@ -1,20 +1,20 @@
-fileResources.base=Le "document base" {0} n''existe pas ou n''est pas un r�pertoire lisible
+fileResources.base=Le document base {0} n''existe pas ou n''est pas un r�pertoire lisible
 warResources.notWar=Doc base doit point� vers un fichier WAR
 warResources.invalidWar=Fichier WAR invalide ou illisible  : {0}
-jarResources.syntax=Le document base {0} doit commencer par 'jar:' et finir avec '!/'
+jarResources.syntax=Le document base {0} doit commenc� par 'jar:' et finir avec '!/'
 resources.alreadyStarted=Les Ressources ont d�j� �t� d�marr�es
 resources.connect=Impossible de se connecter au document base {0}
-resources.input=Impossible de cr�er le flux d''entr�e (input stream) pour la ressource {0}
+resources.input=Impossible de cr�er l'input stream pour la ressource {0}
 resources.notStarted=Les ressources n''ont pas encore �t� d�marr�es
-resources.null=Le "document base" ne peut �tre nul
+resources.null=Le document base ne peut �tre nul
 resources.notFound=La ressource {0} est introuvable
-resources.path=Le chemin relatif de context {0} doit commencer par '/'
-resources.alreadyBound=Le nom {0} a d�j� �t� r�f�renc� par ce contexte
+resources.path=Le chemin relatif de context {0} doit commenc� par '/'
+resources.alreadyBound=Le nom {0} est d�j� r�f�renc� par ce contexte
 resources.bindFailed=Le liage a �chou�: {0}
 resources.unbindFailed=Le d�liage a �chou�: {0}
 standardResources.alreadyStarted=Les ressources ont d�ja �t� d�marr�es
-standardResources.directory=Le "file base" {0} n''est pas un r�pertoire
-standardResources.exists=Le "file base" {0} n''existe pas
+standardResources.directory=Le file base {0} n''est pas un r�pertoire
+standardResources.exists=Le file base {0} n''existe pas
 standardResources.notStarted=Les ressources n''ont pas encore �t� d�marr�es
 standardResources.null=Le document base ne peut �tre nul
 standardResources.slash=Le document base {0} ne doit pas se terminer par un '/'

Modified: incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings_ja.properties
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings_ja.properties?view=diff&rev=123921&p1=incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings_ja.properties&r1=123920&p2=incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings_ja.properties&r2=123921
==============================================================================
--- incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings_ja.properties	(original)
+++ incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/LocalStrings_ja.properties	Sun Jan  2 17:29:34 2005
@@ -1,18 +1,19 @@
-fileResources.base=\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u30d9\u30fc\u30b9 {0} \u304c\u5b58\u5728\u3057\u306a\u3044\u3001\u307e\u305f\u306f\u8aad\u3081\u306a\u3044\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3067\u3059
+fileResources.base=\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u30d9\u30fc\u30b9 {0} \u304c\u5b58\u5728\u3057\u306a\u3044\u3001\u53c8\u306f\u8aad\u3081\u306a\u3044\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3067\u3059
+fileResources.listingNull={0} \u306e\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u30ea\u30b9\u30c8\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093
 warResources.notWar=\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u30d9\u30fc\u30b9\u306fWAR\u30d5\u30a1\u30a4\u30eb\u3092\u793a\u3055\u306a\u3051\u308c\u3070\u3044\u3051\u307e\u305b\u3093
-warResources.invalidWar=\u7121\u52b9\u307e\u305f\u306f\u8aad\u3081\u306a\u3044WAR\u30d5\u30a1\u30a4\u30eb\u3067\u3059 : {0}
+warResources.invalidWar=\u7121\u52b9\u53c8\u306f\u8aad\u3081\u306a\u3044WAR\u30d5\u30a1\u30a4\u30eb\u3067\u3059 : {0}
 jarResources.syntax=\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u30d9\u30fc\u30b9 {0} \u306f'jar:'\u3067\u59cb\u307e\u308a\u3001'!/'\u3067\u7d42\u3089\u306a\u3051\u308c\u3070\u3044\u3051\u307e\u305b\u3093
-resources.alreadyStarted=\u30ea\u30bd\u30fc\u30b9\u306f\u3059\u3067\u306b\u8d77\u52d5\u3055\u308c\u3066\u3044\u307e\u3059
+resources.alreadyStarted=\u30ea\u30bd\u30fc\u30b9\u306f\u65e2\u306b\u8d77\u52d5\u3055\u308c\u3066\u3044\u307e\u3059
 resources.connect=\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u30d9\u30fc\u30b9 {0} \u306b\u63a5\u7d9a\u3067\u304d\u307e\u305b\u3093
 resources.input=\u30ea\u30bd\u30fc\u30b9 {0} \u306b\u5165\u529b\u30b9\u30c8\u30ea\u30fc\u30e0\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093
 resources.notStarted=\u30ea\u30bd\u30fc\u30b9\u306f\u307e\u3060\u8d77\u52d5\u3055\u308c\u3066\u3044\u307e\u305b\u3093
 resources.null=\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u30d9\u30fc\u30b9\u306fnull\u3067\u3042\u3063\u3066\u306f\u3044\u3051\u307e\u305b\u3093
 resources.notFound=\u30ea\u30bd\u30fc\u30b9 {0} \u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093
 resources.path=\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u76f8\u5bfe\u30d1\u30b9 {0} \u306f'/'\u3067\u59cb\u307e\u3089\u306a\u3051\u308c\u3070\u3044\u3051\u307e\u305b\u3093
-resources.alreadyBound=\u540d\u524d {0} \u306f\u3059\u3067\u306b\u3053\u306e\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306b\u30d0\u30a4\u30f3\u30c9\u3055\u308c\u3066\u3044\u307e\u3059
+resources.alreadyBound=\u540d\u524d {0} \u306f\u65e2\u306b\u3053\u306e\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306b\u30d0\u30a4\u30f3\u30c9\u3055\u308c\u3066\u3044\u307e\u3059
 resources.bindFailed=\u30d0\u30a4\u30f3\u30c9\u304c\u5931\u6557\u3057\u307e\u3057\u305f: {0}
 resources.unbindFailed=\u30a2\u30f3\u30d0\u30a4\u30f3\u30c9\u304c\u5931\u6557\u3057\u307e\u3057\u305f: {0}
-standardResources.alreadyStarted=\u30ea\u30bd\u30fc\u30b9\u306f\u3059\u3067\u306b\u8d77\u52d5\u3055\u308c\u3066\u3044\u307e\u3059
+standardResources.alreadyStarted=\u30ea\u30bd\u30fc\u30b9\u306f\u65e2\u306b\u8d77\u52d5\u3055\u308c\u3066\u3044\u307e\u3059
 standardResources.directory=\u30d5\u30a1\u30a4\u30eb\u30d9\u30fc\u30b9 {0} \u306f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3067\u306f\u3042\u308a\u307e\u305b\u3093
 standardResources.exists=\u30d5\u30a1\u30a4\u30eb\u30d9\u30fc\u30b9 {0} \u306f\u5b58\u5728\u3057\u307e\u305b\u3093
 standardResources.notStarted=\u30ea\u30bd\u30fc\u30b9\u304c\u307e\u3060\u8d77\u52d5\u3055\u308c\u3066\u3044\u307e\u305b\u3093

Modified: incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/ProxyDirContext.java
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/ProxyDirContext.java?view=diff&rev=123921&p1=incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/ProxyDirContext.java&r1=123920&p2=incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/ProxyDirContext.java&r2=123921
==============================================================================
--- incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/ProxyDirContext.java	(original)
+++ incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/ProxyDirContext.java	Sun Jan  2 17:29:34 2005
@@ -17,28 +17,24 @@
 
 package org.apache.naming.resources;
 
-import java.util.Collections;
-import java.util.Hashtable;
-import java.util.Map;
-import java.io.InputStream;
-import java.io.IOException;
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Hashtable;
 
 import javax.naming.Context;
 import javax.naming.Name;
-import javax.naming.NameParser;
 import javax.naming.NameNotFoundException;
+import javax.naming.NameParser;
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
-import javax.naming.directory.DirContext;
 import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
 import javax.naming.directory.ModificationItem;
 import javax.naming.directory.SearchControls;
 
 import org.apache.naming.StringManager;
 
-import org.apache.commons.collections.LRUMap;
-
 /**
  * Proxy Directory Context implementation.
  *
@@ -68,11 +64,18 @@
         if (dirContext instanceof BaseDirContext) {
             // Initialize parameters based on the associated dir context, like
             // the caching policy.
-            if (((BaseDirContext) dirContext).isCached()) {
-                cache = Collections.synchronizedMap(new LRUMap(cacheSize));
-                cacheTTL = ((BaseDirContext) dirContext).getCacheTTL();
-                cacheObjectMaxSize = 
-                    ((BaseDirContext) dirContext).getCacheObjectMaxSize();
+            BaseDirContext baseDirContext = (BaseDirContext) dirContext;
+            if (baseDirContext.isCached()) {
+                try {
+                    cache = (ResourceCache) 
+                        Class.forName(cacheClassName).newInstance();
+                } catch (Exception e) {
+                    //FIXME
+                    e.printStackTrace();
+                }
+                cache.setCacheMaxSize(baseDirContext.getCacheMaxSize());
+                cacheTTL = baseDirContext.getCacheTTL();
+                cacheObjectMaxSize = baseDirContext.getCacheMaxSize() / 20;
             }
         }
         hostName = (String) env.get(HOST);
@@ -84,24 +87,35 @@
      * Builds a clone of this proxy dir context, wrapping the given directory
      * context, and sharing the same cache.
      */
+    // TODO: Refactor using the proxy field
+    /*
     protected ProxyDirContext(ProxyDirContext proxyDirContext, 
                               DirContext dirContext, String vPath) {
         this.env = proxyDirContext.env;
         this.dirContext = dirContext;
         this.vPath = vPath;
         this.cache = proxyDirContext.cache;
+        this.cacheMaxSize = proxyDirContext.cacheMaxSize;
         this.cacheSize = proxyDirContext.cacheSize;
         this.cacheTTL = proxyDirContext.cacheTTL;
         this.cacheObjectMaxSize = proxyDirContext.cacheObjectMaxSize;
+        this.notFoundCache = proxyDirContext.notFoundCache;
         this.hostName = proxyDirContext.hostName;
         this.contextName = proxyDirContext.contextName;
     }
+    */
 
 
     // ----------------------------------------------------- Instance Variables
 
 
     /**
+     * Proxy DirContext (either this or the real proxy).
+     */
+    protected ProxyDirContext proxy = this;
+
+
+    /**
      * Environment.
      */
     protected Hashtable env;
@@ -138,16 +152,16 @@
 
 
     /**
-     * Cache.
-     * Path -> Cache entry.
+     * Cache class.
      */
-    protected Map cache = null;
+    protected String cacheClassName = 
+        "org.apache.naming.resources.ResourceCache";
 
 
     /**
-     * Cache size
+     * Cache.
      */
-    protected int cacheSize = 1000;
+    protected ResourceCache cache = null;
 
 
     /**
@@ -159,7 +173,7 @@
     /**
      * Max size of resources which will have their content cached.
      */
-    protected int cacheObjectMaxSize = 32768; // 32 KB
+    protected int cacheObjectMaxSize = 512; // 512 KB
 
 
     /**
@@ -169,10 +183,24 @@
         new ImmutableNameNotFoundException();
 
 
+    /**
+     * Non cacheable resources.
+     */
+    protected String[] nonCacheable = { "/WEB-INF/lib/", "/WEB-INF/classes/" };
+
+
     // --------------------------------------------------------- Public Methods
 
 
     /**
+     * Get the cache used for this context.
+     */
+    public ResourceCache getCache() {
+        return cache;
+    }
+
+
+    /**
      * Return the actual directory context we are wrapping.
      */
     public DirContext getDirContext() {
@@ -224,6 +252,9 @@
         throws NamingException {
         CacheEntry entry = cacheLookup(name.toString());
         if (entry != null) {
+            if (!entry.exists) {
+                throw notFoundException;
+            }
             if (entry.resource != null) {
                 // Check content caching.
                 return entry.resource;
@@ -250,6 +281,9 @@
         throws NamingException {
         CacheEntry entry = cacheLookup(name);
         if (entry != null) {
+            if (!entry.exists) {
+                throw notFoundException;
+            }
             if (entry.resource != null) {
                 return entry.resource;
             } else {
@@ -650,9 +684,9 @@
      * @exception NamingException if a naming exception is encountered
      */
     public Name composeName(Name name, Name prefix)
-        throws NamingException {
+    throws NamingException {
         Name result = (Name) prefix.clone();
-	return result.addAll(name);
+        return result.addAll(name);
     }
 
 
@@ -768,6 +802,9 @@
         throws NamingException {
         CacheEntry entry = cacheLookup(name.toString());
         if (entry != null) {
+            if (!entry.exists) {
+                throw notFoundException;
+            }
             return entry.attributes;
         }
         Attributes attributes = dirContext.getAttributes(parseName(name));
@@ -789,6 +826,9 @@
         throws NamingException {
         CacheEntry entry = cacheLookup(name);
         if (entry != null) {
+            if (!entry.exists) {
+                throw notFoundException;
+            }
             return entry.attributes;
         }
         Attributes attributes = dirContext.getAttributes(parseName(name));
@@ -1323,6 +1363,45 @@
     }
 
 
+    // --------------------------------------------------------- Public Methods
+
+
+    /**
+     * Retrieves the named object as a cache entry, without any exception.
+     * 
+     * @param name the name of the object to look up
+     * @return the cache entry bound to name
+     */
+    public CacheEntry lookupCache(String name) {
+        CacheEntry entry = cacheLookup(name);
+        if (entry == null) {
+            entry = new CacheEntry();
+            entry.name = name;
+            try {
+                Object object = dirContext.lookup(parseName(name));
+                if (object instanceof InputStream) {
+                    entry.resource = new Resource((InputStream) object);
+                } else if (object instanceof DirContext) {
+                    entry.context = (DirContext) object;
+                } else if (object instanceof Resource) {
+                    entry.resource = (Resource) object;
+                } else {
+                    entry.resource = new Resource(new ByteArrayInputStream
+                        (object.toString().getBytes()));
+                }
+                Attributes attributes = dirContext.getAttributes(parseName(name));
+                if (!(attributes instanceof ResourceAttributes)) {
+                    attributes = new ResourceAttributes(attributes);
+                }
+                entry.attributes = (ResourceAttributes) attributes;
+            } catch (NamingException e) {
+                entry.exists = false;
+            }
+        }
+        return entry;
+    }
+
+
     // ------------------------------------------------------ Protected Methods
 
 
@@ -1351,11 +1430,17 @@
     /**
      * Lookup in cache.
      */
-    protected CacheEntry cacheLookup(String name)
-        throws NamingException {
+    protected CacheEntry cacheLookup(String name) {
         if (cache == null)
             return (null);
-        CacheEntry cacheEntry = (CacheEntry) cache.get(name);
+        if (name == null)
+            name = "";
+        for (int i = 0; i < nonCacheable.length; i++) {
+            if (name.startsWith(nonCacheable[i])) {
+                return (null);
+            }
+        }
+        CacheEntry cacheEntry = cache.lookup(name);
         if (cacheEntry == null) {
             cacheEntry = new CacheEntry();
             cacheEntry.name = name;
@@ -1371,9 +1456,7 @@
                         System.currentTimeMillis() + cacheTTL;
                 }
             }
-        }
-        if (!cacheEntry.exists) {
-            throw notFoundException;
+            cacheEntry.accessCount++;
         }
         return (cacheEntry);
     }
@@ -1474,8 +1557,12 @@
         if ((exists) && (entry.resource != null) 
             && (entry.resource.getContent() == null) 
             && (entry.attributes.getContentLength() >= 0)
-            && (entry.attributes.getContentLength() < cacheObjectMaxSize)) {
+            && (entry.attributes.getContentLength() < 
+                (cacheObjectMaxSize * 1024))) {
             int length = (int) entry.attributes.getContentLength();
+            // The entry size is 1 + the resource size in KB, if it will be 
+            // cached
+            entry.size += (entry.attributes.getContentLength() / 1024);
             InputStream is = null;
             try {
                 is = entry.resource.streamContent();
@@ -1507,7 +1594,12 @@
         entry.timestamp = System.currentTimeMillis() + cacheTTL;
 
         // Add new entry to cache
-        cache.put(name, entry);
+        synchronized (cache) {
+            // Check cache size, and remove elements if too big
+            if (cache.allocate(entry.size)) {
+                cache.load(entry);
+            }
+        }
 
     }
 
@@ -1518,49 +1610,9 @@
     protected boolean cacheUnload(String name) {
         if (cache == null)
             return false;
-        return (cache.remove(name) != null);
-    }
-
-
-    // ------------------------------------------------- CacheEntry Inner Class
-
-
-    protected class CacheEntry {
-
-
-        // ------------------------------------------------- Instance Variables
-
-
-        long timestamp = -1;
-        String name = null;
-        ResourceAttributes attributes = null;
-        Resource resource = null;
-        DirContext context = null;
-        boolean exists = true;
-
-
-        // ----------------------------------------------------- Public Methods
-
-
-        public void recycle() {
-            timestamp = -1;
-            name = null;
-            attributes = null;
-            resource = null;
-            context = null;
-            exists = true;
+        synchronized (cache) {
+            return cache.unload(name);
         }
-
-
-        public String toString() {
-            return ("Cache entry: " + name + "\n"
-                    + "Exists: " + exists + "\n"
-                    + "Attributes: " + attributes + "\n"
-                    + "Resource: " + resource + "\n"
-                    + "Context: " + context);
-        }
-
-
     }
 
 

Modified: incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/ResourceAttributes.java
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/ResourceAttributes.java?view=diff&rev=123921&p1=incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/ResourceAttributes.java&r1=123920&p2=incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/ResourceAttributes.java&r2=123921
==============================================================================
--- incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/ResourceAttributes.java	(original)
+++ incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/ResourceAttributes.java	Sun Jan  2 17:29:34 2005
@@ -16,22 +16,24 @@
 
 package org.apache.naming.resources;
 
-import java.util.Vector;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Locale;
-import java.text.SimpleDateFormat;
-import java.text.ParseException;
-import javax.naming.NamingException;
+import java.util.TimeZone;
+import java.util.Vector;
+
 import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
 import javax.naming.directory.Attributes;
 import javax.naming.directory.BasicAttribute;
-import javax.naming.directory.Attribute;
 
 /**
  * Attributes implementation.
  * 
  * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
- * @version $Revision: 1.2 $
+ * @version $Revision: 1.5 $
  */
 public class ResourceAttributes implements Attributes {
     
@@ -137,12 +139,28 @@
      */
     protected static final SimpleDateFormat formats[] = {
         new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
-        new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US),
         new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
         new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US)
     };
     
     
+    protected final static TimeZone gmtZone = TimeZone.getTimeZone("GMT");
+
+
+    /**
+     * GMT timezone - all HTTP dates are on GMT
+     */
+    static {
+
+        format.setTimeZone(gmtZone);
+
+        formats[0].setTimeZone(gmtZone);
+        formats[1].setTimeZone(gmtZone);
+        formats[2].setTimeZone(gmtZone);
+
+    }
+
+
     // ----------------------------------------------------------- Constructors
     
     
@@ -199,6 +217,18 @@
      */
     protected Date lastModifiedDate = null;
 
+    
+    /**
+     * Last modified date in HTTP format.
+     */
+    protected String lastModifiedHttp = null;
+    
+
+    /**
+     * MIME type.
+     */
+    protected String mimeType = null;
+    
 
     /**
      * Name.
@@ -241,8 +271,8 @@
     
     /**
      * Set collection flag.
-     * 
-     * @return value of the collection flag
+     *
+     * @param collection New flag value
      */
     public void setCollection(boolean collection) {
         this.collection = collection;
@@ -552,6 +582,50 @@
             attributes.put(LAST_MODIFIED, lastModifiedDate);
     }
     
+    
+    /**
+     * @return Returns the lastModifiedHttp.
+     */
+    public String getLastModifiedHttp() {
+        if (lastModifiedHttp != null)
+            return lastModifiedHttp;
+        Date modifiedDate = getLastModifiedDate();
+        if (modifiedDate == null) {
+            modifiedDate = getCreationDate();
+        }
+        if (modifiedDate == null) {
+            modifiedDate = new Date();
+        }
+        synchronized (format) {
+            lastModifiedHttp = format.format(modifiedDate);
+        }
+        return lastModifiedHttp;
+    }
+    
+    
+    /**
+     * @param lastModifiedHttp The lastModifiedHttp to set.
+     */
+    public void setLastModifiedHttp(String lastModifiedHttp) {
+        this.lastModifiedHttp = lastModifiedHttp;
+    }
+    
+    
+    /**
+     * @return Returns the mimeType.
+     */
+    public String getMimeType() {
+        return mimeType;
+    }
+    
+    
+    /**
+     * @param mimeType The mimeType to set.
+     */
+    public void setMimeType(String mimeType) {
+        this.mimeType = mimeType;
+    }
+
     
     /**
      * Get name.

Added: incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/ResourceCache.java
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/ResourceCache.java?view=auto&rev=123921
==============================================================================
--- (empty file)
+++ incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/ResourceCache.java	Sun Jan  2 17:29:34 2005
@@ -0,0 +1,412 @@
+/*
+ * Copyright 1999,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */ 
+
+package org.apache.naming.resources;
+
+import java.util.HashMap;
+
+/**
+ * Implements a special purpose cache.
+ * 
+ * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
+ * @version $Revision: 1.3 $
+ */
+public class ResourceCache {
+    
+    
+    // ----------------------------------------------------------- Constructors
+    
+    
+    public ResourceCache() {
+    }
+    
+    
+    // ----------------------------------------------------- Instance Variables
+    
+    
+    /**
+     * Cache.
+     * Path -> Cache entry.
+     */
+    protected CacheEntry[] cache = new CacheEntry[0];
+
+
+    /**
+     * Not found cache.
+     */
+    protected HashMap notFoundCache = new HashMap();
+
+
+    /**
+     * Max size of resources which will have their content cached.
+     */
+    protected int cacheMaxSize = 10240; // 10 MB
+
+
+    /**
+     * Max amount of removals during a make space.
+     */
+    protected int maxAllocateIterations = 20;
+
+
+    /**
+     * Entry hit ratio at which an entry will never be removed from the cache.
+     * Compared with entry.access / hitsCount
+     */
+    protected long desiredEntryAccessRatio = 3;
+
+
+    /**
+     * Spare amount of not found entries.
+     */
+    protected int spareNotFoundEntries = 500;
+
+
+    /**
+     * Current cache size in KB.
+     */
+    protected int cacheSize = 0;
+
+
+    /**
+     * Number of accesses to the cache.
+     */
+    protected long accessCount = 0;
+
+
+    /**
+     * Number of cache hits.
+     */
+    protected long hitsCount = 0;
+
+
+    // ------------------------------------------------------------- Properties
+
+
+    /**
+     * Return the access count.
+     * Note: Update is not synced, so the number may not be completely 
+     * accurate.
+     */
+    public long getAccessCount() {
+        return accessCount;
+    }
+
+
+    /**
+     * Return the maximum size of the cache in KB.
+     */
+    public int getCacheMaxSize() {
+        return cacheMaxSize;
+    }
+
+
+    /**
+     * Set the maximum size of the cache in KB.
+     */
+    public void setCacheMaxSize(int cacheMaxSize) {
+        this.cacheMaxSize = cacheMaxSize;
+    }
+
+
+    /**
+     * Return the current cache size in KB.
+     */
+    public int getCacheSize() {
+        return cacheSize;
+    }
+
+
+    /**
+     * Return desired entry access ratio.
+     */
+    public long getDesiredEntryAccessRatio() {
+        return desiredEntryAccessRatio;
+    }
+
+
+    /**
+     * Set the desired entry access ratio.
+     */
+    public void setDesiredEntryAccessRatio(long desiredEntryAccessRatio) {
+        this.desiredEntryAccessRatio = desiredEntryAccessRatio;
+    }
+
+
+    /**
+     * Return the number of cache hits.
+     * Note: Update is not synced, so the number may not be completely 
+     * accurate.
+     */
+    public long getHitsCount() {
+        return hitsCount;
+    }
+
+
+    /**
+     * Return the maximum amount of iterations during a space allocation.
+     */
+    public int getMaxAllocateIterations() {
+        return maxAllocateIterations;
+    }
+
+
+    /**
+     * Set the maximum amount of iterations during a space allocation.
+     */
+    public void setMaxAllocateIterations(int maxAllocateIterations) {
+        this.maxAllocateIterations = maxAllocateIterations;
+    }
+
+
+    /**
+     * Return the amount of spare not found entries.
+     */
+    public int getSpareNotFoundEntries() {
+        return spareNotFoundEntries;
+    }
+
+
+    /**
+     * Set the amount of spare not found entries.
+     */
+    public void setSpareNotFoundEntries(int spareNotFoundEntries) {
+        this.spareNotFoundEntries = spareNotFoundEntries;
+    }
+
+
+    // --------------------------------------------------------- Public Methods
+
+
+    public boolean allocate(int space) {
+
+        int toFree = space - (cacheMaxSize - cacheSize);
+
+        if (toFree <= 0) {
+            return true;
+        }
+
+        // Increase the amount to free so that allocate won't have to run right
+        // away again
+        toFree += (cacheMaxSize / 20);
+
+        int size = notFoundCache.size();
+        if (size > spareNotFoundEntries) {
+            notFoundCache.clear();
+            cacheSize -= size;
+            toFree -= size;
+        }
+
+        if (toFree <= 0) {
+            return true;
+        }
+
+        int attempts = 0;
+        int entriesFound = 0;
+        long totalSpace = 0;
+        int[] toRemove = new int[maxAllocateIterations];
+        while (toFree > 0) {
+            if (attempts == maxAllocateIterations) {
+                // Give up, no changes are made to the current cache
+                return false;
+            }
+            if (toFree > 0) {
+                // Randomly select an entry in the array
+                int entryPos = -1;
+                boolean unique = false;
+                int count = 0;
+                while (!unique) {
+                    unique = true;
+                    entryPos = (int) Math.floor(Math.random() 
+                                                * (cache.length - 1));
+                    // Guarantee uniqueness
+                    for (int i = 0; i < entriesFound; i++) {
+                        if (toRemove[i] == entryPos) {
+                            unique = false;
+                        }
+                    }
+                }
+                long entryAccessRatio = 
+                    ((cache[entryPos].accessCount * 100) / accessCount);
+                if (entryAccessRatio < desiredEntryAccessRatio) {
+                    toRemove[entriesFound] = entryPos;
+                    totalSpace += cache[entryPos].size;
+                    toFree -= cache[entryPos].size;
+                    entriesFound++;
+                }
+            }
+            attempts++;
+        }
+
+        // Now remove the selected entries
+        java.util.Arrays.sort(toRemove, 0, entriesFound);
+        CacheEntry[] newCache = new CacheEntry[cache.length - entriesFound];
+        int pos = 0;
+        int n = -1;
+        if (entriesFound > 0) {
+            n = toRemove[0];
+            for (int i = 0; i < cache.length; i++) {
+                if (i == n) {
+                    if ((pos + 1) < entriesFound) {
+                        n = toRemove[pos + 1];
+                        pos++;
+                    } else {
+                        pos++;
+                        n = -1;
+                    }
+                } else {
+                    newCache[i - pos] = cache[i];
+                }
+            }
+        }
+        cache = newCache;
+        cacheSize -= totalSpace;
+
+        return true;
+
+    }
+
+
+    public CacheEntry lookup(String name) {
+
+        CacheEntry cacheEntry = null;
+        accessCount++;
+        int pos = find(cache, name);
+        if ((pos != -1) && (name.equals(cache[pos].name))) {
+            cacheEntry = cache[pos];
+        }
+        if (cacheEntry == null) {
+            try {
+                cacheEntry = (CacheEntry) notFoundCache.get(name);
+            } catch (Exception e) {
+                // Ignore: the reliability of this lookup is not critical
+            }
+        }
+        if (cacheEntry != null) {
+            hitsCount++;
+        }
+        return cacheEntry;
+
+    }
+
+
+    public void load(CacheEntry entry) {
+        if (entry.exists) {
+            insertCache(entry);
+        } else {
+            notFoundCache.put(entry.name, entry);
+        }
+        cacheSize += entry.size;
+    }
+
+
+    public boolean unload(String name) {
+        CacheEntry removedEntry = removeCache(name);
+        if (removedEntry != null) {
+            cacheSize -= removedEntry.size;
+            return true;
+        } else if (notFoundCache.remove(name) != null) {
+            cacheSize--;
+            return true;
+        }
+        return false;
+    }
+
+
+    /**
+     * Find a map elemnt given its name in a sorted array of map elements.
+     * This will return the index for the closest inferior or equal item in the
+     * given array.
+     */
+    private static final int find(CacheEntry[] map, String name) {
+
+        int a = 0;
+        int b = map.length - 1;
+
+        // Special cases: -1 and 0
+        if (b == -1) {
+            return -1;
+        }
+        if (name.compareTo(map[0].name) < 0) {
+            return -1;
+        }
+        if (b == 0) {
+            return 0;
+        }
+
+        int i = 0;
+        while (true) {
+            i = (b + a) / 2;
+            int result = name.compareTo(map[i].name);
+            if (result > 0) {
+                a = i;
+            } else if (result == 0) {
+                return i;
+            } else {
+                b = i;
+            }
+            if ((b - a) == 1) {
+                int result2 = name.compareTo(map[b].name);
+                if (result2 < 0) {
+                    return a;
+                } else {
+                    return b;
+                }
+            }
+        }
+
+    }
+
+
+    /**
+     * Insert into the right place in a sorted MapElement array, and prevent
+     * duplicates.
+     */
+    private final boolean insertCache(CacheEntry newElement) {
+        CacheEntry[] oldCache = cache;
+        int pos = find(oldCache, newElement.name);
+        if ((pos != -1) && (newElement.name.equals(oldCache[pos].name))) {
+            return false;
+        }
+        CacheEntry[] newCache = new CacheEntry[cache.length + 1];
+        System.arraycopy(oldCache, 0, newCache, 0, pos + 1);
+        newCache[pos + 1] = newElement;
+        System.arraycopy
+            (oldCache, pos + 1, newCache, pos + 2, oldCache.length - pos - 1);
+        cache = newCache;
+        return true;
+    }
+
+
+    /**
+     * Insert into the right place in a sorted MapElement array.
+     */
+    private final CacheEntry removeCache(String name) {
+        CacheEntry[] oldCache = cache;
+        int pos = find(oldCache, name);
+        if ((pos != -1) && (name.equals(oldCache[pos].name))) {
+            CacheEntry[] newCache = new CacheEntry[cache.length - 1];
+            System.arraycopy(oldCache, 0, newCache, 0, pos);
+            System.arraycopy(oldCache, pos + 1, newCache, pos, 
+                             oldCache.length - pos - 1);
+            cache = newCache;
+            return oldCache[pos];
+        }
+        return null;
+    }
+
+
+}

Modified: incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/WARDirContext.java
Url: http://svn.apache.org/viewcvs/incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/WARDirContext.java?view=diff&rev=123921&p1=incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/WARDirContext.java&r1=123920&p2=incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/WARDirContext.java&r2=123921
==============================================================================
--- incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/WARDirContext.java	(original)
+++ incubator/directory/naming/trunk/resources/src/java/org/apache/naming/resources/WARDirContext.java	Sun Jan  2 17:29:34 2005
@@ -17,40 +17,44 @@
 
 package org.apache.naming.resources;
 
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Hashtable;
-import java.util.Vector;
 import java.util.Date;
 import java.util.Enumeration;
-import java.io.File;
-import java.io.InputStream;
-import java.io.IOException;
+import java.util.Hashtable;
 import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
 import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+
+import javax.naming.CompositeName;
 import javax.naming.Name;
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
-import javax.naming.CompositeName;
 import javax.naming.OperationNotSupportedException;
-import javax.naming.directory.DirContext;
 import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
 import javax.naming.directory.ModificationItem;
 import javax.naming.directory.SearchControls;
-import org.apache.naming.NamingEntry;
+
 import org.apache.naming.NamingContextBindingsEnumeration;
 import org.apache.naming.NamingContextEnumeration;
+import org.apache.naming.NamingEntry;
 
 /**
  * WAR Directory Context implementation.
  *
  * @author Remy Maucherat
- * @version $Revision: 1.2 $ $Date: 2003/10/13 08:15:54 $
+ * @version $Revision: 1.7 $ $Date: 2004/09/16 23:19:54 $
  */
 
 public class WARDirContext extends BaseDirContext {
 
-
+    private static org.apache.commons.logging.Log log=
+        org.apache.commons.logging.LogFactory.getLog( WARDirContext.class );
+    
     // ----------------------------------------------------------- Constructors
 
 
@@ -123,7 +127,7 @@
 	// Validate that the document base is an existing directory
 	if (!base.exists() || !base.canRead() || base.isDirectory())
 	    throw new IllegalArgumentException
-		(sm.getString("warResources.notWar"));
+		(sm.getString("warResources.invalidWar", docBase));
         try {
             this.base = new ZipFile(base);
         } catch (Exception e) {
@@ -150,9 +154,8 @@
             try {
                 base.close();
             } catch (IOException e) {
-                System.out.println
-                    ("Exception closing WAR File " + base.getName());
-                e.printStackTrace(System.out);
+                log.warn
+                    ("Exception closing WAR File " + base.getName(), e);
             }
         }
         base = null;
@@ -275,12 +278,12 @@
     public NamingEnumeration list(Name name)
         throws NamingException {
         if (name.isEmpty())
-            return new NamingContextEnumeration(list(entries));
+            return new NamingContextEnumeration(list(entries).iterator());
         Entry entry = treeLookup(name);
         if (entry == null)
             throw new NamingException
                 (sm.getString("resources.notFound", name));
-        return new NamingContextEnumeration(list(entry));
+        return new NamingContextEnumeration(list(entry).iterator());
     }
 
 
@@ -319,12 +322,12 @@
     public NamingEnumeration listBindings(Name name)
         throws NamingException {
         if (name.isEmpty())
-            return new NamingContextBindingsEnumeration(list(entries));
+            return new NamingContextBindingsEnumeration(list(entries).iterator());
         Entry entry = treeLookup(name);
         if (entry == null)
             throw new NamingException
                 (sm.getString("resources.notFound", name));
-        return new NamingContextBindingsEnumeration(list(entry));
+        return new NamingContextBindingsEnumeration(list(entry).iterator());
     }
 
 
@@ -448,7 +451,7 @@
         if (!zipEntry.isDirectory())
             attrs.setResourceType("");
         attrs.setContentLength(zipEntry.getSize());
-        attrs.setLastModifiedDate(new Date(zipEntry.getTime()));
+        attrs.setLastModified(zipEntry.getTime());
         
         return attrs;
         
@@ -795,9 +798,9 @@
     /**
      * List children as objects.
      */
-    protected Vector list(Entry entry) {
+    protected ArrayList list(Entry entry) {
         
-        Vector entries = new Vector();
+        ArrayList entries = new ArrayList();
         Entry[] children = entry.getChildren();
         Arrays.sort(children);
         NamingEntry namingEntry = null;
@@ -812,7 +815,7 @@
             }
             namingEntry = new NamingEntry
                 (children[i].getName(), object, NamingEntry.ENTRY);
-            entries.addElement(namingEntry);
+            entries.add(namingEntry);
         }
         
         return entries;