You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by an...@apache.org on 2006/04/22 01:10:44 UTC

svn commit: r396031 - in /cocoon/trunk: ./ blocks/cocoon-xsp/cocoon-xsp-impl/ blocks/cocoon-xsp/cocoon-xsp-impl/src/main/java/org/apache/cocoon/components/language/markup/ blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/ blocks/cocoon-xs...

Author: anathaniel
Date: Fri Apr 21 16:10:42 2006
New Revision: 396031

URL: http://svn.apache.org/viewcvs?rev=396031&view=rev
Log:
XSP block: Fix regression introduced in 2.1.8 that under specific circumstances logicsheets
were not applied, leading to compilation errors.  This manifested itself only if
a) two XSPs referred to the same custom logicsheet by a relative location path,
b) the custom logicsheet used another logicsheet, and
c) the built-in logicsheet's namespace was not mentioned in xsp:page.
The compilation errors occurred always when calling the second XSP for the first time.
Fix also race condition which could lead to similar XSP compilation errors under high load
when accessing the same logicsheet for the first time.

Added:
    cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/java/logicsheet2.xsp
Modified:
    cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-impl/src/main/java/org/apache/cocoon/components/language/markup/AbstractMarkupLanguage.java
    cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-impl/src/main/java/org/apache/cocoon/components/language/markup/Logicsheet.java
    cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-impl/status.xml
    cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/java/logicsheet.xsp
    cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/logicsheets/hello.xsl
    cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/samples.xml
    cocoon/trunk/commons/status.xml
    cocoon/trunk/pom.xml

