You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2012/10/30 11:37:10 UTC
svn commit: r1403656 - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/ oak-jcr/
oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/
Author: angela
Date: Tue Oct 30 10:37:09 2012
New Revision: 1403656
URL: http://svn.apache.org/viewvc?rev=1403656&view=rev
Log:
OAK-250 : Enforce jcr constraints for 'protected' items
- move definition and effective node type related code to nodetype plugin package
- remove duplicate code in NodeTypeImpl
- add missing test for protection in NodeType#canSetProperty
- add TODO/FIXME comments in NodeTypeImpl for code that seems insufficient to me
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/DefinitionProvider.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveNodeTypeProvider.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/NodeTypeImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/ReadOnlyNodeTypeManager.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/ReadWriteNodeTypeManager.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/RootNodeDefinition.java
jackrabbit/oak/trunk/oak-jcr/pom.xml
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/DefinitionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/DefinitionProvider.java?rev=1403656&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/DefinitionProvider.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/DefinitionProvider.java Tue Oct 30 10:37:09 2012
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.nodetype;
+
+import javax.annotation.Nonnull;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeDefinition;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.PropertyDefinition;
+
+/**
+ * DefinitionProvider... TODO
+ */
+public interface DefinitionProvider {
+
+ @Nonnull
+ NodeDefinition getRootDefinition() throws RepositoryException;
+
+ @Nonnull
+ NodeDefinition getDefinition(Node parent, Node targetNode) throws RepositoryException;
+
+ @Nonnull
+ PropertyDefinition getDefinition(Node parent, Property targetProperty) throws RepositoryException;
+
+ @Nonnull
+ PropertyDefinition getDefinition(Node parent, String propertyName, boolean isMultiple, int type, boolean exactTypeMatch) throws RepositoryException;
+
+ @Nonnull
+ PropertyDefinition getDefinition(NodeType nodeType, String propertyName, boolean isMultiple, int type, boolean exactTypeMatch) throws RepositoryException;
+}
\ No newline at end of file
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveNodeTypeProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveNodeTypeProvider.java?rev=1403656&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveNodeTypeProvider.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveNodeTypeProvider.java Tue Oct 30 10:37:09 2012
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.nodetype;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeType;
+
+/**
+ * EffectiveNodeTypeProvider... TODO
+ */
+public interface EffectiveNodeTypeProvider {
+
+ /**
+ * Calculates and returns all effective node types of the given node.
+ *
+ * @param targetNode the node for which the types should be calculated.
+ * @return all types of the given node
+ * @throws RepositoryException if the type information can not be accessed
+ */
+ Iterable<NodeType> getEffectiveNodeTypes(Node targetNode) throws RepositoryException;
+}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/NodeTypeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/NodeTypeImpl.java?rev=1403656&r1=1403655&r2=1403656&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/NodeTypeImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/NodeTypeImpl.java Tue Oct 30 10:37:09 2012
@@ -35,7 +35,6 @@ import javax.jcr.nodetype.NoSuchNodeType
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.NodeTypeIterator;
-import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.nodetype.PropertyDefinition;
import org.apache.jackrabbit.commons.iterator.NodeTypeIteratorAdapter;
@@ -73,17 +72,15 @@ import static org.apache.jackrabbit.oak.
*/
class NodeTypeImpl implements NodeType {
- private static final Logger log =
- LoggerFactory.getLogger(NodeTypeImpl.class);
+ private static final Logger log = LoggerFactory.getLogger(NodeTypeImpl.class);
- private final NodeTypeManager manager;
+ private final ReadOnlyNodeTypeManager manager;
private final ValueFactory factory;
private final NodeUtil node;
- public NodeTypeImpl(
- NodeTypeManager manager, ValueFactory factory, NodeUtil node) {
+ public NodeTypeImpl(ReadOnlyNodeTypeManager manager, ValueFactory factory, NodeUtil node) {
this.manager = manager;
this.factory = factory;
this.node = node;
@@ -272,16 +269,15 @@ class NodeTypeImpl implements NodeType {
return canRemoveProperty(propertyName);
}
- for (PropertyDefinition definition : getPropertyDefinitions()) {
- String name = definition.getName();
- if (propertyName.equals(name) || "*".equals(name)) {
- if (!definition.isMultiple()) {
- return meetsTypeConstraints(value, definition.getRequiredType()) &&
- meetsValueConstraints(value, definition.getValueConstraints());
- }
- }
+ try {
+ PropertyDefinition def = manager.getDefinition(this, propertyName, false, value.getType(), false);
+ return !def.isProtected() &&
+ meetsTypeConstraints(value, def.getRequiredType()) &&
+ meetsValueConstraints(value, def.getValueConstraints());
+ } catch (RepositoryException e) {
+ log.debug(e.getMessage());
+ return false;
}
- return false;
}
@Override
@@ -290,16 +286,16 @@ class NodeTypeImpl implements NodeType {
return canRemoveProperty(propertyName);
}
- for (PropertyDefinition definition : getPropertyDefinitions()) {
- String name = definition.getName();
- if (propertyName.equals(name) || "*".equals(name)) {
- if (definition.isMultiple()) {
- return meetsTypeConstraints(values, definition.getRequiredType()) &&
- meetsValueConstraints(values, definition.getValueConstraints());
- }
- }
+ try {
+ int type = (values.length == 0) ? PropertyType.STRING : values[0].getType();
+ PropertyDefinition def = manager.getDefinition(this, propertyName, true, type, false);
+ return !def.isProtected() &&
+ meetsTypeConstraints(values, def.getRequiredType()) &&
+ meetsValueConstraints(values, def.getValueConstraints());
+ } catch (RepositoryException e) {
+ log.debug(e.getMessage());
+ return false;
}
- return false;
}
private static boolean meetsTypeConstraints(Value value, int requiredType) {
@@ -427,9 +423,13 @@ class NodeTypeImpl implements NodeType {
log.warn("Unable to access node type " + nodeTypeName, e);
return false;
}
+ // FIXME: properly calculate matching definition
for (NodeDefinition definition : getChildNodeDefinitions()) {
String name = definition.getName();
if (matches(childNodeName, name) || "*".equals(name)) {
+ if (definition.isProtected()) {
+ return false;
+ }
for (String required : definition.getRequiredPrimaryTypeNames()) {
if (type.isNodeType(required)) {
return true;
@@ -447,6 +447,7 @@ class NodeTypeImpl implements NodeType {
@Override
public boolean canRemoveNode(String nodeName) {
+ // FIXME: properly calculate matching definition taking residual definitions into account.
NodeDefinition[] childNodeDefinitions = getChildNodeDefinitions();
for (NodeDefinition definition : childNodeDefinitions) {
String name = definition.getName();
@@ -461,6 +462,7 @@ class NodeTypeImpl implements NodeType {
@Override
public boolean canRemoveProperty(String propertyName) {
+ // FIXME: should properly calculate matching definition taking residual definitions into account.
PropertyDefinition[] propertyDefinitions = getPropertyDefinitions();
for (PropertyDefinition definition : propertyDefinitions) {
String name = definition.getName();
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/ReadOnlyNodeTypeManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/ReadOnlyNodeTypeManager.java?rev=1403656&r1=1403655&r2=1403656&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/ReadOnlyNodeTypeManager.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/ReadOnlyNodeTypeManager.java Tue Oct 30 10:37:09 2012
@@ -16,36 +16,50 @@
*/
package org.apache.jackrabbit.oak.plugins.nodetype;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
-
+import java.util.Map;
+import java.util.Queue;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.Value;
import javax.jcr.ValueFactory;
import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.NodeDefinitionTemplate;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.NodeTypeDefinition;
import javax.jcr.nodetype.NodeTypeIterator;
import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.nodetype.NodeTypeTemplate;
+import javax.jcr.nodetype.PropertyDefinition;
import javax.jcr.nodetype.PropertyDefinitionTemplate;
import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Queues;
import org.apache.jackrabbit.commons.iterator.NodeTypeIteratorAdapter;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.namepath.NameMapper;
import org.apache.jackrabbit.oak.namepath.NamePathMapperImpl;
import org.apache.jackrabbit.oak.util.NodeUtil;
+import static javax.jcr.PropertyType.UNDEFINED;
+
/**
* Base implementation of a {@link NodeTypeManager} with support for reading
* node types from the {@link Tree} returned by {@link #getTypes()}. Methods
* related to node type modifications throw
* {@link UnsupportedRepositoryOperationException}.
*/
-public abstract class ReadOnlyNodeTypeManager implements NodeTypeManager {
+public abstract class ReadOnlyNodeTypeManager implements NodeTypeManager, EffectiveNodeTypeProvider, DefinitionProvider {
/**
* Returns the internal name for the specified JCR name.
@@ -206,4 +220,203 @@ public abstract class ReadOnlyNodeTypeMa
public void unregisterNodeTypes(String[] names) throws RepositoryException {
throw new UnsupportedRepositoryOperationException();
}
+
+ //------------------------------------------< EffectiveNodeTypeProvider >---
+
+ /**
+ * Returns all the node types of the given node, in a breadth-first
+ * traversal order of the type hierarchy.
+ *
+ * @param node node instance
+ * @return all types of the given node
+ * @throws RepositoryException if the type information can not be accessed
+ * @param node
+ * @return
+ * @throws RepositoryException
+ */
+ @Override
+ public Iterable<NodeType> getEffectiveNodeTypes(Node node) throws RepositoryException {
+ Queue<NodeType> queue = Queues.newArrayDeque();
+ queue.add(node.getPrimaryNodeType());
+ queue.addAll(Arrays.asList(node.getMixinNodeTypes()));
+
+ return getEffectiveNodeTypes(queue);
+ }
+
+
+ //-------------------------------------------------< DefinitionProvider >---
+
+ @Override
+ public NodeDefinition getRootDefinition() throws RepositoryException {
+ return new RootNodeDefinition(this);
+ }
+
+ @Override
+ public NodeDefinition getDefinition(@Nonnull Node parent, @Nonnull Node targetNode) throws RepositoryException {
+ String name = targetNode.getName();
+ List<NodeDefinition> residualDefs = new ArrayList<NodeDefinition>();
+ // TODO: This may need to be optimized
+ for (NodeType nt : getEffectiveNodeTypes(parent)) {
+ for (NodeDefinition def : nt.getDeclaredChildNodeDefinitions()) {
+ String defName = def.getName();
+ if (name.equals(defName)) {
+ boolean match = true;
+ for (String type : def.getRequiredPrimaryTypeNames()) {
+ if (!targetNode.isNodeType(type)) {
+ match = false;
+ }
+ }
+ if (match) {
+ return def;
+ }
+ } else if ("*".equals(defName)) {
+ residualDefs.add(def);
+ }
+ }
+ }
+
+ for (NodeDefinition def : residualDefs) {
+ String defName = def.getName();
+ if ("*".equals(defName)) {
+ boolean match = true;
+ for (String type : def.getRequiredPrimaryTypeNames()) {
+ if (!targetNode.isNodeType(type)) {
+ match = false;
+ }
+ }
+ if (match) {
+ return def;
+ }
+ }
+ }
+
+ throw new RepositoryException("No matching node definition found for " + this);
+ }
+
+ @Override
+ public PropertyDefinition getDefinition(Node parent, Property targetProperty) throws RepositoryException {
+ String name = targetProperty.getName();
+ boolean isMultiple = targetProperty.isMultiple();
+ int type = UNDEFINED;
+ if (isMultiple) {
+ Value[] values = targetProperty.getValues();
+ if (values.length > 0) {
+ type = values[0].getType();
+ }
+ } else {
+ type = targetProperty.getValue().getType();
+ }
+
+ // TODO: This may need to be optimized
+ List<PropertyDefinition> residualDefs = new ArrayList<PropertyDefinition>();
+ for (NodeType nt : getEffectiveNodeTypes(parent)) {
+ for (PropertyDefinition def : nt.getDeclaredPropertyDefinitions()) {
+ String defName = def.getName();
+ int defType = def.getRequiredType();
+ if ((name.equals(defName))
+ && (type == defType || UNDEFINED == type || UNDEFINED == defType)
+ && isMultiple == def.isMultiple()) {
+ return def;
+ } else if ("*".equals(defName)) {
+ residualDefs.add(def);
+ }
+ }
+ }
+
+ for (PropertyDefinition def : residualDefs) {
+ String defName = def.getName();
+ int defType = def.getRequiredType();
+ if (("*".equals(defName))
+ && (type == defType || UNDEFINED == type || UNDEFINED == defType)
+ && isMultiple == def.isMultiple()) {
+ return def;
+ }
+ }
+
+ // FIXME: Shouldn't be needed
+ for (NodeType nt : getEffectiveNodeTypes(parent)) {
+ for (PropertyDefinition def : nt.getDeclaredPropertyDefinitions()) {
+ String defName = def.getName();
+ if ((name.equals(defName) || "*".equals(defName))
+ && type == PropertyType.STRING
+ && isMultiple == def.isMultiple()) {
+ return def;
+ }
+ }
+ }
+
+ throw new RepositoryException("No matching property definition found for " + this);
+ }
+
+ @Override
+ public PropertyDefinition getDefinition(Node parent, String propertyName, boolean isMultiple, int type, boolean exactTypeMatch) throws RepositoryException {
+ return getPropertyDefinition(getEffectiveNodeTypes(parent), propertyName, isMultiple, type, exactTypeMatch);
+ }
+
+ @Override
+ public PropertyDefinition getDefinition(NodeType nodeType, String propertyName, boolean isMultiple, int type, boolean exactTypeMatch) throws RepositoryException {
+ Queue<NodeType> queue = Queues.newArrayDeque();
+ queue.add(nodeType);
+ Collection<NodeType> effective = getEffectiveNodeTypes(queue);
+ return getPropertyDefinition(effective, propertyName, isMultiple, type, exactTypeMatch);
+ }
+
+ //------------------------------------------------------------< private >---
+
+ private Collection<NodeType> getEffectiveNodeTypes(Queue<NodeType> queue) {
+ Map<String, NodeType> types = Maps.<String, NodeType>newHashMap();
+ while (!queue.isEmpty()) {
+ NodeType type = queue.remove();
+ String name = type.getName();
+ if (!types.containsKey(name)) {
+ types.put(name, type);
+ queue.addAll(Arrays.asList(type.getDeclaredSupertypes()));
+ }
+ }
+
+ return types.values();
+ }
+
+ private PropertyDefinition getPropertyDefinition(Iterable<NodeType> effectiveNodeTypes,
+ String propertyName, boolean isMultiple,
+ int type, boolean exactTypeMatch) throws RepositoryException {
+ // TODO: This may need to be optimized
+ for (NodeType nt : effectiveNodeTypes) {
+ for (PropertyDefinition def : nt.getDeclaredPropertyDefinitions()) {
+ String defName = def.getName();
+ int defType = def.getRequiredType();
+ if (propertyName.equals(defName)
+ && isMultiple == def.isMultiple()
+ &&(!exactTypeMatch || (type == defType || UNDEFINED == type || UNDEFINED == defType))) {
+ return def;
+ }
+ }
+ }
+
+ // try if there is a residual definition
+ for (NodeType nt : effectiveNodeTypes) {
+ for (PropertyDefinition def : nt.getDeclaredPropertyDefinitions()) {
+ String defName = def.getName();
+ int defType = def.getRequiredType();
+ if ("*".equals(defName)
+ && isMultiple == def.isMultiple()
+ && (!exactTypeMatch || (type == defType || UNDEFINED == type || UNDEFINED == defType))) {
+ return def;
+ }
+ }
+ }
+
+ // FIXME: Shouldn't be needed
+ for (NodeType nt : effectiveNodeTypes) {
+ for (PropertyDefinition def : nt.getDeclaredPropertyDefinitions()) {
+ String defName = def.getName();
+ if ((propertyName.equals(defName) || "*".equals(defName))
+ && type == PropertyType.STRING
+ && isMultiple == def.isMultiple()) {
+ return def;
+ }
+ }
+ }
+ throw new RepositoryException("No matching property definition found for " + propertyName);
+ }
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/ReadWriteNodeTypeManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/ReadWriteNodeTypeManager.java?rev=1403656&r1=1403655&r2=1403656&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/ReadWriteNodeTypeManager.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/ReadWriteNodeTypeManager.java Tue Oct 30 10:37:09 2012
@@ -100,7 +100,6 @@ import static org.apache.jackrabbit.oak.
* {@link ReadOnlyNodeTypeManager} for the following methods:
* <ul>
* <li>{@link #getValueFactory()}</li>
- * <li>{@link #getCoreValueFactory()}</li>
* <li>{@link #getNameMapper()}</li>
* </ul>
*/
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/RootNodeDefinition.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/RootNodeDefinition.java?rev=1403656&r1=1403655&r2=1403656&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/RootNodeDefinition.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/RootNodeDefinition.java Tue Oct 30 10:37:09 2012
@@ -28,7 +28,7 @@ import org.slf4j.LoggerFactory;
/**
* Node definition for the root node.
*/
-public final class RootNodeDefinition implements NodeDefinition {
+final class RootNodeDefinition implements NodeDefinition {
/**
* logger instance
@@ -39,10 +39,11 @@ public final class RootNodeDefinition im
private final NodeTypeManager ntManager;
- public RootNodeDefinition(NodeTypeManager ntManager) {
+ RootNodeDefinition(NodeTypeManager ntManager) {
this.ntManager = ntManager;
}
+ //-----------------------------------------------------< NodeDefinition >---
@Override
public NodeType[] getRequiredPrimaryTypes() {
try {
Modified: jackrabbit/oak/trunk/oak-jcr/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/pom.xml?rev=1403656&r1=1403655&r2=1403656&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-jcr/pom.xml Tue Oct 30 10:37:09 2012
@@ -65,8 +65,6 @@
org.apache.jackrabbit.test.api.nodetype.CanSetPropertyDoubleTest#testConversionsMultiple <!-- OAK-302 -->
org.apache.jackrabbit.test.api.nodetype.CanSetPropertyLongTest#testConversions <!-- OAK-302 -->
org.apache.jackrabbit.test.api.nodetype.CanSetPropertyLongTest#testConversionsMultiple <!-- OAK-302 -->
- org.apache.jackrabbit.test.api.nodetype.CanSetPropertyMultipleTest#testReturnFalseBecauseIsProtected <!-- OAK-250 -->
- org.apache.jackrabbit.test.api.nodetype.CanSetPropertyTest#testReturnFalseBecauseIsProtected <!-- OAK-250 -->
org.apache.jackrabbit.test.api.SetPropertyAssumeTypeTest#testValueConstraintViolationExceptionBecauseOfInvalidTypeParameter
org.apache.jackrabbit.test.api.SetPropertyAssumeTypeTest#testValuesConstraintViolationExceptionBecauseOfInvalidTypeParameter
org.apache.jackrabbit.test.api.SetPropertyAssumeTypeTest#testStringConstraintViolationExceptionBecauseOfInvalidTypeParameter
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java?rev=1403656&r1=1403655&r2=1403656&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/ItemImpl.java Tue Oct 30 10:37:09 2012
@@ -16,31 +16,21 @@
*/
package org.apache.jackrabbit.oak.jcr;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Queue;
import javax.annotation.Nonnull;
import javax.jcr.InvalidItemStateException;
import javax.jcr.Item;
import javax.jcr.Node;
import javax.jcr.Property;
-import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.ValueFactory;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.ItemDefinition;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.nodetype.PropertyDefinition;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Queues;
import org.apache.jackrabbit.commons.AbstractItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import static javax.jcr.PropertyType.UNDEFINED;
-
/**
* {@code ItemImpl}...
*/
@@ -158,85 +148,7 @@ abstract class ItemImpl<T extends ItemDe
return (isNode() ? "Node[" : "Property[") + dlg + ']';
}
- //------------------------------------------------------------< internal >---
-
- /**
- * Returns all the node types of the given node, in a breadth-first
- * traversal order of the type hierarchy.
- * <p>
- * This utility method used by the getDefinition() methods in the
- * {@link PropertyImpl} and {@link NodeImpl} subclasses.
- *
- * @param node node instance
- * @return all types of the given node
- * @throws RepositoryException if the type information can not be accessed
- */
- protected static Iterable<NodeType> getAllNodeTypes(Node node)
- throws RepositoryException {
- Map<String, NodeType> types = Maps.newHashMap();
-
- Queue<NodeType> queue = Queues.newArrayDeque();
- queue.add(node.getPrimaryNodeType());
- queue.addAll(Arrays.asList(node.getMixinNodeTypes()));
- while (!queue.isEmpty()) {
- NodeType type = queue.remove();
- String name = type.getName();
- if (!types.containsKey(name)) {
- types.put(name, type);
- queue.addAll(Arrays.asList(type.getDeclaredSupertypes()));
- }
- }
-
- return types.values();
- }
-
- // FIXME: move to node type utility (oak-nodetype-plugin)
- protected static PropertyDefinition getPropertyDefinition(Node parent,
- String propName,
- boolean isMultiple,
- int type,
- boolean exactTypeMatch) throws RepositoryException {
- // TODO: This may need to be optimized
- for (NodeType nt : getAllNodeTypes(parent)) {
- for (PropertyDefinition def : nt.getDeclaredPropertyDefinitions()) {
- String defName = def.getName();
- int defType = def.getRequiredType();
- if (propName.equals(defName)
- && isMultiple == def.isMultiple()
- &&(!exactTypeMatch || (type == defType || UNDEFINED == type || UNDEFINED == defType))) {
- return def;
- }
- }
- }
-
- // try if there is a residual definition
- for (NodeType nt : getAllNodeTypes(parent)) {
- for (PropertyDefinition def : nt.getDeclaredPropertyDefinitions()) {
- String defName = def.getName();
- int defType = def.getRequiredType();
- if ("*".equals(defName)
- && isMultiple == def.isMultiple()
- && (!exactTypeMatch || (type == defType || UNDEFINED == type || UNDEFINED == defType))) {
- return def;
- }
- }
- }
-
- // FIXME: Shouldn't be needed
- for (NodeType nt : getAllNodeTypes(parent)) {
- for (PropertyDefinition def : nt.getDeclaredPropertyDefinitions()) {
- String defName = def.getName();
- if ((propName.equals(defName) || "*".equals(defName))
- && type == PropertyType.STRING
- && isMultiple == def.isMultiple()) {
- return def;
- }
- }
- }
- throw new RepositoryException("No matching property definition found for " + propName);
- }
-
-
+ //-----------------------------------------------------------< internal >---
/**
* Performs a sanity check on this item and the associated session.
*
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java?rev=1403656&r1=1403655&r2=1403656&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/NodeImpl.java Tue Oct 30 10:37:09 2012
@@ -18,7 +18,6 @@ package org.apache.jackrabbit.oak.jcr;
import java.io.InputStream;
import java.math.BigDecimal;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
@@ -75,7 +74,6 @@ import org.apache.jackrabbit.oak.api.Tre
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.plugins.identifier.IdentifierManager;
import org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants;
-import org.apache.jackrabbit.oak.plugins.nodetype.RootNodeDefinition;
import org.apache.jackrabbit.oak.util.TODO;
import org.apache.jackrabbit.value.ValueHelper;
import org.slf4j.Logger;
@@ -954,47 +952,10 @@ public class NodeImpl extends ItemImpl<N
@Nonnull
public NodeDefinition getDefinition() throws RepositoryException {
if (getDepth() == 0) {
- return new RootNodeDefinition(dlg.sessionDelegate.getNodeTypeManager());
- }
-
- String name = getName();
- List<NodeDefinition> residualDefs = new ArrayList<NodeDefinition>();
- // TODO: This may need to be optimized
- for (NodeType nt : getAllNodeTypes(getParent())) {
- for (NodeDefinition def : nt.getDeclaredChildNodeDefinitions()) {
- String defName = def.getName();
- if (name.equals(defName)) {
- boolean match = true;
- for (String type : def.getRequiredPrimaryTypeNames()) {
- if (!isNodeType(type)) {
- match = false;
- }
- }
- if (match) {
- return def;
- }
- } else if ("*".equals(defName)) {
- residualDefs.add(def);
- }
- }
- }
-
- for (NodeDefinition def : residualDefs) {
- String defName = def.getName();
- if ("*".equals(defName)) {
- boolean match = true;
- for (String type : def.getRequiredPrimaryTypeNames()) {
- if (!isNodeType(type)) {
- match = false;
- }
- }
- if (match) {
- return def;
- }
- }
+ return dlg.sessionDelegate.getDefinitionProvider().getRootDefinition();
+ } else {
+ return dlg.sessionDelegate.getDefinitionProvider().getDefinition(getParent(), this);
}
-
- throw new RepositoryException("No matching node definition found for " + this);
}
@Override
@@ -1359,7 +1320,7 @@ public class NodeImpl extends ItemImpl<N
}
private void autoCreateItems() throws RepositoryException {
- Iterable<NodeType> types = getAllNodeTypes(this);
+ Iterable<NodeType> types = dlg.sessionDelegate.getEffectiveNodeTypeProvider().getEffectiveNodeTypes(this);
for (NodeType nt : types) {
for (PropertyDefinition pd : nt.getPropertyDefinitions()) {
if (pd.isAutoCreated() && dlg.getProperty(pd.getName()) == null) {
@@ -1442,7 +1403,7 @@ public class NodeImpl extends ItemImpl<N
addNode(definition.getName(), definition.getDefaultPrimaryTypeName());
}
- // TODO: hack to filter for a subset of supported mixins for now
+ // FIXME: hack to filter for a subset of supported mixins for now
// this allows only harmless mixin types so that other code like addMixin gets test coverage
private boolean isSupportedMixinName(String mixinName) throws RepositoryException {
String oakName = sessionDelegate.getOakPathOrThrow(mixinName);
@@ -1500,7 +1461,7 @@ public class NodeImpl extends ItemImpl<N
if (hasProperty(jcrName)) {
definition = getProperty(jcrName).getDefinition();
} else {
- definition = getPropertyDefinition(NodeImpl.this, oakName, false, type, exactTypeMatch);
+ definition = dlg.sessionDelegate.getDefinitionProvider().getDefinition(NodeImpl.this, oakName, false, type, exactTypeMatch);
}
checkProtected(definition);
if (definition.isMultiple()) {
@@ -1535,7 +1496,7 @@ public class NodeImpl extends ItemImpl<N
if (hasProperty(jcrName)) {
definition = getProperty(jcrName).getDefinition();
} else {
- definition = getPropertyDefinition(NodeImpl.this, oakName, true, type, exactTypeMatch);
+ definition = dlg.sessionDelegate.getDefinitionProvider().getDefinition(NodeImpl.this, oakName, true, type, exactTypeMatch);
}
checkProtected(definition);
if (!definition.isMultiple()) {
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java?rev=1403656&r1=1403655&r2=1403656&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/PropertyImpl.java Tue Oct 30 10:37:09 2012
@@ -45,7 +45,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.google.common.base.Preconditions.checkArgument;
-import static javax.jcr.PropertyType.UNDEFINED;
/**
* {@code PropertyImpl}...
@@ -550,17 +549,7 @@ public class PropertyImpl extends ItemIm
@Override
@Nonnull
public PropertyDefinition getDefinition() throws RepositoryException {
- int type = UNDEFINED;
- if (isMultiple()) {
- Value[] values = getValues();
- if (values.length > 0) {
- type = values[0].getType();
- }
- } else {
- type = getValue().getType();
- }
-
- return getPropertyDefinition(getParent(), getName(), isMultiple(), type, true);
+ return dlg.sessionDelegate.getDefinitionProvider().getDefinition(getParent(), this);
}
/**
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java?rev=1403656&r1=1403655&r2=1403656&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java Tue Oct 30 10:37:09 2012
@@ -47,6 +47,8 @@ import org.apache.jackrabbit.oak.commons
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
import org.apache.jackrabbit.oak.namepath.NamePathMapperImpl;
import org.apache.jackrabbit.oak.plugins.identifier.IdentifierManager;
+import org.apache.jackrabbit.oak.plugins.nodetype.DefinitionProvider;
+import org.apache.jackrabbit.oak.plugins.nodetype.EffectiveNodeTypeProvider;
import org.apache.jackrabbit.oak.plugins.observation.ObservationManagerImpl;
import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeManagerImpl;
@@ -512,4 +514,14 @@ public class SessionDelegate {
}
return privilegeManager;
}
+
+ @Nonnull
+ EffectiveNodeTypeProvider getEffectiveNodeTypeProvider() throws RepositoryException {
+ return (EffectiveNodeTypeProvider) workspace.getNodeTypeManager();
+ }
+
+ @Nonnull
+ DefinitionProvider getDefinitionProvider() throws RepositoryException {
+ return (DefinitionProvider) workspace.getNodeTypeManager();
+ }
}