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 2011/12/27 19:17:40 UTC
svn commit: r1224964 [1/2] - in
/jackrabbit/sandbox/jackrabbit-microkernel/src:
main/java/org/apache/jackrabbit/ main/java/org/apache/jackrabbit/state/
main/java/org/apache/jackrabbit/utils/ test/java/org/apache/jackrabbit/
test/java/org/apache/jackrab...
Author: mduerig
Date: Tue Dec 27 18:17:39 2011
New Revision: 1224964
URL: http://svn.apache.org/viewvc?rev=1224964&view=rev
Log:
Microkernel based prototype of JCR implementation (WIP)
- re-implement transient space
Added:
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/ChangeTree.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/Function1.java
jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/state/
jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/state/TransientSpaceTest.java
Modified:
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/ItemImpl.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/NodeImpl.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/PropertyImpl.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionContext.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionImpl.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientSpace.java
jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/RepositoryTest.java
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/ItemImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/ItemImpl.java?rev=1224964&r1=1224963&r2=1224964&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/ItemImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/ItemImpl.java Tue Dec 27 18:17:39 2011
@@ -20,7 +20,7 @@
package org.apache.jackrabbit;
import org.apache.jackrabbit.SessionImpl.Context;
-import org.apache.jackrabbit.state.NodeDelta;
+import org.apache.jackrabbit.state.ChangeTree;
import javax.jcr.Item;
import javax.jcr.ItemNotFoundException;
@@ -85,12 +85,24 @@ abstract class ItemImpl implements Item
@Override
public boolean isNew() {
- return getNodeDelta().isNew();
+ try {
+ return getNodeDelta().isTransient();
+ }
+ catch (ItemNotFoundException e) {
+ // should never happen
+ throw new IllegalStateException(e);
+ }
}
@Override
public boolean isModified() {
- return getNodeDelta().isModified();
+ try {
+ return getNodeDelta().hasChanges();
+ }
+ catch (ItemNotFoundException e) {
+ // should never happen
+ throw new IllegalStateException(e);
+ }
}
@Override
@@ -136,9 +148,9 @@ abstract class ItemImpl implements Item
protected final boolean isStale() {
return !sessionContext.getRevision().equals(revision);
}
-
- protected final NodeDelta getNodeDelta() {
- return sessionContext.getTransientSpace().getNodeDelta(path);
+
+ protected final ChangeTree.NodeDelta getNodeDelta() throws ItemNotFoundException {
+ return sessionContext.getTransientSpace().getNode(path);
}
}
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=1224964&r1=1224963&r2=1224964&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 Tue Dec 27 18:17:39 2011
@@ -25,21 +25,22 @@ import org.apache.jackrabbit.json.JsonVa
import org.apache.jackrabbit.json.JsonValue.JsonObject;
import org.apache.jackrabbit.json.JsonValue.Type;
import org.apache.jackrabbit.json.UnescapingJsonTokenizer;
-import org.apache.jackrabbit.state.NodeDelta;
+import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.apache.jackrabbit.spi.commons.iterator.Iterators;
+import org.apache.jackrabbit.spi.commons.iterator.Transformer;
+import org.apache.jackrabbit.state.ChangeTree;
import org.apache.jackrabbit.state.TransientSpace;
import org.apache.jackrabbit.utils.Arrays;
import org.apache.jackrabbit.utils.ChildItemCollector;
import org.apache.jackrabbit.utils.NodeIteratorAdapter;
import org.apache.jackrabbit.utils.PropertyIteratorAdapter;
import org.apache.jackrabbit.utils.ValueConverter;
-import org.apache.jackrabbit.mk.api.MicroKernel;
-import org.apache.jackrabbit.spi.commons.iterator.Iterators;
-import org.apache.jackrabbit.spi.commons.iterator.Transformer;
import javax.jcr.Binary;
import javax.jcr.InvalidItemStateException;
import javax.jcr.Item;
import javax.jcr.ItemExistsException;
+import javax.jcr.ItemNotFoundException;
import javax.jcr.ItemVisitor;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
@@ -97,7 +98,7 @@ public class NodeImpl extends ItemImpl i
TransientSpace transientSpace = sessionContext.getTransientSpace();
Path newPath = path.concat(relPath);
- transientSpace.addNode(newPath.getParent(), newPath.getName());
+ transientSpace.getNode(newPath.getParent()).addNode(newPath.getName());
return getNode(relPath);
}
@@ -109,7 +110,7 @@ public class NodeImpl extends ItemImpl i
TransientSpace transientSpace = sessionContext.getTransientSpace();
Path newPath = path.concat(relPath);
- transientSpace.addNode(newPath.getParent(), newPath.getName());
+ transientSpace.getNode(newPath.getParent()).addNode(newPath.getName());
setPrimaryType(primaryNodeTypeName);
return getNode(relPath);
}
@@ -117,20 +118,20 @@ public class NodeImpl extends ItemImpl i
@Override
public void remove() throws RepositoryException {
TransientSpace transientSpace = sessionContext.getTransientSpace();
- transientSpace.removeNode(path);
+ transientSpace.getNode(path.getParent()).removeNode(path.getName());
}
@Override
public Property setProperty(String name, Value value, int type) throws RepositoryException {
TransientSpace transientSpace = sessionContext.getTransientSpace();
- transientSpace.addProperty(path, name, ValueConverter.toJsonValue(value));
+ transientSpace.getNode(path).setValue(name, ValueConverter.toJsonValue(value));
return getProperty(name);
}
@Override
public Property setProperty(String name, Value[] values, int type) throws RepositoryException {
TransientSpace transientSpace = sessionContext.getTransientSpace();
- transientSpace.addProperty(path, name, ValueConverter.toJsonValue(values));
+ transientSpace.getNode(path).setValue(name, ValueConverter.toJsonValue(values));
return getProperty(name);
}
@@ -140,7 +141,7 @@ public class NodeImpl extends ItemImpl i
ValueFactory valueFactory = sessionContext.getValueFactory();
Value value = valueFactory.createValue(mixinName);
Value[] values = getProperty("jcr:mixinTypes").getValues();
- transientSpace.setMixin(path, ValueConverter.toJsonValue(Arrays.add(values, value)));
+ transientSpace.getNode(path).setValue("jcr:mixinTypes", ValueConverter.toJsonValue(Arrays.add(values, value)));
}
@Override
@@ -149,7 +150,7 @@ public class NodeImpl extends ItemImpl i
ValueFactory valueFactory = sessionContext.getValueFactory();
Value value = valueFactory.createValue(mixinName);
Value[] values = getProperty("jcr:mixinTypes").getValues();
- transientSpace.setMixin(path, ValueConverter.toJsonValue(Arrays.remove(values, value)));
+ transientSpace.getNode(path).setValue("jcr:mixinTypes", ValueConverter.toJsonValue(Arrays.remove(values, value)));
}
@Override
@@ -157,7 +158,7 @@ public class NodeImpl extends ItemImpl i
TransientSpace transientSpace = sessionContext.getTransientSpace();
ValueFactory valueFactory = sessionContext.getValueFactory();
Value value = valueFactory.createValue(nodeTypeName);
- transientSpace.setPrimaryType(path, ValueConverter.toJsonValue(value));
+ transientSpace.getNode(path).setValue("jcr:primaryType", ValueConverter.toJsonValue(value));
}
@@ -277,15 +278,14 @@ public class NodeImpl extends ItemImpl i
@Override
public NodeIterator getNodes() throws RepositoryException {
- final NodeDelta delta = getNodeDelta();
-
- Iterator<Entry<String, JsonValue>> childItems =
- Iterators.iteratorChain(getPersistedItems(this), getAddedNodes(delta));
+ Iterator<Entry<String, JsonValue>> persistedItems = getPersistedItems(this);
+ Iterator<Entry<String, JsonValue>> addedNodes = getAddedNodes(getNodeDelta());
+ Iterator<Entry<String, JsonValue>> childItems = Iterators.iteratorChain(persistedItems, addedNodes);
return new NodeIteratorAdapter(new ChildItemCollector<Node>(childItems) {
@Override
protected boolean include(String name, JsonValue value) {
- return value.type() == Type.OBJECT && !delta.hasRemovedNode(name);
+ return value.type() == Type.OBJECT;
}
@Override
@@ -297,17 +297,14 @@ public class NodeImpl extends ItemImpl i
@Override
public NodeIterator getNodes(final String namePattern) throws RepositoryException {
- final NodeDelta delta = getNodeDelta();
-
- Iterator<Entry<String, JsonValue>> childItems =
- Iterators.iteratorChain(getPersistedItems(this), getAddedNodes(delta));
+ Iterator<Entry<String, JsonValue>> persistedItems = getPersistedItems(this);
+ Iterator<Entry<String, JsonValue>> addedNodes = getAddedNodes(getNodeDelta());
+ Iterator<Entry<String, JsonValue>> childItems = Iterators.iteratorChain(persistedItems, addedNodes);
return new NodeIteratorAdapter(new ChildItemCollector<Node>(childItems) {
@Override
protected boolean include(String name, JsonValue value) {
- return value.type() == Type.OBJECT
- && ChildItemCollector.matches(name, namePattern)
- && !delta.hasRemovedNode(name);
+ return value.type() == Type.OBJECT && ChildItemCollector.matches(name, namePattern);
}
@Override
@@ -319,17 +316,14 @@ public class NodeImpl extends ItemImpl i
@Override
public NodeIterator getNodes(final String[] nameGlobs) throws RepositoryException {
- final NodeDelta delta = getNodeDelta();
-
- Iterator<Entry<String, JsonValue>> childItems =
- Iterators.iteratorChain(getPersistedItems(this), getAddedNodes(delta));
+ Iterator<Entry<String, JsonValue>> persistedItems = getPersistedItems(this);
+ Iterator<Entry<String, JsonValue>> addedNodes = getAddedNodes(getNodeDelta());
+ Iterator<Entry<String, JsonValue>> childItems = Iterators.iteratorChain(persistedItems, addedNodes);
return new NodeIteratorAdapter(new ChildItemCollector<Node>(childItems) {
@Override
protected boolean include(String name, JsonValue value) {
- return value.type() == Type.OBJECT
- && ChildItemCollector.matches(name, nameGlobs)
- && !delta.hasRemovedNode(name);
+ return value.type() == Type.OBJECT && ChildItemCollector.matches(name, nameGlobs);
}
@Override
@@ -356,17 +350,14 @@ public class NodeImpl extends ItemImpl i
@Override
public PropertyIterator getProperties() throws RepositoryException {
- final NodeDelta delta = getNodeDelta();
-
- Iterator<Entry<String, JsonValue>> childItems =
- Iterators.iteratorChain(getPersistedItems(this), getProperties(delta));
+ Iterator<Entry<String, JsonValue>> persistedItems = getPersistedItems(this);
+ Iterator<Entry<String, JsonValue>> addedProperties = getProperties(getNodeDelta());
+ Iterator<Entry<String, JsonValue>> childItems = Iterators.iteratorChain(persistedItems, addedProperties);
return new PropertyIteratorAdapter(new ChildItemCollector<Property>(childItems){
@Override
protected boolean include(String name, JsonValue value) {
- return !name.startsWith(":")
- && value.type() != Type.OBJECT
- && !delta.hasRemovedProperty(name);
+ return !name.startsWith(":") && value.type() != Type.OBJECT;
}
@Override
@@ -378,18 +369,15 @@ public class NodeImpl extends ItemImpl i
@Override
public PropertyIterator getProperties(final String namePattern) throws RepositoryException {
- final NodeDelta delta = getNodeDelta();
-
- Iterator<Entry<String, JsonValue>> childItems =
- Iterators.iteratorChain(getPersistedItems(this), getProperties(delta));
+ Iterator<Entry<String, JsonValue>> persistedItems = getPersistedItems(this);
+ Iterator<Entry<String, JsonValue>> addedProperties = getProperties(getNodeDelta());
+ Iterator<Entry<String, JsonValue>> childItems = Iterators.iteratorChain(persistedItems, addedProperties);
return new PropertyIteratorAdapter(new ChildItemCollector<Property>(childItems){
@Override
protected boolean include(String name, JsonValue value) {
- return !name.startsWith(":")
- && value.type() != Type.OBJECT
- && ChildItemCollector.matches(name, namePattern)
- && ! delta.hasRemovedProperty(name);
+ return !name.startsWith(":") && value.type() != Type.OBJECT
+ && ChildItemCollector.matches(name, namePattern);
}
@Override
@@ -401,18 +389,15 @@ public class NodeImpl extends ItemImpl i
@Override
public PropertyIterator getProperties(final String[] nameGlobs) throws RepositoryException {
- final NodeDelta delta = getNodeDelta();
-
- Iterator<Entry<String, JsonValue>> childItems =
- Iterators.iteratorChain(getPersistedItems(this), getProperties(delta));
+ Iterator<Entry<String, JsonValue>> persistedItems = getPersistedItems(this);
+ Iterator<Entry<String, JsonValue>> addedProperties = getProperties(getNodeDelta());
+ Iterator<Entry<String, JsonValue>> childItems = Iterators.iteratorChain(persistedItems, addedProperties);
return new PropertyIteratorAdapter(new ChildItemCollector<Property>(childItems){
@Override
protected boolean include(String name, JsonValue value) {
- return !name.startsWith(":")
- && value.type() != Type.OBJECT
- && ChildItemCollector.matches(name, nameGlobs)
- && ! delta.hasRemovedProperty(name);
+ return !name.startsWith(":") && value.type() != Type.OBJECT
+ && ChildItemCollector.matches(name, nameGlobs);
}
@Override
@@ -646,11 +631,19 @@ public class NodeImpl extends ItemImpl i
}
private static JsonObject getNode(Context sessionContext, Path path) {
- NodeDelta delta = sessionContext.getTransientSpace().getNodeDelta(path);
- if (delta == null) {
+ if (!sessionContext.getTransientSpace().nodeExists(path)) {
return null;
}
+ ChangeTree.NodeDelta delta;
+ try {
+ delta = sessionContext.getTransientSpace().getNode(path);
+ }
+ catch (ItemNotFoundException e) {
+ // should not happen
+ throw new IllegalStateException(e);
+ }
+
Path persistedPath = delta.getPersistentPath();
if (persistedPath == null) {
return JsonObject.EMPTY;
@@ -672,16 +665,16 @@ public class NodeImpl extends ItemImpl i
return node.getNode().value().entrySet().iterator();
}
- private static Iterator<Entry<String, JsonValue>> getAddedNodes(NodeDelta delta) {
- return Iterators.transformIterator(delta.getAddedNodes().keySet().iterator(),
- new Transformer<String, Entry<String, JsonValue>>() {
+ private static Iterator<Entry<String, JsonValue>> getAddedNodes(ChangeTree.NodeDelta delta) {
+ return Iterators.transformIterator(delta.getNodes(),
+ new Transformer<Entry<String, ChangeTree.NodeDelta>, Entry<String, JsonValue>>() {
@Override
- public Entry<String, JsonValue> transform(final String name) {
+ public Entry<String, JsonValue> transform(final Entry<String, ChangeTree.NodeDelta> entry) {
return new Entry<String, JsonValue>() {
@Override
public String getKey() {
- return name;
+ return entry.getKey();
}
@Override
@@ -691,16 +684,16 @@ public class NodeImpl extends ItemImpl i
@Override
public JsonValue setValue(JsonValue value) {
- assert false;
- return null;
+ assert false;
+ return null;
+ }
+ };
}
- };
- }
- });
+ });
}
- private Iterator<? extends Entry<String, JsonValue>> getProperties(NodeDelta delta) {
- return delta.getProperties().entrySet().iterator();
+ private static Iterator<Entry<String, JsonValue>> getProperties(ChangeTree.NodeDelta delta) {
+ return delta.getProperties();
}
}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/PropertyImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/PropertyImpl.java?rev=1224964&r1=1224963&r2=1224964&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/PropertyImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/PropertyImpl.java Tue Dec 27 18:17:39 2011
@@ -25,13 +25,14 @@ import org.apache.jackrabbit.json.JsonVa
import org.apache.jackrabbit.json.JsonValue.JsonObject;
import org.apache.jackrabbit.json.JsonValue.Type;
import org.apache.jackrabbit.json.UnescapingJsonTokenizer;
-import org.apache.jackrabbit.state.NodeDelta;
+import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.apache.jackrabbit.state.ChangeTree;
import org.apache.jackrabbit.state.TransientSpace;
import org.apache.jackrabbit.utils.ValueConverter;
-import org.apache.jackrabbit.mk.api.MicroKernel;
import javax.jcr.Binary;
import javax.jcr.InvalidItemStateException;
+import javax.jcr.ItemNotFoundException;
import javax.jcr.ItemVisitor;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
@@ -74,25 +75,20 @@ public class PropertyImpl extends ItemIm
@Override
public void remove() throws RepositoryException {
- TransientSpace transientSpace = sessionContext.getTransientSpace();
- transientSpace.removeProperty(path);
+ setValue((Value) null);
}
@Override
public void setValue(Value value) throws RepositoryException {
TransientSpace transientSpace = sessionContext.getTransientSpace();
- if (value == null) {
- remove();
- }
- else {
- transientSpace.setValue(path, ValueConverter.toJsonValue(value));
- }
+ transientSpace.getNode(path.getParent()).setValue(path.getName(),
+ value == null ? null : ValueConverter.toJsonValue(value));
}
@Override
public void setValue(Value[] values) throws RepositoryException {
TransientSpace transientSpace = sessionContext.getTransientSpace();
- transientSpace.setValue(path, ValueConverter.toJsonValue(values));
+ transientSpace.getNode(path.getParent()).setValue(path.getName(), ValueConverter.toJsonValue(values));
}
@Override
@@ -320,16 +316,21 @@ public class PropertyImpl extends ItemIm
private static JsonValue getProperty(Context sessionContext, Path path) {
Path parentPath = path.getParent();
- NodeDelta delta = sessionContext.getTransientSpace().getNodeDelta(parentPath);
- if (delta == null) {
+ if (!sessionContext.getTransientSpace().nodeExists(parentPath)) {
return null;
}
- String name = path.getName();
- if (delta.hasRemovedProperty(name)) {
- return null;
+ ChangeTree.NodeDelta delta;
+ try {
+ delta = sessionContext.getTransientSpace().getNode(parentPath);
+ }
+ catch (ItemNotFoundException e) {
+ // should never happen
+ throw new IllegalStateException(e);
}
- if (delta.hasAddedProperty(name)) {
+
+ String name = path.getName();
+ if (delta.hasProperty(name)) {
return delta.getProperty(name);
}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionContext.java?rev=1224964&r1=1224963&r2=1224964&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionContext.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionContext.java Tue Dec 27 18:17:39 2011
@@ -19,9 +19,9 @@
package org.apache.jackrabbit;
+import org.apache.jackrabbit.mk.api.MicroKernel;
import org.apache.jackrabbit.security.CredentialsInfo;
import org.apache.jackrabbit.state.TransientSpace;
-import org.apache.jackrabbit.mk.api.MicroKernel;
import javax.jcr.Session;
import javax.jcr.ValueFactory;
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionImpl.java?rev=1224964&r1=1224963&r2=1224964&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/SessionImpl.java Tue Dec 27 18:17:39 2011
@@ -19,10 +19,10 @@
package org.apache.jackrabbit;
+import org.apache.jackrabbit.mk.api.MicroKernel;
import org.apache.jackrabbit.security.Authenticator;
import org.apache.jackrabbit.security.CredentialsInfo;
import org.apache.jackrabbit.state.TransientSpace;
-import org.apache.jackrabbit.mk.api.MicroKernel;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
@@ -136,7 +136,7 @@ public class SessionImpl implements Sess
this.workspaceName = workspaceName;
this.revision = revision;
microKernel = globalContext.getInstance(MicroKernel.class);
- transientSpace = new TransientSpace(microKernel, revision, Path.create(workspaceName));
+ transientSpace = new TransientSpace(workspaceName, microKernel, revision);
}
//------------------------------------------< Session >---
Added: 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=1224964&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/ChangeTree.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/ChangeTree.java Tue Dec 27 18:17:39 2011
@@ -0,0 +1,580 @@
+package org.apache.jackrabbit.state;
+
+import org.apache.jackrabbit.Path;
+import org.apache.jackrabbit.json.JsonValue;
+import org.apache.jackrabbit.spi.commons.iterator.Iterators;
+import org.apache.jackrabbit.spi.commons.iterator.Predicate;
+import org.apache.jackrabbit.utils.Function1;
+
+import javax.jcr.ItemExistsException;
+import javax.jcr.ItemNotFoundException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * A change tree records changes to a tree of nodes and properties and it provides
+ * a consolidated view of these changes. Changes are described by operations for
+ * adding nodes, removing nodes, moving nodes and setting properties. <p/>
+ *
+ * A consolidate change list can be obtained from change trees. A change list is
+ * a list of operations. A consolidated changes list is a change list which is
+ * equivalent to the change list consisting of all operations applied to the change
+ * tree and which is minimal amongst all change lists which are equivalent to the
+ * former one. <p/>
+ *
+ * Two change lists are equivalent iff their effect on a tree of nodes and properties
+ * is the same. That is, when applied to a tree both result in the same final state
+ * of that tree. <p/>
+ *
+ * A change list is minimal amongst a set of change lists, if no change list in that
+ * set contains more operations. <p/>
+ *
+ * Internally a change tree is a tree of node deltas. A node delta describes whether
+ * a node has been added, removed, moved or whether its properties have been changed.
+ * A change tree contains a node delta for each touched node. A node is touched if it
+ * is modified or one of its child nodes is touched. A node is modified if it is
+ * transient or has modified properties. A node is transient if it is either added,
+ * removed or moved. <p/>
+ *
+ * A move operation is conceptually handled as a remove operation followed by an add
+ * operation of the respective sub tree. In order to keep track of the move operation
+ * the individual remove and add operations are marked as belonging to that move
+ * operation. <p/>
+ *
+ * Since a remove node operation cancels a preceding add node operation for the same
+ * node and because a move operation resembles a remove followed by an add operation
+ * following equivalencies apply for move operations:
+ *
+ * <ul>
+ * <li>Removing a node after it has been moved is equivalent to removing the original
+ * node.</li>
+ * <li>Moving a node after it has been added is equivalent to adding the node at the
+ * target of the move.</li>
+ * <li>Moving a moved node is equivalent to directly moving from the original source
+ * to the eventual target.</li>
+ * </ul>
+ */
+public class ChangeTree {
+ private final NodeDelta root;
+ private final Function1<String, Boolean> nodeExists;
+
+ public ChangeTree(final Path rootPath, Function1<String, Boolean> nodeExists) {
+ this.nodeExists = nodeExists;
+
+ root = new Existing(null, "") {
+ @Override
+ public Path getPath() {
+ return rootPath;
+ }
+ };
+ }
+
+ public boolean nodeExists(Path path) {
+ return getNodeOrNull(path) != null;
+ }
+
+ public NodeDelta getNode(Path path) throws ItemNotFoundException {
+ NodeDelta delta = getNodeOrNull(path);
+ if (delta == null) {
+ throw new ItemNotFoundException(path.getPath());
+ }
+
+ return delta;
+ }
+
+ public void collectChanges(Listener listener) {
+ root.accept(new ChangeVisitor(listener));
+ }
+
+ public void clear() {
+ root.clear();
+ }
+
+ public boolean hasChanges() {
+ return root.hasChanges();
+ }
+
+ private NodeDelta getNodeOrNull(Path path) {
+ NodeDelta delta = root;
+ for (String name : path.getNames()) {
+ delta = delta.getNode(name);
+ if (delta == null) {
+ return null;
+ }
+ }
+ return delta;
+ }
+
+ public interface Visitor {
+ void visit(Existing delta);
+ void visit(Added delta);
+ void visit(Removed delta);
+ void visit(Moved delta);
+ }
+
+ public interface Listener {
+ void addNode(Path path);
+ void removeNode(Path path);
+ void moveNode(Path sourcePath, Path destinationPath);
+ void setProperty(Path path, JsonValue value);
+ }
+
+ private class ChangeVisitor implements Visitor {
+ private final Listener listener;
+
+ public ChangeVisitor(Listener listener) {
+ this.listener = listener;
+ }
+
+ @Override
+ public void visit(Existing delta) {
+ handleProperties(delta);
+ visitNodes(delta);
+ }
+
+ @Override
+ public void visit(Added delta) {
+ listener.addNode(delta.getPath());
+ handleProperties(delta);
+ visitNodes(delta);
+ }
+
+ @Override
+ public void visit(Removed delta) {
+ if (!delta.isMoved()) {
+ listener.removeNode(delta.getPath());
+ }
+ }
+
+ @Override
+ public void visit(Moved delta) {
+ delta.source.accept(this);
+ listener.moveNode(delta.getSourcePath(), delta.getPath());
+ }
+
+ private void handleProperties(NodeDelta delta) {
+ Path path = delta.getPath();
+ for (Entry<String, JsonValue> property : delta.properties.entrySet()) {
+ String name = property.getKey();
+ JsonValue value = property.getValue();
+ listener.setProperty(path.concat(name), value);
+ }
+ }
+
+ private void visitNodes(NodeDelta delta) {
+ for (NodeDelta node : delta.childNodes()) {
+ node.accept(this);
+ }
+ }
+ }
+
+ public abstract class NodeDelta {
+ private final Map<String, NodeDelta> childNodes = new HashMap<String, NodeDelta>();
+ private final Map<String, JsonValue> properties = new HashMap<String, JsonValue>();
+ protected NodeDelta parent;
+ protected String name;
+
+ NodeDelta(NodeDelta parent, String name) {
+ this.parent = parent;
+ this.name = name;
+ }
+
+ public Path getPath() {
+ return parent.getPath().concat(name);
+ }
+
+ public Path getPersistentPath() {
+ return null;
+ }
+
+ public abstract boolean isRemoved();
+ public abstract boolean isMoved();
+ public abstract boolean isTransient();
+
+ public abstract void accept(Visitor visitor);
+
+ public boolean hasChanges() {
+ return !childNodes.isEmpty() || !properties.isEmpty();
+ }
+
+ public final boolean hasNode(String name) {
+ return getNode(name) != null;
+ }
+
+ public abstract NodeDelta getNode(String name);
+
+ public Iterator<Entry<String, NodeDelta>> getNodes() {
+ return Iterators.filterIterator(childNodes.entrySet().iterator(), new Predicate<Entry<String, NodeDelta>>() {
+ @Override
+ public boolean evaluate(Entry<String, NodeDelta> entry) {
+ NodeDelta delta = entry.getValue();
+ return delta.isTransient() && !delta.isRemoved();
+ }
+ });
+ }
+
+ public boolean hasProperty(String name) {
+ return properties.containsKey(name);
+ }
+
+ public JsonValue getProperty(String name) {
+ return properties.get(name);
+ }
+
+ public Iterator<Entry<String, JsonValue>> getProperties() {
+ return Iterators.filterIterator(properties.entrySet().iterator(), new Predicate<Entry<String, JsonValue>>() {
+ @Override
+ public boolean evaluate(Entry<String, JsonValue> entry) {
+ return entry.getValue() != null;
+ }
+ });
+ }
+
+ public NodeDelta addNode(String name) throws ItemExistsException {
+ if (hasNode(name)) {
+ throw new ItemExistsException(name);
+ }
+
+ return addChild(new Added(this, name));
+ }
+
+ public NodeDelta removeNode(String name) throws ItemNotFoundException {
+ NodeDelta delta = getNode(name);
+ if (delta == null) {
+ throw new ItemNotFoundException(name);
+ }
+
+ return delta.remove();
+ }
+
+ public void moveNode(String name, Path destination) throws ItemNotFoundException, ItemExistsException {
+ NodeDelta source = getNode(name);
+ if (source == null) {
+ throw new ItemNotFoundException(name);
+ }
+
+ if (nodeExists(destination)) {
+ throw new ItemExistsException(destination.getPath());
+ }
+
+ Path destParentPath = destination.getParent();
+ if (!nodeExists(destParentPath)) {
+ throw new ItemNotFoundException(destParentPath.getPath());
+ }
+
+ if (source.isTransient()) {
+ removeChild(name);
+ }
+ else {
+ addChild(new Removed(this, name, true));
+ }
+
+ // Resolve destination only *after* source has been removed in order
+ // to make sure nodes on any common path prefix are already touched.
+ NodeDelta destParent = ChangeTree.this.getNode(destParentPath);
+ source.moveTo(destParent, destination.getName());
+ }
+
+ public void setValue(String name, JsonValue value) {
+ if (value == null && properties.containsKey(name) && properties.get(name) != null) {
+ properties.remove(name);
+ }
+ else {
+ properties.put(name, value);
+ touch();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return getPath().toString();
+ }
+
+ //------------------------------------------< internal >---
+
+ void touch() { }
+
+ abstract NodeDelta remove() throws ItemNotFoundException;
+ abstract void moveTo(NodeDelta parent, String name);
+
+ final void clear() {
+ childNodes.clear();
+ properties.clear();
+ }
+
+ final Iterable<NodeDelta> childNodes() {
+ return childNodes.values();
+ }
+
+ final NodeDelta getChild(String name) {
+ return childNodes.get(name);
+ }
+
+ final boolean hasChild(String name) {
+ return childNodes.containsKey(name);
+ }
+
+ final NodeDelta addChild(NodeDelta delta) {
+ childNodes.put(delta.name, delta);
+ touch();
+ return delta;
+ }
+
+ final NodeDelta removeChild(String name) {
+ NodeDelta delta = childNodes.remove(name);
+ if (delta != null) {
+ touch();
+ }
+ return delta;
+ }
+ }
+
+ public class Existing extends NodeDelta {
+ Existing(NodeDelta parent, String name) {
+ super(parent, name);
+ }
+
+ @Override
+ public Path getPersistentPath() {
+ return getPath();
+ }
+
+ @Override
+ public boolean isRemoved() {
+ return false;
+ }
+
+ @Override
+ public boolean isMoved() {
+ return false;
+ }
+
+ @Override
+ public boolean isTransient() {
+ return false;
+ }
+
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public NodeDelta getNode(String name) {
+ NodeDelta delta = getChild(name);
+ if (delta == null) {
+ return nodeExists.apply(getPath().concat(name).getMkPath())
+ ? new Existing(this, name)
+ : null;
+ }
+ else {
+ return delta.isRemoved() ? null : delta;
+ }
+ }
+
+ @Override
+ void touch() {
+ if (parent != null && ! parent.hasChild(name)) {
+ parent.addChild(this);
+ }
+ }
+
+ @Override
+ NodeDelta remove() {
+ return parent.addChild(new Removed(parent, name, false));
+ }
+
+ @Override
+ void moveTo(NodeDelta parent, String name) {
+ parent.addChild(new Moved(parent, name, this));
+ }
+ }
+
+ public class Added extends NodeDelta {
+ Added(NodeDelta parent, String name) {
+ super(parent, name);
+ }
+
+ @Override
+ public boolean isRemoved() {
+ return false;
+ }
+
+ @Override
+ public boolean isMoved() {
+ return false;
+ }
+
+ @Override
+ public boolean isTransient() {
+ return true;
+ }
+
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public NodeDelta getNode(String name) {
+ return getChild(name);
+ }
+
+ @Override
+ NodeDelta remove() {
+ return parent.removeChild(name);
+ }
+
+ @Override
+ void moveTo(NodeDelta parent, String name) {
+ this.parent = parent;
+ this.name = name;
+ parent.addChild(this);
+ }
+ }
+
+ public class Moved extends NodeDelta {
+ private final NodeDelta source;
+
+ Moved(NodeDelta parent, String name, NodeDelta source) {
+ super(parent, name);
+ this.source = source;
+ }
+
+ Path getSourcePath() {
+ return source.getPath();
+ }
+
+ @Override
+ public Path getPersistentPath() {
+ return source.getPersistentPath();
+ }
+
+ @Override
+ public boolean isRemoved() {
+ return false;
+ }
+
+ @Override
+ public boolean isMoved() {
+ return true;
+ }
+
+ @Override
+ public boolean isTransient() {
+ return true;
+ }
+
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public NodeDelta getNode(String name) {
+ return source.getNode(name);
+ }
+
+ @Override
+ public NodeDelta addNode(String name) throws ItemExistsException {
+ return source.addNode(name);
+ }
+
+ @Override
+ public NodeDelta removeNode(String name) throws ItemNotFoundException {
+ return source.removeNode(name);
+ }
+
+ @Override
+ public void moveNode(String name, Path destination) throws ItemNotFoundException, ItemExistsException {
+ source.moveNode(name, destination);
+ }
+
+ @Override
+ public void setValue(String name, JsonValue value) {
+ source.setValue(name, value);
+ }
+
+ @Override
+ NodeDelta remove() throws ItemNotFoundException {
+ // convert source from moved away to removed
+ if (source.parent.childNodes.remove(source.name) != null) {
+ source.parent.removeNode(source.name);
+ }
+
+ return parent.removeChild(name);
+ }
+
+ @Override
+ void moveTo(NodeDelta parent, String name) {
+ parent.addChild(new Moved(parent, name, source));
+ }
+ }
+
+ public class Removed extends NodeDelta {
+ private final boolean moved;
+
+ Removed(NodeDelta parent, String name, boolean moved) {
+ super(parent, name);
+ this.moved = moved;
+ }
+
+ @Override
+ public boolean isRemoved() {
+ return true;
+ }
+
+ @Override
+ public boolean isMoved() {
+ return moved;
+ }
+
+ @Override
+ public boolean isTransient() {
+ return true;
+ }
+
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public NodeDelta getNode(String name) {
+ throw new IllegalStateException("Removed");
+ }
+
+ @Override
+ public NodeDelta addNode(String name) {
+ throw new IllegalStateException("Removed");
+ }
+
+ @Override
+ public NodeDelta removeNode(String name) {
+ throw new IllegalStateException("Removed");
+ }
+
+ @Override
+ public void moveNode(String name, Path destination) {
+ throw new IllegalStateException("Removed");
+ }
+
+ @Override
+ public void setValue(String name, JsonValue value) {
+ throw new IllegalStateException("Removed");
+ }
+
+ @Override
+ NodeDelta remove() throws ItemNotFoundException {
+ throw new IllegalStateException("Removed");
+ }
+
+ @Override
+ void moveTo(NodeDelta parent, String name) {
+ throw new IllegalStateException("Removed");
+ }
+ }
+
+}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientSpace.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientSpace.java?rev=1224964&r1=1224963&r2=1224964&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientSpace.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/state/TransientSpace.java Tue Dec 27 18:17:39 2011
@@ -1,298 +1,78 @@
-/*
- * 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.state;
import org.apache.jackrabbit.Path;
import org.apache.jackrabbit.json.JsonValue;
-import org.apache.jackrabbit.json.JsonValue.JsonArray;
-import org.apache.jackrabbit.json.JsonValue.JsonAtom;
-import org.apache.jackrabbit.state.Operation.AddNode;
-import org.apache.jackrabbit.state.Operation.AddProperty;
-import org.apache.jackrabbit.state.Operation.Move;
-import org.apache.jackrabbit.state.Operation.RemoveNode;
-import org.apache.jackrabbit.state.Operation.RemoveProperty;
-import org.apache.jackrabbit.state.Operation.Reorder;
-import org.apache.jackrabbit.state.Operation.SetMixin;
-import org.apache.jackrabbit.state.Operation.SetPrimaryType;
-import org.apache.jackrabbit.state.Operation.SetValue;
-import org.apache.jackrabbit.state.Operation.Visitor;
import org.apache.jackrabbit.mk.api.MicroKernel;
import org.apache.jackrabbit.mk.api.MicroKernelException;
+import org.apache.jackrabbit.state.ChangeTree.Listener;
+import org.apache.jackrabbit.utils.Function1;
-import javax.jcr.PathNotFoundException;
+import javax.jcr.ItemNotFoundException;
import javax.jcr.RepositoryException;
-import javax.jcr.UnsupportedRepositoryOperationException;
public class TransientSpace {
- private final ChangeLog changeLog = new ChangeLog();
- private final MicroKernel microKernel;
- private final Path rootPath;
-
+ private final MicroKernel microkernel;
+ private final ChangeTree changeTree;
private String revision;
- private NodeDelta root;
- public TransientSpace(MicroKernel microKernel, String revision, Path rootPath) {
- this.microKernel = microKernel;
- this.rootPath = rootPath;
+ public TransientSpace(String workspace, final MicroKernel microkernel, final String revision) {
+ this.microkernel = microkernel;
this.revision = revision;
- root = new NodeDelta(rootPath, rootPath);
- }
-
- public void apply(Operation operation) throws RepositoryException {
- operation.accept(new Visitor() {
- @Override
- public void visit(Operation.AddNode addNode) throws RepositoryException {
- Path parentPath = addNode.getParent();
- String name = addNode.getName();
- NodeDelta parent = getOrCreateNodeDelta(parentPath);
- parent.addNode(name, new NodeDelta(parentPath.concat(name), null));
- }
-
- @Override
- public void visit(Operation.AddProperty addProperty) throws RepositoryException {
- NodeDelta parent = getOrCreateNodeDelta(addProperty.getParent());
- parent.addProperty(addProperty.getName(), addProperty.getValue());
- }
-
- @Override
- public void visit(Operation.SetValue setValue) throws RepositoryException {
- Path path = setValue.getPath();
- NodeDelta parent = getOrCreateNodeDelta(path.getParent());
- parent.setValue(path.getName(), setValue.getValue());
- }
-
- @Override
- public void visit(Operation.RemoveNode removeNode) throws RepositoryException {
- Path path = removeNode.getPath();
- NodeDelta parent = getOrCreateNodeDelta(path.getParent());
- parent.removeNode(path.getName());
- }
+ changeTree = new ChangeTree(Path.create(workspace), new Function1<String, Boolean>() {
@Override
- public void visit(RemoveProperty removeProperty) throws RepositoryException {
- Path path = removeProperty.getPath();
- NodeDelta parent = getOrCreateNodeDelta(path.getParent());
- parent.setValue(path.getName(), JsonAtom.NULL);
- }
-
- @Override
- public void visit(Operation.Reorder reorder) {
- // todo implement visit(Reorder)
- }
-
- @Override
- public void visit(Operation.SetMixin setMixin) throws RepositoryException {
- NodeDelta parent = getOrCreateNodeDelta(setMixin.getPath());
- parent.setValue("jcr:mixinTypes", setMixin.getMixins());
- }
-
- @Override
- public void visit(Operation.SetPrimaryType setPrimaryType) throws RepositoryException {
- NodeDelta parent = getOrCreateNodeDelta(setPrimaryType.getPath());
- parent.setValue("jcr:primaryType", setPrimaryType.getPrimaryType());
- }
-
- @Override
- public void visit(Operation.Move move) throws RepositoryException {
- Path source = move.getSource();
- Path destination = move.getDestination();
-
- NodeDelta sourceNode = getOrCreateNodeDelta(source);
- NodeDelta sourceParent = getOrCreateNodeDelta(source.getParent());
- sourceParent.removeNode(source.getName());
- sourceNode.setSessionPath(destination);
-
- NodeDelta destinationParent = getOrCreateNodeDelta(destination.getParent());
- destinationParent.addNode(destination.getName(), sourceNode);
- }
-
- private NodeDelta getOrCreateNodeDelta(Path path) throws PathNotFoundException {
- NodeDelta delta = root;
- for (String name : path.getNames()) {
- if (delta.hasChildNode(name)) {
- delta = delta.getChildNode(name);
- }
- else if (delta.hasAddedNode(name)) {
- delta = delta.getAddedNode(name);
- }
- else if (delta.hasRemovedNode(name)) {
- throw new PathNotFoundException(path.toString());
- }
- else {
- Path persistedPath = delta.getPersistentPath();
- if (persistedPath == null) {
- throw new PathNotFoundException(path.toString());
- }
-
- persistedPath = persistedPath.concat(name);
- if (!microKernel.nodeExists(persistedPath.getMkPath(), revision)) {
- throw new PathNotFoundException(path.toString());
- }
-
- Path sessionPath = delta.getSessionPath().concat(name);
- delta = delta.addChild(name, new NodeDelta(sessionPath, persistedPath));
- }
- }
- return delta;
+ public Boolean apply(String path) {
+ return microkernel.nodeExists(path, getRevision());
}
});
-
- changeLog.addOperation(operation);
}
- public NodeDelta getNodeDelta(final Path path) {
- if (!rootPath.getWorkspace().equals(path.getWorkspace())) {
- return new NodeDelta(path, path);
- }
-
- NodeDelta delta = root;
- for (String name : path.getNames()) {
- if (delta.hasRemovedNode(name)) {
- return null;
- }
- else if (delta.hasAddedNode(name)) {
- delta = delta.getAddedNode(name);
- }
- else if (delta.hasChildNode(name)) {
- delta = delta.getChildNode(name);
- }
- else {
- return new NodeDelta(path, path);
- }
- }
- return delta;
- }
-
- public ChangeLog getChangeLog() {
- return changeLog;
+ public ChangeTree.NodeDelta getNode(Path path) throws ItemNotFoundException {
+ return changeTree.getNode(path);
}
- public String refresh(boolean keepChanges) throws RepositoryException {
- NodeDelta oldRoot = root;
- String oldRevision = revision;
- try {
- root = new NodeDelta(rootPath, rootPath);
- revision = microKernel.getHeadRevision();
-
- if (keepChanges) {
- apply(changeLog);
- }
- else {
- changeLog.clear();
- }
-
- return revision;
- }
- catch (RepositoryException e) {
- root = oldRoot;
- revision = oldRevision;
- throw e;
- }
+ public boolean nodeExists(Path path) {
+ return changeTree.nodeExists(path);
}
public String save() throws RepositoryException {
try {
final StringBuilder jsop = new StringBuilder();
- changeLog.accept(new Visitor() {
+ changeTree.collectChanges(new Listener() {
@Override
- public void visit(AddNode addNode) {
- Path target = addNode.getParent().concat(addNode.getName());
+ public void addNode(Path path) {
jsop.append("+\"")
- .append(target.getMkPath())
- .append("\":")
- .append("{}")
- .append('\n');
- }
-
- @Override
- public void visit(AddProperty addProperty) {
- Path target = addProperty.getParent().concat(addProperty.getName());
- jsop.append("^\"")
- .append(target.getMkPath())
- .append("\":")
- .append(addProperty.getValue().toJson())
- .append('\n');
- }
-
- @Override
- public void visit(SetValue setValue) {
- jsop.append("^\"")
- .append(setValue.getPath().getMkPath())
- .append("\":")
- .append(setValue.getValue().toJson())
- .append('\n');
+ .append(path.getMkPath())
+ .append("\":{}");
}
@Override
- public void visit(RemoveNode removeNode) {
+ public void removeNode(Path path) {
jsop.append("-\"")
- .append(removeNode.getPath().getMkPath())
- .append("\"\n");
+ .append(path.getMkPath())
+ .append('"');
}
@Override
- public void visit(RemoveProperty removeProperty) {
- jsop.append("^\"")
- .append(removeProperty.getPath().getMkPath())
- .append("\":null\n");
- }
-
- @Override
- public void visit(Reorder reorder) throws UnsupportedRepositoryOperationException {
- throw new UnsupportedRepositoryOperationException("Reorder");
- }
-
- @Override
- public void visit(SetMixin setMixin) {
- Path target = setMixin.getPath().concat("jcr:mixinTypes");
- jsop.append("^\"")
- .append(target.getMkPath())
- .append("\":")
- .append(setMixin.getMixins().toJson())
- .append('\n');
+ public void moveNode(Path sourcePath, Path destinationPath) {
+ jsop.append(">\"")
+ .append(sourcePath.getMkPath())
+ .append("\":\"")
+ .append(destinationPath.getMkPath())
+ .append('"');
}
@Override
- public void visit(SetPrimaryType setPrimaryType) {
- Path target = setPrimaryType.getPath().concat("jcr:primaryType");
+ public void setProperty(Path path, JsonValue value) {
jsop.append("^\"")
- .append(target.getMkPath())
- .append("\":")
- .append(setPrimaryType.getPrimaryType().toJson())
- .append('\n');
- }
-
- @Override
- public void visit(Move move) {
- jsop.append(">\"")
- .append(move.getSource().getMkPath())
- .append("\":\"")
- .append(move.getDestination().getMkPath())
- .append("\"\n");
+ .append(path.getMkPath())
+ .append("\":").append(value == null ? "null" : value.toJson());
}
});
- revision = microKernel.commit("", jsop.toString(), revision, "");
- root = new NodeDelta(rootPath, rootPath);
- changeLog.clear();
+ revision = microkernel.commit("", jsop.toString(), revision, "");
+ changeTree.clear();
return revision;
}
catch (MicroKernelException e) {
@@ -300,45 +80,21 @@ public class TransientSpace {
}
}
- public boolean isDirty() {
- return !changeLog.isEmpty();
- }
-
- //------------------------------------------< convenience >---
-
- public void addNode(Path parent, String name) throws RepositoryException {
- apply(new Operation.AddNode(parent, name));
- }
-
- public void addProperty(Path parent, String name, JsonValue value) throws RepositoryException {
- apply(new Operation.AddProperty(parent, name, value));
- }
-
- public void setValue(Path path, JsonValue value) throws RepositoryException {
- apply(new Operation.SetValue(path, value));
- }
-
- public void removeNode(Path path) throws RepositoryException {
- apply(new Operation.RemoveNode(path));
- }
-
- public void removeProperty(Path path) throws RepositoryException {
- apply(new Operation.RemoveProperty(path));
- }
+ public String refresh(boolean keepChanges) {
+ if (!keepChanges) {
+ changeTree.clear();
+ }
- public void reorder() throws RepositoryException {
- apply(new Operation.Reorder());
+ return revision = microkernel.getHeadRevision();
}
- public void setMixin(Path path, JsonArray mixins) throws RepositoryException {
- apply(new Operation.SetMixin(path, mixins));
+ public boolean isDirty() {
+ return changeTree.hasChanges();
}
- public void setPrimaryType(Path path, JsonValue type) throws RepositoryException {
- apply(new Operation.SetPrimaryType(path, type));
- }
+ //------------------------------------------< private >---
- public void move(Path source, Path target) throws RepositoryException {
- apply(new Operation.Move(source, target));
+ private String getRevision() {
+ return revision;
}
}
Added: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/Function1.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/Function1.java?rev=1224964&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/Function1.java (added)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/utils/Function1.java Tue Dec 27 18:17:39 2011
@@ -0,0 +1,5 @@
+package org.apache.jackrabbit.utils;
+
+public interface Function1<S, T> {
+ T apply(S s);
+}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/RepositoryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/RepositoryTest.java?rev=1224964&r1=1224963&r2=1224964&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/RepositoryTest.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/test/java/org/apache/jackrabbit/RepositoryTest.java Tue Dec 27 18:17:39 2011
@@ -80,7 +80,7 @@ import static org.junit.Assert.assertTru
import static org.junit.Assert.fail;
public class RepositoryTest {
- private static final String URL = "fs:target/repository-test/repository;clean";
+ private static final String URL = "fs:target/repository-test/repository";
// private static final String URL = "mem:";
private static final String TEST_NODE = "test_node";
@@ -1131,7 +1131,7 @@ public class RepositoryTest {
session1.save();
try {
- session2.refresh(true);
+ session2.save();
fail();
}
catch (RepositoryException e) {