You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2009/10/21 13:38:44 UTC

svn commit: r827966 [7/15] - in /jackrabbit/sandbox/JCR-1456: ./ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/management/ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/...

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserAccessControlProvider.java Wed Oct 21 11:38:31 2009
@@ -239,11 +239,14 @@
             return session.getProperty(absPath).getParent();
         } else {
             String pPath = Text.getRelativeParent(absPath, 1);
-            if (session.nodeExists(pPath)) {
-                return session.getNode(pPath);
-            } else {
-                throw new ItemNotFoundException("Unable to determine permissions: No item and no existing parent for target path " + absPath);
-            }
+            while (!"/".equals(pPath)) {
+                if (session.nodeExists(pPath)) {
+                    return session.getNode(pPath);
+                } else {
+                    pPath = Text.getRelativeParent(pPath, 1);
+                }
+            }         
+            throw new ItemNotFoundException("Unable to determine permissions: No item and no existing parent for target path " + absPath);
         }
     }
 

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserConstants.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserConstants.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserConstants.java Wed Oct 21 11:38:31 2009
@@ -46,9 +46,12 @@
      */
     String GROUP_ADMIN_GROUP_NAME = "GroupAdmin";
 
-    Name P_REFEREES = NF.create(Name.NS_REP_URI, "referees");
     Name P_PRINCIPAL_NAME = NF.create(Name.NS_REP_URI, "principalName");
-
+    /**
+     * @deprecated As of 2.0 the id-hash is stored with the jcr:uuid making the
+     * rep:userId property redundant. It has been removed from the node type
+     * definition.
+     */
     Name P_USERID = NF.create(Name.NS_REP_URI, "userId");
     Name P_PASSWORD = NF.create(Name.NS_REP_URI, "password");
 

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserImpl.java Wed Oct 21 11:38:31 2009
@@ -35,19 +35,14 @@
  */
 public class UserImpl extends AuthorizableImpl implements User {
 
-    private final String id;
-
     private Principal principal;
     private Impersonation impersonation;
 
     protected UserImpl(NodeImpl node, UserManagerImpl userManager) throws RepositoryException {
         super(node, userManager);
-
-        id = node.getProperty(P_USERID).getString();
     }
 
     //--------------------------------------------------------------------------
-
     /**
      *
      * @param password
@@ -65,20 +60,18 @@
         }
     }
 
-    //-------------------------------------------------------< Authorizable >---
-    /**
-     * @see org.apache.jackrabbit.api.security.user.Authorizable#getID()
-     */
-    public String getID() throws RepositoryException {
-        return id;
-    }
-
     //------------------------------------------------< User >------------------
     /**
      * @see User#isAdmin()
      */
     public boolean isAdmin() {
-        return userManager.isAdminId(id);
+        try {
+            return userManager.isAdminId(getID());
+        } catch (RepositoryException e) {
+            // should never get here
+            log.error("Internal error while retrieving UserID.", e);
+            return false;
+        }
     }
 
     /**
@@ -87,8 +80,7 @@
     public Credentials getCredentials() throws RepositoryException {
         try {
             String password = getNode().getProperty(P_PASSWORD).getString();
-            Credentials creds = new CryptedSimpleCredentials(getID(), password);
-            return creds;
+            return new CryptedSimpleCredentials(getID(), password);
         } catch (NoSuchAlgorithmException e) {
             throw new RepositoryException(e);
         } catch (UnsupportedEncodingException e) {

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/user/UserManagerImpl.java Wed Oct 21 11:38:31 2009
@@ -27,9 +27,9 @@
 import org.apache.jackrabbit.core.ProtectedItemModifier;
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.SessionListener;
+import org.apache.jackrabbit.core.id.NodeId;
 import org.apache.jackrabbit.core.security.principal.PrincipalImpl;
 import org.apache.jackrabbit.spi.Name;
-import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.apache.jackrabbit.util.Text;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -41,6 +41,8 @@
 import javax.jcr.NodeIterator;
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
+import javax.jcr.Session;
+import javax.jcr.ItemNotFoundException;
 import javax.jcr.lock.LockException;
 import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.version.VersionException;
@@ -50,6 +52,8 @@
 import java.util.NoSuchElementException;
 import java.util.Set;
 import java.util.Properties;
+import java.util.UUID;
+import java.io.UnsupportedEncodingException;
 
 /**
  * Default implementation of the <code>UserManager</code> interface with the
@@ -58,30 +62,33 @@
  * <ul>
  * <li>Users and Groups are stored in the repository as JCR nodes.</li>
  * <li>Users are created below {@link UserConstants#USERS_PATH},<br>Groups are
- * created below {@link UserConstants#GROUPS_PATH}.</li>
- * <li>In order to structure the users and groups tree and void creating a flat
+ * created below {@link UserConstants#GROUPS_PATH} (unless otherwise configured).</li>
+ * <li>The Id of an authorizable is stored in the jcr:uuid property (md5 hash).</li>
+ * <li>In order to structure the users and groups tree and avoid creating a flat
  * hierarchy, additional hierarchy nodes of type "rep:AuthorizableFolder" are
- * introduced.</li>
+ * introduced using
+ *    <ul>
+ *    <li>the specified intermediate path passed to the create methods</li>
+ *    <li>or some built-in logic if the intermediate path is missing.</li>
+ *    </ul>
+ * </li>
+ * </ul>
+ *
+ * The built-in logic applies the following rules:
+ * <ul>
  * <li>The names of the hierarchy folders is determined from ID of the
  * authorizable to be created, consisting of the leading N chars where N is
  * the relative depth starting from the node at {@link UserConstants#USERS_PATH}
  * or {@link UserConstants#GROUPS_PATH}.</li>
  * <li>By default 2 levels (depth == 2) are created.</li>
- * <li>Searching authorizables by ID always starts looking at that specific
- * hierarchy level. Parent nodes are expected to consist of folder structure only.</li>
+ * <li>Parent nodes are expected to consist of folder structure only.</li>
  * <li>If the ID contains invalid JCR chars that would prevent the creation of
  * a Node with that name, the names of authorizable node and the intermediate
  * hierarchy nodes are {@link Text#escapeIllegalJcrChars(String) escaped}.</li>
- * <li>Any intermediate path passed to either
- * {@link #createUser(String, String, Principal, String) createUser} or
- * {@link #createGroup(Principal, String) createGroup} are ignored. This allows
- * to directly find authorizables by ID without having to search or traverse
- * the complete tree.<br>
- * See also {@link #PARAM_COMPATIBILE_JR16}.
- * </li>
  * </ul>
- * Example: Creating an non-existing authorizable with ID 'aSmith' would result
- * in the following structure:
+ * Examples:
+ * Creating an non-existing user with ID 'aSmith' without specifying an
+ * intermediate path would result in the following structure:
  * 
  * <pre>
  * + rep:security            [nt:unstructured]
@@ -92,10 +99,26 @@
  *           + aSmith        [rep:User]
  * </pre>
  *
+ * Creating a non-existing user with ID 'aSmith' specifying an intermediate
+ * path 'some/tree' would result in the following structure:
+ *
+ * <pre>
+ * + rep:security            [nt:unstructured]
+ *   + rep:authorizables     [rep:AuthorizableFolder]
+ *     + rep:users           [rep:AuthorizableFolder]
+ *       + some              [rep:AuthorizableFolder]
+ *         + tree            [rep:AuthorizableFolder]
+ *           + aSmith        [rep:User]
+ * </pre>
+ *
  * This <code>UserManager</code> is able to handle the following configuration
  * options:
  *
  * <ul>
+ * <li>{@link #PARAM_USERS_PATH}: Defines where user nodes are created.
+ * If missing set to {@link #USERS_PATH}.</li>
+ * <li>{@link #PARAM_GROUPS_PATH}. Defines where group nodes are created.
+ * If missing set to {@link #GROUPS_PATH}.</li>
  * <li>{@link #PARAM_COMPATIBILE_JR16}: If the param is present and its
  * value is <code>true</code> looking up authorizables by ID will use the
  * <code>NodeResolver</code> if not found otherwise.<br>
@@ -103,23 +126,9 @@
  * with a Jackrabbit repository &lt; v2.0 will not be found any more.<br>
  * By default this option is disabled.</li>
  * <li>{@link #PARAM_DEFAULT_DEPTH}: Parameter used to change the number of
- * levels that are used by default store authorizable nodes.<br>The value is
+ * levels that are used by default to store authorizable nodes.<br>The value is
  * expected to be a positive integer greater than zero. The default
  * number of levels is 2.
- * <p/>
- * <strong>NOTE:</strong> Changing the default depth once users and groups
- * have been created in the repository will cause inconsistencies, due to
- * the fact that the resolution of ID to an authorizable relies on the
- * structure defined by the default depth.<br>
- * It is recommended to remove all authorizable nodes that will not be
- * reachable any more, before this config option is changed.
- * <ul>
- * <li>If default depth is increased:<br>
- * All authorizables on levels &lt; default depth are not reachable any more.</li>
- * <li>If default depth is decreased:<br>
- * All authorizables on levels &gt; default depth aren't reachable any more
- * unless the {@link #PARAM_AUTO_EXPAND_TREE} flag is set to <code>true</code>.</li>
- * </ul>
  * </li>
  * <li>{@link #PARAM_AUTO_EXPAND_TREE}: If this parameter is present and its
  * value is <code>true</code>, the trees containing user and group nodes will
@@ -135,6 +144,18 @@
         implements UserManager, UserConstants, SessionListener {
 
     /**
+     * Configuration option to change the {@link #USERS_PATH default path} for
+     * creating users.
+     */
+    public static final String PARAM_USERS_PATH = "usersPath";
+
+    /**
+     * Configuration option to change the {@link #GROUPS_PATH default path} for
+     * creating groups.
+     */
+    public static final String PARAM_GROUPS_PATH = "groupsPath";
+
+    /**
      * Flag to enable a minimal backwards compatibility with Jackrabbit &lt;
      * v2.0<br>
      * If the param is present and its value is <code>true</code> looking up
@@ -186,7 +207,19 @@
     private final SessionImpl session;
     private final String adminId;
     private final NodeResolver authResolver;
-    private final IdResolver idResolver;
+    private final NodeCreator nodeCreator;
+
+    /**
+     * Configuration value defining the node where User nodes will be created.
+     * Default value is {@link #USERS_PATH}.
+     */
+    private final String usersPath;
+
+    /**
+     * Configuration value defining the node where Group nodes will be created.
+     * Default value is {@link #GROUPS_PATH}.
+     */
+    private final String groupsPath;
 
     /**
      * Flag indicating if {@link #getAuthorizable(String)} should find users or
@@ -199,6 +232,17 @@
     private final boolean compatibleJR16;
 
     /**
+     * Flat storing the batch modus.
+     * If this option is turned on changes made through this user manager will
+     * only be persisted upon an explicit call to {@link javax.jcr.Session#save()},
+     * which must be the editing session object. Otherwise (default behavior)
+     * changes are immediately persisted.
+     *
+     * @see #setPersistenceModus(boolean, Session)
+     */
+    boolean batchModus = false;
+
+    /**
      * Create a new <code>UserManager</code> with the default configuration.
      *
      * @param session
@@ -214,7 +258,8 @@
      * Currently the following configuration options are respected:
      *
      * <ul>
-     * <li>{@link #PARAM_COMPATIBILE_JR16}. By default this option is disabled.</li>
+     * <li>{@link #PARAM_USERS_PATH}. If missing set to {@link #USERS_PATH}.</li>
+     * <li>{@link #PARAM_GROUPS_PATH}. If missing set to {@link #GROUPS_PATH}.</li>
      * <li>{@link #PARAM_DEFAULT_DEPTH}. The default number of levels is 2.</li>
      * <li>{@link #PARAM_AUTO_EXPAND_TREE}. By default this option is disabled.</li>
      * <li>{@link #PARAM_AUTO_EXPAND_SIZE}. The default value is 1000.</li>
@@ -231,6 +276,17 @@
         this.session = session;
         this.adminId = adminId;
 
+        nodeCreator = new NodeCreator(config);
+
+        Object param = (config != null) ? config.get(PARAM_USERS_PATH) : null;
+        usersPath = (param != null) ? param.toString() : USERS_PATH;
+
+        param = (config != null) ? config.get(PARAM_GROUPS_PATH) : null;
+        groupsPath = (param != null) ? param.toString() : GROUPS_PATH;
+
+        param = (config != null) ? config.get(PARAM_COMPATIBILE_JR16) : null;
+        compatibleJR16 = (param != null) && Boolean.parseBoolean(param.toString());
+
         NodeResolver nr;
         try {
             nr = new IndexNodeResolver(session, session);
@@ -239,13 +295,45 @@
             nr = new TraversingNodeResolver(session, session);
         }
         authResolver = nr;
+        authResolver.setSearchRoots(usersPath, groupsPath);
+    }
 
-        idResolver = new IdResolver(config);
-        boolean compatMode = false;
-        if (config != null && config.containsKey(PARAM_COMPATIBILE_JR16)) {
-            compatMode = Boolean.parseBoolean(config.get(PARAM_COMPATIBILE_JR16).toString());
+    /**
+     * @param batched If <code>true</code> changes made through this manager and
+     * to authorizables are only persisted upon explict call to {@link
+     * javax.jcr.Session#save()}.
+     * @throws RepositoryException If the passed <code>editingSession</code> is
+     * not the same this UserManager is writing to.
+     */
+    /* COMMENTED. WORK IN PROGRESS
+    public void setPersistenceModus(boolean batched, Session editingSession) throws RepositoryException {
+        if (editingSession != session) {
+            throw new RepositoryException("Cannot change persistence modus: Session mismatch.");
         }
-        compatibleJR16 = compatMode;
+        batchModus = batched;
+    }
+    */
+
+    /**
+     * Implementation specific methods releaving where users are created within
+     * the content.
+     *
+     * @return root path for user content.
+     * @see #PARAM_USERS_PATH For the corresponding configuration parameter.
+     */
+    public String getUsersPath() {
+        return usersPath;
+    }
+
+    /**
+     * Implementation specific methods releaving where groups are created within
+     * the content.
+     *
+     * @return root path for group content.
+     * @see #PARAM_GROUPS_PATH For the corresponding configuration parameter.
+     */
+    public String getGroupsPath() {
+        return groupsPath;
     }
 
     //--------------------------------------------------------< UserManager >---
@@ -257,15 +345,34 @@
             throw new IllegalArgumentException("Invalid authorizable name '" + id + "'");
         }
         Authorizable authorz = null;
