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/08/03 18:48:46 UTC
svn commit: r800464 -
/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
Author: jukka
Date: Mon Aug 3 16:48:46 2009
New Revision: 800464
URL: http://svn.apache.org/viewvc?rev=800464&view=rev
Log:
JCR-1972: Preserving UUID and document version history on repository migration
Added the Node.addNodeWithUuid() method signatures contributed by Paco Avila.
Streamlined and documented much of the addNode functionality.
Modified:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
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=800464&r1=800463&r2=800464&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 Mon Aug 3 16:48:46 2009
@@ -622,131 +622,6 @@
setRemoved();
}
- protected NodeImpl internalAddNode(String relPath, NodeTypeImpl nodeType)
- throws ItemExistsException, PathNotFoundException, VersionException,
- ConstraintViolationException, LockException, RepositoryException {
- return internalAddNode(relPath, nodeType, null);
- }
-
- protected NodeImpl internalAddNode(String relPath, NodeTypeImpl nodeType,
- NodeId id)
- throws ItemExistsException, PathNotFoundException, VersionException,
- ConstraintViolationException, LockException, RepositoryException {
- Path nodePath;
- Name nodeName;
- Path parentPath;
- try {
- nodePath =
- PathFactoryImpl.getInstance().create(getPrimaryPath(), session.getQPath(relPath), false)
- .getCanonicalPath();
- if (nodePath.getNameElement().getIndex() != 0) {
- String msg = "illegal subscript specified: " + nodePath;
- log.debug(msg);
- throw new RepositoryException(msg);
- }
- nodeName = nodePath.getNameElement().getName();
- parentPath = nodePath.getAncestor(1);
- } catch (NameException e) {
- String msg =
- "failed to resolve path " + relPath + " relative to " + this;
- log.debug(msg);
- throw new RepositoryException(msg, e);
- }
-
- NodeImpl parentNode;
- try {
- Item parent = itemMgr.getItem(parentPath);
- if (!parent.isNode()) {
- String msg = "cannot add a node to property " + parentPath;
- log.debug(msg);
- throw new ConstraintViolationException(msg);
- }
- parentNode = (NodeImpl) parent;
- } catch (AccessDeniedException ade) {
- throw new PathNotFoundException(relPath);
- }
-
- // make sure that parent node is checked-out and not locked
- int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_CHECKED_OUT;
- session.getValidator().checkModify(parentNode, options, Permission.NONE);
-
- // delegate the creation of the child node to the parent node
- return parentNode.internalAddChildNode(nodeName, nodeType, id);
- }
-
- protected NodeImpl internalAddChildNode(Name nodeName,
- NodeTypeImpl nodeType)
- throws ItemExistsException, ConstraintViolationException,
- RepositoryException {
- return internalAddChildNode(nodeName, nodeType, null);
- }
-
- protected NodeImpl internalAddChildNode(Name nodeName,
- NodeTypeImpl nodeType, NodeId id)
- throws ItemExistsException, ConstraintViolationException,
- RepositoryException {
- Path nodePath;
- try {
- nodePath = PathFactoryImpl.getInstance().create(getPrimaryPath(), nodeName, true);
- } catch (MalformedPathException e) {
- // should never happen
- String msg = "internal error: invalid path " + this;
- log.debug(msg);
- throw new RepositoryException(msg, e);
- }
-
- Name nodeTypeName = null;
- if (nodeType != null) {
- nodeTypeName = nodeType.getQName();
- if (nodeType.isMixin()) {
- throw new ConstraintViolationException(session.getJCRName(nodeTypeName) + ": not a primary node type.");
- }
- if (nodeType.isAbstract()) {
- throw new ConstraintViolationException(session.getJCRName(nodeTypeName) + ": is an abstract node type.");
- }
- }
- NodeDefinitionImpl def;
- try {
- def = getApplicableChildNodeDefinition(nodeName, nodeTypeName);
- } catch (RepositoryException re) {
- String msg = "no definition found in parent node's node type for new node";
- log.debug(msg);
- throw new ConstraintViolationException(msg, re);
- }
- if (nodeType == null) {
- // use default node type
- nodeType = (NodeTypeImpl) def.getDefaultPrimaryType();
- } else {
- // adding a node with explicit specifying the node type name
- // requires the editing session to have nt_management privilege.
- session.getAccessManager().checkPermission(nodePath, Permission.NODE_TYPE_MNGMT);
- }
-
- // check for name collisions
- NodeState thisState = data.getNodeState();
- ChildNodeEntry cne = thisState.getChildNodeEntry(nodeName, 1);
- if (cne != null) {
- // there's already a child node entry with that name;
- // check same-name sibling setting of new node
- if (!def.allowsSameNameSiblings()) {
- throw new ItemExistsException(itemMgr.safeGetJCRPath(nodePath));
- }
- // check same-name sibling setting of existing node
- NodeId newId = cne.getId();
- if (!((NodeImpl) itemMgr.getItem(newId)).getDefinition().allowsSameNameSiblings()) {
- throw new ItemExistsException(itemMgr.safeGetJCRPath(nodePath));
- }
- }
-
- // check protected flag of parent (i.e. this) node and retention/hold
- int options = ItemValidator.CHECK_CONSTRAINTS | ItemValidator.CHECK_HOLD
- | ItemValidator.CHECK_RETENTION;
- session.getValidator().checkModify(this, options, Permission.NONE);
-
- // now do create the child node
- return createChildNode(nodeName, def, nodeType, id);
- }
-
private void setMixinTypesProperty(Set<Name> mixinNames) throws RepositoryException {
NodeState thisState = data.getNodeState();
// get or create jcr:mixinTypes property
@@ -1533,29 +1408,81 @@
* @param id id of the new node or <code>null</code> if a new
* id should be assigned
* @return the newly added node
- * @throws ItemExistsException
- * @throws NoSuchNodeTypeException
- * @throws VersionException
- * @throws ConstraintViolationException
- * @throws LockException
- * @throws RepositoryException
+ * @throws RepositoryException if the node can not added
*/
- public synchronized NodeImpl addNode(Name nodeName, Name nodeTypeName,
- NodeId id)
- throws ItemExistsException, NoSuchNodeTypeException, VersionException,
- ConstraintViolationException, LockException, RepositoryException {
+ public synchronized NodeImpl addNode(
+ Name nodeName, Name nodeTypeName, NodeId id)
+ throws RepositoryException {
// check state of this instance
sanityCheck();
- // make sure this node is checked-out and not locked by another session.
- int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_CHECKED_OUT;
- session.getValidator().checkModify(this, options, Permission.NONE);
+ Path nodePath = PathFactoryImpl.getInstance().create(
+ getPrimaryPath(), nodeName, true);
+ // Check the explicitly specified node type (if any)
NodeTypeImpl nt = null;
if (nodeTypeName != null) {
nt = session.getNodeTypeManager().getNodeType(nodeTypeName);
+ if (nt.isMixin()) {
+ throw new ConstraintViolationException(
+ "Unable to add a node with a mixin node type: "
+ + session.getJCRName(nodeTypeName));
+ } else if (nt.isAbstract()) {
+ throw new ConstraintViolationException(
+ "Unable to add a node with an abstract node type: "
+ + session.getJCRName(nodeTypeName));
+ } else {
+ // adding a node with explicit specifying the node type name
+ // requires the editing session to have nt_management privilege.
+ session.getAccessManager().checkPermission(
+ nodePath, Permission.NODE_TYPE_MNGMT);
+ }
}
- return internalAddChildNode(nodeName, nt, id);
+
+ // Get the applicable child node definition for this node.
+ NodeDefinitionImpl def;
+ try {
+ def = getApplicableChildNodeDefinition(nodeName, nodeTypeName);
+ } catch (RepositoryException e) {
+ throw new ConstraintViolationException(
+ "No child node definition for "
+ + session.getJCRName(nodeName) + " found in " + this, e);
+ }
+
+ // Use default node type from child node definition if needed
+ if (nt == null) {
+ nt = (NodeTypeImpl) def.getDefaultPrimaryType();
+ }
+
+ // check for name collisions
+ NodeState thisState = data.getNodeState();
+ ChildNodeEntry cne = thisState.getChildNodeEntry(nodeName, 1);
+ if (cne != null) {
+ // there's already a child node entry with that name;
+ // check same-name sibling setting of new node
+ if (!def.allowsSameNameSiblings()) {
+ throw new ItemExistsException(
+ "This node already exists: "
+ + itemMgr.safeGetJCRPath(nodePath));
+ }
+ // check same-name sibling setting of existing node
+ NodeImpl existing = itemMgr.getNode(cne.getId(), getNodeId());
+ if (!existing.getDefinition().allowsSameNameSiblings()) {
+ throw new ItemExistsException(
+ "Same-name siblings not allowed for " + existing);
+ }
+ }
+
+ // check protected flag of parent (i.e. this) node and retention/hold
+ // make sure this node is checked-out and not locked by another session.
+ int options =
+ ItemValidator.CHECK_LOCK | ItemValidator.CHECK_CHECKED_OUT
+ | ItemValidator.CHECK_CONSTRAINTS | ItemValidator.CHECK_HOLD
+ | ItemValidator.CHECK_RETENTION;
+ session.getValidator().checkModify(this, options, Permission.NONE);
+
+ // now do create the child node
+ return createChildNode(nodeName, def, nt, id);
}
/**
@@ -2048,31 +1975,116 @@
return (Node) itemMgr.getItem(parentId);
}
- //-----------------------------------------------------------------< Node >
+ //----------------------------------------------------------------< Node >
+
/**
* {@inheritDoc}
*/
- public synchronized Node addNode(String relPath)
- throws ItemExistsException, PathNotFoundException, VersionException,
- ConstraintViolationException, LockException, RepositoryException {
- // check state of this instance
- sanityCheck();
-
- return internalAddNode(relPath, null);
+ public Node addNode(String relPath) throws RepositoryException {
+ return addNodeWithUuid(relPath, null, null);
}
/**
* {@inheritDoc}
*/
- public synchronized Node addNode(String relPath, String nodeTypeName)
- throws ItemExistsException, PathNotFoundException,
- NoSuchNodeTypeException, VersionException,
- ConstraintViolationException, LockException, RepositoryException {
+ public Node addNode(String relPath, String nodeTypeName)
+ throws RepositoryException {
+ return addNodeWithUuid(relPath, nodeTypeName, null);
+ }
+
+ /**
+ * Adds a node with the given UUID. You can only add a node with a UUID
+ * that is not already assigned to another node in this workspace.
+ *
+ * @since Apache Jackrabbit 1.6
+ * @see <a href="https://issues.apache.org/jira/browse/JCR-1972">JCR-1972</a>
+ * @see Node#addNode(String)
+ * @param relPath path of the new node
+ * @param uuid UUID of the new node,
+ * or <code>null</code> for a random new UUID
+ * @return the newly added node
+ * @throws RepositoryException if the node can not be added
+ */
+ public Node addNodeWithUuid(String relPath, String uuid)
+ throws RepositoryException {
+ return addNodeWithUuid(relPath, null, uuid);
+ }
+
+ /**
+ * Adds a node with the given node type and UUID. You can only add a node
+ * with a UUID that is not already assigned to another node in this
+ * workspace.
+ *
+ * @since Apache Jackrabbit 1.6
+ * @see <a href="https://issues.apache.org/jira/browse/JCR-1972">JCR-1972</a>
+ * @see Node#addNode(String, String)
+ * @param relPath path of the new node
+ * @param nodeTypeName name of the new node's node type,
+ * or <code>null</code> for automatic type assignment
+ * @param uuid UUID of the new node,
+ * or <code>null</code> for a random new UUID
+ * @return the newly added node
+ * @throws RepositoryException if the node can not be added
+ */
+ public synchronized Node addNodeWithUuid(
+ String relPath, String nodeTypeName, String uuid)
+ throws RepositoryException {
// check state of this instance
sanityCheck();
- NodeTypeImpl nt = (NodeTypeImpl) session.getNodeTypeManager().getNodeType(nodeTypeName);
- return internalAddNode(relPath, nt);
+ // Get the canonical path of the new node
+ Path path;
+ try {
+ path = PathFactoryImpl.getInstance().create(
+ getPrimaryPath(), session.getQPath(relPath), true);
+ } catch (NameException e) {
+ throw new RepositoryException(
+ "Failed to resolve path " + relPath
+ + " relative to " + this, e);
+ }
+
+ // Get the last path element and check that it's a simple name
+ Path.Element last = path.getNameElement();
+ if (!last.denotesName() || last.getIndex() != 0) {
+ throw new RepositoryException(
+ "Invalid last path element for adding node "
+ + relPath + " relative to " + this);
+ }
+
+ // Get the parent node instance
+ NodeImpl parentNode;
+ Path parentPath = path.getAncestor(1);
+ try {
+ parentNode = itemMgr.getNode(parentPath);
+ } catch (PathNotFoundException e) {
+ if (itemMgr.propertyExists(parentPath)) {
+ throw new ConstraintViolationException(
+ "Unable to add a child node to property "
+ + session.getJCRPath(parentPath));
+ }
+ throw e;
+ } catch (AccessDeniedException ade) {
+ throw new PathNotFoundException(
+ "Failed to resolve path " + relPath + " relative to " + this);
+ }
+
+ // Resolve node type name (if any)
+ Name typeName = null;
+ if (nodeTypeName != null) {
+ typeName = session.getQName(nodeTypeName);
+ }
+
+ // Check that the given UUID (if any) does not already exist
+ NodeId id = null;
+ if (uuid != null) {
+ id = new NodeId(uuid);
+ if (itemMgr.itemExists(id)) {
+ throw new ItemExistsException(
+ "A node with this UUID already exists: " + uuid);
+ }
+ }
+
+ return parentNode.addNode(last.getName(), typeName, id);
}
/**