jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dpfis...@apache.org
Subject svn commit: r1351618 [1/3] - in /jackrabbit/oak/trunk: ./ oak-core/ oak-it/mk/ oak-it/mk/src/main/java/org/apache/jackrabbit/mk/test/ oak-it/osgi/ oak-it/osgi/src/test/java/org/apache/jackrabbit/oak/osgi/ oak-mk-api/ oak-mk-api/src/ oak-mk-api/src/main...
Date Tue, 19 Jun 2012 09:39:45 GMT
Author: dpfister
Date: Tue Jun 19 09:39:41 2012
New Revision: 1351618

URL: http://svn.apache.org/viewvc?rev=1351618&view=rev
Log:
OAK-183 - Move client/server package in oak-mk to separate project
- create oak-mk-api and added reference to this project where needed

Added:
    jackrabbit/oak/trunk/oak-mk-api/
    jackrabbit/oak/trunk/oak-mk-api/pom.xml   (with props)
    jackrabbit/oak/trunk/oak-mk-api/src/
    jackrabbit/oak/trunk/oak-mk-api/src/main/
    jackrabbit/oak/trunk/oak-mk-api/src/main/java/
    jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/
    jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/
    jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/
    jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/
    jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/
    jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/MicroKernel.java   (with props)
    jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/MicroKernelException.java   (with props)
    jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/package-info.java   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/
    jackrabbit/oak/trunk/oak-mk-remote/pom.xml   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/
    jackrabbit/oak/trunk/oak-mk-remote/src/main/
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/Client.java   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/HttpExecutor.java   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/Request.java   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/remote/
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/remote/util/
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/remote/util/BoundedInputStream.java   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/remote/util/ChunkedInputStream.java   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/remote/util/ChunkedOutputStream.java   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/remote/util/package-info.java   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/server/
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/server/BoundaryInputStream.java   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/server/FileServlet.java   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/server/HttpProcessor.java   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/server/MicroKernelServlet.java   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/server/Request.java   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/server/Response.java   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/server/Server.java   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/server/Servlet.java   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/bg-body.png   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/branch.html   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/commit.html   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/diff.html   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/footer.js   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/getChildNodeCount.html   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/getHeadRevision.html   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/getJournal.html   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/getLength.html   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/getNodes.html   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/getRevisionHistory.html   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/header.js   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/index.html   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/logo.png   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/main.css   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/merge.html   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/nodeExists.html   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/read.html   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/waitForCommit.html   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/main/resources/org/apache/jackrabbit/mk/server/write.html   (with props)
    jackrabbit/oak/trunk/oak-mk-remote/src/test/
    jackrabbit/oak/trunk/oak-mk-remote/src/test/java/
    jackrabbit/oak/trunk/oak-mk-remote/src/test/java/org/
    jackrabbit/oak/trunk/oak-mk-remote/src/test/java/org/apache/
    jackrabbit/oak/trunk/oak-mk-remote/src/test/java/org/apache/jackrabbit/
    jackrabbit/oak/trunk/oak-mk-remote/src/test/java/org/apache/jackrabbit/mk/
    jackrabbit/oak/trunk/oak-mk-remote/src/test/java/org/apache/jackrabbit/mk/server/
    jackrabbit/oak/trunk/oak-mk-remote/src/test/java/org/apache/jackrabbit/mk/server/BoundaryInputStreamTest.java   (with props)
Removed:
    jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/api/
    jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/client/
    jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/server/
    jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/util/BoundedInputStream.java
    jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/util/ChunkedInputStream.java
    jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/util/ChunkedOutputStream.java
    jackrabbit/oak/trunk/oak-mk/src/test/java/org/apache/jackrabbit/mk/server/
Modified:
    jackrabbit/oak/trunk/oak-core/pom.xml
    jackrabbit/oak/trunk/oak-it/mk/pom.xml
    jackrabbit/oak/trunk/oak-it/mk/src/main/java/org/apache/jackrabbit/mk/test/AbstractMicroKernelIT.java
    jackrabbit/oak/trunk/oak-it/mk/src/main/java/org/apache/jackrabbit/mk/test/MicroKernelTestSuite.java
    jackrabbit/oak/trunk/oak-it/osgi/pom.xml
    jackrabbit/oak/trunk/oak-it/osgi/src/test/java/org/apache/jackrabbit/oak/osgi/OSGiIT.java
    jackrabbit/oak/trunk/oak-it/osgi/test-bundles.xml
    jackrabbit/oak/trunk/oak-mk/pom.xml
    jackrabbit/oak/trunk/pom.xml

Modified: jackrabbit/oak/trunk/oak-core/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/pom.xml?rev=1351618&r1=1351617&r2=1351618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-core/pom.xml Tue Jun 19 09:39:41 2012
@@ -105,12 +105,24 @@
 
     <dependency>
       <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>oak-mk-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.jackrabbit</groupId>
       <artifactId>oak-mk</artifactId>
       <version>${project.version}</version>
     </dependency>
 
     <dependency>
       <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>oak-mk-remote</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.jackrabbit</groupId>
       <artifactId>oak-commons</artifactId>
       <version>${project.version}</version>
     </dependency>

Modified: jackrabbit/oak/trunk/oak-it/mk/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-it/mk/pom.xml?rev=1351618&r1=1351617&r2=1351618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-it/mk/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-it/mk/pom.xml Tue Jun 19 09:39:41 2012
@@ -53,10 +53,20 @@
     </dependency>
     <dependency>
       <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>oak-mk-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jackrabbit</groupId>
       <artifactId>oak-mk</artifactId>
       <version>${project.version}</version>
     </dependency>
     <dependency>
+      <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>oak-mk-remote</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
       <groupId>com.googlecode.json-simple</groupId>
       <artifactId>json-simple</artifactId>
       <version>1.1</version>

Modified: jackrabbit/oak/trunk/oak-it/mk/src/main/java/org/apache/jackrabbit/mk/test/AbstractMicroKernelIT.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-it/mk/src/main/java/org/apache/jackrabbit/mk/test/AbstractMicroKernelIT.java?rev=1351618&r1=1351617&r2=1351618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-it/mk/src/main/java/org/apache/jackrabbit/mk/test/AbstractMicroKernelIT.java (original)
+++ jackrabbit/oak/trunk/oak-it/mk/src/main/java/org/apache/jackrabbit/mk/test/AbstractMicroKernelIT.java Tue Jun 19 09:39:41 2012
@@ -55,6 +55,7 @@ public abstract class AbstractMicroKerne
         Class<MicroKernelFixture> iface = MicroKernelFixture.class;
         ServiceLoader<MicroKernelFixture> loader =
                 ServiceLoader.load(iface, iface.getClassLoader());
+        
         for (MicroKernelFixture fixture : loader) {
             fixtures.add(new Object[] { fixture });
         }

Modified: jackrabbit/oak/trunk/oak-it/mk/src/main/java/org/apache/jackrabbit/mk/test/MicroKernelTestSuite.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-it/mk/src/main/java/org/apache/jackrabbit/mk/test/MicroKernelTestSuite.java?rev=1351618&r1=1351617&r2=1351618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-it/mk/src/main/java/org/apache/jackrabbit/mk/test/MicroKernelTestSuite.java (original)
+++ jackrabbit/oak/trunk/oak-it/mk/src/main/java/org/apache/jackrabbit/mk/test/MicroKernelTestSuite.java Tue Jun 19 09:39:41 2012
@@ -22,7 +22,8 @@ import org.junit.runners.Suite;
 @RunWith(Suite.class)
 @Suite.SuiteClasses({
     MicroKernelIT.class,
-    DataStoreIT.class
+    // TODO remove 
+    // DataStoreIT.class
 })
 public class MicroKernelTestSuite {
 }

