cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ilgro...@apache.org
Subject svn commit: r1308780 - in /cocoon/cocoon3/trunk: cocoon-sample/src/main/resources/COB-INF/sitemap.xmap cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/SitemapBuilder.java cocoon-sitemap/src/main/resources/cocoon-sitemap-1.0.xsd
Date Tue, 03 Apr 2012 09:34:56 GMT
Author: ilgrosso
Date: Tue Apr  3 09:34:56 2012
New Revision: 1308780

URL: http://svn.apache.org/viewvc?rev=1308780&view=rev
Log:
[COCOON3-95] Applying and reworking a bit provided patch in order to handle sitemap XML validation
when controller: and servlet: namespaces are also present; cocoon-sitemap-1.0.xsd further
extended in order to deal with existing sitemap files

Modified:
    cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/sitemap.xmap
    cocoon/cocoon3/trunk/cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/SitemapBuilder.java
    cocoon/cocoon3/trunk/cocoon-sitemap/src/main/resources/cocoon-sitemap-1.0.xsd

Modified: cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/sitemap.xmap
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/sitemap.xmap?rev=1308780&r1=1308779&r2=1308780&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/sitemap.xmap (original)
+++ cocoon/cocoon3/trunk/cocoon-sample/src/main/resources/COB-INF/sitemap.xmap Tue Apr  3
09:34:56 2012
@@ -19,7 +19,7 @@
  -->
 <!-- $Id$ -->
 <map:sitemap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:map="http://apache.org/cocoon/sitemap"
-  xmlns:servlet="http://apache.org/cocoon/servlet" xmlns:controller="http://apache.org/cocoon/controller">
+             xmlns:servlet="http://apache.org/cocoon/servlet" xmlns:controller="http://apache.org/cocoon/controller">
 
   <map:pipelines>
     <!-- ~~~~~~~~~~~~~~~~ map:read ~~~~~~~~~~~~~~~ -->
@@ -45,7 +45,7 @@
       <map:match pattern="read/style.css">
         <map:read src="read/style.css"/>
       </map:match>
-      </map:pipeline>
+    </map:pipeline>
 
     <!-- ~~~~~~~~~~~~~~~~ sax pipelines ~~~~~~~~~~~~~~~ -->
     <map:pipeline jmx-group-name="sax">
@@ -386,13 +386,13 @@
       <map:match equals="linkrewriting/regexplinkrewriter-transformer">
         <map:generate src="linkrewriting/apache_home.html" />
         <map:transform type="regexplinkrewriter">
-            <map:parameter name="element1"
+          <map:parameter name="element1"
                            value="a href"/>
-            <map:parameter name="element2"
+          <map:parameter name="element2"
                            value="http://www.w3.org/1999/xhtml link * href"/>
-            <map:parameter name="regexp1"
+          <map:parameter name="regexp1"
                            value="^\./([\.]*) http://www.apache.org/$1"/>
-            <map:parameter name="regexp2"
+          <map:parameter name="regexp2"
                            value="^/([\.]*) http://www.apache.org/$1"/>
         </map:transform>
         <map:serialize type="xml" />
@@ -557,16 +557,16 @@
     <map:pipeline type="noncaching">
       <map:match wildcard="string-template/generator">
         <map:generate type="string-template" src="string-template/template.xml">
-	  <map:parameter name="parameter" value="A value"/>
-	  <map:parameter name="booleanParameter" value="{jexl:true}"/>
+          <map:parameter name="parameter" value="A value"/>
+          <map:parameter name="booleanParameter" value="{jexl:true}"/>
         </map:generate>
         <map:serialize/>
       </map:match>
       <map:match wildcard="string-template/transformer">
         <map:generate src="string-template/template.xml"/>
         <map:transform type="string-template">
-	  <map:parameter name="parameter" value="Another value"/>
-	  <map:parameter name="booleanParameter" value="{jexl:false}"/>
+          <map:parameter name="parameter" value="Another value"/>
+          <map:parameter name="booleanParameter" value="{jexl:false}"/>
         </map:transform>
         <map:serialize/>
       </map:match>

Modified: cocoon/cocoon3/trunk/cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/SitemapBuilder.java
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/SitemapBuilder.java?rev=1308780&r1=1308779&r2=1308780&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/SitemapBuilder.java
(original)
+++ cocoon/cocoon3/trunk/cocoon-sitemap/src/main/java/org/apache/cocoon/sitemap/SitemapBuilder.java
Tue Apr  3 09:34:56 2012
@@ -18,14 +18,21 @@
  */
 package org.apache.cocoon.sitemap;
 
