Author: markt
Date: Fri Oct 28 14:14:22 2011
New Revision: 1190339

URL: http://svn.apache.org/viewvc?rev=1190339&view=rev
Log:
Merge branch 'bug51744' into trunk

Modified:
    tomcat/trunk/java/org/apache/catalina/core/NamingContextListener.java
    tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
    tomcat/trunk/java/org/apache/naming/NamingContext.java
    tomcat/trunk/test/org/apache/naming/resources/TestNamingContext.java
    tomcat/trunk/webapps/docs/config/context.xml

Modified: tomcat/trunk/java/org/apache/catalina/core/NamingContextListener.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/NamingContextListener.java?rev=1190339&r1=1190338&r2=1190339&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/NamingContextListener.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/core/NamingContextListener.java Fri 
Oct 28 14:14:22 2011
@@ -141,6 +141,13 @@ public class NamingContextListener
 
 
     /**
+     * Determines if an attempt to write to a read-only context results in an
+     * exception or if the request is ignored.
+     */
+    private boolean exceptionOnFailedWrite = true;
+
+
+    /**
      * The string manager for this package.
      */
     protected static final StringManager sm =
@@ -149,6 +156,25 @@ public class NamingContextListener
 
     // ------------------------------------------------------------- Properties
 
+    /**
+     * Returns whether or not an attempt to modify the JNDI context will 
trigger
+     * an exception or if the request will be ignored.
+     */
+    public boolean getExceptionOnFailedWrite() {
+        return exceptionOnFailedWrite;
+    }
+
+
+    /**
+     * Controls whether or not an attempt to modify the JNDI context will
+     * trigger an exception or if the request will be ignored.
+     *
+     * @param exceptionOnFailedWrite    The new value
+     */
+    public void setExceptionOnFailedWrite(boolean exceptionOnFailedWrite) {
+        this.exceptionOnFailedWrite = exceptionOnFailedWrite;
+    }
+
 
     /**
      * Return the "name" property.
@@ -214,6 +240,10 @@ public class NamingContextListener
                 log.debug("Bound " + container );
             }
 
+            // Configure write when read-only behaviour
+            namingContext.setExceptionOnFailedWrite(
+                    getExceptionOnFailedWrite());
+
             // Setting the context in read/write mode
             ContextAccessController.setWritable(getName(), container);
 

Modified: tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardContext.java?rev=1190339&r1=1190338&r2=1190339&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/StandardContext.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/StandardContext.java Fri Oct 28 
14:14:22 2011
@@ -834,6 +834,7 @@ public class StandardContext extends Con
 
     private boolean sendRedirectBody = false;
 
+    private boolean jndiExceptionOnFailedWrite = true;
 
     // ----------------------------------------------------- Context Properties
 
@@ -2429,6 +2430,26 @@ public class StandardContext extends Con
 
     // ------------------------------------------------------ Public Properties
 
+    /**
+     * Returns whether or not an attempt to modify the JNDI context will 
trigger
+     * an exception or if the request will be ignored.
+     */
+    public boolean getJndiExceptionOnFailedWrite() {
+        return jndiExceptionOnFailedWrite;
+    }
+
+
+    /**
+     * Controls whether or not an attempt to modify the JNDI context will
+     * trigger an exception or if the request will be ignored.
+     *
+     * @param jndiExceptionOnFailedWrite
+     */
+    public void setJndiExceptionOnFailedWrite(
+            boolean jndiExceptionOnFailedWrite) {
+        this.jndiExceptionOnFailedWrite = jndiExceptionOnFailedWrite;
+    }
+
 
     /**
      * Return the Locale to character set mapper class for this Context.
@@ -4969,6 +4990,7 @@ public class StandardContext extends Con
             if (getNamingContextListener() == null) {
                 NamingContextListener ncl = new NamingContextListener();
                 ncl.setName(getNamingContextName());
+                ncl.setExceptionOnFailedWrite(getJndiExceptionOnFailedWrite());
                 addLifecycleListener(ncl);
                 setNamingContextListener(ncl);
             }

Modified: tomcat/trunk/java/org/apache/naming/NamingContext.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/naming/NamingContext.java?rev=1190339&r1=1190338&r2=1190339&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/naming/NamingContext.java (original)
+++ tomcat/trunk/java/org/apache/naming/NamingContext.java Fri Oct 28 14:14:22 
2011
@@ -123,12 +123,21 @@ public class NamingContext implements Co
     protected String name;
 
 
-    // --------------------------------------------------------- Public Methods
+    /**
+     * Determines if an attempt to write to a read-only context results in an
+     * exception or if the request is ignored.
+     */
+    private boolean exceptionOnFailedWrite = true;
+    public boolean getExceptionOnFailedWrite() {
+        return exceptionOnFailedWrite;
+    }
+    public void setExceptionOnFailedWrite(boolean exceptionOnFailedWrite) {
+        this.exceptionOnFailedWrite = exceptionOnFailedWrite;
+    }
 
 
     // -------------------------------------------------------- Context Methods
 
