You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2008/02/26 11:28:40 UTC

svn commit: r631164 - in /incubator/sling/trunk/sling/servlets-default: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/sling/ src/main/java/org/apache/sling/servlets/ src/main/resources/ src/main/...

Author: fmeschbe
Date: Tue Feb 26 02:28:36 2008
New Revision: 631164

URL: http://svn.apache.org/viewvc?rev=631164&view=rev
Log:
SLING-268 Add former launchpad servlets to new servlets-default project

Added:
    incubator/sling/trunk/sling/servlets-default/pom.xml   (with props)
    incubator/sling/trunk/sling/servlets-default/src/
    incubator/sling/trunk/sling/servlets-default/src/main/
    incubator/sling/trunk/sling/servlets-default/src/main/java/
    incubator/sling/trunk/sling/servlets-default/src/main/java/org/
    incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/
    incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/
    incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/
    incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/DefaultHtmlRenderer.java   (with props)
    incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/DefaultHtmlRendererServlet.java   (with props)
    incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/JsonRendererServlet.java   (with props)
    incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/PlainTextRendererServlet.java   (with props)
    incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/RedirectServlet.java   (with props)
    incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/StreamRendererServlet.java   (with props)
    incubator/sling/trunk/sling/servlets-default/src/main/resources/
    incubator/sling/trunk/sling/servlets-default/src/main/resources/SLING-INF/
    incubator/sling/trunk/sling/servlets-default/src/main/resources/SLING-INF/nodetypes/
    incubator/sling/trunk/sling/servlets-default/src/main/resources/SLING-INF/nodetypes/redirect.cnd   (with props)
    incubator/sling/trunk/sling/servlets-default/src/test/
    incubator/sling/trunk/sling/servlets-default/src/test/java/
    incubator/sling/trunk/sling/servlets-default/src/test/java/org/
    incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/
    incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/
    incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/servlets/
    incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/servlets/MockRequestPathInfo.java   (with props)
    incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/servlets/MockSlingHttpServletRequest.java   (with props)
    incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/servlets/RedirectServletTest.java   (with props)

Added: incubator/sling/trunk/sling/servlets-default/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlets-default/pom.xml?rev=631164&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlets-default/pom.xml (added)
+++ incubator/sling/trunk/sling/servlets-default/pom.xml Tue Feb 26 02:28:36 2008
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>1-incubator-SNAPSHOT</version>
+        <relativePath>../../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.sling.servlets.default</artifactId>
+    <packaging>bundle</packaging>
+    <version>2.0.0-incubator-SNAPSHOT</version>
+
+    <name>Sling Default GET Servlets</name>
+    <description>
+        Provides default GET servlets for HTML, Text and JSON rendering
+        and streaming resources.
+    </description>
+
+    <scm>
+        <connection>
+            scm:svn:http://svn.apache.org/repos/asf/incubator/sling/trunk/sling/servlets-default
+        </connection>
+        <developerConnection>
+            scm:svn:https://svn.apache.org/repos/asf/incubator/sling/trunk/sling/servlets-default
+        </developerConnection>
+        <url>
+            http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlets-default
+        </url>
+    </scm>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Private-Package>
+                            org.apache.sling.servlets.*
+                        </Private-Package>
+
+                        <Sling-Nodetypes>
+                            SLING-INF/nodetypes/redirect.cnd
+                        </Sling-Nodetypes>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.jcr</groupId>
+            <artifactId>jcr</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.api</artifactId>
+            <version>2.0.0-incubator-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.json</artifactId>
+            <version>2.0.0-incubator-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+    </dependencies>
+</project>

Propchange: incubator/sling/trunk/sling/servlets-default/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/DefaultHtmlRenderer.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/DefaultHtmlRenderer.java?rev=631164&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/DefaultHtmlRenderer.java (added)
+++ incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/DefaultHtmlRenderer.java Tue Feb 26 02:28:36 2008
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+package org.apache.sling.servlets;
+
+import java.io.PrintWriter;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+
+import org.apache.sling.api.resource.Resource;
+
+/** Reusable default HTML rendering of a Node
+ */
+public class DefaultHtmlRenderer {
+
+    public void render(PrintWriter pw, Resource r, Node n) throws RepositoryException {
+        pw.println("<h1>Node dumped by " + getClass().getSimpleName() + "</h1>");
+        pw.println("<p>Node path: <b>" + n.getPath() + "</b></p>");
+        pw.println("<p>Resource metadata: <b>" + r.getResourceMetadata() + "</b></p>");
+
+        pw.println("<h2>Node properties</h2>");
+        for (PropertyIterator pi = n.getProperties(); pi.hasNext();) {
+            final Property p = pi.nextProperty();
+            printPropertyValue(pw, p);
+        }
+    }
+
+    /* TODO
+    public void render(PrintWriter pw, Resource r, SyntheticResourceData data) {
+        pw.println("<h1>SyntheticResourceData</h1>");
+        pw.println("<p>" + data.toString() + "</p>");
+    }
+    */
+
+    public void render(PrintWriter pw, Resource r, Property p) throws RepositoryException {
+        pw.print(p.getValue().getString());
+    }
+
+    protected void dump(PrintWriter pw, Resource r, Property p) throws RepositoryException {
+        pw.println("<h2>Property dumped by " + getClass().getSimpleName() + "</h1>");
+        pw.println("<p>Property path:" + p.getPath() + "</p>");
+        pw.println("<p>Resource metadata: " + r.getResourceMetadata() + "</p>");
+
+        printPropertyValue(pw, p);
+    }
+
+    protected void printPropertyValue(PrintWriter pw, Property p)
+            throws RepositoryException {
+
+        pw.print(p.getName() + ": <b>");
+
+        if (p.getDefinition().isMultiple()) {
+            Value[] values = p.getValues();
+            pw.print('[');
+            for (int i = 0; i < values.length; i++) {
+                if (i > 0) {
+                    pw.print(", ");
+                }
+                pw.print(values[i].getString());
+            }
+            pw.print(']');
+        } else {
+            pw.print(p.getValue().getString());
+        }
+
+        pw.print("</b><br/>");
+    }
+}