-        NodeImpl n = getUserNode(id);
+        NodeId nodeId = buildNodeId(id);        
+        NodeImpl n = null;
+        try {
+            n = session.getNodeById(nodeId);
+        } catch (ItemNotFoundException e) {
+            if (compatibleJR16) {
+                // backwards-compatibility with JR < 2.0 user/group structure that doesn't
+                // allow to determine existance of an authorizable from the id directly.
+                // search for it the node belonging to that id
+                n = (NodeImpl) authResolver.findNode(P_USERID, id, NT_REP_USER);
+                if (n == null) {
+                    // no user -> look for group.
+                    // NOTE: JR < 2.0 always returned groupIDs that didn't contain any
+                    // illegal JCR chars. Since Group.getID() now unescapes the node
+                    // name additional escaping is required.
+                    Name nodeName = session.getQName(Text.escapeIllegalJcrChars(id));
+                    n = (NodeImpl) authResolver.findNode(nodeName, NT_REP_GROUP);
+                }
+            } // else: no matching node found -> ignore exception.
+        }
+
         if (n != null) {
-            authorz = createUser(n);
-        } else {
-            n = getGroupNode(id);
-            if (n != null) {
+            if (n.isNodeType(NT_REP_USER)) {
+                authorz = createUser(n);
+            } else if (n.isNodeType(NT_REP_GROUP)) {
                 authorz = createGroup(n);
-            }
-        }
+            } // else some other node but not an authorizable -> return null.
+        } // else no matching node -> return null.
         return authorz;
     }
 
@@ -373,21 +480,18 @@
         if (getAuthorizable(userID) != null) {
             throw new AuthorizableExistsException("User for '" + userID + "' already exists");
         }
