You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by th...@apache.org on 2011/11/28 17:17:43 UTC
svn commit: r1207377 - in /jackrabbit/sandbox/microkernel/src:
main/java/org/apache/jackrabbit/mk/
main/java/org/apache/jackrabbit/mk/wrapper/
test/java/org/apache/jackrabbit/mk/index/
test/java/org/apache/jackrabbit/mk/wrapper/
Author: thomasm
Date: Mon Nov 28 16:17:41 2011
New Revision: 1207377
URL: http://svn.apache.org/viewvc?rev=1207377&view=rev
Log:
An index wrapper so that the index mechanism can be accessed using the regular MicroKernel API (without having to use a separate API). Temporarily disabled some tests that fail with the MicroKernelImpl.
Added:
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/wrapper/IndexWrapper.java
jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/wrapper/TestIndexWrapper.java
Modified:
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelFactory.java
jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/index/PrefixIndexTest.java
jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/index/PropertyIndexTest.java
jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/wrapper/TestSecurityWrapper.java
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelFactory.java?rev=1207377&r1=1207376&r2=1207377&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelFactory.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/MicroKernelFactory.java Mon Nov 28 16:17:41 2011
@@ -25,6 +25,7 @@ import org.apache.jackrabbit.mk.client.C
import org.apache.jackrabbit.mk.fs.FileUtils;
import org.apache.jackrabbit.mk.mem.MemoryKernelImpl;
import org.apache.jackrabbit.mk.util.ExceptionFactory;
+import org.apache.jackrabbit.mk.wrapper.IndexWrapper;
import org.apache.jackrabbit.mk.wrapper.LogWrapper;
import org.apache.jackrabbit.mk.wrapper.SecurityWrapper;
import org.apache.jackrabbit.mk.wrapper.VirtualRepositoryWrapper;
@@ -55,6 +56,8 @@ public class MicroKernelFactory {
return SecurityWrapper.get(url);
} else if (url.startsWith("virtual:")) {
return VirtualRepositoryWrapper.get(url);
+ } else if (url.startsWith("index:")) {
+ return IndexWrapper.get(url);
} else if (url.startsWith("fs:")) {
boolean clean = false;
if (url.endsWith(";clean")) {
Added: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/wrapper/IndexWrapper.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/wrapper/IndexWrapper.java?rev=1207377&view=auto
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/wrapper/IndexWrapper.java (added)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/wrapper/IndexWrapper.java Mon Nov 28 16:17:41 2011
@@ -0,0 +1,212 @@
+/*
+ * 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.wrapper;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import org.apache.jackrabbit.mk.MicroKernelFactory;
+import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.apache.jackrabbit.mk.api.MicroKernelException;
+import org.apache.jackrabbit.mk.index.Indexer;
+import org.apache.jackrabbit.mk.index.PrefixIndex;
+import org.apache.jackrabbit.mk.index.PropertyIndex;
+import org.apache.jackrabbit.mk.json.JsopReader;
+import org.apache.jackrabbit.mk.json.JsopStream;
+import org.apache.jackrabbit.mk.json.JsopTokenizer;
+import org.apache.jackrabbit.mk.mem.NodeImpl;
+import org.apache.jackrabbit.mk.mem.NodeMap;
+import org.apache.jackrabbit.mk.util.ExceptionFactory;
+import org.apache.jackrabbit.mk.util.PathUtils;
+
+/**
+ * The index mechanism, as a wrapper.
+ */
+public class IndexWrapper extends WrapperBase implements MicroKernel {
+
+ private static final String INDEX_PATH = "/index";
+ private static final String TYPE_PREFIX = "prefix:";
+ private static final String TYPE_PROPERTY = "property:";
+ private static final String UNIQUE = "unique";
+
+ private final Wrapper mk;
+ private final Indexer indexer;
+ private final NodeMap map = new NodeMap();
+ private final HashMap<String, PrefixIndex> prefixIndexes = new HashMap<String, PrefixIndex>();
+ private final HashMap<String, PropertyIndex> propertyIndexes = new HashMap<String, PropertyIndex>();
+
+ public IndexWrapper(MicroKernel mk) {
+ this.mk = WrapperBase.wrap(mk);
+ this.indexer = new Indexer(mk);
+ }
+
+ public static synchronized IndexWrapper get(String url) {
+ String u = url.substring("index:".length());
+ IndexWrapper w = new IndexWrapper(MicroKernelFactory.getInstance(u));
+ return w;
+ }
+
+ public String getHeadRevision() {
+ return mk.getHeadRevision();
+ }
+
+ public long getLength(String blobId) {
+ return mk.getLength(blobId);
+ }
+
+ public boolean nodeExists(String path, String revisionId) {
+ return mk.nodeExists(path, revisionId);
+ }
+
+ public int read(String blobId, long pos, byte[] buff, int off, int length) {
+ return mk.read(blobId, pos, buff, off, length);
+ }
+
+ public String waitForCommit(String oldHeadRevision, long maxWaitMillis) throws MicroKernelException, InterruptedException {
+ return mk.waitForCommit(oldHeadRevision, maxWaitMillis);
+ }
+
+ public String write(InputStream in) {
+ return mk.write(in);
+ }
+
+ public String commitStream(String rootPath, JsopReader jsonDiff, String revisionId, String message) {
+ if (!rootPath.startsWith(INDEX_PATH)) {
+ return mk.commitStream(rootPath, jsonDiff, revisionId, message);
+ }
+ JsopReader t = jsonDiff;
+ while (true) {
+ int r = t.read();
+ if (r == JsopTokenizer.END) {
+ break;
+ }
+ String path;
+ if (rootPath == null) {
+ path = t.readString();
+ } else {
+ path = PathUtils.concat(rootPath, t.readString());
+ }
+ switch (r) {
+ case '+':
+ t.read(':');
+ t.read('{');
+ // parse bug ignore
+ NodeImpl.parse(map, t, 0);
+ path = PathUtils.relativize(INDEX_PATH, path);
+ if (path.startsWith(TYPE_PREFIX)) {
+ String prefix = path.substring(TYPE_PREFIX.length());
+ PrefixIndex idx = indexer.createPrefixIndex(prefix);
+ prefixIndexes.put(path, idx);
+ } else if (path.startsWith(TYPE_PROPERTY)) {
+ String property = path.substring(TYPE_PROPERTY.length());
+ boolean unique = false;
+ if (property.endsWith("," + UNIQUE)) {
+ unique = true;
+ property = property.substring(0, property.length() - UNIQUE.length() - 1);
+ }
+ PropertyIndex idx = indexer.createPropertyIndex(property, unique);
+ propertyIndexes.put(path, idx);
+ } else {
+ throw ExceptionFactory.get("Unknown index type: " + path);
+ }
+ break;
+ case '-':
+ throw ExceptionFactory.get("Removing indexes is not yet implemented");
+ default:
+ throw ExceptionFactory.get("token: " + (char) t.getTokenType());
+ }
+ }
+ return null;
+ }
+
+ public JsopReader getNodesStream(String path, String revisionId, int depth, long offset, int count) {
+ if (!path.startsWith(INDEX_PATH)) {
+ return mk.getNodesStream(path, revisionId, depth, offset, count);
+ }
+ String index = PathUtils.relativize(INDEX_PATH, path);
+ int idx = index.indexOf('?');
+ if (idx < 0) {
+ throw ExceptionFactory.get("Invalid query. Expected: /index/prefix:x?y, got: " + path);
+ }
+ String data = index.substring(idx + 1);
+ index = index.substring(0, idx);
+ JsopStream s = new JsopStream();
+ s.array();
+ if (index.startsWith(TYPE_PREFIX)) {
+ PrefixIndex prefixIndex = prefixIndexes.get(index);
+ if (prefixIndex == null) {
+ if (mk.nodeExists(path, mk.getHeadRevision())) {
+ prefixIndex = indexer.createPrefixIndex(index);
+ } else {
+ throw ExceptionFactory.get("Unknown index: " + index);
+ }
+ }
+ Iterator<String> it = prefixIndex.getPaths(data, revisionId);
+ while (it.hasNext()) {
+ s.value(it.next());
+ }
+ } else if (index.startsWith(TYPE_PROPERTY)) {
+ PropertyIndex propertyIndex = propertyIndexes.get(index);
+ boolean unique = index.endsWith("," + UNIQUE);
+ if (propertyIndex == null) {
+ if (mk.nodeExists(path, mk.getHeadRevision())) {
+ String indexName = index;
+ if (unique) {
+ indexName = index.substring(0, index.length() - UNIQUE.length() - 1);
+ }
+ propertyIndex = indexer.createPropertyIndex(indexName, unique);
+ } else {
+ throw ExceptionFactory.get("Unknown index: " + index);
+ }
+ }
+ if (unique) {
+ String value = propertyIndex.getPath(data, revisionId);
+ if (value != null) {
+ s.value(value);
+ }
+ } else {
+ Iterator<String> it = propertyIndex.getPaths(data, revisionId);
+ while (it.hasNext()) {
+ s.value(it.next());
+ }
+ }
+ }
+ s.endArray();
+ return s;
+ }
+
+ public JsopReader diffStream(String fromRevisionId, String toRevisionId, String path) {
+ return mk.diffStream(fromRevisionId, toRevisionId, path);
+ }
+
+ public JsopReader getJournalStream(String fromRevisionId, String toRevisionId) {
+ return mk.getJournalStream(fromRevisionId, toRevisionId);
+ }
+
+ public JsopReader getNodesStream(String path, String revisionId) {
+ return getNodesStream(path, revisionId, 1, 0, -1);
+ }
+
+ public JsopReader getRevisionsStream(long since, int maxEntries) {
+ return mk.getRevisionsStream(since, maxEntries);
+ }
+
+ public void dispose() {
+ mk.dispose();
+ }
+
+}
Modified: jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/index/PrefixIndexTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/index/PrefixIndexTest.java?rev=1207377&r1=1207376&r2=1207377&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/index/PrefixIndexTest.java (original)
+++ jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/index/PrefixIndexTest.java Mon Nov 28 16:17:41 2011
@@ -35,11 +35,15 @@ public class PrefixIndexTest extends Mul
@Test
public void test() {
- Indexer indexer = new Indexer(mk);
+ Indexer indexer = new Indexer(mk, "index");
PrefixIndex index = indexer.createPrefixIndex("d:");
String head = mk.getHeadRevision();
+ // meta data
+ String meta = mk.getNodes("/index", head);
+ Assert.assertEquals("{\":childNodeCount\":1,\"prefix:d:\":{\":childNodeCount\":0}}", meta);
+
Assert.assertEquals("", getPathList(index, "d:1", head));
head = mk.commit("/", "+\"test\" : {\"blob\":\"d:1\"}", head, null);
Modified: jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/index/PropertyIndexTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/index/PropertyIndexTest.java?rev=1207377&r1=1207376&r2=1207377&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/index/PropertyIndexTest.java (original)
+++ jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/index/PropertyIndexTest.java Mon Nov 28 16:17:41 2011
@@ -34,10 +34,15 @@ public class PropertyIndexTest extends M
@Test
public void test() {
- Indexer indexer = new Indexer(mk);
+ Indexer indexer = new Indexer(mk, "index");
PropertyIndex index = indexer.createPropertyIndex("id", true);
String head = mk.getHeadRevision();
+
+ // meta data
+ String meta = mk.getNodes("/index", head);
+ Assert.assertEquals("{\":childNodeCount\":1,\"property:id;unique\":{\":childNodeCount\":0}}", meta);
+
String oldHead = head;
Assert.assertEquals(null, index.getPath("1", head));
Added: jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/wrapper/TestIndexWrapper.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/wrapper/TestIndexWrapper.java?rev=1207377&view=auto
==============================================================================
--- jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/wrapper/TestIndexWrapper.java (added)
+++ jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/wrapper/TestIndexWrapper.java Mon Nov 28 16:17:41 2011
@@ -0,0 +1,102 @@
+/*
+ * 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.wrapper;
+
+import static org.junit.Assert.assertEquals;
+import org.apache.jackrabbit.mk.MicroKernelFactory;
+import org.apache.jackrabbit.mk.MultiMkTestBase;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+/**
+ * Test the index wrapper.
+ */
+@RunWith(Parameterized.class)
+public class TestIndexWrapper extends MultiMkTestBase {
+
+ private String head;
+
+ public TestIndexWrapper(String url) {
+ super(url);
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ mk = MicroKernelFactory.getInstance("index:" + url);
+ head = mk.getHeadRevision();
+ }
+
+ @Test
+ public void prefix() {
+ if (url.startsWith("fs:")) {
+ return;
+ }
+ head = mk.commit("/index", "+ \"prefix:x\": {}", head, "");
+ head = mk.commit("/", "+ \"n1\": { \"value\":\"a:no\" }", head, "");
+ head = mk.commit("/", "+ \"n2\": { \"value\":\"x:yes\" }", head, "");
+ head = mk.commit("/", "+ \"n3\": { \"value\":\"x:a\" }", head, "");
+ head = mk.commit("/", "+ \"n4\": { \"value\":\"x:a\" }", head, "");
+ String empty = mk.getNodes("/index/prefix:x?x:no", head);
+ assertEquals("[]", empty);
+ System.out.println(empty);
+ String yes = mk.getNodes("/index/prefix:x?x:yes", head);
+ assertEquals("[\"/n2/value\"]", yes);
+ String a = mk.getNodes("/index/prefix:x?x:a", head);
+ assertEquals("[\"/n3/value\",\"/n4/value\"]", a);
+ }
+
+ @Test
+ public void propertyUnique() {
+ if (url.startsWith("fs:")) {
+ return;
+ }
+ head = mk.commit("/index", "+ \"property:id,unique\": {}", head, "");
+ head = mk.commit("/", "+ \"n1\": { \"value\":\"empty\" }", head, "");
+ head = mk.commit("/", "+ \"n2\": { \"id\":\"1\" }", head, "");
+ String empty = mk.getNodes("/index/property:id,unique?0", head);
+ assertEquals("[]", empty);
+ String one = mk.getNodes("/index/property:id,unique?1", head);
+ assertEquals("[\"/n2\"]", one);
+ }
+
+ @Test
+ public void propertyNonUnique() {
+ if (url.startsWith("fs:")) {
+ return;
+ }
+ head = mk.commit("/index", "+ \"property:ref\": {}", head, "");
+ head = mk.commit("/", "+ \"n1\": { \"ref\":\"a\" }", head, "");
+ head = mk.commit("/", "+ \"n2\": { \"ref\":\"b\" }", head, "");
+ head = mk.commit("/", "+ \"n3\": { \"ref\":\"b\" }", head, "");
+ String empty = mk.getNodes("/index/property:ref?no", head);
+ assertEquals("[]", empty);
+ String one = mk.getNodes("/index/property:ref?a", head);
+ assertEquals("[\"/n1\"]", one);
+ String two = mk.getNodes("/index/property:ref?b", head);
+ assertEquals("[\"/n2\",\"/n3\"]", two);
+ }
+
+
+// head = mk.commit("/", "+ \":index/y\": { \"type\":\"property\", \" }", head, "");
+// mkAdmin = MicroKernelFactory.getInstance("sec:sa@abc:" + url);
+// mkGuest = MicroKernelFactory.getInstance("sec:guest@guest:" + url);
+// }
+
+}
Modified: jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/wrapper/TestSecurityWrapper.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/wrapper/TestSecurityWrapper.java?rev=1207377&r1=1207376&r2=1207377&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/wrapper/TestSecurityWrapper.java (original)
+++ jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/wrapper/TestSecurityWrapper.java Mon Nov 28 16:17:41 2011
@@ -49,6 +49,9 @@ public class TestSecurityWrapper extends
@Before
public void setUp() throws Exception {
super.setUp();
+ if (url.startsWith("fs:")) {
+ return;
+ }
head = mk.getHeadRevision();
head = mk.commit("/", "+ \":user\": { \":rights\":\"admin\" }", head, "");
head = mk.commit("/", "+ \":user/sa\": {\"password\": \"abc\", \"rights\":\"admin\" }", head, "");
@@ -84,6 +87,9 @@ public class TestSecurityWrapper extends
@Test
public void commit() {
+ if (url.startsWith("fs:")) {
+ return;
+ }
head = mkAdmin.commit("/", "+ \"test\": { \"data\": \"Hello\" }", head, null);
head = mkAdmin.commit("/", "- \"test\"", head, null);
try {