You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by md...@apache.org on 2012/03/10 12:54:22 UTC
svn commit: r1299183 - in
/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit:
NodeImpl.java state/ChangeTree.java state/EmptyNodeState.java
state/PersistentNodeState.java state/TransientNodeState.java
Author: mduerig
Date: Sat Mar 10 11:54:21 2012
New Revision: 1299183
URL: http://svn.apache.org/viewvc?rev=1299183&view=rev
Log:
Microkernel based prototype of JCR implementation (WIP)
- introduce NodeState interface
Added:
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/EmptyNodeState.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/PersistentNodeState.java
Modified:
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/NodeImpl.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/ChangeTree.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientNodeState.java
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/NodeImpl.java?rev=1299183&r1=1299182&r2=1299183&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/NodeImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/NodeImpl.java Sat Mar 10 11:54:21 2012
@@ -22,9 +22,11 @@ package org.apache.jackrabbit;
import org.apache.jackrabbit.SessionImpl.Context;
import org.apache.jackrabbit.json.JsonValue;
import org.apache.jackrabbit.json.JsonValue.JsonAtom;
+import org.apache.jackrabbit.oak.model.PropertyState;
import org.apache.jackrabbit.spi.commons.iterator.Iterators;
import org.apache.jackrabbit.spi.commons.iterator.Predicate;
import org.apache.jackrabbit.spi.commons.iterator.Transformer;
+import org.apache.jackrabbit.state.PersistentNodeState.PropertyStateImpl;
import org.apache.jackrabbit.state.TransientNodeState;
import org.apache.jackrabbit.utils.ItemNameMatcher;
import org.apache.jackrabbit.utils.NodeIteratorAdapter;
@@ -54,7 +56,6 @@ import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Iterator;
-import java.util.Map.Entry;
public class NodeImpl extends ItemImpl implements Node {
private final TransientNodeState state;
@@ -342,17 +343,17 @@ public class NodeImpl extends ItemImpl i
@Override
public PropertyIterator getProperties() throws RepositoryException {
- Iterator<Entry<String,JsonValue>> properties = state.getProperties();
+ Iterator<PropertyState> properties = state.getProperties();
return new PropertyIteratorAdapter(propertyIterator(properties));
}
@Override
public PropertyIterator getProperties(final String namePattern) throws RepositoryException {
- Iterator<Entry<String, JsonValue>> properties = state.getProperties(
- new Predicate<Entry<String, JsonValue>>() {
+ Iterator<PropertyState> properties = state.getProperties(
+ new Predicate<PropertyState>() {
@Override
- public boolean evaluate(Entry<String, JsonValue> entry) {
- return ItemNameMatcher.matches(entry.getKey(), namePattern);
+ public boolean evaluate(PropertyState entry) {
+ return ItemNameMatcher.matches(entry.getName(), namePattern);
}
});
@@ -361,11 +362,11 @@ public class NodeImpl extends ItemImpl i
@Override
public PropertyIterator getProperties(final String[] nameGlobs) throws RepositoryException {
- Iterator<Entry<String, JsonValue>> propertyNames = state.getProperties(
- new Predicate<Entry<String, JsonValue>>() {
+ Iterator<PropertyState> propertyNames = state.getProperties(
+ new Predicate<PropertyState>() {
@Override
- public boolean evaluate(Entry<String, JsonValue> entry) {
- return ItemNameMatcher.matches(entry.getKey(), nameGlobs);
+ public boolean evaluate(PropertyState entry) {
+ return ItemNameMatcher.matches(entry.getName(), nameGlobs);
}
});
@@ -599,12 +600,14 @@ public class NodeImpl extends ItemImpl i
});
}
- private Iterator<Property> propertyIterator(Iterator<Entry<String, JsonValue>> properties) {
- return Iterators.transformIterator(properties, new Transformer<Entry<String, JsonValue>, Property>() {
+ private Iterator<Property> propertyIterator(Iterator<PropertyState> properties) {
+ return Iterators.transformIterator(properties, new Transformer<PropertyState, Property>() {
@Override
- public Property transform(Entry<String, JsonValue> entry) {
- return PropertyImpl.create(sessionContext, state, entry.getKey(), entry.getValue());
+ public Property transform(PropertyState state) { // fixme don't cast
+ JsonValue value = ((PropertyStateImpl) state).getValue();
+ return PropertyImpl.create(sessionContext, NodeImpl.this.state, state.getName(), value);
}
});
}
+
}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/ChangeTree.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/ChangeTree.java?rev=1299183&r1=1299182&r2=1299183&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/ChangeTree.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/ChangeTree.java Sat Mar 10 11:54:21 2012
@@ -23,8 +23,11 @@ import org.apache.commons.collections.ma
import org.apache.jackrabbit.Path;
import org.apache.jackrabbit.json.JsonValue;
import org.apache.jackrabbit.json.JsonValue.JsonAtom;
+import org.apache.jackrabbit.oak.model.PropertyState;
import org.apache.jackrabbit.spi.commons.iterator.Iterators;
import org.apache.jackrabbit.spi.commons.iterator.Predicate;
+import org.apache.jackrabbit.spi.commons.iterator.Transformer;
+import org.apache.jackrabbit.state.PersistentNodeState.PropertyStateImpl;
import javax.jcr.ItemExistsException;
import javax.jcr.ItemNotFoundException;
@@ -257,13 +260,24 @@ public class ChangeTree {
/**
* @return an iterator of all added and modified properties.
*/
- public Iterator<Entry<String, JsonValue>> getProperties() {
- return Iterators.filterIterator(properties.entrySet().iterator(), new Predicate<Entry<String, JsonValue>>() {
- @Override
- public boolean evaluate(Entry<String, JsonValue> e) {
- return e.getValue() != JsonAtom.NULL;
- }
- });
+ public Iterator<PropertyState> getPropertyStates() {
+ Iterator<Entry<String, JsonValue>> entries =
+ Iterators.filterIterator(properties.entrySet().iterator(),
+ new Predicate<Entry<String, JsonValue>>() {
+ @Override
+ public boolean evaluate(Entry<String, JsonValue> entry) {
+ return entry.getValue() != JsonAtom.NULL;
+ }
+ });
+
+ // fixme: refactor property value encoding
+ return Iterators.transformIterator(entries,
+ new Transformer<Entry<String, JsonValue>, PropertyState>() {
+ @Override
+ public PropertyState transform(final Entry<String, JsonValue> entry) {
+ return new PropertyStateImpl(entry.getKey(), entry.getValue());
+ }
+ });
}
/**
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/EmptyNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/EmptyNodeState.java?rev=1299183&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/EmptyNodeState.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/EmptyNodeState.java Sat Mar 10 11:54:21 2012
@@ -0,0 +1,34 @@
+package org.apache.jackrabbit.state;
+
+import org.apache.jackrabbit.oak.model.AbstractNodeState;
+import org.apache.jackrabbit.oak.model.ChildNodeEntry;
+import org.apache.jackrabbit.oak.model.PropertyState;
+import org.apache.jackrabbit.spi.commons.iterator.Iterators;
+
+import java.util.Iterator;
+
+public final class EmptyNodeState extends AbstractNodeState {
+ public static final EmptyNodeState INSTANCE = new EmptyNodeState();
+
+ private EmptyNodeState() { }
+
+ @Override
+ public Iterable<PropertyState> getProperties() {
+ return new Iterable<PropertyState>() {
+ @Override
+ public Iterator<PropertyState> iterator() {
+ return Iterators.empty();
+ }
+ };
+ }
+
+ @Override
+ public Iterable<ChildNodeEntry> getChildNodeEntries(long offset, long length) {
+ return new Iterable<ChildNodeEntry>() {
+ @Override
+ public Iterator<ChildNodeEntry> iterator() {
+ return Iterators.empty();
+ }
+ };
+ }
+}
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/PersistentNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/PersistentNodeState.java?rev=1299183&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/PersistentNodeState.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/PersistentNodeState.java Sat Mar 10 11:54:21 2012
@@ -0,0 +1,186 @@
+package org.apache.jackrabbit.state;
+
+import org.apache.jackrabbit.Path;
+import org.apache.jackrabbit.json.FullJsonParser;
+import org.apache.jackrabbit.json.JsonValue;
+import org.apache.jackrabbit.json.JsonValue.JsonObject;
+import org.apache.jackrabbit.json.UnescapingJsonTokenizer;
+import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.apache.jackrabbit.oak.model.AbstractChildNodeEntry;
+import org.apache.jackrabbit.oak.model.AbstractNodeState;
+import org.apache.jackrabbit.oak.model.AbstractPropertyState;
+import org.apache.jackrabbit.oak.model.ChildNodeEntry;
+import org.apache.jackrabbit.oak.model.NodeState;
+import org.apache.jackrabbit.oak.model.PropertyState;
+import org.apache.jackrabbit.spi.commons.iterator.Iterators;
+import org.apache.jackrabbit.spi.commons.iterator.Predicate;
+import org.apache.jackrabbit.spi.commons.iterator.Transformer;
+
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+public class PersistentNodeState extends AbstractNodeState {
+ private MicroKernel microkernel;
+ private String revision;
+ private Path path;
+
+ public PersistentNodeState(MicroKernel microkernel, String revision, Path path) {
+ this.microkernel = microkernel;
+ this.revision = revision;
+ this.path = path;
+ }
+
+ @Override
+ public PropertyState getProperty(String name) {
+ JsonObject jsonObject = getPropertiesAsJson();
+ return createPropertyState(name, jsonObject.get(name));
+ }
+
+ @Override
+ public Iterable<PropertyState> getProperties() {
+ return new Iterable<PropertyState>() {
+ private final JsonObject jsonObject = getPropertiesAsJson();
+
+ @Override
+ public Iterator<PropertyState> iterator() {
+ return Iterators.transformIterator(jsonObject.value().entrySet().iterator(),
+ new Transformer<Entry<String, JsonValue>, PropertyState>() {
+ @Override
+ public PropertyState transform(Entry<String, JsonValue> entry) {
+ return createPropertyState(entry.getKey(), entry.getValue());
+ }
+ });
+ }
+ };
+ }
+
+ @Override
+ public NodeState getChildNode(String name) {
+ if (microkernel.nodeExists(name, revision)) {
+ return new PersistentNodeState(microkernel, revision, path.concat(name));
+ }
+ else {
+ return null;
+ }
+ }
+
+ @Override
+ public long getChildNodeCount() {
+ JsonObject jsonObject = getPropertiesAsJson();
+ JsonValue count = jsonObject.get(":childNodeCount");
+ long c = toLong(count);
+ if (c < 0) {
+ return super.getChildNodeCount();
+ }
+ else {
+ return c;
+ }
+ }
+
+ @Override
+ public Iterable<ChildNodeEntry> getChildNodeEntries(final long offset, final long length) {
+ return new Iterable<ChildNodeEntry>() {
+ private final JsonObject jsonObject = getNodesAsJson(offset, length);
+
+ Iterator<Entry<String, JsonValue>> childObjects =
+ Iterators.filterIterator(jsonObject.value().entrySet().iterator(),
+ new Predicate<Entry<String, JsonValue>>() {
+ @Override
+ public boolean evaluate(Entry<String, JsonValue> entry) {
+ return entry.getValue().isObject();
+ }
+ });
+
+ Iterator<ChildNodeEntry> childNodeEntry = Iterators.transformIterator(childObjects,
+ new Transformer<Entry<String, JsonValue>, ChildNodeEntry>() {
+ @Override
+ public ChildNodeEntry transform(Entry<String, JsonValue> entry) {
+ return createChildNodeEntry(entry.getKey());
+ }
+ });
+
+ @Override
+ public Iterator<ChildNodeEntry> iterator() {
+ return childNodeEntry;
+ }
+ };
+ }
+
+ //------------------------------------------< private >---
+
+ private JsonObject getPropertiesAsJson() {
+ String json = microkernel.getNodes(path.toMkPath(), revision, 0, 0, -1, null);
+ return FullJsonParser.parseObject(new UnescapingJsonTokenizer(json));
+ }
+
+ private JsonObject getNodesAsJson(long offset, long length) {
+ // fixme: microkernel should also use long for length
+ String json = microkernel.getNodes(path.toMkPath(), revision, 1, offset, (int) length, null);
+ return FullJsonParser.parseObject(new UnescapingJsonTokenizer(json));
+ }
+
+ private static PropertyState createPropertyState(String name, JsonValue jsonObject) {
+ return new PropertyStateImpl(name, jsonObject);
+ }
+
+ private ChildNodeEntry createChildNodeEntry(String name) {
+ return new ChildNodeEntryImpl(name);
+ }
+
+ private static long toLong(JsonValue count) {
+ if (count == null || !count.isAtom()) {
+ return -1;
+ }
+ else {
+ try {
+ return Long.parseLong(count.asAtom().value());
+ }
+ catch (NumberFormatException e) {
+ return -1;
+ }
+ }
+ }
+
+ public static class PropertyStateImpl extends AbstractPropertyState {
+ private final String name;
+ private final JsonValue value;
+
+ public PropertyStateImpl(String name, JsonValue value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ public JsonValue getValue() {
+ return value;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String getEncodedValue() {
+ return value.toJson();
+ }
+ }
+
+ private class ChildNodeEntryImpl extends AbstractChildNodeEntry {
+ private final String name;
+
+ public ChildNodeEntryImpl(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public NodeState getNode() {
+ return new PersistentNodeState(microkernel, revision, path.concat(name));
+ }
+ }
+
+}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientNodeState.java?rev=1299183&r1=1299182&r2=1299183&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientNodeState.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientNodeState.java Sat Mar 10 11:54:21 2012
@@ -21,29 +21,28 @@ package org.apache.jackrabbit.state;
import org.apache.jackrabbit.Path;
import org.apache.jackrabbit.SessionImpl.Context;
-import org.apache.jackrabbit.json.FullJsonParser;
import org.apache.jackrabbit.json.JsonValue;
import org.apache.jackrabbit.json.JsonValue.JsonAtom;
-import org.apache.jackrabbit.json.JsonValue.JsonObject;
-import org.apache.jackrabbit.json.UnescapingJsonTokenizer;
import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.apache.jackrabbit.oak.model.ChildNodeEntry;
+import org.apache.jackrabbit.oak.model.NodeState;
+import org.apache.jackrabbit.oak.model.PropertyState;
import org.apache.jackrabbit.spi.commons.iterator.Iterators;
import org.apache.jackrabbit.spi.commons.iterator.Predicate;
import org.apache.jackrabbit.spi.commons.iterator.Transformer;
import org.apache.jackrabbit.state.ChangeTree.NodeDelta;
+import org.apache.jackrabbit.state.PersistentNodeState.PropertyStateImpl;
import javax.jcr.ItemExistsException;
import javax.jcr.ItemNotFoundException;
import javax.jcr.PathNotFoundException;
import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
public class TransientNodeState {
private final Context sessionContext;
private String revision;
- private JsonObject jsonObject;
+ private NodeState persistentNodeState;
private NodeDelta nodeDelta;
private TransientNodeState(Context sessionContext, NodeDelta nodeDelta) {
@@ -97,36 +96,35 @@ public class TransientNodeState {
}
public Iterator<TransientNodeState> getChildNodeStates() {
- Map<String, JsonValue> childEntries = getJsonObject().value();
+ Iterable<ChildNodeEntry> persistedEntries = getPersistentNodeState().getChildNodeEntries(0, Long.MAX_VALUE);
final NodeDelta delta = getNodeDelta();
- // fixme: this is not safe against concurrent modifications. Either cope delta or make NodeDelta immutable
- Iterator<Entry<String, JsonValue>> childNodeEntries =
- Iterators.filterIterator(childEntries.entrySet().iterator(),
- new Predicate<Entry<String, JsonValue>>() {
- @Override
- public boolean evaluate(Entry<String, JsonValue> entry) {
- return isNode(entry.getValue()) && !delta.isNodeModified(entry.getKey());
- }
- });
-
- Iterator<TransientNodeState> childNodeStates = Iterators.transformIterator(childNodeEntries,
- new Transformer<Entry<String, JsonValue>, TransientNodeState>() {
+ // fixme: this is not safe against concurrent modifications. Either copy delta or make NodeDelta immutable
+ Iterator<ChildNodeEntry> unmodifiedEntries = Iterators.filterIterator(persistedEntries.iterator(),
+ new Predicate<ChildNodeEntry>() {
+ @Override
+ public boolean evaluate(ChildNodeEntry entry) {
+ return !delta.isNodeModified(entry.getName());
+ }
+ });
+
+ Iterator<TransientNodeState> unmodifiedStates = Iterators.transformIterator(unmodifiedEntries,
+ new Transformer<ChildNodeEntry, TransientNodeState>() {
@Override
- public TransientNodeState transform(Entry<String, JsonValue> entry) {
- return getNodeState(sessionContext, delta.getNode(entry.getKey()));
+ public TransientNodeState transform(ChildNodeEntry entry) {
+ return getNodeState(sessionContext, delta.getNode(entry.getName()));
}
});
- Iterator<TransientNodeState> modifiedNodeStates = Iterators.transformIterator(delta.getNodes(),
- new Transformer<NodeDelta, TransientNodeState>() {
- @Override
- public TransientNodeState transform(NodeDelta delta) {
- return getNodeState(sessionContext, delta);
- }
- });
+ Iterator<TransientNodeState> modifiedStates = Iterators.transformIterator(delta.getNodes(),
+ new Transformer<NodeDelta, TransientNodeState>() {
+ @Override
+ public TransientNodeState transform(NodeDelta delta) {
+ return getNodeState(sessionContext, delta);
+ }
+ });
- return Iterators.iteratorChain(childNodeStates, modifiedNodeStates);
+ return Iterators.iteratorChain(unmodifiedStates, modifiedStates);
}
public Iterator<TransientNodeState> getChildNodeStates(Predicate<TransientNodeState> condition) {
@@ -137,25 +135,24 @@ public class TransientNodeState {
return getProperties().hasNext();
}
- public Iterator<Entry<String, JsonValue>> getProperties() {
- Map<String, JsonValue> childEntries = getJsonObject().value();
+ public Iterator<PropertyState> getProperties() {
+ Iterable<PropertyState> propertyStates = getPersistentNodeState().getProperties();
final NodeDelta delta = getNodeDelta();
- // fixme: this is not safe against concurrent modifications. Either cope delta or make NodeDelta immutable
- Iterator<Entry<String, JsonValue>> propertyEntries =
- Iterators.filterIterator(childEntries.entrySet().iterator(),
- new Predicate<Entry<String, JsonValue>>() {
- @Override
- public boolean evaluate(Entry<String, JsonValue> entry) {
- return !entry.getKey().startsWith(":") && !isNode(entry.getValue())
- && !delta.hasProperty(entry.getKey());
- }
- });
+ // fixme: this is not safe against concurrent modifications. Either copy delta or make NodeDelta immutable
+ Iterator<PropertyState> propertyEntries =
+ Iterators.filterIterator(propertyStates.iterator(),
+ new Predicate<PropertyState>() {
+ @Override
+ public boolean evaluate(PropertyState state) {
+ return !state.getName().startsWith(":") && !delta.hasProperty(state.getName());
+ }
+ });
- return Iterators.iteratorChain(propertyEntries, delta.getProperties());
+ return Iterators.iteratorChain(propertyEntries, delta.getPropertyStates());
}
- public Iterator<Entry<String, JsonValue>> getProperties(Predicate<Entry<String, JsonValue>> condition) {
+ public Iterator<PropertyState> getProperties(Predicate<PropertyState> condition) {
return Iterators.filterIterator(getProperties(), condition);
}
@@ -244,30 +241,29 @@ public class TransientNodeState {
}
private JsonValue getPersistedPropertyValue(String name) {
- JsonValue value = getJsonObject().get(name);
- if (value == null) {
+ PropertyState state = getPersistentNodeState().getProperty(name);
+ if (state == null) {
return null;
}
else {
- return isNode(value) ? null : value;
+ return ((PropertyStateImpl) state).getValue(); // fixme: don't cast
}
}
- private synchronized JsonObject getJsonObject() {
+ private synchronized NodeState getPersistentNodeState() {
Path path = getNodeDelta().getPersistentPath();
String baseRevision = getBaseRevision();
- if (jsonObject == null || !revision.equals(baseRevision)) {
+ if (persistentNodeState == null || !revision.equals(baseRevision)) {
revision = baseRevision;
if (path == null) {
- jsonObject = JsonObject.EMPTY;
+ persistentNodeState = EmptyNodeState.INSTANCE;
}
else {
- String json = getMicrokernel().getNodes(path.toMkPath(), revision);
- jsonObject = FullJsonParser.parseObject(new UnescapingJsonTokenizer(json));
+ persistentNodeState = new PersistentNodeState(getMicrokernel(), revision, path);
}
}
- return jsonObject;
+ return persistentNodeState;
}
private NodeDelta getNodeDelta() {