You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2007/12/10 16:15:05 UTC

svn commit: r602927 - in /incubator/sling/trunk/microsling/microsling-core/src: main/java/org/apache/sling/microsling/resource/ main/java/org/apache/sling/microsling/slingservlets/ main/java/org/apache/sling/microsling/slingservlets/renderers/ test/jav...

Author: bdelacretaz
Date: Mon Dec 10 07:15:02 2007
New Revision: 602927

URL: http://svn.apache.org/viewvc?rev=602927&view=rev
Log:
SLING-129 - /SyntheticResource added, with simple regexp-based SyntheticResourceProvider

Added:
    incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResource.java   (with props)
    incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResourceData.java   (with props)
    incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResourceProvider.java   (with props)
    incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/SyntheticResourceTest.java   (with props)
Modified:
    incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/MicroslingResourceResolver.java
    incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/DefaultSlingServlet.java
    incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRenderer.java
    incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRendererServlet.java
    incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/JsonRendererServlet.java
    incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/PlainTextRendererServlet.java

Modified: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/MicroslingResourceResolver.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/MicroslingResourceResolver.java?rev=602927&r1=602926&r2=602927&view=diff
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/MicroslingResourceResolver.java (original)
+++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/MicroslingResourceResolver.java Mon Dec 10 07:15:02 2007
@@ -62,6 +62,7 @@
         + "jcr/sling/1.0";
 
     private Session session;
