Return-Path: Delivered-To: apmail-incubator-sling-commits-archive@locus.apache.org Received: (qmail 50298 invoked from network); 5 May 2008 06:56:55 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 5 May 2008 06:56:55 -0000 Received: (qmail 57246 invoked by uid 500); 5 May 2008 06:56:56 -0000 Delivered-To: apmail-incubator-sling-commits-archive@incubator.apache.org Received: (qmail 57198 invoked by uid 500); 5 May 2008 06:56:56 -0000 Mailing-List: contact sling-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: sling-dev@incubator.apache.org Delivered-To: mailing list sling-commits@incubator.apache.org Received: (qmail 57189 invoked by uid 99); 5 May 2008 06:56:56 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 04 May 2008 23:56:56 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 05 May 2008 06:56:09 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 9EEEB2388A2E; Sun, 4 May 2008 23:56:29 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r653315 - in /incubator/sling/trunk: launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/ scripting/jst/src/main/java/org/apache/sling/scripting/jst/ sling/servlets-get/src/main/java/org/apache/sling/servlets/ s... Date: Mon, 05 May 2008 06:56:29 -0000 To: sling-commits@incubator.apache.org From: fmeschbe@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080505065629.9EEEB2388A2E@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: fmeschbe Date: Sun May 4 23:56:28 2008 New Revision: 653315 URL: http://svn.apache.org/viewvc?rev=653315&view=rev Log: SLING-419 Create new default GET servlet dispatching itself depending on the request extension. plus: adapt the Integration Testcases which depend - hard coded - on the name of the HTML renderer class. plus: adapt JstScriptEngine which also depends on the HTML renderer Added: incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/DefaultGetServlet.java incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/HtmlRendererServlet.java incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/JsonRendererServlet.java incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/PlainTextRendererServlet.java incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/StreamRendererServlet.java Removed: incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/DefaultHtmlRendererServlet.java incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/JsonRendererServlet.java incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/PlainTextRendererServlet.java incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/StreamRendererServlet.java incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/DefaultHtmlRenderer.java Modified: incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/CreateNodeTest.java incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/GetStarTest.java incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/NodetypeRenderingTest.java incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/PathBasedResourceTypeTest.java incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/JstScriptEngine.java incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/JsonQueryServlet.java incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/RedirectServlet.java Modified: incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/CreateNodeTest.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/CreateNodeTest.java?rev=653315&r1=653314&r2=653315&view=diff ============================================================================== --- incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/CreateNodeTest.java (original) +++ incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/CreateNodeTest.java Sun May 4 23:56:28 2008 @@ -56,9 +56,9 @@ getContent(urlOfNewNode + ".json", CONTENT_TYPE_JSON); // And extensions for which we have no renderer fail - assertHttpStatus(urlOfNewNode + ".xml", 404); - assertHttpStatus(urlOfNewNode + ".pdf", 404); - assertHttpStatus(urlOfNewNode + ".someWeirdExtension", 404); + assertHttpStatus(urlOfNewNode + ".xml", 500); + assertHttpStatus(urlOfNewNode + ".pdf", 500); + assertHttpStatus(urlOfNewNode + ".someWeirdExtension", 500); } public void testCreateNodeMultipart() throws IOException { Modified: incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/GetStarTest.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/GetStarTest.java?rev=653315&r1=653314&r2=653315&view=diff ============================================================================== --- incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/GetStarTest.java (original) +++ incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/GetStarTest.java Sun May 4 23:56:28 2008 @@ -46,7 +46,7 @@ { final String content = getContent(fakeNodePath, CONTENT_TYPE_HTML); assertTrue("Without script, default renderer marker must be present (" + content + ")", - content.contains("Node dumped by DefaultHtmlRenderer")); + content.contains("Node dumped by HtmlRendererServlet")); } final String urlToDelete = uploadTestScript(scriptPath, "rendering-test.esp", "html.esp"); Modified: incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/NodetypeRenderingTest.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/NodetypeRenderingTest.java?rev=653315&r1=653314&r2=653315&view=diff ============================================================================== --- incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/NodetypeRenderingTest.java (original) +++ incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/NodetypeRenderingTest.java Sun May 4 23:56:28 2008 @@ -56,7 +56,7 @@ public void testWithoutScriptHtml() throws IOException { final String content = getContent(displayUrl + ".html", CONTENT_TYPE_HTML); - assertTrue("Content contains default rendering",content.contains("Node dumped by DefaultHtmlRenderer")); + assertTrue("Content contains default rendering",content.contains("Node dumped by HtmlRendererServlet")); } public void testMiniScriptHtml() throws IOException { Modified: incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/PathBasedResourceTypeTest.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/PathBasedResourceTypeTest.java?rev=653315&r1=653314&r2=653315&view=diff ============================================================================== --- incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/PathBasedResourceTypeTest.java (original) +++ incubator/sling/trunk/launchpad/webapp/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/PathBasedResourceTypeTest.java Sun May 4 23:56:28 2008 @@ -40,7 +40,7 @@ // without script -> default rendering String content = getContent(tn.nodeUrl + ".html", CONTENT_TYPE_HTML); - assertTrue("Content contains default rendering",content.contains("Node dumped by DefaultHtmlRenderer")); + assertTrue("Content contains default rendering",content.contains("Node dumped by HtmlRendererServlet")); // check default resource type final String scriptPath = "/apps/" + testPath; Modified: incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/JstScriptEngine.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/JstScriptEngine.java?rev=653315&r1=653314&r2=653315&view=diff ============================================================================== --- incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/JstScriptEngine.java (original) +++ incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/JstScriptEngine.java Sun May 4 23:56:28 2008 @@ -43,7 +43,7 @@ import org.apache.sling.commons.json.jcr.JsonItemWriter; import org.apache.sling.scripting.api.AbstractSlingScriptEngine; import org.apache.sling.scripting.javascript.io.EspReader; -import org.apache.sling.servlets.helpers.DefaultHtmlRenderer; +import org.apache.sling.servlets.helpers.HtmlRendererServlet; /** Experimental JST script engine: converts a JST template (using the * same templating syntax as ESP) to client-side javascript code @@ -54,7 +54,7 @@ public class JstScriptEngine extends AbstractSlingScriptEngine { private final List libraryScripts = new LinkedList(); - private final DefaultHtmlRenderer htmlRenderer; + private final HtmlRendererServlet htmlRenderer; private final ScriptFilteredCopy copier = new ScriptFilteredCopy(); // TODO should be configurable or synced with the actual location @@ -64,7 +64,7 @@ super(scriptEngineFactory); libraryScripts.add(SLING_JS_PATH); - htmlRenderer = new DefaultHtmlRenderer(); + htmlRenderer = new HtmlRendererServlet(); } public Object eval(Reader script, ScriptContext context) throws ScriptException { Added: incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/DefaultGetServlet.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/DefaultGetServlet.java?rev=653315&view=auto ============================================================================== --- incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/DefaultGetServlet.java (added) +++ incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/DefaultGetServlet.java Sun May 4 23:56:28 2008 @@ -0,0 +1,127 @@ +/* + * 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.util.HashMap; +import java.util.Map; + +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.servlets.SlingSafeMethodsServlet; +import org.apache.sling.servlets.helpers.HtmlRendererServlet; +import org.apache.sling.servlets.helpers.JsonRendererServlet; +import org.apache.sling.servlets.helpers.PlainTextRendererServlet; +import org.apache.sling.servlets.helpers.StreamRendererServlet; + +/** + * A SlingSafeMethodsServlet that renders the current Resource as simple HTML + * + * @scr.component immediate="true" metatype="false" + * @scr.service interface="javax.servlet.Servlet" + * + * @scr.property name="service.description" value="Default GET Servlet" + * @scr.property name="service.vendor" value="The Apache Software Foundation" + * + * Use this as a default servlet for Sling + * @scr.property name="sling.servlet.resourceTypes" + * value="sling/servlet/default" + * + * Generic handler for all get requests + * @scr.property name="sling.servlet.methods" value="GET" + */ +public class DefaultGetServlet extends SlingSafeMethodsServlet { + + private static final long serialVersionUID = -5815904221043005085L; + + private Map rendererMap = new HashMap(); + + private Servlet streamerServlet; + + @Override + public void init() throws ServletException { + super.init(); + + // Register renderer servlets + setupServlet(rendererMap, HtmlRendererServlet.EXT_HTML, + new HtmlRendererServlet()); + setupServlet(rendererMap, PlainTextRendererServlet.EXT_TXT, + new PlainTextRendererServlet()); + setupServlet(rendererMap, JsonRendererServlet.EXT_JSON, + new JsonRendererServlet()); + setupServlet(rendererMap, StreamRendererServlet.EXT_RES, + new StreamRendererServlet()); + + // use the servlet for rendering StreamRendererServlet.EXT_RES as the + // streamer servlet + streamerServlet = rendererMap.get(StreamRendererServlet.EXT_RES); + } + + @Override + protected void doGet(SlingHttpServletRequest request, + SlingHttpServletResponse response) throws ServletException, + IOException { + + Servlet rendererServlet; + String ext = request.getRequestPathInfo().getExtension(); + if (ext == null) { + rendererServlet = streamerServlet; + } else { + rendererServlet = rendererMap.get(ext); + } + + // fail if we should not just stream or we cannot support the ext. + if (rendererServlet == null) { + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, + "No renderer for extension='" + ext + "'"); + return; + } + + rendererServlet.service(request, response); + } + + @Override + public void destroy() { + + for (Servlet servlet : rendererMap.values()) { + try { + servlet.destroy(); + } catch (Throwable t) { + // TODO: log + } + } + + streamerServlet = null; + rendererMap.clear(); + + super.destroy(); + } + + private void setupServlet(Map rendererMap, String key, + Servlet servlet) { + try { + servlet.init(getServletConfig()); + rendererMap.put(key, servlet); + } catch (Throwable t) { + // TODO: log + } + } +} Modified: incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/JsonQueryServlet.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/JsonQueryServlet.java?rev=653315&r1=653314&r2=653315&view=diff ============================================================================== --- incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/JsonQueryServlet.java (original) +++ incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/JsonQueryServlet.java Sun May 4 23:56:28 2008 @@ -39,18 +39,20 @@ import org.apache.sling.commons.json.JSONException; import org.apache.sling.commons.json.io.JSONWriter; import org.apache.sling.jcr.resource.JcrResourceUtil; +import org.apache.sling.servlets.helpers.JsonRendererServlet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A SlingSafeMethodsServlet that renders the search results as JSON data * - * @scr.service interface="javax.servlet.Servlet" * @scr.component immediate="true" metatype="false" + * @scr.service interface="javax.servlet.Servlet" + * * @scr.property name="service.description" value="Default Query Servlet" * @scr.property name="service.vendor" value="The Apache Software Foundation" - * Use this as the default query servlet for json get requests for - * Sling + * + * Use this as the default query servlet for json get requests for Sling * @scr.property name="sling.servlet.resourceTypes" * value="sling/servlet/default" * @scr.property name="sling.servlet.extensions" value="json" Modified: incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/RedirectServlet.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/RedirectServlet.java?rev=653315&r1=653314&r2=653315&view=diff ============================================================================== --- incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/RedirectServlet.java (original) +++ incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/RedirectServlet.java Sun May 4 23:56:28 2008 @@ -22,6 +22,7 @@ import javax.jcr.Node; import javax.jcr.RepositoryException; +import javax.servlet.Servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServletResponse; @@ -30,6 +31,7 @@ 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.servlets.helpers.JsonRendererServlet; /** * The RedirectServlet implements support for GET requests to @@ -52,10 +54,12 @@ * 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.service interface="javax.servlet.Servlet" + * * @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" */ @@ -64,11 +68,19 @@ /** The name of the target property */ public static final String TARGET_PROP = "sling:target"; + private Servlet jsonRendererServlet; + @Override protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { + // handle json export of the redirect node + if (JsonRendererServlet.EXT_JSON.equals(request.getRequestPathInfo().getExtension())) { + getJsonRendererServlet().service(request, response); + return; + } + Resource targetResource = request.getResourceResolver().getResource( request.getResource(), TARGET_PROP); if (targetResource == null) { @@ -195,4 +207,17 @@ pathBuffer.append(tParts[i]); } } + + private Servlet getJsonRendererServlet() { + if (jsonRendererServlet == null) { + Servlet jrs = new JsonRendererServlet(); + try { + jrs.init(getServletConfig()); + } catch (Exception e) { + // don't care too much here + } + jsonRendererServlet = jrs; + } + return jsonRendererServlet; + } } Added: incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/HtmlRendererServlet.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/HtmlRendererServlet.java?rev=653315&view=auto ============================================================================== --- incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/HtmlRendererServlet.java (added) +++ incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/HtmlRendererServlet.java Sun May 4 23:56:28 2008 @@ -0,0 +1,134 @@ +/* + * 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.helpers; + +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; + +/** + * The HtmlRendererServlet renders the current resource in HTML + * on behalf of the {@link org.apache.sling.servlets.DefaultGetServlet}. + */ +public class HtmlRendererServlet extends SlingSafeMethodsServlet { + + private static final long serialVersionUID = -5815904221043005085L; + + public static final String EXT_HTML = "html"; + + private static final String responseContentType = "text/html"; + + @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(""); + render(pw, r, node); + pw.println(""); + + } else if (p != null) { + // for properties, we just output the String value + render(pw, r, p); + } + + } catch (RepositoryException re) { + throw new ServletException("Cannot dump contents of " + + req.getResource().getPath(), re); + } + } + + public void render(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("

