use of org.apache.jackrabbit.core.state.ItemStateException in project jackrabbit by apache.
the class VersionManagerImplMerge method merge.
/**
* Merge the given activity to this workspace
*
* @param activity internal activity
* @param failedIds list of failed ids
* @throws RepositoryException if an error occurs
*/
protected void merge(InternalActivity activity, List<ItemId> failedIds) throws RepositoryException {
VersionSet changeSet = activity.getChangeSet();
WriteOperation ops = startWriteOperation();
try {
Iterator<NodeId> iter = changeSet.versions().keySet().iterator();
while (iter.hasNext()) {
InternalVersion v = changeSet.versions().remove(iter.next());
NodeStateEx state = getNodeStateEx(v.getFrozenNode().getFrozenId());
if (state != null) {
InternalVersion base = getBaseVersion(state);
// but merge it anyways
if (base.isMoreRecent(v)) {
failedIds.add(state.getNodeId());
// add it to the jcr:mergeFailed property
Set<NodeId> set = getMergeFailed(state);
set.add(base.getId());
setMergeFailed(state, set);
state.store();
} else {
for (InternalVersion restored : internalRestore(state, v, changeSet, true)) {
changeSet.versions().remove(restored.getVersionHistory().getId());
}
}
}
// reset iterator
iter = changeSet.versions().keySet().iterator();
}
ops.save();
} catch (ItemStateException e) {
throw new RepositoryException(e);
} finally {
ops.close();
}
}
use of org.apache.jackrabbit.core.state.ItemStateException in project jackrabbit by apache.
the class NodeStateEx method getName.
/**
* returns the name of this node
*
* @return the name of this node
*/
public Name getName() {
if (name == null) {
try {
NodeId parentId = nodeState.getParentId();
NodeState parent = (NodeState) stateMgr.getItemState(parentId);
name = parent.getChildNodeEntry(nodeState.getNodeId()).getName();
} catch (ItemStateException e) {
// should never occur
throw new IllegalStateException(e.toString());
}
}
return name;
}
use of org.apache.jackrabbit.core.state.ItemStateException in project jackrabbit by apache.
the class VersionManagerImpl method mergeOrUpdate.
/**
* Combines merge and update method
* @param state the state to merge or update
* @param srcWorkspaceName source workspace name
* @param failedIds list that will contain the failed ids.
* if <code>null</code> and update will be performed.
* @param bestEffort best effort flag
* @param isShallow is shallow flag
* @throws RepositoryException if an error occurs
*/
private void mergeOrUpdate(NodeStateEx state, String srcWorkspaceName, List<ItemId> failedIds, boolean bestEffort, boolean isShallow) throws RepositoryException {
// if same workspace, ignore
if (!srcWorkspaceName.equals(session.getWorkspace().getName())) {
// check authorization for specified workspace
if (!session.getAccessManager().canAccess(srcWorkspaceName)) {
String msg = "not authorized to access " + srcWorkspaceName;
log.error(msg);
throw new AccessDeniedException(msg);
}
// get root node of src workspace
SessionImpl srcSession = null;
try {
// create session on other workspace for current subject
// (may throw NoSuchWorkspaceException and AccessDeniedException)
srcSession = ((RepositoryImpl) session.getRepository()).createSession(session.getSubject(), srcWorkspaceName);
WorkspaceImpl srcWsp = (WorkspaceImpl) srcSession.getWorkspace();
NodeId rootNodeId = ((NodeImpl) srcSession.getRootNode()).getNodeId();
NodeStateEx srcRoot = new NodeStateEx(srcWsp.getItemStateManager(), ntReg, rootNodeId);
merge(state, srcRoot, failedIds, bestEffort, isShallow);
} catch (ItemStateException e) {
throw new RepositoryException(e);
} finally {
if (srcSession != null) {
// we don't need the other session anymore, logout
srcSession.logout();
}
}
}
}
use of org.apache.jackrabbit.core.state.ItemStateException in project jackrabbit by apache.
the class ConsistencyCheck method checkIndexConsistency.
private void checkIndexConsistency() throws IOException {
log.info("Checking index consistency");
// Ids of multiple nodes in the index
Set<NodeId> multipleEntries = new HashSet<NodeId>();
CachingMultiIndexReader reader = index.getIndexReader();
try {
for (int i = 0; i < reader.maxDoc(); i++) {
if (i > 10 && i % (reader.maxDoc() / 5) == 0) {
long progress = Math.round((100.0 * (float) i) / ((float) reader.maxDoc() * 2f));
log.info("progress: " + progress + "%");
}
if (reader.isDeleted(i)) {
continue;
}
Document d = reader.document(i, FieldSelectors.UUID);
NodeId id = new NodeId(d.get(FieldNames.UUID));
if (!isIgnored(id)) {
boolean nodeExists = nodeIds.containsKey(id);
if (nodeExists) {
Boolean alreadyIndexed = nodeIds.put(id, Boolean.TRUE);
if (alreadyIndexed) {
multipleEntries.add(id);
}
} else {
errors.add(new NodeDeleted(id));
}
}
}
} finally {
reader.release();
}
// create multiple entries errors
for (NodeId id : multipleEntries) {
errors.add(new MultipleEntries(id));
}
reader = index.getIndexReader();
try {
// run through documents again and check parent
for (int i = 0; i < reader.maxDoc(); i++) {
if (i > 10 && i % (reader.maxDoc() / 5) == 0) {
long progress = Math.round((100.0 * (float) i) / ((float) reader.maxDoc() * 2f));
log.info("progress: " + (progress + 50) + "%");
}
if (reader.isDeleted(i)) {
continue;
}
Document d = reader.document(i, FieldSelectors.UUID_AND_PARENT);
NodeId id = new NodeId(d.get(FieldNames.UUID));
if (!nodeIds.containsKey(id) || isIgnored(id)) {
// this node is ignored or was already marked for deletion
continue;
}
String parent = d.get(FieldNames.PARENT);
if (parent == null || parent.isEmpty()) {
continue;
}
final NodeId parentId = new NodeId(parent);
boolean parentExists = nodeIds.containsKey(parentId);
boolean parentIndexed = parentExists && nodeIds.get(parentId);
if (parentIndexed) {
continue;
} else if (id.equals(RepositoryImpl.SYSTEM_ROOT_NODE_ID) && parentId.equals(RepositoryImpl.ROOT_NODE_ID)) {
// special case for the /jcr:system node
continue;
}
// parent is missing from index
if (parentExists) {
errors.add(new MissingAncestor(id, parentId));
} else {
try {
final ItemState itemState = stateMgr.getItemState(id);
if (parentId.equals(itemState.getParentId())) {
// orphaned node
errors.add(new UnknownParent(id, parentId));
} else {
errors.add(new WrongParent(id, parentId, itemState.getParentId()));
}
} catch (ItemStateException ignored) {
}
}
}
} finally {
reader.release();
}
}
use of org.apache.jackrabbit.core.state.ItemStateException in project jackrabbit by apache.
the class NodeImpl method setMixins.
/**
* {@inheritDoc}
*/
public void setMixins(String[] mixinNames) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException {
// check state of this instance
sanityCheck();
NodeTypeManagerImpl ntMgr = sessionContext.getNodeTypeManager();
Set<Name> newMixins = new HashSet<Name>();
for (String name : mixinNames) {
Name qName = sessionContext.getQName(name);
if (!ntMgr.getNodeType(qName).isMixin()) {
throw new RepositoryException(sessionContext.getJCRName(qName) + " is not a mixin node type");
}
newMixins.add(qName);
}
// make sure this node is checked-out, neither protected nor locked and
// the editing session has sufficient permission to change the mixin types.
// special handling of mix:(simple)versionable. since adding the
// mixin alters the version storage jcr:versionManagement privilege
// is required in addition.
int permissions = Permission.NODE_TYPE_MNGMT;
if (newMixins.contains(MIX_VERSIONABLE) || newMixins.contains(MIX_SIMPLE_VERSIONABLE)) {
permissions |= Permission.VERSION_MNGMT;
}
int options = ItemValidator.CHECK_CHECKED_OUT | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_CONSTRAINTS | ItemValidator.CHECK_HOLD;
sessionContext.getItemValidator().checkModify(this, options, permissions);
final NodeState state = data.getNodeState();
// build effective node type of primary type & new mixin's
// in order to detect conflicts
NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry();
EffectiveNodeType entNew, entOld, entAll;
try {
entNew = ntReg.getEffectiveNodeType(newMixins);
entOld = ntReg.getEffectiveNodeType(state.getMixinTypeNames());
// try to build new effective node type (will throw in case of conflicts)
entAll = ntReg.getEffectiveNodeType(state.getNodeTypeName(), newMixins);
} catch (NodeTypeConflictException ntce) {
throw new ConstraintViolationException(ntce.getMessage());
}
// added child item definitions
Set<QItemDefinition> addedDefs = new HashSet<QItemDefinition>(Arrays.asList(entNew.getAllItemDefs()));
addedDefs.removeAll(Arrays.asList(entOld.getAllItemDefs()));
// referential integrity check
boolean referenceableOld = getEffectiveNodeType().includesNodeType(NameConstants.MIX_REFERENCEABLE);
boolean referenceableNew = entAll.includesNodeType(NameConstants.MIX_REFERENCEABLE);
if (referenceableOld && !referenceableNew) {
// node would become non-referenceable;
// make sure no references exist
PropertyIterator iter = getReferences();
if (iter.hasNext()) {
throw new ConstraintViolationException("the new mixin types cannot be set as it would render " + "this node 'non-referenceable' while it is still being " + "referenced through at least one property of type REFERENCE");
}
}
// gather currently assigned definitions *before* doing actual modifications
Map<ItemId, ItemDefinition> oldDefs = new HashMap<ItemId, ItemDefinition>();
for (Name name : getNodeState().getPropertyNames()) {
PropertyId id = new PropertyId(getNodeId(), name);
try {
PropertyState propState = (PropertyState) stateMgr.getItemState(id);
oldDefs.put(id, itemMgr.getDefinition(propState));
} catch (ItemStateException ise) {
String msg = name + ": failed to retrieve property state";
log.error(msg, ise);
throw new RepositoryException(msg, ise);
}
}
for (ChildNodeEntry cne : getNodeState().getChildNodeEntries()) {
try {
NodeState nodeState = (NodeState) stateMgr.getItemState(cne.getId());
oldDefs.put(cne.getId(), itemMgr.getDefinition(nodeState));
} catch (ItemStateException ise) {
String msg = cne + ": failed to retrieve node state";
log.error(msg, ise);
throw new RepositoryException(msg, ise);
}
}
// now do the actual modifications in content as mandated by the new mixins
// modify the state of this node
NodeState thisState = (NodeState) getOrCreateTransientItemState();
thisState.setMixinTypeNames(newMixins);
// set jcr:mixinTypes property
setMixinTypesProperty(newMixins);
// walk through properties and child nodes and change definition as necessary
// use temp set to avoid ConcurrentModificationException
HashSet<Name> set = new HashSet<Name>(thisState.getPropertyNames());
for (Name propName : set) {
PropertyState propState = null;
try {
propState = (PropertyState) stateMgr.getItemState(new PropertyId(thisState.getNodeId(), propName));
// the following call triggers ConstraintViolationException
// if there isn't any suitable definition anymore
itemMgr.getDefinition(propState);
} catch (ConstraintViolationException cve) {
// redefine property if possible
try {
if (oldDefs.get(propState.getId()).isProtected()) {
// remove 'orphaned' protected properties immediately
removeChildProperty(propName);
continue;
}
PropertyDefinitionImpl pdi = getApplicablePropertyDefinition(propName, propState.getType(), propState.isMultiValued(), false);
PropertyImpl prop = (PropertyImpl) itemMgr.getItem(propState.getId());
if (pdi.getRequiredType() != PropertyType.UNDEFINED && pdi.getRequiredType() != propState.getType()) {
// value conversion required
if (propState.isMultiValued()) {
// convert value
Value[] values = ValueHelper.convert(prop.getValues(), pdi.getRequiredType(), getSession().getValueFactory());
// redefine property
prop.onRedefine(pdi.unwrap());
// set converted values
prop.setValue(values);
} else {
// convert value
Value value = ValueHelper.convert(prop.getValue(), pdi.getRequiredType(), getSession().getValueFactory());
// redefine property
prop.onRedefine(pdi.unwrap());
// set converted values
prop.setValue(value);
}
} else {
// redefine property
prop.onRedefine(pdi.unwrap());
}
// update collection of added definitions
addedDefs.remove(pdi.unwrap());
} catch (ValueFormatException vfe) {
// value conversion failed, remove it
removeChildProperty(propName);
} catch (ConstraintViolationException cve1) {
// no suitable definition found for this property,
// remove it
removeChildProperty(propName);
}
} catch (ItemStateException ise) {
String msg = propName + ": failed to retrieve property state";
log.error(msg, ise);
throw new RepositoryException(msg, ise);
}
}
// use temp array to avoid ConcurrentModificationException
ArrayList<ChildNodeEntry> list = new ArrayList<ChildNodeEntry>(thisState.getChildNodeEntries());
// start from tail to avoid problems with same-name siblings
for (int i = list.size() - 1; i >= 0; i--) {
ChildNodeEntry entry = list.get(i);
NodeState nodeState = null;
try {
nodeState = (NodeState) stateMgr.getItemState(entry.getId());
// the following call triggers ConstraintViolationException
// if there isn't any suitable definition anymore
itemMgr.getDefinition(nodeState);
} catch (ConstraintViolationException cve) {
// redefine node if possible
try {
if (oldDefs.get(nodeState.getId()).isProtected()) {
// remove 'orphaned' protected child node immediately
removeChildNode(entry.getId());
continue;
}
NodeDefinitionImpl ndi = getApplicableChildNodeDefinition(entry.getName(), nodeState.getNodeTypeName());
NodeImpl node = (NodeImpl) itemMgr.getItem(nodeState.getId());
// redefine node
node.onRedefine(ndi.unwrap());
// update collection of added definitions
addedDefs.remove(ndi.unwrap());
} catch (ConstraintViolationException cve1) {
// no suitable definition found for this child node,
// remove it
removeChildNode(entry.getId());
}
} catch (ItemStateException ise) {
String msg = entry + ": failed to retrieve node state";
log.error(msg, ise);
throw new RepositoryException(msg, ise);
}
}
// and at the same time were not present with the old mixins
for (QItemDefinition def : addedDefs) {
if (def.isAutoCreated()) {
if (def.definesNode()) {
NodeDefinitionImpl ndi = ntMgr.getNodeDefinition((QNodeDefinition) def);
createChildNode(def.getName(), (NodeTypeImpl) ndi.getDefaultPrimaryType(), null);
} else {
PropertyDefinitionImpl pdi = ntMgr.getPropertyDefinition((QPropertyDefinition) def);
createChildProperty(pdi.unwrap().getName(), pdi.getRequiredType(), pdi);
}
}
}
}
Aggregations