Modified: jackrabbit/oak/trunk/oak-it/osgi/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-it/osgi/pom.xml?rev=1351618&r1=1351617&r2=1351618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-it/osgi/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-it/osgi/pom.xml Tue Jun 19 09:39:41 2012
@@ -75,12 +75,24 @@
     </dependency>
     <dependency>
       <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>oak-mk-api</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jackrabbit</groupId>
       <artifactId>oak-mk</artifactId>
       <version>${project.version}</version>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>oak-mk-remote</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jackrabbit</groupId>
       <artifactId>oak-core</artifactId>
       <version>${project.version}</version>
       <scope>test</scope>

Modified: jackrabbit/oak/trunk/oak-it/osgi/src/test/java/org/apache/jackrabbit/oak/osgi/OSGiIT.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-it/osgi/src/test/java/org/apache/jackrabbit/oak/osgi/OSGiIT.java?rev=1351618&r1=1351617&r2=1351618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-it/osgi/src/test/java/org/apache/jackrabbit/oak/osgi/OSGiIT.java (original)
+++ jackrabbit/oak/trunk/oak-it/osgi/src/test/java/org/apache/jackrabbit/oak/osgi/OSGiIT.java Tue Jun 19 09:39:41 2012
@@ -53,7 +53,9 @@ public class OSGiIT {
                 bundle(new File(base, "jackrabbit-api.jar").toURI().toURL().toString()),
                 bundle(new File(base, "jackrabbit-jcr-commons.jar").toURI().toURL().toString()),
                 bundle(new File(base, "oak-commons.jar").toURI().toURL().toString()),
+                bundle(new File(base, "oak-mk-api.jar").toURI().toURL().toString()),
                 bundle(new File(base, "oak-mk.jar").toURI().toURL().toString()),
+                bundle(new File(base, "oak-mk-remote.jar").toURI().toURL().toString()),
                 bundle(new File(base, "oak-core.jar").toURI().toURL().toString()),
                 bundle(new File(base, "oak-jcr.jar").toURI().toURL().toString()));
     }

Modified: jackrabbit/oak/trunk/oak-it/osgi/test-bundles.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-it/osgi/test-bundles.xml?rev=1351618&r1=1351617&r2=1351618&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-it/osgi/test-bundles.xml (original)
+++ jackrabbit/oak/trunk/oak-it/osgi/test-bundles.xml Tue Jun 19 09:39:41 2012
@@ -34,10 +34,12 @@
         <include>org.apache.jackrabbit:jackrabbit-api</include>
         <include>org.apache.jackrabbit:jackrabbit-jcr-commons</include>
         <include>org.apache.jackrabbit:oak-commons</include>
+        <include>org.apache.jackrabbit:oak-mk-api</include>
         <include>org.apache.jackrabbit:oak-mk</include>
+        <include>org.apache.jackrabbit:oak-mk-remote</include>
         <include>org.apache.jackrabbit:oak-core</include>
         <include>org.apache.jackrabbit:oak-jcr</include>
       </includes>
     </dependencySet>
   </dependencySets>
-</assembly>
\ No newline at end of file
+</assembly>

Added: jackrabbit/oak/trunk/oak-mk-api/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk-api/pom.xml?rev=1351618&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-mk-api/pom.xml (added)
+++ jackrabbit/oak/trunk/oak-mk-api/pom.xml Tue Jun 19 09:39:41 2012
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+   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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd ">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.jackrabbit</groupId>
+    <artifactId>oak-parent</artifactId>
+    <version>0.3-SNAPSHOT</version>
+    <relativePath>../oak-parent/pom.xml</relativePath>
+  </parent>
+
+  <artifactId>oak-mk-api</artifactId>
+  <name>Oak MicroKernel API</name>
+  <packaging>bundle</packaging>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Export-Package>
+              org.apache.jackrabbit.mk.api
+            </Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-scr-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <!-- Optional OSGi dependencies, used only when running within OSGi -->
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <scope>provided</scope>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <scope>provided</scope>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>biz.aQute</groupId>
+      <artifactId>bndlib</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.scr.annotations</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    
+    <!-- Findbugs annotations -->
+    <dependency>
+      <groupId>com.google.code.findbugs</groupId>
+      <artifactId>jsr305</artifactId>
+      <version>2.0.0</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <!--Test Dependencies-->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
+