+    private final SyntheticResourceProvider syntheticResourceProvider = new SyntheticResourceProvider();
 
     // package private default constructor for unit tests, DO NOT USE
     MicroslingResourceResolver() {
@@ -104,6 +105,8 @@
     public Resource resolve(ServletRequest request) throws SlingException {
         Resource result = null;
         String path = null;
+        
+        // look for a real JCR Resource
         String pathInfo = SlingRequestPaths.getPathInfo((HttpServletRequest)request);
         try {
             Session session = getSession();
@@ -114,7 +117,13 @@
         } catch (RepositoryException re) {
             throw new SlingException("RepositoryException for path=" + path, re);
         }
-
+        
+        // not found -> try synthetic resource
+        if (result == null) {
+            result = syntheticResourceProvider.getSyntheticResource(pathInfo);
+        }
+        
+        // not found -> NonExistingResource
         if (result == null) {
             result = new NonExistingResource(pathInfo);
         }

Added: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResource.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResource.java?rev=602927&view=auto
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResource.java (added)
+++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResource.java Mon Dec 10 07:15:02 2007
@@ -0,0 +1,87 @@
+/*
+ * 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.microsling.resource;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceMetadata;
+
+/**
+ * The <code>SyntheticResource</code> class is a simple implementation of the
+ * <code>Resource</code> interface which may be used to provide a resource
+ * object which has no related repository item.
+ * <p>
+ * Clients may call the {@link #setRawData(Object)} and
+ * {@link #setObject(Object)} method as appropriate.
+ * TODO: a similar interface exists in sling, we might want to
+ * consolidate (see SLING-129).
+ */
+public class SyntheticResource implements Resource {
+
+    /** The path of the synthetic resource */
+    private String path;
+
+    /** The type this synthetic resource assumes */
+    private String resourceType;
+
+    /** The metadata of this resource, contains just the resource path */
+    private ResourceMetadata resourceMetadata;
+    
+    /** default resource type for these resources */
+    public static String DEFAULT_RESOURCE_TYPE = "/sling/synthetic-resource";
+
+    /**
+     * Creates a synthetic content with the given path and component Id.
+     *
+     * @param path The path of the synthetic content
+     * @param resourceType The ID of the component rendering the synthetic
+     *            content
+     */
+    public SyntheticResource(String path, String resourceType) {
+        this.path = path;
+        this.resourceType = (resourceType != null ? resourceType : DEFAULT_RESOURCE_TYPE);
+        this.resourceMetadata = new ResourceMetadata();
+        this.resourceMetadata.put(ResourceMetadata.RESOLUTION_PATH, path);
+    }
+    
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + ", path=" + path + ", resourceType=" + resourceType;
+    }
+
+    public String getURI() {
+        return path;
+    }
+
+    public String getResourceType() {
+        return resourceType;
+    }
+
+    public ResourceMetadata getResourceMetadata() {
+        return resourceMetadata;
+    }
+
+    public <Type> Type adaptTo(Class<Type> type) {
+        if(SyntheticResourceData.class.equals(type)) {
+            final SyntheticResourceData srd = new SyntheticResourceData(path);
+            return (Type)srd;  // unchecked cast
+        }
+        return null;
+    }
+
+}
\ No newline at end of file

Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResource.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResource.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResourceData.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResourceData.java?rev=602927&view=auto
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResourceData.java (added)
+++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResourceData.java Mon Dec 10 07:15:02 2007
@@ -0,0 +1,37 @@
+/*
+ * 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.microsling.resource;
+
+
+/** Data object provided by SyntheticResource, contains no
+ *  data for now */
+public class SyntheticResourceData {
+
+    private final String path;
+    
+    SyntheticResourceData(String path) {
+        this.path = path;
+        
+    }
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + ", path=" + path;
+    }
+    
+}

Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResourceData.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResourceData.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResourceProvider.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResourceProvider.java?rev=602927&view=auto
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResourceProvider.java (added)
+++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResourceProvider.java Mon Dec 10 07:15:02 2007
@@ -0,0 +1,83 @@
+/*
+ * 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.microsling.resource;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import org.apache.sling.api.resource.Resource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** Provides SyntheticResource objects to the
+ *  {@link MicroslingResourceResolver}, based on
+ *  (hardcoded for now) regular expressions: if the
+ *  request path matches one of these expressions,
+ *  a SyntheticResource is created.
+ */
+public class SyntheticResourceProvider {
+
+    private final Logger log = LoggerFactory.getLogger(SyntheticResourceProvider.class);
+    
+    /** Default regular expressions, SyntheticResources are
+     *  created if the given path matches one of these.
+     */
+    public static String [] DEFAULT_PATH_REGEXP = {
+        "/search(/.*)?",   // everything under /search
+        ".*\\*$"          // everything ending with *
+    };
+    
+    private final List<Pattern> pathPattern = new LinkedList<Pattern>();
+    
+    SyntheticResourceProvider() throws PatternSyntaxException {
+        for(String pattern : DEFAULT_PATH_REGEXP) {
+            addPathRegexp(pattern);
+        }
+    }
+    
+    Resource getSyntheticResource(String pathInfo) {
+        Resource result = null;
+        
+        final ResourcePathIterator it = new ResourcePathIterator(pathInfo);
+        while (it.hasNext() && result == null) {
+            final String path = it.next();
+            for(Pattern p : pathPattern) {
+                if(p.matcher(path).matches()) {
+                    result = new SyntheticResource(path,null);
+                    if(log.isInfoEnabled()) {
+                        log.info("Path matches Pattern " + p + ", returning " + result);
+                    }
+                    break;
+                }
+            }
+        }
+        
+        return result;
+    }
+    
+    public void addPathRegexp(String str) throws PatternSyntaxException {
+        pathPattern.add(Pattern.compile(str));
+    }
+    
+    public void clearPathRegexps() {
+        pathPattern.clear();
+    }
+}

Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResourceProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/resource/SyntheticResourceProvider.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Modified: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/DefaultSlingServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/DefaultSlingServlet.java?rev=602927&r1=602926&r2=602927&view=diff
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/DefaultSlingServlet.java (original)
+++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/DefaultSlingServlet.java Mon Dec 10 07:15:02 2007
@@ -36,6 +36,7 @@
 import org.apache.sling.api.resource.ResourceMetadata;
 import org.apache.sling.api.servlets.HttpConstants;
 import org.apache.sling.api.servlets.SlingAllMethodsServlet;
+import org.apache.sling.microsling.resource.SyntheticResourceData;
 import org.apache.sling.microsling.servlet.MicroslingServletConfig;
 import org.apache.sling.microsling.slingservlets.renderers.DefaultHtmlRendererServlet;
 import org.apache.sling.microsling.slingservlets.renderers.JsonRendererServlet;
@@ -98,20 +99,24 @@
                 throw new HttpStatusCodeException(HttpServletResponse.SC_NOT_FOUND,
                         "Resource not found: " + r.getURI());
             }