Propchange: incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/DefaultHtmlRenderer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/DefaultHtmlRendererServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/DefaultHtmlRendererServlet.java?rev=631164&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/DefaultHtmlRendererServlet.java (added)
+++ incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/DefaultHtmlRendererServlet.java Tue Feb 26 02:28:36 2008
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+package org.apache.sling.servlets;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.servlet.ServletException;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.SlingHttpServletResponse;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
+
+/**
+ * A SlingSafeMethodsServlet that renders the current Resource as simple HTML
+ * 
+ * @scr.service
+ *  interface="javax.servlet.Servlet"
+ *  
+ * @scr.component 
+ *  immediate="true" 
+ *  metatype="false"
+ *  
+ * @scr.property 
+ *  name="service.description"
+ *  value="Default HTML Renderer Servlet"
+ *  
+ * @scr.property 
+ *  name="service.vendor" 
+ *  value="The Apache Software Foundation"
+ *
+ * Use this as the default servlet for POST requests for Sling 
+ * @scr.property 
+ *  name="sling.servlet.resourceTypes" 
+ *  value="sling/servlet/default"
+ * @scr.property
+ *  name="sling.servlet.extensions"
+ *  value="html"
+ */
+public class DefaultHtmlRendererServlet extends SlingSafeMethodsServlet {
+
+    private static final long serialVersionUID = -5815904221043005085L;
+
+    private static final String responseContentType = "text/html";
+
+    private final DefaultHtmlRenderer renderer;
+
+    public DefaultHtmlRendererServlet() {
+        this.renderer = new DefaultHtmlRenderer();
+    }
+
+    @Override
+    protected void doGet(SlingHttpServletRequest req,
+            SlingHttpServletResponse resp) throws ServletException, IOException {
+        final Resource r = req.getResource();
+
+        resp.setContentType(responseContentType);
+        resp.setCharacterEncoding("UTF-8");
+
+        final PrintWriter pw = resp.getWriter();
+
+        final Node node = r.adaptTo(Node.class);
+        /*
+         * TODO final SyntheticResourceData srd =
+         * r.adaptTo(SyntheticResourceData.class);
+         */
+        final Property p = r.adaptTo(Property.class);
+
+        try {
+            /*
+             * TODO if(srd != null) { renderer.render(pw, r, srd); } else
+             */
+            if (node != null) {
+                pw.println("<html><body>");
+                renderer.render(pw, r, node);
+                pw.println("</body></html>");
+            } else {
+                // for properties, we just output the String value
+                renderer.render(pw, r, p);
+            }
+
+        } catch (RepositoryException re) {
+            throw new ServletException("Cannot dump contents of "
+                + req.getResource().getPath(), re);
+        }
+    }
+}

