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 00:15:25 UTC

svn commit: r396019 - in /cocoon/branches/BRANCH_2_1_X: ./ src/blocks/xsp/java/org/apache/cocoon/components/language/markup/ src/blocks/xsp/samples/ src/blocks/xsp/samples/java/ src/blocks/xsp/samples/logicsheets/

Author: anathaniel
Date: Fri Apr 21 15:15:23 2006
New Revision: 396019

URL: http://svn.apache.org/viewcvs?rev=396019&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/branches/BRANCH_2_1_X/src/blocks/xsp/samples/java/logicsheet2.xsp   (with props)
Modified:
    cocoon/branches/BRANCH_2_1_X/   (props changed)
    cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/java/org/apache/cocoon/components/language/markup/AbstractMarkupLanguage.java
    cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/java/org/apache/cocoon/components/language/markup/Logicsheet.java
    cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/java/logicsheet.xsp
    cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/logicsheets/hello.xsl
    cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/samples.xml
    cocoon/branches/BRANCH_2_1_X/status.xml

Propchange: cocoon/branches/BRANCH_2_1_X/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Fri Apr 21 15:15:23 2006
@@ -1,18 +1,20 @@
-build
-dist
-prj.el
-.project
-.classpath
-*.launch
-local.build.properties
-local.blocks.properties
-cocoon.sampledata
-.DS_Store
-*.ipr
-*.iws
-*.iml
-mount-table.xml
-tomcat
-tomcat.bat
-slide
+
+build
+dist
+prj.el
+.project
+.classpath
+*.launch
+local.build.properties
+local.blocks.properties
+cocoon.sampledata
+.DS_Store
+*.ipr
+*.iws
+*.iml
+mount-table.xml
+tomcat
+tomcat.bat
+slide
 local.blocks.*.xconf
+.settings

Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/java/org/apache/cocoon/components/language/markup/AbstractMarkupLanguage.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/java/org/apache/cocoon/components/language/markup/AbstractMarkupLanguage.java?rev=396019&r1=396018&r2=396019&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/java/org/apache/cocoon/components/language/markup/AbstractMarkupLanguage.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/java/org/apache/cocoon/components/language/markup/AbstractMarkupLanguage.java Fri Apr 21 15:15:23 2006
@@ -432,29 +432,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: "
@@ -474,7 +494,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/branches/BRANCH_2_1_X/src/blocks/xsp/java/org/apache/cocoon/components/language/markup/Logicsheet.java
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/java/org/apache/cocoon/components/language/markup/Logicsheet.java?rev=396019&r1=396018&r2=396019&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/java/org/apache/cocoon/components/language/markup/Logicsheet.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/java/org/apache/cocoon/components/language/markup/Logicsheet.java Fri Apr 21 15:15:23 2006
@@ -62,7 +62,7 @@
     /**
      * the template namespace's list
      */
-    protected Map namespaceURIs = new HashMap();
+    protected Map namespaceURIs = null;
 
     /**
      * The ServiceManager of this instance.
@@ -74,30 +74,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 );
-        }
     }
 
     /**
@@ -132,17 +116,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.
      *
@@ -160,6 +151,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/branches/BRANCH_2_1_X/src/blocks/xsp/samples/java/logicsheet.xsp
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/java/logicsheet.xsp?rev=396019&r1=396018&r2=396019&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/java/logicsheet.xsp (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/java/logicsheet.xsp Fri Apr 21 15:15:23 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/branches/BRANCH_2_1_X/src/blocks/xsp/samples/java/logicsheet2.xsp
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/java/logicsheet2.xsp?rev=396019&view=auto
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/java/logicsheet2.xsp (added)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/java/logicsheet2.xsp Fri Apr 21 15:15:23 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>

Propchange: cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/java/logicsheet2.xsp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/java/logicsheet2.xsp
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/logicsheets/hello.xsl
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/logicsheets/hello.xsl?rev=396019&r1=396018&r2=396019&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/logicsheets/hello.xsl (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/logicsheets/hello.xsl Fri Apr 21 15:15:23 2006
@@ -26,8 +26,13 @@
   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">
       <xsl:choose>

Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/samples.xml
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/samples.xml?rev=396019&r1=396018&r2=396019&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/samples.xml (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/xsp/samples/samples.xml Fri Apr 21 15:15:23 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/branches/BRANCH_2_1_X/status.xml
URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/status.xml?rev=396019&r1=396018&r2=396019&view=diff
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/status.xml (original)
+++ cocoon/branches/BRANCH_2_1_X/status.xml Fri Apr 21 15:15:23 2006
@@ -182,6 +182,16 @@
   <release version="@version@" date="@date@">
 -->
   <release version="2.1.10" date="TBD">
+    <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="CZ" type="fix">
       Template block: Make the template block usable with JDK 1.3+ and enable it by default.
     </action>