-        } else if(r.adaptTo(Node.class) != null) {
+        } else if(r.adaptTo(Node.class) != null || r.adaptTo(SyntheticResourceData.class) != null) {
 
-            // make sure we have an Item, and render it via one of our renderingServlets
-            final String suffix = req.getRequestPathInfo().getSuffix();
-            if(suffix != null && suffix.length() > 0) {
-                // accept exact addressing only for default rendering:
-                // a non-empty suffix means there was extra stuff after the path
-                // of the resource
-                throw new HttpStatusCodeException(
-                        HttpServletResponse.SC_NOT_FOUND,
-                        "Ancestor resource found (" + r.getResourceMetadata().get(ResourceMetadata.RESOLUTION_PATH) + ")"
-                        + " but URL suffix must be empty for default rendering (suffix=" + suffix + ")"
-                );
+            if(r.adaptTo(Node.class) != null) {
+                // When rendering Nodes,
+                // make sure we have an Item, and render it via one of our renderingServlets
+                final String suffix = req.getRequestPathInfo().getSuffix();
+                if(suffix != null && suffix.length() > 0) {
+                    // accept exact addressing only for default rendering:
+                    // a non-empty suffix means there was extra stuff after the path
+                    // of the resource
+                    throw new HttpStatusCodeException(
+                            HttpServletResponse.SC_NOT_FOUND,
+                            "Ancestor resource found (" + r.getResourceMetadata().get(ResourceMetadata.RESOLUTION_PATH) + ")"
+                            + " but URL suffix must be empty for default rendering (suffix=" + suffix + ")"
+                    );
+                }
             }
+            
             final String contentType = req.getResponseContentType();
             final Servlet s = renderingServlets.get(contentType);
             if(s!=null) {

Modified: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRenderer.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRenderer.java?rev=602927&r1=602926&r2=602927&view=diff
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRenderer.java (original)
+++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRenderer.java Mon Dec 10 07:15:02 2007
@@ -25,6 +25,7 @@
 import javax.jcr.Value;
 
 import org.apache.sling.api.resource.Resource;
+import org.apache.sling.microsling.resource.SyntheticResourceData;
 
 /** Reusable default HTML rendering of a Node
  */
@@ -40,6 +41,11 @@
             final Property p = pi.nextProperty();
             printPropertyValue(pw, p);
         }
+    }
+
+    public void render(PrintWriter pw, Resource r, SyntheticResourceData data) {
+        pw.println("<h1>SyntheticResourceData</h1>");
+        pw.println("<p>" + data.toString() + "</p>");
     }
 
     protected void dump(PrintWriter pw, Resource r, Property p) throws RepositoryException {

Modified: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRendererServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRendererServlet.java?rev=602927&r1=602926&r2=602927&view=diff
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRendererServlet.java (original)
+++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRendererServlet.java Mon Dec 10 07:15:02 2007
@@ -27,6 +27,7 @@
 import org.apache.sling.api.SlingHttpServletResponse;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
+import org.apache.sling.microsling.resource.SyntheticResourceData;
 
 /** A SlingSafeMethodsServlet that renders the current Resource
  *  as simple HTML
@@ -47,16 +48,23 @@
     throws ServletException,IOException
     {
         final Resource  r = req.getResource();
-        final Node node = r.adaptTo(Node.class);
+        
         resp.setContentType(responseContentType);
         final PrintWriter pw = resp.getWriter();
-        try {
-            pw.println("<html><body>");
-            renderer.render(pw, r, node);
-            pw.println("</body></html>");
-        } catch (RepositoryException re) {
-            throw new ServletException("Cannot dump contents of "
-                + req.getResource().getURI(), re);
+        
+        final Node node = r.adaptTo(Node.class);
+        final SyntheticResourceData srd = r.adaptTo(SyntheticResourceData.class); 
+        if(srd != null) {
+            renderer.render(pw, r, srd);
+        } else {
+            try {
+                pw.println("<html><body>");
+                renderer.render(pw, r, node);
+                pw.println("</body></html>");
+            } catch (RepositoryException re) {
+                throw new ServletException("Cannot dump contents of "
+                    + req.getResource().getURI(), re);
+            }
         }
     }
 }

Modified: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/JsonRendererServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/JsonRendererServlet.java?rev=602927&r1=602926&r2=602927&view=diff
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/JsonRendererServlet.java (original)
+++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/JsonRendererServlet.java Mon Dec 10 07:15:02 2007
@@ -31,6 +31,7 @@
 import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
 import org.apache.sling.commons.json.JSONException;
 import org.apache.sling.microsling.helpers.json.JsonItemWriter;
+import org.apache.sling.microsling.resource.SyntheticResourceData;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -63,6 +64,12 @@
         if(r instanceof NonExistingResource) {
             throw new HttpStatusCodeException(HttpServletResponse.SC_NOT_FOUND, "No data to dump");
         }
+        
+        if(r.adaptTo(SyntheticResourceData.class) != null) {
+            renderSyntheticResource(req, resp);
+            return;
+        }
+        
         final Node n = r.adaptTo(Node.class);
         if(n == null) {
             throw new HttpStatusCodeException(
@@ -91,6 +98,12 @@
         } catch(RepositoryException re) {
             reportException(re);
         }
+    }
+
+    /** Render synthetic resources as empty JSON objects */ 
+    private void renderSyntheticResource(SlingHttpServletRequest req,SlingHttpServletResponse resp) throws IOException {
+        resp.setContentType(responseContentType);
+        resp.getOutputStream().write("{}".getBytes());
     }
 
     private void reportException(Exception e) throws HttpStatusCodeException {

Modified: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/PlainTextRendererServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/PlainTextRendererServlet.java?rev=602927&r1=602926&r2=602927&view=diff
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/PlainTextRendererServlet.java (original)
+++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/PlainTextRendererServlet.java Mon Dec 10 07:15:02 2007
@@ -30,6 +30,7 @@
 import org.apache.sling.api.SlingHttpServletResponse;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
+import org.apache.sling.microsling.resource.SyntheticResourceData;
 
 /** A SlingSafeMethodsServlet that renders the current Resource
  *  as plain text.
@@ -48,6 +49,12 @@
     throws ServletException,IOException
     {
         final Resource  r = req.getResource();
+        final SyntheticResourceData srd = r.adaptTo(SyntheticResourceData.class); 
+        if(srd != null) {
+            renderSyntheticResource(req, resp, srd);
+            return;
+        }
+        
         final Node node = r.adaptTo(Node.class);
         resp.setContentType(responseContentType);
         final PrintWriter pw = resp.getWriter();
@@ -59,6 +66,13 @@
         }
     }
 
+    /** Render synthetic resource */ 
+    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());

Added: incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/SyntheticResourceTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/SyntheticResourceTest.java?rev=602927&view=auto
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/SyntheticResourceTest.java (added)
+++ incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/SyntheticResourceTest.java Mon Dec 10 07:15:02 2007
@@ -0,0 +1,77 @@
+/*
+ * 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.microsling.integration;
+
+import java.io.IOException;
+
+import org.apache.sling.microsling.resource.SyntheticResourceProvider;
+
+/** Test the SLING-129 {@link SyntheticResources}, by requesting
+ *  non-existent Nodes that match the "configured" path
+ *  patterns of the  {@link SyntheticResourceProvider}.
+ */
+public class SyntheticResourceTest extends MicroslingHttpTestBase {
+
+    /** recurse random URLs under basePath, going nLevels deep,
+     *  and check that we get the specified status for every URL
+     * @throws IOException 
+     */ 
+    private void assertDeepGetStatus(String basePath, int nLevels, int expectedStatus, String urlSuffix) throws IOException {
+        String path = basePath;
+        for(int level=1; level <= nLevels; level++) {
+            final String url = HTTP_BASE_URL + path + urlSuffix; 
+            assertHttpStatus(url, expectedStatus,"Unexpected status at URL=" + url);
+            basePath += "/level_" + level + "_" + (int)(Math.random() * Integer.MAX_VALUE);
+        }
+    }
+    
+    public void testSearchSyntheticResource() throws IOException {
+        // build a very random deep URL under /search and
+        // verify that we get a 200 every time
+        assertDeepGetStatus("/search",10,200,"");
+    }
+    
+    public void testSearchSyntheticResourceHtml() throws IOException {
+        // build a very random deep URL under /search and
+        // verify that we get a 200 every time
+        assertDeepGetStatus("/search",10,200,".html");
+        assertDeepGetStatus("/search",10,200,".a4.print.html");
+    }
+    
+    public void testSearchSyntheticResourceJson() throws IOException {
+        // build a very random deep URL under /search and
+        // verify that we get a 200 every time
+        assertDeepGetStatus("/search",10,200,".json");
+        assertDeepGetStatus("/search",10,200,".a4.print.json");
+    }
+    
+    public void testSearchSyntheticResourceTxt() throws IOException {
+        // build a very random deep URL under /search and
+        // verify that we get a 200 every time
+        assertDeepGetStatus("/search",10,200,".txt");
+        assertDeepGetStatus("/search",10,200,".a4.print.txt");
+    }
+    
+    public void testNoSyntheticResourceTest() throws IOException {
+        // walk down a random path, verify that we 
+        // get 404s all the time
+        final String basePath = "/" + getClass().getSimpleName() + "_" + System.currentTimeMillis() + "/" + (int)(Math.random() * Integer.MAX_VALUE);
+        assertDeepGetStatus(basePath,10,404,"");
+    }
+}

Propchange: incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/SyntheticResourceTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/SyntheticResourceTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL