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 2013/03/26 15:01:06 UTC
svn commit: r1461135 - in
/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr:
SessionImpl.java delegate/SessionDelegate.java
Author: mduerig
Date: Tue Mar 26 14:01:05 2013
New Revision: 1461135
URL: http://svn.apache.org/r1461135
Log:
OAK-672: Avoid JCR APIs calling other JCR APIs
OAK-662: Reduce boilerplate code in JCR impl methods
refactor session related methods to use common base class of SessionOperation, which takes care of establishing session preconditions.
Modified:
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/delegate/SessionDelegate.java
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=1461135&r1=1461134&r2=1461135&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 Tue Mar 26 14:01:05 2013
@@ -25,6 +25,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
+import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.jcr.AccessDeniedException;
import javax.jcr.Credentials;
@@ -54,7 +55,6 @@ import org.apache.jackrabbit.commons.xml
import org.apache.jackrabbit.commons.xml.ParsingContentHandler;
import org.apache.jackrabbit.commons.xml.SystemViewExporter;
import org.apache.jackrabbit.commons.xml.ToXmlContentHandler;
-import org.apache.jackrabbit.oak.api.TreeLocation;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.jcr.delegate.NodeDelegate;
import org.apache.jackrabbit.oak.jcr.delegate.PropertyDelegate;
@@ -62,7 +62,6 @@ import org.apache.jackrabbit.oak.jcr.del
import org.apache.jackrabbit.oak.jcr.delegate.SessionOperation;
import org.apache.jackrabbit.oak.jcr.xml.ImportHandler;
import org.apache.jackrabbit.oak.spi.security.authentication.ImpersonationCredentials;
-import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
import org.apache.jackrabbit.oak.util.TODO;
import org.apache.jackrabbit.util.Text;
import org.apache.jackrabbit.util.XMLChar;
@@ -75,14 +74,10 @@ import org.xml.sax.SAXException;
* TODO document
*/
public class SessionImpl implements JackrabbitSession {
-
- /**
- * logger instance
- */
private static final Logger log = LoggerFactory.getLogger(SessionImpl.class);
private final SessionContext sessionContext;
- private final SessionDelegate dlg;
+ private final SessionDelegate sd;
/**
* Local namespace remappings. Prefixes as keys and namespace URIs as values.
@@ -94,7 +89,7 @@ public class SessionImpl implements Jack
SessionImpl(SessionContext sessionContext, Map<String, String> namespaces) {
this.sessionContext = sessionContext;
- this.dlg = sessionContext.getSessionDelegate();
+ this.sd = sessionContext.getSessionDelegate();
this.namespaces = namespaces;
}
@@ -105,6 +100,108 @@ public class SessionImpl implements Jack
}
}
+ private abstract class CheckedSessionOperation<T> extends SessionOperation<T> {
+ @Override
+ protected void checkPreconditions() throws RepositoryException {
+ sd.checkAlive();
+ }
+ }
+
+ @CheckForNull
+ private <T> T perform(@Nonnull CheckedSessionOperation<T> op) throws RepositoryException {
+ return sd.perform(op);
+ }
+
+ @Nonnull
+ private String getOakPathOrThrow(String absPath) throws RepositoryException {
+ return sessionContext.getOakPathOrThrow(absPath);
+ }
+
+ @Nonnull
+ private String getOakPathOrThrowNotFound(String absPath) throws PathNotFoundException {
+ return sessionContext.getOakPathOrThrowNotFound(absPath);
+ }
+
+ private NodeImpl<?> createNodeOrNull(NodeDelegate nd) {
+ return nd == null ? null : new NodeImpl<NodeDelegate>(nd, sessionContext);
+ }
+
+ private PropertyImpl createPropertyOrNull(PropertyDelegate pd) {
+ return pd == null ? null : new PropertyImpl(pd, sessionContext);
+ }
+
+ @CheckForNull
+ private ItemImpl<?> getItemInternal(@Nonnull String oakPath) {
+ NodeDelegate nd = sd.getNode(oakPath);
+ if (nd != null) {
+ return createNodeOrNull(nd);
+ }
+ PropertyDelegate pd = sd.getProperty(oakPath);
+ if (pd != null) {
+ return createPropertyOrNull(pd);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the node at the specified absolute path in the workspace or
+ * {@code null} if no such node exists.
+ *
+ * @param absPath An absolute path.
+ * @return the specified {@code Node} or {@code null}.
+ * @throws RepositoryException If another error occurs.
+ */
+ @CheckForNull
+ public Node getNodeOrNull(final String absPath) throws RepositoryException {
+ return perform(new CheckedSessionOperation<Node>() {
+ @Override
+ public Node perform() throws RepositoryException {
+ return createNodeOrNull(sd.getNode(getOakPathOrThrow(absPath)));
+ }
+ });
+ }
+
+ /**
+ * Returns the property at the specified absolute path in the workspace or
+ * {@code null} if no such node exists.
+ *
+ * @param absPath An absolute path.
+ * @return the specified {@code Property} or {@code null}.
+ * @throws RepositoryException if another error occurs.
+ */
+ @CheckForNull
+ public Property getPropertyOrNull(final String absPath) throws RepositoryException {
+ if (absPath.equals("/")) {
+ return null;
+ } else {
+ return perform(new CheckedSessionOperation<Property>() {
+ @Override
+ public Property perform() throws RepositoryException {
+ return createPropertyOrNull(sd.getProperty(getOakPathOrThrow(absPath)));
+ }
+ });
+ }
+ }
+
+ /**
+ * Returns the node at the specified absolute path in the workspace. If no
+ * such node exists, then it returns the property at the specified path.
+ * If no such property exists, then it return {@code null}.
+ *
+ * @param absPath An absolute path.
+ * @return the specified {@code Item} or {@code null}.
+ * @throws RepositoryException if another error occurs.
+ */
+ @CheckForNull
+ public Item getItemOrNull(final String absPath) throws RepositoryException {
+ return perform(new CheckedSessionOperation<Item>() {
+ @Override
+ public Item perform() throws RepositoryException {
+ return getItemInternal(getOakPathOrThrow(absPath));
+ }
+ });
+ }
+
//------------------------------------------------------------< Session >---
@Override
@@ -115,17 +212,17 @@ public class SessionImpl implements Jack
@Override
public String getUserID() {
- return dlg.getAuthInfo().getUserID();
+ return sd.getAuthInfo().getUserID();
}
@Override
public String[] getAttributeNames() {
- return dlg.getAuthInfo().getAttributeNames();
+ return sd.getAuthInfo().getAttributeNames();
}
@Override
public Object getAttribute(String name) {
- return dlg.getAuthInfo().getAttribute(name);
+ return sd.getAuthInfo().getAttribute(name);
}
@Override
@@ -137,166 +234,108 @@ public class SessionImpl implements Jack
@Override
@Nonnull
public Session impersonate(Credentials credentials) throws RepositoryException {
- dlg.checkAlive();
+ sd.checkAlive();
- ImpersonationCredentials impCreds = new ImpersonationCredentials(credentials, dlg.getAuthInfo());
- return getRepository().login(impCreds, dlg.getWorkspaceName());
+ ImpersonationCredentials impCreds = new ImpersonationCredentials(credentials, sd.getAuthInfo());
+ return getRepository().login(impCreds, sd.getWorkspaceName());
}
@Override
@Nonnull
public ValueFactory getValueFactory() throws RepositoryException {
- dlg.checkAlive();
+ sd.checkAlive();
return sessionContext.getValueFactory();
}
@Override
@Nonnull
public Node getRootNode() throws RepositoryException {
- return dlg.perform(new SessionOperation<NodeImpl<?>>() {
+ return perform(new CheckedSessionOperation<Node>() {
@Override
- protected void checkPreconditions() throws RepositoryException {
- dlg.checkAlive();
- }
-
- @Override
- public NodeImpl<?> perform() throws AccessDeniedException {
- NodeDelegate nd = dlg.getRootNode();
+ protected Node perform() throws AccessDeniedException {
+ NodeDelegate nd = sd.getRootNode();
if (nd == null) {
throw new AccessDeniedException("Root node is not accessible.");
- } else {
- return new NodeImpl<NodeDelegate>(nd, sessionContext);
}
+ return createNodeOrNull(nd);
}
});
}
@Override
- @Nonnull
- public Node getNodeByUUID(String uuid) throws RepositoryException {
- return getNodeByIdentifier(uuid);
+ public Node getNode(String absPath) throws RepositoryException {
+ Node node = getNodeOrNull(absPath);
+ if (node == null) {
+ throw new PathNotFoundException("Node with path " + absPath + " does not exist.");
+ }
+ return node;
}
@Override
- @Nonnull
- public Node getNodeByIdentifier(final String id) throws RepositoryException {
- return dlg.perform(new SessionOperation<NodeImpl<?>>() {
- @Override
- protected void checkPreconditions() throws RepositoryException {
- dlg.checkAlive();
- }
+ public boolean nodeExists(String absPath) throws RepositoryException {
+ return getNodeOrNull(absPath) != null;
+ }
+ @Nonnull
+ private Node getNodeById(final String id) throws RepositoryException {
+ return perform(new CheckedSessionOperation<Node>() {
@Override
- public NodeImpl<?> perform() throws RepositoryException {
- NodeDelegate d = dlg.getNodeByIdentifier(id);
- if (d == null) {
+ public Node perform() throws ItemNotFoundException {
+ NodeDelegate nd = sd.getNodeByIdentifier(id);
+ if (nd == null) {
throw new ItemNotFoundException("Node with id " + id + " does not exist.");
}
- return new NodeImpl<NodeDelegate>(d, sessionContext);
+ return createNodeOrNull(nd);
}
});
}
@Override
- public Item getItem(String absPath) throws RepositoryException {
- if (nodeExists(absPath)) {
- return getNode(absPath);
- } else {
- return getProperty(absPath);
- }
+ @Nonnull
+ public Node getNodeByUUID(String uuid) throws RepositoryException {
+ return getNodeById(uuid);
}
@Override
- public boolean itemExists(String absPath) throws RepositoryException {
- return nodeExists(absPath) || propertyExists(absPath);
- }
-
- private String getOakPath(String absPath) throws RepositoryException {
- return sessionContext.getOakPathOrThrow(absPath);
+ @Nonnull
+ public Node getNodeByIdentifier(String id) throws RepositoryException {
+ return getNodeById(id);
}
@Override
- public Node getNode(final String absPath) throws RepositoryException {
- return dlg.perform(new SessionOperation<NodeImpl<?>>() {
- @Override
- protected void checkPreconditions() throws RepositoryException {
- dlg.checkAlive();
- }
-
- @Override
- public NodeImpl<?> perform() throws RepositoryException {
- String oakPath = getOakPath(absPath);
- NodeDelegate d = dlg.getNode(oakPath);
- if (d == null) {
- throw new PathNotFoundException("Node with path " + absPath + " does not exist.");
- }
- return new NodeImpl<NodeDelegate>(d, sessionContext);
- }
- });
+ public Property getProperty(String absPath) throws RepositoryException {
+ Property property = getPropertyOrNull(absPath);
+ if (property == null) {
+ throw new PathNotFoundException(absPath);
+ }
+ return property;
}
@Override
- public boolean nodeExists(final String absPath) throws RepositoryException {
- return dlg.perform(new SessionOperation<Boolean>() {
- @Override
- protected void checkPreconditions() throws RepositoryException {
- dlg.checkAlive();
- }
-
- @Override
- public Boolean perform() throws RepositoryException {
- String oakPath = getOakPath(absPath);
- return dlg.getNode(oakPath) != null;
- }
- });
+ public boolean propertyExists(String absPath) throws RepositoryException {
+ return getPropertyOrNull(absPath) != null;
}
@Override
- public Property getProperty(final String absPath) throws RepositoryException {
- if (absPath.equals("/")) {
- throw new RepositoryException("The root node is not a property");
- } else {
- return dlg.perform(new SessionOperation<PropertyImpl>() {
- @Override
- public PropertyImpl perform() throws RepositoryException {
- String oakPath = getOakPathOrThrowNotFound(absPath);
- TreeLocation loc = dlg.getLocation(oakPath);
- if (loc.getProperty() == null) {
- throw new PathNotFoundException(absPath);
- } else {
- return new PropertyImpl(new PropertyDelegate(dlg, loc), sessionContext);
- }
- }
- });
+ public Item getItem(String absPath) throws RepositoryException {
+ Item item = getItemOrNull(absPath);
+ if (item == null) {
+ throw new PathNotFoundException(absPath);
}
- }
-
- private String getOakPathOrThrowNotFound(String absPath) throws PathNotFoundException {
- return sessionContext.getOakPathOrThrowNotFound(absPath);
+ return item;
}
@Override
- public boolean propertyExists(final String absPath) throws RepositoryException {
- if (absPath.equals("/")) {
- throw new RepositoryException("The root node is not a property");
- } else {
- return dlg.perform(new SessionOperation<Boolean>() {
- @Override
- public Boolean perform() throws RepositoryException {
- String oakPath = getOakPathOrThrowNotFound(absPath);
- TreeLocation loc = dlg.getLocation(oakPath);
- return loc.getProperty() != null;
- }
- });
- }
+ public boolean itemExists(String absPath) throws RepositoryException {
+ return getItemOrNull(absPath) != null;
}
@Override
public void move(final String srcAbsPath, final String destAbsPath) throws RepositoryException {
- dlg.perform(new SessionOperation<Void>() {
+ sd.perform(new CheckedSessionOperation<Void>() {
@Override
protected void checkPreconditions() throws RepositoryException {
- dlg.checkAlive();
+ super.checkPreconditions();
checkProtectedNodes(SessionImpl.this,
Text.getRelativeParent(srcAbsPath, 1), Text.getRelativeParent(destAbsPath, 1));
}
@@ -309,49 +348,64 @@ public class SessionImpl implements Jack
throw new RepositoryException("Cannot create a new node using a name including an index");
}
- dlg.move(getOakPathOrThrowNotFound(srcAbsPath), oakDestPath, true);
+ sd.move(getOakPathOrThrowNotFound(srcAbsPath), oakDestPath, true);
return null;
}
});
}
@Override
- public void removeItem(String absPath) throws RepositoryException {
- getItem(absPath).remove();
+ public void removeItem(final String absPath) throws RepositoryException {
+ perform(new CheckedSessionOperation<Void>() {
+ @Override
+ protected Void perform() throws RepositoryException {
+ String oakPath = getOakPathOrThrowNotFound(absPath);
+ ItemImpl<?> item = getItemInternal(oakPath);
+ if (item == null) {
+ throw new PathNotFoundException(absPath);
+ }
+
+ item.checkProtected();
+ item.remove();
+ return null;
+ }
+ });
}
@Override
public void save() throws RepositoryException {
- dlg.checkAlive();
- dlg.save();
+ sd.checkAlive();
+ sd.save();
sessionContext.refresh();
}
@Override
public void refresh(boolean keepChanges) throws RepositoryException {
- dlg.checkAlive();
- dlg.refresh(keepChanges);
+ sd.checkAlive();
+ sd.refresh(keepChanges);
sessionContext.refresh();
}
@Override
public boolean hasPendingChanges() throws RepositoryException {
- dlg.checkAlive();
- return dlg.hasPendingChanges();
+ sd.checkAlive();
+ return sd.hasPendingChanges();
}
@Override
public boolean isLive() {
- return dlg.isAlive();
+ return sd.isAlive();
}
@Override
public void logout() {
- sessionContext.dispose();
- dlg.logout();
- synchronized (namespaces) {
- namespaces.clear();
+ if (sd.isAlive()) {
+ sessionContext.dispose();
+ sd.logout();
+ synchronized (namespaces) {
+ namespaces.clear();
+ }
}
}
@@ -414,7 +468,7 @@ public class SessionImpl implements Jack
throws IOException, RepositoryException {
try {
ContentHandler handler = new ToXmlContentHandler(out);
- exportSystemView(absPath, handler, skipBinary, noRecurse);
+ export(absPath, new SystemViewExporter(this, handler, !noRecurse, !skipBinary));
} catch (SAXException e) {
Exception exception = e.getException();
if (exception instanceof RepositoryException) {
@@ -438,7 +492,7 @@ public class SessionImpl implements Jack
throws IOException, RepositoryException {
try {
ContentHandler handler = new ToXmlContentHandler(out);
- exportDocumentView(absPath, handler, skipBinary, noRecurse);
+ export(absPath, new DocumentViewExporter(this, handler, !noRecurse, !skipBinary));
} catch (SAXException e) {
Exception exception = e.getException();
if (exception instanceof RepositoryException) {
@@ -495,16 +549,14 @@ public class SessionImpl implements Jack
}
@Override
- public boolean hasPermission(String absPath, String actions) throws RepositoryException {
- dlg.checkAlive();
-
- String oakPath = sessionContext.getOakPathKeepIndex(absPath);
- if (oakPath == null) {
- throw new RepositoryException("Invalid JCR path: " + absPath);
- }
-
- PermissionProvider permissionProvider = sessionContext.getPermissionProvider();
- return permissionProvider.isGranted(absPath, actions);
+ public boolean hasPermission(final String absPath, final String actions) throws RepositoryException {
+ return perform(new CheckedSessionOperation<Boolean>() {
+ @Override
+ protected Boolean perform() throws RepositoryException {
+ String oakPath = getOakPathOrThrow(absPath);
+ return sessionContext.getPermissionProvider().isGranted(oakPath, actions);
+ }
+ });
}
@Override
@@ -516,7 +568,7 @@ public class SessionImpl implements Jack
@Override
public boolean hasCapability(String methodName, Object target, Object[] arguments) throws RepositoryException {
- dlg.checkAlive();
+ sd.checkAlive();
// TODO
return TODO.unimplemented().returnValue(false);
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java?rev=1461135&r1=1461134&r2=1461135&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java Tue Mar 26 14:01:05 2013
@@ -58,6 +58,11 @@ public class SessionDelegate {
this.idManager = new IdentifierManager(root);
}
+ /**
+ * Called by {@link #perform(SessionOperation)} when the session needs to be
+ * refreshed before the actual {@link SessionOperation} is executed.
+ * This default implementation is empty.
+ */
protected void refresh() {
}
@@ -74,24 +79,19 @@ public class SessionDelegate {
*/
public synchronized <T> T perform(SessionOperation<T> sessionOperation) throws RepositoryException {
// Synchronize to avoid conflicting refreshes from concurrent JCR API calls
+ if (sessionOpCount == 0) {
+ // Refresh and checks only for non re-entrant session operations
+ refresh();
+ sessionOperation.checkPreconditions();
+ }
try {
- if (sessionOpCount == 0) {
- // Refresh only for non re-entrant session operations
- refresh();
- }
sessionOpCount++;
- sessionOperation.checkPreconditions();
return sessionOperation.perform();
} finally {
sessionOpCount--;
}
}
- @Nonnull // FIXME this should be package private
- public Root getRoot() {
- return root;
- }
-
@Nonnull
public ContentSession getContentSession() {
return contentSession;
@@ -143,11 +143,6 @@ public class SessionDelegate {
return idManager;
}
- @Nonnull
- public TreeLocation getLocation(String path) {
- return root.getLocation(path);
- }
-
@CheckForNull
public NodeDelegate getRootNode() {
return getNode("/");
@@ -297,6 +292,16 @@ public class SessionDelegate {
//-----------------------------------------------------------< internal >---
+ @Nonnull // FIXME this should be package private
+ public Root getRoot() {
+ return root;
+ }
+
+ @Nonnull
+ TreeLocation getLocation(String path) {
+ return root.getLocation(path);
+ }
+
/**
* Revision of this session. The revision is incremented each time a session is refreshed or saved.
* This allows items to determine whether they need to re-resolve their underlying state when the