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 2006/10/18 13:30:51 UTC
svn commit: r465218 -
/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java
Author: jukka
Date: Wed Oct 18 04:30:50 2006
New Revision: 465218
URL: http://svn.apache.org/viewvc?view=rev&rev=465218
Log:
JCR-569: Applied the WorkspaceImporter refactoring patch from Nicolas Toper.
Modified:
jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java
Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java?view=diff&rev=465218&r1=465217&r2=465218
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java Wed Oct 18 04:30:50 2006
@@ -16,6 +16,23 @@
*/
package org.apache.jackrabbit.core.xml;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Stack;
+
+import javax.jcr.AccessDeniedException;
+import javax.jcr.ImportUUIDBehavior;
+import javax.jcr.ItemExistsException;
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.ValueFormatException;
+import javax.jcr.lock.LockException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.version.VersionException;
+import javax.jcr.version.VersionHistory;
+
import org.apache.jackrabbit.core.BatchedItemOperations;
import org.apache.jackrabbit.core.HierarchyManager;
import org.apache.jackrabbit.core.NodeId;
@@ -39,36 +56,23 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.jcr.ImportUUIDBehavior;
-import javax.jcr.ItemExistsException;
-import javax.jcr.ItemNotFoundException;
-import javax.jcr.PathNotFoundException;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.lock.LockException;
-import javax.jcr.nodetype.ConstraintViolationException;
-import javax.jcr.version.VersionException;
-import javax.jcr.version.VersionHistory;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Stack;
-
/**
- * <code>WorkspaceImporter</code> ...
+ * WorkspaceImporter. It imports the content submitted to it
+ * by the Content Handler
+ *
*/
public class WorkspaceImporter implements Importer {
private static Logger log = LoggerFactory.getLogger(WorkspaceImporter.class);
-
private final NodeState importTarget;
- private final WorkspaceImpl wsp;
private final NodeTypeRegistry ntReg;
private final HierarchyManager hierMgr;
private final BatchedItemOperations itemOps;
-
private final int uuidBehavior;
- private boolean aborted;
+ //It is not useful anymore: we never abort: we raise an exception.
+ // I suggest to delete it. Do you see any issue with this?
+ private boolean aborted = false;
private Stack parents;
/**
@@ -77,12 +81,31 @@
*/
private final ReferenceChangeTracker refTracker;
+ // Unused for now. It will be used in the next iteration on JIRA
+ private boolean raw = false;
+
+ /**
+ * True if we skip the tree with current node as root
+ */
+ private boolean skip = false;
+
/**
- * Creates a new <code>WorkspaceImporter</code> instance.
+ * Used to find when stopping skipping
+ */
+ private NodeInfo skipNode;
+
+ /**
+ * True if this node already exist
+ */
+ private NodeState existing = null;
+ private WorkspaceImpl wsp;
+
+ /**
+ * Creates a new <code>sWorkspaceImporter</code> instance.
*
* @param parentPath target path where to add the imported subtree
- * @param wsp
- * @param ntReg
+ * @param wsp the workspace we want to import content to
+ * @param ntReg the NodeTypeRegistry of the repository
* @param uuidBehavior flag that governs how incoming UUIDs are handled
* @throws PathNotFoundException if no node exists at
* <code>parentPath</code> or if the
@@ -98,108 +121,195 @@
* @throws RepositoryException if another error occurs
*/
public WorkspaceImporter(Path parentPath,
- WorkspaceImpl wsp,
- NodeTypeRegistry ntReg,
- int uuidBehavior)
- throws PathNotFoundException, ConstraintViolationException,
- VersionException, LockException, RepositoryException {
-
+ WorkspaceImpl wsp,
+ NodeTypeRegistry ntReg,
+ int uuidBehavior)
+ throws PathNotFoundException, ConstraintViolationException,
+ VersionException, LockException, RepositoryException {
SessionImpl ses = (SessionImpl) wsp.getSession();
itemOps = new BatchedItemOperations(wsp.getItemStateManager(),
ntReg, ses.getLockManager(), ses, wsp.getHierarchyManager(),
ses.getNamespaceResolver());
- hierMgr = wsp.getHierarchyManager();
- // perform preliminary checks
+ this.hierMgr = wsp.getHierarchyManager();
+ //Perform preliminary checks
itemOps.verifyCanWrite(parentPath);
importTarget = itemOps.getNodeState(parentPath);
-
this.wsp = wsp;
this.ntReg = ntReg;
this.uuidBehavior = uuidBehavior;
-
aborted = false;
-
refTracker = new ReferenceChangeTracker();
-
parents = new Stack();
parents.push(importTarget);
}
/**
- * @param parent
- * @param conflicting
- * @param nodeInfo
- * @return
- * @throws RepositoryException
+ * Performs some checks to know if the node is importable or not.
+ * If it is a serious issue, raises an exception, else return false.
+ * this subtree.
+ * <br/>
+ * Performs also if needed some remapping.
+ *
+ * @param parent the parent NodeState
+ * @param nodeInfo NodeInfo passed by the ContentHandler
+ * @param propInfo PropInfo passed by the ContentHandler
+ * @return true if the node is fine; else false
+ * @throws RepositoryException if some constraints checks are not OK
+ * @throws ItemExistsException if the item exist
+ * @throws ItemNotFoundException if some constraints checks are not OK (shouldn't happen)
+ * @throws LockException if some constraints checks are not OK
+ * @throws VersionException if some constraints checks are not OK
+ * @throws AccessDeniedException if some constraints checks are not OK
+ * @throws ConstraintViolationException if some constraints checks are not OK
*/
- protected NodeState resolveUUIDConflict(NodeState parent,
- NodeState conflicting,
- NodeInfo nodeInfo)
- throws RepositoryException {
+ private boolean checkNode(NodeState parent, NodeInfo nodeInfo, List propInfo)
+ throws ConstraintViolationException, AccessDeniedException, VersionException,
+ LockException, ItemNotFoundException, ItemExistsException, RepositoryException {
+ itemOps.checkAddNode(parent, nodeInfo.getName(), nodeInfo.getNodeTypeName(),
+ BatchedItemOperations.CHECK_ACCESS
+ | BatchedItemOperations.CHECK_CONSTRAINTS
+ | BatchedItemOperations.CHECK_LOCK
+ | BatchedItemOperations.CHECK_VERSIONING);
+
+ QName nodeName = nodeInfo.getName();
+ QName ntName = nodeInfo.getNodeTypeName();
+
+ if (parent.hasChildNodeEntry(nodeName)) {
+ // a node with that name already exists...
+ //No need to check for more than one, since if it
+ //is the case we can import it.
+ NodeState.ChildNodeEntry entry =
+ parent.getChildNodeEntry(nodeName, 1);
+ NodeId idExisting = entry.getId();
+ NodeState existing = (NodeState) itemOps.getItemState(idExisting);
+ NodeDef def = ntReg.getNodeDef(existing.getDefinitionId());
+ if (!def.allowsSameNameSiblings()) {
+ // existing doesn't allow same-name siblings,
+ // check for potential conflicts
+ EffectiveNodeType entExisting =
+ itemOps.getEffectiveNodeType(existing);
+ if (!raw && def.isProtected() && entExisting.includesNodeType(ntName)) {
+ return false;
+ }
- NodeState node;
- if (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW) {
- // create new with new uuid:
- // check if new node can be added (check access rights &
- // node type constraints only, assume locking & versioning status
- // has already been checked on ancestor)
- itemOps.checkAddNode(parent, nodeInfo.getName(),
- nodeInfo.getNodeTypeName(),
- BatchedItemOperations.CHECK_ACCESS
- | BatchedItemOperations.CHECK_CONSTRAINTS);
- node = itemOps.createNodeState(parent, nodeInfo.getName(),
- nodeInfo.getNodeTypeName(), nodeInfo.getMixinNames(), null);
- // remember uuid mapping
- EffectiveNodeType ent = itemOps.getEffectiveNodeType(node);
- if (ent.includesNodeType(QName.MIX_REFERENCEABLE)) {
- refTracker.mappedUUID(nodeInfo.getId().getUUID(), node.getNodeId().getUUID());
+ if (def.isAutoCreated() && entExisting.includesNodeType(ntName)) {
+ // this node has already been auto-created,
+ // no need to create it
+ this.existing = existing;
+ } else {
+ throw new ItemExistsException(itemOps.safeGetJCRPath(existing.getNodeId()));
+ }
}
- } else if (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW) {
- String msg = "a node with uuid " + nodeInfo.getId()
- + " already exists!";
- log.debug(msg);
- throw new ItemExistsException(msg);
- } else if (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING) {
- // make sure conflicting node is not importTarget or an ancestor thereof
- Path p0 = hierMgr.getPath(importTarget.getNodeId());
- Path p1 = hierMgr.getPath(conflicting.getNodeId());
- try {
- if (p1.equals(p0) || p1.isAncestorOf(p0)) {
- String msg = "cannot remove ancestor node";
- log.debug(msg);
- throw new ConstraintViolationException(msg);
+ }
+
+ if (parent.hasPropertyName(nodeName)) {
+ /**
+ * a property with the same name already exists; if this property
+ * has been imported as well (e.g. through document view import
+ * where an element can have the same name as one of the attributes
+ * of its parent element) we have to rename the onflicting property;
+ *
+ * see http://issues.apache.org/jira/browse/JCR-61
+ */
+ PropertyId propId = new PropertyId(parent.getNodeId(), nodeName);
+ PropertyState conflicting = itemOps.getPropertyState(propId);
+ if (conflicting.getStatus() == ItemState.STATUS_NEW) {
+ // assume this property has been imported as well;
+ // rename conflicting property
+ // @todo use better reversible escaping scheme to create unique name
+ QName newName = new QName(nodeName.getNamespaceURI(), nodeName.getLocalName() + "_");
+ if (parent.hasPropertyName(newName)) {
+ newName = new QName(newName.getNamespaceURI(), newName.getLocalName() + "_");
}
- } catch (MalformedPathException mpe) {
- // should never get here...
- String msg = "internal error: failed to determine degree of relationship";
- log.error(msg, mpe);
- throw new RepositoryException(msg, mpe);
+ PropertyState newProp =
+ itemOps.createPropertyState(parent, newName,
+ conflicting.getType(), conflicting.getValues().length);
+ newProp.setValues(conflicting.getValues());
+ parent.removePropertyName(nodeName);
+ itemOps.store(parent);
+ itemOps.destroy(conflicting);
}
- // remove conflicting:
- // check if conflicting can be removed
- // (access rights, node type constraints, locking & versioning status)
- itemOps.checkRemoveNode(conflicting,
- BatchedItemOperations.CHECK_ACCESS
- | BatchedItemOperations.CHECK_LOCK
- | BatchedItemOperations.CHECK_VERSIONING
- | BatchedItemOperations.CHECK_CONSTRAINTS);
- // do remove conflicting (recursive)
- itemOps.removeNodeState(conflicting);
+ }
- // create new with given uuid:
- // check if new node can be added (check access rights &
- // node type constraints only, assume locking & versioning status
- // has already been checked on ancestor)
- itemOps.checkAddNode(parent, nodeInfo.getName(),
- nodeInfo.getNodeTypeName(),
- BatchedItemOperations.CHECK_ACCESS
- | BatchedItemOperations.CHECK_CONSTRAINTS);
+ return true;
+ }
+
+ /**
+ * Create propoerties on a specific NodeState
+ * @param myNode the NodeState
+ * @param propInfos PropInfo
+ * @throws ItemNotFoundException if issue in the NodeState
+ * @throws ItemExistsException if issue in the NodeState
+ * @throws ConstraintViolationException if issue in the NodeState
+ * @throws ValueFormatException if issue in the NodeState
+ * @throws RepositoryException if issue in the NodeState
+ */
+ private void createProperties(NodeState myNode, List propInfos)
+ throws ItemNotFoundException, ItemExistsException, ConstraintViolationException,
+ ValueFormatException, RepositoryException {
+ // process properties
+ Iterator iter = propInfos.iterator();
+ while (iter.hasNext()) {
+ PropInfo pi = (PropInfo) iter.next();
+ pi.apply(myNode, itemOps, ntReg, refTracker);
+ }
+ }
+
+ /**
+ * Create the specific NodeState
+ * @param parent NodeState
+ * @param nodeInfo NodeInfo
+ * @return newly create NodeState
+ * @throws ConstraintViolationException if we cannot create the NodeState
+ * @throws RepositoryException if we cannot create the NodeState
+ */
+ private NodeState createNode(NodeState parent, NodeInfo nodeInfo) throws ConstraintViolationException, RepositoryException {
+
+ NodeDef def =
+ itemOps.findApplicableNodeDefinition(nodeInfo.getName(), nodeInfo.getNodeTypeName(), parent);
+
+ // potential uuid conflict
+ NodeState conflicting = null;
+ NodeState node;
+
+ try {
+ if (nodeInfo.getId() != null) {
+ conflicting = itemOps.getNodeState(nodeInfo.getId());
+ }
+ } catch (ItemNotFoundException infe) {
+ conflicting = null;
+ }
+ if (conflicting != null) {
+ // resolve uuid conflict
+ node = resolveUUIDConflict(parent, conflicting, nodeInfo);
+ }
+ else {
// do create new node
- node = itemOps.createNodeState(parent, nodeInfo.getName(),
- nodeInfo.getNodeTypeName(), nodeInfo.getMixinNames(),
- nodeInfo.getId());
- } else if (uuidBehavior == ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING) {
+ node = itemOps.createNodeState(parent, nodeInfo.getName(), nodeInfo.getNodeTypeName(),
+ nodeInfo.getMixinNames(), null, def);
+ }
+ return node;
+ }
+
+ /**
+ * Resolve UUID conflict if any.
+ *
+ * @param parent NodeState
+ * @param conflicting NodeState
+ * @param nodeInfo NodeInfo
+ * @return the new conflicting NodeState
+ * @throws ItemExistsException
+ * @throws ConstraintViolationException
+ * @throws IllegalStateException
+ * @throws RepositoryException
+ */
+ private NodeState resolveUUIDConflict(NodeState parent, NodeState conflicting, NodeInfo nodeInfo)
+ throws ItemExistsException, ConstraintViolationException, IllegalStateException, RepositoryException {
+ NodeState node = null;
+ switch (uuidBehavior) {
+
+ case ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING:
NodeId parentId = conflicting.getParentId();
if (parentId == null) {
String msg = "root node cannot be replaced";
@@ -225,34 +335,83 @@
| BatchedItemOperations.CHECK_CONSTRAINTS);
// do remove conflicting (recursive)
itemOps.removeNodeState(conflicting);
- // create new with given uuid at same location as conflicting:
- // check if new node can be added at other location
+ // do create new node
+ node = itemOps.createNodeState(parent, nodeInfo.getName(),
+ nodeInfo.getNodeTypeName(), nodeInfo.getMixinNames(),
+ nodeInfo.getId());
+ break;
+
+ case ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING:
+ // make sure conflicting node is not importTarget or an ancestor thereof
+ Path p0 = hierMgr.getPath(importTarget.getNodeId());
+ Path p1 = hierMgr.getPath(conflicting.getNodeId());
+ try {
+ if (p1.equals(p0) || p1.isAncestorOf(p0)) {
+ String msg = "cannot remove ancestor node";
+ log.debug(msg);
+ throw new ConstraintViolationException(msg);
+ }
+ } catch (MalformedPathException mpe) {
+ // should never get here...
+ String msg = "internal error: failed to determine degree of relationship";
+ log.error(msg, mpe);
+ throw new RepositoryException(msg, mpe);
+ }
+ // remove conflicting:
+ // check if conflicting can be removed
// (access rights, node type constraints, locking & versioning status)
- itemOps.checkAddNode(parent, nodeInfo.getName(),
- nodeInfo.getNodeTypeName(),
+ itemOps.checkRemoveNode(conflicting,
BatchedItemOperations.CHECK_ACCESS
| BatchedItemOperations.CHECK_LOCK
| BatchedItemOperations.CHECK_VERSIONING
| BatchedItemOperations.CHECK_CONSTRAINTS);
+ // do remove conflicting (recursive)
+ itemOps.removeNodeState(conflicting);
+
+ // create new with given uuid:
// do create new node
node = itemOps.createNodeState(parent, nodeInfo.getName(),
nodeInfo.getNodeTypeName(), nodeInfo.getMixinNames(),
nodeInfo.getId());
- } else {
- String msg = "unknown uuidBehavior: " + uuidBehavior;
+ break;
+
+ case ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW:
+ String msg = "a node with uuid " + nodeInfo.getId()
+ + " already exists!";
log.debug(msg);
- throw new RepositoryException(msg);
- }
+ throw new ItemExistsException(msg);
+ case ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW:
+ // create new with new uuid:
+ // check if new node can be added (check access rights &
+ // node type constraints only, assume locking & versioning status
+ // has already been checked on ancestor)
+ node = itemOps.createNodeState(parent, nodeInfo.getName(),
+ nodeInfo.getNodeTypeName(), nodeInfo.getMixinNames(), null);
+ // remember uuid mapping
+ EffectiveNodeType ent = itemOps.getEffectiveNodeType(node);
+ if (ent.includesNodeType(QName.MIX_REFERENCEABLE)) {
+ refTracker.mappedUUID(nodeInfo.getId().getUUID(), node.getNodeId().getUUID());
+ }
+ break;
+ //No need for default case.
+ }
return node;
}
/**
+ * @return true if skip mode is on.
+ */
+ protected boolean isSkipped() {
+ return skip;
+ }
+
+ /**
* Post-process imported node (initialize properties with special
* semantics etc.)
*
- * @param node
- * @throws RepositoryException
+ * @param node NodeState to postprocess
+ * @throws RepositoryException if issue when postprocessing a node
*/
protected void postProcessNode(NodeState node) throws RepositoryException {
/**
@@ -319,6 +478,7 @@
}
}
+
//-------------------------------------------------------------< Importer >
/**
* {@inheritDoc}
@@ -339,213 +499,58 @@
* {@inheritDoc}
*/
public void startNode(NodeInfo nodeInfo, List propInfos)
- throws RepositoryException {
+ throws RepositoryException {
if (aborted) {
- // the import has been aborted, get outta here...
return;
}
- boolean succeeded = false;
- NodeState parent;
- try {
- // check sanity of workspace/session first
- wsp.sanityCheck();
-
- parent = (NodeState) parents.peek();
+ NodeState parent = (NodeState) parents.peek();
- // process node
-
- NodeState node = null;
- NodeId id = nodeInfo.getId();
- QName nodeName = nodeInfo.getName();
- QName ntName = nodeInfo.getNodeTypeName();
- QName[] mixins = nodeInfo.getMixinNames();
-
- if (parent == null) {
- // parent node was skipped, skip this child node also
- parents.push(null); // push null onto stack for skipped node
- succeeded = true;
- log.debug("skipping node " + nodeName);
- return;
- }
- if (parent.hasChildNodeEntry(nodeName)) {
- // a node with that name already exists...
- NodeState.ChildNodeEntry entry =
- parent.getChildNodeEntry(nodeName, 1);
- NodeId idExisting = entry.getId();
- NodeState existing = (NodeState) itemOps.getItemState(idExisting);
- NodeDef def = ntReg.getNodeDef(existing.getDefinitionId());
-
- if (!def.allowsSameNameSiblings()) {
- // existing doesn't allow same-name siblings,
- // check for potential conflicts
- EffectiveNodeType entExisting =
- itemOps.getEffectiveNodeType(existing);
- if (def.isProtected() && entExisting.includesNodeType(ntName)) {
- // skip protected node
- parents.push(null); // push null onto stack for skipped node
- succeeded = true;
- log.debug("skipping protected node "
- + itemOps.safeGetJCRPath(existing.getNodeId()));
- return;
- }
- if (def.isAutoCreated() && entExisting.includesNodeType(ntName)) {
- // this node has already been auto-created,
- // no need to create it
- node = existing;
- } else {
- throw new ItemExistsException(itemOps.safeGetJCRPath(existing.getNodeId()));
- }
- }
- }
-
- if (node == null) {
- // there's no node with that name...
- if (id == null) {
- // no potential uuid conflict, always create new node
-
- NodeDef def =
- itemOps.findApplicableNodeDefinition(nodeName, ntName, parent);
- if (def.isProtected()) {
- // skip protected node
- parents.push(null); // push null onto stack for skipped node
- succeeded = true;
- log.debug("skipping protected node " + nodeName);
- return;
- }
-
- if (parent.hasPropertyName(nodeName)) {
- /**
- * a property with the same name already exists; if this property
- * has been imported as well (e.g. through document view import
- * where an element can have the same name as one of the attributes
- * of its parent element) we have to rename the onflicting property;
- *
- * see http://issues.apache.org/jira/browse/JCR-61
- */
- PropertyId propId = new PropertyId(parent.getNodeId(), nodeName);
- PropertyState conflicting = itemOps.getPropertyState(propId);
- if (conflicting.getStatus() == ItemState.STATUS_NEW) {
- // assume this property has been imported as well;
- // rename conflicting property
- // @todo use better reversible escaping scheme to create unique name
- QName newName = new QName(nodeName.getNamespaceURI(), nodeName.getLocalName() + "_");
- if (parent.hasPropertyName(newName)) {
- newName = new QName(newName.getNamespaceURI(), newName.getLocalName() + "_");
- }
- PropertyState newProp =
- itemOps.createPropertyState(parent, newName,
- conflicting.getType(), conflicting.getValues().length);
- newProp.setValues(conflicting.getValues());
- parent.removePropertyName(nodeName);
- itemOps.store(parent);
- itemOps.destroy(conflicting);
- }
- }
-
- // check if new node can be added (check access rights &
- // node type constraints only, assume locking & versioning status
- // has already been checked on ancestor)
- itemOps.checkAddNode(parent, nodeName, ntName,
- BatchedItemOperations.CHECK_ACCESS
- | BatchedItemOperations.CHECK_CONSTRAINTS);
- // do create new node
- node = itemOps.createNodeState(parent, nodeName, ntName, mixins, null, def);
- } else {
- // potential uuid conflict
- NodeState conflicting;
-
- try {
- conflicting = itemOps.getNodeState(id);
- } catch (ItemNotFoundException infe) {
- conflicting = null;
- }
- if (conflicting != null) {
- // resolve uuid conflict
- node = resolveUUIDConflict(parent, conflicting, nodeInfo);
- } else {
- // create new with given uuid
-
- NodeDef def =
- itemOps.findApplicableNodeDefinition(nodeName, ntName, parent);
- if (def.isProtected()) {
- // skip protected node
- parents.push(null); // push null onto stack for skipped node
- succeeded = true;
- log.debug("skipping protected node " + nodeName);
- return;
- }
-
- // check if new node can be added (check access rights &
- // node type constraints only, assume locking & versioning status
- // has already been checked on ancestor)
- itemOps.checkAddNode(parent, nodeName, ntName,
- BatchedItemOperations.CHECK_ACCESS
- | BatchedItemOperations.CHECK_CONSTRAINTS);
- // do create new node
- node = itemOps.createNodeState(parent, nodeName, ntName, mixins, id, def);
- }
- }
- }
-
- // process properties
-
- Iterator iter = propInfos.iterator();
- while (iter.hasNext()) {
- PropInfo pi = (PropInfo) iter.next();
- pi.apply(node, itemOps, ntReg, refTracker);
- }
-
- // store affected nodes
- itemOps.store(node);
- itemOps.store(parent);
+ if (raw && !checkNode(parent, nodeInfo, propInfos)) {
+ skip = true;
+ }
- // push current node onto stack of parents
- parents.push(node);
+ if (skip) {
+ return;
+ }
- succeeded = true;
- } finally {
- if (!succeeded) {
- // update operation failed, cancel all modifications
- aborted = true;
- itemOps.cancel();
- }
+ NodeState myNode;
+ if (existing == null) {
+ myNode = createNode(parent, nodeInfo);
+ }
+ else {
+ myNode = existing;
+ existing = null;
}
+ createProperties(myNode, propInfos);
+ parents.push(myNode);
}
/**
* {@inheritDoc}
*/
public void endNode(NodeInfo nodeInfo) throws RepositoryException {
- if (aborted) {
- // the import has been aborted, get outta here...
+ //End of skip mode
+ if (skipNode != null && skipNode.equals(nodeInfo)) {
+ skip = false;
+ skipNode = null;
return;
}
- NodeState node = (NodeState) parents.pop();
- if (node == null) {
- // node was skipped, nothing to do here
+
+ if (aborted || skip) {
return;
}
- boolean succeeded = false;
- try {
- // check sanity of workspace/session first
- wsp.sanityCheck();
-
- // post-process node (initialize properties with special semantics etc.)
- postProcessNode(node);
- // make sure node is valid according to its definition
- itemOps.validate(node);
+ try {
+ NodeState node = (NodeState) parents.pop();
- // we're done with that node, now store its state
- itemOps.store(node);
- succeeded = true;
- } finally {
- if (!succeeded) {
- // update operation failed, cancel all modifications
- aborted = true;
- itemOps.cancel();
+ if (!raw) {
+ this.postProcessNode(node);
}
+ itemOps.store(node);
+ } catch (IllegalStateException e) {
+ itemOps.cancel();
+ aborted = true;
}
}
@@ -554,66 +559,54 @@
*/
public void end() throws RepositoryException {
if (aborted) {
- // the import has been aborted, get outta here...
+ itemOps.cancel();
return;
}
- boolean succeeded = false;
- try {
- // check sanity of workspace/session first
- wsp.sanityCheck();
-
- /**
- * adjust references that refer to uuid's which have been mapped to
- * newly gererated uuid's on import
- */
- Iterator iter = refTracker.getProcessedReferences();
- while (iter.hasNext()) {
- PropertyState prop = (PropertyState) iter.next();
- // being paranoid...
- if (prop.getType() != PropertyType.REFERENCE) {
- continue;
- }
- boolean modified = false;
- InternalValue[] values = prop.getValues();
- InternalValue[] newVals = new InternalValue[values.length];
- for (int i = 0; i < values.length; i++) {
- InternalValue val = values[i];
- UUID original = (UUID) val.internalValue();
- UUID adjusted = refTracker.getMappedUUID(original);
- if (adjusted != null) {
- newVals[i] = InternalValue.create(adjusted);
- modified = true;
- } else {
- // reference doesn't need adjusting, just copy old value
- newVals[i] = val;
- }
- }
- if (modified) {
- prop.setValues(newVals);
- itemOps.store(prop);
+ wsp.sanityCheck();
+ /**
+ * adjust references that refer to uuid's which have been mapped to
+ * newly gererated uuid's on import
+ */
+ Iterator iter = refTracker.getProcessedReferences();
+ while (iter.hasNext()) {
+ PropertyState prop = (PropertyState) iter.next();
+ // being paranoid...
+ if (prop.getType() != PropertyType.REFERENCE) {
+ continue;
+ }
+ boolean modified = false;
+ InternalValue[] values = prop.getValues();
+ InternalValue[] newVals = new InternalValue[values.length];
+ for (int i = 0; i < values.length; i++) {
+ InternalValue val = values[i];
+ UUID original = (UUID) val.internalValue();
+ UUID adjusted = refTracker.getMappedUUID(original);
+ if (adjusted != null) {
+ newVals[i] = InternalValue.create(adjusted);
+ modified = true;
+ } else {
+ // reference doesn't need adjusting, just copy old value
+ newVals[i] = val;
}
}
- refTracker.clear();
-
- // make sure import target is valid according to its definition
- itemOps.validate(importTarget);
-
- // finally store the state of the import target
- // (the parent of the imported subtree)
- itemOps.store(importTarget);
- succeeded = true;
- } finally {
- if (!succeeded) {
- // update operation failed, cancel all modifications
- aborted = true;
- itemOps.cancel();
+ if (modified) {
+ prop.setValues(newVals);
+ itemOps.store(prop);
}
}
+ refTracker.clear();
- if (!aborted) {
- // finish update
- itemOps.update();
- }
+ // make sure import target is valid according to its definition
+ itemOps.validate(importTarget);
+
+ // finally store the state of the import target
+ // (the parent of the imported subtree)
+ itemOps.store(importTarget);
+
+ // finish update
+ itemOps.update();
}
+
}
+