You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by da...@apache.org on 2007/02/18 21:41:50 UTC

svn commit: r508986 - in /cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components: ./ src/main/java/org/apache/cocoon/servletservice/components/ src/main/resources/META-INF/cocoon/avalon/ src/main/resources/META-INF/cocoon/spring/

Author: danielf
Date: Sun Feb 18 12:41:49 2007
New Revision: 508986

URL: http://svn.apache.org/viewvc?view=rev&rev=508986
Log:
A LinkRewriterReader with configurations and configuration files for setting up the LinkRewriterTransformer for translating servlet sources to absolute paths. See https://issues.apache.org/jira/browse/COCOON-1997. Thanks to Grzegorz Kossakowski for the patches. I haven't done any serious testing yet.

Added:
    cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/java/org/apache/cocoon/servletservice/components/LinkRewriterReader.java   (with props)
    cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/avalon/
    cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/avalon/cocoon-servlet-complete-path-resolver.xconf   (with props)
    cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/avalon/cocoon-servlet-sitemapcomponents.xconf   (with props)
    cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/spring/cocoon-servlet-linkRewritingReader.xml   (with props)
Modified:
    cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/pom.xml

Modified: cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/pom.xml
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/pom.xml?view=diff&rev=508986&r1=508985&r2=508986
==============================================================================
--- cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/pom.xml (original)
+++ cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/pom.xml Sun Feb 18 12:41:49 2007
@@ -48,6 +48,11 @@
       <version>1.0.0-RC1-SNAPSHOT</version>
     </dependency>
     <dependency>
+      <groupId>org.apache.cocoon</groupId>
+      <artifactId>cocoon-linkrewriter-impl</artifactId>
+      <version>1.0.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
       <groupId>javax.servlet</groupId>
       <artifactId>servlet-api</artifactId>
       <version>2.4</version>