Node properties

"); + for (PropertyIterator pi = n.getProperties(); pi.hasNext();) { + final Property p = pi.nextProperty(); + printPropertyValue(pw, 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("

Property dumped by " + getClass().getSimpleName() + + "

"); + pw.println("

Property path:" + p.getPath() + "

"); + pw.println("

Resource metadata: " + r.getResourceMetadata() + "

"); + + printPropertyValue(pw, p); + } + + protected void printPropertyValue(PrintWriter pw, Property p) + throws RepositoryException { + + 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()); + } + + pw.print("
"); + } + +} Added: incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/JsonRendererServlet.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/JsonRendererServlet.java?rev=653315&view=auto ============================================================================== --- incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/JsonRendererServlet.java (added) +++ incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/JsonRendererServlet.java Sun May 4 23:56:28 2008 @@ -0,0 +1,139 @@ +/* + * 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.helpers; + +import java.io.IOException; + +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.RepositoryException; +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; + +/** + * The JsonRendererServlet renders the current resource in JSON + * on behalf of the {@link org.apache.sling.servlets.DefaultGetServlet}. + */ +public class JsonRendererServlet extends SlingSafeMethodsServlet { + + private final Logger log = LoggerFactory.getLogger(JsonRendererServlet.class); + + private static final long serialVersionUID = 5577121546674133317L; + + public static final String EXT_JSON = "json"; + + public 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; + } + + // Send empty response if we don't have a Node + final Node n = r.adaptTo(Node.class); + if (n == null) { + resp.setContentType(responseContentType); + resp.setCharacterEncoding("UTF-8"); + 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); + } +} Added: incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/PlainTextRendererServlet.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/PlainTextRendererServlet.java?rev=653315&view=auto ============================================================================== --- incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/PlainTextRendererServlet.java (added) +++ incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/PlainTextRendererServlet.java Sun May 4 23:56:28 2008 @@ -0,0 +1,134 @@ +/* + * 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.helpers; + +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; + +/** + * The PlainTextRendererServlet renders the current resource in + * plain text on behalf of the + * {@link org.apache.sling.servlets.DefaultGetServlet}. + */ +public class PlainTextRendererServlet extends SlingSafeMethodsServlet { + + private static final long serialVersionUID = -5815904221043005085L; + + public static final String EXT_TXT = "txt"; + + 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()); + } + } +} Added: incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/StreamRendererServlet.java URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/StreamRendererServlet.java?rev=653315&view=auto ============================================================================== --- incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/StreamRendererServlet.java (added) +++ incubator/sling/trunk/sling/servlets-get/src/main/java/org/apache/sling/servlets/helpers/StreamRendererServlet.java Sun May 4 23:56:28 2008 @@ -0,0 +1,160 @@ +/* + * 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.helpers; + +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.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 StreamRendererServlet streams the current resource to the + * client on behalf of the {@link org.apache.sling.servlets.DefaultGetServlet}. + * If the current resource cannot be streamed it is rendered using the + * {@link PlainTextRendererServlet}. + */ +public class StreamRendererServlet extends PlainTextRendererServlet { + + public static final String EXT_RES = "res"; + + 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(EXT_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); + } + + long length = meta.getContentLength(); + if (length > 0 && length < Integer.MAX_VALUE) { + response.setContentLength((int) length); + } + + 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 true if the request has a + * If-Modified-Since header whose date value is later than + * the last modification time given as modifTime. + * + * @param request The ComponentRequest checked for the + * If-Modified-Since header. + * @param modifTime The last modification time to compare the header to. + * @return true if the modifTime is less than + * or equal to the time of the If-Modified-Since + * 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