You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by ju...@apache.org on 2012/06/24 23:57:40 UTC

svn commit: r1353346 - in /jackrabbit/oak/trunk/oak-http: pom.xml src/main/java/org/apache/jackrabbit/oak/http/OakServlet.java

Author: jukka
Date: Sun Jun 24 21:57:39 2012
New Revision: 1353346

URL: http://svn.apache.org/viewvc?rev=1353346&view=rev
Log:
OAK-104: HTTP bindings for Oak

Add basic JSON read support

Modified:
    jackrabbit/oak/trunk/oak-http/pom.xml
    jackrabbit/oak/trunk/oak-http/src/main/java/org/apache/jackrabbit/oak/http/OakServlet.java

Modified: jackrabbit/oak/trunk/oak-http/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-http/pom.xml?rev=1353346&r1=1353345&r2=1353346&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-http/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-http/pom.xml Sun Jun 24 21:57:39 2012
@@ -92,6 +92,11 @@
       <version>2.0.0</version>
     </dependency>
     <dependency>
+      <groupId>com.fasterxml.jackson.dataformat</groupId>
+      <artifactId>jackson-dataformat-smile</artifactId>
+      <version>2.0.2</version>
+    </dependency>
+    <dependency>
       <groupId>javax.servlet</groupId>
       <artifactId>servlet-api</artifactId>
       <version>2.5</version>

Modified: jackrabbit/oak/trunk/oak-http/src/main/java/org/apache/jackrabbit/oak/http/OakServlet.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-http/src/main/java/org/apache/jackrabbit/oak/http/OakServlet.java?rev=1353346&r1=1353345&r2=1353346&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-http/src/main/java/org/apache/jackrabbit/oak/http/OakServlet.java (original)
+++ jackrabbit/oak/trunk/oak-http/src/main/java/org/apache/jackrabbit/oak/http/OakServlet.java Sun Jun 24 21:57:39 2012
@@ -16,11 +16,13 @@
  */
 package org.apache.jackrabbit.oak.http;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.PrintWriter;
+import java.io.InputStream;
 
 import javax.jcr.GuestCredentials;
 import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.PropertyType;
 import javax.security.auth.login.LoginException;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
@@ -29,11 +31,22 @@ import javax.servlet.http.HttpServletRes
 
 import org.apache.jackrabbit.oak.api.ContentRepository;
 import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.api.CoreValue;
 import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.Tree;
 
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.dataformat.smile.SmileFactory;
+
 public class OakServlet extends HttpServlet {
 
+    private static final JsonFactory JSON_FACTORY = new JsonFactory();
+
+    private static final JsonFactory SMILE_FACTORY = new SmileFactory();
+
     private final ContentRepository repository;
 
     public OakServlet(ContentRepository repository) {
@@ -47,17 +60,12 @@ public class OakServlet extends HttpServ
         try {
             ContentSession session = repository.login(new GuestCredentials(), null);
             try {
-                response.setContentType("text/plain");
-                PrintWriter writer = response.getWriter();
-                Tree tree =
-                        session.getCurrentRoot().getTree(request.getPathInfo());
+                Root root = session.getCurrentRoot();
+                Tree tree = root.getTree(request.getPathInfo());
                 if (tree != null) {
-                    for (PropertyState property : tree.getProperties()) {
-                        writer.print("- " + property.getName() + "\n");
-                    }
-                    for (Tree child : tree.getChildren()) {
-                        writer.print("+ " + child.getName() + "\n");
-                    }
+                    JsonGenerator generator = getRenderer(request, response);
+                    int depth = getDepth(request);
+                    render(tree, depth, generator);
                 } else {
                     response.sendError(HttpServletResponse.SC_NOT_FOUND);
                 }
@@ -71,4 +79,95 @@ public class OakServlet extends HttpServ
         }
     }
 
+    private int getDepth(HttpServletRequest request) {
+        String d = request.getParameter("depth");
+        if (d == null) {
+            d = request.getParameter("d");
+        }
+        if (d != null) {
+            try {
+                return Integer.parseInt(d);
+            } catch (NumberFormatException e) {
+                // ignore
+            }
+        }
+        return 1;
+    }
+
+    private JsonGenerator getRenderer(
+            HttpServletRequest request, HttpServletResponse response)
+            throws IOException {
+        AcceptHeader accept = new AcceptHeader(request.getHeader("Accept"));
+        String type = accept.resolve(
+                "application/json",
+                "application/x-jackson-smile");
+        if ("application/x-jackson-smile".equals(type)) {
+            response.setContentType("application/x-jackson-smile");
+            return SMILE_FACTORY.createJsonGenerator(response.getOutputStream());
+        } else {
+            response.setContentType("application/json");
+            return JSON_FACTORY.createJsonGenerator(response.getOutputStream());
+        }
+    }
+
+    private void render(Tree tree, int depth, JsonGenerator generator)
+            throws JsonGenerationException, IOException {
+        generator.writeStartObject();
+        if (depth > 0) {
+            for (PropertyState property : tree.getProperties()) {
+                render(property, generator);
+            }
+            for (Tree child : tree.getChildren()) {
+                generator.writeFieldName(child.getName());
+                render(child, depth - 1, generator);
+            }
+        }
+        generator.writeEndObject();
+        generator.close();
+    }
+
+    private void render(PropertyState property, JsonGenerator generator)
+            throws JsonGenerationException, IOException {
+        generator.writeFieldName(property.getName());
+        if (property.isArray()) {
+            generator.writeStartArray();
+            for (CoreValue value : property.getValues()) {
+                render(value, generator);
+            }
+            generator.writeEndArray();
+        } else {
+            render(property.getValue(), generator);
+        }
+    }
+
+    private void render(CoreValue value, JsonGenerator generator)
+            throws JsonGenerationException, IOException {
+        // TODO: Type info?
+        if (value.getType() == PropertyType.BOOLEAN) {
+            generator.writeBoolean(value.getBoolean());
+        } else if (value.getType() == PropertyType.DECIMAL) {
+            generator.writeNumber(value.getDecimal());
+        } else if (value.getType() == PropertyType.DOUBLE) {
+            generator.writeNumber(value.getDouble());
+        } else if (value.getType() == PropertyType.LONG) {
+            generator.writeNumber(value.getLong());
+        } else if (value.getType() == PropertyType.BINARY) {
+            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+            InputStream stream = value.getNewStream();
+            try {
+                byte[] b = new byte[1024];
+                int n = stream.read(b);
+                while (n != -1) {
+                    buffer.write(b, 0, n);
+                    n = stream.read(b);
+                }
+            } finally {
+                stream.close();
+            }
+            generator.writeBinary(buffer.toByteArray());
+        } else {
+            generator.writeString(value.getString());
+        }
+    }
+
 }