jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ste...@apache.org
Subject svn commit: r985211 - in /jackrabbit/trunk: jackrabbit-api/src/main/java/org/apache/jackrabbit/api/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ jackrabbit-jcr-rmi/
Date Fri, 13 Aug 2010 14:38:55 GMT
Author: stefan
Date: Fri Aug 13 14:38:55 2010
New Revision: 985211

URL: http://svn.apache.org/viewvc?rev=985211&view=rev
Log:
JCR-2683: Provide rename method for nodes

Added:
    jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/JackrabbitNode.java
Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionMoveOperation.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeState.java
    jackrabbit/trunk/jackrabbit-jcr-rmi/pom.xml

Added: jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/JackrabbitNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/JackrabbitNode.java?rev=985211&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/JackrabbitNode.java
(added)
+++ jackrabbit/trunk/jackrabbit-api/src/main/java/org/apache/jackrabbit/api/JackrabbitNode.java
Fri Aug 13 14:38:55 2010
@@ -0,0 +1,33 @@
+/*
+ * 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.api;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * The Jackrabbit Node interface. This interface contains the
+ * Jackrabbit-specific extensions to the JCR {@link javax.jcr.Node} interface.
+ */
+public interface JackrabbitNode {
+
+    /**
+     * 
+     * @param newName
+     * @throws javax.jcr.RepositoryException
+     */
+    void rename(String newName) throws RepositoryException;
+}

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java?rev=985211&r1=985210&r2=985211&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
Fri Aug 13 14:38:55 2010
@@ -64,6 +64,7 @@ import javax.jcr.version.VersionExceptio
 import javax.jcr.version.VersionHistory;
 import javax.jcr.version.VersionManager;
 
+import org.apache.jackrabbit.api.JackrabbitNode;
 import org.apache.jackrabbit.commons.JcrUtils;
 import org.apache.jackrabbit.commons.iterator.NodeIteratorAdapter;
 import org.apache.jackrabbit.commons.iterator.PropertyIteratorAdapter;
@@ -112,7 +113,7 @@ import org.slf4j.LoggerFactory;
 /**
  * <code>NodeImpl</code> implements the <code>Node</code> interface.
  */
-public class NodeImpl extends ItemImpl implements Node {
+public class NodeImpl extends ItemImpl implements Node, JackrabbitNode {
 
     private static Logger log = LoggerFactory.getLogger(NodeImpl.class);
 
@@ -555,12 +556,41 @@ public class NodeImpl extends ItemImpl i
         return node;
     }
 
+    /**
+     *
+     * @param oldName
+     * @param index
+     * @param id
+     * @param newName
+     * @throws RepositoryException
+     * @deprecated use #renameChildNode(NodeId, Name, boolean) 
+     */
     protected void renameChildNode(Name oldName, int index, NodeId id,
                                    Name newName)
             throws RepositoryException {
+        renameChildNode(id, newName, false);
+    }
+
+    /**
+     *
+     * @param id
+     * @param newName
+     * @param replace
+     * @throws RepositoryException
+     */
+    protected void renameChildNode(NodeId id, Name newName, boolean replace)
+            throws RepositoryException {
         // modify the state of 'this', i.e. the parent node
         NodeState thisState = (NodeState) getOrCreateTransientItemState();
-        thisState.renameChildNodeEntry(oldName, index, newName);
+        if (replace) {
+            // rename the specified child node by replacing the old
+            // child node entry with a new one at the same relative position
+            thisState.replaceChildNodeEntry(id, newName, id);
+        } else {
+            // rename the specified child node by removing the old and adding
+            // a new child node entry.
+            thisState.renameChildNodeEntry(id, newName);
+        }
     }
 
     protected void removeChildProperty(Name propName) throws RepositoryException {
@@ -3425,6 +3455,87 @@ public class NodeImpl extends ItemImpl i
                 InternalValue.create(state));
     }
 