Propchange: incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/DefaultHtmlRendererServlet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/JsonRendererServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/JsonRendererServlet.java?rev=631164&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/JsonRendererServlet.java (added)
+++ incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/JsonRendererServlet.java Tue Feb 26 02:28:36 2008
@@ -0,0 +1,162 @@
+/*
+ * 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.
+ */
+package org.apache.sling.servlets;
+
+import java.io.IOException;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.api.SlingException;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.SlingHttpServletResponse;
+import org.apache.sling.api.resource.NonExistingResource;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceNotFoundException;
+import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
+import org.apache.sling.commons.json.JSONException;
+import org.apache.sling.commons.json.jcr.JsonItemWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A SlingSafeMethodsServlet that renders the current Resource as a JSON data
+ * block
+ * 
+ * @scr.service
+ *  interface="javax.servlet.Servlet"
+ *  
+ * @scr.component 
+ *  immediate="true" 
+ *  metatype="false"
+ *  
+ * @scr.property 
+ *  name="service.description"
+ *  value="Default JSON Renderer Servlet"
+ *  
+ * @scr.property 
+ *  name="service.vendor" 
+ *  value="The Apache Software Foundation"
+ *
+ * Use this as the default servlet for POST requests for Sling 
+ * @scr.property 
+ *  name="sling.servlet.resourceTypes" 
+ *  values.0="sling/servlet/default"
+ *  values.1="sling:redirect"
+ * @scr.property
+ *  name="sling.servlet.extensions"
+ *  value="json"
+ */
+public class JsonRendererServlet extends SlingSafeMethodsServlet {
+
+    private static final Logger log = LoggerFactory.getLogger(JsonRendererServlet.class);
+
+    private static final long serialVersionUID = 5577121546674133317L;
+
+    private static final String responseContentType = "application/json";
+
+    private final JsonItemWriter itemWriter;
+
+    /** Recursion level selector that means "all levels" */
+    public static final String INFINITY = "infinity";
+
+    public JsonRendererServlet() {
+        itemWriter = new JsonItemWriter(null);
+    }
+
+    @Override
+    protected void doGet(SlingHttpServletRequest req,
+            SlingHttpServletResponse resp) throws IOException {
+        // Access and check our data
+        final Resource r = req.getResource();
+        if (r instanceof NonExistingResource) {
+            throw new ResourceNotFoundException("No data to dump");
+        }
+
+        // Do we have a Property?
+        final Property p = r.adaptTo(Property.class);
+        if (p != null) {
+            try {
+                renderProperty(p, resp);
+            } catch (JSONException je) {
+                reportException(je);
+            } catch (RepositoryException re) {
+                reportException(re);
+            }
+            return;
+        }
+
+        // Do we have a Node?
+        final Node n = r.adaptTo(Node.class);
+        if (n == null) {
+            resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED,
+                "Can only dump nodes");
+            return;
+        }
+
+        // SLING-167: the last selector, if present, gives the number of
+        // recursion levels, 0 being the default
+        int maxRecursionLevels = 0;
+        final String[] selectors = req.getRequestPathInfo().getSelectors();
+        if (selectors != null && selectors.length > 0) {
+            String level = selectors[selectors.length - 1];
+            if (INFINITY.equals(level)) {
+                maxRecursionLevels = -1;
+            } else {
+                try {
+                    maxRecursionLevels = Integer.parseInt(level);
+                } catch (NumberFormatException nfe) {
+                    resp.sendError(HttpServletResponse.SC_BAD_REQUEST,
+                        "Invalid recursion selector value '" + level + "'");
+                    return;
+                }
+            }
+        }
+
+        resp.setContentType(responseContentType);
+        resp.setCharacterEncoding("UTF-8");
+
+        // do the dump
+        try {
+            itemWriter.dump(n, resp.getWriter(), maxRecursionLevels);
+        } catch (JSONException je) {
+            reportException(je);
+        } catch (RepositoryException re) {
+            reportException(re);
+        }
+    }
+
+    /** Render a Property by dumping its String value */
+    private void renderProperty(Property p, SlingHttpServletResponse resp)
+            throws JSONException, RepositoryException, IOException {
+        resp.setContentType(responseContentType);
+        resp.setCharacterEncoding("UTF-8");
+        new JsonItemWriter(null).dump(p, resp.getWriter());
+    }
+
+    /**
+     * @param e
+     * @throws SlingException wrapping the given exception
+     */
+    private void reportException(Exception e) {
+        log.warn("Error in JsonRendererServlet: " + e.toString(), e);
+        throw new SlingException(e.toString(), e);
+    }
+}

Propchange: incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/JsonRendererServlet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/PlainTextRendererServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/PlainTextRendererServlet.java?rev=631164&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/PlainTextRendererServlet.java (added)
+++ incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/PlainTextRendererServlet.java Tue Feb 26 02:28:36 2008
@@ -0,0 +1,153 @@
+/*
+ * 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.
+ */
+package org.apache.sling.servlets;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.servlet.ServletException;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.SlingHttpServletResponse;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
+
+/**
+ * A SlingSafeMethodsServlet that renders the current Resource as plain text.
+ * 
+ * @scr.service
+ *  interface="javax.servlet.Servlet"
+ *  
+ * @scr.component 
+ *  immediate="true" 
+ *  metatype="false"
+ *  
+ * @scr.property 
+ *  name="service.description"
+ *  value="Default Plain Text Renderer Servlet"
+ *  
+ * @scr.property 
+ *  name="service.vendor" 
+ *  value="The Apache Software Foundation"
+ *
+ * Use this as the default servlet for POST requests for Sling 
+ * @scr.property 
+ *  name="sling.servlet.resourceTypes" 
+ *  value="sling/servlet/default"
+ * @scr.property
+ *  name="sling.servlet.extensions"
+ *  value="txt"
+ */
+public class PlainTextRendererServlet extends SlingSafeMethodsServlet {
+
+    private static final long serialVersionUID = -5815904221043005085L;
+
+    private static final String responseContentType = "text/plain";
+
+    @Override
+    protected void doGet(SlingHttpServletRequest req,
+            SlingHttpServletResponse resp) throws ServletException, IOException {
+        final Resource r = req.getResource();
+        /*
+         * TODO if(srd != null) { renderSyntheticResource(req, resp, srd);
+         * return; }
+         */
+
+        resp.setContentType(responseContentType);
+        resp.setCharacterEncoding("UTF-8");
+
+        final PrintWriter pw = resp.getWriter();
+        try {
+            renderItem(pw, r);
+        } catch (RepositoryException re) {
+            throw new ServletException("Exception while rendering Resource "
+                + req.getResource(), re);
+        }
+    }
+
+    /** Render a Node or Property */
+    private void renderItem(PrintWriter pw, Resource r)
+            throws ServletException, RepositoryException {
+        Node n = null;
+        Property p = null;
+
+        if ((n = r.adaptTo(Node.class)) != null) {
+            dump(pw, r, n);
+
+        } else if ((p = r.adaptTo(Property.class)) != null) {
+            dump(pw, r, p);
+
+        } else {
+            throw new ServletException("Resource " + r
+                + " does not adapt to a Node or a Property");
+        }
+    }
+
+    /** Render synthetic resource */
+    /*
+     * TODO private void renderSyntheticResource(SlingHttpServletRequest
+     * req,SlingHttpServletResponse resp,SyntheticResourceData data) throws
+     * IOException { resp.setContentType(responseContentType);
+     * resp.getOutputStream().write(data.toString().getBytes()); }
+     */
+
+    protected void dump(PrintWriter pw, Resource r, Node n)
+            throws RepositoryException {
+        pw.println("** Node dumped by " + getClass().getSimpleName() + "**");
+        pw.println("Node path:" + n.getPath());
+        pw.println("Resource metadata: " + r.getResourceMetadata());
+
+        pw.println("\n** Node properties **");
+        for (PropertyIterator pi = n.getProperties(); pi.hasNext();) {
+            final Property p = pi.nextProperty();
+            printPropertyValue(pw, p, true);
+            pw.println();
+        }
+    }
+
+    protected void dump(PrintWriter pw, Resource r, Property p)
+            throws RepositoryException {
+        printPropertyValue(pw, p, false);
+    }
+
+    protected void printPropertyValue(PrintWriter pw, Property p,
+            boolean includeName) throws RepositoryException {
+
+        if (includeName) {
+            pw.print(p.getName() + ": ");
+        }
+
+        if (p.getDefinition().isMultiple()) {
+            Value[] values = p.getValues();
+            pw.print('[');
+            for (int i = 0; i < values.length; i++) {
+                if (i > 0) {
+                    pw.print(", ");
+                }
+                pw.print(values[i].getString());
+            }
+            pw.print(']');
+        } else {
+            pw.print(p.getValue().getString());
+        }
+    }
+}