-        if (hasAuthorizableOrReferee(principal)) {
+        if (hasAuthorizable(principal)) {
             throw new AuthorizableExistsException("Authorizable for '" + principal.getName() + "' already exists");
         }
-        if (intermediatePath != null) {
-            log.debug("Intermediate path param " + intermediatePath + " is ignored.");
-        }
 
-        NodeImpl parent = null;
         try {
-            NodeImpl userNode = (NodeImpl) idResolver.createUserNode(userID);
+            NodeImpl userNode = (NodeImpl) nodeCreator.createUserNode(userID, intermediatePath);
 
-            setProperty(userNode, P_USERID, getValue(userID), true);
             setProperty(userNode, P_PASSWORD, getValue(UserImpl.buildPasswordValue(password)), true);
             setProperty(userNode, P_PRINCIPAL_NAME, getValue(principal.getName()), true);
-            session.save();
+            if (!batchModus) {
+                session.save();
+            }
 
             log.debug("User created: " + userID + "; " + userNode.getPath());
             return createUser(userNode);
@@ -429,20 +533,18 @@
         if (!isValidPrincipal(principal)) {
             throw new IllegalArgumentException("Cannot create Group: Principal may not be null and must have a valid name.");
         }
-        if (hasAuthorizableOrReferee(principal)) {
+        if (hasAuthorizable(principal)) {
             throw new AuthorizableExistsException("Authorizable for '" + principal.getName() + "' already exists: ");
         }
-        if (intermediatePath != null) {
-            log.debug("Intermediate path param " + intermediatePath + " is ignored.");
-        }
         
-        NodeImpl parent = null;
         try {
             String groupID = getGroupId(principal.getName());
-            NodeImpl groupNode = (NodeImpl) idResolver.createGroupNode(groupID);
+            NodeImpl groupNode = (NodeImpl) nodeCreator.createGroupNode(groupID, intermediatePath);
 
             setProperty(groupNode, P_PRINCIPAL_NAME, getValue(principal.getName()));
-            session.save();
+            if (!batchModus) {
+                session.save();
+            }
 
             log.debug("Group created: " + groupID + "; " + groupNode.getPath());
 
@@ -461,32 +563,36 @@
      * @return
      * @throws RepositoryException
      */
-    boolean hasAuthorizableOrReferee(Principal principal) throws RepositoryException {
-        Set<Name> s = new HashSet<Name>(2);
-        s.add(P_PRINCIPAL_NAME);
-        s.add(P_REFEREES);
-        NodeIterator res = authResolver.findNodes(s, principal.getName(), NT_REP_AUTHORIZABLE, true, 1);
-        return res.hasNext();
+    private boolean hasAuthorizable(Principal principal) throws RepositoryException {
+        return getAuthorizable(principal) != null;
     }
 
     void setProtectedProperty(NodeImpl node, Name propName, Value value) throws RepositoryException, LockException, ConstraintViolationException, ItemExistsException, VersionException {
         setProperty(node, propName, value);
-        node.save();
+        if (!batchModus) {
+            node.save();
+        }
     }
 
     void setProtectedProperty(NodeImpl node, Name propName, Value[] values) throws RepositoryException, LockException, ConstraintViolationException, ItemExistsException, VersionException {
         setProperty(node, propName, values);
-        node.save();
+        if (!batchModus) {
+            node.save();
+        }
     }
 
     void setProtectedProperty(NodeImpl node, Name propName, Value[] values, int type) throws RepositoryException, LockException, ConstraintViolationException, ItemExistsException, VersionException {
         setProperty(node, propName, values, type);
-        node.save();
+        if (!batchModus) {
+            node.save();
+        }
     }
 
     void removeProtectedItem(ItemImpl item, Node parent) throws RepositoryException, AccessDeniedException, VersionException {
         removeItem(item);
-        parent.save();
+        if (!batchModus) {
+            parent.save();
+        }
     }
 
     /**
@@ -499,11 +605,10 @@
      * @throws RepositoryException
      */
     private String getGroupId(String principalName) throws RepositoryException {
-        String escHint = principalName;
-        String groupID = escHint;
+        String groupID = principalName;
         int i = 0;
         while (getAuthorizable(groupID) != null) {
-            groupID = escHint + "_" + i;
+            groupID = principalName + "_" + i;
             i++;
         }
         return groupID;
@@ -532,11 +637,10 @@
         if (userNode == null || !userNode.isNodeType(NT_REP_USER)) {
             throw new IllegalArgumentException();
         }
-        if (!Text.isDescendant(USERS_PATH, userNode.getPath())) {
+        if (!Text.isDescendant(usersPath, userNode.getPath())) {
             throw new IllegalArgumentException("User has to be within the User Path");
         }
-        User user = doCreateUser(userNode);
-        return user;
+        return doCreateUser(userNode);
     }
 
     /**
@@ -560,52 +664,26 @@
      * @throws RepositoryException
      */
     Group createGroup(NodeImpl groupNode) throws RepositoryException {
-        Group group = GroupImpl.create(groupNode, this);
-        return group;
+        return GroupImpl.create(groupNode, this);
     }
 
-    /**
-     * Resolve the given <code>userID</code> to an rep:user node in the repository.
-     *
-     * @param userID A valid userID.
-     * @return the node associated with the given userID or <code>null</code>.
-     * @throws RepositoryException If an error occurs.
-     */
-    private NodeImpl getUserNode(String userID) throws RepositoryException {
-        NodeImpl n = (NodeImpl) idResolver.findNode(userID, false);
-        if (n == null && compatibleJR16) {
-            // backwards-compatibility with JR < 2.0 user structure that doesn't
-            // allow to determine the auth-path from the id directly.
-            // search for it the node belonging to that userID
-            n = (NodeImpl) authResolver.findNode(P_USERID, userID, NT_REP_USER);
-        } // else: no such user -> return null.
-        return n;
+    private static boolean isValidPrincipal(Principal principal) {
+        return principal != null && principal.getName() != null && principal.getName().length() > 0;
     }
 
     /**
-     * Resolve the given <code>groupID</code> to an rep:group node in the repository.
      *
-     * @param groupID A valid groupID.
-     * @return the node associated with the given userID or <code>null</code>.
-     * @throws RepositoryException If an error occurs.
-     */
-    private NodeImpl getGroupNode(String groupID) throws RepositoryException {
-        NodeImpl n = (NodeImpl) idResolver.findNode(groupID, true);
-        if (n == null && compatibleJR16) {
-            // backwards-compatibility with JR < 2.0 group structure that doesn't
-            // allow to determine the auth-path from the id directly
-            // search for it the node belonging to that groupID.
-            // NOTE: JR < 2.0 always returned groupIDs that didn't contain any
-            // illegal JCR chars. Since Group.getID() now unescapes the node
-            // name additional escaping is required.
-            Name nodeName = session.getQName(Text.escapeIllegalJcrChars(groupID));
-            n = (NodeImpl) authResolver.findNode(nodeName, NT_REP_GROUP);
-        } // else: no such group -> return null.
-        return n;
-    }
-
-    private static boolean isValidPrincipal(Principal principal) {
-        return principal != null && principal.getName() != null && principal.getName().length() > 0;
+     * @param id
+     * @return
+     * @throws RepositoryException
+     */
+    private static NodeId buildNodeId(String id) throws RepositoryException {
+        try {
+            UUID uuid = UUID.nameUUIDFromBytes(id.getBytes("UTF-8"));
+            return new NodeId(uuid);
+        } catch (UnsupportedEncodingException e) {
+            throw new RepositoryException("Unexpected error while build ID hash", e);
+        }
     }
 
     //----------------------------------------------------< SessionListener >---
@@ -700,14 +778,16 @@
 
     //--------------------------------------------------------------------------
     /**
-     * Inner class creating and finding the JCR nodes corresponding the a given
+     * Inner class creating the JCR nodes corresponding the a given
      * authorizable ID with the following behavior:
      * <ul>
-     * <li>Users are created below /rep:security/rep:authorizables/rep:users</li>
-     * <li>Groups are created below /rep:security/rep:authorizables/rep:users</li>
+     * <li>Users are created below /rep:security/rep:authorizables/rep:users or
+     * the corresponding path configured.</li>
+     * <li>Groups are created below /rep:security/rep:authorizables/rep:groups or
+     * the corresponding path configured.</li>
      * <li>Below each category authorizables are created within a human readable
-     * structure, whose depth is defined by the <code>defaultDepth</code> config
-     * option.<br>
+     * structure based on the defined intermediate path or some internal logic
+     * with a depth defined by the <code>defaultDepth</code> config option.<br>
      * E.g. creating a user node for an ID 'aSmith' would result in the following
      * structure assuming defaultDepth == 2 is used:
      * <pre>
@@ -723,8 +803,8 @@
      * {@link Text#escapeIllegalJcrChars(String) escaping} any illegal JCR chars.
      * In case of a Group the node name is calculated from the specified principal
      * name circumventing any conflicts with existing ids and escaping illegal chars.</li>
-     * <li>The names of the intermediate folders are caculated from the leading
-     * chars of the escaped node name.</li>
+     * <li>If no intermediate path is passed the names of the intermediate
+     * folders are calculated from the leading chars of the escaped node name.</li>
      * <li>If the escaped node name is shorter than the <code>defaultDepth</code>
      * the last char is repeated.<br>
      * E.g. creating a user node for an ID 'a' would result in the following
@@ -832,7 +912,7 @@
      * autoExpandSize.</li>
      * </ul>
      */
-    private class IdResolver {
+    private class NodeCreator {
 
         private static final String DELIMITER = "/";
         private static final int DEFAULT_DEPTH = 2;
@@ -845,7 +925,7 @@
         // all child nodes.
         private final long autoExpandSize;
 
-        private IdResolver(Properties config) {
+        private NodeCreator(Properties config) {
             int d = DEFAULT_DEPTH;
             boolean expand = false;
             long size = DEFAULT_SIZE;
@@ -883,83 +963,46 @@
             autoExpandSize = size;
         }
 
-        public Node createUserNode(String userID) throws RepositoryException {
-            return createAuthorizableNode(userID, false);
+        public Node createUserNode(String userID, String intermediatePath) throws RepositoryException {
+            return createAuthorizableNode(userID, false, intermediatePath);
         }
 
-        public Node createGroupNode(String groupID) throws RepositoryException {
-            return createAuthorizableNode(groupID, true);
+        public Node createGroupNode(String groupID, String intermediatePath) throws RepositoryException {
+            return createAuthorizableNode(groupID, true, intermediatePath);
         }
 
-        public Node findNode(String id, boolean isGroup) throws RepositoryException {
-            String defaultFolderPath = getDefaultFolderPath(id, isGroup);
-            String escapedId = Text.escapeIllegalJcrChars(id);
-
-            if (session.nodeExists(defaultFolderPath)) {
-                Node folder = session.getNode(defaultFolderPath);
-                Name expectedNt = (isGroup) ? NT_REP_GROUP : NT_REP_USER;
-
-                // traverse the potentially existing hierarchy looking for the
-                // authorizable node.
-                int segmLength = defaultDepth +1;
-                while (folder != null) {
-                    if (folder.hasNode(escapedId)) {
-                        NodeImpl aNode = (NodeImpl) folder.getNode(escapedId);
-                        if (aNode.isNodeType(expectedNt)) {
-                            // done. found the right auth-node
-                            return aNode;
-                        } else {
-                            folder = aNode;
-                        }
-                    } else {
-                        // no child node with name 'escapedId' -> look for
-                        // additional levels that may exist.
-                        Node parent = folder;
-                        folder = null;
-                        if (id.length() >= segmLength) {
-                            String folderName = Text.escapeIllegalJcrChars(id.substring(0, segmLength));
-                            if (parent.hasNode(folderName)) {
-                                NodeImpl f = (NodeImpl) parent.getNode(folderName);
-                                if (f.isNodeType(NT_REP_AUTHORIZABLE_FOLDER)) {
-                                    folder = f;
-                                } // else: matching node isn't an authorizable-folder
-                            } // else: failed to find a suitable next level
-                        } // else: id is shorter than required length at the current level.
-                    }
-                    segmLength++;
-                }
-            } // else: no node at default-path
-
-            // no matching node found -> authorizable doesn't exist.
-            return null;
-        }
-
-        private Node createAuthorizableNode(String id, boolean isGroup) throws RepositoryException {
+        private Node createAuthorizableNode(String id, boolean isGroup, String intermediatePath) throws RepositoryException {
             String escapedId = Text.escapeIllegalJcrChars(id);
 
+            Node folder;
             // first create the default folder nodes, that are always present.
-            Node folder = createDefaultFolderNodes(id, escapedId, isGroup);
+            folder = createDefaultFolderNodes(id, escapedId, isGroup, intermediatePath);
             // eventually create additional intermediate folders.
-            folder = createIntermediateFolderNodes(id, escapedId, folder);
+            if (intermediatePath == null) {
+                // internal logic only
+                folder = createIntermediateFolderNodes(id, escapedId, folder);
+            }
 
             // finally create the authorizable node
             Name nodeName = session.getQName(escapedId);
             Name ntName = (isGroup) ? NT_REP_GROUP : NT_REP_USER;
-            Node authNode = addNode((NodeImpl) folder, nodeName, ntName);
+            NodeId nid = buildNodeId(id);
 
-            return authNode;
+            return addNode((NodeImpl) folder, nodeName, ntName, nid);
         }
 
-        private Node createDefaultFolderNodes(String id, String escapedId, boolean isGroup) throws RepositoryException {
+        private Node createDefaultFolderNodes(String id, String escapedId,
+                                              boolean isGroup, String intermediatePath) throws RepositoryException {
             NodeImpl folder;
-            // first create the levels that are always present -> see #getDefaultFolderPath
-            String defaultPath = getDefaultFolderPath(id, isGroup);
+            String defaultPath = getDefaultFolderPath(id, isGroup, intermediatePath);
             if (session.nodeExists(defaultPath)) {
                 folder = (NodeImpl) session.getNode(defaultPath);
+                if (!folder.isNodeType(NT_REP_AUTHORIZABLE_FOLDER)) {
+                    throw new RepositoryException("Invalid intermediate path. Must be of type rep:AuthorizableFolder.");
+                }
             } else {
                 String[] segmts = defaultPath.split("/");
                 folder = (NodeImpl) session.getRootNode();
-                String repSecurity = SECURITY_ROOT_PATH.substring(1);
 
                 for (String segment : segmts) {
                     if (segment.length() < 1) {
@@ -967,42 +1010,52 @@
                     }
                     if (folder.hasNode(segment)) {
                         folder = (NodeImpl) folder.getNode(segment);
-                    } else {
-                        Name ntName;
-                        if (repSecurity.equals(segment)) {
-                            // rep:security node
-                            ntName = NameConstants.NT_UNSTRUCTURED;
-                        } else {
-                            ntName = NT_REP_AUTHORIZABLE_FOLDER;
+                        if (!folder.isNodeType(NT_REP_AUTHORIZABLE_FOLDER)) {
+                            throw new RepositoryException("Invalid intermediate path. Must be of type rep:AuthorizableFolder.");
                         }
-                        NodeImpl added = addNode(folder, session.getQName(segment), ntName);
-                        folder = added;
+                    } else {
+                        folder = addNode(folder, session.getQName(segment), NT_REP_AUTHORIZABLE_FOLDER);
                     }
                 }
             }
 
-            // validation check if authorizable to be create doesn't conflict.
+            // validation check if authorizable to be created doesn't conflict.
             checkAuthorizableNodeExists(escapedId, folder);
             return folder;
         }
 
-        private String getDefaultFolderPath(String id, boolean isGroup) {
+        private String getDefaultFolderPath(String id, boolean isGroup, String intermediatePath) {
             StringBuilder bld = new StringBuilder();
             if (isGroup) {
-                bld.append(GROUPS_PATH);
+                bld.append(groupsPath);
             } else {
-                bld.append(USERS_PATH);
+                bld.append(usersPath);
             }
-            StringBuilder lastSegment = new StringBuilder(defaultDepth);
-            int idLength = id.length();
-            for (int i = 0; i < defaultDepth; i++) {
-                if (idLength > i) {
-                    lastSegment.append(id.charAt(i));
-                } else {
-                    // escapedID is too short -> append the last char again
-                    lastSegment.append(id.charAt(idLength-1));
+
+            if (intermediatePath == null) {
+                // internal logic
+                StringBuilder lastSegment = new StringBuilder(defaultDepth);
+                int idLength = id.length();
+                for (int i = 0; i < defaultDepth; i++) {
+                    if (idLength > i) {
+                        lastSegment.append(id.charAt(i));
+                    } else {
+                        // escapedID is too short -> append the last char again
+                        lastSegment.append(id.charAt(idLength-1));
+                    }
+                    bld.append(DELIMITER).append(Text.escapeIllegalJcrChars(lastSegment.toString()));
+                }
+            } else {
+                // structure defined by intermediate path
+                if (intermediatePath.startsWith(bld.toString())) {
+                    intermediatePath = intermediatePath.substring(bld.toString().length());
+                }
+                if (intermediatePath.length() > 0 && !"/".equals(intermediatePath)) {
+                    if (!intermediatePath.startsWith("/")) {
+                        bld.append("/");
+                    }
+                    bld.append(intermediatePath);
                 }
-                bld.append(DELIMITER).append(Text.escapeIllegalJcrChars(lastSegment.toString()));
             }
             return bld.toString();
         }
@@ -1018,8 +1071,7 @@
             // - if the auth-node to be created potentially collides with any
             //   of the intermediate nodes.
             int segmLength = defaultDepth +1;
-            int idLength = id.length();
-
+            
             while (intermediateFolderNeeded(escapedId, folder)) {
                 String folderName = Text.escapeIllegalJcrChars(id.substring(0, segmLength));
                 if (folder.hasNode(folderName)) {

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/DefaultISMLocking.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/DefaultISMLocking.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/DefaultISMLocking.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/DefaultISMLocking.java Wed Oct 21 11:38:31 2009
@@ -16,10 +16,14 @@
  */
 package org.apache.jackrabbit.core.state;
 
+import java.util.Arrays;
+
 import javax.transaction.xa.Xid;
 
 import org.apache.jackrabbit.core.id.ItemId;
 import org.apache.jackrabbit.core.TransactionContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import EDU.oswego.cs.dl.util.concurrent.ReentrantWriterPreferenceReadWriteLock;
 import EDU.oswego.cs.dl.util.concurrent.Sync;
@@ -32,6 +36,11 @@
 public class DefaultISMLocking implements ISMLocking {
 
     /**
+     * Logger instance
+     */
+    private static final Logger log = LoggerFactory.getLogger(DefaultISMLocking.class);
+
+    /**
      * The internal read-write lock.
      */
     private final RWLock rwLock = new RWLock();
@@ -60,7 +69,6 @@
              * {@inheritDoc}
              */
             public void release() {
-                rwLock.setActiveXid(null);
                 rwLock.writeLock().release();
             }
 
@@ -109,8 +117,36 @@
          * @param xid
          */
         synchronized void setActiveXid(Xid xid) {
+            if (activeXid != null && xid != null) {
+                boolean sameGTI = Arrays.equals(activeXid.getGlobalTransactionId(), xid.getGlobalTransactionId());
+                if (!sameGTI) {
+                    log.warn("Unable to set the ActiveXid while a other one is associated with a different GloalTransactionId with this RWLock.");
+                    return;
+                }
+            }
             activeXid = xid;
         }
-        
+
+        /**
+         * {@inheritDoc}
+         * 
+         * If there are no more writeHolds the activeXid will be set to null
+         */
+        protected synchronized Signaller endWrite() {
+            --writeHolds_;
+            if (writeHolds_ > 0) {  // still being held
+                return null;
+            } else {
+                activeXid = null;
+                activeWriter_ = null;
+                if (waitingReaders_ > 0 && allowReader()) {
+                    return readerLock_;
+                } else if (waitingWriters_ > 0) {
+                    return writerLock_;
+                } else {
+                    return null;
+                }
+            }
+        }
     }
 }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeState.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeState.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeState.java Wed Oct 21 11:38:31 2009
@@ -18,7 +18,6 @@
 
 import org.apache.jackrabbit.core.id.ItemId;
 import org.apache.jackrabbit.core.id.NodeId;
-import org.apache.jackrabbit.core.nodetype.NodeDefId;
 import org.apache.jackrabbit.spi.Name;
 
 import java.util.ArrayList;
@@ -56,11 +55,6 @@
     private NodeId parentId;
 
     /**
-     * id of this node's definition
-     */
-    private NodeDefId defId;
-
-    /**
      * insertion-ordered collection of ChildNodeEntry objects
      */
     private ChildNodeEntries childNodeEntries = new ChildNodeEntries();
@@ -127,7 +121,6 @@
             parentId = nodeState.parentId;
             nodeTypeName = nodeState.nodeTypeName;
             mixinTypeNames = (NameSet) nodeState.mixinTypeNames.clone();
-            defId = nodeState.defId;
             propertyNames = (NameSet) nodeState.propertyNames.clone();
             childNodeEntries = (ChildNodeEntries) nodeState.childNodeEntries.clone();
             if (syncModCount) {
@@ -211,24 +204,6 @@
     }
 
     /**
-     * Returns the id of the definition applicable to this node state.
-     *
-     * @return the id of the definition
-     */
-    public NodeDefId getDefinitionId() {
-        return defId;
-    }
-
-    /**
-     * Sets the id of the definition applicable to this node state.
-     *
-     * @param defId the id of the definition
-     */
-    public void setDefinitionId(NodeDefId defId) {
-        this.defId = defId;
-    }
-
-    /**
      * Determines if there are any child node entries.
      *
      * @return <code>true</code> if there are child node entries,

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/PropertyState.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/PropertyState.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/PropertyState.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/PropertyState.java Wed Oct 21 11:38:31 2009
@@ -19,7 +19,6 @@
 import org.apache.jackrabbit.core.id.PropertyId;
 import org.apache.jackrabbit.core.id.NodeId;
 import org.apache.jackrabbit.core.id.ItemId;
-import org.apache.jackrabbit.core.nodetype.PropDefId;
 import org.apache.jackrabbit.core.value.InternalValue;
 import org.apache.jackrabbit.spi.Name;
 
@@ -51,11 +50,6 @@
     private boolean multiValued;
 
     /**
-     * the property definition id
-     */
-    private PropDefId defId;
-
-    /**
      * Constructs a new property state that is initially connected to an
      * overlayed state.
      *
@@ -92,7 +86,6 @@
             PropertyState propState = (PropertyState) state;
             id = propState.id;
             type = propState.type;
-            defId = propState.defId;
             values = propState.values;
             multiValued = propState.multiValued;
             if (syncModCount) {
@@ -183,24 +176,6 @@
     }
 
     /**
-     * Returns the id of the definition applicable to this property state.
-     *
-     * @return the id of the definition
-     */
-    public PropDefId getDefinitionId() {
-        return defId;
-    }
-
-    /**
-     * Sets the id of the definition applicable to this property state.
-     *
-     * @param defId the id of the definition
-     */
-    public void setDefinitionId(PropDefId defId) {
-        this.defId = defId;
-    }
-
-    /**
      * Sets the value(s) of this property.
      *
      * @param values the new values

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java Wed Oct 21 11:38:31 2009
@@ -27,6 +27,7 @@
 import javax.jcr.ItemNotFoundException;
 import javax.jcr.ReferentialIntegrityException;
 import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
 
 import org.apache.commons.collections.iterators.IteratorChain;
 import org.apache.jackrabbit.core.CachingHierarchyManager;
@@ -35,10 +36,12 @@
 import org.apache.jackrabbit.core.id.ItemId;
 import org.apache.jackrabbit.core.id.NodeId;
 import org.apache.jackrabbit.core.id.PropertyId;
-import org.apache.jackrabbit.core.nodetype.NodeDef;
 import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
+import org.apache.jackrabbit.core.nodetype.EffectiveNodeType;
+import org.apache.jackrabbit.core.nodetype.NodeTypeConflictException;
 import org.apache.jackrabbit.core.util.Dumpable;
 import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.QNodeDefinition;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -782,7 +785,7 @@
      *
      * @return attic
      */
-    ItemStateManager getAttic() {
+    public ItemStateManager getAttic() {
         if (attic == null) {
             attic = new AtticItemStateManager();
         }
@@ -861,14 +864,19 @@
                                 }
 
                                 public boolean allowsSameNameSiblings(NodeId id) {
-                                    NodeState ns;
                                     try {
-                                        ns = (NodeState) getItemState(id);
-                                    } catch (ItemStateException e) {
+                                        NodeState ns = (NodeState) getItemState(id);
+                                        NodeState parent = (NodeState) getItemState(ns.getParentId());
+                                        Name name = parent.getChildNodeEntry(id).getName();
+                                        EffectiveNodeType ent = ntReg.getEffectiveNodeType(
+                                                parent.getNodeTypeName(),
+                                                parent.getMixinTypeNames());
+                                        QNodeDefinition def = ent.getApplicableChildNodeDef(name, ns.getNodeTypeName(), ntReg);
+                                        return def != null ? def.allowsSameNameSiblings() : false;
+                                    } catch (Exception e) {
+                                        log.warn("Unable to get node definition", e);
                                         return false;
                                     }
-                                    NodeDef def = ntReg.getNodeDef(ns.getDefinitionId());
-                                    return def != null ? def.allowsSameNameSiblings() : false;
                                 }
                             };
                     if (NodeStateMerger.merge((NodeState) transientState, context)) {

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java Wed Oct 21 11:38:31 2009
@@ -24,7 +24,6 @@
 import javax.jcr.PropertyType;
 import javax.jcr.ReferentialIntegrityException;
 import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.ConstraintViolationException;
 import javax.jcr.nodetype.NoSuchNodeTypeException;
 
 import org.apache.jackrabbit.core.RepositoryImpl;
@@ -33,11 +32,8 @@
 import org.apache.jackrabbit.core.id.NodeId;
 import org.apache.jackrabbit.core.id.PropertyId;
 import org.apache.jackrabbit.core.nodetype.EffectiveNodeType;
-import org.apache.jackrabbit.core.nodetype.NodeDef;
-import org.apache.jackrabbit.core.nodetype.NodeDefId;
 import org.apache.jackrabbit.core.nodetype.NodeTypeConflictException;
 import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
-import org.apache.jackrabbit.core.nodetype.PropDef;
 import org.apache.jackrabbit.core.observation.EventState;
 import org.apache.jackrabbit.core.observation.EventStateCollection;
 import org.apache.jackrabbit.core.observation.EventStateCollectionFactory;
@@ -47,6 +43,7 @@
 import org.apache.jackrabbit.core.value.InternalValue;
 import org.apache.jackrabbit.core.virtual.VirtualItemStateProvider;
 import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.QNodeDefinition;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -621,18 +618,28 @@
                                         }
 
                                         public boolean allowsSameNameSiblings(NodeId id) {
-                                            NodeState ns;
                                             try {
-                                                if (local.has(id)) {
-                                                    ns = (NodeState) local.get(id);
-                                                } else {
-                                                    ns = (NodeState) getItemState(id);
-                                                }
-                                            } catch (ItemStateException e) {
+                                                NodeState ns = getNodeState(id);
+                                                NodeState parent = getNodeState(ns.getParentId());
+                                                Name name = parent.getChildNodeEntry(id).getName();
+                                                EffectiveNodeType ent = ntReg.getEffectiveNodeType(
+                                                        parent.getNodeTypeName(),
+                                                        parent.getMixinTypeNames());
+                                                QNodeDefinition def = ent.getApplicableChildNodeDef(name, ns.getNodeTypeName(), ntReg);
+                                                return def != null ? def.allowsSameNameSiblings() : false;
+                                            } catch (Exception e) {
+                                                log.warn("Unable to get node definition", e);
                                                 return false;
                                             }
-                                            NodeDef def = ntReg.getNodeDef(ns.getDefinitionId());
-                                            return def != null ? def.allowsSameNameSiblings() : false;
+                                        }
+
+                                        protected NodeState getNodeState(NodeId id)
+                                                throws ItemStateException {
+                                            if (local.has(id)) {
+                                                return (NodeState) local.get(id);
+                                            } else {
+                                                return (NodeState) getItemState(id);
+                                            }
                                         }
                                     };
 
@@ -1248,47 +1255,21 @@
         // FIXME need to manually setup root node by creating mandatory jcr:primaryType property
         // @todo delegate setup of root node to NodeTypeInstanceHandler
 
-        // id of the root node's definition
-        NodeDefId nodeDefId;
-        // definition of jcr:primaryType property
-        PropDef propDef;
-        // id of the jcr:system node's definition
-        NodeDefId jcrSystemDefId;
-        try {
-            nodeDefId = ntReg.getRootNodeDef().getId();
-            EffectiveNodeType ent = ntReg.getEffectiveNodeType(NameConstants.REP_ROOT);
-            propDef = ent.getApplicablePropertyDef(NameConstants.JCR_PRIMARYTYPE,
-                    PropertyType.NAME, false);
-            jcrSystemDefId = ent.getApplicableChildNodeDef(NameConstants.JCR_SYSTEM, NameConstants.REP_SYSTEM, ntReg).getId();
-        } catch (NoSuchNodeTypeException nsnte) {
-            String msg = "internal error: failed to create root node";
-            log.error(msg, nsnte);
-            throw new ItemStateException(msg, nsnte);
-        } catch (ConstraintViolationException cve) {
-            String msg = "internal error: failed to create root node";
-            log.error(msg, cve);
-            throw new ItemStateException(msg, cve);
-        }
-        rootState.setDefinitionId(nodeDefId);
-        jcrSystemState.setDefinitionId(jcrSystemDefId);
-
         // create jcr:primaryType property on root node state
-        rootState.addPropertyName(propDef.getName());
+        rootState.addPropertyName(NameConstants.JCR_PRIMARYTYPE);
 
-        PropertyState prop = createInstance(propDef.getName(), rootNodeId);
+        PropertyState prop = createInstance(NameConstants.JCR_PRIMARYTYPE, rootNodeId);
         prop.setValues(new InternalValue[]{InternalValue.create(NameConstants.REP_ROOT)});
-        prop.setType(propDef.getRequiredType());
-        prop.setMultiValued(propDef.isMultiple());
-        prop.setDefinitionId(propDef.getId());
+        prop.setType(PropertyType.NAME);
+        prop.setMultiValued(false);
 
         // create jcr:primaryType property on jcr:system node state
-        jcrSystemState.addPropertyName(propDef.getName());
+        jcrSystemState.addPropertyName(NameConstants.JCR_PRIMARYTYPE);
 
-        PropertyState primaryTypeProp = createInstance(propDef.getName(), jcrSystemState.getNodeId());
+        PropertyState primaryTypeProp = createInstance(NameConstants.JCR_PRIMARYTYPE, jcrSystemState.getNodeId());
         primaryTypeProp.setValues(new InternalValue[]{InternalValue.create(NameConstants.REP_SYSTEM)});
-        primaryTypeProp.setType(propDef.getRequiredType());
-        primaryTypeProp.setMultiValued(propDef.isMultiple());
-        primaryTypeProp.setDefinitionId(propDef.getId());
+        primaryTypeProp.setType(PropertyType.NAME);
+        primaryTypeProp.setMultiValued(false);
 
         // add child node entry for jcr:system node
         rootState.addChildNodeEntry(NameConstants.JCR_SYSTEM, RepositoryImpl.SYSTEM_ROOT_NODE_ID);

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java Wed Oct 21 11:38:31 2009
@@ -78,10 +78,18 @@
     public int read(byte[] b, long position) throws IOException, RepositoryException {
         InputStream in = getStream();
         try {
-            in.skip(position);
+            long skip = position;
+            while (skip > 0) {
+                long skipped = in.skip(skip);
+                if (skipped <= 0) {
+                    return -1;
+                }
+                skip -= skipped;
+            }
             return in.read(b);
         } finally {
             in.close();
         }
     }
+
 }

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/InternalValue.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/InternalValue.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/InternalValue.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/InternalValue.java Wed Oct 21 11:38:31 2009
@@ -242,6 +242,18 @@
         }
     }
 
+    public static InternalValue[] create(QValue[] values)
+            throws RepositoryException {
+        if (values == null) {
+            return null;
+        }
+        InternalValue[] tmp = new InternalValue[values.length];
+        for (int i = 0; i < values.length; i++) {
+            tmp[i] = InternalValue.create(values[i]);
+        }
+        return tmp;
+    }
+
     static InternalValue getInternalValue(DataIdentifier identifier, DataStore store) throws DataStoreException {
         // access the record to ensure it is not garbage collected
         if (store.getRecordIfStored(identifier) != null) {

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionManagerImpl.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionManagerImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalVersionManagerImpl.java Wed Oct 21 11:38:31 2009
@@ -190,12 +190,8 @@
             if (false && !pMgr.exists(systemId)) {
                 NodeState root = pMgr.createNew(systemId);
                 root.setParentId(RepositoryImpl.ROOT_NODE_ID);
-                root.setDefinitionId(ntReg.getEffectiveNodeType(NameConstants.REP_ROOT).getApplicableChildNodeDef(
-                        NameConstants.JCR_SYSTEM, NameConstants.REP_SYSTEM, ntReg).getId());
                 root.setNodeTypeName(NameConstants.REP_SYSTEM);
                 PropertyState pt = pMgr.createNew(new PropertyId(systemId, NameConstants.JCR_PRIMARYTYPE));
-                pt.setDefinitionId(ntReg.getEffectiveNodeType(NameConstants.REP_SYSTEM).getApplicablePropertyDef(
-                        NameConstants.JCR_PRIMARYTYPE, PropertyType.NAME, false).getId());
                 pt.setMultiValued(false);
                 pt.setType(PropertyType.NAME);
                 pt.setValues(new InternalValue[]{InternalValue.create(NameConstants.REP_SYSTEM)});
@@ -215,12 +211,8 @@
             if (!pMgr.exists(historiesId)) {
                 NodeState root = pMgr.createNew(historiesId);
                 root.setParentId(systemId);
-                root.setDefinitionId(ntReg.getEffectiveNodeType(NameConstants.REP_SYSTEM).getApplicableChildNodeDef(
-                        NameConstants.JCR_VERSIONSTORAGE, NameConstants.REP_VERSIONSTORAGE, ntReg).getId());
                 root.setNodeTypeName(NameConstants.REP_VERSIONSTORAGE);
                 PropertyState pt = pMgr.createNew(new PropertyId(historiesId, NameConstants.JCR_PRIMARYTYPE));
-                pt.setDefinitionId(ntReg.getEffectiveNodeType(NameConstants.REP_VERSIONSTORAGE).getApplicablePropertyDef(
-                        NameConstants.JCR_PRIMARYTYPE, PropertyType.NAME, false).getId());
                 pt.setMultiValued(false);
                 pt.setType(PropertyType.NAME);
                 pt.setValues(new InternalValue[]{InternalValue.create(NameConstants.REP_VERSIONSTORAGE)});
@@ -235,12 +227,8 @@
             if (!pMgr.exists(activitiesId)) {
                 NodeState root = pMgr.createNew(activitiesId);
                 root.setParentId(systemId);
-                root.setDefinitionId(ntReg.getEffectiveNodeType(NameConstants.REP_SYSTEM).getApplicableChildNodeDef(
-                        NameConstants.JCR_ACTIVITIES, NameConstants.REP_ACTIVITIES, ntReg).getId());
                 root.setNodeTypeName(NameConstants.REP_ACTIVITIES);
                 PropertyState pt = pMgr.createNew(new PropertyId(activitiesId, NameConstants.JCR_PRIMARYTYPE));
-                pt.setDefinitionId(ntReg.getEffectiveNodeType(NameConstants.REP_ACTIVITIES).getApplicablePropertyDef(
-                        NameConstants.JCR_PRIMARYTYPE, PropertyType.NAME, false).getId());
                 pt.setMultiValued(false);
                 pt.setType(PropertyType.NAME);
                 pt.setValues(new InternalValue[]{InternalValue.create(NameConstants.REP_ACTIVITIES)});

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/NodeStateEx.java Wed Oct 21 11:38:31 2009
@@ -30,10 +30,8 @@
 import org.apache.jackrabbit.core.id.NodeId;
 import org.apache.jackrabbit.core.id.PropertyId;
 import org.apache.jackrabbit.core.nodetype.EffectiveNodeType;
-import org.apache.jackrabbit.core.nodetype.NodeDef;
 import org.apache.jackrabbit.core.nodetype.NodeTypeConflictException;
 import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
-import org.apache.jackrabbit.core.nodetype.PropDef;
 import org.apache.jackrabbit.core.state.ChildNodeEntry;
 import org.apache.jackrabbit.core.state.ItemState;
 import org.apache.jackrabbit.core.state.ItemStateException;
@@ -42,6 +40,8 @@
 import org.apache.jackrabbit.core.state.UpdatableItemStateManager;
 import org.apache.jackrabbit.core.value.InternalValue;
 import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
+import org.apache.jackrabbit.spi.QNodeDefinition;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
 
 /**
@@ -70,6 +70,11 @@
     private Name name;
 
     /**
+     * the cached node definition
+     */
+    private QNodeDefinition def;
+
+    /**
      * Creates a new persistent node
      *
      * @param stateMgr state manager
@@ -280,13 +285,9 @@
                 throw new RepositoryException("Unable to create property: " + e.toString());
             }
         } else {
-
-            PropDef pd = getEffectiveNodeType().getApplicablePropertyDef(name, type, multiple);
-
             PropertyState propState = stateMgr.createNew(name, nodeState.getNodeId());
             propState.setType(type);
             propState.setMultiValued(multiple);
-            propState.setDefinitionId(pd.getId());
             propState.setValues(values);
 
             // need to store node state
@@ -560,10 +561,6 @@
         }
         NodeState state = stateMgr.createNew(id, nodeTypeName, parentId);
 
-        NodeDef cnd =
-                getEffectiveNodeType().getApplicableChildNodeDef(name, nodeTypeName, ntReg);
-        state.setDefinitionId(cnd.getId());
-
         // create Node instance wrapping new node state
         NodeStateEx node = new NodeStateEx(stateMgr, ntReg, state, name);
         node.setPropertyValue(NameConstants.JCR_PRIMARYTYPE, InternalValue.create(nodeTypeName));
@@ -589,10 +586,11 @@
         if (name == null) {
             name = src.getName();
         }
+        EffectiveNodeType ent = getEffectiveNodeType();
         // (4) check for name collisions
-        NodeDef def;
+        QNodeDefinition def;
         try {
-            def = getEffectiveNodeType().getApplicableChildNodeDef(name, nodeState.getNodeTypeName(), ntReg);
+            def = ent.getApplicableChildNodeDef(name, nodeState.getNodeTypeName(), ntReg);
         } catch (RepositoryException re) {
             String msg = "no definition found in parent node's node type for new node";
             throw new ConstraintViolationException(msg, re);
@@ -611,7 +609,9 @@
             } catch (ItemStateException e) {
                 throw new RepositoryException(e);
             }
-            if (!ntReg.getNodeDef(existingChild.getDefinitionId()).allowsSameNameSiblings()) {
+            QNodeDefinition existingChildDef = ent.getApplicableChildNodeDef(
+                    cne.getName(), existingChild.getNodeTypeName(), ntReg);
+            if (!existingChildDef.allowsSameNameSiblings()) {
                 throw new ItemExistsException(existingChild.toString());
             }
         } else {
@@ -646,8 +646,7 @@
             }
             NodeState srcState = src.getState();
             srcState.setParentId(getNodeId());
-            srcState.setDefinitionId(def.getId());
-            
+
             if (srcState.getStatus() == ItemState.STATUS_EXISTING) {
                 srcState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
             }
@@ -823,20 +822,29 @@
     }
 
     /**
-     * Returns the NodeDef for this state
+     * Returns the QNodeDefinition for this state
      * @return the node def
+     * @throws RepositoryException if an error occurs
      */
-    public NodeDef getDefinition() {
-        return ntReg.getNodeDef(nodeState.getDefinitionId());
+    public QNodeDefinition getDefinition() throws RepositoryException {
+        if (def == null) {
+            EffectiveNodeType ent = getParent().getEffectiveNodeType();
+            def = ent.getApplicableChildNodeDef(getName(),
+                    nodeState.getNodeTypeName(), ntReg);
+        }
+        return def;
     }
 
     /**
      * Returns the property definition for the property state
      * @param prop the property state
      * @return the prop def
+     * @throws RepositoryException if an error occurs
      */
-    public PropDef getDefinition(PropertyState prop) {
-        return ntReg.getPropDef(prop.getDefinitionId());
+    public QPropertyDefinition getDefinition(PropertyState prop)
+            throws RepositoryException {
+        return getEffectiveNodeType().getApplicablePropertyDef(
+                prop.getName(), prop.getType(), prop.isMultiValued());
     }
 
     /**

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImplRestore.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImplRestore.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImplRestore.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImplRestore.java Wed Oct 21 11:38:31 2009
@@ -34,7 +34,6 @@
 import org.apache.jackrabbit.core.ItemValidator;
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.id.NodeId;
-import org.apache.jackrabbit.core.nodetype.PropDef;
 import org.apache.jackrabbit.core.security.authorization.Permission;
 import org.apache.jackrabbit.core.state.ChildNodeEntry;
 import org.apache.jackrabbit.core.state.ItemStateException;
@@ -43,6 +42,7 @@
 import org.apache.jackrabbit.core.value.InternalValue;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.Path;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -428,7 +428,7 @@
         }
 
         // add 'auto-create' properties that do not exist yet
-        for (PropDef def: state.getEffectiveNodeType().getAutoCreatePropDefs()) {
+        for (QPropertyDefinition def: state.getEffectiveNodeType().getAutoCreatePropDefs()) {
             if (!state.hasProperty(def.getName())) {
                 InternalValue[] values = computeAutoValues(state, def, true);
                 if (values != null) {
@@ -644,14 +644,16 @@
      * @param def property definition
      * @param useDefaultValues if <code>true</code> the default values are respected
      * @return the values or <code>null</code>
+     * @throws RepositoryException if the values cannot be computed.
      */
-    private InternalValue[] computeAutoValues(NodeStateEx state, PropDef def,
-                                                     boolean useDefaultValues) {
+    private InternalValue[] computeAutoValues(NodeStateEx state, QPropertyDefinition def,
+                                              boolean useDefaultValues)
+            throws RepositoryException {
         // compute system generated values if necessary
         InternalValue[] values = session.getNodeTypeInstanceHandler().
                 computeSystemGeneratedPropertyValues(state.getState(), def);
         if (values == null && useDefaultValues) {
-            values = def.getDefaultValues();
+            values = InternalValue.create(def.getDefaultValues());
         }
         // avoid empty value array for single value property
         if (values != null && values.length == 0 && !def.isMultiple()) {

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/virtual/AbstractVISProvider.java Wed Oct 21 11:38:31 2009
@@ -20,11 +20,8 @@
 import org.apache.jackrabbit.core.id.NodeId;
 import org.apache.jackrabbit.core.id.PropertyId;
 import org.apache.jackrabbit.core.nodetype.EffectiveNodeType;
-import org.apache.jackrabbit.core.nodetype.NodeDef;
-import org.apache.jackrabbit.core.nodetype.NodeDefId;
 import org.apache.jackrabbit.core.nodetype.NodeTypeConflictException;
 import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
-import org.apache.jackrabbit.core.nodetype.PropDef;
 import org.apache.jackrabbit.core.state.ItemState;
 import org.apache.jackrabbit.core.state.ItemStateException;
 import org.apache.jackrabbit.core.state.NoSuchItemStateException;
@@ -34,8 +31,9 @@
 import org.apache.jackrabbit.core.state.ItemStateListener;
 import org.apache.jackrabbit.core.state.ChildNodeEntry;
 import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
+import org.apache.jackrabbit.spi.QNodeDefinition;
 import org.apache.jackrabbit.util.WeakIdentityCollection;
-import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -262,12 +260,10 @@
                                                     Name name, int type,
                                                     boolean multiValued)
             throws RepositoryException {
-        PropDef def = getApplicablePropertyDef(parent, name, type, multiValued);
         PropertyId id = new PropertyId(parent.getNodeId(), name);
         VirtualPropertyState prop = new VirtualPropertyState(id);
         prop.setType(type);
         prop.setMultiValued(multiValued);
-        prop.setDefinitionId(def.getId());
         return prop;
     }
 
@@ -278,25 +274,12 @@
                                             NodeId id, Name nodeTypeName)
             throws RepositoryException {
 
-        NodeDefId def;
-        try {
-            def = getApplicableChildNodeDef(parent, name, nodeTypeName).getId();
-        } catch (RepositoryException re) {
-            // hack, use nt:unstructured as parent
-            NodeTypeRegistry ntReg = getNodeTypeRegistry();
-            EffectiveNodeType ent = ntReg.getEffectiveNodeType(NameConstants.NT_UNSTRUCTURED);
-            NodeDef cnd = ent.getApplicableChildNodeDef(name, nodeTypeName, ntReg);
-            ntReg.getNodeDef(cnd.getId());
-            def = cnd.getId();
-        }
-
         // create a new node state
         VirtualNodeState state;
         if (id == null) {
             id = new NodeId();
         }
         state = new VirtualNodeState(this, parent.getNodeId(), id, nodeTypeName, new Name[0]);
-        state.setDefinitionId(def);
 
         cache(state);
         return state;
@@ -385,7 +368,7 @@
      * @return
      * @throws RepositoryException
      */
-    protected PropDef getApplicablePropertyDef(NodeState parent, Name propertyName,
+    protected QPropertyDefinition getApplicablePropertyDef(NodeState parent, Name propertyName,
                                                int type, boolean multiValued)
             throws RepositoryException {
         return getEffectiveNodeType(parent).getApplicablePropertyDef(propertyName, type, multiValued);
@@ -400,7 +383,7 @@
      * @return
      * @throws RepositoryException
      */
-    protected NodeDef getApplicableChildNodeDef(NodeState parent, Name nodeName, Name nodeTypeName)
+    protected QNodeDefinition getApplicableChildNodeDef(NodeState parent, Name nodeName, Name nodeTypeName)
             throws RepositoryException {
         return getEffectiveNodeType(parent).getApplicableChildNodeDef(
                 nodeName, nodeTypeName, getNodeTypeRegistry());

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/DefaultProtectedPropertyImporter.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/DefaultProtectedPropertyImporter.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/DefaultProtectedPropertyImporter.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/DefaultProtectedPropertyImporter.java Wed Oct 21 11:38:31 2009
@@ -20,9 +20,9 @@
 
 import org.apache.jackrabbit.core.NodeImpl;
 import org.apache.jackrabbit.core.state.NodeState;
-import org.apache.jackrabbit.core.nodetype.PropDef;
 import org.apache.jackrabbit.api.JackrabbitSession;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
 
 /**
  * Default implementation that isn't able to handle any protected properties.
@@ -46,18 +46,18 @@
     /**
      * Always returns <code>false</code>.
      *
-     * @see ProtectedPropertyImporter#handlePropInfo(org.apache.jackrabbit.core.NodeImpl, PropInfo, org.apache.jackrabbit.core.nodetype.PropDef)
+     * @see ProtectedPropertyImporter#handlePropInfo(org.apache.jackrabbit.core.NodeImpl, PropInfo, QPropertyDefinition)
      */
-    public boolean handlePropInfo(NodeImpl parent, PropInfo protectedPropInfo, PropDef def) {
+    public boolean handlePropInfo(NodeImpl parent, PropInfo protectedPropInfo, QPropertyDefinition def) {
         return false;
     }
 
     /**
      * Always returns <code>false</code>.
      *
-     * @see ProtectedPropertyImporter#handlePropInfo(org.apache.jackrabbit.core.state.NodeState, PropInfo, PropDef)
+     * @see ProtectedPropertyImporter#handlePropInfo(org.apache.jackrabbit.core.state.NodeState, PropInfo, QPropertyDefinition)
      */
-    public boolean handlePropInfo(NodeState parent, PropInfo protectedPropInfo, PropDef def) throws RepositoryException {
+    public boolean handlePropInfo(NodeState parent, PropInfo protectedPropInfo, QPropertyDefinition def) throws RepositoryException {
         return false;
     }
 }
\ No newline at end of file

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/PropInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/PropInfo.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/PropInfo.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/PropInfo.java Wed Oct 21 11:38:31 2009
@@ -23,12 +23,10 @@
 
 import org.apache.jackrabbit.core.NodeImpl;
 import org.apache.jackrabbit.core.nodetype.EffectiveNodeType;
-import org.apache.jackrabbit.core.nodetype.PropDef;
 import org.apache.jackrabbit.core.state.NodeState;
 import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Information about a property being imported. This class is used
@@ -79,7 +77,7 @@
         }
     }
 
-    public int getTargetType(PropDef def) {
+    public int getTargetType(QPropertyDefinition def) {
         int target = def.getRequiredType();
         if (target != PropertyType.UNDEFINED) {
             return target;
@@ -90,7 +88,7 @@
         }
     }
 
-    public PropDef getApplicablePropertyDef(EffectiveNodeType ent)
+    public QPropertyDefinition getApplicablePropertyDef(EffectiveNodeType ent)
             throws ConstraintViolationException {
         if (values.length == 1) {
             // could be single- or multi-valued (n == 1)

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/ProtectedPropertyImporter.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/ProtectedPropertyImporter.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/ProtectedPropertyImporter.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/ProtectedPropertyImporter.java Wed Oct 21 11:38:31 2009
@@ -19,12 +19,12 @@
 import javax.jcr.RepositoryException;
 
 import org.apache.jackrabbit.core.NodeImpl;
-import org.apache.jackrabbit.core.nodetype.PropDef;
 import org.apache.jackrabbit.core.state.NodeState;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
 
 /**
  * <code>ProtectedPropertyImporter</code> is in charge of importing single
- * properties whith a protected <code>PropDef</code>.
+ * properties whith a protected <code>QPropertyDefinition</code>.
  *
  * @see ProtectedNodeImporter for an abstract class used to import protected
  * nodes and the subtree below them.
@@ -42,7 +42,7 @@
      * <code>false</code> otherwise.
      * @throws RepositoryException If an error occurs.
      */
-    boolean handlePropInfo(NodeImpl parent, PropInfo protectedPropInfo, PropDef def)
+    boolean handlePropInfo(NodeImpl parent, PropInfo protectedPropInfo, QPropertyDefinition def)
             throws RepositoryException;
 
     /**
@@ -56,7 +56,7 @@
      * <code>false</code> otherwise.
      * @throws RepositoryException If an error occurs.
      */
-    boolean handlePropInfo(NodeState parent, PropInfo protectedPropInfo, PropDef def)
+    boolean handlePropInfo(NodeState parent, PropInfo protectedPropInfo, QPropertyDefinition def)
             throws RepositoryException;
 
 

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/SessionImporter.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/SessionImporter.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/SessionImporter.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/SessionImporter.java Wed Oct 21 11:38:31 2009
@@ -35,10 +35,10 @@
 import org.apache.jackrabbit.core.NodeImpl;
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.id.NodeId;
-import org.apache.jackrabbit.core.nodetype.PropDef;
 import org.apache.jackrabbit.core.security.authorization.Permission;
 import org.apache.jackrabbit.core.util.ReferenceChangeTracker;
 import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -153,7 +153,7 @@
     }
 
 
-    protected void createProperty(NodeImpl node, PropInfo pInfo, PropDef def) throws RepositoryException {
+    protected void createProperty(NodeImpl node, PropInfo pInfo, QPropertyDefinition def) throws RepositoryException {
         // convert serialized values to Value objects
         Value[] va = pInfo.getValues(pInfo.getTargetType(def), session);
 
@@ -369,7 +369,7 @@
 
         for (PropInfo pi : propInfos) {
             // find applicable definition
-            PropDef def = pi.getApplicablePropertyDef(node.getEffectiveNodeType());
+            QPropertyDefinition def = pi.getApplicablePropertyDef(node.getEffectiveNodeType());
             if (def.isProtected()) {
                 // skip protected property
                 log.debug("Skipping protected property " + pi.getName());

Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java?rev=827966&r1=827965&r2=827966&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java Wed Oct 21 11:38:31 2009
@@ -38,9 +38,7 @@
 import org.apache.jackrabbit.core.id.NodeId;
 import org.apache.jackrabbit.core.id.PropertyId;
 import org.apache.jackrabbit.core.nodetype.EffectiveNodeType;
-import org.apache.jackrabbit.core.nodetype.NodeDef;
 import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
-import org.apache.jackrabbit.core.nodetype.PropDef;
 import org.apache.jackrabbit.core.state.ChildNodeEntry;
 import org.apache.jackrabbit.core.state.NodeState;
 import org.apache.jackrabbit.core.state.PropertyState;
@@ -50,6 +48,8 @@
 import org.apache.jackrabbit.core.version.VersionHistoryInfo;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.Path;
+import org.apache.jackrabbit.spi.QNodeDefinition;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
 import org.apache.jackrabbit.spi.commons.conversion.MalformedPathException;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.slf4j.Logger;
@@ -348,7 +348,7 @@
 
     protected void processProperty(NodeState node, PropInfo pInfo) throws RepositoryException {
         PropertyState prop;
-        PropDef def;
+        QPropertyDefinition def;
 
         Name name = pInfo.getName();
         int type = pInfo.getType();
@@ -357,7 +357,7 @@
             // a property with that name already exists...
             PropertyId idExisting = new PropertyId(node.getNodeId(), name);
             prop = (PropertyState) itemOps.getItemState(idExisting);
-            def = ntReg.getPropDef(prop.getDefinitionId());
+            def = itemOps.findApplicablePropertyDefinition(prop.getName(), prop.getType(), prop.isMultiValued(), node);
             if (def.isProtected()) {
                 // skip protected property
                 log.debug("skipping protected property "
@@ -429,7 +429,7 @@
             InternalValue value)
             throws RepositoryException {
         if (!node.hasPropertyName(name)) {
-            PropDef def = itemOps.findApplicablePropertyDefinition(
+            QPropertyDefinition def = itemOps.findApplicablePropertyDefinition(
                     name, type, multiple, node);
             PropertyState prop = itemOps.createPropertyState(
                     node, name, type, def);
@@ -492,7 +492,8 @@
                         parent.getChildNodeEntry(nodeName, 1);
                 NodeId idExisting = entry.getId();
                 NodeState existing = (NodeState) itemOps.getItemState(idExisting);
-                NodeDef def = ntReg.getNodeDef(existing.getDefinitionId());
+                QNodeDefinition def = itemOps.findApplicableNodeDefinition(
+                        nodeName, existing.getNodeTypeName(), parent);
 
                 if (!def.allowsSameNameSiblings()) {
                     // existing doesn't allow same-name siblings,
@@ -528,7 +529,7 @@
                 // there's no node with that name...
                 if (id == null) {
                     // no potential uuid conflict, always create new node
-                    NodeDef def = itemOps.findApplicableNodeDefinition(
+                    QNodeDefinition def = itemOps.findApplicableNodeDefinition(
                             nodeName, ntName, parent);
                     if (def.isProtected()) {
                         // skip protected node
@@ -561,7 +562,7 @@
                         }
                     } catch (ItemNotFoundException e) {
                         // create new with given uuid
-                        NodeDef def = itemOps.findApplicableNodeDefinition(
+                        QNodeDefinition def = itemOps.findApplicableNodeDefinition(
                                 nodeName, ntName, parent);
                         if (def.isProtected()) {
                             // skip protected node