use of org.apache.jackrabbit.core.nodetype.NodeTypeImpl in project jackrabbit by apache.
the class ObservationManagerImpl method createEventFilter.
/**
* Creates a new event filter with the given restrictions.
*
* @param eventTypes A combination of one or more event type constants encoded as a bitmask.
* @param absPaths absolute paths.
* @param isDeep a <code>boolean</code>.
* @param uuid array of UUIDs.
* @param nodeTypeName array of node type names.
* @param noLocal a <code>boolean</code>.
* @param noExternal a <code>boolean</code>.
* @param noInternal a <code>boolean</code>.
* @return the event filter with the given restrictions.
* @throws RepositoryException if an error occurs.
*/
public EventFilter createEventFilter(int eventTypes, List<String> absPaths, boolean isDeep, String[] uuid, String[] nodeTypeName, boolean noLocal, boolean noExternal, boolean noInternal) throws RepositoryException {
// create NodeType instances from names
NodeTypeImpl[] nodeTypes;
if (nodeTypeName == null) {
nodeTypes = null;
} else {
NodeTypeManagerImpl ntMgr = session.getNodeTypeManager();
nodeTypes = new NodeTypeImpl[nodeTypeName.length];
for (int i = 0; i < nodeTypes.length; i++) {
nodeTypes[i] = (NodeTypeImpl) ntMgr.getNodeType(nodeTypeName[i]);
}
}
List<Path> paths = new ArrayList<Path>();
for (String absPath : absPaths) {
try {
Path normalizedPath = session.getQPath(absPath).getNormalizedPath();
if (!normalizedPath.isAbsolute()) {
throw new RepositoryException("absPath must be absolute");
}
paths.add(normalizedPath);
} catch (NameException e) {
String msg = "invalid path syntax: " + absPath;
log.debug(msg);
throw new RepositoryException(msg, e);
}
}
NodeId[] ids = null;
if (uuid != null) {
ids = new NodeId[uuid.length];
for (int i = 0; i < uuid.length; i++) {
ids[i] = NodeId.valueOf(uuid[i]);
}
}
// create filter
return new EventFilter(session, eventTypes, paths, isDeep, ids, nodeTypes, noLocal, noExternal, noInternal);
}
use of org.apache.jackrabbit.core.nodetype.NodeTypeImpl in project jackrabbit by apache.
the class EventStateCollection method createEventStates.
/**
* Creates {@link EventState} instances from <code>ItemState</code>
* <code>changes</code>.
*
* @param rootNodeId the id of the root node.
* @param changes the changes on <code>ItemState</code>s.
* @param stateMgr an <code>ItemStateManager</code> to provide <code>ItemState</code>
* of items that are not contained in the <code>changes</code> collection.
* @throws ItemStateException if an error occurs while creating events
* states for the item state changes.
*/
public void createEventStates(NodeId rootNodeId, ChangeLog changes, ItemStateManager stateMgr) throws ItemStateException {
// create a hierarchy manager, that is based on the ChangeLog and
// the ItemStateProvider
ChangeLogBasedHierarchyMgr hmgr = new ChangeLogBasedHierarchyMgr(rootNodeId, stateMgr, changes);
// 1. modified items
for (ItemState state : changes.modifiedStates()) {
if (state.isNode()) {
// node changed
// covers the following cases:
// 1) property added
// 2) property removed
// 3) child node added
// 4) child node removed
// 5) node moved/reordered
// 6) node reordered
// 7) shareable node added
// 8) shareable node removed
// cases 1) and 2) are detected with added and deleted states
// on the PropertyState itself.
// cases 3) and 4) are detected with added and deleted states
// on the NodeState itself.
// in case 5) two or three nodes change. two nodes are changed
// when a child node is renamed. three nodes are changed when
// a node is really moved. In any case we are only interested in
// the node that actually got moved.
// in case 6) only one node state changes. the state of the
// parent node.
// in case 7) parent of added shareable node has new child node
// entry.
// in case 8) parent of removed shareable node has removed child
// node entry.
NodeState n = (NodeState) state;
if (n.hasOverlayedState()) {
NodeId oldParentId = n.getOverlayedState().getParentId();
NodeId newParentId = n.getParentId();
if (newParentId != null && !oldParentId.equals(newParentId) && !n.isShareable()) {
Path oldPath = getZombiePath(n.getNodeId(), hmgr);
// node moved
// generate node removed & node added event
NodeState oldParent;
try {
oldParent = (NodeState) changes.get(oldParentId);
} catch (NoSuchItemStateException e) {
// old parent has been deleted, retrieve from
// shared item state manager
oldParent = (NodeState) stateMgr.getItemState(oldParentId);
}
if (oldParent != null) {
NodeTypeImpl oldParentNodeType = getNodeType(oldParent, session);
events.add(EventState.childNodeRemoved(oldParentId, getParent(oldPath), n.getNodeId(), oldPath.getLastElement(), oldParentNodeType.getQName(), oldParent.getMixinTypeNames(), session));
} else {
// JCR-2298: In some cases the old parent node
// state is no longer available anywhere. Log an
// error since in this case we can't generate the
// correct REMOVE event.
log.error("The old parent (node id " + oldParentId + ") of a moved node (old path " + oldPath + ") is no longer available." + " No REMOVE event generated!");
}
NodeState newParent = (NodeState) changes.get(newParentId);
NodeTypeImpl newParentNodeType = getNodeType(newParent, session);
Set<Name> mixins = newParent.getMixinTypeNames();
Path newPath = getPath(n.getNodeId(), hmgr);
events.add(EventState.childNodeAdded(newParentId, getParent(newPath), n.getNodeId(), newPath.getLastElement(), newParentNodeType.getQName(), mixins, session));
events.add(EventState.nodeMovedWithInfo(newParentId, newPath, n.getNodeId(), oldPath, newParentNodeType.getQName(), mixins, session, false));
} else {
// a moved node always has a modified parent node
NodeState parent = null;
try {
// root node does not have a parent UUID
if (state.getParentId() != null) {
parent = (NodeState) changes.get(state.getParentId());
}
} catch (NoSuchItemStateException e) {
// should never happen actually. this would mean
// the parent of this modified node is deleted
String msg = "Parent of node " + state.getId() + " is deleted.";
log.error(msg);
throw new ItemStateException(msg, e);
}
if (parent != null) {
// check if node has been renamed
ChildNodeEntry moved = null;
for (ChildNodeEntry child : parent.getRemovedChildNodeEntries()) {
if (child.getId().equals(n.getNodeId())) {
// found node re-added with different name
moved = child;
}
}
if (moved != null) {
NodeTypeImpl nodeType = getNodeType(parent, session);
Set<Name> mixins = parent.getMixinTypeNames();
Path newPath = getPath(state.getId(), hmgr);
Path parentPath = getParent(newPath);
Path oldPath;
try {
if (moved.getIndex() == 0) {
oldPath = PathFactoryImpl.getInstance().create(parentPath, moved.getName(), false);
} else {
oldPath = PathFactoryImpl.getInstance().create(parentPath, moved.getName(), moved.getIndex(), false);
}
} catch (RepositoryException e) {
// should never happen actually
String msg = "Malformed path for item: " + state.getId();
log.error(msg);
throw new ItemStateException(msg, e);
}
events.add(EventState.childNodeRemoved(parent.getNodeId(), parentPath, n.getNodeId(), oldPath.getLastElement(), nodeType.getQName(), mixins, session));
events.add(EventState.childNodeAdded(parent.getNodeId(), parentPath, n.getNodeId(), newPath.getLastElement(), nodeType.getQName(), mixins, session));
events.add(EventState.nodeMovedWithInfo(parent.getNodeId(), newPath, n.getNodeId(), oldPath, nodeType.getQName(), mixins, session, false));
}
}
}
}
// check if child nodes of modified node state have been reordered
List<ChildNodeEntry> reordered = n.getReorderedChildNodeEntries();
NodeTypeImpl nodeType = getNodeType(n, session);
Set<Name> mixins = n.getMixinTypeNames();
if (reordered.size() > 0) {
// reorder
for (ChildNodeEntry child : reordered) {
Path addedElem = getPathElement(child);
Path parentPath = getPath(n.getNodeId(), hmgr);
// get removed index
NodeState overlayed = (NodeState) n.getOverlayedState();
ChildNodeEntry entry = overlayed.getChildNodeEntry(child.getId());
if (entry == null) {
throw new ItemStateException("Unable to retrieve old child index for item: " + child.getId());
}
Path removedElem = getPathElement(entry);
events.add(EventState.childNodeRemoved(n.getNodeId(), parentPath, child.getId(), removedElem, nodeType.getQName(), mixins, session));
events.add(EventState.childNodeAdded(n.getNodeId(), parentPath, child.getId(), addedElem, nodeType.getQName(), mixins, session));
List<ChildNodeEntry> cne = n.getChildNodeEntries();
// index of the child node entry before which this
// child node entry was reordered
int idx = cne.indexOf(child) + 1;
Path beforeElem = null;
if (idx < cne.size()) {
beforeElem = getPathElement(cne.get(idx));
}
events.add(EventState.nodeReordered(n.getNodeId(), parentPath, child.getId(), addedElem, removedElem, beforeElem, nodeType.getQName(), mixins, session, false));
}
}
// create events if n is shareable
createShareableNodeEvents(n, changes, hmgr, stateMgr);
} else {
// property changed
Path path = getPath(state.getId(), hmgr);
NodeState parent = (NodeState) stateMgr.getItemState(state.getParentId());
NodeTypeImpl nodeType = getNodeType(parent, session);
Set<Name> mixins = parent.getMixinTypeNames();
events.add(EventState.propertyChanged(state.getParentId(), getParent(path), path.getLastElement(), nodeType.getQName(), mixins, session));
}
}
// 2. removed items
for (ItemState state : changes.deletedStates()) {
if (state.isNode()) {
// node deleted
NodeState n = (NodeState) state;
NodeState parent = (NodeState) stateMgr.getItemState(n.getParentId());
NodeTypeImpl nodeType = getNodeType(parent, session);
Set<Name> mixins = parent.getMixinTypeNames();
Path path = getZombiePath(state.getId(), hmgr);
events.add(EventState.childNodeRemoved(n.getParentId(), getParent(path), n.getNodeId(), path.getLastElement(), nodeType.getQName(), mixins, session));
// create events if n is shareable
createShareableNodeEvents(n, changes, hmgr, stateMgr);
} else {
// only create an event if node still exists
try {
NodeState n = (NodeState) changes.get(state.getParentId());
// node state exists -> only property removed
NodeTypeImpl nodeType = getNodeType(n, session);
Set<Name> mixins = n.getMixinTypeNames();
Path path = getZombiePath(state.getId(), hmgr);
events.add(EventState.propertyRemoved(state.getParentId(), getParent(path), path.getLastElement(), nodeType.getQName(), mixins, session));
} catch (NoSuchItemStateException e) {
// node removed as well -> do not create an event
}
}
}
// 3. added items
for (ItemState state : changes.addedStates()) {
if (state.isNode()) {
// node created
NodeState n = (NodeState) state;
NodeId parentId = n.getParentId();
// the parent of an added item is always modified or new
NodeState parent = (NodeState) changes.get(parentId);
if (parent == null) {
String msg = "Parent " + parentId + " must be changed as well.";
log.error(msg);
throw new ItemStateException(msg);
}
NodeTypeImpl nodeType = getNodeType(parent, session);
Set<Name> mixins = parent.getMixinTypeNames();
Path path = getPath(n.getNodeId(), hmgr);
events.add(EventState.childNodeAdded(parentId, getParent(path), n.getNodeId(), path.getLastElement(), nodeType.getQName(), mixins, session));
// create events if n is shareable
createShareableNodeEvents(n, changes, hmgr, stateMgr);
} else {
// property created / set
NodeState n = (NodeState) changes.get(state.getParentId());
if (n == null) {
String msg = "Node " + state.getParentId() + " must be changed as well.";
log.error(msg);
throw new ItemStateException(msg);
}
NodeTypeImpl nodeType = getNodeType(n, session);
Set<Name> mixins = n.getMixinTypeNames();
Path path = getPath(state.getId(), hmgr);
events.add(EventState.propertyAdded(state.getParentId(), getParent(path), path.getLastElement(), nodeType.getQName(), mixins, session));
}
}
}
use of org.apache.jackrabbit.core.nodetype.NodeTypeImpl 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;
}
use of org.apache.jackrabbit.core.nodetype.NodeTypeImpl in project jackrabbit by apache.
the class QueryImpl method getColumns.
/**
* Returns the columns for this query.
*
* @return array of columns.
* @throws RepositoryException if an error occurs.
*/
protected ColumnImpl[] getColumns() throws RepositoryException {
SessionImpl session = sessionContext.getSessionImpl();
QueryObjectModelFactory qomFactory = session.getWorkspace().getQueryManager().getQOMFactory();
// get columns
Map<Name, ColumnImpl> columns = new LinkedHashMap<Name, ColumnImpl>();
for (Name name : root.getSelectProperties()) {
String pn = sessionContext.getJCRName(name);
ColumnImpl col = (ColumnImpl) qomFactory.column(sessionContext.getJCRName(DEFAULT_SELECTOR_NAME), pn, pn);
columns.put(name, col);
}
if (columns.size() == 0) {
// use node type constraint
LocationStepQueryNode[] steps = root.getLocationNode().getPathSteps();
final Name[] ntName = new Name[1];
steps[steps.length - 1].acceptOperands(new DefaultQueryNodeVisitor() {
public Object visit(AndQueryNode node, Object data) throws RepositoryException {
return node.acceptOperands(this, data);
}
public Object visit(NodeTypeQueryNode node, Object data) {
ntName[0] = node.getValue();
return data;
}
}, null);
if (ntName[0] == null) {
ntName[0] = NameConstants.NT_BASE;
}
NodeTypeImpl nt = session.getNodeTypeManager().getNodeType(ntName[0]);
PropertyDefinition[] propDefs = nt.getPropertyDefinitions();
for (PropertyDefinition pd : propDefs) {
QPropertyDefinition propDef = ((PropertyDefinitionImpl) pd).unwrap();
if (!propDef.definesResidual() && !propDef.isMultiple()) {
columns.put(propDef.getName(), columnForName(propDef.getName()));
}
}
}
// add jcr:path and jcr:score if not selected already
if (!columns.containsKey(NameConstants.JCR_PATH)) {
columns.put(NameConstants.JCR_PATH, columnForName(NameConstants.JCR_PATH));
}
if (!columns.containsKey(NameConstants.JCR_SCORE)) {
columns.put(NameConstants.JCR_SCORE, columnForName(NameConstants.JCR_SCORE));
}
return columns.values().toArray(new ColumnImpl[columns.size()]);
}
use of org.apache.jackrabbit.core.nodetype.NodeTypeImpl in project jackrabbit by apache.
the class AbstractAccessControlProvider method isAcItem.
/**
* Test if the given node is itself a rep:ACL or a rep:ACE node.
* @see org.apache.jackrabbit.core.security.authorization.AccessControlUtils#isAcItem(org.apache.jackrabbit.core.ItemImpl)
*/
public boolean isAcItem(ItemImpl item) throws RepositoryException {
NodeImpl n = ((item.isNode()) ? (NodeImpl) item : (NodeImpl) item.getParent());
Name ntName = ((NodeTypeImpl) n.getPrimaryNodeType()).getQName();
return ntName.equals(NT_REP_ACL) || ntName.equals(NT_REP_GRANT_ACE) || ntName.equals(NT_REP_DENY_ACE);
}
Aggregations