Propchange: incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/PlainTextRendererServlet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/RedirectServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/RedirectServlet.java?rev=631164&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/RedirectServlet.java (added)
+++ incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/RedirectServlet.java Tue Feb 26 02:28:36 2008
@@ -0,0 +1,191 @@
+/*
+ * 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.
+ */
+package org.apache.sling.servlets;
+
+import java.io.IOException;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.SlingHttpServletResponse;
+import org.apache.sling.api.request.RequestPathInfo;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
+import org.apache.sling.api.wrappers.SlingRequestPaths;
+
+/**
+ * The <code>RedirectServlet</code> implements support for GET requests to
+ * resources of type <code>sling:redirect</code>. This servlet accesses the
+ * resource <code>sling:target</code> below the requested resource and tries
+ * to redirect to the target resource:
+ * <ul>
+ * <li>If the <code>sling:target</code> resource is based on a JCR property
+ * of type <em>REFERENCE</em> the path of the target node is used as the
+ * target for the redirection.
+ * <li>Otherwise the <code>sling:target</code> resource is adapted to a
+ * String which is taken as the path to the target for the redirection if not
+ * <code>null</code>.
+ * </ul>
+ * <p>
+ * If there is no <code>sling:target</code> child resource or the resource
+ * does not adapt to a JCR Node or a (path) String a 404 (NOT FOUND) status is
+ * sent by this servlet. Otherwise a 302 (FOUND, temporary redirect) status is
+ * sent where the target is the relative URL from the current resource to the
+ * target resource. Selectors, extension, suffix and query string are also
+ * appended to the redirect URL.
+ * 
+ * @scr.service interface="javax.servlet.Servlet"
+ * @scr.component immediate="true" metatype="false"
+ * @scr.property name="service.description" value="Request Redirect Servlet"
+ * @scr.property name="service.vendor" value="The Apache Software Foundation"
+ * @scr.property name="sling.servlet.resourceTypes" value="sling:redirect"
+ * @scr.property name="sling.servlet.methods" value="GET"
+ */
+public class RedirectServlet extends SlingSafeMethodsServlet {
+
+    /** The name of the target property */
+    public static final String TARGET_PROP = "sling:target";
+
+    @Override
+    protected void doGet(SlingHttpServletRequest request,
+            SlingHttpServletResponse response) throws ServletException,
+            IOException {
+
+        Resource targetResource = request.getResourceResolver().getResource(
+            request.getResource(), TARGET_PROP);
+        if (targetResource == null) {
+            response.sendError(HttpServletResponse.SC_NOT_FOUND,
+                "Missing target for redirection");
+            return;
+        }
+
+        String targetPath = null;
+
+        // if the target resource is a reference, we can adapt to node
+        Node targetNode = targetResource.adaptTo(Node.class);
+        if (targetNode != null) {
+
+            // get the node path (aka resource path)
+            try {
+                targetPath = targetNode.getPath();
+            } catch (RepositoryException re) {
+                throw new ServletException(
+                    "Failed to access repository for redirection", re);
+
+            }
+
+        } else {
+
+            // if the target resource is a path (string), redirect there
+            targetPath = targetResource.adaptTo(String.class);
+
+        }
+
+        // if we got a target path, make it external and redirect to it
+        if (targetPath != null) {
+            // make path relative and append selectors, extension etc.
+            targetPath = toRedirectPath(targetPath, request);
+
+            // and redirect there ...
+            response.sendRedirect(targetPath);
+
+            return;
+        }
+
+        // no way of finding the target, just fail
+        response.sendError(HttpServletResponse.SC_NOT_FOUND,
+            "Cannot redirect to target resource " + targetResource);
+    }
+
+    /**
+     * Create a relative redirect URL for the targetPath relative to the given
+     * request. The URL is relative to the request's resource and will include
+     * the selectors, extension, suffix and query string of the request.
+     */
+    protected static String toRedirectPath(String targetPath,
+            SlingHttpServletRequest request) {
+
+        String postFix;
+        RequestPathInfo rpi = request.getRequestPathInfo();
+        if (rpi.getExtension() != null) {
+            StringBuffer postfixBuf = new StringBuffer();
+            if (rpi.getSelectorString() != null) {
+                postfixBuf.append('.').append(rpi.getSelectorString());
+            }
+            postfixBuf.append('.').append(rpi.getExtension());
+            if (rpi.getSuffix() != null) {
+                postfixBuf.append(rpi.getSuffix());
+            }
+            postFix = postfixBuf.toString();
+        } else {
+            postFix = null;
+        }
+        
+
+        StringBuffer pathBuf = new StringBuffer();
+
+        String basePath = request.getResource().getPath();
+        if (postFix != null) {
+            basePath += postFix;
+        }
+        
+        makeRelative(pathBuf, basePath, targetPath);
+
+        if (postFix != null) {
+            pathBuf.append(postFix);
+        }
+
+        if (request.getQueryString() != null) {
+            pathBuf.append('?').append(request.getQueryString());
+        }
+
+        return pathBuf.toString();
+    }
+
+    /**
+     * Converts the absolute path target into a path relative to base and stores
+     * this relative path into pathBuffer.
+     */
+    private static void makeRelative(StringBuffer pathBuffer, String base,
+            String target) {
+
+        String[] bParts = base.substring(1).split("/");
+        String[] tParts = target.substring(1).split("/");
+
+        // find first non-matching part
+        int off;
+        for (off = 0; off < bParts.length && off < tParts.length
+            && bParts[off].equals(tParts[off]); off++);
+
+        for (int i = bParts.length - off; i > 1; i--) {
+            pathBuffer.append("../");
+        }
+
+        for (int i = off; i < tParts.length; i++) {
+            if (i > off) {
+                pathBuffer.append('/');
+            }
+            pathBuffer.append(tParts[i]);
+        }
+    }
+}