+    //-------------------------------------------------------< JackrabbitNode >
+
+    /**
+     * {@inheritDoc}
+     */
+    public void rename(String newName) throws RepositoryException {
+        // check if this is the root node
+        if (getDepth() == 0) {
+            throw new RepositoryException("Cannot rename the root node");
+        }
+
+        Name qName;
+        try {
+            qName = session.getQName(newName);
+        } catch (NameException e) {
+            throw new RepositoryException("invalid node name: " + newName, e);
+        }
+
+        NodeImpl parent = (NodeImpl) getParent();
+
+        // check for name collisions
+        NodeImpl existing = null;
+        try {
+            existing = parent.getNode(qName);
+            // there's already a node with that name:
+            // check same-name sibling setting of existing node
+            if (!existing.getDefinition().allowsSameNameSiblings()) {
+                throw new ItemExistsException(
+                        "Same name siblings are not allowed: " + existing);
+            }
+        } catch (AccessDeniedException ade) {
+            // FIXME by throwing ItemExistsException we're disclosing too much information
+            throw new ItemExistsException();
+        } catch (ItemNotFoundException infe) {
+            // no name collision, fall through
+        }
+
+        // verify that parent node
+        // - is checked-out
+        // - is not protected neither by node type constraints nor by retention/hold
+        int options = ItemValidator.CHECK_CHECKED_OUT | ItemValidator.CHECK_LOCK |
+        ItemValidator.CHECK_CONSTRAINTS | ItemValidator.CHECK_HOLD | ItemValidator.CHECK_RETENTION;
+        sessionContext.getItemValidator().checkRemove(parent, options, Permission.NONE);
+        sessionContext.getItemValidator().checkModify(parent, options, Permission.NONE);
+
+        // check constraints
+        // get applicable definition of target node at new location
+        NodeTypeImpl nt = (NodeTypeImpl) getPrimaryNodeType();
+        org.apache.jackrabbit.spi.commons.nodetype.NodeDefinitionImpl newTargetDef;
+        try {
+            newTargetDef = parent.getApplicableChildNodeDefinition(qName, nt.getQName());
+        } catch (RepositoryException re) {
+            String msg = safeGetJCRPath() + ": no definition found in parent node's node
type for new node";
+            log.debug(msg);
+            throw new ConstraintViolationException(msg, re);
+        }
+        // if there's already a node with that name also check same-name sibling
+        // setting of new node; just checking same-name sibling setting on
+        // existing node is not sufficient since same-name sibling nodes don't
+        // necessarily have identical definitions
+        if (existing != null && !newTargetDef.allowsSameNameSiblings()) {
+            throw new ItemExistsException(
+                    "Same name siblings not allowed: " + existing);
+        }
+
+        // check permissions
+        AccessManager acMgr = sessionContext.getAccessManager();
+        if (!(acMgr.isGranted(getPrimaryPath(), Permission.REMOVE_NODE) &&
+                acMgr.isGranted(parent.getPrimaryPath(), qName, Permission.ADD_NODE | Permission.NODE_TYPE_MNGMT)))
{
+            String msg = "Not allowed to rename node " + safeGetJCRPath() + " to " + newName;
+            log.debug(msg);
+            throw new AccessDeniedException(msg);
+        }
+
+        // change definition
+        onRedefine(newTargetDef.unwrap());
+
+        // delegate to parent
+        parent.renameChildNode(getNodeId(), qName, true);
+    }
+
     //--------------------------------------------------------------< Object >
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionMoveOperation.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionMoveOperation.java?rev=985211&r1=985210&r2=985211&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionMoveOperation.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionMoveOperation.java
Fri Aug 13 14:38:55 2010
@@ -181,7 +181,7 @@ public class SessionMoveOperation implem
             // change definition of target
             targetNode.onRedefine(newTargetDef.unwrap());
             // do rename
