void restoreFrozenState(InternalFrozenNode freeze, VersionSelector vsel, Set restored, boolean removeExisting)
throws RepositoryException {
// 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);
}
}