Added: cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/java/org/apache/cocoon/servletservice/components/LinkRewriterReader.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/java/org/apache/cocoon/servletservice/components/LinkRewriterReader.java?view=auto&rev=508986
==============================================================================
--- cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/java/org/apache/cocoon/servletservice/components/LinkRewriterReader.java (added)
+++ cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/java/org/apache/cocoon/servletservice/components/LinkRewriterReader.java Sun Feb 18 12:41:49 2007
@@ -0,0 +1,199 @@
+package org.apache.cocoon.servletservice.components;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.components.modules.input.InputModule;
+import org.apache.cocoon.components.source.util.SourceUtil;
+import org.apache.cocoon.environment.Context;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.Response;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.reading.AbstractReader;
+import org.apache.cocoon.util.avalon.CLLoggerWrapper;
+import org.apache.cocoon.util.location.LocationImpl;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceException;
+import org.xml.sax.SAXException;
+
+/**
+ * <p>LinkRewriterReader realizes servlet: link rewriting in text resources. It should be used especially for serving js files that have
+ * paths refering to other blocks (servlet: links).</p>
+ * <p><b>Configuration</b><br>
+ * <code>encoding</code> - see {@link #setEncoding}<br>
+ * <code>expires</code> - see {@link #setExpires}.
+ */
+public class LinkRewriterReader extends AbstractReader {
+
+    /** The default logger for this class. */
+    private Log logger = LogFactory.getLog(getClass());
+        
+    protected long configuredExpires = -1;
+    protected String configuredEncoding = "UTF-8";
+    
+    protected Response response;
+    protected Request request;
+    protected Source inputSource;
+    
+    protected InputModule inputModule;
+    
+    protected long expires;
+    protected String encoding;
+    
+    /**
+     * This parameter is optional. When specified it determines how long
+     * in miliseconds the resources can be cached by any proxy or browser
+     * between Cocoon and the requesting visitor. Defaults to -1.
+     *
+     * @param expires
+     */
+    public void setExpires(long expires) {
+        this.configuredExpires = expires;
+    }
+    
+    /**
+     * This parameter is optional. When specified it determines charset encoding
+     * of <b>input</b> files. This is needed for parsing working properly.
+     * Defaults to "UTF-8".
+     * @param encoding
+     */
+    public void setEncoding(String encoding) {
+        this.configuredEncoding = encoding;
+    }
+    
+    public void setInputModule(InputModule inputModule) {
+        this.inputModule = inputModule;
+    }
+    
+    public void init() {
+        this.enableLogging(new CLLoggerWrapper(this.logger));
+    }
+    
+    public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) throws ProcessingException, SAXException, IOException {
+        super.setup(resolver, objectModel, src, par);
+        
+        this.request = ObjectModelHelper.getRequest(objectModel);
+        this.response = ObjectModelHelper.getResponse(objectModel);
+        
+        this.expires = par.getParameterAsLong("expires", this.configuredExpires);
+        this.encoding = par.getParameter("encoding", this.configuredEncoding);
+        
+        try {
+            this.inputSource = resolver.resolveURI(src);
+        } catch (SourceException e) {
+            throw SourceUtil.handle("Error during resolving of '" + src + "'.", e);
+        }
+        
+        setupHeaders();
+    }
+    
+    protected void setupHeaders() {
+        response.setHeader("Accept-Ranges", "none");
+        if (expires > 0) {
+            response.setDateHeader("Expires", System.currentTimeMillis() + expires);
+        } else if (expires == 0) {
+            response.setDateHeader("Expires", 0);
+        }
+        
+        long lastModified = inputSource.getLastModified(); 
+        if (lastModified > 0)
+            response.setDateHeader("Last-Modified", lastModified);
+    }
+
+    public void generate() throws IOException, ProcessingException {
+        InputStream inputStream = this.inputSource.getInputStream();
+        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, encoding);
+        BufferedWriter outputWriter = new BufferedWriter(new OutputStreamWriter(out, encoding));
+        
+        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
+        
+        String line = bufferedReader.readLine();
+        int lineNumber = 1;
+        while (line != null) {
+            line = proccessLine(line, lineNumber);
+            outputWriter.write(line, 0, line.length());
+            outputWriter.newLine();
+            line = bufferedReader.readLine();
+            lineNumber++;
+        }
+        bufferedReader.close();
+        outputWriter.close();
+    }
+    
+    /**
+     * This class is just container for regexp URI pattern. This regexp bases on RFC2396.
+     * Actually it's stripped version of original definition. It suits well for the task - servlet: links rewriting.
+     */
+    protected static class URIregexp {
+        static final String scheme = "(?:[a-zA-Z](?:[a-zA-Z0-9]|\\+|-|\\.)*)";
+        static final String mark = "-|_|\\.|!|~|\\*|'|\\(|\\)";
+        static final String unreserved = "[a-zA-Z0-9]" + "|" + mark;
+        static final String escaped = "%[a-fA-F0-9]{2}";
+        static final String pChar = unreserved+"|"+escaped+"|:|@|&|=|\\+|\\$|,";
+        static final String pathSegment = "(?:"+pChar+")*(?:;(?:"+pChar+")*)*";
+        static final String absPath = "(?:/"+pathSegment+")+";
+        static final String reserved = ";|/|\\?|:|@|&|=|\\+|\\$|,";
+        static final String uric = reserved+"|"+unreserved+"|"+escaped; 
+        static final String hierPath = absPath+"(?:\\?(?:"+uric+")*)*";
+        static final String URIpattern = "servlet:((?:"+scheme+":)??"+hierPath+"(?:#(?:"+uric+")*)*)";
+        static final Pattern compiledURIpattern = Pattern.compile(URIpattern);
+    }
+    
+    protected String proccessLine(String line, int lineNumber) throws ProcessingException {
+        if (getLogger().isDebugEnabled())
+            getLogger().debug("Processing line: " + line);
+        
+        Matcher matcher = URIregexp.compiledURIpattern.matcher(line);
+        StringBuffer sb = new StringBuffer(line.length());
+        while (matcher.find()) {
+            if (getLogger().isDebugEnabled())
+                getLogger().debug("Processing link: " + matcher.group(0));
+            String link = matcher.group(1);
+            
+            Object replacement;
+            try {
+                replacement = inputModule.getAttribute(link, null, objectModel);
+            } catch (ConfigurationException e) {
+                throw ProcessingException.throwLocated("Failed to obtain attribute from input module", e, 
+                        new LocationImpl(null, inputSource.getURI(), lineNumber, matcher.start()));
+            }
+            
+            if (!(replacement instanceof String)) 
+                throw new ProcessingException("Attribute named '" + link + "' obtained from 'servlet' input module has to be String object.",
+                        new LocationImpl(null, inputSource.getURI(), lineNumber, matcher.start()));
+            
+            matcher.appendReplacement(sb, (String)replacement);
+        }
+        matcher.appendTail(sb);
+        return sb.toString();
+    }
+    
+    /**
+     * Returns the mime-type of the resource in process.
+     */
+    public String getMimeType() {
+        Context ctx = ObjectModelHelper.getContext(objectModel);
+        if (ctx != null) {
+            final String mimeType = ctx.getMimeType(source);
+            if (mimeType != null) {
+                return mimeType;
+            }
+        }
+
+        return inputSource.getMimeType();
+    }
+
+}

