// check uuid
if (isNodeType(QName.MIX_REFERENCEABLE)) {
UUID uuid = freeze.getFrozenUUID();
if (!internalGetUUID().equals(uuid)) {
throw new ItemExistsException("Unable to restore version of " + safeGetJCRPath() + ". UUID changed.");
}
}
// check primary type
if (!freeze.getFrozenPrimaryType().equals(primaryTypeName)) {
// todo: check with spec what should happen here
throw new ItemExistsException("Unable to restore version of " + safeGetJCRPath() + ". PrimaryType changed.");
}
// adjust mixins
QName[] mixinNames = freeze.getFrozenMixinTypes();
setMixinTypesProperty(new HashSet(Arrays.asList(mixinNames)));
// copy frozen properties
PropertyState[] props = freeze.getFrozenProperties();
HashSet propNames = new HashSet();
for (int i = 0; i < props.length; i++) {
PropertyState prop = props[i];
propNames.add(prop.getName());
if (prop.isMultiValued()) {
internalSetProperty(props[i].getName(), prop.getValues());
} else {
internalSetProperty(props[i].getName(), prop.getValues()[0]);
}
}
// remove properties that do not exist in the frozen representation
PropertyIterator piter = getProperties();
while (piter.hasNext()) {
PropertyImpl prop = (PropertyImpl) piter.nextProperty();
// ignore some props that are not well guarded by the OPV
if (prop.getQName().equals(QName.JCR_VERSIONHISTORY)) {
continue;
} else if (prop.getQName().equals(QName.JCR_PREDECESSORS)) {
continue;
}
if (prop.getDefinition().getOnParentVersion() == OnParentVersionAction.COPY
|| prop.getDefinition().getOnParentVersion() == OnParentVersionAction.VERSION) {
if (!propNames.contains(prop.getQName())) {
removeChildProperty(prop.getQName());
}
}
}
// add 'auto-create' properties that do not exist yet
NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
for (int j = 0; j < mixinNames.length; j++) {
NodeTypeImpl mixin = ntMgr.getNodeType(mixinNames[j]);
PropertyDefinition[] pda = mixin.getAutoCreatedPropertyDefinitions();
for (int i = 0; i < pda.length; i++) {
PropertyDefinitionImpl pd = (PropertyDefinitionImpl) pda[i];
if (!hasProperty(pd.getQName())) {
createChildProperty(pd.getQName(), pd.getRequiredType(), pd);
}
}
}
// first delete some of the version histories
NodeIterator iter = getNodes();
while (iter.hasNext()) {
NodeImpl n = (NodeImpl) iter.nextNode();
if (n.getDefinition().getOnParentVersion() == OnParentVersionAction.COPY) {
// only remove OPV=Copy nodes
n.internalRemove(true);
} else if (n.getDefinition().getOnParentVersion() == OnParentVersionAction.VERSION) {
// only remove, if node to be restored does not contain child,
// or if restored child is not versionable
UUID vhUUID = n.hasProperty(QName.JCR_VERSIONHISTORY)
? new UUID(n.getProperty(QName.JCR_VERSIONHISTORY).getString())
: null;
if (vhUUID == null || !freeze.hasFrozenHistory(vhUUID)) {
n.internalRemove(true);
}
}
}
// restore the frozen nodes
InternalFreeze[] frozenNodes = freeze.getFrozenChildNodes();
for (int i = 0; i < frozenNodes.length; i++) {
InternalFreeze child = frozenNodes[i];
NodeImpl restoredChild = null;
if (child instanceof InternalFrozenNode) {
InternalFrozenNode f = (InternalFrozenNode) child;
// check for existing
if (f.getFrozenUUID() != null) {
try {
NodeImpl existing = (NodeImpl) session.getNodeByUUID(f.getFrozenUUID());
// check if one of this restoretrees node
if (removeExisting) {
existing.remove();
} else {
// since we delete the OPV=Copy children beforehand, all
// found nodes must be outside of this tree
throw new ItemExistsException("Unable to restore node, item already exists outside of restored tree: "
+ existing.safeGetJCRPath());
}
} catch (ItemNotFoundException e) {
// ignore, item with uuid does not exist
}
}
restoredChild = addNode(f.getName(), f);
restoredChild.restoreFrozenState(f, vsel, restored, removeExisting);
} else if (child instanceof InternalFrozenVersionHistory) {
InternalFrozenVersionHistory f = (InternalFrozenVersionHistory) child;
VersionHistory history = (VersionHistory) session.getNodeById(f.getVersionHistoryId());
NodeId nodeId = NodeId.valueOf(history.getVersionableUUID());
String oldVersion = "jcr:dummy";
// check if representing versionable already exists somewhere
if (itemMgr.itemExists(nodeId)) {
NodeImpl n = session.getNodeById(nodeId);
if (removeExisting) {
String dstPath = getPath() + "/" + n.getName();
if (!n.getPath().equals(dstPath)) {
session.move(n.getPath(), dstPath);
}
oldVersion = n.getBaseVersion().getName();
} else if (n.getParent().isSame(this)) {
n.internalRemove(true);
} else {
// since we delete the OPV=Copy children beforehand, all
// found nodes must be outside of this tree
throw new ItemExistsException("Unable to restore node, item already exists outside of restored tree: "
+ n.safeGetJCRPath());
}
}
// get desired version from version selector
VersionImpl v = (VersionImpl) vsel.select(history);