jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ang...@apache.org
Subject svn commit: r732693 [2/6] - in /jackrabbit/trunk: jackrabbit-api/src/main/java/org/apache/jackrabbit/api/jsr283/security/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ jackra...
Date Thu, 08 Jan 2009 11:52:45 GMT
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java Thu Jan  8 03:52:38 2009
@@ -16,9 +16,12 @@
  */
 package org.apache.jackrabbit.core.lock;
 
+import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.core.NodeImpl;
+import org.apache.jackrabbit.core.security.authorization.Permission;
+
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
-import javax.jcr.lock.Lock;
 import javax.jcr.lock.LockException;
 
 /**
@@ -54,8 +57,6 @@
      * {@inheritDoc}
      */
     public String getLockOwner() {
-        // TODO:  TOBEFIXED for 2.0
-        // TODO   - respect ownerInfo supplied by the client -> see LockManager#lock
         return info.lockOwner;
     }
 
@@ -118,6 +119,11 @@
         if (getLockToken() == null) {
             throw new LockException("Session does not hold lock.");
         }
+        // make sure the current session has sufficient privileges to refresh
+        // the lock.
+        SessionImpl s = (SessionImpl) node.getSession();
+        s.getAccessManager().checkPermission(((NodeImpl) node).getPrimaryPath(), Permission.LOCK_MNGMT);
+
         // TODO: TOBEFIXED for 2.0
         // TODO  - add refresh if timeout is supported -> see #getSecondsRemaining
         // since a lock has no expiration date no other action is required