-            destParentNode.renameChildNode(srcName.getName(), index, targetId, destName.getName());
+            destParentNode.renameChildNode(targetId, destName.getName(), false);
         } else {
             // check shareable case
             if (targetNode.getNodeState().isShareable()) {

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeState.java?rev=985211&r1=985210&r2=985211&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeState.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeState.java
Fri Aug 13 14:38:55 2010
@@ -330,7 +330,7 @@ public class NodeState extends ItemState
     }
 
     /**
-     * Renames a  <code>ChildNodeEntry</code> by removing the old entry and
+     * Renames a <code>ChildNodeEntry</code> by removing the old entry and
      * appending the new entry to the end of the list.
      *
      * @param oldName <code>Name</code> object specifying the entry's old name
@@ -341,10 +341,27 @@ public class NodeState extends ItemState
      */
     public boolean renameChildNodeEntry(Name oldName, int index,
                                                      Name newName) {
+        ChildNodeEntry oldEntry = childNodeEntries.get(oldName, index);;
+        if (oldEntry != null) {
+            return renameChildNodeEntry(oldEntry.getId(), newName);
+        }
+        return false;
+    }
+
+    /**
+     * Renames a <code>ChildNodeEntry</code> by removing the old entry and
+     * appending the new entry to the end of the list.
+     *
+     * @param id id the entry to be renamed is refering to.
+     * @param newName <code>Name</code> object specifying the entry's new name
+     * @return <code>true</code> if the entry was successfully renamed;
+     *         otherwise <code>false</code>
+     */
+    public boolean renameChildNodeEntry(NodeId id, Name newName) {
         ChildNodeEntry oldEntry = null;
         ChildNodeEntry newEntry = null;
         synchronized (this) {
-            oldEntry = childNodeEntries.remove(oldName, index);
+            oldEntry = childNodeEntries.remove(id);
             if (oldEntry != null) {
                 newEntry =
                     childNodeEntries.add(newName, oldEntry.getId());
@@ -359,6 +376,39 @@ public class NodeState extends ItemState
     }
 
     /**
+     * Replaces the <code>ChildNodeEntry</code> identified by <code>oldId</code>
+     * with a new entry. Note that the entry will <i>overwrite</i> the old
+     * entry at the same relative position within the child node entries list.
+     *
+     * @param oldId id the entry to be replaced is refering to.
+     * @param newName <code>Name</code> object specifying the entry's new name
+     * @param newId the id the new entry is refering to.
+     * @return <code>true</code> if the entry was successfully replaced;
+     *         otherwise <code>false</code>
+     */
+    public boolean replaceChildNodeEntry(NodeId oldId, Name newName, NodeId newId) {
+        synchronized (this) {
+            ChildNodeEntry oldEntry = childNodeEntries.get(oldId);
+            if (oldEntry == null) {
+                return false;
+            }
+
+            ChildNodeEntries entries = new ChildNodeEntries();
+            for (ChildNodeEntry entry : childNodeEntries.list()) {
+                if (entry.getId() == oldId) {
+                    entries.add(newName, newId);
+                } else {
+                    entries.add(entry.getName(), entry.getId());
+                }
+            }
+            childNodeEntries = entries;
+        }
+
+        notifyNodesReplaced();
+        return true;
+    }
+
+    /**
      * Removes a <code>ChildNodeEntry</code>.
      *
      * @param nodeName <code>ChildNodeEntry</code> object specifying a node name

Modified: jackrabbit/trunk/jackrabbit-jcr-rmi/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-rmi/pom.xml?rev=985211&r1=985210&r2=985211&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-rmi/pom.xml (original)
+++ jackrabbit/trunk/jackrabbit-jcr-rmi/pom.xml Fri Aug 13 14:38:55 2010
@@ -656,7 +656,7 @@ org.apache.jackrabbit.test.api.version.W
     <dependency>
       <groupId>org.apache.jackrabbit</groupId>
       <artifactId>jackrabbit-jcr-commons</artifactId>
-      <version>2.0.0</version>
+        <version>2.2-SNAPSHOT</version>
       <scope>provided</scope>
     </dependency>
     
@@ -664,7 +664,7 @@ org.apache.jackrabbit.test.api.version.W
     <dependency>
       <groupId>org.apache.jackrabbit</groupId>
       <artifactId>jackrabbit-api</artifactId>
-      <version>2.0.0</version>
+        <version>2.2-SNAPSHOT</version>
       <scope>provided</scope>
     </dependency>
 



Mime
View raw message