Propchange: jackrabbit/oak/trunk/oak-mk-api/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/MicroKernel.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/MicroKernel.java?rev=1351618&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/MicroKernel.java (added)
+++ jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/MicroKernel.java Tue Jun 19 09:39:41 2012
@@ -0,0 +1,466 @@
+/*
+ * 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.api;
+
+import java.io.InputStream;
+
+/**
+ * The MicroKernel <b>Design Goals and Principles</b>:
+ * <ul>
+ * <li>manage huge trees of nodes and properties efficiently</li>
+ * <li>MVCC-based concurrency control
+ * (writers don't interfere with readers, snapshot isolation)</li>
+ * <li>GIT/SVN-inspired DAG-based versioning model</li>
+ * <li>highly scalable concurrent read & write operations</li>
+ * <li>session-less API (there's no concept of sessions; an implementation doesn't need to track/manage session state)</li>
+ * <li>easily portable to C</li>
+ * <li>easy to remote</li>
+ * <li>efficient support for large number of child nodes</li>
+ * <li>integrated API for efficiently storing/retrieving large binaries</li>
+ * <li>human-readable data serialization (JSON)</li>
+ * </ul>
+ * <p>
+ * The MicroKernel <b>Data Model</b>:
+ * </p>
+ * <ul>
+ * <li>simple JSON-inspired data model: just nodes and properties</li>
+ * <li>a node consists of an unordered set of name -&gt; item mappings. each
+ * property and child node is uniquely named and a single name can only
+ * refer to a property or a child node, not both at the same time.
+ * <li>properties are represented as name/value pairs</li>
+ * <li>supported property types: string, number, boolean, array</li>
+ * <li>a property value is stored and used as an opaque, unparsed character sequence</li>
+ * </ul>
+ * <p>
+ * The <b>Retention Policy for Revisions</b>:
+ * <p>
+ * TODO specify retention policy for old revisions, i.e. minimal guaranteed retention period (OAK-114)
+ * </p>
+ * <p>
+ * The <b>Retention Policy for Binaries</b>:
+ * </p>
+ * <p>
+ * The MicroKernel implementation is free to remove binaries if both of the
+ * following conditions are met:
+ * </p>
+ * <ul>
+ * <li>If the binary is not references as a property value of the
+ * format ":blobId:&lt;blobId&gt;" where &lt;blobId&gt; is the id returned by
+ * {@link #write(InputStream in)}. This includes simple property values such as
+ * {"bin": ":blobId:1234"} as well as array property values such as
+ * {"array": [":blobId:1234", ":blobId:5678"]}.</li>
+ * <li>If the binary was stored before the last retained revision (this is to
+ * keep temporary binaries, and binaries that are not yet referenced).</li>
+ * </ul>
+ */
+public interface MicroKernel {
+
+    //---------------------------------------------------------< REVISION ops >
+
+    /**
+     * Return the id of the current head revision.
+     *
+     * @return the id of the head revision
+     * @throws MicroKernelException if an error occurs
+     */
+    String getHeadRevision() throws MicroKernelException;
+
+    /**
+     * Returns a list of all currently available (historical) head revisions in
+     * chronological order since a specific point. <i>Private</i> branch
+     * revisions won't be included in the result.
+     * <p/>
+     * Format:
+     * <pre>
+     * [
+     *   {
+     *     "id" : "&lt;revisionId&gt;",
+     *     "ts" : &lt;revisionTimestamp&gt;,
+     *     "msg" : "&lt;commitMessage&gt;"
+     *   },
+     *   ...
+     * ]
+     * </pre>
+     * The {@code path} parameter allows to filter the revisions by path, i.e.
+     * only those revisions that affected the subtree rooted at {@code path}
+     * will be included.
+     *
+     * @param since      timestamp (ms) of earliest revision to be returned
+     * @param maxEntries maximum #entries to be returned;
+     *                   if < 0, no limit will be applied.
+     * @param path       optional path filter; if {@code null} or {@code ""} the
+     *                   default ({@code"/"}) will be assumed, i.e. no filter
+     *                   will be applied
+     * @return a list of revisions in chronological order in JSON format.
+     * @throws MicroKernelException if an error occurs
+     */
+    String /* jsonArray */ getRevisionHistory(long since, int maxEntries, String path)
+            throws MicroKernelException;
+
+    /**
+     * Waits for a commit to occur that is more recent than {@code oldHeadRevisionId}.
+     * <p/>
+     * This method allows for efficient polling for new revisions. The method
+     * will return the id of the current head revision if it is more recent than
+     * {@code oldHeadRevisionId}, or waits if either the specified amount of time
+     * has elapsed or a new head revision has become available.
+     * <p/>
+     * if a zero or negative {@code timeout} value has been specified the method
+     * will return immediately, i.e. calling {@code waitForCommit(0)} is
+     * equivalent to calling {@code getHeadRevision()}.
+     *
+     * @param oldHeadRevisionId id of earlier head revision
+     * @param timeout the maximum time to wait in milliseconds
+     * @return the id of the head revision
+     * @throws MicroKernelException if an error occurs
+     * @throws InterruptedException if the thread was interrupted
+     */
+    String waitForCommit(String oldHeadRevisionId, long timeout)
+            throws MicroKernelException, InterruptedException;
+
+    /**
+     * Returns a revision journal, starting with {@code fromRevisionId}
+     * and ending with {@code toRevisionId} in chronological order.
+     * <p/>
+     * Format:
+     * <pre>
+     * [
+     *   {
+     *     "id" : "&lt;revisionId&gt;",
+     *     "ts" : &lt;revisionTimestamp&gt;,
+     *     "msg" : "&lt;commitMessage&gt;",
+     *     "changes" : "&lt;JSON diff&gt;"
+     *   },
+     *   ...
+     * ]
+     * </pre>
+     * If {@code fromRevisionId} and {@code toRevisionId} are not in chronological
+     * order the returned journal will be empty (i.e. {@code []})
+     * <p/>
+     * The {@code path} parameter allows to filter the revisions by path, i.e.
+     * only those revisions that affected the subtree rooted at {@code path}
+     * will be included. The filter will also be applied to the JSON diff, i.e.
+     * the diff will include only those changes that affected the subtree rooted
+     * at {@code path}.
+     * <p/>
+     * A {@code MicroKernelException} is thrown if either {@code fromRevisionId}
+     * or {@code toRevisionId}  doesn't exist, denotes a <i>private</i> branch
+     * revision or if another error occurs.
+     *
+     * @param fromRevisionId id of first revision to be returned in journal
+     * @param toRevisionId   id of last revision to be returned in journal,
+     *                       if {@code null} the current head revision is assumed
+     * @param path           optional path filter; if {@code null} or {@code ""}
+     *                       the default ({@code"/"}) will be assumed, i.e. no
+     *                       filter will be applied
+     * @return a chronological list of revisions in JSON format
+     * @throws MicroKernelException if an error occurs
+     */
+    String /* jsonArray */ getJournal(String fromRevisionId, String toRevisionId,
+                                      String path)
+            throws MicroKernelException;
+
+    /**
+     * Returns the JSON diff representation of the changes between the specified
+     * revisions. The changes will be consolidated if the specified range
+     * covers intermediary revisions. {@code fromRevisionId} and {@code toRevisionId}
+     * don't need not be in a specific chronological order.
+     * <p/>
+     * The {@code path} parameter allows to filter the changes included in the
+     * JSON diff, i.e. only those changes that affected the subtree rooted at
+     * {@code path} will be included.
+     *
+     * @param fromRevisionId a revision id, if {@code null} the current head revision is assumed
+     * @param toRevisionId   another revision id, if {@code null} the current head revision is assumed
+     * @param path           optional path filter; if {@code null} or {@code ""}
+     *                       the default ({@code"/"}) will be assumed, i.e. no
+     *                       filter will be applied
+     * @return JSON diff representation of the changes
+     * @throws MicroKernelException if an error occurs
+     */
+    String /* JSON diff */ diff(String fromRevisionId, String toRevisionId,
+                                String path)
+            throws MicroKernelException;
+
+    //-------------------------------------------------------------< READ ops >
+
+    /**
+     * Determines whether the specified node exists.
+     *
+     * @param path       path denoting node
+     * @param revisionId revision id, if {@code null} the current head revision is assumed
+     * @return {@code true} if the specified node exists, otherwise {@code false}
+     * @throws MicroKernelException if the specified revision does not exist or if another error occurs
+     */
+    boolean nodeExists(String path, String revisionId) throws MicroKernelException;
+
+    /**
+     * Returns the number of child nodes of the specified node.
+     * <p/>
+     * This is a convenience method since this information could gathered by
+     * calling {@code getNodes(path, revisionId, 0, 0, 0, null)} and evaluating
+     * the {@code :childNodeCount} property.
+     *
+     * @param path       path denoting node
+     * @param revisionId revision id, if {@code null} the current head revision is assumed
+     * @return the number of child nodes
+     * @throws MicroKernelException if the specified node does not exist or if an error occurs
+     */
+    long getChildNodeCount(String path, String revisionId) throws MicroKernelException;
+
+    /**
+     * Returns the node tree rooted at the specified parent node with the
+     * specified depth, maximum child node maxChildNodes and offset. The depth of the
+     * returned tree is governed by the {@code depth} parameter:
+     * <table>
+     * <tr>
+     * <td>depth = 0</td>
+     * <td>properties, including {@code :childNodeCount} and
+     * child node names (i.e. empty child node objects)</td>
+     * </tr>
+     * <tr>
+     * <td>depth = 1</td>
+     * <td>properties, child nodes and their properties (including
+     * {@code :childNodeCount}) and their child node names
+     * (i.e. empty child node objects)</td>
+     * </tr>
+     * <tr>
+     * <td>depth = 2</td>
+     * <td>[and so on...]</td>
+     * </tr>
+     * </table>
+     * <p/>
+     * Example (depth=0):
+     * <pre>
+     * {
+     *   "someprop" : "someval",
+     *   ":childNodeCount" : 2,
+     *   "child1" : {},
+     *   "child2" : {}
+     * }
+     * </pre>
+     * Example (depth=1):
+     * <pre>
+     * {
+     *   "someprop" : "someval",
+     *   ":childNodeCount" : 2,
+     *   "child1" : {
+     *     "prop1" : 123,
+     *     ":childNodeCount" : 2,
+     *     "grandchild1" : {},
+     *     "grandchild2" : {}
+     *   },
+     *   "child2" : {
+     *     "prop1" : "bar",
+     *     ":childNodeCount" : 0
+     *   }
+     * }
+     * </pre>
+     * Remarks:
+     * <ul>
+     * <li>If the property {@code :childNodeCount} equals 0, then the
+     * node does not have any child nodes.
+     * <li>If the value of {@code :childNodeCount} is larger than the number
+     * of returned child nodes, then the node has more child nodes than those
+     * included in the returned tree.</li>
+     * </ul>
+     * The {@code offset} parameter is only applied to the direct child nodes
+     * of the root of the returned node tree. {@code maxChildNodes} however
+     * is applied on all hierarchy levels.
+     * <p/>
+     * An {@code IllegalArgumentException} is thrown if both an {@code offset}
+     * greater than zero and a {@code filter} on node names (see below) have been
+     * specified.
+     * <p/>
+     * The optional {@code filter} parameter allows to specify glob patterns for names of
+     * nodes and/or properties to be included or excluded.
+     * <p/>
+     * Example:
+     * <pre>
+     * {
+     *   nodes: [ "foo*", "-foo1" ],
+     *   properties: [ "*", "-:childNodeCount" ]
+     * }
+     * </pre>
+     * In the above example all child nodes with names starting with "foo" will
+     * be included, except for nodes named "foo1"; similarly, all properties will
+     * be included except for the ":childNodeCount" metadata property (see below).
+     * <p/>
+     * Glob Syntax:
+     * <ul>
+     * <li>a {@code nodes} or {@code properties} filter consists of one or more <i>globs</i>.</li>
+     * <li>a <i>glob</i> prefixed by {@code -} (dash) is treated as an exclusion pattern;
+     * all others are considered inclusion patterns.</li>
+     * <li>a leading {@code -} (dash) must be escaped by prepending {@code \} (backslash)
+     * if it should be interpreted as a literal.</li>
+     * <li>{@code *} (asterisk) serves as a <i>wildcard</i>, i.e. it matches any
+     * substring in the target name.</li>
+     * <li>{@code *} (asterisk) occurrences within the glob to be interpreted as
+     * literals must be escaped by prepending {@code \} (backslash).</li>
+     * <li>a filter matches a target name if any of the inclusion patterns match but
+     * none of the exclusion patterns.</li>
+     * </ul>
+     * If no filter is specified the implicit default filter is assumed:
+     * {@code {nodes:["*"],properties:["*"]}}
+     * <p/>
+     * System-provided metadata properties:
+     * <ul>
+     *     <li>{@code :childNodeCount} provides the actual number of direct child nodes; this property
+     *     is included by the implicit default filter. it can be excluded by specifying a filter such
+     *     as {@code {properties:["*", "-:childNodeCount"]}}</li>
+     *     <li>{@code :hash} provides a content-based identifier for the subtree
+     *     rooted at the {@code :hash} property's parent node. {@code :hash} values
+     *     are similar to fingerprints. they can be compared to quickly determine
+     *     if two subtrees are identical. if the {@code :hash} values are different
+     *     the respective subtrees are different with regard to structure and/or properties.
+     *     if on the other hand the {@code :hash} values are identical the respective
+     *     subtrees are identical with regard to structure and properties.
+     *     {@code :hash} is <i>not</i> included by the implicit default filter.
+     *     it can be included by specifying a filter such as {@code {properties:["*", ":hash"]}}
+     *     <p>Returning the {@code :hash} property is optional. Some implementations
+     *     might only return it on specific nodes or might not support it at all.
+     *     If however a {@code :hash} property is returned it has to obey the contract
+     *     described above.</p></li>
+     * </ul>
+     *
+     * @param path          path denoting root of node tree to be retrieved
+     * @param revisionId    revision id, if {@code null} the current head revision is assumed
+     * @param depth         maximum depth of returned tree
+     * @param offset        start position in the iteration order of child nodes (0 to start at the
+     *                      beginning)
+     * @param maxChildNodes maximum number of sibling child nodes to retrieve (-1 for all)
+     * @param filter        optional filter on property and/or node names; if {@code null} or
+     *                      {@code ""} the default filter will be assumed
+     * @return node tree in JSON format or {@code null} if the specified node does not exist
+     * @throws MicroKernelException if the specified revision does not exist or if another error occurs
+     * @throws IllegalArgumentException if both an {@code offset > 0} and a {@code filter} on node names have been specified
+     */
+    String /* jsonTree */ getNodes(String path, String revisionId, int depth,
+                                   long offset, int maxChildNodes, String filter)
+            throws MicroKernelException;
+
+    //------------------------------------------------------------< WRITE ops >
+
+    /**
+     * Applies the specified changes on the specified target node.
+     * <p>
+     * If {@code path.length() == 0} the paths specified in the
+     * {@code jsonDiff} are expected to be absolute.
+     * <p>
+     * The implementation tries to merge changes if the revision id of the
+     * commit is set accordingly. As an example, deleting a node is allowed if
+     * the node existed in the given revision, even if it was deleted in the
+     * meantime.
+     *
+     * @param path path denoting target node
+     * @param jsonDiff changes to be applied in JSON diff format.
+     * @param revisionId id of revision the changes are based on,
+     *                   if {@code null} the current head revision is assumed
+     * @param message commit message
+     * @return id of newly created revision
+     * @throws MicroKernelException if an error occurs
+     */
+    String /* revisionId */ commit(String path, String jsonDiff,
+                                   String revisionId, String message)
+            throws MicroKernelException;
+
+    /**
+     * Creates a <i>private</i> branch revision off the specified <i>public</i>
+     * trunk revision.
+     * <p/>
+     * A {@code MicroKernelException} is thrown if {@code trunkRevisionId} doesn't
+     * exist, if it's not a <i>trunk</i> revision (i.e. it's not reachable
+     * by traversing the revision history in reverse chronological order starting
+     * from the current head revision) or if another error occurs.
+     *
+     * @param trunkRevisionId id of public trunk revision to base branch on,
+     *                        if {@code null} the current head revision is assumed
+     * @return id of newly created private branch revision
+     * @throws MicroKernelException if {@code trunkRevisionId} doesn't exist,
+     *                              if it's not a <i>trunk</i> revision
+     *                              or if another error occurs
+     * @see #merge(String, String)
+     */
+    String /* revisionId */ branch(String trunkRevisionId)
+            throws MicroKernelException;
+
+    /**
+     * Merges the specified <i>private</i> branch revision with the current
+     * head revision.
+     * <p/>
+     * A {@code MicroKernelException} is thrown if {@code branchRevisionId} doesn't
+     * exist, if it's not a branch revision, if the merge fails because of
+     * conflicting changes or if another error occurs.
+     *
+     * @param branchRevisionId id of private branch revision
+     * @param message commit message
+     * @return id of newly created head revision
+     * @throws MicroKernelException if {@code branchRevisionId} doesn't exist,
+     *                              if it's not a branch revision, if the merge
+     *                              fails because of conflicting changes or if
+     *                              another error occurs.
+     * @see #branch(String)
+     */
+    String /* revisionId */ merge(String branchRevisionId, String message)
+            throws MicroKernelException;
+
+    //--------------------------------------------------< BLOB READ/WRITE ops >
+
+    /**
+     * Returns the length of the specified blob.
+     *
+     * @param blobId blob identifier
+     * @return length of the specified blob
+     * @throws MicroKernelException if an error occurs
+     */
+    long getLength(String blobId) throws MicroKernelException;
+
+    /**
+     * Reads up to {@code length} bytes of data from the specified blob into
+     * the given array of bytes.  An attempt is made to read as many as
+     * {@code length} bytes, but a smaller number may be read.
+     * The number of bytes actually read is returned as an integer.
+     *
+     * @param blobId blob identifier
+     * @param pos    the offset within the blob
+     * @param buff   the buffer into which the data is read.
+     * @param off    the start offset in array {@code buff}
+     *               at which the data is written.
+     * @param length the maximum number of bytes to read
+     * @return the total number of bytes read into the buffer, or
+     *         {@code -1} if there is no more data because the end of
+     *         the blob content has been reached.
+     * @throws MicroKernelException if an error occurs
+     */
+    int /* count */ read(String blobId, long pos, byte[] buff, int off, int length)
+            throws MicroKernelException;
+
+    /**
+     * Stores the content of the given stream and returns an associated
+     * identifier for later retrieval.
+     * <p>
+     * If identical stream content has been stored previously, then the existing
+     * identifier will be returned instead of storing a redundant copy.
+     * <p>
+     * The stream is closed by this method.
+     *
+     * @param in InputStream providing the blob content
+     * @return blob identifier associated with the given content
+     * @throws MicroKernelException if an error occurs
+     */
+    String /* blobId */ write(InputStream in) throws MicroKernelException;
+}

