use of org.apache.jackrabbit.core.state.NodeState in project jackrabbit by apache.
the class SearchIndexConsistencyCheckTest method testIndexContainsMultipleEntries.
public void testIndexContainsMultipleEntries() throws Exception {
Session s = getHelper().getSuperuserSession();
SearchManager searchManager = TestHelper.getSearchManager(s);
SearchIndex searchIndex = (SearchIndex) searchManager.getQueryHandler();
Node foo = testRootNode.addNode("foo");
testRootNode.getSession().save();
NodeId fooId = new NodeId(foo.getIdentifier());
NodeState nodeState = new NodeState(fooId, null, null, 1, false);
Iterator<NodeId> remove = Collections.<NodeId>emptyList().iterator();
Iterator<NodeState> add = Arrays.asList(nodeState).iterator();
searchIndex.updateNodes(remove, add);
searchIndex.flush();
remove = Collections.<NodeId>emptyList().iterator();
add = Arrays.asList(nodeState).iterator();
searchIndex.updateNodes(remove, add);
ConsistencyCheck consistencyCheck = searchIndex.runConsistencyCheck();
List<ConsistencyCheckError> errors = consistencyCheck.getErrors();
assertEquals("Expected 1 index consistency error", 1, errors.size());
assertEquals("Different node was reported to be duplicate", errors.get(0).id, fooId);
consistencyCheck.doubleCheckErrors();
errors = consistencyCheck.getErrors();
assertEquals("Expected 1 index consistency error after double check", 1, errors.size());
assertEquals("Different node was reported to be duplicate after double check", errors.get(0).id, fooId);
consistencyCheck.repair(false);
assertTrue("Index was not repaired properly", searchIndexContainsNode(searchIndex, fooId));
consistencyCheck.doubleCheckErrors();
errors = consistencyCheck.getErrors();
assertTrue("Consistency double check of multiple entries failed", errors.isEmpty());
assertTrue("Consistency check still finds errors", searchIndex.runConsistencyCheck().getErrors().isEmpty());
}
use of org.apache.jackrabbit.core.state.NodeState in project jackrabbit by apache.
the class BatchedItemOperations method checkAddNode.
//--------------------------------------< misc. high-level helper methods >
/**
* Checks if adding a child node called <code>nodeName</code> of node type
* <code>nodeTypeName</code> to the given parent node is allowed in the
* current context.
*
* @param parentState
* @param nodeName
* @param nodeTypeName
* @param options bit-wise OR'ed flags specifying the checks that should be
* performed; any combination of the following constants:
* <ul>
* <li><code>{@link #CHECK_ACCESS}</code>: make sure
* current session is granted read & write access on
* parent node</li>
* <li><code>{@link #CHECK_LOCK}</code>: make sure
* there's no foreign lock on parent node</li>
* <li><code>{@link #CHECK_CHECKED_OUT}</code>: make sure
* parent node is checked-out</li>
* <li><code>{@link #CHECK_CONSTRAINTS}</code>:
* make sure no node type constraints would be violated</li>
* <li><code>{@link #CHECK_HOLD}</code>: check for effective holds preventing the add operation</li>
* <li><code>{@link #CHECK_RETENTION}</code>: check for effective retention policy preventing the add operation</li>
* </ul>
* @throws ConstraintViolationException
* @throws AccessDeniedException
* @throws VersionException
* @throws LockException
* @throws ItemNotFoundException
* @throws ItemExistsException
* @throws RepositoryException
*/
public void checkAddNode(NodeState parentState, Name nodeName, Name nodeTypeName, int options) throws ConstraintViolationException, AccessDeniedException, VersionException, LockException, ItemNotFoundException, ItemExistsException, RepositoryException {
Path parentPath = hierMgr.getPath(parentState.getNodeId());
if ((options & CHECK_LOCK) == CHECK_LOCK) {
// make sure there's no foreign lock on parent node
verifyUnlocked(parentPath);
}
if ((options & CHECK_CHECKED_OUT) == CHECK_CHECKED_OUT) {
// make sure parent node is checked-out
verifyCheckedOut(parentPath);
}
if ((options & CHECK_ACCESS) == CHECK_ACCESS) {
AccessManager accessMgr = context.getAccessManager();
// make sure current session is granted read access on parent node
if (!accessMgr.isGranted(parentPath, Permission.READ)) {
throw new ItemNotFoundException(safeGetJCRPath(parentState.getNodeId()));
}
// make sure current session is granted write access on parent node
if (!accessMgr.isGranted(parentPath, nodeName, Permission.ADD_NODE)) {
throw new AccessDeniedException(safeGetJCRPath(parentState.getNodeId()) + ": not allowed to add child node");
}
// specified node type (and ev. mixins)
if (!accessMgr.isGranted(parentPath, nodeName, Permission.NODE_TYPE_MNGMT)) {
throw new AccessDeniedException(safeGetJCRPath(parentState.getNodeId()) + ": not allowed to add child node");
}
}
if ((options & CHECK_CONSTRAINTS) == CHECK_CONSTRAINTS) {
QItemDefinition parentDef = context.getItemManager().getDefinition(parentState).unwrap();
// make sure parent node is not protected
if (parentDef.isProtected()) {
throw new ConstraintViolationException(safeGetJCRPath(parentState.getNodeId()) + ": cannot add child node to protected parent node");
}
// make sure there's an applicable definition for new child node
EffectiveNodeType entParent = getEffectiveNodeType(parentState);
entParent.checkAddNodeConstraints(nodeName, nodeTypeName, context.getNodeTypeRegistry());
QNodeDefinition newNodeDef = findApplicableNodeDefinition(nodeName, nodeTypeName, parentState);
// check for name collisions
if (parentState.hasChildNodeEntry(nodeName)) {
// there's already a node with that name...
// get definition of existing conflicting node
ChildNodeEntry entry = parentState.getChildNodeEntry(nodeName, 1);
NodeState conflictingState;
NodeId conflictingId = entry.getId();
try {
conflictingState = (NodeState) stateMgr.getItemState(conflictingId);
} catch (ItemStateException ise) {
String msg = "internal error: failed to retrieve state of " + safeGetJCRPath(conflictingId);
log.debug(msg);
throw new RepositoryException(msg, ise);
}
QNodeDefinition conflictingTargetDef = context.getItemManager().getDefinition(conflictingState).unwrap();
// check same-name sibling setting of both target and existing node
if (!conflictingTargetDef.allowsSameNameSiblings() || !newNodeDef.allowsSameNameSiblings()) {
throw new ItemExistsException("cannot add child node '" + nodeName.getLocalName() + "' to " + safeGetJCRPath(parentState.getNodeId()) + ": colliding with same-named existing node");
}
}
}
RetentionRegistry retentionReg = context.getSessionImpl().getRetentionRegistry();
if ((options & CHECK_HOLD) == CHECK_HOLD) {
if (retentionReg.hasEffectiveHold(parentPath, false)) {
throw new RepositoryException("Unable to add node. Parent is affected by a hold.");
}
}
if ((options & CHECK_RETENTION) == CHECK_RETENTION) {
if (retentionReg.hasEffectiveRetention(parentPath, false)) {
throw new RepositoryException("Unable to add node. Parent is affected by a retention.");
}
}
}
use of org.apache.jackrabbit.core.state.NodeState in project jackrabbit by apache.
the class BatchedItemOperations method verifyCanWrite.
/**
* Verifies that the node at <code>nodePath</code> is writable. The
* following conditions must hold true:
* <ul>
* <li>the node must exist</li>
* <li>the current session must be granted read & write access on it</li>
* <li>the node must not be locked by another session</li>
* <li>the node must not be checked-in</li>
* <li>the node must not be protected</li>
* <li>the node must not be affected by a hold or a retention policy</li>
* </ul>
*
* @param nodePath path of node to check
* @throws PathNotFoundException if no node exists at
* <code>nodePath</code> of the current
* session is not granted read access
* to the specified path
* @throws AccessDeniedException if write access to the specified
* path is not allowed
* @throws ConstraintViolationException if the node at <code>nodePath</code>
* is protected
* @throws VersionException if the node at <code>nodePath</code>
* is checked-in
* @throws LockException if the node at <code>nodePath</code>
* is locked by another session
* @throws RepositoryException if another error occurs
*/
public void verifyCanWrite(Path nodePath) throws PathNotFoundException, AccessDeniedException, ConstraintViolationException, VersionException, LockException, RepositoryException {
NodeState node = getNodeState(nodePath);
// access rights
// make sure current session is granted read access on node
AccessManager accessMgr = context.getAccessManager();
if (!accessMgr.isGranted(nodePath, Permission.READ)) {
throw new PathNotFoundException(safeGetJCRPath(node.getNodeId()));
}
// TODO: removed check for 'WRITE' permission on node due to the fact,
// TODO: that add_node and set_property permission are granted on the
// TODO: items to be create/modified and not on their parent.
// in any case, the ability to add child-nodes and properties is checked
// while executing the corresponding operation.
// locking status
verifyUnlocked(nodePath);
// node type constraints
verifyNotProtected(nodePath);
// versioning status
verifyCheckedOut(nodePath);
RetentionRegistry retentionReg = context.getSessionImpl().getRetentionRegistry();
if (retentionReg.hasEffectiveHold(nodePath, false)) {
throw new RepositoryException("Unable to write. Node is affected by a hold.");
}
if (retentionReg.hasEffectiveRetention(nodePath, false)) {
throw new RepositoryException("Unable to write. Node is affected by a retention.");
}
}
use of org.apache.jackrabbit.core.state.NodeState in project jackrabbit by apache.
the class BatchedItemOperations method checkRemoveNode.
/**
* Checks if removing the given target node from the specifed parent
* is allowed in the current context.
*
* @param targetState
* @param parentId
* @param options bit-wise OR'ed flags specifying the checks that should be
* performed; any combination of the following constants:
* <ul>
* <li><code>{@link #CHECK_ACCESS}</code>: make sure
* current session is granted read access on parent
* and remove privilege on target node</li>
* <li><code>{@link #CHECK_LOCK}</code>: make sure
* there's no foreign lock on parent node</li>
* <li><code>{@link #CHECK_CHECKED_OUT}</code>: make sure
* parent node is checked-out</li>
* <li><code>{@link #CHECK_CONSTRAINTS}</code>:
* make sure no node type constraints would be violated</li>
* <li><code>{@link #CHECK_REFERENCES}</code>:
* make sure no references exist on target node</li>
* <li><code>{@link #CHECK_HOLD}</code>: check for effective holds preventing the add operation</li>
* <li><code>{@link #CHECK_RETENTION}</code>: check for effective retention policy preventing the add operation</li>
* </ul>
* @throws ConstraintViolationException
* @throws AccessDeniedException
* @throws VersionException
* @throws LockException
* @throws ItemNotFoundException
* @throws ReferentialIntegrityException
* @throws RepositoryException
*/
public void checkRemoveNode(NodeState targetState, NodeId parentId, int options) throws ConstraintViolationException, AccessDeniedException, VersionException, LockException, ItemNotFoundException, ReferentialIntegrityException, RepositoryException {
if (targetState.getParentId() == null) {
// root or orphaned node
throw new ConstraintViolationException("cannot remove root node");
}
Path targetPath = hierMgr.getPath(targetState.getNodeId());
NodeState parentState = getNodeState(parentId);
Path parentPath = hierMgr.getPath(parentId);
if ((options & CHECK_LOCK) == CHECK_LOCK) {
// make sure there's no foreign lock on parent node
verifyUnlocked(parentPath);
}
if ((options & CHECK_CHECKED_OUT) == CHECK_CHECKED_OUT) {
// make sure parent node is checked-out
verifyCheckedOut(parentPath);
}
if ((options & CHECK_ACCESS) == CHECK_ACCESS) {
try {
AccessManager accessMgr = context.getAccessManager();
// make sure current session is granted read access on parent node
if (!accessMgr.isGranted(targetPath, Permission.READ)) {
throw new PathNotFoundException(safeGetJCRPath(targetPath));
}
// make sure current session is allowed to remove target node
if (!accessMgr.isGranted(targetPath, Permission.REMOVE_NODE)) {
throw new AccessDeniedException(safeGetJCRPath(targetPath) + ": not allowed to remove node");
}
} catch (ItemNotFoundException infe) {
String msg = "internal error: failed to check access rights for " + safeGetJCRPath(targetPath);
log.debug(msg);
throw new RepositoryException(msg, infe);
}
}
if ((options & CHECK_CONSTRAINTS) == CHECK_CONSTRAINTS) {
QItemDefinition parentDef = context.getItemManager().getDefinition(parentState).unwrap();
if (parentDef.isProtected()) {
throw new ConstraintViolationException(safeGetJCRPath(parentId) + ": cannot remove child node of protected parent node");
}
QItemDefinition targetDef = context.getItemManager().getDefinition(targetState).unwrap();
if (targetDef.isMandatory()) {
throw new ConstraintViolationException(safeGetJCRPath(targetPath) + ": cannot remove mandatory node");
}
if (targetDef.isProtected()) {
throw new ConstraintViolationException(safeGetJCRPath(targetPath) + ": cannot remove protected node");
}
}
if ((options & CHECK_REFERENCES) == CHECK_REFERENCES) {
EffectiveNodeType ent = getEffectiveNodeType(targetState);
if (ent.includesNodeType(NameConstants.MIX_REFERENCEABLE)) {
NodeId targetId = targetState.getNodeId();
if (stateMgr.hasNodeReferences(targetId)) {
try {
NodeReferences refs = stateMgr.getNodeReferences(targetId);
if (refs.hasReferences()) {
throw new ReferentialIntegrityException(safeGetJCRPath(targetPath) + ": cannot remove node with references");
}
} catch (ItemStateException ise) {
String msg = "internal error: failed to check references on " + safeGetJCRPath(targetPath);
log.error(msg, ise);
throw new RepositoryException(msg, ise);
}
}
}
}
RetentionRegistry retentionReg = context.getSessionImpl().getRetentionRegistry();
if ((options & CHECK_HOLD) == CHECK_HOLD) {
if (retentionReg.hasEffectiveHold(targetPath, true)) {
throw new RepositoryException("Unable to perform removal. Node is affected by a hold.");
}
}
if ((options & CHECK_RETENTION) == CHECK_RETENTION) {
if (retentionReg.hasEffectiveRetention(targetPath, true)) {
throw new RepositoryException("Unable to perform removal. Node is affected by a retention.");
}
}
}
use of org.apache.jackrabbit.core.state.NodeState in project jackrabbit by apache.
the class BatchedItemOperations method clone.
//-------------------------------------------< high-level item operations >
/**
* Clones the subtree at the node <code>srcAbsPath</code> in to the new
* location at <code>destAbsPath</code>. This operation is only supported:
* <ul>
* <li>If the source element has the mixin <code>mix:shareable</code> (or some
* derived node type)</li>
* <li>If the parent node of <code>destAbsPath</code> has not already a shareable
* node in the same shared set as the node at <code>srcPath</code>.</li>
* </ul>
*
* @param srcPath source path
* @param destPath destination path
* @return the node id of the destination's parent
*
* @throws ConstraintViolationException if the operation would violate a
* node-type or other implementation-specific constraint.
* @throws VersionException if the parent node of <code>destAbsPath</code> is
* versionable and checked-in, or is non-versionable but its nearest versionable ancestor is
* checked-in. This exception will also be thrown if <code>removeExisting</code> is <code>true</code>,
* and a UUID conflict occurs that would require the moving and/or altering of a node that is checked-in.
* @throws AccessDeniedException if the current session does not have
* sufficient access rights to complete the operation.
* @throws PathNotFoundException if the node at <code>srcAbsPath</code> in
* <code>srcWorkspace</code> or the parent of <code>destAbsPath</code> in this workspace does not exist.
* @throws ItemExistsException if a property already exists at
* <code>destAbsPath</code> or a node already exist there, and same name
* siblings are not allowed or if <code>removeExisting</code> is false and a
* UUID conflict occurs.
* @throws LockException if a lock prevents the clone.
* @throws RepositoryException if the last element of <code>destAbsPath</code>
* has an index or if another error occurs.
*/
public NodeId clone(Path srcPath, Path destPath) throws ConstraintViolationException, AccessDeniedException, VersionException, PathNotFoundException, ItemExistsException, LockException, RepositoryException, IllegalStateException {
// check precondition
checkInEditMode();
// 1. check paths & retrieve state
NodeState srcState = getNodeState(srcPath);
Path destParentPath = destPath.getAncestor(1);
NodeState destParentState = getNodeState(destParentPath);
int ind = destPath.getIndex();
if (ind > 0) {
// subscript in name element
String msg = "invalid destination path: " + safeGetJCRPath(destPath) + " (subscript in name element is not allowed)";
log.debug(msg);
throw new RepositoryException(msg);
}
return clone(srcState, destParentState, destPath.getName());
}
Aggregations