Propchange: incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/RedirectServlet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/StreamRendererServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/StreamRendererServlet.java?rev=631164&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/StreamRendererServlet.java (added)
+++ incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/StreamRendererServlet.java Tue Feb 26 02:28:36 2008
@@ -0,0 +1,181 @@
+/*
+ * 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.
+ */
+package org.apache.sling.servlets;
+
+import static javax.servlet.http.HttpServletResponse.SC_NOT_MODIFIED;
+import static org.apache.sling.api.servlets.HttpConstants.HEADER_IF_MODIFIED_SINCE;
+import static org.apache.sling.api.servlets.HttpConstants.HEADER_LAST_MODIFIED;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.SlingHttpServletResponse;
+import org.apache.sling.api.resource.NonExistingResource;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceMetadata;
+
+/**
+ * The <code>StreamRendererServlet</code> TODO
+ * 
+ * @scr.service
+ *  interface="javax.servlet.Servlet"
+ *  
+ * @scr.component 
+ *  immediate="true" 
+ *  metatype="false"
+ *  
+ * @scr.property 
+ *  name="service.description"
+ *  value="Default Streaming Renderer Servlet"
+ *  
+ * @scr.property 
+ *  name="service.vendor" 
+ *  value="The Apache Software Foundation"
+ *
+ * Use this as the default servlet for POST requests for Sling 
+ * @scr.property 
+ *  name="sling.servlet.resourceTypes" 
+ *  value="sling/servlet/default"
+ *  
+ * Handler for .res requests
+ * @scr.property
+ *  name="sling.servlet.extensions"
+ *  value="res"
+ *  
+ * Generic handler for all get requests
+ * @scr.property
+ *  name="sling.servlet.methods"
+ *  value="GET"
+ */
+public class StreamRendererServlet extends PlainTextRendererServlet {
+
+    private static final long serialVersionUID = -1L;
+
+    @Override
+    protected void doGet(SlingHttpServletRequest request,
+            SlingHttpServletResponse response) throws ServletException,
+            IOException {
+
+        // ensure no extension or "res"
+        String ext = request.getRequestPathInfo().getExtension();
+        if (ext != null && !ext.equals("res")) {
+            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                "No default renderer found for extension='" + ext + "'");
+            return;
+        }
+        
+        Resource resource = request.getResource();
+
+        // cannot handle the request for missing resources
+        if (resource instanceof NonExistingResource) {
+            response.sendError(HttpServletResponse.SC_NOT_FOUND,
+                "Resource not found at path " + resource.getPath());
+            return;
+        }
+
+        // check the last modification time and If-Modified-Since header
+        ResourceMetadata meta = resource.getResourceMetadata();
+        long modifTime = meta.getModificationTime();
+        if (unmodified(request, modifTime)) {
+            response.setStatus(SC_NOT_MODIFIED);
+            return;
+        }
+
+        // fall back to plain text rendering if the resource has no stream
+        InputStream stream = resource.adaptTo(InputStream.class);
+        if (stream == null) {
+            super.doGet(request, response);
+            return;
+        }
+
+        // finally stream the resource
+        try {
+
+            if (modifTime > 0) {
+                response.setDateHeader(HEADER_LAST_MODIFIED, modifTime);
+            }
+
+            final String defaultContentType = "application/octet-stream";
+            String contentType = meta.getContentType();
+            if (contentType == null || defaultContentType.equals(contentType)) {
+                // if repository doesn't provide a content-type, or
+                // provides the
+                // default one,
+                // try to do better using our servlet context
+                final String ct = getServletContext().getMimeType(
+                    resource.getPath());
+                if (ct != null) {
+                    contentType = ct;
+                }
+            }
+            if (contentType != null) {
+                response.setContentType(contentType);
+            }
+
+            String encoding = meta.getCharacterEncoding();
+            if (encoding != null) {
+                response.setCharacterEncoding(encoding);
+            }
+
+            OutputStream out = response.getOutputStream();
+
+            byte[] buf = new byte[1024];
+            int rd;
+            while ((rd = stream.read(buf)) >= 0) {
+                out.write(buf, 0, rd);
+            }
+
+        } finally {
+            try {
+                stream.close();
+            } catch (IOException ignore) {
+                // don't care
+            }
+        }
+    }
+
+    /**
+     * Returns <code>true</code> if the request has a
+     * <code>If-Modified-Since</code> header whose date value is later than
+     * the last modification time given as <code>modifTime</code>.
+     * 
+     * @param request The <code>ComponentRequest</code> checked for the
+     *            <code>If-Modified-Since</code> header.
+     * @param modifTime The last modification time to compare the header to.
+     * @return <code>true</code> if the <code>modifTime</code> is less than
+     *         or equal to the time of the <code>If-Modified-Since</code>
+     *         header.
+     */
+    private boolean unmodified(HttpServletRequest request, long modifTime) {
+        if (modifTime > 0) {
+            long modTime = modifTime / 1000; // seconds
+            long ims = request.getDateHeader(HEADER_IF_MODIFIED_SINCE) / 1000;
+            return modTime <= ims;
+        }
+
+        // we have no modification time value, assume modified
+        return false;
+    }
+
+}
\ No newline at end of file