Propchange: jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/MicroKernel.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/MicroKernel.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/MicroKernelException.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/MicroKernelException.java?rev=1351618&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/MicroKernelException.java (added)
+++ jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/MicroKernelException.java Tue Jun 19 09:39:41 2012
@@ -0,0 +1,41 @@
+/*
+ * 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.api;
+
+/**
+ * Exception thrown by methods of the {@code MicroKernel} API
+ */
+public class MicroKernelException extends RuntimeException {
+
+    private static final long serialVersionUID = 1L;
+
+    public MicroKernelException() {
+        super();
+    }
+
+    public MicroKernelException(String message) {
+        super(message);
+    }
+
+    public MicroKernelException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public MicroKernelException(Throwable cause) {
+        super(cause);
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/MicroKernelException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/MicroKernelException.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/package-info.java?rev=1351618&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/package-info.java (added)
+++ jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/package-info.java Tue Jun 19 09:39:41 2012
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+@Version("0.1")
+@Export(optional = "provide:=true")
+package org.apache.jackrabbit.mk.api;
+
+import aQute.bnd.annotation.Export;
+import aQute.bnd.annotation.Version;
+

Propchange: jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/package-info.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-mk-api/src/main/java/org/apache/jackrabbit/mk/api/package-info.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/oak/trunk/oak-mk-remote/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk-remote/pom.xml?rev=1351618&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-mk-remote/pom.xml (added)
+++ jackrabbit/oak/trunk/oak-mk-remote/pom.xml Tue Jun 19 09:39:41 2012
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+   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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd ">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.jackrabbit</groupId>
+    <artifactId>oak-parent</artifactId>
+    <version>0.3-SNAPSHOT</version>
+    <relativePath>../oak-parent/pom.xml</relativePath>
+  </parent>
+
+  <artifactId>oak-mk-remote</artifactId>
+  <name>Oak MicroKernel Remoting</name>
+  <packaging>bundle</packaging>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <configuration>
+          <instructions>
+            <Export-Package>
+              org.apache.jackrabbit.mk.server,
+              org.apache.jackrabbit.mk.client
+            </Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-scr-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <!-- Optional OSGi dependencies, used only when running within OSGi -->
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <scope>provided</scope>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <scope>provided</scope>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>biz.aQute</groupId>
+      <artifactId>bndlib</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.scr.annotations</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    
+    <!-- mk dependency -->
+    <dependency>
+      <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>oak-mk</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <!-- commons dependency -->
+    <dependency>
+      <groupId>org.apache.jackrabbit</groupId>
+      <artifactId>oak-commons</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <!-- Findbugs annotations -->
+    <dependency>
+      <groupId>com.google.code.findbugs</groupId>
+      <artifactId>jsr305</artifactId>
+      <version>2.0.0</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <!--Test Dependencies-->
+    <dependency>
+      <groupId>com.googlecode.json-simple</groupId>
+      <artifactId>json-simple</artifactId>
+      <version>1.1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
+

Propchange: jackrabbit/oak/trunk/oak-mk-remote/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/Client.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/Client.java?rev=1351618&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/Client.java (added)
+++ jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/Client.java Tue Jun 19 09:39:41 2012
@@ -0,0 +1,378 @@
+/*
+ * 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.client;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.net.SocketFactory;
+
+import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.apache.jackrabbit.mk.api.MicroKernelException;
+import org.apache.jackrabbit.mk.util.IOUtils;
+
+/**
+ * Client exposing a {@code MicroKernel} interface, that "remotes" commands
+ * to a server.
+ */
+public class Client implements MicroKernel {
+    
+    private static final String MK_EXCEPTION_PREFIX = MicroKernelException.class.getName() + ":";
+
+    private final InetSocketAddress addr;
+    
+    private final SocketFactory socketFactory;
+
+    private final AtomicBoolean disposed = new AtomicBoolean();
+    
+    private HttpExecutor executor;
+
+    /**
+     * Returns the socket address of the given URL.
+     * 
+     * @param url URL
+     * @return socket address
+     */
+    private static InetSocketAddress getAddress(String url) {
+        try {
+            URI uri = new URI(url);
+            return new InetSocketAddress(uri.getHost(), uri.getPort());
+        } catch (URISyntaxException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+    
+
+    /**
+     * Create a new instance of this class.
+     * 
+     * @param url socket address
+     */
+    public Client(String url) {
+        this(getAddress(url));
+    }
+
+    /**
+     * Create a new instance of this class.
+     * 
+     * @param addr socket address
+     */
+    public Client(InetSocketAddress addr) {
+        this(addr, SocketFactory.getDefault());
+    }
+
+    /**
+     * Create a new instance of this class.
+     * 
+     * @param addr socket address
+     */
+    public Client(InetSocketAddress addr, SocketFactory socketFactory) {
+        this.addr = addr;
+        this.socketFactory = socketFactory;
+    }
+
+    public void dispose() {
+        // do nothing
+    }
+
+    //-------------------------------------------------- implements MicroKernel
+    
+    @Override
+    public String getHeadRevision() throws MicroKernelException {
+        Request request = null;
+        
+        try {
+            request = createRequest("getHeadRevision");
+            return request.getString();
+        } catch (IOException e) {
+            throw new MicroKernelException(e);
+        } finally {
+            IOUtils.closeQuietly(request);
+        }
+    }
+
+    @Override
+    public String getRevisionHistory(long since, int maxEntries, String path)
+            throws MicroKernelException {
+
+        Request request = null;
+
+        try {
+            request = createRequest("getRevisionHistory");
+            request.addParameter("since", since);
+            request.addParameter("max_entries", maxEntries);
+            request.addParameter("path", path);
+            return request.getString();
+        } catch (IOException e) {
+            throw toMicroKernelException(e);
+        } finally {
+            IOUtils.closeQuietly(request);
+        }
+    }
+
+    @Override
+    public String waitForCommit(String oldHeadRevisionId, long maxWaitMillis)
+            throws MicroKernelException, InterruptedException {
+
+        Request request = null;
+
+        try {
+            request = createRequest("waitForCommit");
+            request.addParameter("revision_id", oldHeadRevisionId);
+            request.addParameter("max_wait_millis", maxWaitMillis);
+            return request.getString();
+        } catch (IOException e) {
+            throw toMicroKernelException(e);
+        } finally {
+            IOUtils.closeQuietly(request);
+        }
+    }
+
+    @Override
+    public String getJournal(String fromRevisionId, String toRevisionId, String path)
+            throws MicroKernelException {
+        
+        Request request = null;
+
+        try {
+            request = createRequest("getJournal");
+            request.addParameter("from_revision_id", fromRevisionId);
+            request.addParameter("to_revision_id", toRevisionId);
+            request.addParameter("path", path);
+            return request.getString();
+        } catch (IOException e) {
+            throw toMicroKernelException(e);
+        } finally {
+            IOUtils.closeQuietly(request);
+        }
+    }
+
+    @Override
+    public String diff(String fromRevisionId, String toRevisionId, String path)
+            throws MicroKernelException {
+        Request request = null;
+
+        try {
+            request = createRequest("diff");
+            request.addParameter("from_revision_id", fromRevisionId);
+            request.addParameter("to_revision_id", toRevisionId);
+            request.addParameter("path", path);
+            return request.getString();
+        } catch (IOException e) {
+            throw toMicroKernelException(e);
+        } finally {
+            IOUtils.closeQuietly(request);
+        }
+    }
+
+    @Override
+    public boolean nodeExists(String path, String revisionId)
+            throws MicroKernelException {
+
+        Request request = null;
+
+        try {
+            request = createRequest("nodeExists");
+            request.addParameter("path", path);
+            request.addParameter("revision_id", revisionId);
+            return request.getBoolean();
+        } catch (IOException e) {
+            throw toMicroKernelException(e);
+        } finally {
+            IOUtils.closeQuietly(request);
+        }
+    }
+
+    @Override
+    public long getChildNodeCount(String path, String revisionId)
+            throws MicroKernelException {
+
+        Request request = null;
+
+        try {
+            request = createRequest("getChildNodeCount");
+            request.addParameter("path", path);
+            request.addParameter("revision_id", revisionId);
+            return request.getLong();
+        } catch (IOException e) {
+            throw toMicroKernelException(e);
+        } finally {
+            IOUtils.closeQuietly(request);
+        }
+    }
+
+    @Override
+    public String getNodes(String path, String revisionId, int depth,
+            long offset, int count, String filter) throws MicroKernelException {
+        
+        Request request = null;
+
+        try {
+            request = createRequest("getNodes");
+            request.addParameter("path", path);
+            request.addParameter("revision_id", revisionId);
+            request.addParameter("depth", depth);
+            request.addParameter("offset", offset);
+            request.addParameter("max_child_nodes", count);
+            request.addParameter("filter", filter);
+            // OAK-48: MicroKernel.getNodes() should return null for not existing nodes instead of throwing an exception
+            String result = request.getString();
+            return result.equals("null") ? null : result;
+        } catch (IOException e) {
+            throw toMicroKernelException(e);
+        } finally {
+            IOUtils.closeQuietly(request);
+        }
+    }
+
+    @Override
+    public String commit(String path, String jsonDiff, String revisionId,
+            String message) throws MicroKernelException {
+        
+        Request request = null;
+
+        try {
+            request = createRequest("commit");
+            request.addParameter("path", path);
+            request.addParameter("json_diff", jsonDiff);
+            request.addParameter("revision_id", revisionId);
+            request.addParameter("message", message);
+            return request.getString();
+        } catch (IOException e) {
+            throw toMicroKernelException(e);
+        } finally {
+            IOUtils.closeQuietly(request);
+        }
+    }
+
+    @Override
+    public String branch(String trunkRevisionId)
+            throws MicroKernelException {
+
+        Request request = null;
+
+        try {
+            request = createRequest("branch");
+            request.addParameter("trunk_revision_id", trunkRevisionId);
+            return request.getString();
+        } catch (IOException e) {
+            throw toMicroKernelException(e);
+        } finally {
+            IOUtils.closeQuietly(request);
+        }
+    }
+
+    @Override
+    public String merge(String branchRevisionId, String message)
+            throws MicroKernelException {
+
+        Request request = null;
+
+        try {
+            request = createRequest("merge");
+            request.addParameter("branch_revision_id", branchRevisionId);
+            request.addParameter("message", message);
+            return request.getString();
+        } catch (IOException e) {
+            throw toMicroKernelException(e);
+        } finally {
+            IOUtils.closeQuietly(request);
+        }
+    }
+
+    @Override
+    public long getLength(String blobId) throws MicroKernelException {
+        Request request = null;
+
+        try {
+            request = createRequest("getLength");
+            request.addParameter("blob_id", blobId);
+            return request.getLong();
+        } catch (IOException e) {
+            throw toMicroKernelException(e);
+        } finally {
+            IOUtils.closeQuietly(request);
+        }
+    }
+
+    @Override
+    public int read(String blobId, long pos, byte[] buff, int off, int length)
+            throws MicroKernelException {
+
+        Request request = null;
+
+        try {
+            request = createRequest("read");
+            request.addParameter("blob_id", blobId);
+            request.addParameter("pos", pos);
+            request.addParameter("length", length);
+            return request.read(buff, off, length);
+        } catch (IOException e) {
+            throw toMicroKernelException(e);
+        } finally {
+            IOUtils.closeQuietly(request);
+        }
+    }
+
+    @Override
+    public String write(InputStream in) throws MicroKernelException {
+        Request request = null;
+
+        try {
+            request = createRequest("write");
+            request.addFileParameter("file", in);
+            return request.getString();
+        } catch (IOException e) {
+            throw toMicroKernelException(e);
+        } finally {
+            IOUtils.closeQuietly(request);
+            IOUtils.closeQuietly(in);
+        }
+    }
+    
+    /**
+     * Convert an I/O exception into a MicroKernelException, possibly by 
+     * unwrapping an already wrapped MicroKernelException.
+     * 
+     * @param e I/O exception 
+     * @return MicroKernelException
+     */
+    private MicroKernelException toMicroKernelException(IOException e) {
+        String msg = e.getMessage();
+        if (msg != null && msg.startsWith(MK_EXCEPTION_PREFIX)) {
+            return new MicroKernelException(msg.substring(MK_EXCEPTION_PREFIX.length()).trim());
+        }
+        return new MicroKernelException(e);
+    }
+
+    /**
+     * Create a request for the given command to be executed.
+     * 
+     * @param command command name
+     * @return request
+     * @throws IOException if an I/O error occurs
+     * @throws MicroKernelException if an exception occurs
+     */
+    private Request createRequest(String command) throws IOException, MicroKernelException {
+        return new Request(socketFactory, addr, command);
+    }
+    
+}

Propchange: jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/Client.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/Client.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/HttpExecutor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/HttpExecutor.java?rev=1351618&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/HttpExecutor.java (added)
+++ jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/HttpExecutor.java Tue Jun 19 09:39:41 2012
@@ -0,0 +1,294 @@
+/*
+ * 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.client;
+
+import org.apache.jackrabbit.mk.remote.util.BoundedInputStream;
+import org.apache.jackrabbit.mk.remote.util.ChunkedInputStream;
+import org.apache.jackrabbit.mk.util.IOUtils;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.URLEncoder;
+import java.security.SecureRandom;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Random;
+
+import javax.net.SocketFactory;
+
+/**
+ * Executes commands as HTTP requests.
+ * <p>
+ * This class is NOT thread-safe: its execute() method should operate within a
+ * lock, which must be held if a result input stream is returned UNTIL this
+ * stream is consumed or closed.
+ */
+class HttpExecutor implements Closeable {
+
+    private final Socket socket;
+    
+    private InputStream socketIn;
+    
+    private OutputStream socketOut;
+    
+//    private final ChunkedOutputStream bodyOut = new ChunkedOutputStream(null);
+    private final ByteArrayOutputStream bodyOut = new ByteArrayOutputStream(256);
+    
+    private final ChunkedInputStream bodyIn = new ChunkedInputStream(null); 
+    
+    private boolean connectionClosed;
+    
+    /**
+     * Create a new instance of this class.
+     * 
+     * @param socketFactory socket factory
+     * @param socketAddress server address
+     * @throws IOException if the server could not be contacted
+     */
+    public HttpExecutor(SocketFactory socketFactory, InetSocketAddress socketAddress)
+	    throws IOException {
+        if (socketAddress != null) {
+            socket = socketFactory.createSocket(
+                    socketAddress.getAddress(), socketAddress.getPort());
+        } else {
+            socket = socketFactory.createSocket();
+        }
+    }
+    
+    /**
+     * Execute a request.
+     * 
+     * @param command command to execute
+     * @param params arguments to command
+     * @param in bytes to pass
+     * @return result input stream
+     * 
+     * @throws IOException if an I/O error occurs
+     */
+    public InputStream execute(String command, Map<String, String> params, InputStream in)
+            throws IOException {
+        
+        // send request
+        if (socketOut == null) {
+            socketOut = new BufferedOutputStream(socket.getOutputStream());
+        }
+        String contentType = "application/x-www-form-urlencoded";
+        String boundary = null;
+        if (in != null) {
+        	boundary = getBoundary();
+            contentType = "multipart/form-data; boundary=" + boundary;
+        }
+        
+        writeLine(String.format("POST /%s HTTP/1.1", command));
+        writeLine(String.format("Content-Type: %s", contentType));
+
+        if (in != null) {
+            bodyOut.write("--".getBytes());
+            bodyOut.write(boundary.getBytes());
+            bodyOut.write("\r\n".getBytes());
+            bodyOut.write("Content-Disposition: form-data; name=\"file\"; filename=\"upload\"\r\n".getBytes());
+            bodyOut.write("Content-Type: application/octet-stream\r\n".getBytes());
+            bodyOut.write("\r\n".getBytes());
+            IOUtils.copy(in, bodyOut);
+            bodyOut.write("\r\n".getBytes());
+            bodyOut.write("--".getBytes());
+            bodyOut.write(boundary.getBytes());
+            bodyOut.write("--".getBytes	());
+        } else {
+            for (Map.Entry<String,String> param : params.entrySet()) {
+                String s = String.format("%s=%s&", 
+                        URLEncoder.encode(param.getKey(), "8859_1"),
+                        URLEncoder.encode(param.getValue(), "8859_1"));
+                bodyOut.write(s.getBytes());
+            }
+        }
+        
+        byte[] data = bodyOut.toByteArray();
+        writeLine(String.format("Content-Length: %d", data.length));
+        writeLine("");     
+        socketOut.write(data);
+        socketOut.flush();
+        
+        // read response
+        if (socketIn == null) {
+            socketIn = new BufferedInputStream(socket.getInputStream());
+        }
+        
+        String responseLine = readLine(socketIn);
+        String[] parts = responseLine.split(" ");
+        if (parts.length < 3) {
+            String msg = String.format("Malformed HTTP response line: %s", responseLine);
+            throw new IOException(msg);
+        }
+        
+        int statusCode;
+        
+        try {
+            statusCode = Integer.parseInt(parts[1]);
+        } catch (RuntimeException e) {
+            String msg = String.format("Malformed HTTP response line: %s", responseLine);
+            throw new IOException(msg);
+        }
+        
+        Map<String, String> headers = new LinkedHashMap<String, String>();
+        
+        for (;;) {
+            String headerLine = readLine(socketIn);
+            if (headerLine.length() == 0) {
+                break;
+            }
+            parts = headerLine.split(":");
+            if (parts.length == 2) {
+                headers.put(parts[0].trim(), parts[1].trim());
+            }
+        }
+
+        InputStream reqIn;
+        
+        String encoding = headers.get("Transfer-Encoding");
+        if ("chunked".equalsIgnoreCase(encoding)) {
+            bodyIn.recycle(socketIn);
+            reqIn = bodyIn;
+        } else {
+            int contentLength = -1;
+            
+            String s = headers.get("Content-Length");
+            if (s != null) {
+                try {
+                    contentLength = Integer.parseInt(s);
+                } catch (RuntimeException e) {
+                    /* ignore */
+                }
+            }
+            if (contentLength == -1) {
+                contentLength = 0;
+            }
+            reqIn = new BoundedInputStream(socketIn, contentLength);
+        }
+        
+        String connectionState = headers.get("Connection");
+        if ("close".equalsIgnoreCase(connectionState)) {
+            connectionClosed = true;
+        }
+        
+        switch (statusCode) {
+        case 200:
+            return reqIn;
+        case 500:
+            try {
+                throw new IOException(readLine(reqIn));
+            } finally {
+                IOUtils.closeQuietly(reqIn);
+            }
+        default:
+            String msg = String.format("HTTP request failed with status code: %d", statusCode);
+            throw new IOException(msg);
+        }
+    }
+    
+    /**
+     * Return a flag indicating whether the executor is alive.
+     *
+     * @return {@code true} if it is alive; {@code false} otherwise
+     */
+    public boolean isAlive() {
+        return !connectionClosed && !socket.isClosed();
+    }
+    
+    /**
+     * Close this executor.
+     */
+    @Override
+    public void close() {
+        IOUtils.closeQuietly(socketOut);
+        IOUtils.closeQuietly(socketIn);
+        IOUtils.closeQuietly(socket);
+    }
+
+    /**
+     * Write a request header.
+     * 
+     * @param s line
+     * @throws IOException if an I/O error occurs
+     */
+    private void writeLine(String s) throws IOException {
+        socketOut.write(s.getBytes());
+        socketOut.write("\r\n".getBytes());
+    }
+
+    /**
+     * Read a single line, terminated by a CR LF combination from an input.
+     * 
+     * @return line
+     * @throws IOException if an I/O error occurs
+     */
+    private static String readLine(InputStream in) throws IOException {
+        StringBuilder line = new StringBuilder(128);
+        
+        for (;;) {
+            int c = in.read();
+            switch (c) {
+            case '\r':
+                // swallow
+                break;
+            case '\n':
+                return line.toString();
+            case -1:
+                throw new EOFException();
+            default:
+                line.append((char) c);
+            }
+        }
+    }
+
+    /**
+     * Boundary.
+     */
+    private static String boundary; 
+    
+    /**
+     * Boundary characters.
+     */
+    private static final char[] BOUNDARY_CHARACTERS = 
+            "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
+    
+    /**
+     * Return a multipart boundary.
+     * 
+     * @return boundary
+     */
+    private static String getBoundary() {
+        if (boundary == null) {
+            StringBuilder b = new StringBuilder();
+            Random random = new SecureRandom();
+            
+            for (int i = 0; i < 16; i++) {
+                b.append(BOUNDARY_CHARACTERS[random.nextInt(BOUNDARY_CHARACTERS.length)]);
+            }
+            boundary = String.format("----ClientFormBoundary%s", b.toString());
+        }
+        return boundary;
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/HttpExecutor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/HttpExecutor.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/Request.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/Request.java?rev=1351618&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/Request.java (added)
+++ jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/Request.java Tue Jun 19 09:39:41 2012
@@ -0,0 +1,197 @@
+/*
+ * 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.client;
+
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import javax.net.SocketFactory;
+
+import org.apache.jackrabbit.mk.util.IOUtils;
+
+/**
+ * Contains the details of a request to some remote {@code MicroKernel}
+ * implementation.
+ */
+class Request implements Closeable {
+
+    private final SocketFactory socketFactory;
+
+    private final InetSocketAddress socketAddress;
+    
+    private final String command;
+    
+    private final Map<String, String> params = new LinkedHashMap<String, String>();
+    
+    private InputStream in;
+    
+    /**
+     * Create a new instance of this class.
+     * 
+     * @param socketFactory socket factory
+     * @param socketAddress server address
+     * @param command command name
+     */
+    public Request(
+            SocketFactory socketFactory, InetSocketAddress socketAddress,
+            String command) {
+        this.socketFactory = socketFactory;
+        this.socketAddress = socketAddress;
+        this.command = command;
+    }
+
+    /**
+     * Add a string parameter.
+     *
+     * @param name name
+     * @param value value, if {@code null} the call is ignored
+     */
+    public Request addParameter(String name, String value) {
+        if (value != null) {
+            params.put(name, value);
+        }
+        return this;
+    }
+
+    /**
+     * Add an integer parameter, equivalent to 
+     * {@code addParameter(name, String.valueOf(value))}.
+     *
+     * @param name name
+     * @param value value
+     */
+    public Request addParameter(String name, int value) {
+        params.put(name, String.valueOf(value));
+        return this;
+    }
+    
+    /**
+     * Add a long parameter, equivalent to 
+     * {@code addParameter(name, String.valueOf(value))}.
+     *
+     * @param name name
+     * @param value value
+     */
+    public Request addParameter(String name, long value) {
+        params.put(name, String.valueOf(value));
+        return this;
+    }
+    
+    /**
+     * Add a file parameter that will be transmitted as form data. 
+     * 
+     * @param name name
+     * @param in input stream
+     */
+    public Request addFileParameter(String name, InputStream in) {
+        this.in = in;
+        return this;
+    }
+    
+    /**
+     * Execute the request.
+     * 
+     * @throws IOException if an I/O error occurs
+     */
+    private byte[] execute() throws IOException {
+        HttpExecutor executor = new HttpExecutor(socketFactory, socketAddress);
+        try {
+            InputStream stream = executor.execute(command, params, in);
+            try {
+                ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+                IOUtils.copy(stream, buffer);
+                return buffer.toByteArray();
+            } finally {
+                stream.close();
+            }
+        } finally {
+            executor.close();
+        }
+    }
+
+    /**
+     * Return a string from the result stream. Automatically executes
+     * the request first.
+     * 
+     * @return string
+     * @throws IOException if an I/O error occurs
+     */
+    public String getString() throws IOException {
+        return new String(execute(), "8859_1");
+    }
+
+    /**
+     * Return a boolean from the result stream, equivalent to 
+     * {@code Boolean.parseBoolean(getString())}.
+     * Automatically executes the request first.
+     *
+     * @return boolean
+     * @throws IOException if an I/O error occurs
+     */
+    public boolean getBoolean() throws IOException {
+        return Boolean.parseBoolean(getString());
+    }
+    
+    /**
+     * Return a long from the result stream, equivalent to 
+     * {@code Long.parseLong(getString())}.
+     * Automatically executes the request first.
+     *
+     * @return boolean
+     * @throws IOException if an I/O error occurs
+     */
+    public long getLong() throws IOException {
+        return Long.parseLong(getString());
+    }
+
+    /**
+     * Read bytes from the result stream. Automatically executes the
+     * request first.
+     *
+     * @param b buffer
+     * @param off offset
+     * @param len length
+     * @return number of bytes or {@code -1} if no more bytes are available
+     *
+     * @throws IOException if an I/O error occurs
+     */
+    public int read(byte[] b, int off, int len) throws IOException {
+        if (len == 0) {
+            return 0;
+        }
+
+        byte[] bytes = execute();
+        len = Math.min(bytes.length, len);
+        if (len == 0) {
+            return -1;
+        }
+
+        System.arraycopy(bytes, 0, b, off, len);
+        return len;
+    }
+
+    @Override
+    public void close() {
+        // do nothing
+    }
+
+}

Propchange: jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/Request.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/client/Request.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url

Added: jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/remote/util/BoundedInputStream.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/remote/util/BoundedInputStream.java?rev=1351618&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/remote/util/BoundedInputStream.java (added)
+++ jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/remote/util/BoundedInputStream.java Tue Jun 19 09:39:41 2012
@@ -0,0 +1,92 @@
+/*
+ * 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.remote.util;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Implementation of an {@code InputStream} that is bounded by a limit
+ * and will return {@code -1} on reads when this limit is exceeded.
+ */
+public class BoundedInputStream extends FilterInputStream {
+    
+    private final int limit;
+    private int count;
+    
+    /**
+     * Create a new instance of this class.
+     *
+     * @param in input stream
+     * @param limit limit
+     */
+    public BoundedInputStream(InputStream in, int limit) {
+        super(in);
+        
+        this.limit = limit;
+    }
+
+    @Override
+    public int read() throws IOException {
+        if (count < limit) {
+            int c = in.read();
+            if (c != -1) {
+                count++;
+            }
+            return c;
+        }
+        return -1;
+    }
+    
+    @Override
+    public int read(byte[] b, int off, int len) throws IOException {
+        if (count < limit) {
+            if (limit - count < len) {
+                len = limit - count;
+            }
+            int n = in.read(b, off, len);
+            if (n > 0) {
+                count += n;
+            }
+            return n;
+        }
+        return -1;
+    }
+    
+    /**
+     * Close this input stream. Finishes reading any pending chunks until
+     * the last chunk is received. Does <b>not</b> close the underlying input
+     * stream.
+     *
+     * @see java.io.FilterInputStream#close()
+     */
+    @Override
+    public void close() throws IOException {
+        if (in == null) {
+            return;
+        }
+        try {
+            int remains = limit - count;
+            if (remains > 0) {
+                in.skip(remains);
+            }
+        } finally {
+            in = null;
+        }
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/remote/util/BoundedInputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-mk-remote/src/main/java/org/apache/jackrabbit/mk/remote/util/BoundedInputStream.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev Url



Mime
View raw message