use of org.apache.jackrabbit.spi.Name in project jackrabbit by apache.
the class SharedItemStateManager method isShareable.
/**
* Determines whether the specified node is <i>shareable</i>, i.e. whether the mixin type <code>mix:shareable</code>
* is either directly assigned or indirectly inherited.
*
* @param state
* node state to check
* @return true if the specified node is <i>shareable</i>, false otherwise.
* @throws RepositoryException
* if an error occurs
*/
private boolean isShareable(NodeState state) throws RepositoryException {
// shortcut: check some well-known built-in types first
Name primary = state.getNodeTypeName();
Set<Name> mixins = state.getMixinTypeNames();
if (mixins.contains(NameConstants.MIX_SHAREABLE)) {
return true;
}
try {
EffectiveNodeType type = ntReg.getEffectiveNodeType(primary, mixins);
return type.includesNodeType(NameConstants.MIX_SHAREABLE);
} catch (NodeTypeConflictException ntce) {
String msg = "internal error: failed to build effective node type for node " + state.getNodeId();
log.debug(msg);
throw new RepositoryException(msg, ntce);
}
}
use of org.apache.jackrabbit.spi.Name in project jackrabbit by apache.
the class NodeStateMerger method conflicts.
/**
*
* @param state The state of the node to be saved.
* @param addedMixins The added mixins to be used for testing
* @param ctx
* @param compareToOverlayed
* @return true if a conflict can be determined, false otherwise.
*/
private static boolean conflicts(NodeState state, Set<Name> addedMixins, MergeContext ctx, boolean compareToOverlayed) {
try {
// if the mixin defines residual item definitions -> return false.
for (Name mixinName : addedMixins) {
EffectiveNodeType ent = ctx.getEffectiveNodeType(mixinName);
if (ent.getUnnamedItemDefs().length > 0) {
// easily determine conflicts
return false;
}
NodeState overlayed = (NodeState) state.getOverlayedState();
for (ChildNodeEntry cne : state.getChildNodeEntries()) {
if (ent.getNamedNodeDefs(cne.getName()).length > 0) {
if (ctx.isAdded(cne.getId()) || isAutoCreated(cne, ent)) {
if (!compareToOverlayed || overlayed.hasChildNodeEntry(cne.getName())) {
return true;
}
}
// else: neither added nor autocreated in 'state' .
}
// else: child node not defined by the added mixin type
}
for (Name propName : state.getPropertyNames()) {
if (ent.getNamedPropDefs(propName).length > 0) {
PropertyId pid = new PropertyId(state.getNodeId(), propName);
if (ctx.isAdded(pid) || isAutoCreated(propName, ent)) {
if (!compareToOverlayed || overlayed.hasPropertyName(propName)) {
return true;
}
}
// else: neither added nor autocreated in 'state'
}
// else: property not defined by added mixin
}
}
} catch (NoSuchNodeTypeException e) {
// unable to determine collision
return true;
}
// no conflict detected
return false;
}
use of org.apache.jackrabbit.spi.Name in project jackrabbit by apache.
the class NodeStateMerger method mergeMixinTypes.
/**
*
* @param state
* @param overlayedState
* @return true if the mixin type names are the same in both node states or
* if the mixin modifications do not conflict (and could be merged); false
* otherwise.
*/
private static boolean mergeMixinTypes(NodeState state, NodeState overlayedState, MergeContext ctx) {
Set<Name> mixins = new HashSet<Name>(state.getMixinTypeNames());
Set<Name> overlayedMixins = new HashSet<Name>(overlayedState.getMixinTypeNames());
if (mixins.equals(overlayedMixins)) {
// by the mixins according to the general rule.
return true;
}
PropertyId mixinPropId = new PropertyId(state.getNodeId(), NameConstants.JCR_MIXINTYPES);
boolean mergeDone;
if (ctx.isAdded(mixinPropId)) {
// existing items on the overlayed state
if (overlayedMixins.isEmpty() || mixins.containsAll(overlayedMixins)) {
mixins.removeAll(overlayedMixins);
mergeDone = !conflicts(state, mixins, ctx, true);
} else {
// different mixins added in overlayedState and state
// -> don't merge
mergeDone = false;
}
} else if (ctx.isDeleted(mixinPropId)) {
// jcr:mixinTypes property was removed in 'state'.
// we can't determine if there was any change to mixin types in the
// overlayed state.
// -> don't merge.
mergeDone = false;
} else if (ctx.isModified(mixinPropId)) {
/* jcr:mixinTypes property was modified in 'state'.
NOTE: if the mixins of the overlayed state was modified as well
the property (jcr:mixinTypes) cannot not be persisted (stale).
since there is not way to determine if the overlayed mixins have
been modified just check for conflicts related to a net mixin
addition.
*/
if (mixins.containsAll(overlayedMixins)) {
// net result of modifications is only addition.
// -> so far the changes are save if there are no conflicts
// caused by mixins modification in 'state'.
// NOTE: the save may still fail if the mixin property has
// been modified in the overlayed state as well.
mixins.removeAll(overlayedMixins);
mergeDone = !conflicts(state, mixins, ctx, true);
} else {
// net result is either a removal in 'state' or modifications
// in both node states.
// -> don't merge.
mergeDone = false;
}
} else {
// state but neither added nor modified in 'state'.
if (overlayedMixins.containsAll(mixins)) {
// the modification in the overlayed state only includes the
// addition of mixin node types, but no removal.
// -> need to check if any added items from state would
// collide with the items defined by the new mixin on the
// overlayed state.
overlayedMixins.removeAll(mixins);
if (!conflicts(state, overlayedMixins, ctx, false)) {
// update the mixin names in 'state'. the child items defined
// by the new mixins will be added later on during merge of
// child nodes and properties.
state.setMixinTypeNames(overlayedMixins);
mergeDone = true;
} else {
mergeDone = false;
}
} else {
// either remove-mixin(s) or both add and removal of mixin in
// the overlayed state.
// -> we cannot merge easily
mergeDone = false;
}
}
return mergeDone;
}
use of org.apache.jackrabbit.spi.Name in project jackrabbit by apache.
the class UserManagerImpl method findAuthorizables.
/**
* @see UserManager#findAuthorizables(String,String, int)
*/
public Iterator<Authorizable> findAuthorizables(String relPath, String value, int searchType) throws RepositoryException {
if (searchType < SEARCH_TYPE_USER || searchType > SEARCH_TYPE_AUTHORIZABLE) {
throw new IllegalArgumentException("Invalid search type " + searchType);
}
Path path = session.getQPath(relPath);
NodeIterator nodes;
if (relPath.indexOf('/') == -1) {
// search for properties somewhere below an authorizable node
nodes = authResolver.findNodes(path, value, searchType, true, Long.MAX_VALUE);
} else {
path = path.getNormalizedPath();
if (path.getLength() == 1) {
// only search below the authorizable node
Name ntName;
switch(searchType) {
case SEARCH_TYPE_GROUP:
ntName = NT_REP_GROUP;
break;
case SEARCH_TYPE_USER:
ntName = NT_REP_USER;
break;
default:
ntName = NT_REP_AUTHORIZABLE;
}
nodes = authResolver.findNodes(path.getName(), value, ntName, true);
} else {
// search below authorizable nodes but take some path constraints
// into account.
nodes = authResolver.findNodes(path, value, searchType, true, Long.MAX_VALUE);
}
}
return new AuthorizableIterator(nodes);
}
use of org.apache.jackrabbit.spi.Name in project jackrabbit by apache.
the class UserManagerImpl method internalGetAuthorizable.
/**
* @param id The user or group ID.
* @return The authorizable with the given <code>id</code> or <code>null</code>.
* @throws RepositoryException If an error occurs.
*/
private Authorizable internalGetAuthorizable(String id) throws RepositoryException {
NodeId nodeId = buildNodeId(id);
NodeImpl n = null;
try {
n = session.getNodeById(nodeId);
} catch (ItemNotFoundException e) {
boolean compatibleJR16 = config.getConfigValue(PARAM_COMPATIBLE_JR16, false);
if (compatibleJR16) {
// backwards-compatibility with JR < 2.0 user/group structure that doesn't
// allow to determine existence of an authorizable from the id directly.
// search for it the node belonging to that id
n = (NodeImpl) authResolver.findNode(P_USERID, id, NT_REP_USER);
if (n == null) {
// no user -> look for group.
// NOTE: JR < 2.0 always returned groupIDs that didn't contain any
// illegal JCR chars. Since Group.getID() 'unescapes' the node
// name additional escaping is required.
Name nodeName = session.getQName(Text.escapeIllegalJcrChars(id));
n = (NodeImpl) authResolver.findNode(nodeName, NT_REP_GROUP);
}
}
// else: no matching node found -> ignore exception.
}
return getAuthorizable(n);
}
Aggregations