Propchange: incubator/sling/trunk/sling/servlets-default/src/main/java/org/apache/sling/servlets/StreamRendererServlet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/sling/servlets-default/src/main/resources/SLING-INF/nodetypes/redirect.cnd
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlets-default/src/main/resources/SLING-INF/nodetypes/redirect.cnd?rev=631164&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlets-default/src/main/resources/SLING-INF/nodetypes/redirect.cnd (added)
+++ incubator/sling/trunk/sling/servlets-default/src/main/resources/SLING-INF/nodetypes/redirect.cnd Tue Feb 26 02:28:36 2008
@@ -0,0 +1,26 @@
+//
+//  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.
+//
+
+<sling = 'http://sling.apache.org/jcr/sling/1.0'>
+
+//-----------------------------------------------------------------------------
+// Mixin node type for Sling Redirect nodes
+[sling:Redirect] > sling:Resource
+    mixin
+  - sling:target (Undefined)

Propchange: incubator/sling/trunk/sling/servlets-default/src/main/resources/SLING-INF/nodetypes/redirect.cnd
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/servlets/MockRequestPathInfo.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/servlets/MockRequestPathInfo.java?rev=631164&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/servlets/MockRequestPathInfo.java (added)
+++ incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/servlets/MockRequestPathInfo.java Tue Feb 26 02:28:36 2008
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+package org.apache.sling.servlets;
+
+import org.apache.sling.api.request.RequestPathInfo;
+
+class MockRequestPathInfo implements RequestPathInfo {
+
+    private final String selectors;
+
+    private final String extension;
+
+    private final String suffix;
+
+    MockRequestPathInfo(String selectors, String extension, String suffix) {
+        this.selectors = selectors;
+        this.extension = extension;
+        this.suffix = suffix;
+    }
+
+    public String getExtension() {
+        return extension;
+    }
+
+    public String getResourcePath() {
+        return null;
+    }
+
+    public String getSelectorString() {
+        return selectors;
+    }
+
+    public String[] getSelectors() {
+        return (getSelectorString() != null)
+                ? getSelectorString().split(".")
+                : new String[0];
+    }
+
+    public String getSuffix() {
+        return suffix;
+    }
+}

