You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by dp...@apache.org on 2011/09/12 15:06:03 UTC

svn commit: r1169728 - in /jackrabbit/sandbox/microkernel/src/main: java/org/apache/jackrabbit/mk/server/ resources/org/apache/jackrabbit/mk/server/

Author: dpfister
Date: Mon Sep 12 13:06:03 2011
New Revision: 1169728

URL: http://svn.apache.org/viewvc?rev=1169728&view=rev
Log:
HTTP interface to microkernel
- support binary upload

Added:
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/BoundaryInputStream.java   (with props)
    jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/nodeExists.html
      - copied, changed from r1169627, jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/getNodes.html
    jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/write.html
Modified:
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/FileServlet.java
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/MicroKernelServlet.java
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Request.java
    jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Server.java
    jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/commit.html
    jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/getRevisions.html
    jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/index.html

Added: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/BoundaryInputStream.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/BoundaryInputStream.java?rev=1169728&view=auto
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/BoundaryInputStream.java (added)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/BoundaryInputStream.java Mon Sep 12 13:06:03 2011
@@ -0,0 +1,124 @@
+/*
+ * 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.jackrabbit.mk.server;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * Stream that reads bytes until a given string boundary.
+ */
+public class BoundaryInputStream extends InputStream {
+
+    private InputStream in;
+    private final byte[] boundary;
+    private final byte[] buf;
+    private int offset;
+    private int count;
+    private int boundaryIndex;
+    private boolean eos;
+
+    public BoundaryInputStream(InputStream in, String boundary) {
+        this(in, boundary, 8192);
+    }
+
+    public BoundaryInputStream(InputStream in, String boundary, int size) {
+        /* Must be able to unread this many bytes */
+        if (size < boundary.length() + 3) {
+            size = boundary.length() + 3;
+        }
+        this.in = in;
+        this.boundary = ("\r\n" + boundary).getBytes();
+
+        buf = new byte[size];
+    }
+
+    public int read() throws IOException {
+        if (eos) {
+            return -1;
+        }
+        byte[] b = new byte[1];
+        int count = read(b, 0, 1);
+        if (count == -1) {
+            return -1;
+        }
+        return b[0] & 0xff;
+    }
+
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        if (eos) {
+            return -1;
+        }
+        if (offset == count) {
+            fillBuffer();
+            if (eos) {
+                return -1;
+            }
+        }
+        return copy(b, off, len);
+    }
+
+    private void fillBuffer() throws IOException {
+        if (boundaryIndex > 0) {
+            System.arraycopy(boundary, 0, buf, 0, boundaryIndex);
+        }
+        offset = boundaryIndex;
+        count = in.read(buf, offset, buf.length - offset);
+
+        if (count < 0) {
+            eos = true;
+        }
+    }
+
+    private int copy(byte[] b, int off, int len) throws IOException {
+        int i = 0, j = 0;
+
+        while (i < count && j < len) {
+            if (boundary[boundaryIndex] == buf[offset + i]) {
+                boundaryIndex++;
+                i++;
+
+                if (boundaryIndex == boundary.length) {
+                    eos = true;
+                    break;
+                }
+            } else {
+                if (boundaryIndex > 0) {
+                    i -= boundaryIndex;
+                    if (i < 0) {
+                        offset += i;
+                        count += (-i);
+                        i = 0;
+                    }
+                    boundaryIndex = 0;
+                }
+                b[off + j] = buf[offset + i];
+                i++;
+                j++;
+            }
+        }
+        offset += i;
+        return j == 0 && eos ? -1 : j;
+    }
+
+    @Override
+    public void close() throws IOException {
+        in = null;
+        eos = true;
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/BoundaryInputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/FileServlet.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/FileServlet.java?rev=1169728&r1=1169727&r2=1169728&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/FileServlet.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/FileServlet.java Mon Sep 12 13:06:03 2011
@@ -33,11 +33,15 @@ class FileServlet implements Servlet {
         }
         InputStream in = FileServlet.class.getResourceAsStream(file.substring(1));
         if (in != null) {
-            int ext = file.lastIndexOf('.');
-            if (ext != -1) {
-                response.setContentTypeByExtension(file.substring(ext + 1));
+            try {
+                int ext = file.lastIndexOf('.');
+                if (ext != -1) {
+                    response.setContentTypeByExtension(file.substring(ext + 1));
+                }
+                IOUtils.copy(in, response.getOutputStream());
+            } finally {
+                IOUtils.closeQuietly(in);
             }
-            IOUtils.copy(in, response.getOutputStream());
         } else {
             response.setStatusCode(404);
         }

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/MicroKernelServlet.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/MicroKernelServlet.java?rev=1169728&r1=1169727&r2=1169728&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/MicroKernelServlet.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/MicroKernelServlet.java Mon Sep 12 13:06:03 2011
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.mk.server;
 
 import java.io.IOException;
 import java.io.PrintStream;
+import java.io.InputStream;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicReference;
@@ -51,6 +52,9 @@ class MicroKernelServlet implements Serv
                 } catch (MicroKernelException e) {
                     response.setStatusCode(500);
                     e.printStackTrace(new PrintStream(response.getOutputStream()));
+                } catch (Throwable e) {
+                    response.setStatusCode(500);
+                    e.printStackTrace(new PrintStream(response.getOutputStream()));
                 }
                 return;
             }
