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;
+
+}