Propchange: incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/servlets/MockRequestPathInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/servlets/MockSlingHttpServletRequest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/servlets/MockSlingHttpServletRequest.java?rev=631164&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/servlets/MockSlingHttpServletRequest.java (added)
+++ incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/servlets/MockSlingHttpServletRequest.java Tue Feb 26 02:28:36 2008
@@ -0,0 +1,344 @@
+/*
+ * 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.
+ */
+package org.apache.sling.servlets;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.Principal;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpSession;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.request.RequestDispatcherOptions;
+import org.apache.sling.api.request.RequestParameter;
+import org.apache.sling.api.request.RequestParameterMap;
+import org.apache.sling.api.request.RequestPathInfo;
+import org.apache.sling.api.request.RequestProgressTracker;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.SyntheticResource;
+import org.apache.sling.api.services.ServiceLocator;
+
+class MockSlingHttpServletRequest implements SlingHttpServletRequest {
+
+    private final Resource resource;
+
+    private final RequestPathInfo requestPathInfo;
+
+    private final String queryString;
+
+    MockSlingHttpServletRequest() {
+        this(null, null, null, null, null);
+    }
+
+    MockSlingHttpServletRequest(String resourcePath, String selectors,
+            String extension, String suffix, String queryString) {
+        this.resource = new SyntheticResource(null, resourcePath, null);
+        this.requestPathInfo = new MockRequestPathInfo(selectors, extension,
+            suffix);
+        this.queryString = queryString;
+    }
+
+    public Cookie getCookie(String name) {
+        return null;
+    }
+
+    public RequestDispatcher getRequestDispatcher(String path,
+            RequestDispatcherOptions options) {
+        return null;
+    }
+
+    public RequestDispatcher getRequestDispatcher(Resource resource,
+            RequestDispatcherOptions options) {
+        return null;
+    }
+
+    public RequestDispatcher getRequestDispatcher(Resource resource) {
+        return null;
+    }
+
+    public RequestParameter getRequestParameter(String name) {
+        return null;
+    }
+
+    public RequestParameterMap getRequestParameterMap() {
+        return null;
+    }
+
+    public RequestParameter[] getRequestParameters(String name) {
+        return null;
+    }
+
+    public RequestPathInfo getRequestPathInfo() {
+        return requestPathInfo;
+    }
+
+    public RequestProgressTracker getRequestProgressTracker() {
+        return null;
+    }
+
+    public Resource getResource() {
+        return resource;
+    }
+
+    public ResourceBundle getResourceBundle(Locale locale) {
+        return null;
+    }
+
+    public ResourceResolver getResourceResolver() {
+        return null;
+    }
+
+    public String getResponseContentType() {
+        return null;
+    }
+
+    public Enumeration<String> getResponseContentTypes() {
+        return null;
+    }
+
+    public ServiceLocator getServiceLocator() {
+        return null;
+    }
+
+    public String getAuthType() {
+        return null;
+    }
+
+    public String getContextPath() {
+        return null;
+    }
+
+    public Cookie[] getCookies() {
+        return null;
+    }
+
+    public long getDateHeader(String name) {
+        return 0;
+    }
+
+    public String getHeader(String name) {
+        return null;
+    }
+
+    public Enumeration<?> getHeaderNames() {
+        return null;
+    }
+
+    public Enumeration<?> getHeaders(String name) {
+        return null;
+    }
+
+    public int getIntHeader(String name) {
+        return 0;
+    }
+
+    public String getMethod() {
+        return null;
+    }
+
+    public String getPathInfo() {
+        return null;
+    }
+
+    public String getPathTranslated() {
+        return null;
+    }
+
+    public String getQueryString() {
+        return queryString;
+    }
+
+    public String getRemoteUser() {
+        return null;
+    }
+
+    public String getRequestURI() {
+        return null;
+    }
+
+    public StringBuffer getRequestURL() {
+        return null;
+    }
+
+    public String getRequestedSessionId() {
+        return null;
+    }
+
+    public String getServletPath() {
+        return null;
+    }
+
+    public HttpSession getSession() {
+        return null;
+    }
+
+    public HttpSession getSession(boolean create) {
+        return null;
+    }
+
+    public Principal getUserPrincipal() {
+        return null;
+    }
+
+    public boolean isRequestedSessionIdFromCookie() {
+        return false;
+    }
+
+    public boolean isRequestedSessionIdFromURL() {
+        return false;
+    }
+
+    public boolean isRequestedSessionIdFromUrl() {
+        return false;
+    }
+
+    public boolean isRequestedSessionIdValid() {
+        return false;
+    }
+
+    public boolean isUserInRole(String role) {
+        return false;
+    }
+
+    public Object getAttribute(String name) {
+        return null;
+    }
+
+    public Enumeration<?> getAttributeNames() {
+        return null;
+    }
+
+    public String getCharacterEncoding() {
+        return null;
+    }
+
+    public int getContentLength() {
+        return 0;
+    }
+
+    public String getContentType() {
+        return null;
+    }
+
+    public ServletInputStream getInputStream() {
+        return null;
+    }
+
+    public String getLocalAddr() {
+        return null;
+    }
+
+    public String getLocalName() {
+        return null;
+    }
+
+    public int getLocalPort() {
+        return 0;
+    }
+
+    public Locale getLocale() {
+        return null;
+    }
+
+    public Enumeration<?> getLocales() {
+        return null;
+    }
+
+    public String getParameter(String name) {
+        return null;
+    }
+
+    public Map<?, ?> getParameterMap() {
+        return null;
+    }
+
+    public Enumeration<?> getParameterNames() {
+        return null;
+    }
+
+    public String[] getParameterValues(String name) {
+        return null;
+    }
+
+    public String getProtocol() {
+        return null;
+    }
+
+    public BufferedReader getReader() {
+        return null;
+    }
+
+    public String getRealPath(String path) {
+        return null;
+    }
+
+    public String getRemoteAddr() {
+        return null;
+    }
+
+    public String getRemoteHost() {
+        return null;
+    }
+
+    public int getRemotePort() {
+        return 0;
+    }
+
+    public RequestDispatcher getRequestDispatcher(String path) {
+        return null;
+    }
+
+    public String getScheme() {
+        return null;
+    }
+
+    public String getServerName() {
+        return null;
+    }
+
+    public int getServerPort() {
+        return 0;
+    }
+
+    public boolean isSecure() {
+        return false;
+    }
+
+    public void removeAttribute(String name) {
+
+    }
+
+    public void setAttribute(String name, Object o) {
+
+    }
+
+    public void setCharacterEncoding(String env) {
+
+    }
+
+}