@@ -71,8 +75,10 @@ class MicroKernelServlet implements Serv
         COMMANDS.put("getHeadRevision", new GetHeadRevision());
         COMMANDS.put("getRevisions", new GetRevisions());
         COMMANDS.put("getJournal", new GetJournal());
+        COMMANDS.put("nodeExists", new NodeExists());
         COMMANDS.put("getNodes", new GetNodes());
         COMMANDS.put("commit", new Commit());
+        COMMANDS.put("write", new Write());
     }
     
     static class GetHeadRevision implements Command {
@@ -110,6 +116,20 @@ class MicroKernelServlet implements Serv
         }        
     }
 
+    static class NodeExists implements Command {
+
+        public void execute(MicroKernel mk, Request request, Response response)
+                throws IOException, MicroKernelException {
+
+            String headRevision = mk.getHeadRevision();
+
+            String path = request.getParameter("path", "/");
+            String revisionId = request.getParameter("revision_id", headRevision);
+
+            response.getOutputStream().write(Boolean.toString(mk.nodeExists(path, revisionId)).getBytes());
+        }
+    }
+
     static class GetNodes implements Command {
 
         public void execute(MicroKernel mk, Request request, Response response)
@@ -143,4 +163,16 @@ class MicroKernelServlet implements Serv
             response.getOutputStream().write(newRevision.getBytes());
         }        
     }