@@ -126,15 +132,10 @@
     //--------------------------------------------------< new JSR 283 methods >
 
     /**
-     * Always returns {@link Long#MAX_VALUE}.
-     *
-     * @return Always returns {@link Long#MAX_VALUE}.
      * @see org.apache.jackrabbit.api.jsr283.lock.Lock#getSecondsRemaining()
      */
     public long getSecondsRemaining() {
-        // TODO: TOBEFIXED for 2.0
-        // TODO  - add support for timeout specified by the API user -> LockManager#lock
-        return Long.MAX_VALUE;
+        return info.getSecondsRemaining();
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManager.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManager.java Thu Jan  8 03:52:38 2009
@@ -45,6 +45,24 @@
             throws LockException, RepositoryException;
 
     /**
+     * Lock a node. Checks whether the node is not locked and then
+     * returns a lock object for this node.
+     *
+     * @param node
+     * @param isDeep whether the lock applies to this node only
+     * @param isSessionScoped whether the lock is session scoped
+     * @param timoutHint
+     * @param ownerInfo
+     * @return
+     * @throws LockException if this node already is locked, or some descendant
+     *         node is locked and <code>isDeep</code> is <code>true</code>
+     * @see org.apache.jackrabbit.api.jsr283.lock.LockManager#lock(String, boolean, boolean, long, String)
+     * @throws RepositoryException
+     */
+    Lock lock(NodeImpl node, boolean isDeep, boolean isSessionScoped, long timoutHint, String ownerInfo)
+            throws LockException, RepositoryException;
+
+    /**
      * Returns the Lock object that applies to a node. This may be either a lock
      * on this node itself or a deep lock on a node above this node.
      * @param node node

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java Thu Jan  8 03:52:38 2009
@@ -19,30 +19,40 @@
 import EDU.oswego.cs.dl.util.concurrent.ReentrantLock;
 import org.apache.commons.collections.map.LinkedMap;
 import org.apache.commons.io.IOUtils;
-import org.apache.jackrabbit.spi.commons.conversion.MalformedPathException;
 import org.apache.jackrabbit.core.ItemId;
+import org.apache.jackrabbit.core.ItemValidator;
 import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.core.NodeImpl;
+import org.apache.jackrabbit.core.PropertyId;
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.SessionListener;
+import org.apache.jackrabbit.core.WorkspaceImpl;
 import org.apache.jackrabbit.core.cluster.ClusterOperation;
 import org.apache.jackrabbit.core.cluster.LockEventChannel;
 import org.apache.jackrabbit.core.cluster.LockEventListener;
 import org.apache.jackrabbit.core.fs.FileSystem;
 import org.apache.jackrabbit.core.fs.FileSystemException;
 import org.apache.jackrabbit.core.fs.FileSystemResource;
+import org.apache.jackrabbit.core.nodetype.PropDef;
 import org.apache.jackrabbit.core.observation.EventImpl;
 import org.apache.jackrabbit.core.observation.SynchronousEventListener;
+import org.apache.jackrabbit.core.state.ItemStateException;
+import org.apache.jackrabbit.core.state.NodeState;
+import org.apache.jackrabbit.core.state.PropertyState;
+import org.apache.jackrabbit.core.state.UpdatableItemStateManager;
 import org.apache.jackrabbit.core.util.Dumpable;
+import org.apache.jackrabbit.core.value.InternalValue;
+import org.apache.jackrabbit.spi.Path;
+import org.apache.jackrabbit.spi.commons.conversion.MalformedPathException;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.apache.jackrabbit.spi.commons.name.PathMap;
-import org.apache.jackrabbit.spi.Path;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.jcr.ItemNotFoundException;
 import javax.jcr.Node;
 import javax.jcr.PathNotFoundException;
+import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.lock.Lock;
@@ -229,27 +239,33 @@
 
     /**
      * Internal <code>lock</code> implementation that takes the same parameters
-     * as the public method but will not modify content.
+     * as the public method.
+     *
      * @param node node to lock
      * @param isDeep whether the lock applies to this node only
      * @param isSessionScoped whether the lock is session scoped
+     * @param timeoutHint
+     * @param ownerInfo
      * @return lock
      * @throws LockException       if the node is already locked
      * @throws RepositoryException if another error occurs
      */
-    AbstractLockInfo internalLock(NodeImpl node, boolean isDeep, boolean isSessionScoped)
+    AbstractLockInfo internalLock(NodeImpl node, boolean isDeep,
+                                  boolean isSessionScoped, long timeoutHint,
+                                  String ownerInfo)
             throws LockException, RepositoryException {
 
         SessionImpl session = (SessionImpl) node.getSession();
+        String lockOwner = (ownerInfo != null) ? ownerInfo : session.getUserID();
         LockInfo info = new LockInfo(new LockToken(node.getNodeId()),
-                isSessionScoped, isDeep, session.getUserID());
+                isSessionScoped, isDeep, lockOwner, timeoutHint);
 
         ClusterOperation operation = null;
         boolean successful = false;
 
         // Cluster is only informed about open-scoped locks
         if (eventChannel != null && !isSessionScoped) {
-            operation = eventChannel.create(node.getNodeId(), isDeep, session.getUserID());
+            operation = eventChannel.create(node.getNodeId(), isDeep, lockOwner);
         }
 
         acquire();
@@ -277,7 +293,11 @@
             info.setLockHolder(session);
             info.setLive(true);
             session.addListener(info);
-            session.addLockToken(info.lockToken.toString(), false);
+            // TODO: TOBEFIXED for 2.0
+            // TODO  only tokens of open-scoped locks must be added to the session.
+            // if (!info.isSessionScoped()) {
+                session.addLockToken(info.lockToken.toString(), false);
+            //}
             lockMap.put(path, info);
 
             if (!info.sessionScoped) {
@@ -314,7 +334,6 @@
 
         try {
             SessionImpl session = (SessionImpl) node.getSession();
-
             // check whether node is locked by this session
             PathMap.Element element = lockMap.map(getPath(node.getId()), true);
             if (element == null) {
@@ -327,6 +346,7 @@
             if (session != info.getLockHolder()) {
                 throw new LockException("Node not locked by session: " + node);
             }
+
             session.removeLockToken(info.getLockToken(session), false);
 
             element.set(null);
@@ -402,8 +422,14 @@
      */
     public Lock lock(NodeImpl node, boolean isDeep, boolean isSessionScoped)
             throws LockException, RepositoryException {
+        return lock(node, isDeep, isSessionScoped, Long.MAX_VALUE, null);
+    }
+
+    public Lock lock(NodeImpl node, boolean isDeep, boolean isSessionScoped, long timoutHint, String ownerInfo)
+            throws LockException, RepositoryException {
+        AbstractLockInfo info = internalLock(node, isDeep, isSessionScoped, timoutHint, ownerInfo);
+        writeLockProperties(node, info.lockOwner, info.deep);
 
-        AbstractLockInfo info = internalLock(node, isDeep, isSessionScoped);
         return new LockImpl(info, node);
     }
 
@@ -466,6 +492,7 @@
     public void unlock(NodeImpl node)
             throws LockException, RepositoryException {
 
+        removeLockProperties(node);
         internalUnlock(node);
     }
 
@@ -679,6 +706,125 @@
         release();
     }
 
+    /**
+     * Add the lock related properties to the target node.
+     *
+     * @param node
+     * @param lockOwner
+     * @param isDeep
+     */
+    protected void writeLockProperties(NodeImpl node, String lockOwner, boolean isDeep) throws RepositoryException {
+        boolean success = false;
+
+        SessionImpl editingSession = (SessionImpl) node.getSession();
+        WorkspaceImpl wsp = (WorkspaceImpl) editingSession.getWorkspace();
+        UpdatableItemStateManager stateMgr = wsp.getItemStateManager();
+        ItemValidator helper = new ItemValidator(editingSession.getNodeTypeManager().getNodeTypeRegistry(), wsp.getHierarchyManager(), editingSession);
+
+        synchronized (stateMgr) {
+            if (stateMgr.inEditMode()) {
+                throw new RepositoryException("Unable to write lock properties.");
+            }
+            stateMgr.edit();
+            try {
+                // add properties to content
+                NodeId nodeId = node.getNodeId();
+                NodeState nodeState = (NodeState) stateMgr.getItemState(nodeId);
+
+                PropertyState propState;
+                if (!nodeState.hasPropertyName(NameConstants.JCR_LOCKOWNER)) {
+                    PropDef def = helper.findApplicablePropertyDefinition(NameConstants.JCR_LOCKOWNER, PropertyType.STRING, false, nodeState);
+                    propState = stateMgr.createNew(NameConstants.JCR_LOCKOWNER, nodeId);
+                    propState.setDefinitionId(def.getId());
+                    propState.setType(PropertyType.STRING);
+                    propState.setMultiValued(false);
+                } else {
+                    propState = (PropertyState) stateMgr.getItemState(new PropertyId(nodeId, NameConstants.JCR_LOCKOWNER));
+                }
+                propState.setValues(new InternalValue[] { InternalValue.create(lockOwner) });
+                nodeState.addPropertyName(NameConstants.JCR_LOCKOWNER);
+                stateMgr.store(nodeState);
+
+                if (!nodeState.hasPropertyName(NameConstants.JCR_LOCKISDEEP)) {
+                    PropDef def = helper.findApplicablePropertyDefinition(NameConstants.JCR_LOCKISDEEP, PropertyType.BOOLEAN, false, nodeState);
+                    propState = stateMgr.createNew(NameConstants.JCR_LOCKISDEEP, nodeId);
+                    propState.setDefinitionId(def.getId());
+                    propState.setType(PropertyType.BOOLEAN);
+                    propState.setMultiValued(false);
+                } else {
+                    propState = (PropertyState) stateMgr.getItemState(new PropertyId(nodeId, NameConstants.JCR_LOCKISDEEP));
+                }
+                propState.setValues(new InternalValue[] { InternalValue.create(isDeep) });
+                nodeState.addPropertyName(NameConstants.JCR_LOCKISDEEP);
+                stateMgr.store(nodeState);
+
+                stateMgr.update();
+                success = true;
+            } catch (ItemStateException e) {
+                throw new RepositoryException("Error while creating lock.", e);
+            } finally {
+                if (!success) {
+                    // failed to set lock meta-data content, cleanup
+                    stateMgr.cancel();
+                    try {
+                        unlock(node);
+                    } catch (RepositoryException e) {
+                        // cleanup failed
+                        log.error("error while cleaning up after failed lock attempt", e);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     *
+     * @param node
+     * @throws RepositoryException
+     */
+    protected void removeLockProperties(NodeImpl node) throws RepositoryException {
+        boolean success = false;
+
+        SessionImpl editingSession = (SessionImpl) node.getSession();
+        WorkspaceImpl wsp = (WorkspaceImpl) editingSession.getWorkspace();
+        UpdatableItemStateManager stateMgr = wsp.getItemStateManager();
+
+        synchronized (stateMgr) {
+            try {
+                // add properties to content
+                NodeId nodeId = node.getNodeId();
+                NodeState nodeState = (NodeState) stateMgr.getItemState(nodeId);
+
+                if (stateMgr.inEditMode()) {
+                    throw new RepositoryException("Unable to remove lock properties.");
+                }
+                stateMgr.edit();
+                if (nodeState.hasPropertyName(NameConstants.JCR_LOCKOWNER)) {
+                    PropertyState propState = (PropertyState) stateMgr.getItemState(new PropertyId(nodeId, NameConstants.JCR_LOCKOWNER));
+                    nodeState.removePropertyName(NameConstants.JCR_LOCKOWNER);
+                    stateMgr.destroy(propState);
+                    stateMgr.store(nodeState);
+                }
+
+                if (nodeState.hasPropertyName(NameConstants.JCR_LOCKISDEEP)) {
+                    PropertyState propState = (PropertyState) stateMgr.getItemState(new PropertyId(nodeId, NameConstants.JCR_LOCKISDEEP));
+                    nodeState.removePropertyName(NameConstants.JCR_LOCKISDEEP);
+                    stateMgr.destroy(propState);
+                    stateMgr.store(nodeState);
+                }
+
+                stateMgr.update();
+                success = true;
+            } catch (ItemStateException e) {
+                throw new RepositoryException("Error while removing lock.", e);
+            } finally {
+                if (!success) {
+                    // failed to set lock meta-data content, cleanup
+                    stateMgr.cancel();
+                }
+            }
+        }
+    }
 
     //----------------------------------------------< SynchronousEventListener >
 
@@ -945,7 +1091,21 @@
          */
         public LockInfo(LockToken lockToken, boolean sessionScoped,
                         boolean deep, String lockOwner) {
-            super(lockToken, sessionScoped, deep, lockOwner);
+            this(lockToken, sessionScoped, deep, lockOwner, Long.MAX_VALUE);
+        }
+
+        /**
+         * Create a new instance of this class.
+         *
+         * @param lockToken     lock token
+         * @param sessionScoped whether lock token is session scoped
+         * @param deep          whether lock is deep
+         * @param lockOwner     owner of lock
+         * @param timeoutHint
+         */
+        public LockInfo(LockToken lockToken, boolean sessionScoped,
+                        boolean deep, String lockOwner, long timeoutHint) {
+            super(lockToken, sessionScoped, deep, lockOwner, timeoutHint);
         }
 
         /**
@@ -969,9 +1129,19 @@
                         NodeImpl node = (NodeImpl) session.getItemManager().getItem(getId());
                         node.unlock();
                     } catch (RepositoryException e) {
-                        log.warn("Unable to remove session-scoped lock on node '"
-                                + lockToken + "': " + e.getMessage());
-                        log.debug("Root cause: ", e);
+                        // Session is not allowed/able to unlock.
+                        // Use system session present with lock-mgr as fallback
+                        // in order to make sure, that session-scoped locks are
+                        // properly cleaned.
+                        SessionImpl systemSession = LockManagerImpl.this.session;
+                        setLockHolder(systemSession);
+                        try {
+                            NodeImpl node = (NodeImpl) systemSession.getItemManager().getItem(getId());
+                            node.unlock();
+                        } catch (RepositoryException re) {
+                            log.warn("Unable to remove session-scoped lock on node '" + lockToken + "': " + e.getMessage());
+                            log.debug("Root cause: ", e);
+                        }
                     }
                 } else {
                     if (session == lockHolder) {
@@ -1004,14 +1174,14 @@
     /**
      * {@inheritDoc}
      */
-    public void externalLock(NodeId nodeId, boolean isDeep, String userId) throws RepositoryException {
+    public void externalLock(NodeId nodeId, boolean isDeep, String lockOwner) throws RepositoryException {
         acquire();
 
         try {
             Path path = getPath(nodeId);
 
             // create lock token
-            LockInfo info = new LockInfo(new LockToken(nodeId), false, isDeep, userId);
+            LockInfo info = new LockInfo(new LockToken(nodeId), false, isDeep, lockOwner);
             info.setLive(true);
             lockMap.put(path, info);
 

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/SessionLockManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/SessionLockManager.java?rev=732693&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/SessionLockManager.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/SessionLockManager.java Thu Jan  8 03:52:38 2009
@@ -0,0 +1,179 @@
+/*
+ * 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.core.lock;
+
+import org.apache.jackrabbit.api.jsr283.lock.Lock;
+import org.apache.jackrabbit.core.NodeImpl;
+import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.core.security.authorization.Permission;
+import org.apache.jackrabbit.spi.commons.name.NameConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.lock.LockException;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * <code>SessionLockManager</code> implements the
+ * {@link org.apache.jackrabbit.api.jsr283.lock.LockManager}. In contrast
+ * to the internal {@link LockManager} interface that is created once
+ * for each <code>WorkspaceInfo</code>, the JSR 283 <code>LockManager</code>
+ * is associated with a single <code>Session</code> and its
+ * <code>Workspace</code>.
+ *
+ * @see org.apache.jackrabbit.api.jsr283.Workspace#getLockManager()
+ */
+public class SessionLockManager implements org.apache.jackrabbit.api.jsr283.lock.LockManager {
+
+    private static Logger log = LoggerFactory.getLogger(SessionLockManager.class);
+
+    private final SessionImpl session;
+    private final LockManager systemLockMgr;
+    private final Set lockTokens = new HashSet();
+
+    public SessionLockManager(SessionImpl session, LockManager systemLockMgr) throws RepositoryException {
+        this.session = session;
+        this.systemLockMgr = systemLockMgr;
+    }
+
+    /**
+     * @see org.apache.jackrabbit.api.jsr283.lock.LockManager#getLockTokens()
+     */
+    public String[] getLockTokens() throws RepositoryException {
+        synchronized (lockTokens) {
+            String[] result = new String[lockTokens.size()];
+            lockTokens.toArray(result);
+            return result;
+        }
+    }
+
+    /**
+     * @see org.apache.jackrabbit.api.jsr283.lock.LockManager#addLockToken(String)
+     */
+    public void addLockToken(String lockToken) throws LockException, RepositoryException {
+        // TODO
+        throw new UnsupportedRepositoryOperationException("Not yet implemented");
+    }
+
+    /**
+     * @see org.apache.jackrabbit.api.jsr283.lock.LockManager#removeLockToken(String)
+     */
+    public void removeLockToken(String lockToken) throws LockException, RepositoryException {
+        // TODO
+        throw new UnsupportedRepositoryOperationException("Not yet implemented");
+    }
+
+    /**
+     * @see org.apache.jackrabbit.api.jsr283.lock.LockManager#isLocked(String)
+     */
+    public boolean isLocked(String absPath) throws RepositoryException {
+        NodeImpl node = (NodeImpl) session.getNode(absPath);
+        /*
+         NOTE: with JSR 283 a transient node below a deep lock will report
+         islocked = true. therefore, the shortcut for NEW nodes that was
+         present with NodeImpl.isLocked before cannot be applied any more.
+         */
+        return systemLockMgr.isLocked(node);
+    }
+
+    /**
+     * @see org.apache.jackrabbit.api.jsr283.lock.LockManager#getLock(String)
+     */
+    public Lock getLock(String absPath) throws
+            UnsupportedRepositoryOperationException, LockException,
+            AccessDeniedException, RepositoryException {
+        NodeImpl node = (NodeImpl) session.getNode(absPath);
+        return (Lock) systemLockMgr.getLock(node);
+    }
+
+    /**
+     * @see org.apache.jackrabbit.api.jsr283.lock.LockManager#holdsLock(String)
+     */
+    public boolean holdsLock(String absPath) throws RepositoryException {
+        NodeImpl node = (NodeImpl) session.getNode(absPath);
+        /* Shortcut:
+           New nodes never hold or not-lockable nodes never hold a lock. */
+        if (node.isNew() || !node.isNodeType(NameConstants.MIX_LOCKABLE)) {
+            return false;
+        } else {
+            return systemLockMgr.holdsLock(node);
+        }
+    }
+
+    /**
+     * @see org.apache.jackrabbit.api.jsr283.lock.LockManager#lock(String, boolean, boolean, long, String)
+     */
+    public Lock lock(String absPath, boolean isDeep, boolean isSessionScoped,
+                     long timeoutHint, String ownerInfo) throws RepositoryException {
+        NodeImpl node = (NodeImpl) session.getNode(absPath);
+
+        if (session.hasPendingChanges(node)) {
+            String msg = "Unable to lock node. Node has pending changes: " + this;
+            log.debug(msg);
+            throw new InvalidItemStateException(msg);
+        }
+        checkLockable(node);
+        session.getAccessManager().checkPermission(session.getQPath(node.getPath()), Permission.LOCK_MNGMT);
+
+        synchronized (systemLockMgr) {
+            return (Lock) systemLockMgr.lock(node, isDeep, isSessionScoped, timeoutHint, ownerInfo);
+        }
+    }
+
+    /**
+     * @see org.apache.jackrabbit.api.jsr283.lock.LockManager#unlock(String)
+     */
+    public void unlock(String absPath) throws
+            UnsupportedRepositoryOperationException, LockException,
+            AccessDeniedException, InvalidItemStateException,
+            RepositoryException {
+
+        NodeImpl node = (NodeImpl) session.getNode(absPath);
+        if (session.hasPendingChanges(node)) {
+            String msg = "Unable to unlock node. Node has pending changes: " + this;
+            log.debug(msg);
+            throw new InvalidItemStateException(msg);
+        }
+        checkLockable(node);
+        session.getAccessManager().checkPermission(session.getQPath(node.getPath()), Permission.LOCK_MNGMT);
+
+        synchronized (systemLockMgr) {
+            systemLockMgr.unlock(node);
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    /**
+     * Checks if the given node is lockable, i.e. has 'mix:lockable'.
+     *
+     * @param node
+     * @throws LockException       if this node is not lockable
+     * @throws RepositoryException if another error occurs
+     */
+    private static void checkLockable(NodeImpl node) throws LockException, RepositoryException {
+        if (!node.isNodeType(NameConstants.MIX_LOCKABLE)) {
+            String msg = "Unable to perform a locking operation on a non-lockable node: " + node.safeGetJCRPath();
+            log.debug(msg);
+            throw new LockException(msg);
+        }
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/SessionLockManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/SessionLockManager.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XAEnvironment.java Thu Jan  8 03:52:38 2009
@@ -107,6 +107,23 @@
      */
     public AbstractLockInfo lock(NodeImpl node, boolean isDeep, boolean isSessionScoped)
             throws LockException, RepositoryException {
+        return lock(node, isDeep, isSessionScoped, Long.MAX_VALUE, null);
+    }
+
+    /**
+     * Lock some node.
+     * @param node node to lock
+     * @param isDeep <code>true</code> to deep lock this node;
+     *               <code>false</code> otherwise
+     * @param isSessionScoped <code>true</code> if lock should be session scoped;
+     *                        <code>false</code> otherwise
+     * @param timeoutHint
+     * @param ownerInfo
+     * @throws LockException if node is already locked
+     * @throws RepositoryException if an error occurs
+     */
+    public AbstractLockInfo lock(NodeImpl node, boolean isDeep, boolean isSessionScoped, long timeoutHint, String ownerInfo)
+            throws LockException, RepositoryException {
 
         NodeId id = node.getNodeId();
 
@@ -127,11 +144,12 @@
         }
 
         // create a new lock info for this node
-        info = new LockInfo(node, new LockToken(id),
-                isSessionScoped, isDeep, node.getSession().getUserID());
+        String lockOwner = (ownerInfo != null) ? ownerInfo : node.getSession().getUserID();
+        info = new LockInfo(node, new LockToken(id), isSessionScoped, isDeep, lockOwner);
         SessionImpl session = (SessionImpl) node.getSession();
         info.setLockHolder(session);
         info.setLive(true);
+
         session.addLockToken(info.lockToken.toString(), false);
         lockedNodesMap.put(id, info);
         operations.add(info);
@@ -374,8 +392,21 @@
         public LockInfo(NodeImpl node, LockToken lockToken,
                         boolean sessionScoped, boolean deep, String lockOwner) {
 
-            super(lockToken, sessionScoped, deep, lockOwner);
+            this(node, lockToken, sessionScoped, deep, lockOwner, Long.MAX_VALUE);
+        }
+
+        /**
+         * Create a new instance of this class.
+         * @param lockToken     lock token
+         * @param sessionScoped whether lock token is session scoped
+         * @param deep          whether lock is deep
+         * @param lockOwner     owner of lock
+         */
+        public LockInfo(NodeImpl node, LockToken lockToken,
+                        boolean sessionScoped, boolean deep, String lockOwner,
+                        long timeoutHint) {
 
+            super(lockToken, sessionScoped, deep, lockOwner, timeoutHint);
             this.node = node;
         }
 
@@ -384,7 +415,7 @@
          * unlock operation on some existing lock information.
          */
         public LockInfo(NodeImpl node, AbstractLockInfo info) {
-            super(info.lockToken, info.sessionScoped, info.deep, info.lockOwner);
+            super(info.lockToken, info.sessionScoped, info.deep, info.lockOwner, info.getSecondsRemaining());
 
             this.node = node;
             this.isUnlock = true;
@@ -406,7 +437,7 @@
             if (isUnlock) {
                 lockMgr.internalUnlock(node);
             } else {
-                lockMgr.internalLock(node, deep, sessionScoped);
+                lockMgr.internalLock(node, deep, sessionScoped, getSecondsRemaining(), lockOwner);
             }
         }
 
@@ -415,7 +446,7 @@
          */
         public void undo() throws LockException, RepositoryException {
             if (isUnlock) {
-                lockMgr.internalLock(node, deep, sessionScoped);
+                lockMgr.internalLock(node, deep, sessionScoped, getSecondsRemaining(), lockOwner);
             } else {
                 lockMgr.internalUnlock(node);
             }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XALockManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XALockManager.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XALockManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/XALockManager.java Thu Jan  8 03:52:38 2009
@@ -65,13 +65,21 @@
      */
     public Lock lock(NodeImpl node, boolean isDeep, boolean isSessionScoped)
             throws LockException, RepositoryException {
+        return lock(node, isDeep, isSessionScoped, Long.MAX_VALUE, null);
+    }
 
+    /**
+     * @see LockManager#lock(NodeImpl, boolean, boolean, long, String)
+     */
+    public Lock lock(NodeImpl node, boolean isDeep, boolean isSessionScoped, long timoutHint, String ownerInfo)
+            throws LockException, RepositoryException {
         AbstractLockInfo info;
         if (isInXA()) {
-            info = xaEnv.lock(node, isDeep, isSessionScoped);
+            info = xaEnv.lock(node, isDeep, isSessionScoped, timoutHint, ownerInfo);
         } else {
-            info = lockMgr.internalLock(node, isDeep, isSessionScoped);
+            info = lockMgr.internalLock(node, isDeep, isSessionScoped, timoutHint, ownerInfo);
         }
+        lockMgr.writeLockProperties(node, info.lockOwner, info.deep);
         return new XALock(this, info, node);
     }
 
@@ -118,10 +126,11 @@
      * {@inheritDoc}
      */
     public void unlock(NodeImpl node) throws LockException, RepositoryException {
+        lockMgr.removeLockProperties(node);
         if (isInXA()) {
             xaEnv.unlock(node);
         } else {
-            lockMgr.unlock(node);
+            lockMgr.internalUnlock(node);
         }
     }
 

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AbstractAccessControlManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AbstractAccessControlManager.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AbstractAccessControlManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AbstractAccessControlManager.java Thu Jan  8 03:52:38 2009
@@ -22,6 +22,7 @@
 import org.apache.jackrabbit.api.jsr283.security.AccessControlPolicyIterator;
 import org.apache.jackrabbit.api.jsr283.security.Privilege;
 import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry;
+import org.apache.jackrabbit.core.security.authorization.Permission;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -72,7 +73,7 @@
      */
     public AccessControlPolicy[] getPolicies(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
         checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.READ_AC);
+        checkPermission(absPath, Permission.READ_AC);
 
         log.debug("Implementation does not provide applicable policies -> getPolicy() always returns an empty array.");
         return new AccessControlPolicy[0];
@@ -87,7 +88,7 @@
      */
     public AccessControlPolicyIterator getApplicablePolicies(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
         checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.READ_AC);
+        checkPermission(absPath, Permission.READ_AC);
 
         log.debug("Implementation does not provide applicable policies -> returning empty iterator.");
         return AccessControlPolicyIteratorAdapter.EMPTY;
@@ -100,7 +101,7 @@
      */
     public void setPolicy(String absPath, AccessControlPolicy policy) throws PathNotFoundException, AccessControlException, AccessDeniedException, RepositoryException {
         checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.MODIFY_AC);
+        checkPermission(absPath, Permission.MODIFY_AC);
 
         throw new AccessControlException("AccessControlPolicy " + policy + " cannot be applied.");
     }
@@ -112,7 +113,7 @@
      */
     public void removePolicy(String absPath, AccessControlPolicy policy) throws PathNotFoundException, AccessControlException, AccessDeniedException, RepositoryException {
         checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.MODIFY_AC);
+        checkPermission(absPath, Permission.MODIFY_AC);
 
         throw new AccessControlException("No AccessControlPolicy has been set through this API -> Cannot be removed.");
     }
@@ -139,14 +140,14 @@
      * Check if the specified privileges are granted at <code>absPath</code>.
      *
      * @param absPath
-     * @param privileges
+     * @param permission
      * @throws AccessDeniedException if the session does not have the
      * specified privileges.
      * @throws PathNotFoundException if no node exists at <code>absPath</code>
-     * of if the session does not have the privilege to READ it.
+     * of if the session does not have the permission to READ it.
      * @throws RepositoryException
      */
-    protected abstract void checkPrivileges(String absPath, int privileges) throws AccessDeniedException, PathNotFoundException, RepositoryException;
+    protected abstract void checkPermission(String absPath, int permission) throws AccessDeniedException, PathNotFoundException, RepositoryException;
 
     /**
      * @return the privilege registry

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AccessManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AccessManager.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AccessManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AccessManager.java Thu Jan  8 03:52:38 2009
@@ -106,6 +106,19 @@
             throws AccessDeniedException, ItemNotFoundException, RepositoryException;
 
     /**
+     *      * Determines whether the specified <code>permissions</code> are granted
+     * on the item with the specified <code>id</code> (i.e. the <i>target</i> item).
+     *
+     * @param absPath
+     * @param permissions A combination of one or more of the
+     * {@link org.apache.jackrabbit.core.security.authorization.Permission}
+     * constants encoded as a bitmask value.
+     * @throws AccessDeniedException if permission is denied
+     * @throws RepositoryException   it another error occurs
+     */
+    void checkPermission(Path absPath, int permissions) throws AccessDeniedException, RepositoryException;
+    
+    /**
      * Determines whether the specified <code>permissions</code> are granted
      * on the item with the specified <code>id</code> (i.e. the <i>target</i> item).
      *
@@ -131,15 +144,9 @@
      * item, that may or may not yet exist).
      *
      * @param absPath     the absolute path to test
-     * @param permissions A combination of one or more of the following constants
-     *                    encoded as a bitmask value:
-     * <ul>
-     * <li>{@link org.apache.jackrabbit.core.security.authorization.Permission#READ READ}</li>
-     * <li>{@link org.apache.jackrabbit.core.security.authorization.Permission#ADD_NODE ADD_NODE}</code></li>
-     * <li>{@link org.apache.jackrabbit.core.security.authorization.Permission#REMOVE_NODE REMOVE_NODE}</li>
-     * <li>{@link org.apache.jackrabbit.core.security.authorization.Permission#SET_PROPERTY SET_PROPERTY}</li>
-     * <li>{@link org.apache.jackrabbit.core.security.authorization.Permission#REMOVE_PROPERTY REMOVE_PROPERTY}</li>
-     * </ul>
+     * @param permissions A combination of one or more of the
+     * {@link org.apache.jackrabbit.core.security.authorization.Permission}
+     * constants encoded as a bitmask value.
      * @return <code>true</code> if the specified permissions are granted;
      * otherwise <code>false</code>.
      * @throws RepositoryException if an error occurs.
@@ -154,15 +161,9 @@
      *
      * @param parentPath  Path to an existing parent node.
      * @param childName   Name of the child item that may or may not exist yet.
-     * @param permissions A combination of one or more of the following constants
-     *                    encoded as a bitmask value:
-     * <ul>
-     * <li>{@link org.apache.jackrabbit.core.security.authorization.Permission#READ READ}</li>
-     * <li>{@link org.apache.jackrabbit.core.security.authorization.Permission#ADD_NODE ADD_NODE}</code></li>
-     * <li>{@link org.apache.jackrabbit.core.security.authorization.Permission#REMOVE_NODE REMOVE_NODE}</li>
-     * <li>{@link org.apache.jackrabbit.core.security.authorization.Permission#SET_PROPERTY SET_PROPERTY}</li>
-     * <li>{@link org.apache.jackrabbit.core.security.authorization.Permission#REMOVE_PROPERTY REMOVE_PROPERTY}</li>
-     * </ul>
+     * @param permissions A combination of one or more of the
+     * {@link org.apache.jackrabbit.core.security.authorization.Permission}
+     * constants encoded as a bitmask value.
      * @return <code>true</code> if the specified permissions are granted;
      * otherwise <code>false</code>.
      * @throws RepositoryException if an error occurs.

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/DefaultAccessManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/DefaultAccessManager.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/DefaultAccessManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/DefaultAccessManager.java Thu Jan  8 03:52:38 2009
@@ -187,7 +187,16 @@
      */
     public void checkPermission(ItemId id, int permissions) throws AccessDeniedException, ItemNotFoundException, RepositoryException {
         if (!isGranted(id, permissions)) {
-            throw new AccessDeniedException("Not sufficient privileges for permissions : " + permissions + " on " + id);
+            throw new AccessDeniedException("Access denied.");
+        }
+    }
+
+    /**
+     * @see AccessManager#checkPermission(Path, int)
+     */
+    public void checkPermission(Path absPath, int permissions) throws AccessDeniedException, RepositoryException {
+        if (!isGranted(absPath, permissions)) {
+            throw new AccessDeniedException("Access denied.");
         }
     }
 
@@ -268,11 +277,12 @@
         checkValidNodePath(absPath);
         if (privileges == null || privileges.length == 0) {
             // null or empty privilege array -> return true
-            log.debug("No privileges defined for hasPrivilege test.");
+            log.debug("No privileges passed -> allowed.");
             return true;
         } else {
-            int privs = privilegeRegistry.getBits(privileges);
-            return internalHasPrivileges(absPath, privs);
+            int privs = PrivilegeRegistry.getBits(privileges);
+            Path p = resolver.getQPath(absPath);
+            return (compiledPermissions.getPrivileges(p) | ~privs) == -1;
         }
     }
 
@@ -293,7 +303,7 @@
      */
     public AccessControlPolicy[] getPolicies(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
         checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.READ_AC);
+        checkPermission(absPath, Permission.READ_AC);
 
         AccessControlPolicy[] policies;
         if (editor != null) {
@@ -309,7 +319,7 @@
      */
     public AccessControlPolicy[] getEffectivePolicies(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
         checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.READ_AC);
+        checkPermission(absPath, Permission.READ_AC);
 
         // TODO: acProvider may not retrieve the correct policy in case of transient modifications
         return acProvider.getEffectivePolicies(getPath(absPath));
@@ -320,7 +330,7 @@
      */
     public AccessControlPolicyIterator getApplicablePolicies(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
         checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.READ_AC);
+        checkPermission(absPath, Permission.READ_AC);
 
         if (editor != null) {
             try {
@@ -339,7 +349,7 @@
      */
     public void setPolicy(String absPath, AccessControlPolicy policy) throws PathNotFoundException, AccessControlException, AccessDeniedException, RepositoryException {
         checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.MODIFY_AC);
+        checkPermission(absPath, Permission.MODIFY_AC);
         if (editor == null) {
             throw new UnsupportedRepositoryOperationException("Modification of AccessControlPolicies is not supported. ");
         }
@@ -351,7 +361,7 @@
      */
     public void removePolicy(String absPath, AccessControlPolicy policy) throws PathNotFoundException, AccessControlException, AccessDeniedException, RepositoryException {
         checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.MODIFY_AC);
+        checkPermission(absPath, Permission.MODIFY_AC);
         if (editor == null) {
             throw new UnsupportedRepositoryOperationException("Removal of AccessControlPolicies is not supported.");
         }
@@ -394,11 +404,12 @@
     }
 
     /**
-     * @see AbstractAccessControlManager#checkPrivileges(String, int)
+     * @see AbstractAccessControlManager#checkPermission(String,int)
      */
-    protected void checkPrivileges(String absPath, int privileges) throws AccessDeniedException, RepositoryException {
+    protected void checkPermission(String absPath, int permission) throws AccessDeniedException, RepositoryException {
         checkValidNodePath(absPath);
-        if (!internalHasPrivileges(absPath, privileges)) {
+        Path p = resolver.getQPath(absPath);
+        if (!compiledPermissions.grants(p, permission)) {
             throw new AccessDeniedException("Access denied at " + absPath);
         }
     }
@@ -412,18 +423,6 @@
     }
 
     //------------------------------------------------------------< private >---
-    /**
-     *
-     * @param absPath
-     * @param privileges
-     * @return
-     * @throws RepositoryException
-     */
-    private boolean internalHasPrivileges(String absPath, int privileges) throws RepositoryException {
-        Path p = resolver.getQPath(absPath);
-        return (compiledPermissions.getPrivileges(p) | ~privileges) == -1;
-    }
-
     private Path getPath(String absPath) throws RepositoryException {
         return resolver.getQPath(absPath);
     }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/SimpleJBossAccessManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/SimpleJBossAccessManager.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/SimpleJBossAccessManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/SimpleJBossAccessManager.java Thu Jan  8 03:52:38 2009
@@ -104,6 +104,12 @@
         }
     }
 
+    public void checkPermission(Path absPath, int permissions) throws AccessDeniedException, RepositoryException {
+        if (!isGranted(absPath, permissions)) {
+            throw new AccessDeniedException("Access denied");
+        }
+    }
+
     public boolean isGranted(ItemId id, int permissions) throws RepositoryException {
         // system has always all permissions
         // anonymous has only READ premissions

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractAccessControlProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractAccessControlProvider.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractAccessControlProvider.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractAccessControlProvider.java Thu Jan  8 03:52:38 2009
@@ -21,6 +21,7 @@
 import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
 import org.apache.jackrabbit.spi.Path;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
+import org.apache.jackrabbit.api.jsr283.security.Privilege;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -48,6 +49,9 @@
     protected ObservationManager observationMgr;
     protected NamePathResolver resolver;
 
+    protected int privAll;
+    protected int privRead;
+
     private boolean initialized;
 
     protected AbstractAccessControlProvider() {
@@ -65,15 +69,15 @@
 
     /**
      * Returns compiled permissions for the administrator i.e. permissions
-     * that grants everything and returns {@link PrivilegeRegistry#ALL}
+     * that grants everything and returns the int representation of {@link Privilege#JCR_ALL}
      * upon {@link CompiledPermissions#getPrivileges(Path)} for all
      * paths.
      *
      * @return an implementation of <code>CompiledPermissions</code> that
-     * grants everything and always returns {@link PrivilegeRegistry#ALL}
-     * upon {@link CompiledPermissions#getPrivileges(Path)}.
+     * grants everything and always returns the int representation of
+     * {@link Privilege#JCR_ALL} upon {@link CompiledPermissions#getPrivileges(Path)}.
      */
-    protected static CompiledPermissions getAdminPermissions() {
+    protected CompiledPermissions getAdminPermissions() {
         return new CompiledPermissions() {
             public void close() {
                 //nop
@@ -82,7 +86,7 @@
                 return true;
             }
             public int getPrivileges(Path absPath) {
-                return PrivilegeRegistry.ALL;
+                return privAll;
             }
             public boolean canReadAll() {
                 return true;
@@ -114,7 +118,7 @@
                 if (isAcItem(absPath)) {
                     return PrivilegeRegistry.NO_PRIVILEGE;
                 } else {
-                    return PrivilegeRegistry.READ;
+                    return privRead;
                 }
             }
             public boolean canReadAll() {
@@ -165,6 +169,10 @@
         session = (SessionImpl) systemSession;
         observationMgr = systemSession.getWorkspace().getObservationManager();
         resolver = (SessionImpl) systemSession;
+
+        privAll = PrivilegeRegistry.getBits(new Privilege[] {session.getAccessControlManager().privilegeFromName(Privilege.JCR_ALL)});
+        privRead = PrivilegeRegistry.getBits(new Privilege[] {session.getAccessControlManager().privilegeFromName(Privilege.JCR_READ)});
+
         initialized = true;
     }
 

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlEntryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlEntryImpl.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlEntryImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlEntryImpl.java Thu Jan  8 03:52:38 2009
@@ -96,9 +96,15 @@
         if (principal == null) {
             throw new IllegalArgumentException();
         }
+        // make sure no abstract privileges are passed.
+        for (int i = 0; i < privileges.length; i++) {
+            if (privileges[i].isAbstract()) {
+                throw new AccessControlException("Privilege " + privileges[i] + " is abstract.");
+            }
+        }
         this.principal = principal;
         this.privileges = privileges;
-        this.privilegeBits = PrivilegeRegistry.getBits(privileges);;
+        this.privilegeBits = PrivilegeRegistry.getBits(privileges);
         this.allow = isAllow;
         if (restrictions == null) {
             this.restrictions = Collections.EMPTY_MAP;
@@ -122,6 +128,13 @@
     }
 
     /**
+     * @return the int representation of the privileges defined for this entry.
+     */
+    public int getPrivilegeBits() {
+        return privilegeBits;
+    }
+
+    /**
      * Build the hash code.
      *
      * @return the hash code.
@@ -160,13 +173,6 @@
     }
 
     /**
-     * @see JackrabbitAccessControlEntry#getPrivilegeBits()
-     */
-    public int getPrivilegeBits() {
-        return privilegeBits;
-    }
-
-    /**
      * @see JackrabbitAccessControlEntry#getRestrictionNames()
      */
     public String[] getRestrictionNames() {
@@ -196,10 +202,6 @@
     }
 
     /**
-     * Returns true if the principal and all privileges are equal / the same.
-     *
-     * @param obj
-     * @return
      * @see Object#equals(Object)
      */
     public boolean equals(Object obj) {

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/CompiledPermissions.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/CompiledPermissions.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/CompiledPermissions.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/CompiledPermissions.java Thu Jan  8 03:52:38 2009
@@ -50,10 +50,11 @@
     boolean grants(Path absPath, int permissions) throws RepositoryException;
 
     /**
-     * Returns the <code>Privilege</code>s granted by the underlying policy
+     * Returns the <code>Privilege</code> bits granted by the underlying policy
      * if the given <code>absPath</code> denotes an existing <code>Node</code>,
      * otherwise it returns zero.
      *
+     * @param absPath Absolute path to a <code>Node</code>.
      * @return the granted privileges at <code>absPath</code> or zero if
      * the path does not denote an existing <code>Node</code>.
      * @throws RepositoryException if an error occurs

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/JackrabbitAccessControlEntry.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/JackrabbitAccessControlEntry.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/JackrabbitAccessControlEntry.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/JackrabbitAccessControlEntry.java Thu Jan  8 03:52:38 2009
@@ -34,12 +34,6 @@
     boolean isAllow();
 
     /**
-     * @return the int representation of the privileges defined for this entry.
-     * @see #getPrivileges()
-     */
-    int getPrivilegeBits();
-
-    /**
      * Return the names of the restrictions present with this access control entry.
      *
      * @return the names of the restrictions

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/Permission.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/Permission.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/Permission.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/Permission.java Thu Jan  8 03:52:38 2009
@@ -33,71 +33,21 @@
 
     public static final int REMOVE_PROPERTY = 16;
 
-    public static final int ALL = (READ | SET_PROPERTY | ADD_NODE | REMOVE_NODE | REMOVE_PROPERTY);
+    public static final int READ_AC = 32;
+    
+    public static final int MODIFY_AC = 64;
 
-    /**
-     * Build the permissions granted by evaluating the given privileges. If
-     * <code>protectesPolicy</code> is <code>true</code> read and write
-     * permission are only granted if the corresponding ac-privilege is
-     * present.
-     *
-     * @param privs The privileges granted on the Node itself (for properties
-     * the ACL of the direct ancestor).
-     * @param parentPrivs The privileges granted on the parent of the Node. Not
-     * relevant for properties since it only is used to determine permissions
-     * on a Node (add_child_nodes, remove_child_nodes).
-     * @param isAllow
-     * @param protectsPolicy
-     * @return the permissions granted evaluating the given privileges.
-     */
-    public static int calculatePermissions(int privs, int parentPrivs,
-                                           boolean isAllow, boolean protectsPolicy) {
-        int perm = Permission.NONE;
-        if (protectsPolicy) {
-            if ((parentPrivs & PrivilegeRegistry.READ_AC) == PrivilegeRegistry.READ_AC) {
-                perm |= Permission.READ;
-            }
-            if ((parentPrivs & PrivilegeRegistry.MODIFY_AC) == PrivilegeRegistry.MODIFY_AC) {
-                perm |= Permission.ADD_NODE;
-                perm |= Permission.SET_PROPERTY;
-                perm |= Permission.REMOVE_NODE;
-                perm |= Permission.REMOVE_PROPERTY;
-            }
-        } else {
-            if ((privs & PrivilegeRegistry.READ) == PrivilegeRegistry.READ) {
-                perm |= Permission.READ;
-            }
-            if ((privs & PrivilegeRegistry.MODIFY_PROPERTIES) == PrivilegeRegistry.MODIFY_PROPERTIES) {
-                perm |= Permission.SET_PROPERTY;
-                perm |= Permission.REMOVE_PROPERTY;
-            }
-            // add_node permission is granted through privilege on the parent.
-            if ((parentPrivs & PrivilegeRegistry.ADD_CHILD_NODES) == PrivilegeRegistry.ADD_CHILD_NODES) {
-                perm |= Permission.ADD_NODE;
-            }
-            /*
-             remove_node is
-             allowed: only if remove_child_nodes privilege is present on
-                      the parent AND remove_node is present on the node itself
-             denied : if either remove_child_nodes is denied on the parent
-                      OR remove_node is denied on the node itself.
-            */
-            if (isAllow) {
-                if ((parentPrivs & PrivilegeRegistry.REMOVE_CHILD_NODES) ==
-                        PrivilegeRegistry.REMOVE_CHILD_NODES &&
-                        (privs & PrivilegeRegistry.REMOVE_NODE) == PrivilegeRegistry.REMOVE_NODE) {
-                    perm |= Permission.REMOVE_NODE;
-                }
-            } else {
-                if ((parentPrivs & PrivilegeRegistry.REMOVE_CHILD_NODES) ==
-                        PrivilegeRegistry.REMOVE_CHILD_NODES ||
-                        (privs & PrivilegeRegistry.REMOVE_NODE) == PrivilegeRegistry.REMOVE_NODE) {
-                    perm |= Permission.REMOVE_NODE;
-                }
-            }
-        }
-        return perm;
-    }
+    public static final int NODE_TYPE_MNGMT = 128;
+
+    public static final int VERSION_MNGMT = 256;
+
+    public static final int LOCK_MNGMT = 512;
+
+    public static final int LIFECYCLE_MNGMT = 1024;
+
+    public static final int RETENTION_MNGMT = 2048;
+
+    public static final int ALL = (READ | SET_PROPERTY | ADD_NODE | REMOVE_NODE | REMOVE_PROPERTY | READ_AC | MODIFY_AC | NODE_TYPE_MNGMT | VERSION_MNGMT | LOCK_MNGMT | LIFECYCLE_MNGMT | RETENTION_MNGMT);
 
     /**
      * Returns those bits from <code>permissions</code> that are not present in

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/PrivilegeRegistry.java Thu Jan  8 03:52:38 2009
@@ -40,40 +40,77 @@
  */
 public final class PrivilegeRegistry {
 
-    private static final Set REGISTERED_PRIVILEGES = new HashSet(10);
+    /**
+     * Jackrabbit specific write privilege that combines {@link Privilege#JCR_WRITE}
+     * and {@link Privilege#NODE_TYPE_MNGMT}.
+     */
+    public static final String REP_WRITE = "{" + Name.NS_REP_URI + "}write";
+
+    private static final Set REGISTERED_PRIVILEGES = new HashSet(20);
     private static final Map BITS_TO_PRIVILEGES = new HashMap();
     private static final NameFactory NAME_FACTORY = NameFactoryImpl.getInstance();
 
     private static final Privilege[] EMPTY_ARRAY = new Privilege[0];
 
     public static final int NO_PRIVILEGE = 0;
-    public static final int READ = 1;
-    public static final int MODIFY_PROPERTIES = 2;
-    public static final int ADD_CHILD_NODES = 4;
-    public static final int REMOVE_CHILD_NODES = 8;
-    public static final int REMOVE_NODE = 16;
-    public static final int READ_AC = 32;
-    public static final int MODIFY_AC = 64;
-    public static final int WRITE = 14;
-    public static final int ALL = 127;
+
+    private static final int READ = 1;
+    private static final int MODIFY_PROPERTIES = 2;
+    private static final int ADD_CHILD_NODES = 4;
+    private static final int REMOVE_CHILD_NODES = 8;
+    private static final int REMOVE_NODE = 16;
+    
+    private static final int READ_AC = 32;
+    private static final int MODIFY_AC = 64;
+
+    private static final int NODE_TYPE_MNGMT = 128;
+    private static final int VERSION_MNGMT = 256;
+    private static final int LOCK_MNGMT = 512;
+    private static final int LIFECYCLE_MNGMT = 1024;
+    private static final int RETENTION_MNGMT = 2048;
+
+    private static final int WRITE = 30;
+    private static final int JACKRABBIT_WRITE = 158;
+    private static final int ALL = 4095;
 
     private static final InternalPrivilege READ_PRIVILEGE = registerPrivilege(new InternalPrivilege(Privilege.JCR_READ, READ));
     private static final InternalPrivilege MODIFY_PROPERTIES_PRIVILEGE = registerPrivilege(new InternalPrivilege(Privilege.JCR_MODIFY_PROPERTIES, MODIFY_PROPERTIES));
     private static final InternalPrivilege ADD_CHILD_NODES_PRIVILEGE = registerPrivilege(new InternalPrivilege(Privilege.JCR_ADD_CHILD_NODES, ADD_CHILD_NODES));
     private static final InternalPrivilege REMOVE_CHILD_NODES_PRIVILEGE = registerPrivilege(new InternalPrivilege(Privilege.JCR_REMOVE_CHILD_NODES, REMOVE_CHILD_NODES));
     private static final InternalPrivilege REMOVE_NODE_PRIVILEGE = registerPrivilege(new InternalPrivilege(Privilege.JCR_REMOVE_NODE, REMOVE_NODE));
+
     private static final InternalPrivilege READ_AC_PRIVILEGE = registerPrivilege(new InternalPrivilege(Privilege.JCR_READ_ACCESS_CONTROL, READ_AC));
     private static final InternalPrivilege MODIFY_AC_PRIVILEGE = registerPrivilege(new InternalPrivilege(Privilege.JCR_MODIFY_ACCESS_CONTROL, MODIFY_AC));
+
+    private static final InternalPrivilege NODE_TYPE_MANAGEMENT_PRIVILEGE = registerPrivilege(new InternalPrivilege(Privilege.JCR_NODE_TYPE_MANAGEMENT, NODE_TYPE_MNGMT));
+    private static final InternalPrivilege VERSION_MANAGEMENT_PRIVILEGE = registerPrivilege(new InternalPrivilege(Privilege.JCR_VERSION_MANAGEMENT, VERSION_MNGMT));
+    private static final InternalPrivilege LOCK_MANAGEMENT_PRIVILEGE = registerPrivilege(new InternalPrivilege(Privilege.JCR_LOCK_MANAGEMENT, LOCK_MNGMT));
+    private static final InternalPrivilege LIFECYCLE_MANAGEMENT_PRIVILEGE = registerPrivilege(new InternalPrivilege(Privilege.JCR_LIFECYCLE_MANAGEMENT, LIFECYCLE_MNGMT));
+    private static final InternalPrivilege RETENTION_MANAGEMENT_PRIVILEGE = registerPrivilege(new InternalPrivilege(Privilege.JCR_RETENTION_MANAGEMENT, RETENTION_MNGMT));
+
     private static final InternalPrivilege WRITE_PRIVILEGE = registerPrivilege(new InternalPrivilege(Privilege.JCR_WRITE, new InternalPrivilege[] {
             MODIFY_PROPERTIES_PRIVILEGE,
             ADD_CHILD_NODES_PRIVILEGE,
-            REMOVE_CHILD_NODES_PRIVILEGE }));
+            REMOVE_CHILD_NODES_PRIVILEGE,
+            REMOVE_NODE_PRIVILEGE,
+    }));
+
+    private static final InternalPrivilege JACKRABBIT_WRITE_PRIVILEGE = registerPrivilege(new InternalPrivilege(REP_WRITE, new InternalPrivilege[] {
+            WRITE_PRIVILEGE,
+            NODE_TYPE_MANAGEMENT_PRIVILEGE
+    }));
+
     private static final InternalPrivilege ALL_PRIVILEGE = registerPrivilege(new InternalPrivilege(Privilege.JCR_ALL, new InternalPrivilege[] {
             READ_PRIVILEGE,
             WRITE_PRIVILEGE,
-            REMOVE_NODE_PRIVILEGE,
+            JACKRABBIT_WRITE_PRIVILEGE,
             READ_AC_PRIVILEGE,
-            MODIFY_AC_PRIVILEGE}));
+            MODIFY_AC_PRIVILEGE,
+            VERSION_MANAGEMENT_PRIVILEGE,
+            LOCK_MANAGEMENT_PRIVILEGE,
+            LIFECYCLE_MANAGEMENT_PRIVILEGE,
+            RETENTION_MANAGEMENT_PRIVILEGE
+    }));
 
     /**
      * The name resolver used to determine the correct privilege
@@ -180,6 +217,88 @@
     }
 
     /**
+     * Build the permissions granted by evaluating the given privileges.
+     *
+     * @param privs The privileges granted on the Node itself (for properties
+     * the ACL of the direct ancestor).
+     * @param parentPrivs The privileges granted on the parent of the Node. Not
+     * relevant for properties since it only is used to determine permissions
+     * on a Node (add_child_nodes, remove_child_nodes).
+     * @param isAllow
+     * @param protectsPolicy
+     * @return the permissions granted evaluating the given privileges.
+     */
+    public static int calculatePermissions(int privs, int parentPrivs, boolean isAllow, boolean protectsPolicy) {
+        int perm = Permission.NONE;
+        if (protectsPolicy) {
+            if ((parentPrivs & PrivilegeRegistry.READ_AC) == PrivilegeRegistry.READ_AC) {
+                perm |= Permission.READ;
+            }
+            if ((parentPrivs & PrivilegeRegistry.MODIFY_AC) == PrivilegeRegistry.MODIFY_AC) {
+                perm |= Permission.ADD_NODE;
+                perm |= Permission.SET_PROPERTY;
+                perm |= Permission.REMOVE_NODE;
+                perm |= Permission.REMOVE_PROPERTY;
+                perm |= Permission.NODE_TYPE_MNGMT;
+            }
+        } else {
+            if ((privs & READ) == READ) {
+                perm |= Permission.READ;
+            }
+            if ((privs & MODIFY_PROPERTIES) == MODIFY_PROPERTIES) {
+                perm |= Permission.SET_PROPERTY;
+                perm |= Permission.REMOVE_PROPERTY;
+            }
+            // add_node permission is granted through privilege on the parent.
+            if ((parentPrivs & ADD_CHILD_NODES) == ADD_CHILD_NODES) {
+                perm |= Permission.ADD_NODE;
+            }
+            /*
+             remove_node is
+             allowed: only if remove_child_nodes privilege is present on
+                      the parent AND remove_node is present on the node itself
+             denied : if either remove_child_nodes is denied on the parent
+                      OR remove_node is denied on the node itself.
+            */
+            if (isAllow) {
+                if ((parentPrivs & REMOVE_CHILD_NODES) == REMOVE_CHILD_NODES &&
+                        (privs & REMOVE_NODE) == REMOVE_NODE) {
+                    perm |= Permission.REMOVE_NODE;
+                }
+            } else {
+                if ((parentPrivs & REMOVE_CHILD_NODES) == REMOVE_CHILD_NODES ||
+                        (privs & REMOVE_NODE) == REMOVE_NODE) {
+                    perm |= Permission.REMOVE_NODE;
+                }
+            }
+        }
+
+        // the remaining (special) permissions are simply defined on the node
+        if ((privs & READ_AC) == READ_AC) {
+            perm |= Permission.READ_AC;
+        }
+        if ((privs & MODIFY_AC) == MODIFY_AC) {
+            perm |= Permission.MODIFY_AC;
+        }
+        if ((privs & LIFECYCLE_MNGMT) == LIFECYCLE_MNGMT) {
+            perm |= Permission.LIFECYCLE_MNGMT;
+        }
+        if ((privs & LOCK_MNGMT) == LOCK_MNGMT) {
+            perm |= Permission.LOCK_MNGMT;
+        }
+        if ((privs & NODE_TYPE_MNGMT) == NODE_TYPE_MNGMT) {
+            perm |= Permission.NODE_TYPE_MNGMT;
+        }
+        if ((privs & RETENTION_MNGMT) == RETENTION_MNGMT) {
+            perm |= Permission.RETENTION_MNGMT;
+        }
+        if ((privs & VERSION_MNGMT) == VERSION_MNGMT) {
+            perm |= Permission.VERSION_MNGMT;
+        }
+        return perm;
+    }
+    
+    /**
      *
      * @param bits
      * @return InternalPrivilege that corresponds to the given bits.
@@ -193,7 +312,9 @@
             if ((bits & READ) == READ) {
                 privileges.add(READ_PRIVILEGE);
             }
-            if ((bits & WRITE) == WRITE) {
+            if ((bits & JACKRABBIT_WRITE) == JACKRABBIT_WRITE) {
+                privileges.add(JACKRABBIT_WRITE_PRIVILEGE);
+            } else if ((bits & WRITE) == WRITE) {
                 privileges.add(WRITE_PRIVILEGE);
             } else {
                 if ((bits & MODIFY_PROPERTIES) == MODIFY_PROPERTIES) {
@@ -205,9 +326,12 @@
                 if ((bits & REMOVE_CHILD_NODES) == REMOVE_CHILD_NODES) {
                     privileges.add(REMOVE_CHILD_NODES_PRIVILEGE);
                 }
-            }
-            if ((bits & REMOVE_NODE) == REMOVE_NODE) {
-                privileges.add(REMOVE_NODE_PRIVILEGE);
+                if ((bits & REMOVE_NODE) == REMOVE_NODE) {
+                    privileges.add(REMOVE_NODE_PRIVILEGE);
+                }
+                if ((bits & NODE_TYPE_MNGMT) == NODE_TYPE_MNGMT) {
+                    privileges.add(NODE_TYPE_MANAGEMENT_PRIVILEGE);
+                }
             }
             if ((bits & READ_AC) == READ_AC) {
                 privileges.add(READ_AC_PRIVILEGE);
@@ -215,6 +339,18 @@
             if ((bits & MODIFY_AC) == MODIFY_AC) {
                 privileges.add(MODIFY_AC_PRIVILEGE);
             }
+            if ((bits & VERSION_MNGMT) == VERSION_MNGMT) {
+                privileges.add(VERSION_MANAGEMENT_PRIVILEGE);
+            }
+            if ((bits & LOCK_MNGMT) == LOCK_MNGMT) {
+                privileges.add(LOCK_MANAGEMENT_PRIVILEGE);
+            }
+            if ((bits & LIFECYCLE_MNGMT) == LIFECYCLE_MNGMT) {
+                privileges.add(LIFECYCLE_MANAGEMENT_PRIVILEGE);
+            }
+            if ((bits & RETENTION_MNGMT) == RETENTION_MNGMT) {
+                privileges.add(RETENTION_MANAGEMENT_PRIVILEGE);
+            }
 
             InternalPrivilege[] privs;
             if (!privileges.isEmpty()) {
@@ -241,7 +377,7 @@
     private static class InternalPrivilege {
 
         private final Name name;
-        private final boolean isAbstract = false;
+        private final boolean isAbstract;
         private final boolean isAggregate;
         private final InternalPrivilege[] declaredAggregates;
         private final Set aggregates;
@@ -258,6 +394,7 @@
             this.name = NAME_FACTORY.create(name);
             this.bits = bits;
 
+            isAbstract = false;
             declaredAggregates = null;
             aggregates = null;
             isAggregate = false;
@@ -271,8 +408,8 @@
                 throw new IllegalArgumentException("A privilege must have a name.");
             }
             this.name = NAME_FACTORY.create(name);
+            this.isAbstract = false;
             this.declaredAggregates = declaredAggregates;
-
             Set aggrgt = new HashSet();
             int bts = 0;
             for (int i = 0; i < declaredAggregates.length; i++) {

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLEditor.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLEditor.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLEditor.java Thu Jan  8 03:52:38 2009
@@ -65,6 +65,7 @@
     private final AccessControlUtils utils;
 
     ACLEditor(Session editingSession, AccessControlUtils utils) {
+        super(true);
         if (editingSession instanceof SessionImpl) {
             session = ((SessionImpl) editingSession);
             // TODO: review and find better solution

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java Thu Jan  8 03:52:38 2009
@@ -38,7 +38,6 @@
 import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry;
 import org.apache.jackrabbit.core.security.authorization.UnmodifiableAccessControlList;
 import org.apache.jackrabbit.core.security.authorization.AccessControlEntryIterator;
-import org.apache.jackrabbit.core.security.authorization.JackrabbitAccessControlEntry;
 import org.apache.jackrabbit.core.security.principal.PrincipalImpl;
 import org.apache.jackrabbit.spi.Path;
 import org.apache.jackrabbit.spi.commons.name.PathFactoryImpl;
@@ -480,8 +479,8 @@
             int parentAllows = PrivilegeRegistry.NO_PRIVILEGE;
             int parentDenies = PrivilegeRegistry.NO_PRIVILEGE;
 
-            while (entries.hasNext() && allows != PrivilegeRegistry.ALL) {
-                JackrabbitAccessControlEntry ace = (JackrabbitAccessControlEntry) entries.next();
+            while (entries.hasNext() && allows != privAll) {
+                ACLTemplate.Entry ace = (ACLTemplate.Entry) entries.next();
                 // Determine if the ACE is defined on the node at absPath (locally):
                 // Except for READ-privileges the permissions must be determined
                 // from privileges defined for the parent. Consequently aces
@@ -497,11 +496,11 @@
                 }
                 if (ace.isAllow()) {
                     allowPrivileges |= Permission.diff(entryBits, denyPrivileges);
-                    int permissions = Permission.calculatePermissions(allowPrivileges, parentAllows, true, isAcItem);
+                    int permissions = PrivilegeRegistry.calculatePermissions(allowPrivileges, parentAllows, true, isAcItem);
                     allows |= Permission.diff(permissions, denies);
                 } else {
                     denyPrivileges |= Permission.diff(entryBits, allowPrivileges);
-                    int permissions = Permission.calculatePermissions(denyPrivileges, parentDenies, false, isAcItem);
+                    int permissions = PrivilegeRegistry.calculatePermissions(denyPrivileges, parentDenies, false, isAcItem);
                     denies |= Permission.diff(permissions, allows);
                 }
             }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLEditor.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLEditor.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLEditor.java Thu Jan  8 03:52:38 2009
@@ -60,6 +60,7 @@
     private final String acRootPath;
 
     ACLEditor(SessionImpl session, Path acRootPath) throws RepositoryException {
+        super(true);
         this.session = session;
         this.acRootPath = session.getJCRPath(acRootPath);
     }
@@ -69,13 +70,18 @@
             throw new AccessControlException("Unknown principal.");
         }
         String nPath = getPathToAcNode(principal);
+        ACLTemplate acl = null;
         if (session.nodeExists(nPath)) {
-            return (ACLTemplate) getPolicies(nPath)[0];
-        } else {
+            AccessControlPolicy[] plcs = getPolicies(nPath);
+            if (plcs.length > 0) {
+                acl = (ACLTemplate) plcs[0];
+            }
+        }
+        if (acl == null) {
             // no policy for the given principal
-            log.debug("No combined policy template for Principal " + principal.getName());
-            return null;
+            log.debug("No policy template for Principal " + principal.getName());
         }
+        return acl;
     }
 
     //------------------------------------------------< AccessControlEditor >---
@@ -86,7 +92,7 @@
         checkProtectsNode(nodePath);
 
         NodeImpl acNode = getAcNode(nodePath);
-        if (acNode != null) {
+        if (isAccessControlled(acNode)) {
             return new AccessControlPolicy[] {createTemplate(acNode)};
         } else {
             return new AccessControlPolicy[0];
@@ -121,10 +127,13 @@
             throw new AccessControlException("Unknown principal.");
         }
         String nPath = getPathToAcNode(principal);
+        NodeImpl acNode;
         if (!session.nodeExists(nPath)) {
-            createAcNode(nPath);
+            acNode = createAcNode(nPath);
+        } else {
+            acNode = (NodeImpl) session.getNode(nPath);
         }
-        return getPolicies(nPath);
+        return new AccessControlPolicy[] {createTemplate(acNode)};
     }
 
     /**
@@ -193,18 +202,16 @@
         checkValidPolicy(nodePath, policy);
 
         NodeImpl acNode = getAcNode(nodePath);
-        if (acNode != null) {
-            if (isAccessControlled(acNode)) {
-                // build the template in order to have a return value
-                AccessControlPolicy tmpl = createTemplate(acNode);
-                if (tmpl.equals(policy)) {
-                    removeSecurityItem(acNode.getNode(N_POLICY));
-                    return;
-                }
+        if (isAccessControlled(acNode)) {
+            // build the template in order to have a return value
+            AccessControlPolicy tmpl = createTemplate(acNode);
+            if (tmpl.equals(policy)) {
+                removeSecurityItem(acNode.getNode(N_POLICY));
+                return;
             }
         }
         // node either not access-controlled or the passed policy didn't apply
-        // to the node at 'nodePath' -> throw exception.no policy was removed
+        // to the node at 'nodePath' -> throw exception. no policy was removed
         throw new AccessControlException("Policy " + policy + " does not apply to " + nodePath);
     }
 
@@ -312,8 +319,8 @@
      * @return
      * @throws RepositoryException
      */
-    private boolean isAccessControlled(NodeImpl node) throws RepositoryException {
-        return node.isNodeType(NT_REP_ACCESS_CONTROL) && node.hasNode(N_POLICY);
+    private static boolean isAccessControlled(NodeImpl node) throws RepositoryException {
+        return node != null && node.isNodeType(NT_REP_ACCESS_CONTROL) && node.hasNode(N_POLICY);
     }
 
     /**
@@ -322,7 +329,7 @@
      * @return
      * @throws RepositoryException
      */
-    private AccessControlPolicy createTemplate(NodeImpl acNode) throws RepositoryException {
+    private static AccessControlPolicy createTemplate(NodeImpl acNode) throws RepositoryException {
         if (!acNode.isNodeType(NT_REP_ACCESS_CONTROL)) {
             throw new RepositoryException("Expected node of type rep:AccessControl.");
         }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java Thu Jan  8 03:52:38 2009
@@ -360,7 +360,7 @@
                     acPaths.add(editor.getPathToAcNode(princ));
                 } else {
                     // retrieve the ACEs from the node
-                    AccessControlEntry[] aces = (AccessControlEntry[]) acl.getAccessControlEntries();
+                    AccessControlEntry[] aces = acl.getAccessControlEntries();
                     allACEs.addAll(Arrays.asList(aces));
                     acPaths.add(acl.getPath());
                 }
@@ -426,11 +426,11 @@
                 if (matches) {
                     if (entr.isAllow()) {
                         allowPrivileges |= Permission.diff(privs, denyPrivileges);
-                        int permissions = Permission.calculatePermissions(allowPrivileges, parentAllows, true, isAcItem);
+                        int permissions = PrivilegeRegistry.calculatePermissions(allowPrivileges, parentAllows, true, isAcItem);
                         allows |= Permission.diff(permissions, denies);
                     } else {
                         denyPrivileges |= Permission.diff(privs, allowPrivileges);
-                        int permissions = Permission.calculatePermissions(denyPrivileges, parentDenies, false, isAcItem);
+                        int permissions = PrivilegeRegistry.calculatePermissions(denyPrivileges, parentDenies, false, isAcItem);
                         denies |= Permission.diff(permissions, allows);
                     }
                 }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLTemplate.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLTemplate.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLTemplate.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLTemplate.java Thu Jan  8 03:52:38 2009
@@ -277,8 +277,8 @@
             checkValidEntry();
 
             // TODO: review again
-            nodePath = ((Value) getRestriction(jcrNodePathName)).getString();
-            Value glob = ((Value) getRestriction(jcrGlobName));
+            nodePath = getRestriction(jcrNodePathName).getString();
+            Value glob = getRestriction(jcrGlobName);
             if (glob != null) {
                 StringBuffer b = new StringBuffer(nodePath);
                 b.append(glob.getString());

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java?rev=732693&r1=732692&r2=732693&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/simple/SimpleAccessManager.java Thu Jan  8 03:52:38 2009
@@ -131,6 +131,15 @@
     /**
      * {@inheritDoc}
      */
+    public void checkPermission(Path absPath, int permissions) throws AccessDeniedException, RepositoryException {
+        if (!isGranted(absPath, permissions)) {
+            throw new AccessDeniedException("Access denied");
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public boolean isGranted(ItemId id, int permissions) throws RepositoryException {
         checkInitialized();
         if (system) {
@@ -200,12 +209,11 @@
             // null or empty privilege array -> return true
             return true;
         } else {
-            int bits = privilegeRegistry.getBits(privileges);
             if (system) {
                 // system has always all permissions
                 return true;
             } else if (anonymous) {
-                if (bits != PrivilegeRegistry.READ) {
+                if (privileges.length != 1 || !privileges[0].equals(privilegeRegistry.getPrivilege(Privilege.JCR_READ))) {
                     // anonymous is only granted READ premissions
                     return false;
                 }
@@ -223,14 +231,16 @@
         checkInitialized();
         checkValidNodePath(absPath);
 
+        Privilege priv;
         if (anonymous) {
-            return privilegeRegistry.getPrivileges(PrivilegeRegistry.READ);
+            priv = privilegeRegistry.getPrivilege(Privilege.JCR_READ);
         } else if (system) {
-            return privilegeRegistry.getPrivileges(PrivilegeRegistry.ALL);
+            priv = privilegeRegistry.getPrivilege(Privilege.JCR_ALL);
         } else {
             // @todo check permission based on principals
-            return privilegeRegistry.getPrivileges(PrivilegeRegistry.ALL);
+            priv = privilegeRegistry.getPrivilege(Privilege.JCR_ALL);
         }
+        return new Privilege[] {priv};
     }
 
     /**
@@ -238,7 +248,7 @@
      */
     public AccessControlPolicy[] getEffectivePolicies(String absPath) throws PathNotFoundException, AccessDeniedException, RepositoryException {
         checkInitialized();
-        checkPrivileges(absPath, PrivilegeRegistry.READ_AC);
+        checkPermission(absPath, Permission.READ_AC);
 
         return new AccessControlPolicy[] {POLICY};
     }
@@ -254,11 +264,11 @@
     }
 
     /**
-     * @see AbstractAccessControlManager#checkPrivileges(String, int)
+     * @see AbstractAccessControlManager#checkPermission(String,int)
      */
-    protected void checkPrivileges(String absPath, int privileges) throws AccessDeniedException, PathNotFoundException, RepositoryException {
+    protected void checkPermission(String absPath, int permission) throws AccessDeniedException, PathNotFoundException, RepositoryException {
         checkValidNodePath(absPath);
-        if (anonymous && privileges != PrivilegeRegistry.READ) {
+        if (anonymous && permission != Permission.READ) {
             throw new AccessDeniedException("Anonymous may only READ.");
         }
     }



Mime
View raw message