use of javax.jcr.UnsupportedRepositoryOperationException in project jackrabbit-oak by apache.
the class VersionManagerImpl method restore.
@Override
public void restore(final Version[] versions, final boolean removeExisting) throws ItemExistsException, UnsupportedRepositoryOperationException, VersionException, LockException, InvalidItemStateException, RepositoryException {
if (versions.length > 1) {
throw new UnsupportedRepositoryOperationException("OAK-168: Restore of multiple versions not implemented.");
}
final Version version = versions[0];
VersionHistory history = (VersionHistory) version.getParent();
final String versionableId = history.getVersionableIdentifier();
if (history.getRootVersion().isSame(version)) {
throw new VersionException("Restore of root version not possible");
}
final SessionDelegate sessionDelegate = sessionContext.getSessionDelegate();
sessionDelegate.performVoid(new SessionOperation<Void>("restore", true) {
@Override
public void performVoid() throws RepositoryException {
// check for pending changes
checkPendingChangesForRestore(sessionDelegate);
NodeDelegate n = sessionDelegate.getNodeByIdentifier(versionableId);
if (n == null) {
throw new VersionException("Unable to restore version. " + "No versionable node with identifier: " + versionableId);
}
// check lock status
checkNotLocked(n.getPath());
// check for existing nodes
List<NodeDelegate> existing = getExisting(version, Collections.singleton(n.getPath()));
boolean success = false;
try {
if (!existing.isEmpty()) {
if (removeExisting) {
removeExistingNodes(existing);
} else {
List<String> paths = new ArrayList<String>();
for (NodeDelegate nd : existing) {
paths.add(nd.getPath());
}
throw new ItemExistsException("Unable to restore with " + "removeExisting=false. Existing nodes in " + "workspace: " + paths);
}
}
// ready for restore
VersionDelegate vd = versionManagerDelegate.getVersionByIdentifier(version.getIdentifier());
versionManagerDelegate.restore(n.getParent(), n.getName(), vd);
sessionDelegate.commit();
success = true;
} catch (CommitFailedException e) {
throw new RepositoryException(e);
} finally {
if (!success) {
// refresh if one of the modifying operations fail
sessionDelegate.refresh(false);
}
}
}
});
}
use of javax.jcr.UnsupportedRepositoryOperationException in project jackrabbit by apache.
the class NodeImpl method getAllowedLifecycleTransistions.
/**
* Returns all allowed transitions from the current lifecycle state of
* this node.
* <p>
* The lifecycle policy node referenced by the "jcr:lifecyclePolicy"
* property is expected to contain a "transitions" node with a list of
* child nodes, one for each transition. These transition nodes must
* have single-valued string "from" and "to" properties that identify
* the allowed source and target states of each transition.
* <p>
* Note that future versions of Apache Jackrabbit may well use different
* lifecycle policy implementations.
*
* @since Apache Jackrabbit 2.0
* @return allowed transitions for the current lifecycle state of this node
* @throws UnsupportedRepositoryOperationException
* if this node does not have the mix:lifecycle mixin node type
* @throws RepositoryException if a repository error occurs
*/
public String[] getAllowedLifecycleTransistions() throws UnsupportedRepositoryOperationException, RepositoryException {
if (isNodeType(NameConstants.MIX_LIFECYCLE)) {
Node policy = getProperty(JCR_LIFECYCLE_POLICY).getNode();
String state = getProperty(JCR_CURRENT_LIFECYCLE_STATE).getString();
List<String> targetStates = new ArrayList<String>();
if (policy.hasNode("transitions")) {
Node transitions = policy.getNode("transitions");
for (Node transition : JcrUtils.getChildNodes(transitions)) {
String from = transition.getProperty("from").getString();
if (from.equals(state)) {
String to = transition.getProperty("to").getString();
targetStates.add(to);
}
}
}
return targetStates.toArray(new String[targetStates.size()]);
} else {
throw new UnsupportedRepositoryOperationException("Only nodes with mixin node type mix:lifecycle" + " may participate in a lifecycle: " + this);
}
}
use of javax.jcr.UnsupportedRepositoryOperationException in project jackrabbit by apache.
the class NodeImpl method addShareParent.
/**
* Add a share-parent to this node. This method checks, whether:
* <ul>
* <li>this node is shareable</li>
* <li>adding the given would create a share cycle</li>
* <li>the given parent is already a share-parent</li>
* </ul>
* @param parentId parent to add to the shared set
* @throws RepositoryException if an error occurs
*/
void addShareParent(NodeId parentId) throws RepositoryException {
// verify that we're shareable
if (!isShareable()) {
String msg = this + " is not shareable.";
log.debug(msg);
throw new RepositoryException(msg);
}
// detect share cycle
NodeId srcId = getNodeId();
HierarchyManager hierMgr = sessionContext.getHierarchyManager();
if (parentId.equals(srcId) || hierMgr.isAncestor(srcId, parentId)) {
String msg = "This would create a share cycle.";
log.debug(msg);
throw new RepositoryException(msg);
}
// quickly verify whether the share is already contained before creating
// a transient state in vain
NodeState state = data.getNodeState();
if (!state.containsShare(parentId)) {
state = (NodeState) getOrCreateTransientItemState();
if (state.addShare(parentId)) {
return;
}
}
String msg = "Adding a shareable node twice to the same parent is not supported.";
log.debug(msg);
throw new UnsupportedRepositoryOperationException(msg);
}
use of javax.jcr.UnsupportedRepositoryOperationException in project jackrabbit by apache.
the class NodeImpl method orderBefore.
/**
* Same as <code>{@link Node#orderBefore(String, String)}</code> except that
* this method takes a <code>Path.Element</code> arguments instead of
* <code>String</code>s.
*
* @param srcName
* @param dstName
* @throws UnsupportedRepositoryOperationException
* @throws VersionException
* @throws ConstraintViolationException
* @throws ItemNotFoundException
* @throws LockException
* @throws RepositoryException
*/
public synchronized void orderBefore(Path.Element srcName, Path.Element dstName) throws UnsupportedRepositoryOperationException, VersionException, ConstraintViolationException, ItemNotFoundException, LockException, RepositoryException {
// check state of this instance
sanityCheck();
if (!getPrimaryNodeType().hasOrderableChildNodes()) {
throw new UnsupportedRepositoryOperationException("child node ordering not supported on " + this);
}
// check arguments
if (srcName.equals(dstName)) {
// there's nothing to do
return;
}
// check existence
if (!hasNode(srcName.getName(), srcName.getIndex())) {
String name;
try {
Path.Element[] path = new Path.Element[] { srcName };
name = sessionContext.getJCRPath(new PathBuilder(path).getPath());
} catch (NameException e) {
name = srcName.toString();
} catch (NamespaceException e) {
name = srcName.toString();
}
throw new ItemNotFoundException(this + " has no child node with name " + name);
}
if (dstName != null && !hasNode(dstName.getName(), dstName.getIndex())) {
String name;
try {
Path.Element[] path = new Path.Element[] { dstName };
name = sessionContext.getJCRPath(new PathBuilder(path).getPath());
} catch (NameException e) {
name = dstName.toString();
} catch (NamespaceException e) {
name = dstName.toString();
}
throw new ItemNotFoundException(this + " has no child node with name " + name);
}
// make sure this node is checked-out and neither protected nor locked
int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_CHECKED_OUT | ItemValidator.CHECK_CONSTRAINTS;
sessionContext.getItemValidator().checkModify(this, options, Permission.NONE);
/*
make sure the session is allowed to reorder child nodes.
since there is no specific privilege for reordering child nodes,
test if the the node to be reordered can be removed and added,
i.e. treating reorder similar to a move.
TODO: properly deal with sns in which case the index would change upon reorder.
*/
AccessManager acMgr = sessionContext.getAccessManager();
PathBuilder pb = new PathBuilder(getPrimaryPath());
pb.addLast(srcName.getName(), srcName.getIndex());
Path childPath = pb.getPath();
if (!acMgr.isGranted(childPath, Permission.MODIFY_CHILD_NODE_COLLECTION)) {
String msg = "Not allowed to reorder child node " + sessionContext.getJCRPath(childPath) + ".";
log.debug(msg);
throw new AccessDeniedException(msg);
}
ArrayList<ChildNodeEntry> list = new ArrayList<ChildNodeEntry>(data.getNodeState().getChildNodeEntries());
int srcInd = -1, destInd = -1;
for (int i = 0; i < list.size(); i++) {
ChildNodeEntry entry = list.get(i);
if (srcInd == -1) {
if (entry.getName().equals(srcName.getName()) && (entry.getIndex() == srcName.getIndex() || srcName.getIndex() == 0 && entry.getIndex() == 1)) {
srcInd = i;
}
}
if (destInd == -1 && dstName != null) {
if (entry.getName().equals(dstName.getName()) && (entry.getIndex() == dstName.getIndex() || dstName.getIndex() == 0 && entry.getIndex() == 1)) {
destInd = i;
if (srcInd != -1) {
break;
}
}
} else {
if (srcInd != -1) {
break;
}
}
}
// check if resulting order would be different to current order
if (destInd == -1) {
if (srcInd == list.size() - 1) {
// no change, we're done
return;
}
} else {
if ((destInd - srcInd) == 1) {
// no change, we're done
return;
}
}
// reorder list
if (destInd == -1) {
list.add(list.remove(srcInd));
} else {
if (srcInd < destInd) {
list.add(destInd, list.get(srcInd));
list.remove(srcInd);
} else {
list.add(destInd, list.remove(srcInd));
}
}
// modify the state of 'this', i.e. the parent node
NodeState thisState = (NodeState) getOrCreateTransientItemState();
thisState.setChildNodeEntries(list);
}
use of javax.jcr.UnsupportedRepositoryOperationException in project jackrabbit by apache.
the class SessionMoveOperation method perform.
public Object perform(SessionContext context) throws RepositoryException {
// Get node instances
NodeImpl targetNode = getNode(context, srcPath, srcAbsPath);
NodeImpl srcParentNode = getNode(context, srcPath.getAncestor(1), srcAbsPath);
NodeImpl destParentNode = getNode(context, destPath.getAncestor(1), destAbsPath);
if (context.getHierarchyManager().isShareAncestor(targetNode.getNodeId(), destParentNode.getNodeId())) {
throw new RepositoryException("Move not possible because of a share cycle between " + srcAbsPath + " and " + destAbsPath);
}
// check for name collisions
NodeImpl existing = null;
try {
existing = context.getItemManager().getNode(destPath);
// check same-name sibling setting of existing node
if (!existing.getDefinition().allowsSameNameSiblings()) {
throw new ItemExistsException("Same name siblings are not allowed: " + existing);
}
} catch (AccessDeniedException ade) {
// FIXME by throwing ItemExistsException we're disclosing too much information
throw new ItemExistsException(destAbsPath);
} catch (PathNotFoundException pnfe) {
// no name collision, fall through
}
// verify that the targetNode can be removed
int options = ItemValidator.CHECK_HOLD | ItemValidator.CHECK_RETENTION;
context.getItemValidator().checkRemove(targetNode, options, Permission.NONE);
// verify for both source and destination parent nodes that
// - they are checked-out
// - are not protected neither by node type constraints nor by retention/hold
options = ItemValidator.CHECK_CHECKED_OUT | ItemValidator.CHECK_LOCK | ItemValidator.CHECK_CONSTRAINTS | ItemValidator.CHECK_HOLD | ItemValidator.CHECK_RETENTION;
context.getItemValidator().checkModify(srcParentNode, options, Permission.NONE);
context.getItemValidator().checkModify(destParentNode, options, Permission.NONE);
// check constraints
// get applicable definition of target node at new location
NodeTypeImpl nt = (NodeTypeImpl) targetNode.getPrimaryNodeType();
org.apache.jackrabbit.spi.commons.nodetype.NodeDefinitionImpl newTargetDef;
try {
newTargetDef = destParentNode.getApplicableChildNodeDefinition(destPath.getName(), nt.getQName());
} catch (RepositoryException re) {
String msg = destAbsPath + ": no definition found in parent node's node type for new node";
log.debug(msg);
throw new ConstraintViolationException(msg, re);
}
// necessarily have identical definitions
if (existing != null && !newTargetDef.allowsSameNameSiblings()) {
throw new ItemExistsException("Same name siblings not allowed: " + existing);
}
NodeId targetId = targetNode.getNodeId();
// check permissions
AccessManager acMgr = context.getAccessManager();
if (!(acMgr.isGranted(srcPath, Permission.REMOVE_NODE) && acMgr.isGranted(destPath, Permission.ADD_NODE | Permission.NODE_TYPE_MNGMT))) {
String msg = "Not allowed to move node " + srcAbsPath + " to " + destAbsPath;
log.debug(msg);
throw new AccessDeniedException(msg);
}
if (srcParentNode.isSame(destParentNode)) {
// change definition of target
targetNode.onRedefine(newTargetDef.unwrap());
// do rename
destParentNode.renameChildNode(targetId, destPath.getName(), false);
} else {
// check shareable case
if (targetNode.getNodeState().isShareable()) {
String msg = "Moving a shareable node is not supported.";
log.debug(msg);
throw new UnsupportedRepositoryOperationException(msg);
}
// change definition of target
targetNode.onRedefine(newTargetDef.unwrap());
// Get the transient states
NodeState srcParentState = (NodeState) srcParentNode.getOrCreateTransientItemState();
NodeState targetState = (NodeState) targetNode.getOrCreateTransientItemState();
NodeState destParentState = (NodeState) destParentNode.getOrCreateTransientItemState();
// 1. remove child node entry from old parent
if (srcParentState.removeChildNodeEntry(targetId)) {
// 2. re-parent target node
targetState.setParentId(destParentNode.getNodeId());
// 3. add child node entry to new parent
destParentState.addChildNodeEntry(destPath.getName(), targetId);
}
}
return this;
}
Aggregations