Author: cziegeler
Date: Fri Aug 22 10:46:39 2008
New Revision: 688134
URL: http://svn.apache.org/viewvc?rev=688134&view=rev
Log:
SLING-620 - Use resource abstraction and value map for get servlets.
Added:
incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/JsonResourceWriter.java
(with props)
Modified:
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/GetStarTest.java
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/NodetypeRenderingTest.java
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/PathBasedResourceTypeTest.java
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/PropertyRenderingTest.java
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/SlingResourceTypeRenderingTest.java
incubator/sling/trunk/servlets/get/pom.xml
incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/HtmlRendererServlet.java
incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/JsonRendererServlet.java
incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/PlainTextRendererServlet.java
Modified:
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java?rev=688134&r1=688133&r2=688134&view=diff
==============================================================================
---
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java
(original)
+++
incubator/sling/trunk/jcr/resource/src/main/java/org/apache/sling/jcr/resource/JcrPropertyMap.java
Fri Aug 22 10:46:39 2008
@@ -22,7 +22,7 @@
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -30,6 +30,7 @@
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
+import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
@@ -51,7 +52,7 @@
public JcrPropertyMap(Node node) {
this.node = node;
- this.cache = new HashMap<String, Object>();
+ this.cache = new LinkedHashMap<String, Object>();
this.fullyRead = false;
}
@@ -244,10 +245,10 @@
boolean array = type.isArray();
if (array && multiValue) {
- return (T) convertToArray(prop.getValues(),
+ return (T) convertToArray(prop, prop.getValues(),
type.getComponentType());
} else if (!array && !multiValue) {
- return convertToType(prop.getValue(), type);
+ return convertToType(prop, -1, prop.getValue(), type);
}
}
@@ -262,11 +263,11 @@
return null;
}
- private <T> T[] convertToArray(Value[] jcrValues, Class<T> type)
+ private <T> T[] convertToArray(Property p, Value[] jcrValues, Class<T>
type)
throws ValueFormatException, RepositoryException {
List<T> values = new ArrayList<T>();
for (int i = 0; i < jcrValues.length; i++) {
- T value = convertToType(jcrValues[i], type);
+ T value = convertToType(p, i, jcrValues[i], type);
if (value != null) {
values.add(value);
}
@@ -279,12 +280,18 @@
}
@SuppressWarnings("unchecked")
- private <T> T convertToType(Value jcrValue, Class<T> type)
+ private <T> T convertToType(Property p, int index, Value jcrValue,
Class<T> type)
throws ValueFormatException, RepositoryException {
if (String.class == type) {
return (T) jcrValue.getString();
} else if (Long.class == type) {
+ if ( jcrValue.getType() == PropertyType.BINARY ) {
+ if ( index == -1 ) {
+ return (T)new Long(p.getLength());
+ }
+ return (T)new Long(p.getLengths()[index]);
+ }
return (T) new Long(jcrValue.getLong());
} else if (Double.class == type) {
return (T) new Double(jcrValue.getDouble());
Modified:
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/GetStarTest.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/GetStarTest.java?rev=688134&r1=688133&r2=688134&view=diff
==============================================================================
---
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/GetStarTest.java
(original)
+++
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/GetStarTest.java
Fri Aug 22 10:46:39 2008
@@ -25,30 +25,30 @@
*/
public class GetStarTest extends HttpTestBase {
private final String random = getClass().getSimpleName() +
String.valueOf(System.currentTimeMillis());
-
+
public void testGetStarHtml() throws IOException {
getContent(HTTP_BASE_URL + "/*.html", CONTENT_TYPE_HTML);
getContent(HTTP_BASE_URL + "/" + random + "/*.html",
CONTENT_TYPE_HTML);
getContent(HTTP_BASE_URL + "/" + random + "/" + random + "/*.html",
CONTENT_TYPE_HTML);
getContent(HTTP_BASE_URL + "/" + random + "/*.someselector.html",
CONTENT_TYPE_HTML);
}
-
+
public void testGetStarJson() throws IOException {
getContent(HTTP_BASE_URL + "/*.json", CONTENT_TYPE_JSON);
getContent(HTTP_BASE_URL + "/" + random + "/*.json",
CONTENT_TYPE_JSON);
getContent(HTTP_BASE_URL + "/" + random + "/*.12.json",
CONTENT_TYPE_JSON);
}
-
+
public void testGetStarWithScript() throws IOException {
final String scriptPath = "/apps/" + random;
testClient.mkdirs(WEBDAV_BASE_URL, scriptPath);
urlsToDelete.add(WEBDAV_BASE_URL + scriptPath);
- final String fakeNodePath = HTTP_BASE_URL + "/sling-test-pbrt/" +
random + "/something/*.html";
+ final String fakeNodePath = HTTP_BASE_URL + "/sling-test-pbrt/" +
random + "/something/*.html";
{
final String content = getContent(fakeNodePath, CONTENT_TYPE_HTML);
assertTrue("Without script, default renderer marker must be
present (" + content + ")",
- content.contains("Node dumped by HtmlRendererServlet"));
+ content.contains("Resource dumped by
HtmlRendererServlet"));
}
final String urlToDelete = uploadTestScript(scriptPath,
"rendering-test.esp", "html.esp");
@@ -59,7 +59,7 @@
} finally {
testClient.delete(urlToDelete);
}
-
+
}
}
Modified:
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/NodetypeRenderingTest.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/NodetypeRenderingTest.java?rev=688134&r1=688133&r2=688134&view=diff
==============================================================================
---
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/NodetypeRenderingTest.java
(original)
+++
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/NodetypeRenderingTest.java
Fri Aug 22 10:46:39 2008
@@ -29,7 +29,7 @@
public class NodetypeRenderingTest extends RenderingTestBase {
private String secondFolderOfContentPath;
-
+
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -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 HtmlRendererServlet"));
+ assertTrue("Content contains default
rendering",content.contains("Resource dumped by HtmlRendererServlet"));
}
public void testMiniScriptHtml() throws IOException {
@@ -90,15 +90,15 @@
testClient.delete(toDelete);
}
}
-
+
public void TODO_FAILS_testEspHtmlWithContentBasedPath() throws
IOException {
-
+
// make sure there's no leftover rendering script
{
final String content = getContent(displayUrl + ".html",
CONTENT_TYPE_HTML);
assertFalse("Content must not include ESP marker before
test",content.contains("ESP template"));
}
-
+
// put our script in the /apps/<second folder level of content>
(SLING-125)
final String path = "/apps/" + secondFolderOfContentPath;
testClient.mkdirs(WEBDAV_BASE_URL, path);
Modified:
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/PathBasedResourceTypeTest.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/PathBasedResourceTypeTest.java?rev=688134&r1=688133&r2=688134&view=diff
==============================================================================
---
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/PathBasedResourceTypeTest.java
(original)
+++
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/PathBasedResourceTypeTest.java
Fri Aug 22 10:46:39 2008
@@ -27,10 +27,10 @@
*/
public class PathBasedResourceTypeTest extends HttpTestBase {
-
+
public static final String testPath = "sling-integration-test-" +
System.currentTimeMillis();
public static final String contentPath = "/sling-test-pbrt/" + testPath;
-
+
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -39,11 +39,11 @@
public void testDefaultResourceType() throws IOException {
final TestNode tn = new TestNode(HTTP_BASE_URL + contentPath, null);
-
+
// without script -> default rendering
String content = getContent(tn.nodeUrl + ".html", CONTENT_TYPE_HTML);
- assertTrue("Content contains default rendering",content.contains("Node
dumped by HtmlRendererServlet"));
-
+ assertTrue("Content contains default
rendering",content.contains("Resource dumped by HtmlRendererServlet"));
+
// check default resource type
final String scriptPath = "/apps/" + testPath;
testClient.mkdirs(WEBDAV_BASE_URL, scriptPath);
@@ -56,14 +56,14 @@
testClient.delete(urlsToDelete);
}
}
-
+
public void testExplicitResourceType() throws IOException {
-
+
final String resourceType = getClass().getSimpleName();
final Map<String, String> properties = new HashMap<String, String>();
properties.put(SLING_RESOURCE_TYPE, resourceType);
final TestNode tn = new TestNode(HTTP_BASE_URL + contentPath,
properties);
-
+
urlsToDelete.add(uploadTestScript(tn.scriptPath,
"rendering-test-2.esp", "html.esp"));
final String content = getContent(tn.nodeUrl + ".html",
CONTENT_TYPE_HTML);
assertTrue("Test script marker found in content (" + content +
")",content.contains("Template #2 for ESP tests"));
Modified:
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/PropertyRenderingTest.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/PropertyRenderingTest.java?rev=688134&r1=688133&r2=688134&view=diff
==============================================================================
---
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/PropertyRenderingTest.java
(original)
+++
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/PropertyRenderingTest.java
Fri Aug 22 10:46:39 2008
@@ -49,7 +49,7 @@
final String json = getContent(displayUrl + ".json",
CONTENT_TYPE_JSON);
assertJavascript(testText, json, "out.println(data.text)");
}
-
+
public void testTextJson() throws IOException {
final String json = getContent(displayUrl + "/text.json",
CONTENT_TYPE_JSON);
assertEquals("{\"text\":\"" + testText + "\"}",json);
@@ -57,19 +57,19 @@
public void testTextHtml() throws IOException {
final String data = getContent(displayUrl + "/text.html",
CONTENT_TYPE_HTML);
- assertEquals(testText, data);
+ assertTrue(data.contains(testText));
}
-
+
public void testTextTxt() throws IOException {
final String data = getContent(displayUrl + "/text.txt",
CONTENT_TYPE_PLAIN);
assertEquals(testText, data);
}
-
+
public void testTextNoExt() throws IOException {
final String data = getContent(displayUrl + "/text", null);
assertEquals(testText, data);
}
-
+
public void testResourceTypeNoExt() throws IOException {
final String data = getContent(displayUrl + "/sling:resourceType",
null);
assertEquals(slingResourceType, data);
Modified:
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/SlingResourceTypeRenderingTest.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/SlingResourceTypeRenderingTest.java?rev=688134&r1=688133&r2=688134&view=diff
==============================================================================
---
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/SlingResourceTypeRenderingTest.java
(original)
+++
incubator/sling/trunk/launchpad/testing/src/test/java/org/apache/sling/launchpad/webapp/integrationtest/SlingResourceTypeRenderingTest.java
Fri Aug 22 10:46:39 2008
@@ -59,7 +59,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 HtmlRendererServlet"));
+ assertTrue("Content contains default
rendering",content.contains("Resource dumped by HtmlRendererServlet"));
}
public void testEspHtml() throws IOException {
@@ -107,13 +107,13 @@
}
public void TODO_FAILS_testEspHtmlWithContentBasedPath() throws
IOException {
-
+
// make sure there's no leftover rendering script
{
final String content = getContent(displayUrl + ".html",
CONTENT_TYPE_HTML);
assertFalse("Content must not include ESP marker before
test",content.contains("ESP template"));
}
-
+
// put our script in the /apps/<second folder level of content>
(SLING-125)
final String path = "/apps/" + secondFolderOfContentPath;
testClient.mkdirs(WEBDAV_BASE_URL, path);
@@ -132,20 +132,20 @@
final String toDeleteA =
uploadTestScript("rendering-test.esp","html.esp");
final String toDeleteB =
uploadTestScript("rendering-test-2.esp","a4.esp");
final String toDeleteC =
uploadTestScript("rendering-test-3.esp","a4/print.esp");
-
+
try {
String content = getContent(displayUrl + ".html",
CONTENT_TYPE_HTML);
assertTrue("Without selectors, content includes standard
marker",content.contains("ESP template"));
assertTrue("Without selectors, content contains formatted test
text",content.contains("<p>" + testText + "</p>"));
-
+
content = getContent(displayUrl + ".a4.print.html",
CONTENT_TYPE_HTML);
assertTrue("With a4.print selectors, content includes marker
3",content.contains("Template #3 for ESP tests"));
assertTrue("With a4.print selectors, content contains italic
text",content.contains("<em>" + testText + "</em>"));
-
+
content = getContent(displayUrl + ".a4.html", CONTENT_TYPE_HTML);
assertTrue("With a4 selector, content includes marker
2",content.contains("Template #2 for ESP tests"));
assertTrue("With a4 selector, content contains bold
text",content.contains("<b>" + testText + "</b>"));
-
+
content = getContent(displayUrl + ".different.html",
CONTENT_TYPE_HTML);
assertTrue("With different selector only, content includes
standard marker",content.contains("ESP template"));
assertTrue("With different selector only, content contains
formatted test text",content.contains("<p>" + testText + "</p>"));
@@ -177,9 +177,9 @@
assertTrue("Content contains scripted stuff (" + content + ")",
content.contains("something scripted"));
assertFalse("Script opening tag must be broken in two in content
(" + content + ")",
- content.contains("<script>something"));
+ content.contains("<script>something"));
assertFalse("Script closing tag must be broken in two in content
(" + content + ")",
- content.contains("scripted</script>"));
+ content.contains("scripted</script>"));
} finally {
testClient.delete(toDelete);
}
@@ -194,9 +194,9 @@
assertTrue("Content contains scripted stuff (" + content + ")",
content.contains("more scripting"));
assertFalse("Script opening tag must be broken in two in content
(" + content + ")",
- content.contains("<script>more"));
+ content.contains("<script>more"));
assertFalse("Script closing tag must be broken in two in content
(" + content + ")",
- content.contains("scripting</script>"));
+ content.contains("scripting</script>"));
} finally {
testClient.delete(toDelete);
}
Modified: incubator/sling/trunk/servlets/get/pom.xml
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/servlets/get/pom.xml?rev=688134&r1=688133&r2=688134&view=diff
==============================================================================
--- incubator/sling/trunk/servlets/get/pom.xml (original)
+++ incubator/sling/trunk/servlets/get/pom.xml Fri Aug 22 10:46:39 2008
@@ -93,7 +93,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.api</artifactId>
- <version>2.0.2-incubator</version>
+ <version>2.0.3-incubator-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
Modified:
incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/HtmlRendererServlet.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/HtmlRendererServlet.java?rev=688134&r1=688133&r2=688134&view=diff
==============================================================================
---
incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/HtmlRendererServlet.java
(original)
+++
incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/HtmlRendererServlet.java
Fri Aug 22 10:46:39 2008
@@ -18,12 +18,9 @@
import java.io.IOException;
import java.io.PrintWriter;
+import java.util.Iterator;
+import java.util.Map;
-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;
@@ -53,79 +50,55 @@
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>");
- render(pw, r, node);
- pw.println("</body></html>");
-
- } 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("<h1>Node dumped by " + getClass().getSimpleName() +
"</h1>");
- pw.println("<p>Node path: <b>" + n.getPath() + "</b></p>");
+ pw.println("<html><body>");
+ pw.println("<h1>Resource dumped by " + getClass().getSimpleName() +
"</h1>");
+ pw.println("<p>Resource path: <b>" + r.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);
+ @SuppressWarnings("unchecked")
+ final Map map = r.adaptTo(Map.class);
+ if ( map != null ) {
+ render(pw, r, map);
+ } else if ( r.adaptTo(String.class) != null ) {
+ render(pw, r, r.adaptTo(String.class));
+ } else {
+ pw.println("<p>Resource can't be adapted to a map or a
string.</p>");
}
+ pw.println("</body></html>");
}
- public void render(PrintWriter pw, Resource r, Property p)
- throws RepositoryException {
- pw.print(p.getValue().getString());
+ @SuppressWarnings("unchecked")
+ private void render(PrintWriter pw, Resource r, Map map) {
+ pw.println("<h2>Resource properties</h2>");
+ final Iterator<Map.Entry> pi = map.entrySet().iterator();
+ while ( pi.hasNext() ) {
+ final Map.Entry p = pi.next();
+ printPropertyValue(pw, p.getKey().toString(), p.getValue());
+ pw.println();
+ }
}
- 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);
+ private void render(PrintWriter pw, Resource r, String value) {
+ printPropertyValue(pw, "Resource Value", value);
}
- protected void printPropertyValue(PrintWriter pw, Property p)
- throws RepositoryException {
+ private void printPropertyValue(PrintWriter pw, String name, Object value)
{
- pw.print(p.getName() + ": <b>");
+ pw.print(name + ": <b>");
- if (p.getDefinition().isMultiple()) {
- Value[] values = p.getValues();
+ if ( value.getClass().isArray() ) {
+ Object[] values = (Object[])value;
pw.print('[');
for (int i = 0; i < values.length; i++) {
if (i > 0) {
pw.print(", ");
}
- pw.print(values[i].getString());
+ pw.print(values[i].toString());
}
pw.print(']');
} else {
- pw.print(p.getValue().getString());
+ pw.print(value.toString());
}
pw.print("</b><br/>");
Modified:
incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/JsonRendererServlet.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/JsonRendererServlet.java?rev=688134&r1=688133&r2=688134&view=diff
==============================================================================
---
incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/JsonRendererServlet.java
(original)
+++
incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/JsonRendererServlet.java
Fri Aug 22 10:46:39 2008
@@ -18,9 +18,6 @@
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;
@@ -31,7 +28,6 @@
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;
@@ -46,10 +42,10 @@
private static final long serialVersionUID = 5577121546674133317L;
public static final String EXT_JSON = "json";
-
+
public static final String responseContentType = "application/json";
- private final JsonItemWriter itemWriter;
+ private final JsonResourceWriter itemWriter;
/** Recursion level selector that means "all levels" */
public static final String INFINITY = "infinity";
@@ -57,7 +53,7 @@
public static final String TIDY = "tidy";
public JsonRendererServlet() {
- itemWriter = new JsonItemWriter(null);
+ itemWriter = new JsonResourceWriter(null);
}
@Override
@@ -69,27 +65,6 @@
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;
@@ -116,14 +91,12 @@
// do the dump
try {
- itemWriter.dump(n, resp.getWriter(), maxRecursionLevels,
isTidy(req));
+ itemWriter.dump(r, resp.getWriter(), maxRecursionLevels,
isTidy(req));
} catch (JSONException je) {
reportException(je);
- } catch (RepositoryException re) {
- reportException(re);
}
}
-
+
/** True if our request wants the "tidy" pretty-printed format */
protected boolean isTidy(SlingHttpServletRequest req) {
for(String selector : req.getRequestPathInfo().getSelectors()) {
@@ -134,14 +107,6 @@
return false;
}
- /** 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
Added:
incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/JsonResourceWriter.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/JsonResourceWriter.java?rev=688134&view=auto
==============================================================================
---
incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/JsonResourceWriter.java
(added)
+++
incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/JsonResourceWriter.java
Fri Aug 22 10:46:39 2008
@@ -0,0 +1,249 @@
+/*
+ * 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.get.helpers;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.commons.json.JSONException;
+import org.apache.sling.commons.json.io.JSONWriter;
+
+/**
+ * Dumps JCR Items as JSON data. The dump methods are threadsafe.
+ */
+public class JsonResourceWriter {
+
+ private static DateFormat calendarFormat;
+
+ private final Set<String> propertyNamesToIgnore;
+
+ /** Used to format date values */
+ public static final String ECMA_DATE_FORMAT = "EEE MMM dd yyyy HH:mm:ss
'GMT'Z";
+
+ /** Used to format date values */
+ public static final Locale DATE_FORMAT_LOCALE = Locale.US;
+
+
+ /**
+ * Create a JsonItemWriter
+ *
+ * @param propertyNamesToIgnore if not null, a property having a name from
+ * this set of values is ignored. TODO we should use a filtering
+ * interface to make the selection of which Nodes and Properties
+ * to dump more flexible.
+ */
+ public JsonResourceWriter(Set<String> propertyNamesToIgnore) {
+ this.propertyNamesToIgnore = propertyNamesToIgnore;
+ }
+
+ /** Dump given resource in JSON, optionally recursing into its object */
+ public void dump(Resource resource, Writer w, int maxRecursionLevels)
+ throws JSONException {
+ dump(resource, w, maxRecursionLevels, false);
+ }
+
+ /**
+ * Dump given resource in JSON, optionally recursing into its objects
+ * @param tidy if <code>true</code> the json dump is nicely formatted
+ */
+ public void dump(Resource resource, Writer w, int maxRecursionLevels,
boolean tidy)
+ throws JSONException {
+ JSONWriter jw = new JSONWriter(w);
+ jw.setTidy(tidy);
+ dump(resource, jw, 0, maxRecursionLevels);
+ }
+
+ /** Dump given resource in JSON, optionally recursing into its objects */
+ protected void dump(Resource resource, JSONWriter w, int
currentRecursionLevel,
+ int maxRecursionLevels) throws JSONException {
+ final ValueMap valueMap = resource.adaptTo(ValueMap.class);
+ @SuppressWarnings("unchecked")
+ Map propertyMap = valueMap;
+ if ( propertyMap == null ) {
+ propertyMap = resource.adaptTo(Map.class);
+ }
+
+ if ( propertyMap == null ) {
+ // no map available, try string
+ final String value = resource.adaptTo(String.class);
+ if ( value != null ) {
+ w.object();
+ w.key(ResourceUtil.getName(resource));
+ w.value(value);
+ w.endObject();
+ }
+ return;
+ }
+ w.object();
+ @SuppressWarnings("unchecked")
+ final Iterator<Map.Entry> props = propertyMap.entrySet().iterator();
+
+ // the node's actual properties
+ while (props.hasNext()) {
+ @SuppressWarnings("unchecked")
+ final Map.Entry prop = props.next();
+
+ if (propertyNamesToIgnore != null
+ && propertyNamesToIgnore.contains(prop.getKey())) {
+ continue;
+ }
+
+ writeProperty(w, valueMap, prop.getKey().toString(),
prop.getValue());
+ }
+
+ // the child nodes
+ if (recursionLevelActive(currentRecursionLevel, maxRecursionLevels)) {
+ final Iterator<Resource> children =
ResourceUtil.listChildren(resource);
+ while (children.hasNext()) {
+ final Resource n = children.next();
+ dumpSingleResource(n, w, currentRecursionLevel,
maxRecursionLevels);
+ }
+ }
+
+ w.endObject();
+ }
+
+ /** Dump a single node */
+ protected void dumpSingleResource(Resource n, JSONWriter w,
+ int currentRecursionLevel, int maxRecursionLevels)
+ throws JSONException {
+ if (recursionLevelActive(currentRecursionLevel, maxRecursionLevels)) {
+ w.key(ResourceUtil.getName(n));
+ dump(n, w, currentRecursionLevel + 1, maxRecursionLevels);
+ }
+ }
+
+ /** true if the current recursion level is active */
+ protected boolean recursionLevelActive(int currentRecursionLevel,
+ int maxRecursionLevels) {
+ return maxRecursionLevels < 0
+ || currentRecursionLevel < maxRecursionLevels;
+ }
+
+ /**
+ * Write a single property
+ */
+ protected void writeProperty(JSONWriter w,
+ ValueMap valueMap,
+ String key,
+ Object value)
+ throws JSONException {
+ Object[] values = null;
+ if (value.getClass().isArray()) {
+ values = (Object[])value;
+ // write out empty array
+ if ( values.length == 0 ) {
+ w.key(key);
+ w.array();
+ w.endArray();
+ return;
+ }
+ }
+
+ // special handling for binaries: we dump the length and not the length
+ if (value instanceof InputStream
+ || (values != null && values[0] instanceof InputStream)) {
+ // TODO for now we mark binary properties with an initial colon in
+ // their name
+ // (colon is not allowed as a JCR property name)
+ // in the name, and the value should be the size of the binary data
+ w.key(":" + key);
+ if (values == null) {
+ writeLength(w, valueMap, -1, key, (InputStream)value);
+ } else {
+ w.array();
+ for (int i = 0; i < values.length; i++) {
+ writeLength(w, valueMap, i, key, (InputStream)values[i]);
+ }
+ w.endArray();
+ }
+ return;
+ }
+ w.key(key);
+
+ if (!value.getClass().isArray()) {
+ dumpValue(w, value);
+ } else {
+ w.array();
+ for (Object v : values) {
+ dumpValue(w, v);
+ }
+ w.endArray();
+ }
+ }
+
+ private void writeLength(JSONWriter w,
+ ValueMap valueMap,
+ int index,
+ String key,
+ InputStream stream)
+ throws JSONException {
+ try {
+ stream.close();
+ } catch (IOException ignore) {}
+ long length = -1;
+ if ( valueMap != null ) {
+ if ( index == -1 ) {
+ length = valueMap.get(key, length);
+ } else {
+ Long[] lengths = valueMap.get(key, Long[].class);
+ if ( lengths != null && lengths.length > index ) {
+ length = lengths[index];
+ }
+ }
+ }
+ w.value(length);
+ }
+
+ protected void dumpValue(JSONWriter w, Object value)
+ throws JSONException {
+ if ( value instanceof InputStream ) {
+ // input stream is already handled
+ w.value(0);
+ } else if ( value instanceof Calendar ) {
+ w.value(format((Calendar)value));
+ } else if ( value instanceof Boolean ) {
+ w.value(((Boolean)value).booleanValue());
+ } else if ( value instanceof Long ) {
+ w.value(((Long)value).longValue());
+ } else if ( value instanceof Integer ) {
+ w.value(((Integer)value).longValue());
+ } else if ( value instanceof Double ) {
+ w.value(((Double)value).doubleValue());
+ } else {
+ w.value(value.toString());
+ }
+ }
+
+ public static synchronized String format(Calendar date) {
+ if (calendarFormat == null) {
+ calendarFormat = new SimpleDateFormat(ECMA_DATE_FORMAT,
DATE_FORMAT_LOCALE);
+ }
+ return calendarFormat.format(date.getTime());
+ }
+}
Propchange:
incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/JsonResourceWriter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/JsonResourceWriter.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange:
incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/JsonResourceWriter.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified:
incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/PlainTextRendererServlet.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/PlainTextRendererServlet.java?rev=688134&r1=688133&r2=688134&view=diff
==============================================================================
---
incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/PlainTextRendererServlet.java
(original)
+++
incubator/sling/trunk/servlets/get/src/main/java/org/apache/sling/servlets/get/helpers/PlainTextRendererServlet.java
Fri Aug 22 10:46:39 2008
@@ -18,17 +18,15 @@
import java.io.IOException;
import java.io.PrintWriter;
+import java.util.Iterator;
+import java.util.Map;
-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.resource.ResourceUtil;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
/**
@@ -57,29 +55,21 @@
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);
- }
+ renderResource(pw, r);
}
- /** 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);
-
+ /** Render a resource (map or string) */
+ private void renderResource(PrintWriter pw, Resource r)
+ throws ServletException {
+ @SuppressWarnings("unchecked")
+ final Map map = r.adaptTo(Map.class);
+ if ( map != null ) {
+ dump(pw, r, map);
+ } else if ( r.adaptTo(String.class) != null ) {
+ printPropertyValue(pw, ResourceUtil.getName(r),
r.adaptTo(String.class), false);
} else {
throw new ServletException("Resource " + r
- + " does not adapt to a Node or a Property");
+ + " does not adapt to a map or string.");
}
}
@@ -91,44 +81,41 @@
* 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());
+ @SuppressWarnings("unchecked")
+ protected void dump(PrintWriter pw, Resource r, Map map) {
+ pw.println("** Resource dumped by " + getClass().getSimpleName() +
"**");
+ pw.println("Resource path:" + r.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("\n** Resource properties **");
+ final Iterator<Map.Entry> pi = map.entrySet().iterator();
+ while ( pi.hasNext() ) {
+ final Map.Entry p = pi.next();
+ printPropertyValue(pw, p.getKey().toString(), p.getValue(), 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 {
+ protected void printPropertyValue(PrintWriter pw, String name,
+ Object value,
+ boolean includeName) {
if (includeName) {
- pw.print(p.getName() + ": ");
+ pw.print(name + ": ");
}
- if (p.getDefinition().isMultiple()) {
- Value[] values = p.getValues();
+ if ( value.getClass().isArray() ) {
+ final Object[] values = (Object[])value;
pw.print('[');
for (int i = 0; i < values.length; i++) {
if (i > 0) {
pw.print(", ");
}
- pw.print(values[i].getString());
+ pw.print(values[i].toString());
}
pw.print(']');
} else {
- pw.print(p.getValue().getString());
+ pw.print(value.toString());
}
}
}