+import java.io.File;
 import java.io.InputStream;
+import java.net.URISyntaxException;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
-
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
-
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.SchemaFactory;
+import org.apache.cocoon.sax.util.InMemoryLRUResourceCache;
+import org.apache.cocoon.sax.util.ValidityValue;
 import org.apache.cocoon.sitemap.node.SitemapNode;
 import org.apache.cocoon.sitemap.node.SitemapNodeFactory;
 import org.xml.sax.Attributes;
@@ -35,31 +42,88 @@ import org.xml.sax.helpers.DefaultHandle
 
 public class SitemapBuilder {
 
+    /**
+     * Store sitemap file validity.
+     */
+    private static final InMemoryLRUResourceCache<URL> URL_LRU_CACHE = new InMemoryLRUResourceCache<URL>();
+
     private SitemapNodeFactory sitemapNodeFactory;
 
     public SitemapNode build(URL sitemap) {
         if (sitemap == null) {
-            throw new NullPointerException("A valid sitemap URL has to be passed.");
+            throw new IllegalArgumentException("Null sitemap URL was passed");
         }
 
         SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
         saxParserFactory.setNamespaceAware(true);
-        // saxParserFactory.setSchema(SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema").newSchema());
+        enableValidation(sitemap, saxParserFactory);
 
-        SitemapHandler sitemapHandler = new SitemapHandler();
+        final SitemapHandler sitemapHandler = new SitemapHandler();
         try {
-            SAXParser saxParser = saxParserFactory.newSAXParser();
+            final SAXParser saxParser = saxParserFactory.newSAXParser();
 
-            InputStream inputStream = sitemap.openStream();
+            final InputStream inputStream = sitemap.openStream();
             saxParser.parse(inputStream, sitemapHandler);
             inputStream.close();
         } catch (Exception e) {
-            throw new SitemapBuilderException("Can't build sitemap.", e);
+            URL_LRU_CACHE.put(sitemap.toExternalForm(), new ValidityValue<URL>(sitemap,
-1));
+            throw new SitemapBuilderException("Can't build sitemap from " + sitemap.toExternalForm(),
e);
         }
 
         return sitemapHandler.getSitemap();
     }
 
+    /**
+     * Enable sitemap validation against the XSD schema.
+     *
+     * Use {@link InMemoryLRUResourceCache} to validate once until sitemap file changes.
+     *
+     * @param sitemap An {@link URL} with sitemap location.
+     * @param saxParserFactory {@link SAXParserFactory} to configure the schema.
+     */
+    protected void enableValidation(final URL sitemap, final SAXParserFactory saxParserFactory)
{
+        if ("file".equals(sitemap.getProtocol())) {
+            File sitemapFile;
+            try {
+                sitemapFile = new File(sitemap.toURI());
+            } catch (URISyntaxException e) {
+                throw new IllegalArgumentException("Invalid source specified: " + sitemap,
e);
+            }
+
+            if (URL_LRU_CACHE.containsKey(sitemap.toExternalForm())
+                    && URL_LRU_CACHE.get(sitemap.toExternalForm()).getLastModified()
>= sitemapFile.lastModified()) {
+
+                return;
+            }
+
+            final ValidityValue<URL> validity = new ValidityValue<URL>(sitemap,
sitemapFile.lastModified());
+            URL_LRU_CACHE.put(sitemap.toExternalForm(), validity);
+        }
+
+        final List<Source> xsdSources = new ArrayList<Source>();
+
+        // This XSD is mandatory
+        final InputStream sitemapSchema = this.getClass().getResourceAsStream("/cocoon-sitemap-1.0.xsd");
+        xsdSources.add(new StreamSource(sitemapSchema));
+
+        // These two might be present in classpath or not: if present, they will be included
for validation
+        final InputStream servletSchema = this.getClass().getResourceAsStream("/cocoon-servlet-1.0.xsd");
+        if (servletSchema != null) {
+            xsdSources.add(new StreamSource(servletSchema));
+        }
+        final InputStream controllerSchema = this.getClass().getResourceAsStream("/cocoon-controller-1.0.xsd");
+        if (controllerSchema != null) {
+            xsdSources.add(new StreamSource(controllerSchema));
+        }
+
+        try {
+            saxParserFactory.setSchema(SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema").
+                    newSchema(xsdSources.toArray(new Source[xsdSources.size()])));
+        } catch (SAXException e) {
+            throw new SitemapBuilderException("Unable to load the sitemap", e);
+        }
+    }
+
     public void setSitemapNodeFactory(SitemapNodeFactory sitemapNodeFactory) {
         this.sitemapNodeFactory = sitemapNodeFactory;
     }
@@ -80,6 +144,7 @@ public class SitemapBuilder {
     private class SitemapHandler extends DefaultHandler {
 
         private SitemapNode currentNode;
+
         private SitemapNode sitemap;
 
         @Override

Modified: cocoon/cocoon3/trunk/cocoon-sitemap/src/main/resources/cocoon-sitemap-1.0.xsd
URL: http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-sitemap/src/main/resources/cocoon-sitemap-1.0.xsd?rev=1308780&r1=1308779&r2=1308780&view=diff
==============================================================================
--- cocoon/cocoon3/trunk/cocoon-sitemap/src/main/resources/cocoon-sitemap-1.0.xsd (original)
+++ cocoon/cocoon3/trunk/cocoon-sitemap/src/main/resources/cocoon-sitemap-1.0.xsd Tue Apr
 3 09:34:56 2012
@@ -17,8 +17,8 @@
 -->
 <!-- $Id$ -->
 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://apache.org/cocoon/sitemap"
-  xmlns:tns="http://apache.org/cocoon/sitemap" xmlns="http://apache.org/cocoon/sitemap"
-  elementFormDefault="qualified">
+            xmlns:tns="http://apache.org/cocoon/sitemap" xmlns="http://apache.org/cocoon/sitemap"
+            elementFormDefault="qualified">
 
   <xsd:annotation>
     <xsd:documentation>Schema for the Cocoon 3 sitemap language.</xsd:documentation>
@@ -76,6 +76,20 @@
           </xsd:documentation>
         </xsd:annotation>
       </xsd:attribute>
+      <xsd:attribute name="expires" type="xsd:integer" use="optional">
+        <xsd:annotation>
+          <xsd:documentation>
+            Expires time in seconds.
+          </xsd:documentation>
+        </xsd:annotation>
+      </xsd:attribute>
+      <xsd:attribute name="expires-cache-key" type="xsd:string" use="optional">
+        <xsd:annotation>
+          <xsd:documentation>
+            Expires pipelines that have non-cacheable pipeline components require an explicit
cache key.
+          </xsd:documentation>
+        </xsd:annotation>
+      </xsd:attribute>
     </xsd:complexType>
   </xsd:element>
 
@@ -130,6 +144,11 @@
         </xsd:annotation>
       </xsd:attribute>
       <xsd:attributeGroup ref="expression-attrs" />
+      <xsd:attribute name="name" type="xsd:string" use="optional">
+        <xsd:annotation>
+          <xsd:documentation>Attribute for referencing named matchers.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:attribute>
     </xsd:complexType>
   </xsd:element>
   
@@ -241,6 +260,11 @@
           </xsd:documentation>
         </xsd:annotation>
       </xsd:attribute>
+      <xsd:attribute name="id" type="xsd:string" use="optional">
+        <xsd:annotation>
+          <xsd:documentation>Id of this generator (for profiling).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:attribute>
     </xsd:complexType>
   </xsd:element>
 
@@ -291,6 +315,31 @@
           </xsd:documentation>
         </xsd:annotation>
       </xsd:attribute>
+      <xsd:attribute name="id" type="xsd:string" use="optional">
+        <xsd:annotation>
+          <xsd:documentation>Id of this serializer (for profiling).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:attribute>
+      <xsd:attribute name="indent" type="xsd:integer" use="optional">
+        <xsd:annotation>
+          <xsd:documentation>Number of spaces per each indentation step.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:attribute>
+      <xsd:attribute name="doctype-default" type="xsd:string" use="optional">
+        <xsd:annotation>
+          <xsd:documentation>Doctype (for encoding serializers).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:attribute>
+      <xsd:attribute name="omitXmlDeclaration" type="xsd:string" use="optional">
+        <xsd:annotation>
+          <xsd:documentation>Whether to omit XML declaration.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:attribute>
+      <xsd:attribute name="encoding" type="xsd:string" use="optional">
+        <xsd:annotation>
+          <xsd:documentation>Encoding for serialization (for encoding serializers).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:attribute>
     </xsd:complexType>
   </xsd:element>
 
@@ -325,6 +374,11 @@
           <xsd:documentation>The mime-type of the pipeline result.</xsd:documentation>
         </xsd:annotation>
       </xsd:attribute>
+      <xsd:attribute name="base-path" type="xsd:string" use="optional">
+        <xsd:annotation>
+          <xsd:documentation>Base path (for usage with Wicket reader).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:attribute>
     </xsd:complexType>
   </xsd:element>
 



Mime
View raw message