-
     /**
      * Retrieves the named object. If name is empty, returns a new instance
      * of this context (which represents the same naming context as this
@@ -249,9 +258,11 @@ public class NamingContext implements Co
      * @exception NamingException if a naming exception is encountered
      */
     @Override
-    public void unbind(Name name)
-        throws NamingException {
-        checkWritable();
+    public void unbind(Name name) throws NamingException {
+
+        if (!checkWritable()) {
+            return;
+        }
 
         while ((!name.isEmpty()) && (name.get(0).length() == 0))
             name = name.getSuffix(1);
@@ -465,10 +476,11 @@ public class NamingContext implements Co
      * a context, or does not name a context of the appropriate type
      */
     @Override
-    public void destroySubcontext(Name name)
-        throws NamingException {
+    public void destroySubcontext(Name name) throws NamingException {
 
-        checkWritable();
+        if (!checkWritable()) {
+            return;
+        }
 
         while ((!name.isEmpty()) && (name.get(0).length() == 0))
             name = name.getSuffix(1);
@@ -533,13 +545,16 @@ public class NamingContext implements Co
      * @exception NamingException if a naming exception is encountered
      */
     @Override
-    public Context createSubcontext(Name name)
-        throws NamingException {
-        checkWritable();
+    public Context createSubcontext(Name name) throws NamingException {
+        if (!checkWritable()) {
+            return null;
+        }
 
-        Context newContext = new NamingContext(env, this.name);
+        NamingContext newContext = new NamingContext(env, this.name);
         bind(name, newContext);
 
+        newContext.setExceptionOnFailedWrite(getExceptionOnFailedWrite());
+
         return newContext;
     }
 
@@ -744,7 +759,9 @@ public class NamingContext implements Co
      */
     @Override
     public void close() throws NamingException {
-        checkWritable();
+        if (!checkWritable()) {
+            return;
+        }
         env.clear();
     }
 
@@ -866,7 +883,9 @@ public class NamingContext implements Co
     protected void bind(Name name, Object obj, boolean rebind)
         throws NamingException {
 
-        checkWritable();
+        if (!checkWritable()) {
+            return;
+        }
 
         while ((!name.isEmpty()) && (name.get(0).length() == 0))
             name = name.getSuffix(1);
@@ -935,12 +954,16 @@ public class NamingContext implements Co
     /**
      * Throws a naming exception is Context is not writable.
      */
-    protected void checkWritable()
-        throws NamingException {
-        if (!isWritable())
-            throw new NamingException(sm.getString("namingContext.readOnly"));
+    protected boolean checkWritable() throws NamingException {
+        if (isWritable()) {
+            return true;
+        } else {
+            if (exceptionOnFailedWrite) {
+                throw new javax.naming.OperationNotSupportedException(
+                        sm.getString("namingContext.readOnly"));
+            }
+        }
+        return false;
     }
-
-
 }
 

Modified: tomcat/trunk/test/org/apache/naming/resources/TestNamingContext.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/naming/resources/TestNamingContext.java?rev=1190339&r1=1190338&r2=1190339&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/naming/resources/TestNamingContext.java 
(original)
+++ tomcat/trunk/test/org/apache/naming/resources/TestNamingContext.java Fri 
Oct 28 14:14:22 2011
@@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletReq
 import javax.servlet.http.HttpServletResponse;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import org.junit.Test;
 
@@ -215,7 +216,17 @@ public class TestNamingContext extends T
     }
 
     @Test
-    public void testBug51744() throws Exception {
+    public void testBug51744a() throws Exception {
+        doTestBug51744(true);
+    }
+
+    @Test
+    public void testBug51744b() throws Exception {
+        doTestBug51744(false);
+    }
+
+    private void doTestBug51744(boolean exceptionOnFailedWrite)
+            throws Exception {
         Tomcat tomcat = getTomcatInstance();
         tomcat.enableNaming();
 
@@ -223,6 +234,8 @@ public class TestNamingContext extends T
         StandardContext ctx = (StandardContext)
             tomcat.addContext("", System.getProperty("java.io.tmpdir"));
 
+        ctx.setJndiExceptionOnFailedWrite(exceptionOnFailedWrite);
+
         // Map the test Servlet
         Bug51744Servlet bug51744Servlet = new Bug51744Servlet();
         Tomcat.addServlet(ctx, "bug51744Servlet", bug51744Servlet);
@@ -233,7 +246,10 @@ public class TestNamingContext extends T
         ByteChunk bc = new ByteChunk();
         int rc = getUrl("http://localhost:"; + getPort() + "/", bc, null);
         assertEquals(200, rc);
-        assertEquals(Bug51744Servlet.EXPECTED, bc.toString());
+        assertTrue(bc.toString().contains(Bug51744Servlet.EXPECTED));
+        if (exceptionOnFailedWrite) {
+            assertTrue(bc.toString().contains(Bug51744Servlet.ERROR_MESSAGE));
+        }
     }
 
     public static final class Bug51744Servlet extends HttpServlet {
@@ -241,6 +257,7 @@ public class TestNamingContext extends T
         private static final long serialVersionUID = 1L;
 
         public static final String EXPECTED = "TestValue";
+        public static final String ERROR_MESSAGE = "Error";
 
         @Override
         protected void doGet(HttpServletRequest req, HttpServletResponse resp)
@@ -254,18 +271,13 @@ public class TestNamingContext extends T
                 Context env1 = (Context) ctx1.lookup("java:comp/env");
                 env1.addToEnvironment("TestName", EXPECTED);
 
-                boolean error = false;
+                out.print(env1.getEnvironment().get("TestName"));
+
                 try {
                     env1.close();
                 } catch (NamingException ne) {
-                    error = true;
+                    out.print(ERROR_MESSAGE);
                 }
-                if (!error) {
-                    throw new ServletException(
-                            "No error when one was expected");
-                }
-
-                out.print(env1.getEnvironment().get("TestName"));
             } catch (NamingException ne) {
                 ne.printStackTrace(out);
             }

Modified: tomcat/trunk/webapps/docs/config/context.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/context.xml?rev=1190339&r1=1190338&r2=1190339&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/context.xml (original)
+++ tomcat/trunk/webapps/docs/config/context.xml Fri Oct 28 14:14:22 2011
@@ -657,6 +657,19 @@
         not specified, the default value of <code>false</code> will be 
used.</p>
       </attribute>
 
+      <attribute name="jndiExceptionOnFailedWrite" required="false">
+        <p>If <code>true</code>, any attempt by an application to modify the
+        provided JNDI context with a call to bind(), unbind(),
+        createSubContext(), destroySubContext() or close() will trigger a
+        <code>javax.naming.OperationNotSupportedException</code> as required by
+        section EE.5.3.4 of the Java EE specification. This exception can be
+        disabled by setting this attribute to true in which case any calls to
+        modify the JNDI context will return <b>without</b> making any changes
+        and methods that return values will return <code>null</code>. If not
+        specified, the specification compliant default of <code>true</code> 
will
+        be used.</p>
+      </attribute>
+
       <attribute name="processTlds" required="false">
         <p>Whether the context should process TLDs on startup.  The default
         is true.  The false setting is intended for special cases



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to