Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImplBase.java =================================================================== --- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImplBase.java (revision 1065599) +++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/VersionManagerImplBase.java (revision ) @@ -16,34 +16,20 @@ */ package org.apache.jackrabbit.core.version; -import java.util.Calendar; -import java.util.Set; -import java.util.HashSet; - -import javax.jcr.RepositoryException; -import javax.jcr.UnsupportedRepositoryOperationException; -import javax.jcr.NamespaceException; -import javax.jcr.Node; -import javax.jcr.PropertyType; -import javax.jcr.ItemNotFoundException; -import javax.jcr.version.Version; - -import org.apache.jackrabbit.core.HierarchyManager; -import org.apache.jackrabbit.core.SessionImpl; -import org.apache.jackrabbit.core.NodeImpl; -import org.apache.jackrabbit.core.value.InternalValue; +import org.apache.jackrabbit.core.*; import org.apache.jackrabbit.core.id.NodeId; -import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; -import org.apache.jackrabbit.core.session.SessionContext; -import org.apache.jackrabbit.core.state.ItemStateException; -import org.apache.jackrabbit.core.state.LocalItemStateManager; -import org.apache.jackrabbit.core.state.UpdatableItemStateManager; -import org.apache.jackrabbit.core.state.NodeState; -import org.apache.jackrabbit.spi.commons.name.NameConstants; -import org.apache.jackrabbit.spi.Path; -import org.slf4j.LoggerFactory; -import org.slf4j.Logger; +import org.apache.jackrabbit.core.nodetype.*; +import org.apache.jackrabbit.core.session.*; +import org.apache.jackrabbit.core.state.*; +import org.apache.jackrabbit.core.value.*; +import org.apache.jackrabbit.spi.*; +import org.apache.jackrabbit.spi.commons.name.*; +import org.slf4j.*; +import javax.jcr.*; +import javax.jcr.version.*; +import java.util.*; + /** * The JCR Version Manager implementation is split in several classes in order to * group related methods together. @@ -112,7 +98,7 @@ this.session = context.getSessionImpl(); this.stateMgr = stateMgr; this.hierMgr = hierMgr; - this.ntReg = session.getNodeTypeManager().getNodeTypeRegistry(); + this.ntReg = context.getNodeTypeRegistry(); this.vMgr = session.getInternalVersionManager(); } @@ -243,7 +229,7 @@ /** * Recursively collects all base versions of this configuration tree. - * + * * @param root node to traverse * @param baseVersions set of base versions to fill * @throws RepositoryException if an error occurs Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeManagerImpl.java =================================================================== --- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeManagerImpl.java (revision 1023820) +++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/nodetype/NodeTypeManagerImpl.java (revision ) @@ -16,55 +16,27 @@ */ package org.apache.jackrabbit.core.nodetype; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; +import org.apache.commons.collections.map.*; +import org.apache.jackrabbit.api.*; +import org.apache.jackrabbit.commons.*; +import org.apache.jackrabbit.commons.cnd.*; +import org.apache.jackrabbit.commons.iterator.*; +import org.apache.jackrabbit.core.nodetype.xml.*; +import org.apache.jackrabbit.core.security.*; +import org.apache.jackrabbit.core.session.*; +import org.apache.jackrabbit.spi.*; +import org.apache.jackrabbit.spi.commons.*; +import org.apache.jackrabbit.spi.commons.conversion.*; +import org.apache.jackrabbit.spi.commons.namespace.*; +import org.apache.jackrabbit.spi.commons.nodetype.*; +import org.apache.jackrabbit.spi.commons.value.*; +import org.xml.sax.*; -import javax.jcr.NamespaceException; -import javax.jcr.RepositoryException; -import javax.jcr.UnsupportedRepositoryOperationException; -import javax.jcr.nodetype.InvalidNodeTypeDefinitionException; -import javax.jcr.nodetype.NoSuchNodeTypeException; -import javax.jcr.nodetype.NodeType; -import javax.jcr.nodetype.NodeTypeDefinition; -import javax.jcr.nodetype.NodeTypeExistsException; -import javax.jcr.nodetype.NodeTypeIterator; +import javax.jcr.*; +import javax.jcr.nodetype.*; +import java.io.*; +import java.util.*; -import org.apache.commons.collections.map.ReferenceMap; -import org.apache.jackrabbit.api.JackrabbitNodeTypeManager; -import org.apache.jackrabbit.commons.NamespaceHelper; -import org.apache.jackrabbit.commons.cnd.CompactNodeTypeDefReader; -import org.apache.jackrabbit.commons.cnd.ParseException; -import org.apache.jackrabbit.commons.iterator.NodeTypeIteratorAdapter; -import org.apache.jackrabbit.core.nodetype.xml.NodeTypeReader; -import org.apache.jackrabbit.core.session.SessionContext; -import org.apache.jackrabbit.spi.Name; -import org.apache.jackrabbit.spi.QNodeDefinition; -import org.apache.jackrabbit.spi.QNodeTypeDefinition; -import org.apache.jackrabbit.spi.QPropertyDefinition; -import org.apache.jackrabbit.spi.commons.QNodeTypeDefinitionImpl; -import org.apache.jackrabbit.spi.commons.conversion.NameException; -import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver; -import org.apache.jackrabbit.spi.commons.namespace.NamespaceMapping; -import org.apache.jackrabbit.spi.commons.nodetype.AbstractNodeTypeManager; -import org.apache.jackrabbit.spi.commons.nodetype.NodeDefinitionImpl; -import org.apache.jackrabbit.spi.commons.nodetype.PropertyDefinitionImpl; -import org.apache.jackrabbit.spi.commons.nodetype.QDefinitionBuilderFactory; -import org.apache.jackrabbit.spi.commons.value.QValueFactoryImpl; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; - /** * A NodeTypeManagerImpl implements a session dependant * NodeTypeManager. @@ -195,7 +167,7 @@ /** * @return the node type registry */ - public NodeTypeRegistry getNodeTypeRegistry() { + protected NodeTypeRegistry getNodeTypeRegistry() { return context.getNodeTypeRegistry(); } @@ -275,7 +247,11 @@ List newNodeTypeDefs = new ArrayList(); List registeredNodeTypeDefs = new ArrayList(); for (QNodeTypeDefinition nodeTypeDef: nodeTypeDefs) { - if (registry.isRegistered(nodeTypeDef.getName())) { + boolean isUpdate = registry.isRegistered(nodeTypeDef.getName()); + if (context.getAccessManager() instanceof AccessManagerForNodeTypes && + !((AccessManagerForNodeTypes) context.getAccessManager()).canRegisterNodeType(nodeTypeDef, isUpdate)) + throw new AccessDeniedException(nodeTypeDef.getName() + ": Not allowed to register node type."); + if (isUpdate) { registeredNodeTypeDefs.add(nodeTypeDef); } else { newNodeTypeDefs.add(nodeTypeDef); @@ -438,6 +414,10 @@ */ private Collection registerNodeTypes(List defs) throws InvalidNodeTypeDefException, RepositoryException { + for (QNodeTypeDefinition def: defs) + if (context.getAccessManager() instanceof AccessManagerForNodeTypes && + !((AccessManagerForNodeTypes) context.getAccessManager()).canRegisterNodeType(def, false)) + throw new AccessDeniedException(def.getName() + ": Not allowed to register node type."); context.getNodeTypeRegistry().registerNodeTypes(defs); Set types = new HashSet(); @@ -557,7 +537,12 @@ for (NodeTypeDefinition definition : definitions) { // convert to QNodeTypeDefinition QNodeTypeDefinition def = toNodeTypeDef(definition); - if (registry.isRegistered(def.getName())) { + boolean isUpdate = registry.isRegistered(def.getName()); + if (context.getAccessManager() instanceof AccessManagerForNodeTypes && + !((AccessManagerForNodeTypes) context.getAccessManager()).canRegisterNodeType(def, isUpdate)) { + throw new AccessDeniedException(def.getName() + ": Not allowed to register node type."); + } + if (isUpdate) { if (allowUpdate) { modifiedDefs.add(def); } else { @@ -606,7 +591,12 @@ Set ntNames = new HashSet(); for (String name : names) { try { - ntNames.add(context.getQName(name)); + Name qname = context.getQName(name); + ntNames.add(qname); + if (context.getAccessManager() instanceof AccessManagerForNodeTypes && + !((AccessManagerForNodeTypes) context.getAccessManager()).canUnregisterNodeType(qname)) { + throw new AccessDeniedException(name + ": Not allowed to unregister the node type."); + } } catch (NamespaceException e) { throw new RepositoryException("Invalid name: " + name, e); } catch (NameException e) { Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java =================================================================== --- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java (revision 1072087) +++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java (revision ) @@ -16,111 +16,40 @@ */ package org.apache.jackrabbit.core; -import static javax.jcr.PropertyType.STRING; -import static org.apache.jackrabbit.spi.commons.name.NameConstants.JCR_CURRENT_LIFECYCLE_STATE; -import static org.apache.jackrabbit.spi.commons.name.NameConstants.JCR_ISCHECKEDOUT; -import static org.apache.jackrabbit.spi.commons.name.NameConstants.JCR_LIFECYCLE_POLICY; -import static org.apache.jackrabbit.spi.commons.name.NameConstants.MIX_LIFECYCLE; -import static org.apache.jackrabbit.spi.commons.name.NameConstants.MIX_REFERENCEABLE; -import static org.apache.jackrabbit.spi.commons.name.NameConstants.MIX_SIMPLE_VERSIONABLE; -import static org.apache.jackrabbit.spi.commons.name.NameConstants.MIX_VERSIONABLE; - -import java.io.InputStream; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.BitSet; -import java.util.Calendar; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.jcr.AccessDeniedException; -import javax.jcr.Binary; -import javax.jcr.InvalidItemStateException; -import javax.jcr.InvalidLifecycleTransitionException; -import javax.jcr.Item; -import javax.jcr.ItemExistsException; -import javax.jcr.ItemNotFoundException; -import javax.jcr.ItemVisitor; -import javax.jcr.NamespaceException; -import javax.jcr.NoSuchWorkspaceException; -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.PathNotFoundException; -import javax.jcr.Property; -import javax.jcr.PropertyIterator; -import javax.jcr.PropertyType; -import javax.jcr.RepositoryException; -import javax.jcr.UnsupportedRepositoryOperationException; -import javax.jcr.Value; -import javax.jcr.ValueFormatException; -import javax.jcr.lock.Lock; -import javax.jcr.lock.LockException; -import javax.jcr.lock.LockManager; -import javax.jcr.nodetype.ConstraintViolationException; -import javax.jcr.nodetype.ItemDefinition; -import javax.jcr.nodetype.NoSuchNodeTypeException; -import javax.jcr.nodetype.NodeDefinition; -import javax.jcr.nodetype.NodeType; -import javax.jcr.nodetype.PropertyDefinition; -import javax.jcr.query.Query; -import javax.jcr.query.QueryResult; -import javax.jcr.version.Version; -import javax.jcr.version.VersionException; -import javax.jcr.version.VersionHistory; -import javax.jcr.version.VersionManager; - -import org.apache.jackrabbit.api.JackrabbitNode; -import org.apache.jackrabbit.commons.JcrUtils; -import org.apache.jackrabbit.commons.iterator.NodeIteratorAdapter; -import org.apache.jackrabbit.commons.iterator.PropertyIteratorAdapter; +import org.apache.jackrabbit.api.*; +import org.apache.jackrabbit.commons.*; +import org.apache.jackrabbit.commons.iterator.*; import org.apache.jackrabbit.core.id.ItemId; import org.apache.jackrabbit.core.id.NodeId; import org.apache.jackrabbit.core.id.PropertyId; -import org.apache.jackrabbit.core.nodetype.EffectiveNodeType; +import org.apache.jackrabbit.core.nodetype.*; import org.apache.jackrabbit.core.nodetype.NodeTypeConflictException; -import org.apache.jackrabbit.core.nodetype.NodeTypeImpl; -import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl; -import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry; -import org.apache.jackrabbit.core.query.QueryManagerImpl; -import org.apache.jackrabbit.core.security.AccessManager; -import org.apache.jackrabbit.core.security.authorization.Permission; -import org.apache.jackrabbit.core.session.AddNodeOperation; -import org.apache.jackrabbit.core.session.SessionContext; -import org.apache.jackrabbit.core.session.SessionOperation; -import org.apache.jackrabbit.core.session.SessionWriteOperation; -import org.apache.jackrabbit.core.state.ChildNodeEntry; -import org.apache.jackrabbit.core.state.ItemState; -import org.apache.jackrabbit.core.state.ItemStateException; -import org.apache.jackrabbit.core.state.ItemStateManager; -import org.apache.jackrabbit.core.state.NodeReferences; -import org.apache.jackrabbit.core.state.NodeState; -import org.apache.jackrabbit.core.state.PropertyState; -import org.apache.jackrabbit.core.value.InternalValue; -import org.apache.jackrabbit.spi.Name; -import org.apache.jackrabbit.spi.Path; -import org.apache.jackrabbit.spi.QItemDefinition; -import org.apache.jackrabbit.spi.QNodeDefinition; -import org.apache.jackrabbit.spi.QPropertyDefinition; -import org.apache.jackrabbit.spi.commons.conversion.MalformedPathException; -import org.apache.jackrabbit.spi.commons.conversion.NameException; -import org.apache.jackrabbit.spi.commons.name.NameConstants; -import org.apache.jackrabbit.spi.commons.name.PathBuilder; -import org.apache.jackrabbit.spi.commons.name.PathFactoryImpl; -import org.apache.jackrabbit.spi.commons.nodetype.NodeDefinitionImpl; -import org.apache.jackrabbit.spi.commons.nodetype.PropertyDefinitionImpl; -import org.apache.jackrabbit.util.ChildrenCollectorFilter; -import org.apache.jackrabbit.util.ISO9075; -import org.apache.jackrabbit.value.ValueHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.apache.jackrabbit.core.query.*; +import org.apache.jackrabbit.core.security.*; +import org.apache.jackrabbit.core.security.authorization.*; +import org.apache.jackrabbit.core.session.*; +import org.apache.jackrabbit.core.state.*; +import org.apache.jackrabbit.core.value.*; +import org.apache.jackrabbit.spi.*; +import org.apache.jackrabbit.spi.commons.conversion.*; +import org.apache.jackrabbit.spi.commons.name.*; +import org.apache.jackrabbit.spi.commons.nodetype.*; +import org.apache.jackrabbit.util.*; +import org.apache.jackrabbit.value.*; +import org.slf4j.*; +import javax.jcr.*; +import javax.jcr.lock.*; +import javax.jcr.nodetype.*; +import javax.jcr.query.*; +import javax.jcr.version.*; +import java.io.*; +import java.math.*; +import java.util.*; + +import static javax.jcr.PropertyType.*; +import static org.apache.jackrabbit.spi.commons.name.NameConstants.*; + /** * NodeImpl implements the Node interface. */ @@ -2380,7 +2309,7 @@ // build effective node type of mixins & primary type // in order to detect conflicts - NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry(); + NodeTypeRegistry ntReg = sessionContext.getNodeTypeRegistry(); EffectiveNodeType entExisting; try { // existing mixin's @@ -3212,7 +3141,7 @@ // build effective node type of new primary type & existing mixin's // in order to detect conflicts - NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry(); + NodeTypeRegistry ntReg = sessionContext.getNodeTypeRegistry(); EffectiveNodeType entNew, entOld, entAll; try { entNew = ntReg.getEffectiveNodeType(ntName); @@ -3660,7 +3589,7 @@ // build effective node type of primary type & new mixin's // in order to detect conflicts - NodeTypeRegistry ntReg = ntMgr.getNodeTypeRegistry(); + NodeTypeRegistry ntReg = sessionContext.getNodeTypeRegistry(); EffectiveNodeType entNew, entOld, entAll; try { entNew = ntReg.getEffectiveNodeType(newMixins); Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AccessManagerForNodeTypes.java =================================================================== --- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AccessManagerForNodeTypes.java (revision ) +++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/AccessManagerForNodeTypes.java (revision ) @@ -0,0 +1,42 @@ +package org.apache.jackrabbit.core.security; + +import org.apache.jackrabbit.spi.*; + +import javax.jcr.*; + +/** + * an interface for fine-grained control of changes to node type registry by each session + * + * an accessManager can also implements this interface to customize authorization for + * changing node type registry. + * when multiple changes are requested from nodeTypeManager, if one of them is rejected by + * accessManager none of them will be executed. + */ +public interface AccessManagerForNodeTypes { + + /** + * Determines whether the subject of the current context is granted authority + * to unregister the specified node type. The existence of the node type is + * guaranteed. + * + * @param name name of node type to be removed + * @return true if the subject of the current context is + * granted access to remove the node type; otherwise false. + * @throws javax.jcr.RepositoryException if an error occurs. + */ + boolean canUnregisterNodeType(Name name) throws RepositoryException; + + /** + * Determines whether the subject of the current context is granted authority + * to register or modify the specified node type. + * + * + * @param name name of node type to be registered + * @param isModify if the node type exists currently and is to be modified + * @return true if the subject of the current context is + * granted access; otherwise false. + * @throws RepositoryException if an error occurs. + */ + boolean canRegisterNodeType(QNodeTypeDefinition type, boolean isModify) throws RepositoryException; + +}