Propchange: cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/java/org/apache/cocoon/servletservice/components/LinkRewriterReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/java/org/apache/cocoon/servletservice/components/LinkRewriterReader.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/avalon/cocoon-servlet-complete-path-resolver.xconf
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/avalon/cocoon-servlet-complete-path-resolver.xconf?view=auto&rev=508986
==============================================================================
--- cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/avalon/cocoon-servlet-complete-path-resolver.xconf (added)
+++ cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/avalon/cocoon-servlet-complete-path-resolver.xconf Sun Feb 18 12:41:49 2007
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
+-->
+<components>
+
+  <input-modules>
+    <component-instance logger="core.modules.input" name="servlet" class="org.apache.cocoon.components.modules.input.StringConcatMetaModule">
+      <input-module name="constant">/blocks-test</input-module>
+      <input-module name="block-path"/>
+    </component-instance>
+  </input-modules>
+
+</components>

Propchange: cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/avalon/cocoon-servlet-complete-path-resolver.xconf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/avalon/cocoon-servlet-complete-path-resolver.xconf
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/avalon/cocoon-servlet-sitemapcomponents.xconf
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/avalon/cocoon-servlet-sitemapcomponents.xconf?view=auto&rev=508986
==============================================================================
--- cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/avalon/cocoon-servlet-sitemapcomponents.xconf (added)
+++ cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/avalon/cocoon-servlet-sitemapcomponents.xconf Sun Feb 18 12:41:49 2007
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
+-->
+
+<map:components xmlns:map="http://apache.org/cocoon/sitemap/1.0">
+
+ <map:transformers>
+   <map:transformer name="servletLinkRewriter" src="org.apache.cocoon.transformation.LinkRewriterTransformer">
+      <schemes>servlet</schemes>
+      <link-attrs>href src</link-attrs>
+      <input-module name="servlet"/>
+    </map:transformer>
+ </map:transformers>
+  
+</map:components>

Propchange: cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/avalon/cocoon-servlet-sitemapcomponents.xconf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/avalon/cocoon-servlet-sitemapcomponents.xconf
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/spring/cocoon-servlet-linkRewritingReader.xml
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/spring/cocoon-servlet-linkRewritingReader.xml?view=auto&rev=508986
==============================================================================
--- cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/spring/cocoon-servlet-linkRewritingReader.xml (added)
+++ cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/spring/cocoon-servlet-linkRewritingReader.xml Sun Feb 18 12:41:49 2007
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
+
+    <bean name="org.apache.cocoon.reading.Reader/servletLinkRewriter"
+          class="org.apache.cocoon.servletservice.components.LinkRewriterReader" init-method="init">
+        <property name="inputModule" ref="org.apache.cocoon.components.modules.input.InputModule/servlet"/>
+        <!-- Set character encoding of processed files. Defaults to "UTF-8" -->
+        <!-- <property name="encoding" value="UTF-8"/> -->
+        <!-- Set HTTP expires. Defaults t -1 -->
+        <!-- <property name="expires" value="-1" -->
+    </bean>
+
+</beans>

Propchange: cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/spring/cocoon-servlet-linkRewritingReader.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/core/cocoon-servlet-service/cocoon-servlet-service-components/src/main/resources/META-INF/cocoon/spring/cocoon-servlet-linkRewritingReader.xml
------------------------------------------------------------------------------
    svn:keywords = Id