+
+    static class Write implements Command {
+
+        public void execute(MicroKernel mk, Request request, Response response)
+                throws IOException, MicroKernelException {
+
+            InputStream in = request.getFileParameter("file");
+            if (in != null) {
+                response.getOutputStream().write(mk.write(in).getBytes());
+            }
+        }        
+    }
 }

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Request.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Request.java?rev=1169728&r1=1169727&r2=1169728&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Request.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Request.java Mon Sep 12 13:06:03 2011
@@ -38,7 +38,7 @@ class Request {
     private final Map<String,String> headers; 
     private Map<String, String> params;
     private boolean chunked;
-    private InputStreamImpl reqIn;
+    private BodyInputStream reqIn;
     
     private Request(String method, String uri, Map<String,String> headers, InputStream in) {
         this.method = method;
@@ -179,7 +179,31 @@ class Request {
         }
         return defaultValue;
     }
-    
+
+    public InputStream getFileParameter(String name) throws IOException {
+        String ctype = getContentType();
+        if (ctype == null || !ctype.startsWith("multipart/form-data")) {
+            return null;
+        }
+        if (reqIn != null) {
+            /* might already be consumed */
+            return null;
+        }
+
+        InputStream body = getInputStream();
+        String boundary = readLine(body);
+
+        for (;;) {
+            String line = readLine(body);
+            if (line.length() == 0) {
+                break;
+            }
+            // TODO collect information
+        }
+
+        return new BoundaryInputStream(body, boundary);
+    }
+
     private static void collectParameters(String s, Map<String,String> map) {
         for (String param : s.split("&")) {
             String[] nv = param.split("=");
@@ -196,7 +220,7 @@ class Request {
             if (contentLength == -1) {
                 contentLength = 0;
             }
-            reqIn = new InputStreamImpl(contentLength);
+            reqIn = new BodyInputStream(contentLength);
         }
         return reqIn;
     }
@@ -222,22 +246,22 @@ class Request {
     /**
      * Internal <code>InputStream</code> passed to servlet handlers.
      */
-    private class InputStreamImpl extends InputStream {
+    private class BodyInputStream extends InputStream {
         
         private final int limit;
         private int count;
         
-        public InputStreamImpl(int limit) {
+        public BodyInputStream(int limit) {
             this.limit = limit;
         }
-        
+
         @Override
         public int read() throws IOException {
             if (count < limit) {
                 byte[] b = new byte[1];
                 if (readChunk(b, 0, b.length) == 1) {
                     count++;
-                    return b[1] & 0xff;
+                    return b[0] & 0xff;
                 }
             }
             return -1;
@@ -258,4 +282,5 @@ class Request {
             return -1;
         }
     }
+
 }

Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Server.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Server.java?rev=1169728&r1=1169727&r2=1169728&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Server.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/server/Server.java Mon Sep 12 13:06:03 2011
@@ -38,18 +38,26 @@ public class Server {
     private AtomicBoolean stopped = new AtomicBoolean();
     private ServerSocket ss;
     private ExecutorService es;
+    private int port = 28080;
     
     public Server(MicroKernel mk) {
         this.mkref = new AtomicReference<MicroKernel>(mk);
         
         mkServlet = new MicroKernelServlet(mkref);
     }
+
+    public void setPort(int port) {
+        if (started.get()) {
+            throw new IllegalStateException("Server already started.");
+        }
+        this.port = port;
+    }
     
     public void start() throws IOException {
         if (!started.compareAndSet(false, true)) {
             return;
         }
-        ss = new ServerSocket(28080);
+        ss = new ServerSocket(port);
         es = Executors.newFixedThreadPool(10);
         
         new Thread(new Runnable() {

Modified: jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/commit.html
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/commit.html?rev=1169728&r1=1169727&r2=1169728&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/commit.html (original)
+++ jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/commit.html Mon Sep 12 13:06:03 2011
@@ -1,8 +1,8 @@
 <html>
 <head>
 <title>&micro;icroKernel prototype: commit</title>
-<meta http-equiv="content-type" content="text/html; charset=utf-8"></meta>
-<link rel="stylesheet" type="text/css" href="main.css"></link>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<link rel="stylesheet" type="text/css" href="main.css"/>
 </head>
 
 <body>
@@ -17,7 +17,7 @@
             </tr>
             <tr>
                 <td>JSON Diff</td>
-                <td><input class="text" type="text" name="json_diff" id="revision_id"
+                <td><input class="text" type="text" name="json_diff" id="json_diff"
                    value='+"test" : {"jcr:primaryType":"nt:unstructured"}'>
                 </td>
             </tr>

Modified: jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/getRevisions.html
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/getRevisions.html?rev=1169728&r1=1169727&r2=1169728&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/getRevisions.html (original)
+++ jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/getRevisions.html Mon Sep 12 13:06:03 2011
@@ -1,8 +1,8 @@
 <html>
 <head>
 <title>&micro;icroKernel prototype: getRevisions</title>
-<meta http-equiv="content-type" content="text/html; charset=utf-8"></meta>
-<link rel="stylesheet" type="text/css" href="main.css"></link>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<link rel="stylesheet" type="text/css" href="main.css"/>
 </head>
 
 <body>
@@ -17,7 +17,7 @@
             </tr>
             <tr>
                 <td>Max Entries</td>
-                <td><input class="text" type="text" name="max_entries" id=""max_entries" value="10"></td>
+                <td><input class="text" type="text" name="max_entries" id="max_entries" value="10"></td>
             </tr>
             <tr><td>&nbsp;</td><td>
             <input type="submit"><br></td></tr></table>

Modified: jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/index.html
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/index.html?rev=1169728&r1=1169727&r2=1169728&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/index.html (original)
+++ jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/index.html Mon Sep 12 13:06:03 2011
@@ -1,33 +1,33 @@
 <html>
 <head>
 <title>&micro;icroKernel prototype</title>
-<meta http-equiv="content-type" content="text/html; charset=utf-8"></meta>
-<link rel="stylesheet" type="text/css" href="main.css"></link>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<link rel="stylesheet" type="text/css" href="main.css"/>
 </head>
 
 <body>
-<script src="header.js"></script>
-<div class="content">
-<p>
-	<h4>Revision Operations</h4>
-	<a href="getHeadRevision.html">getHeadRevision</a><br>
-	<a href="getRevisions.html">getRevisions</a><br>
-	<a href="waitForCommit.html">waitForCommit</a><br>
-	<a href="getJournal.html">getJournal</a><br>
-	
-	<h4>Read Operations</h4> 
-	<a href="nodeExists.html">nodeExists</a><br>
-	<a href="getNodes.html">getNodes</a><br>
-	
-	<h4>Write Operations</h4> 
-	<a href="commit.html">commit</a><br>
-	
-	<h4>Blob Operations</h4> 
-	<a href="getLength.html">getLength</a><br>
-	<a href="read.html">read</a><br>
-	<a href="write.html">write</a><br>
-</p>
-</div>
-<script src="footer.js"></script>
-</div>
+    <script src="header.js"></script>
+    <div class="content">
+        <p>
+        <h4>Revision Operations</h4>
+        <a href="getHeadRevision.html">getHeadRevision</a><br>
+        <a href="getRevisions.html">getRevisions</a><br>
+        <a href="waitForCommit.html">waitForCommit</a><br>
+        <a href="getJournal.html">getJournal</a><br>
+
+        <h4>Read Operations</h4>
+        <a href="nodeExists.html">nodeExists</a><br>
+        <a href="getNodes.html">getNodes</a><br>
+
+        <h4>Write Operations</h4>
+        <a href="commit.html">commit</a><br>
+
+        <h4>Blob Operations</h4>
+        <a href="getLength.html">getLength</a><br>
+        <a href="read.html">read</a><br>
+        <a href="write.html">write</a><br>
+        </p>
+    </div>
+    <script src="footer.js"></script>
+</body>
 </html>

Copied: jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/nodeExists.html (from r1169627, jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/getNodes.html)
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/nodeExists.html?p2=jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/nodeExists.html&p1=jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/getNodes.html&r1=1169627&r2=1169728&rev=1169728&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/getNodes.html (original)
+++ jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/nodeExists.html Mon Sep 12 13:06:03 2011
@@ -1,14 +1,14 @@
 <html>
 <head>
-<title>&micro;icroKernel prototype: getNodes</title>
-<meta http-equiv="content-type" content="text/html; charset=utf-8"></meta>
-<link rel="stylesheet" type="text/css" href="main.css"></link>
+<title>&micro;icroKernel prototype: nodeExists</title>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<link rel="stylesheet" type="text/css" href="main.css"/>
 </head>
 
 <body>
     <script src="header.js"></script>
     <div class="content">
-        <h1>Read Operations: getNodes</h1>
+        <h1>Read Operations: nodeExists</h1>
         <form method="POST" target="result">
         <table class="formtable">
             <tr>
@@ -19,18 +19,6 @@
                 <td>Revision ID</td>
                 <td><input class="text" type="text" name="revision_id" id="revision_id" value=""></td>
             </tr>
-            <tr>
-                <td>Depth</td>
-                <td><input class="text" type="text" name="depth" id="depth" value="1"></td>
-            </tr>
-            <tr>
-                <td>Offset</td>
-                <td><input class="text" type="text" name="offset" id="offset" value="0"></td>
-            </tr>
-            <tr>
-                <td>Count</td>
-                <td><input class="text" type="text" name="count" id="count" value="-1"></td>
-            </tr>
             <tr><td>&nbsp;</td><td>
             <input type="submit"><br></td></tr></table>
         </form>

Added: jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/write.html
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/write.html?rev=1169728&view=auto
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/write.html (added)
+++ jackrabbit/sandbox/microkernel/src/main/resources/org/apache/jackrabbit/mk/server/write.html Mon Sep 12 13:06:03 2011
@@ -0,0 +1,27 @@
+<html>
+<head>
+<title>&micro;icroKernel prototype: write</title>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<link rel="stylesheet" type="text/css" href="main.css"/>
+</head>
+
+<body>
+    <script src="header.js"></script>
+    <div class="content">
+        <h1>Blob Operations: write</h1>
+        <form method="POST" enctype="multipart/form-data" target="result">
+        <table class="formtable">
+            <tr>
+                <td>File</td>
+                <td><input class="file" type="file" name="file" id="file"/></td>
+            </tr>
+            <tr><td>&nbsp;</td><td>
+            <input type="submit"><br></td></tr></table>
+        </form>
+        <p>
+            <iframe name="result" height="400" width="950" src="about:blank"></iframe>
+        </p>
+        <script src="footer.js"></script>
+    </div>
+</body>
+</html>