You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by md...@apache.org on 2012/07/25 15:07:41 UTC
svn commit: r1365564 [1/2] - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/core/
oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/
oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/
oak-jcr/src/test/java/or...
Author: mduerig
Date: Wed Jul 25 13:07:40 2012
New Revision: 1365564
URL: http://svn.apache.org/viewvc?rev=1365564&view=rev
Log:
OAK-156 Observation events need Session refresh
Added:
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionOperation.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ChangeProcessor.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/RepositoryTest.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java?rev=1365564&r1=1365563&r2=1365564&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java Wed Jul 25 13:07:40 2012
@@ -20,7 +20,7 @@ package org.apache.jackrabbit.oak.core;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
+
import javax.annotation.Nonnull;
import org.apache.jackrabbit.oak.api.ChangeExtractor;
@@ -84,12 +84,6 @@ public class RootImpl implements Root {
}
/**
- * Reference to a {@code NodeState} of the revision up to which
- * observation events are generated.
- */
- private final AtomicReference<NodeState> observationLimit;
-
- /**
* New instance bases on a given {@link NodeStore} and a workspace
* @param store node store
* @param workspaceName name of the workspace
@@ -98,7 +92,6 @@ public class RootImpl implements Root {
@SuppressWarnings("UnusedParameters")
public RootImpl(NodeStore store, String workspaceName) {
this.store = store;
- this.observationLimit = new AtomicReference<NodeState>(store.getRoot());
branch = store.branch();
rootTree = TreeImpl.createRoot(this);
}
@@ -149,10 +142,6 @@ public class RootImpl implements Root {
@Override
public void refresh() {
- // There is a small race here and we risk to get an "earlier" revision for the
- // observation limit than for the branch. This is not a problem though since
- // observation will catch up later on with the next call to ChangeExtractor.getChanges()
- observationLimit.set(store.getRoot());
branch = store.branch();
rootTree = TreeImpl.createRoot(this);
}
@@ -174,11 +163,11 @@ public class RootImpl implements Root {
@Nonnull
public ChangeExtractor getChangeExtractor() {
return new ChangeExtractor() {
- private NodeState baseLine = observationLimit.get();
+ private NodeState baseLine = store.getRoot();
@Override
public void getChanges(NodeStateDiff diff) {
- NodeState head = observationLimit.get();
+ NodeState head = store.getRoot();
head.compareAgainstBaseState(baseLine, diff);
baseLine = head;
}
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java?rev=1365564&r1=1365563&r2=1365564&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java Wed Jul 25 13:07:40 2012
@@ -54,9 +54,14 @@ abstract class ItemImpl<T extends ItemDe
@Override
@Nonnull
public String getName() throws RepositoryException {
- String oakName = dlg.getName();
- // special case name of root node
- return oakName.isEmpty() ? "" : toJcrPath(dlg.getName());
+ return sessionDelegate.perform(new SessionOperation<String>() {
+ @Override
+ public String perform() throws RepositoryException {
+ String oakName = dlg.getName();
+ // special case name of root node
+ return oakName.isEmpty() ? "" : toJcrPath(dlg.getName());
+ }
+ });
}
/**
@@ -65,7 +70,12 @@ abstract class ItemImpl<T extends ItemDe
@Override
@Nonnull
public String getPath() throws RepositoryException {
- return toJcrPath(dlg.getPath());
+ return sessionDelegate.perform(new SessionOperation<String>() {
+ @Override
+ public String perform() throws RepositoryException {
+ return toJcrPath(dlg.getPath());
+ }
+ });
}
@Override
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java?rev=1365564&r1=1365563&r2=1365564&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java Wed Jul 25 13:07:40 2012
@@ -110,11 +110,17 @@ public class NodeImpl extends ItemImpl<N
@Nonnull
public Node getParent() throws RepositoryException {
checkStatus();
- NodeDelegate parent = dlg.getParent();
- if (parent == null) {
- throw new ItemNotFoundException("Root has no parent");
- }
- return new NodeImpl(parent);
+
+ return sessionDelegate.perform(new SessionOperation<NodeImpl>() {
+ @Override
+ public NodeImpl perform() throws RepositoryException {
+ NodeDelegate parent = dlg.getParent();
+ if (parent == null) {
+ throw new ItemNotFoundException("Root has no parent");
+ }
+ return new NodeImpl(parent);
+ }
+ });
}
/**
@@ -123,8 +129,14 @@ public class NodeImpl extends ItemImpl<N
@Override
public boolean isNew() {
try {
- return !dlg.isStale() && dlg.getStatus() == Status.NEW;
- } catch (InvalidItemStateException e) {
+ return sessionDelegate.perform(new SessionOperation<Boolean>() {
+ @Override
+ public Boolean perform() throws InvalidItemStateException {
+ return !dlg.isStale() && dlg.getStatus() == Status.NEW;
+ }
+ });
+ }
+ catch (RepositoryException e) {
return false;
}
}
@@ -135,8 +147,14 @@ public class NodeImpl extends ItemImpl<N
@Override
public boolean isModified() {
try {
- return !dlg.isStale() && dlg.getStatus() == Status.MODIFIED;
- } catch (InvalidItemStateException e) {
+ return sessionDelegate.perform(new SessionOperation<Boolean>() {
+ @Override
+ public Boolean perform() throws InvalidItemStateException {
+ return !dlg.isStale() && dlg.getStatus() == Status.MODIFIED;
+ }
+ });
+ }
+ catch (RepositoryException e) {
return false;
}
}
@@ -147,11 +165,18 @@ public class NodeImpl extends ItemImpl<N
@Override
public void remove() throws RepositoryException {
checkStatus();
- if (dlg.isRoot()) {
- throw new RepositoryException("Cannot remove the root node");
- }
- dlg.remove();
+ sessionDelegate.perform(new SessionOperation<Void>() {
+ @Override
+ public Void perform() throws RepositoryException {
+ if (dlg.isRoot()) {
+ throw new RepositoryException("Cannot remove the root node");
+ }
+
+ dlg.remove();
+ return null;
+ }
+ });
}
/**
@@ -176,71 +201,81 @@ public class NodeImpl extends ItemImpl<N
@Override
@Nonnull
- public Node addNode(String relPath, String primaryNodeTypeName) throws RepositoryException {
+ public Node addNode(final String relPath, final String primaryNodeTypeName) throws RepositoryException {
checkStatus();
- String oakPath = sessionDelegate.getOakPathKeepIndexOrThrowNotFound(relPath);
- String oakName = PathUtils.getName(oakPath);
- String parentPath = sessionDelegate.getOakPathOrThrow(PathUtils.getParentPath(oakPath));
+ return sessionDelegate.perform(new SessionOperation<Node>() {
+ @Override
+ public Node perform() throws RepositoryException {
+ String oakPath = sessionDelegate.getOakPathKeepIndexOrThrowNotFound(relPath);
+ String oakName = PathUtils.getName(oakPath);
+ String parentPath = sessionDelegate.getOakPathOrThrow(PathUtils.getParentPath(oakPath));
+
+ // handle index
+ if (oakName.contains("[")) {
+ throw new RepositoryException("Cannot create a new node using a name including an index");
+ }
- // handle index
- if (oakName.contains("[")) {
- throw new RepositoryException("Cannot create a new node using a name including an index");
- }
+ NodeDelegate parent = dlg.getChild(parentPath);
+ if (parent == null) {
+ // is it a property?
+ String grandParentPath = PathUtils.getParentPath(parentPath);
+ NodeDelegate grandParent = dlg.getChild(grandParentPath);
+ if (grandParent != null) {
+ String propname = PathUtils.getName(parentPath);
+ if (grandParent.getProperty(propname) != null) {
+ throw new ConstraintViolationException("Can't add new node to property.");
+ }
+ }
- NodeDelegate parent = dlg.getChild(parentPath);
- if (parent == null) {
- // is it a property?
- String grandParentPath = PathUtils.getParentPath(parentPath);
- NodeDelegate grandParent = dlg.getChild(grandParentPath);
- if (grandParent != null) {
- String propname = PathUtils.getName(parentPath);
- if (grandParent.getProperty(propname) != null) {
- throw new ConstraintViolationException("Can't add new node to property.");
+ throw new PathNotFoundException(relPath);
}
- }
-
- throw new PathNotFoundException(relPath);
- }
- if (parent.getChild(oakName) != null) {
- throw new ItemExistsException(relPath);
- }
+ if (parent.getChild(oakName) != null) {
+ throw new ItemExistsException(relPath);
+ }
- if (primaryNodeTypeName == null) {
- // TODO retrieve matching nt from effective definition based on name-matching.
- primaryNodeTypeName = NodeType.NT_UNSTRUCTURED;
- }
+ // TODO retrieve matching nt from effective definition based on name-matching.
+ String ntName = primaryNodeTypeName == null ? NodeType.NT_UNSTRUCTURED : primaryNodeTypeName;
- // TODO: figure out the right place for this check
- NodeTypeManager ntm = sessionDelegate.getNodeTypeManager();
- NodeType nt = ntm.getNodeType(primaryNodeTypeName); // throws on not found
- if (nt.isAbstract() || nt.isMixin()) {
- throw new ConstraintViolationException();
- }
- // TODO: END
+ // TODO: figure out the right place for this check
+ NodeTypeManager ntm = sessionDelegate.getNodeTypeManager();
+ NodeType nt = ntm.getNodeType(ntName); // throws on not found
+ if (nt.isAbstract() || nt.isMixin()) {
+ throw new ConstraintViolationException();
+ }
+ // TODO: END
- NodeDelegate added = parent.addChild(oakName);
- if (added == null) {
- throw new ItemExistsException();
- }
+ NodeDelegate added = parent.addChild(oakName);
+ if (added == null) {
+ throw new ItemExistsException();
+ }
- Node childNode = new NodeImpl(added);
- childNode.setPrimaryType(primaryNodeTypeName);
- return childNode;
+ Node childNode = new NodeImpl(added);
+ childNode.setPrimaryType(ntName);
+ return childNode;
+ }
+ });
}
@Override
- public void orderBefore(String srcChildRelPath, String destChildRelPath) throws RepositoryException {
+ public void orderBefore(final String srcChildRelPath, final String destChildRelPath) throws RepositoryException {
checkStatus();
- String oakSrcChildRelPath =
- sessionDelegate.getOakPathOrThrowNotFound(srcChildRelPath);
- String oakDestChildRelPath = null;
- if (destChildRelPath != null) {
- oakDestChildRelPath =
- sessionDelegate.getOakPathOrThrowNotFound(destChildRelPath);
- }
- dlg.orderBefore(oakSrcChildRelPath, oakDestChildRelPath);
+
+ sessionDelegate.perform(new SessionOperation<Void>() {
+ @Override
+ public Void perform() throws RepositoryException {
+ String oakSrcChildRelPath =
+ sessionDelegate.getOakPathOrThrowNotFound(srcChildRelPath);
+ String oakDestChildRelPath = null;
+ if (destChildRelPath != null) {
+ oakDestChildRelPath =
+ sessionDelegate.getOakPathOrThrowNotFound(destChildRelPath);
+ }
+ dlg.orderBefore(oakSrcChildRelPath, oakDestChildRelPath);
+ return null;
+ }
+ });
}
/**
@@ -261,22 +296,27 @@ public class NodeImpl extends ItemImpl<N
*/
@Override
@CheckForNull
- public Property setProperty(String jcrName, Value value, int type)
+ public Property setProperty(final String jcrName, final Value value, final int type)
throws RepositoryException {
checkStatus();
- String oakName = sessionDelegate.getOakPathOrThrow(jcrName);
- if (value == null) {
- dlg.removeProperty(oakName);
- return null;
- } else {
- int targetType = getTargetType(value, type);
- Value targetValue =
- ValueHelper.convert(value, targetType, getValueFactory());
- CoreValue oakValue =
- ValueConverter.toCoreValue(targetValue, sessionDelegate);
- return new PropertyImpl(dlg.setProperty(oakName, oakValue));
- }
+ return sessionDelegate.perform(new SessionOperation<PropertyImpl>() {
+ @Override
+ public PropertyImpl perform() throws RepositoryException {
+ String oakName = sessionDelegate.getOakPathOrThrow(jcrName);
+ if (value == null) {
+ dlg.removeProperty(oakName);
+ return null;
+ } else {
+ int targetType = getTargetType(value, type);
+ Value targetValue =
+ ValueHelper.convert(value, targetType, getValueFactory());
+ CoreValue oakValue =
+ ValueConverter.toCoreValue(targetValue, sessionDelegate);
+ return new PropertyImpl(dlg.setProperty(oakName, oakValue));
+ }
+ }
+ });
}
/**
@@ -296,20 +336,25 @@ public class NodeImpl extends ItemImpl<N
@Override
@Nonnull
- public Property setProperty(String jcrName, Value[] values, int type) throws RepositoryException {
+ public Property setProperty(final String jcrName, final Value[] values, final int type) throws RepositoryException {
checkStatus();
- int targetType = getTargetType(values, type);
- Value[] targetValues = ValueHelper.convert(values, targetType, getValueFactory());
- if (targetValues == null) {
- Property p = getProperty(jcrName);
- p.remove();
- return p;
- } else {
- String oakName = sessionDelegate.getOakPathOrThrow(jcrName);
- List<CoreValue> oakValue = ValueConverter.toCoreValues(targetValues, sessionDelegate);
- return new PropertyImpl(dlg.setProperty(oakName, oakValue));
- }
+ return sessionDelegate.perform(new SessionOperation<Property>() {
+ @Override
+ public Property perform() throws RepositoryException {
+ int targetType = getTargetType(values, type);
+ Value[] targetValues = ValueHelper.convert(values, targetType, getValueFactory());
+ if (targetValues == null) {
+ Property p = getProperty(jcrName);
+ p.remove();
+ return p;
+ } else {
+ String oakName = sessionDelegate.getOakPathOrThrow(jcrName);
+ List<CoreValue> oakValue = ValueConverter.toCoreValues(targetValues, sessionDelegate);
+ return new PropertyImpl(dlg.setProperty(oakName, oakValue));
+ }
+ }
+ });
}
/**
@@ -436,17 +481,22 @@ public class NodeImpl extends ItemImpl<N
@Override
@Nonnull
- public Node getNode(String relPath) throws RepositoryException {
+ public Node getNode(final String relPath) throws RepositoryException {
checkStatus();
- String oakPath = sessionDelegate.getOakPathOrThrowNotFound(relPath);
+ return sessionDelegate.perform(new SessionOperation<NodeImpl>() {
+ @Override
+ public NodeImpl perform() throws RepositoryException {
+ String oakPath = sessionDelegate.getOakPathOrThrowNotFound(relPath);
- NodeDelegate nd = dlg.getChild(oakPath);
- if (nd == null) {
- throw new PathNotFoundException(relPath);
- } else {
- return new NodeImpl(nd);
- }
+ NodeDelegate nd = dlg.getChild(oakPath);
+ if (nd == null) {
+ throw new PathNotFoundException(relPath);
+ } else {
+ return new NodeImpl(nd);
+ }
+ }
+ });
}
@Override
@@ -454,9 +504,14 @@ public class NodeImpl extends ItemImpl<N
public NodeIterator getNodes() throws RepositoryException {
checkStatus();
- Iterator<NodeDelegate> children = dlg.getChildren();
- long size = dlg.getChildCount();
- return new NodeIteratorAdapter(nodeIterator(children), size);
+ return sessionDelegate.perform(new SessionOperation<NodeIterator>() {
+ @Override
+ public NodeIterator perform() throws RepositoryException {
+ Iterator<NodeDelegate> children = dlg.getChildren();
+ long size = dlg.getChildCount();
+ return new NodeIteratorAdapter(nodeIterator(children), size);
+ }
+ });
}
@Override
@@ -465,20 +520,24 @@ public class NodeImpl extends ItemImpl<N
throws RepositoryException {
checkStatus();
- Iterator<NodeDelegate> children = Iterators.filter(
- dlg.getChildren(),
- new Predicate<NodeDelegate>() {
- @Override
- public boolean apply(NodeDelegate state) {
- try {
- return ItemNameMatcher.matches(toJcrPath(state.getName()), namePattern);
- } catch (InvalidItemStateException e) {
- return false;
- }
- }
- });
+ return sessionDelegate.perform(new SessionOperation<NodeIterator>() {
+ @Override
+ public NodeIterator perform() throws RepositoryException {
+ Iterator<NodeDelegate> children = Iterators.filter(dlg.getChildren(),
+ new Predicate<NodeDelegate>() {
+ @Override
+ public boolean apply(NodeDelegate state) {
+ try {
+ return ItemNameMatcher.matches(toJcrPath(state.getName()), namePattern);
+ } catch (InvalidItemStateException e) {
+ return false;
+ }
+ }
+ });
- return new NodeIteratorAdapter(nodeIterator(children));
+ return new NodeIteratorAdapter(nodeIterator(children));
+ }
+ });
}
@Override
@@ -486,34 +545,43 @@ public class NodeImpl extends ItemImpl<N
public NodeIterator getNodes(final String[] nameGlobs) throws RepositoryException {
checkStatus();
- Iterator<NodeDelegate> children = Iterators.filter(
- dlg.getChildren(),
- new Predicate<NodeDelegate>() {
- @Override
- public boolean apply(NodeDelegate state) {
- try {
- return ItemNameMatcher.matches(toJcrPath(state.getName()), nameGlobs);
- } catch (InvalidItemStateException e) {
- return false;
- }
- }
- });
+ return sessionDelegate.perform(new SessionOperation<NodeIterator>() {
+ @Override
+ public NodeIterator perform() throws RepositoryException {
+ Iterator<NodeDelegate> children = Iterators.filter(dlg.getChildren(),
+ new Predicate<NodeDelegate>() {
+ @Override
+ public boolean apply(NodeDelegate state) {
+ try {
+ return ItemNameMatcher.matches(toJcrPath(state.getName()), nameGlobs);
+ } catch (InvalidItemStateException e) {
+ return false;
+ }
+ }
+ });
- return new NodeIteratorAdapter(nodeIterator(children));
+ return new NodeIteratorAdapter(nodeIterator(children));
+ }
+ });
}
@Override
@Nonnull
- public Property getProperty(String relPath) throws RepositoryException {
+ public Property getProperty(final String relPath) throws RepositoryException {
checkStatus();
- String oakPath = sessionDelegate.getOakPathOrThrowNotFound(relPath);
- PropertyDelegate pd = dlg.getProperty(oakPath);
- if (pd == null) {
- throw new PathNotFoundException(relPath + " not found on " + getPath());
- } else {
- return new PropertyImpl(pd);
- }
+ return sessionDelegate.perform(new SessionOperation<PropertyImpl>() {
+ @Override
+ public PropertyImpl perform() throws RepositoryException {
+ String oakPath = sessionDelegate.getOakPathOrThrowNotFound(relPath);
+ PropertyDelegate pd = dlg.getProperty(oakPath);
+ if (pd == null) {
+ throw new PathNotFoundException(relPath + " not found on " + getPath());
+ } else {
+ return new PropertyImpl(pd);
+ }
+ }
+ });
}
@Override
@@ -521,9 +589,14 @@ public class NodeImpl extends ItemImpl<N
public PropertyIterator getProperties() throws RepositoryException {
checkStatus();
- Iterator<PropertyDelegate> properties = dlg.getProperties();
- long size = dlg.getPropertyCount();
- return new PropertyIteratorAdapter(propertyIterator(properties), size);
+ return sessionDelegate.perform(new SessionOperation<PropertyIterator>() {
+ @Override
+ public PropertyIterator perform() throws RepositoryException {
+ Iterator<PropertyDelegate> properties = dlg.getProperties();
+ long size = dlg.getPropertyCount();
+ return new PropertyIteratorAdapter(propertyIterator(properties), size);
+ }
+ });
}
@Override
@@ -531,20 +604,24 @@ public class NodeImpl extends ItemImpl<N
public PropertyIterator getProperties(final String namePattern) throws RepositoryException {
checkStatus();
- Iterator<PropertyDelegate> properties = Iterators.filter(
- dlg.getProperties(),
- new Predicate<PropertyDelegate>() {
- @Override
- public boolean apply(PropertyDelegate entry) {
- try {
- return ItemNameMatcher.matches(toJcrPath(entry.getName()), namePattern);
- } catch (InvalidItemStateException e) {
- return false;
- }
- }
- });
+ return sessionDelegate.perform(new SessionOperation<PropertyIterator>() {
+ @Override
+ public PropertyIterator perform() throws RepositoryException {
+ Iterator<PropertyDelegate> properties = Iterators.filter(dlg.getProperties(),
+ new Predicate<PropertyDelegate>() {
+ @Override
+ public boolean apply(PropertyDelegate entry) {
+ try {
+ return ItemNameMatcher.matches(toJcrPath(entry.getName()), namePattern);
+ } catch (InvalidItemStateException e) {
+ return false;
+ }
+ }
+ });
- return new PropertyIteratorAdapter(propertyIterator(properties));
+ return new PropertyIteratorAdapter(propertyIterator(properties));
+ }
+ });
}
@Override
@@ -552,20 +629,24 @@ public class NodeImpl extends ItemImpl<N
public PropertyIterator getProperties(final String[] nameGlobs) throws RepositoryException {
checkStatus();
- Iterator<PropertyDelegate> propertyNames = Iterators.filter(
- dlg.getProperties(),
- new Predicate<PropertyDelegate>() {
- @Override
- public boolean apply(PropertyDelegate entry) {
- try {
- return ItemNameMatcher.matches(toJcrPath(entry.getName()), nameGlobs);
- } catch (InvalidItemStateException e) {
- return false;
- }
- }
- });
+ return sessionDelegate.perform(new SessionOperation<PropertyIterator>() {
+ @Override
+ public PropertyIterator perform() throws RepositoryException {
+ Iterator<PropertyDelegate> propertyNames = Iterators.filter(dlg.getProperties(),
+ new Predicate<PropertyDelegate>() {
+ @Override
+ public boolean apply(PropertyDelegate entry) {
+ try {
+ return ItemNameMatcher.matches(toJcrPath(entry.getName()), nameGlobs);
+ } catch (InvalidItemStateException e) {
+ return false;
+ }
+ }
+ });
- return new PropertyIteratorAdapter(propertyIterator(propertyNames));
+ return new PropertyIteratorAdapter(propertyIterator(propertyNames));
+ }
+ });
}
/**
@@ -575,17 +656,23 @@ public class NodeImpl extends ItemImpl<N
@Nonnull
public Item getPrimaryItem() throws RepositoryException {
checkStatus();
- String name = getPrimaryNodeType().getPrimaryItemName();
- if (name == null) {
- throw new ItemNotFoundException("No primary item present on node " + this);
- }
- if (hasProperty(name)) {
- return getProperty(name);
- } else if (hasNode(name)) {
- return getNode(name);
- } else {
- throw new ItemNotFoundException("Primary item " + name + " does not exist on node " + this);
- }
+
+ return sessionDelegate.perform(new SessionOperation<Item>() {
+ @Override
+ public Item perform() throws RepositoryException {
+ String name = getPrimaryNodeType().getPrimaryItemName();
+ if (name == null) {
+ throw new ItemNotFoundException("No primary item present on node " + this);
+ }
+ if (hasProperty(name)) {
+ return getProperty(name);
+ } else if (hasNode(name)) {
+ return getNode(name);
+ } else {
+ throw new ItemNotFoundException("Primary item " + name + " does not exist on node " + this);
+ }
+ }
+ });
}
/**
@@ -596,18 +683,29 @@ public class NodeImpl extends ItemImpl<N
public String getUUID() throws RepositoryException {
checkStatus();
- if (isNodeType(NodeType.MIX_REFERENCEABLE)) {
- return getIdentifier();
- }
+ return sessionDelegate.perform(new SessionOperation<String>() {
+ @Override
+ public String perform() throws RepositoryException {
+ if (isNodeType(NodeType.MIX_REFERENCEABLE)) {
+ return getIdentifier();
+ }
- throw new UnsupportedRepositoryOperationException("Node is not referenceable.");
+ throw new UnsupportedRepositoryOperationException("Node is not referenceable.");
+ }
+ });
}
@Override
@Nonnull
public String getIdentifier() throws RepositoryException {
checkStatus();
- return dlg.getIdentifier();
+
+ return sessionDelegate.perform(new SessionOperation<String>() {
+ @Override
+ public String perform() throws RepositoryException {
+ return dlg.getIdentifier();
+ }
+ });
}
@Override
@@ -630,11 +728,16 @@ public class NodeImpl extends ItemImpl<N
public PropertyIterator getReferences(String name) throws RepositoryException {
checkStatus();
- if (!isNodeType(JcrConstants.MIX_REFERENCEABLE)) {
- return PropertyIteratorAdapter.EMPTY;
- } else {
- throw new UnsupportedRepositoryOperationException("TODO: Node.getReferences");
- }
+ return sessionDelegate.perform(new SessionOperation<PropertyIterator>() {
+ @Override
+ public PropertyIterator perform() throws RepositoryException {
+ if (!isNodeType(JcrConstants.MIX_REFERENCEABLE)) {
+ return PropertyIteratorAdapter.EMPTY;
+ } else {
+ throw new UnsupportedRepositoryOperationException("TODO: Node.getReferences");
+ }
+ }
+ });
}
/**
@@ -651,41 +754,66 @@ public class NodeImpl extends ItemImpl<N
public PropertyIterator getWeakReferences(String name) throws RepositoryException {
checkStatus();
- if (!isNodeType(JcrConstants.MIX_REFERENCEABLE)) {
- return PropertyIteratorAdapter.EMPTY;
- } else {
- throw new UnsupportedRepositoryOperationException("TODO: Node.getWeakReferences");
- }
+ return sessionDelegate.perform(new SessionOperation<PropertyIterator>() {
+ @Override
+ public PropertyIterator perform() throws RepositoryException {
+ if (!isNodeType(JcrConstants.MIX_REFERENCEABLE)) {
+ return PropertyIteratorAdapter.EMPTY;
+ } else {
+ throw new UnsupportedRepositoryOperationException("TODO: Node.getWeakReferences");
+ }
+ }
+ });
}
@Override
- public boolean hasNode(String relPath) throws RepositoryException {
+ public boolean hasNode(final String relPath) throws RepositoryException {
checkStatus();
- String oakPath = sessionDelegate.getOakPathOrThrow(relPath);
- return dlg.getChild(oakPath) != null;
+ return sessionDelegate.perform(new SessionOperation<Boolean>() {
+ @Override
+ public Boolean perform() throws RepositoryException {
+ String oakPath = sessionDelegate.getOakPathOrThrow(relPath);
+ return dlg.getChild(oakPath) != null;
+ }
+ });
}
@Override
- public boolean hasProperty(String relPath) throws RepositoryException {
+ public boolean hasProperty(final String relPath) throws RepositoryException {
checkStatus();
- String oakPath = sessionDelegate.getOakPathOrThrow(relPath);
- return dlg.getProperty(oakPath) != null;
+ return sessionDelegate.perform(new SessionOperation<Boolean>() {
+ @Override
+ public Boolean perform() throws RepositoryException {
+ String oakPath = sessionDelegate.getOakPathOrThrow(relPath);
+ return dlg.getProperty(oakPath) != null;
+ }
+ });
}
@Override
public boolean hasNodes() throws RepositoryException {
checkStatus();
- return dlg.getChildCount() != 0;
+ return sessionDelegate.perform(new SessionOperation<Boolean>() {
+ @Override
+ public Boolean perform() throws RepositoryException {
+ return dlg.getChildCount() != 0;
+ }
+ });
}
@Override
public boolean hasProperties() throws RepositoryException {
checkStatus();
- return dlg.getPropertyCount() != 0;
+ return sessionDelegate.perform(new SessionOperation<Boolean>() {
+ @Override
+ public Boolean perform() throws RepositoryException {
+ return dlg.getPropertyCount() != 0;
+ }
+ });
}
/**
@@ -696,14 +824,19 @@ public class NodeImpl extends ItemImpl<N
public NodeType getPrimaryNodeType() throws RepositoryException {
checkStatus();
- // TODO: check if transient changes to mixin-types are reflected here
- NodeTypeManager ntMgr = sessionDelegate.getNodeTypeManager();
- String primaryNtName;
- primaryNtName = hasProperty(Property.JCR_PRIMARY_TYPE)
- ? getProperty(Property.JCR_PRIMARY_TYPE).getString()
- : NodeType.NT_UNSTRUCTURED;
+ return sessionDelegate.perform(new SessionOperation<NodeType>() {
+ @Override
+ public NodeType perform() throws RepositoryException {
+ // TODO: check if transient changes to mixin-types are reflected here
+ NodeTypeManager ntMgr = sessionDelegate.getNodeTypeManager();
+ String primaryNtName;
+ primaryNtName = hasProperty(Property.JCR_PRIMARY_TYPE)
+ ? getProperty(Property.JCR_PRIMARY_TYPE).getString()
+ : NodeType.NT_UNSTRUCTURED;
- return ntMgr.getNodeType(primaryNtName);
+ return ntMgr.getNodeType(primaryNtName);
+ }
+ });
}
/**
@@ -714,129 +847,162 @@ public class NodeImpl extends ItemImpl<N
public NodeType[] getMixinNodeTypes() throws RepositoryException {
checkStatus();
- // TODO: check if transient changes to mixin-types are reflected here
- if (hasProperty(Property.JCR_MIXIN_TYPES)) {
- NodeTypeManager ntMgr = sessionDelegate.getNodeTypeManager();
- Value[] mixinNames = getProperty(Property.JCR_MIXIN_TYPES).getValues();
- NodeType[] mixinTypes = new NodeType[mixinNames.length];
- for (int i = 0; i < mixinNames.length; i++) {
- mixinTypes[i] = ntMgr.getNodeType(mixinNames[i].getString());
+ return sessionDelegate.perform(new SessionOperation<NodeType[]>() {
+ @Override
+ public NodeType[] perform() throws RepositoryException {
+ // TODO: check if transient changes to mixin-types are reflected here
+ if (hasProperty(Property.JCR_MIXIN_TYPES)) {
+ NodeTypeManager ntMgr = sessionDelegate.getNodeTypeManager();
+ Value[] mixinNames = getProperty(Property.JCR_MIXIN_TYPES).getValues();
+ NodeType[] mixinTypes = new NodeType[mixinNames.length];
+ for (int i = 0; i < mixinNames.length; i++) {
+ mixinTypes[i] = ntMgr.getNodeType(mixinNames[i].getString());
+ }
+ return mixinTypes;
+ } else {
+ return new NodeType[0];
+ }
}
- return mixinTypes;
- } else {
- return new NodeType[0];
- }
+ });
}
@Override
- public boolean isNodeType(String nodeTypeName) throws RepositoryException {
+ public boolean isNodeType(final String nodeTypeName) throws RepositoryException {
checkStatus();
- // TODO: might be expanded, need a better way for this
- NameMapper mapper = sessionDelegate.getNamePathMapper();
- String oakName = mapper.getOakName(nodeTypeName);
- if (oakName == null) {
- return false; // An unknown name can't belong to a valid type
- }
- String jcrName = mapper.getJcrName(oakName);
+ return sessionDelegate.perform(new SessionOperation<Boolean>() {
+ @Override
+ public Boolean perform() throws RepositoryException {
+ // TODO: might be expanded, need a better way for this
+ NameMapper mapper = sessionDelegate.getNamePathMapper();
+ String oakName = mapper.getOakName(nodeTypeName);
+ if (oakName == null) {
+ return false; // An unknown name can't belong to a valid type
+ }
+ String jcrName = mapper.getJcrName(oakName);
- // TODO: figure out the right place for this check
- NodeTypeManager ntm = sessionDelegate.getNodeTypeManager();
- NodeType ntToCheck = ntm.getNodeType(jcrName); // throws on not found
- String nameToCheck = ntToCheck.getName();
+ // TODO: figure out the right place for this check
+ NodeTypeManager ntm = sessionDelegate.getNodeTypeManager();
+ NodeType ntToCheck = ntm.getNodeType(jcrName); // throws on not found
+ String nameToCheck = ntToCheck.getName();
- NodeType currentPrimaryType = getPrimaryNodeType();
- if (currentPrimaryType.isNodeType(nameToCheck)) {
- return true;
- }
+ NodeType currentPrimaryType = getPrimaryNodeType();
+ if (currentPrimaryType.isNodeType(nameToCheck)) {
+ return true;
+ }
- for (NodeType mixin : getMixinNodeTypes()) {
- if (mixin.isNodeType(nameToCheck)) {
- return true;
- }
- }
- // TODO: END
+ for (NodeType mixin : getMixinNodeTypes()) {
+ if (mixin.isNodeType(nameToCheck)) {
+ return true;
+ }
+ }
+ // TODO: END
- return false;
+ return false;
+ }
+ });
}
@Override
- public void setPrimaryType(String nodeTypeName) throws RepositoryException {
+ public void setPrimaryType(final String nodeTypeName) throws RepositoryException {
checkStatus();
- // TODO: figure out the right place for this check
- NodeTypeManager ntm = sessionDelegate.getNodeTypeManager();
- NodeType nt = ntm.getNodeType(nodeTypeName); // throws on not found
- if (nt.isAbstract() || nt.isMixin()) {
- throw new ConstraintViolationException();
- }
- // TODO: END
+ sessionDelegate.perform(new SessionOperation<Void>() {
+ @Override
+ public Void perform() throws RepositoryException {
+ // TODO: figure out the right place for this check
+ NodeTypeManager ntm = sessionDelegate.getNodeTypeManager();
+ NodeType nt = ntm.getNodeType(nodeTypeName); // throws on not found
+ if (nt.isAbstract() || nt.isMixin()) {
+ throw new ConstraintViolationException();
+ }
+ // TODO: END
- String jcrPrimaryType = sessionDelegate.getOakPathOrThrow(Property.JCR_PRIMARY_TYPE);
- CoreValue cv = ValueConverter.toCoreValue(nodeTypeName, PropertyType.NAME, sessionDelegate);
- dlg.setProperty(jcrPrimaryType, cv);
+ String jcrPrimaryType = sessionDelegate.getOakPathOrThrow(Property.JCR_PRIMARY_TYPE);
+ CoreValue cv = ValueConverter.toCoreValue(nodeTypeName, PropertyType.NAME, sessionDelegate);
+ dlg.setProperty(jcrPrimaryType, cv);
+ return null;
+ }
+ });
}
@Override
- public void addMixin(String mixinName) throws RepositoryException {
+ public void addMixin(final String mixinName) throws RepositoryException {
checkStatus();
- // TODO: figure out the right place for this check
- NodeTypeManager ntm = sessionDelegate.getNodeTypeManager();
- NodeType nt = ntm.getNodeType(mixinName); // throws on not found
- // TODO: END
-
- String jcrMixinTypes = sessionDelegate.getOakPathOrThrow(Property.JCR_MIXIN_TYPES);
- PropertyDelegate mixins = dlg.getProperty(jcrMixinTypes);
-
- CoreValue cv = ValueConverter.toCoreValue(mixinName, PropertyType.NAME, sessionDelegate);
- boolean nodeModified = false;
+ sessionDelegate.perform(new SessionOperation<Void>() {
+ @Override
+ public Void perform() throws RepositoryException {
+ // TODO: figure out the right place for this check
+ NodeTypeManager ntm = sessionDelegate.getNodeTypeManager();
+ NodeType nt = ntm.getNodeType(mixinName); // throws on not found
+ // TODO: END
+
+ String jcrMixinTypes = sessionDelegate.getOakPathOrThrow(Property.JCR_MIXIN_TYPES);
+ PropertyDelegate mixins = dlg.getProperty(jcrMixinTypes);
+
+ CoreValue cv = ValueConverter.toCoreValue(mixinName, PropertyType.NAME, sessionDelegate);
+
+ boolean nodeModified = false;
+
+ if (mixins == null) {
+ nodeModified = true;
+ dlg.setProperty(jcrMixinTypes, Collections.singletonList(cv));
+ } else {
+ List<CoreValue> values = new ArrayList<CoreValue>();
+ for (CoreValue existingValue : mixins.getValues()) {
+ if (!values.contains(existingValue)) {
+ values.add(existingValue);
+ }
+ }
+ if (!values.contains(cv)) {
+ values.add(cv);
+ nodeModified = true;
+ dlg.setProperty(jcrMixinTypes, values);
+ }
+ }
- if (mixins == null) {
- nodeModified = true;
- dlg.setProperty(jcrMixinTypes, Collections.singletonList(cv));
- } else {
- List<CoreValue> values = new ArrayList<CoreValue>();
- for (CoreValue existingValue : mixins.getValues()) {
- if (!values.contains(existingValue)) {
- values.add(existingValue);
+ // TODO: hack -- make sure we assign a UUID
+ if (nodeModified && nt.isNodeType(NodeType.MIX_REFERENCEABLE)) {
+ String jcrUuid = sessionDelegate.getOakPathOrThrow(Property.JCR_UUID);
+ dlg.setProperty(jcrUuid, ValueConverter.toCoreValue(UUID.randomUUID().toString(), PropertyType.STRING, sessionDelegate));
}
+ return null;
}
- if (!values.contains(cv)) {
- values.add(cv);
- nodeModified = true;
- dlg.setProperty(jcrMixinTypes, values);
- }
- }
-
- // TODO: hack -- make sure we assign a UUID
- if (nodeModified && nt.isNodeType(NodeType.MIX_REFERENCEABLE)) {
- String jcrUuid = sessionDelegate.getOakPathOrThrow(Property.JCR_UUID);
- dlg.setProperty(jcrUuid, ValueConverter.toCoreValue(UUID.randomUUID().toString(), PropertyType.STRING, sessionDelegate));
- }
+ });
}
@Override
- public void removeMixin(String mixinName) throws RepositoryException {
+ public void removeMixin(final String mixinName) throws RepositoryException {
checkStatus();
- if (!isNodeType(mixinName)) {
- throw new NoSuchNodeTypeException();
- }
+ sessionDelegate.perform(new SessionOperation<Void>() {
+ @Override
+ public Void perform() throws RepositoryException {
+ if (!isNodeType(mixinName)) {
+ throw new NoSuchNodeTypeException();
+ }
- throw new ConstraintViolationException();
+ throw new ConstraintViolationException();
+ }
+ });
}
@Override
- public boolean canAddMixin(String mixinName) throws RepositoryException {
+ public boolean canAddMixin(final String mixinName) throws RepositoryException {
checkStatus();
- // TODO: figure out the right place for this check
- NodeTypeManager ntm = sessionDelegate.getNodeTypeManager();
- ntm.getNodeType(mixinName); // throws on not found
- // TODO: END
+ return sessionDelegate.perform(new SessionOperation<Boolean>() {
+ @Override
+ public Boolean perform() throws RepositoryException {
+ // TODO: figure out the right place for this check
+ NodeTypeManager ntm = sessionDelegate.getNodeTypeManager();
+ ntm.getNodeType(mixinName); // throws on not found
+ // TODO: END
- return isSupportedMixinName(mixinName);
+ return isSupportedMixinName(mixinName);
+ }
+ });
}
@Override
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java?rev=1365564&r1=1365563&r2=1365564&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java Wed Jul 25 13:07:40 2012
@@ -24,7 +24,6 @@ import java.util.List;
import javax.annotation.Nonnull;
import javax.jcr.Binary;
-import javax.jcr.InvalidItemStateException;
import javax.jcr.ItemNotFoundException;
import javax.jcr.ItemVisitor;
import javax.jcr.Node;
@@ -71,7 +70,12 @@ public class PropertyImpl extends ItemIm
@Override
@Nonnull
public Node getParent() throws RepositoryException {
- return new NodeImpl(dlg.getParent());
+ return sessionDelegate.perform(new SessionOperation<NodeImpl>() {
+ @Override
+ public NodeImpl perform() throws RepositoryException {
+ return new NodeImpl(dlg.getParent());
+ }
+ });
}
/**
@@ -80,9 +84,14 @@ public class PropertyImpl extends ItemIm
@Override
public boolean isNew() {
try {
- return dlg.getStatus() == Status.NEW;
+ return sessionDelegate.perform(new SessionOperation<Boolean>() {
+ @Override
+ public Boolean perform() throws RepositoryException {
+ return dlg.getStatus() == Status.NEW;
+ }
+ });
}
- catch (InvalidItemStateException e) {
+ catch (RepositoryException e) {
return false;
}
}
@@ -93,9 +102,14 @@ public class PropertyImpl extends ItemIm
@Override
public boolean isModified() {
try {
- return dlg.getStatus() == Status.MODIFIED;
+ return sessionDelegate.perform(new SessionOperation<Boolean>() {
+ @Override
+ public Boolean perform() throws RepositoryException {
+ return dlg.getStatus() == Status.MODIFIED;
+ }
+ });
}
- catch (InvalidItemStateException e) {
+ catch (RepositoryException e) {
return false;
}
}
@@ -106,7 +120,14 @@ public class PropertyImpl extends ItemIm
@Override
public void remove() throws RepositoryException {
checkStatus();
- dlg.remove();
+
+ sessionDelegate.perform(new SessionOperation<Void>() {
+ @Override
+ public Void perform() throws RepositoryException {
+ dlg.remove();
+ return null;
+ }
+ });
}
/**
@@ -135,30 +156,36 @@ public class PropertyImpl extends ItemIm
* @see Property#setValue(Value[])
*/
@Override
- public void setValue(Value[] values) throws RepositoryException {
+ public void setValue(final Value[] values) throws RepositoryException {
checkStatus();
- // assert equal types for all values entries
- int valueType = PropertyType.UNDEFINED;
- if (values != null) {
- for (Value value : values) {
- if (value == null) {
- // skip null values as those will be purged later
- continue;
- }
- if (valueType == PropertyType.UNDEFINED) {
- valueType = value.getType();
- }
- else if (valueType != value.getType()) {
- String msg = "Inhomogeneous type of values (" + this + ')';
- log.debug(msg);
- throw new ValueFormatException(msg);
+ sessionDelegate.perform(new SessionOperation<Void>() {
+ @Override
+ public Void perform() throws RepositoryException {
+ // assert equal types for all values entries
+ int valueType = PropertyType.UNDEFINED;
+ if (values != null) {
+ for (Value value : values) {
+ if (value == null) {
+ // skip null values as those will be purged later
+ continue;
+ }
+ if (valueType == PropertyType.UNDEFINED) {
+ valueType = value.getType();
+ }
+ else if (valueType != value.getType()) {
+ String msg = "Inhomogeneous type of values (" + this + ')';
+ log.debug(msg);
+ throw new ValueFormatException(msg);
+ }
+ }
}
- }
- }
- int reqType = getRequiredType(valueType);
- setValues(values, reqType);
+ int reqType = getRequiredType(valueType);
+ setValues(values, reqType);
+ return null;
+ }
+ });
}
/**
@@ -310,22 +337,34 @@ public class PropertyImpl extends ItemIm
@Nonnull
public Value getValue() throws RepositoryException {
checkStatus();
- if (isMultiple()) {
- throw new ValueFormatException(this + " is multi-valued.");
- }
- return ValueConverter.toValue(dlg.getValue(), sessionDelegate);
+ return sessionDelegate.perform(new SessionOperation<Value>() {
+ @Override
+ public Value perform() throws RepositoryException {
+ if (isMultiple()) {
+ throw new ValueFormatException(this + " is multi-valued.");
+ }
+
+ return ValueConverter.toValue(dlg.getValue(), sessionDelegate);
+ }
+ });
}
@Override
@Nonnull
public Value[] getValues() throws RepositoryException {
checkStatus();
- if (!isMultiple()) {
- throw new ValueFormatException(this + " is not multi-valued.");
- }
- return ValueConverter.toValues(dlg.getValues(), sessionDelegate);
+ return sessionDelegate.perform(new SessionOperation<Value[]>() {
+ @Override
+ public Value[] perform() throws RepositoryException {
+ if (!isMultiple()) {
+ throw new ValueFormatException(this + " is not multi-valued.");
+ }
+
+ return ValueConverter.toValues(dlg.getValues(), sessionDelegate);
+ }
+ });
}
/**
@@ -404,48 +443,53 @@ public class PropertyImpl extends ItemIm
@Override
@Nonnull
public Node getNode() throws RepositoryException {
- Value value = getValue();
- switch (value.getType()) {
- case PropertyType.REFERENCE:
- case PropertyType.WEAKREFERENCE:
- return getSession().getNodeByIdentifier(value.getString());
-
- case PropertyType.PATH:
- case PropertyType.NAME:
- String path = value.getString();
- if (path.startsWith("[") && path.endsWith("]")) {
- // TODO OAK-23
- // TODO correct for NAME?
- return getSession().getNodeByIdentifier(path.substring(1, path.length() - 1));
- }
- else {
- try {
- return (path.charAt(0) == '/') ? getSession().getNode(path) : getParent().getNode(path);
- } catch (PathNotFoundException e) {
- throw new ItemNotFoundException(path);
- }
- }
+ return sessionDelegate.perform(new SessionOperation<Node>() {
+ @Override
+ public Node perform() throws RepositoryException {
+ Value value = getValue();
+ switch (value.getType()) {
+ case PropertyType.REFERENCE:
+ case PropertyType.WEAKREFERENCE:
+ return getSession().getNodeByIdentifier(value.getString());
+
+ case PropertyType.PATH:
+ case PropertyType.NAME:
+ String path = value.getString();
+ if (path.startsWith("[") && path.endsWith("]")) {
+ // TODO OAK-23
+ // TODO correct for NAME?
+ return getSession().getNodeByIdentifier(path.substring(1, path.length() - 1));
+ }
+ else {
+ try {
+ return (path.charAt(0) == '/') ? getSession().getNode(path) : getParent().getNode(path);
+ } catch (PathNotFoundException e) {
+ throw new ItemNotFoundException(path);
+ }
+ }
+
+ case PropertyType.STRING:
+ try {
+ Value refValue = ValueHelper.convert(value, PropertyType.REFERENCE, getValueFactory());
+ return getSession().getNodeByIdentifier(refValue.getString());
+ } catch (ItemNotFoundException e) {
+ throw e;
+ } catch (RepositoryException e) {
+ // try if STRING value can be interpreted as PATH value
+ Value pathValue = ValueHelper.convert(value, PropertyType.PATH, getValueFactory());
+ path = pathValue.getString();
+ try {
+ return (path.charAt(0) == '/') ? getSession().getNode(path) : getParent().getNode(path);
+ } catch (PathNotFoundException e1) {
+ throw new ItemNotFoundException(pathValue.getString());
+ }
+ }
- case PropertyType.STRING:
- try {
- Value refValue = ValueHelper.convert(value, PropertyType.REFERENCE, getValueFactory());
- return getSession().getNodeByIdentifier(refValue.getString());
- } catch (ItemNotFoundException e) {
- throw e;
- } catch (RepositoryException e) {
- // try if STRING value can be interpreted as PATH value
- Value pathValue = ValueHelper.convert(value, PropertyType.PATH, getValueFactory());
- path = pathValue.getString();
- try {
- return (path.charAt(0) == '/') ? getSession().getNode(path) : getParent().getNode(path);
- } catch (PathNotFoundException e1) {
- throw new ItemNotFoundException(pathValue.getString());
- }
+ default:
+ throw new ValueFormatException("Property value cannot be converted to a PATH, REFERENCE or WEAKREFERENCE");
}
-
- default:
- throw new ValueFormatException("Property value cannot be converted to a PATH, REFERENCE or WEAKREFERENCE");
- }
+ }
+ });
}
/**
@@ -454,14 +498,19 @@ public class PropertyImpl extends ItemIm
@Override
@Nonnull
public Property getProperty() throws RepositoryException {
- Value value = getValue();
- Value pathValue = ValueHelper.convert(value, PropertyType.PATH, getValueFactory());
- String path = pathValue.getString();
- try {
- return (path.charAt(0) == '/') ? getSession().getProperty(path) : getParent().getProperty(path);
- } catch (PathNotFoundException e) {
- throw new ItemNotFoundException(path);
- }
+ return sessionDelegate.perform(new SessionOperation<Property>() {
+ @Override
+ public Property perform() throws RepositoryException {
+ Value value = getValue();
+ Value pathValue = ValueHelper.convert(value, PropertyType.PATH, getValueFactory());
+ String path = pathValue.getString();
+ try {
+ return (path.charAt(0) == '/') ? getSession().getProperty(path) : getParent().getProperty(path);
+ } catch (PathNotFoundException e) {
+ throw new ItemNotFoundException(path);
+ }
+ }
+ });
}
/**
@@ -490,7 +539,12 @@ public class PropertyImpl extends ItemIm
@Override
@Nonnull
public PropertyDefinition getDefinition() throws RepositoryException {
- return dlg.getDefinition();
+ return sessionDelegate.perform(new SessionOperation<PropertyDefinition>() {
+ @Override
+ public PropertyDefinition perform() {
+ return dlg.getDefinition();
+ }
+ });
}
/**
@@ -498,23 +552,34 @@ public class PropertyImpl extends ItemIm
*/
@Override
public int getType() throws RepositoryException {
- if (isMultiple()) {
- Value[] values = getValues();
- if (values.length == 0) {
- // retrieve the type from the property definition
- return getRequiredType(PropertyType.UNDEFINED);
- } else {
- return values[0].getType();
+ return sessionDelegate.perform(new SessionOperation<Integer>() {
+ @Override
+ public Integer perform() throws RepositoryException {
+ if (isMultiple()) {
+ Value[] values = getValues();
+ if (values.length == 0) {
+ // retrieve the type from the property definition
+ return getRequiredType(PropertyType.UNDEFINED);
+ } else {
+ return values[0].getType();
+ }
+ } else {
+ return getValue().getType();
+ }
}
- } else {
- return getValue().getType();
- }
+ });
}
@Override
public boolean isMultiple() throws RepositoryException {
checkStatus();
- return dlg.isMultivalue();
+
+ return sessionDelegate.perform(new SessionOperation<Boolean>() {
+ @Override
+ public Boolean perform() throws RepositoryException {
+ return dlg.isMultivalue();
+ }
+ });
}
//------------------------------------------------------------< private >---
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java?rev=1365564&r1=1365563&r2=1365564&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java Wed Jul 25 13:07:40 2012
@@ -76,6 +76,7 @@ public class SessionDelegate {
private ObservationManagerImpl observationManager;
private boolean isAlive = true;
+ private int sessionOpCount;
SessionDelegate(Repository repository, LazyValue<Timer> observationTimer, ContentSession contentSession)
throws RepositoryException {
@@ -92,6 +93,36 @@ public class SessionDelegate {
this.conflictHandler = new AnnotatingConflictHandler(contentSession.getCoreValueFactory());
}
+ /**
+ * Performs the passed {@code SessionOperation} in a safe execution context. This
+ * context ensures that the session is refreshed if necessary and that refreshing
+ * occurs before the session operation is performed and the refreshing is done only
+ * once.
+ *
+ * @param sessionOperation the {@code SessionOperation} to perform
+ * @param <T> return type of {@code sessionOperation}
+ * @return the result of {@code sessionOperation.perform()}
+ * @throws RepositoryException
+ */
+ public <T> T perform(SessionOperation<T> sessionOperation) throws RepositoryException {
+ try {
+ sessionOpCount++;
+ if (refreshNeeded()) {
+ refresh(true);
+ }
+ return sessionOperation.perform();
+ }
+ finally {
+ sessionOpCount--;
+ }
+ }
+
+ private boolean refreshNeeded() {
+ // Refresh is needed only for non re-entrant session operations and only if
+ // observation events have actually been delivered
+ return sessionOpCount <= 1 && observationManager != null && observationManager.hasEvents();
+ }
+
public boolean isAlive() {
return isAlive;
}
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java?rev=1365564&r1=1365563&r2=1365564&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java Wed Jul 25 13:07:40 2012
@@ -113,7 +113,13 @@ public class SessionImpl extends Abstrac
@Nonnull
public Node getRootNode() throws RepositoryException {
ensureIsAlive();
- return new NodeImpl(dlg.getRoot());
+
+ return dlg.perform(new SessionOperation<NodeImpl>() {
+ @Override
+ public NodeImpl perform() {
+ return new NodeImpl(dlg.getRoot());
+ }
+ });
}
@Override
@@ -124,30 +130,43 @@ public class SessionImpl extends Abstrac
@Override
@Nonnull
- public Node getNodeByIdentifier(String id) throws RepositoryException {
+ public Node getNodeByIdentifier(final String id) throws RepositoryException {
ensureIsAlive();
- NodeDelegate d = dlg.getNodeByIdentifier(id);
- if (d == null) {
- throw new ItemNotFoundException("Node with id " + id + " does not exist.");
- }
- return new NodeImpl(d);
+
+ return dlg.perform(new SessionOperation<NodeImpl>() {
+ @Override
+ public NodeImpl perform() throws RepositoryException {
+ NodeDelegate d = dlg.getNodeByIdentifier(id);
+ if (d == null) {
+ throw new ItemNotFoundException("Node with id " + id + " does not exist.");
+ }
+ return new NodeImpl(d);
+ }
+ });
}
@Override
- public void move(String srcAbsPath, String destAbsPath) throws RepositoryException {
+ public void move(final String srcAbsPath, final String destAbsPath) throws RepositoryException {
ensureIsAlive();
- String oakPath = dlg.getOakPathKeepIndexOrThrowNotFound(destAbsPath);
- String oakName = PathUtils.getName(oakPath);
- // handle index
- if (oakName.contains("[")) {
- throw new RepositoryException("Cannot create a new node using a name including an index");
- }
+ dlg.perform(new SessionOperation<Void>() {
+ @Override
+ public Void perform() throws RepositoryException {
+ String oakPath = dlg.getOakPathKeepIndexOrThrowNotFound(destAbsPath);
+ String oakName = PathUtils.getName(oakPath);
+ // handle index
+ if (oakName.contains("[")) {
+ throw new RepositoryException("Cannot create a new node using a name including an index");
+ }
- dlg.move(
- dlg.getOakPathOrThrowNotFound(srcAbsPath),
- dlg.getOakPathOrThrowNotFound(oakPath),
- true);
+ dlg.move(
+ dlg.getOakPathOrThrowNotFound(srcAbsPath),
+ dlg.getOakPathOrThrowNotFound(oakPath),
+ true);
+
+ return null;
+ }
+ });
}
@Override
Added: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionOperation.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionOperation.java?rev=1365564&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionOperation.java (added)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionOperation.java Wed Jul 25 13:07:40 2012
@@ -0,0 +1,28 @@
+/*
+ * 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.oak.jcr;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * A {@code SessionOperation} provides an execution context for executing session scoped operations.
+ */
+public interface SessionOperation<T> {
+ T perform() throws RepositoryException;
+}
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ChangeProcessor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ChangeProcessor.java?rev=1365564&r1=1365563&r2=1365564&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ChangeProcessor.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ChangeProcessor.java Wed Jul 25 13:07:40 2012
@@ -25,6 +25,8 @@ import java.util.concurrent.atomic.Atomi
import javax.jcr.observation.Event;
import javax.jcr.observation.EventListener;
+import com.google.common.base.Function;
+import com.google.common.collect.Iterators;
import org.apache.jackrabbit.commons.iterator.EventIteratorAdapter;
import org.apache.jackrabbit.oak.api.ChangeExtractor;
import org.apache.jackrabbit.oak.api.PropertyState;
@@ -35,10 +37,8 @@ import org.apache.jackrabbit.oak.spi.sta
import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
-import com.google.common.base.Function;
-import com.google.common.collect.Iterators;
-
class ChangeProcessor extends TimerTask {
+ private final ObservationManagerImpl observationManager;
private final NamePathMapper namePathMapper;
private final ChangeExtractor changeExtractor;
private final EventListener listener;
@@ -46,10 +46,10 @@ class ChangeProcessor extends TimerTask
private volatile boolean stopped;
- public ChangeProcessor(NamePathMapper namePathMapper, ChangeExtractor changeExtractor, EventListener listener,
- ChangeFilter filter) {
- this.namePathMapper = namePathMapper;
- this.changeExtractor = changeExtractor;
+ public ChangeProcessor(ObservationManagerImpl observationManager, EventListener listener, ChangeFilter filter) {
+ this.observationManager = observationManager;
+ this.namePathMapper = observationManager.getNamePathMapper();
+ this.changeExtractor = observationManager.getChangeExtractor();
this.listener = listener;
filterRef = new AtomicReference<ChangeFilter>(filter);
}
@@ -67,6 +67,7 @@ class ChangeProcessor extends TimerTask
public void run() {
EventGeneratingNodeStateDiff diff = new EventGeneratingNodeStateDiff();
changeExtractor.getChanges(diff);
+ observationManager.setHasEvents();
diff.sendEvents();
}
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java?rev=1365564&r1=1365563&r2=1365564&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/observation/ObservationManagerImpl.java Wed Jul 25 13:07:40 2012
@@ -19,6 +19,7 @@ package org.apache.jackrabbit.oak.jcr.ob
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
+import java.util.concurrent.atomic.AtomicBoolean;
import javax.jcr.RepositoryException;
import javax.jcr.UnsupportedRepositoryOperationException;
@@ -31,6 +32,7 @@ import org.apache.jackrabbit.commons.ite
import org.apache.jackrabbit.oak.api.ChangeExtractor;
import org.apache.jackrabbit.oak.jcr.SessionDelegate;
import org.apache.jackrabbit.oak.jcr.util.LazyValue;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
public class ObservationManagerImpl implements ObservationManager {
private final SessionDelegate sessionDelegate;
@@ -38,6 +40,7 @@ public class ObservationManagerImpl impl
new HashMap<EventListener, ChangeProcessor>();
private final LazyValue<Timer> timer;
+ private final AtomicBoolean hasEvents = new AtomicBoolean(false);
public ObservationManagerImpl(SessionDelegate sessionDelegate, LazyValue<Timer> timer) {
this.sessionDelegate = sessionDelegate;
@@ -50,6 +53,15 @@ public class ObservationManagerImpl impl
}
}
+ /**
+ * Determine whether events have been generated since the time this method has been called.
+ * @return {@code true} if this {@code ObservationManager} instance has generated events
+ * since the last time this method has been called, {@code false} otherwise.
+ */
+ public boolean hasEvents() {
+ return hasEvents.getAndSet(false);
+ }
+
@Override
public void addEventListener(EventListener listener, int eventTypes, String absPath,
boolean isDeep, String[] uuid, String[] nodeTypeName, boolean noLocal)
@@ -57,10 +69,8 @@ public class ObservationManagerImpl impl
ChangeProcessor processor = processors.get(listener);
if (processor == null) {
- ChangeExtractor extractor = sessionDelegate.getChangeExtractor();
ChangeFilter filter = new ChangeFilter(eventTypes, absPath, isDeep, uuid, nodeTypeName, noLocal);
- ChangeProcessor changeProcessor = new ChangeProcessor(sessionDelegate.getNamePathMapper(), extractor,
- listener, filter);
+ ChangeProcessor changeProcessor = new ChangeProcessor(this, listener, filter);
processors.put(listener, changeProcessor);
timer.get().schedule(changeProcessor, 100, 1000);
}
@@ -99,4 +109,17 @@ public class ObservationManagerImpl impl
throw new UnsupportedRepositoryOperationException();
}
+ //------------------------------------------------------------< internal >---
+
+ NamePathMapper getNamePathMapper() {
+ return sessionDelegate.getNamePathMapper();
+ }
+
+ ChangeExtractor getChangeExtractor() {
+ return sessionDelegate.getChangeExtractor();
+ }
+
+ void setHasEvents() {
+ hasEvents.set(true);
+ }
}