Propchange: incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/servlets/MockSlingHttpServletRequest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/servlets/RedirectServletTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/servlets/RedirectServletTest.java?rev=631164&view=auto
==============================================================================
--- incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/servlets/RedirectServletTest.java (added)
+++ incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/servlets/RedirectServletTest.java Tue Feb 26 02:28:36 2008
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+package org.apache.sling.servlets;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+
+import junit.framework.TestCase;
+
+public class RedirectServletTest extends TestCase {
+
+    public void testSameParent() {
+        String base = "/a";
+        String target = "/b";
+        assertEquals("b", toRedirect(base, target));
+
+        base = "/";
+        target = "/a";
+        assertEquals("a", toRedirect(base, target));
+
+        base = "/a/b/c";
+        target = "/a/b/d";
+        assertEquals("d", toRedirect(base, target));
+    }
+
+    public void testCommonAncestor() {
+        String base = "/a/b/c/d";
+        String target = "/a/b/x/y";
+        assertEquals("../x/y", toRedirect(base, target));
+    }
+
+    public void testUnCommon() {
+        String base = "/a/b/c/d";
+        String target = "/w/x/y/z";
+        assertEquals("../../../w/x/y/z", toRedirect(base, target));
+    }
+
+    public void testSelectorsEtc() {
+        String base = "/a/b/c";
+        String target = "/a/b/d";
+        String expected = "d";
+
+        String selectors = null;
+        String extension = null;
+        String suffix = null;
+        String queryString = null;
+        assertEquals(expected, base, selectors, extension, suffix, queryString,
+            target);
+
+        selectors = null;
+        extension = "html";
+        suffix = null;
+        queryString = null;
+        assertEquals(expected, base, selectors, extension, suffix, queryString,
+            target);
+
+        selectors = "print";
+        extension = "html";
+        suffix = null;
+        queryString = null;
+        assertEquals(expected, base, selectors, extension, suffix, queryString,
+            target);
+
+        selectors = "print.a4";
+        extension = "html";
+        suffix = null;
+        queryString = null;
+        assertEquals(expected, base, selectors, extension, suffix, queryString,
+            target);
+
+        selectors = null;
+        extension = "html";
+        suffix = "/suffix.pdf";
+        queryString = null;
+        assertEquals("../" + expected, base, selectors, extension, suffix,
+            queryString, target);
+
+        selectors = null;
+        extension = "html";
+        suffix = null;
+        queryString = "xy=1";
+        assertEquals(expected, base, selectors, extension, suffix, queryString,
+            target);
+
+        selectors = null;
+        extension = "html";
+        suffix = "/suffix.pdf";
+        queryString = "xy=1";
+        assertEquals("../" + expected, base, selectors, extension, suffix,
+            queryString, target);
+
+        selectors = "print.a4";
+        extension = "html";
+        suffix = "/suffix.pdf";
+        queryString = "xy=1";
+        assertEquals("../" + expected, base, selectors, extension, suffix,
+            queryString, target);
+    }
+
+    private void assertEquals(String expected, String basePath,
+            String selectors, String extension, String suffix,
+            String queryString, String targetPath) {
+
+        if (selectors != null) {
+            expected += "." + selectors;
+        }
+        if (extension != null) {
+            expected += "." + extension;
+        }
+        if (suffix != null) {
+            expected += suffix;
+        }
+        if (queryString != null) {
+            expected += "?" + queryString;
+        }
+
+        String actual = toRedirect(basePath, selectors, extension, suffix,
+            queryString, targetPath);
+
+        assertEquals(expected, actual);
+    }
+
+    private String toRedirect(String basePath, String targetPath) {
+        return toRedirect(basePath, null, null, null, null, targetPath);
+    }
+
+    private String toRedirect(String basePath, String selectors,
+            String extension, String suffix, String queryString,
+            String targetPath) {
+        SlingHttpServletRequest request = new MockSlingHttpServletRequest(
+            basePath, selectors, extension, suffix, queryString);
+        return RedirectServlet.toRedirectPath(targetPath, request);
+    }
+}

Propchange: incubator/sling/trunk/sling/servlets-default/src/test/java/org/apache/sling/servlets/RedirectServletTest.java
------------------------------------------------------------------------------
    svn:eol-style = native