Modified: cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-impl/src/main/java/org/apache/cocoon/components/language/markup/AbstractMarkupLanguage.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-impl/src/main/java/org/apache/cocoon/components/language/markup/AbstractMarkupLanguage.java?rev=396031&r1=396030&r2=396031&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-impl/src/main/java/org/apache/cocoon/components/language/markup/AbstractMarkupLanguage.java (original)
+++ cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-impl/src/main/java/org/apache/cocoon/components/language/markup/AbstractMarkupLanguage.java Fri Apr 21 16:10:42 2006
@@ -429,29 +429,49 @@
                                        String logicsheetLocation)
         throws IOException, SAXException, ProcessingException
     {
-        Logicsheet logicsheet = (Logicsheet)logicsheetCache.get(CACHE_PREFIX + logicsheetLocation);
-        if (logicsheet == null) {
-            Source inputSource = null;
-            try {
-                // Logicsheet is reusable (across multiple XSPs) object,
-                // and it is resolved via urlResolver, and not via per-request
-                // temporary resolver.
-                inputSource = this.resolver.resolveURI(logicsheetLocation);
+        Source inputSource = null;
+        String logicsheetName;
+        try {
+            // Logicsheet is reusable (across multiple XSPs) object,
+            // and it is resolved via urlResolver, and not via per-request
+            // temporary resolver.
+            // Resolve logicsheet location relative to sitemap from where it is used.
+            inputSource = this.resolver.resolveURI(logicsheetLocation);
+            logicsheetName = inputSource.getURI();
+        } catch (SourceException se) {
+            throw SourceUtil.handle(se);
+        } finally {
+            this.resolver.release( inputSource );
+        }
 
+        // Logicsheets are chained by looking at the namespaces on the xsl:stylesheet
+        // root node.  To get at these namespaces, the stylesheet must be parsed.
+        // Stylesheets are cached that we have only one chance to fill the namespaces.
+        // To avoid a race condition, we have to lock the critical section.
+        // For maximum concurrency we lock the cache, store if necessary the new,
+        // unparsed logicsheet, and then lock the logicsheet for the long-running
+        // parse operation.
+        
+        Logicsheet logicsheet;
+        synchronized (logicsheetCache) {
+            String cacheKey = CACHE_PREFIX + logicsheetName;
+            logicsheet = (Logicsheet)logicsheetCache.get(cacheKey);
+            if (logicsheet == null) {
                 // Resolver (local) could not be used as it is temporary
                 // (per-request) object, yet Logicsheet is being cached and reused
                 // across multiple requests. "Global" url-factory-based resolver
                 // passed to the Logicsheet.
-                logicsheet = new Logicsheet(inputSource, manager,
+                logicsheet = new Logicsheet(logicsheetName, manager,
                                             resolver, getLogicsheetFilter());
-                logicsheetCache.store(CACHE_PREFIX + logicsheet.getSystemId(), logicsheet);
-            } catch (SourceException se) {
-                throw SourceUtil.handle(se);
-            } finally {
-                this.resolver.release( inputSource );
+                logicsheetCache.store(cacheKey, logicsheet);
             }
         }
-        String logicsheetName = logicsheet.getSystemId();
+        
+        synchronized (logicsheet) {
+            Map namespaces = logicsheet.getNamespaceURIs();
+            if (namespaces == null)
+                logicsheet.fillNamespaceURIs();
+        }
 
         if (getLogger().isDebugEnabled()) {
             getLogger().debug("addLogicsheetToList: "
@@ -471,7 +491,7 @@
 
         Map namespaces = logicsheet.getNamespaceURIs();
         if(!logicsheetLocation.equals(language.getLogicsheet())) {
-            if(namespaces != null && namespaces.size() > 0) {
+            if(namespaces.size() > 0) {
                 Iterator iter = namespaces.keySet().iterator();
                 while(iter.hasNext()) {
                     String namespace = (String) iter.next();

Modified: cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-impl/src/main/java/org/apache/cocoon/components/language/markup/Logicsheet.java
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-impl/src/main/java/org/apache/cocoon/components/language/markup/Logicsheet.java?rev=396031&r1=396030&r2=396031&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-impl/src/main/java/org/apache/cocoon/components/language/markup/Logicsheet.java (original)
+++ cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-impl/src/main/java/org/apache/cocoon/components/language/markup/Logicsheet.java Fri Apr 21 16:10:42 2006
@@ -59,7 +59,7 @@
     /**
      * the template namespace's list
      */
-    protected Map namespaceURIs = new HashMap();
+    protected Map namespaceURIs = null;
 
     /**
      * The ServiceManager of this instance.
@@ -71,30 +71,14 @@
      */
     private LogicsheetFilter filter;
 
-    public Logicsheet(Source source, ServiceManager manager,
-                      SourceResolver resolver, LogicsheetFilter filter)
-        throws SAXException, IOException, ProcessingException
-    {
-        this.resolver = resolver;
-        this.systemId = source.getURI();
-        this.manager = manager;
-        this.filter = filter;
-    }
-
     public Logicsheet(String systemId, ServiceManager manager,
                       SourceResolver resolver, LogicsheetFilter filter)
         throws SAXException, IOException, SourceException, ProcessingException
     {
-        this.resolver = resolver;
+        this.systemId = systemId;
         this.manager = manager;
+        this.resolver = resolver;
         this.filter = filter;
-        Source source = null;
-        try {
-            source = this.resolver.resolveURI( systemId );
-            this.systemId = source.getURI();
-        } finally {
-            this.resolver.release( source );
-        }
     }
 
     /**
@@ -129,17 +113,24 @@
     }
 
     /**
-     * This will return the list of namespaces in this logicsheet.
+     * This will return the list of namespaces in this logicsheet,
+     * or null, if fillNamespaceURIs has not been called yet.
      */
-    public Map getNamespaceURIs() throws ProcessingException
+    public Map getNamespaceURIs()
     {
-        // Force the parsing of the Source or, if nothing changed,
-        // return the old content of namespaces.
-        getTransformerHandler();
         return namespaceURIs;
     }
 
     /**
+     * Fill the list of namespaces in this logicsheet.
+     */
+    public void fillNamespaceURIs() throws ProcessingException
+    {
+        // Force the parsing of the Source which fills namespaceURIs.
+        getTransformerHandler();
+    }
+
+    /**
      * Obtain the TransformerHandler object that will perform the
      * transformation associated with this logicsheet.
      *
@@ -157,6 +148,8 @@
             // getTransformerHandler() of XSLTProcessor will simply return
             // the old template object. If the Source is unchanged, the
             // namespaces are not modified either.
+            if (namespaceURIs == null)
+                namespaceURIs = new HashMap();
             filter.setNamespaceMap(namespaceURIs);
             return xsltProcessor.getTransformerHandler(source, filter);
 

Modified: cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-impl/status.xml
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-impl/status.xml?rev=396031&r1=396030&r2=396031&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-impl/status.xml (original)
+++ cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-impl/status.xml Fri Apr 21 16:10:42 2006
@@ -66,6 +66,21 @@
  <changes>
   <release version="@version@" date="@date@">
     <action dev="AN" type="fix">
+      XSP block: Fix regression introduced in 2.1.8 that under specific circumstances logicsheets
+      were not applied, leading to compilation errors.  This manifested itself only if
+      a) two XSPs referred to the same custom logicsheet by a relative location path,
+      b) the custom logicsheet used another logicsheet, and
+      c) the built-in logicsheet's namespace was not mentioned in xsp:page.
+      The compilation errors occurred always when calling the second XSP for the first time.
+      Fix also race condition which could lead to similar XSP compilation errors under high load
+      when accessing the same logicsheet for the first time.
+    </action>
+    <action dev="AN" type="add">
+      XSP block: Use private methods to call start/endElement in xsp.xsl.
+      That generates smaller bytecode allowing to compiler larger XSPs before hitting the
+      64k limit for the size of the generate() method.
+    </action>
+    <action dev="AN" type="fix">
       XSP block: Reintroduce locally scoped xspAttr in xsp.xsl to improve backwards compatibility for pre-2.1.9
       logicsheets.  (Suggestion by Vadim Gritsenko).
     </action>

Modified: cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/java/logicsheet.xsp
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/java/logicsheet.xsp?rev=396031&r1=396030&r2=396031&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/java/logicsheet.xsp (original)
+++ cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/java/logicsheet.xsp Fri Apr 21 16:10:42 2006
@@ -15,7 +15,7 @@
   limitations under the License.
 -->
 
-<!-- CVS $Id: logicsheet.xsp,v 1.2 2004/04/05 12:25:30 antonio Exp $ -->
+<!-- CVS $Id$ -->
 
 <!-- XSP can be assotiated with the logicsheet using processing
      instruction xml-logicsheet or the xsp:logicsheet element.
@@ -27,7 +27,6 @@
 
 <xsp:page language="java"
           xmlns:xsp="http://apache.org/xsp"
-          xmlns:xsp-request="http://apache.org/xsp/request/2.0"
           xmlns:xsp-hello="http://apache.org/xsp/hello/1.0">
 
   <xsp:logicsheet location="logicsheets/hello.xsl"/>
@@ -44,7 +43,7 @@
     <title>Greetings Page</title>
     <content>
       <xsp:logic>
-        String name = <xsp-request:get-parameter name="name"/>;
+        String name = <xsp-hello:get-name/>;
         if (name == null) {
           <para>
             <!-- Print default greeting -->

Added: cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/java/logicsheet2.xsp
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/java/logicsheet2.xsp?rev=396031&view=auto
==============================================================================
--- cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/java/logicsheet2.xsp (added)
+++ cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/java/logicsheet2.xsp Fri Apr 21 16:10:42 2006
@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2006 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.
+-->
+
+<!-- CVS $Id$ -->
+
+<!-- Testcase for caching bug in 2.1.9:  same logicsheet used by different XSPs
+     and logicsheet call another logicsheet (here xsp-request) whose namespace
+     does not appear in the XSPs.
+-->
+
+<xsp:page language="java"
+          xmlns:xsp="http://apache.org/xsp"
+          xmlns:xsp-hello="http://apache.org/xsp/hello/1.0">
+
+  <xsp:logicsheet location="logicsheets/hello.xsl"/>
+
+  <page>
+    <title>Greetings Page</title>
+    <content>
+      <xsp:logic>
+        String name = <xsp-hello:get-name/>;
+        if (name == null) {
+          <para>
+            <!-- Print default greeting -->
+            <xsp-hello:greeting name="Unknown"/>
+            <form action="logicsheet">
+              Please enter your name: <input name="name"/> <input type="submit"/>
+            </form>
+          </para>
+        } else {
+          <para>
+            <!-- Override default greeting -->
+            <xsp-hello:greeting value="Welcome to this small logicsheet sample">
+              <!-- Alternate way of specifying name attribute -->
+              <xsp-hello:name><xsp:expr>name</xsp:expr></xsp-hello:name>
+            </xsp-hello:greeting>
+          </para>
+
+          <para>
+            This greeting above was created using simple logicsheet.
+          </para>
+        }
+      </xsp:logic>
+    </content>
+  </page>
+</xsp:page>

Modified: cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/logicsheets/hello.xsl
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/logicsheets/hello.xsl?rev=396031&r1=396030&r2=396031&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/logicsheets/hello.xsl (original)
+++ cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/logicsheets/hello.xsl Fri Apr 21 16:10:42 2006
@@ -25,7 +25,12 @@
   version="1.0"
   xmlns:xsp="http://apache.org/xsp"
   xmlns:xsp-hello="http://apache.org/xsp/hello/1.0"
+  xmlns:xsp-request="http://apache.org/xsp/request/2.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+  <xsl:template match="xsp-hello:get-name">
+    <xsp-request:get-parameter name="name"/>
+  </xsl:template>
 
   <xsl:template match="xsp-hello:greeting">
     <xsl:variable name="name">

Modified: cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/samples.xml
URL: http://svn.apache.org/viewcvs/cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/samples.xml?rev=396031&r1=396030&r2=396031&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/samples.xml (original)
+++ cocoon/trunk/blocks/cocoon-xsp/cocoon-xsp-sample/src/main/resources/COB-INF/samples.xml Fri Apr 21 16:10:42 2006
@@ -31,6 +31,9 @@
    <sample name="Logicsheet" href="java/logicsheet">
     Greetings page with logic separated into logicsheet.
    </sample>
+   <sample name="Logicsheet2" href="java/logicsheet2">
+    Different XSP using same logicsheet.
+   </sample>
    <sample name="Cacheable" href="java/cacheable">
     Cacheable XSP page.
    </sample>

Modified: cocoon/trunk/commons/status.xml
URL: http://svn.apache.org/viewcvs/cocoon/trunk/commons/status.xml?rev=396031&r1=396030&r2=396031&view=diff
==============================================================================
--- cocoon/trunk/commons/status.xml (original)
+++ cocoon/trunk/commons/status.xml Fri Apr 21 16:10:42 2006
@@ -176,11 +176,6 @@
   <!-- These are the changes from the last 2.1.x version. -->
  <changes>
   <release version="@version@" date="@date@">
-    <action dev="AN" type="add">
-      XSP block: Use private methods to call start/endElement in xsp.xsl.
-      That generates smaller bytecode allowing to compiler larger XSPs before hitting the
-      64k limit for the size of the generate() method.
-    </action>
     <action dev="CZ" type="update">
       Removed obsolete support for JCS.
     </action>

Modified: cocoon/trunk/pom.xml
URL: http://svn.apache.org/viewcvs/cocoon/trunk/pom.xml?rev=396031&r1=396030&r2=396031&view=diff
==============================================================================
--- cocoon/trunk/pom.xml (original)
+++ cocoon/trunk/pom.xml Fri Apr 21 16:10:42 2006
@@ -157,6 +157,17 @@
       <timezone>+1</timezone>
     </developer>
     <developer>
+      <id>anathaniel</id>
+      <name>Alfred Nathaniel</name>
+      <email>anathaniel@apache.org</email>
+      <organization>ASF</organization>
+      <organizationUrl>http://www.apache.org</organizationUrl>
+      <roles>
+        <role>Committer</role>
+      </roles>
+      <timezone>+1</timezone>
+    </developer>
+    <developer>
       <id>giacomo</id>
       <name>Giacomo Pati</name>
       <email>giacomo@apache.org</email>