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 ju...@apache.org on 2013/03/22 15:57:58 UTC
svn commit: r1459821 - in
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype:
DefinitionProvider.java EffectiveNodeType.java NodeTypeImpl.java
ReadOnlyNodeTypeManager.java
Author: jukka
Date: Fri Mar 22 14:57:58 2013
New Revision: 1459821
URL: http://svn.apache.org/r1459821
Log:
OAK-702: Optimize access to node type information
Streamline effective type construction and access to property and child node definitions
Modified:
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/EffectiveNodeType.java
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
Modified: 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=1459821&r1=1459820&r2=1459821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/DefinitionProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/DefinitionProvider.java Fri Mar 22 14:57:58 2013
@@ -22,7 +22,6 @@ import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NodeDefinition;
-import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.PropertyDefinition;
import org.apache.jackrabbit.oak.api.PropertyState;
@@ -68,22 +67,6 @@ public interface DefinitionProvider {
throws ConstraintViolationException, RepositoryException;
/**
- * Calculates the applicable definition for the child node with the
- * specified name and node type under the given parent node.
- *
- * @param parentNodeTypes The node types of the parent node.
- * @param nodeName The internal oak name of the child node.
- * @param nodeType The target node type of the child.
- * @return the applicable definition for the child node with the specified
- * name and primary type.
- * @throws ConstraintViolationException If no matching definition can be found.
- * @throws RepositoryException If another error occurs.
- */
- @Nonnull
- NodeDefinition getDefinition(Iterable<NodeType> parentNodeTypes, String nodeName,
- NodeType nodeType) throws ConstraintViolationException, RepositoryException;
-
- /**
* Calculates the definition of the specified property.
*
* @param parent The parent node.
@@ -151,21 +134,4 @@ public interface DefinitionProvider {
int type, boolean exactTypeMatch)
throws ConstraintViolationException, RepositoryException;
- /**
- * Calculates the applicable definition for the property with the specified
- * characteristics under a parent with the specified node types.
- *
- * @param nodeTypes The node types of the parent tree.
- * @param propertyName The internal oak name of the property for which the
- * definition should be retrieved.
- * @param isMultiple {@code true} if the target property is multi-valued.
- * @param type The target type of the property.
- * @param exactTypeMatch {@code true} if the required type of the definition
- * must exactly match the type of the target property.
- * @return the applicable definition for the target property.
- * @throws ConstraintViolationException If no matching definition can be found.
- * @throws RepositoryException If another error occurs.
- */
- @Nonnull
- PropertyDefinition getDefinition(Iterable<NodeType> nodeTypes, String propertyName, boolean isMultiple, int type, boolean exactTypeMatch) throws ConstraintViolationException, RepositoryException;
}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveNodeType.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveNodeType.java?rev=1459821&r1=1459820&r2=1459821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveNodeType.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/EffectiveNodeType.java Fri Mar 22 14:57:58 2013
@@ -16,13 +16,13 @@
*/
package org.apache.jackrabbit.oak.plugins.nodetype;
+import static com.google.common.base.Preconditions.checkNotNull;
import static javax.jcr.PropertyType.UNDEFINED;
+import static org.apache.jackrabbit.JcrConstants.NT_BASE;
import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
+import java.util.Map;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -44,6 +44,7 @@ import org.slf4j.LoggerFactory;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
/**
* EffectiveNodeType... TODO
@@ -52,28 +53,44 @@ public class EffectiveNodeType {
private static final Logger log = LoggerFactory.getLogger(EffectiveNodeType.class);
- private final Collection<NodeType> nodeTypes;
+ private static final NodeType[] NO_MIXINS = new NodeType[0];
+
+ private final Map<String, NodeType> nodeTypes = Maps.newLinkedHashMap();
+
private final ReadOnlyNodeTypeManager ntMgr;
- private EffectiveNodeType(Collection<NodeType> nodeTypes, ReadOnlyNodeTypeManager ntMgr) {
- this.nodeTypes = nodeTypes;
+ EffectiveNodeType(
+ NodeType primary, NodeType[] mixins,
+ ReadOnlyNodeTypeManager ntMgr) {
this.ntMgr = ntMgr;
- }
- static EffectiveNodeType create(Collection<NodeType> nodeTypes, ReadOnlyNodeTypeManager ntMgr) throws ConstraintViolationException {
- if (!isValid(nodeTypes)) {
- throw new ConstraintViolationException("Invalid effective node type");
+ addNodeType(checkNotNull(primary));
+ for (NodeType mixin : checkNotNull(mixins)) {
+ addNodeType(mixin);
}
- return new EffectiveNodeType(nodeTypes, ntMgr);
}
- private static boolean isValid(Collection<NodeType> nodeTypes) {
- // FIXME: add validation
- return true;
+ EffectiveNodeType(NodeType primary, ReadOnlyNodeTypeManager ntMgr) {
+ this(primary, NO_MIXINS, ntMgr);
}
- public Iterable<NodeType> getAllNodeTypes() {
- return nodeTypes;
+ private void addNodeType(NodeType type) {
+ String name = type.getName();
+ if (!nodeTypes.containsKey(name)) {
+ nodeTypes.put(name, type);
+ NodeType[] supertypes = type.getDeclaredSupertypes();
+ if (supertypes.length > 1) {
+ for (NodeType supertype : supertypes) {
+ addNodeType(supertype);
+ }
+ } else if (!type.isMixin() && !nodeTypes.containsKey(NT_BASE)) {
+ try {
+ addNodeType(ntMgr.getNodeType(NT_BASE));
+ } catch (RepositoryException e) {
+ // TODO: ignore/warning/error?
+ }
+ }
+ }
}
/**
@@ -84,7 +101,7 @@ public class EffectiveNodeType {
* @return {@code true} if the given node type is included, otherwise {@code false}.
*/
public boolean includesNodeType(String nodeTypeName) {
- for (NodeType type : nodeTypes) {
+ for (NodeType type : nodeTypes.values()) {
if (type.isNodeType(nodeTypeName)) {
return true;
}
@@ -131,17 +148,12 @@ public class EffectiveNodeType {
log.debug("Unknown mixin type " + mixin);
}
- if (mixinType != null) {
- Set<NodeType> newTypes = new HashSet<NodeType>(nodeTypes);
- newTypes.add(mixinType);
- return isValid(newTypes);
- }
- return false;
+ return true;
}
public Iterable<NodeDefinition> getNodeDefinitions() {
List<NodeDefinition> definitions = new ArrayList<NodeDefinition>();
- for (NodeType nt : nodeTypes) {
+ for (NodeType nt : nodeTypes.values()) {
definitions.addAll(((NodeTypeImpl) nt).internalGetChildDefinitions());
}
return definitions;
@@ -149,7 +161,7 @@ public class EffectiveNodeType {
public Iterable<PropertyDefinition> getPropertyDefinitions() {
List<PropertyDefinition> definitions = new ArrayList<PropertyDefinition>();
- for (NodeType nt : nodeTypes) {
+ for (NodeType nt : nodeTypes.values()) {
definitions.addAll(((NodeTypeImpl) nt).internalGetPropertyDefinitions());
}
return definitions;
@@ -305,7 +317,7 @@ public class EffectiveNodeType {
}
public void checkMandatoryItems(Tree tree) throws ConstraintViolationException {
- for (NodeType nodeType : nodeTypes) {
+ for (NodeType nodeType : nodeTypes.values()) {
for (PropertyDefinition pd : nodeType.getPropertyDefinitions()) {
String name = pd.getName();
if (pd.isMandatory() && !pd.isProtected() && tree.getProperty(name) == null) {
@@ -324,8 +336,7 @@ public class EffectiveNodeType {
}
public void checkOrderableChildNodes() throws UnsupportedRepositoryOperationException {
- Iterable<NodeType> nts = getAllNodeTypes();
- for (NodeType nt : nts) {
+ for (NodeType nt : nodeTypes.values()) {
if (nt.hasOrderableChildNodes()) {
return;
}
@@ -335,13 +346,18 @@ public class EffectiveNodeType {
}
/**
+ * Calculates the applicable definition for the property with the specified
+ * characteristics under a parent with this effective type.
*
- * @param propertyName The internal oak name of the property.
- * @param isMultiple
- * @param type
- * @param exactTypeMatch
- * @return
- * @throws ConstraintViolationException
+ * @param propertyName The internal oak name of the property for which the
+ * definition should be retrieved.
+ * @param isMultiple {@code true} if the target property is multi-valued.
+ * @param type The target type of the property.
+ * @param exactTypeMatch {@code true} if the required type of the definition
+ * must exactly match the type of the target property.
+ * @return the applicable definition for the target property.
+ * @throws ConstraintViolationException If no matching definition can be found.
+ * @throws RepositoryException If another error occurs.
*/
public PropertyDefinition getPropertyDefinition(
String propertyName, boolean isMultiple,
@@ -413,16 +429,29 @@ public class EffectiveNodeType {
return getPropertyDefinition(propertyName, isMultiple, propertyType, true);
}
- private NodeDefinition getDefinition(String nodeName, NodeType nodeType) throws ConstraintViolationException {
+ /**
+ * Calculates the applicable definition for the child node with the
+ * specified name and node type.
+ *
+ * @param nodeName The internal oak name of the child node.
+ * @param nodeType The target node type of the child.
+ * @return the applicable definition for the child node with the specified
+ * name and primary type.
+ * @throws ConstraintViolationException If no matching definition can be found.
+ * @throws RepositoryException If another error occurs.
+ */
+ private NodeDefinition getDefinition(String nodeName, NodeType nodeType)
+ throws ConstraintViolationException {
// FIXME: ugly hack to workaround sns-hack that was used to map sns-item definitions with node types.
String nameToCheck = nodeName;
- if (nodeName.startsWith("jcr:childNodeDefinition") && !nodeName.equals("jcr:childNodeDefinition")) {
+ if (nodeName.startsWith("jcr:childNodeDefinition")) {
nameToCheck = nodeName.substring(0, "jcr:childNodeDefinition".length());
}
- if (nodeName.startsWith("jcr:propertyDefinition") && !nodeName.equals("jcr:propertyDefinition")) {
+ if (nodeName.startsWith("jcr:propertyDefinition")) {
nameToCheck = nodeName.substring(0, "jcr:propertyDefinition".length());
}
- return ntMgr.getDefinition(nodeTypes, nameToCheck, nodeType);
+ return getNodeDefinition(
+ nameToCheck, new EffectiveNodeType(nodeType, ntMgr));
}
private static class DefinitionNamePredicate implements Predicate<ItemDefinition> {
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=1459821&r1=1459820&r2=1459821&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 Fri Mar 22 14:57:58 2013
@@ -21,7 +21,6 @@ import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -305,8 +304,10 @@ class NodeTypeImpl extends AbstractTypeD
}
try {
- Iterable<NodeType> nts = Collections.singleton((NodeType) this);
- PropertyDefinition def = getManager().getDefinition(nts, propertyName, false, value.getType(), false);
+ EffectiveNodeType effective =
+ new EffectiveNodeType(this, getManager());
+ PropertyDefinition def = effective.getPropertyDefinition(
+ propertyName, false, value.getType(), false);
return !def.isProtected() &&
meetsTypeConstraints(value, def.getRequiredType()) &&
meetsValueConstraints(value, def.getValueConstraints());
@@ -323,9 +324,11 @@ class NodeTypeImpl extends AbstractTypeD
}
try {
- Iterable<NodeType> nts = Collections.singleton((NodeType) this);
int type = (values.length == 0) ? PropertyType.STRING : values[0].getType();
- PropertyDefinition def = getManager().getDefinition(nts, propertyName, true, type, false);
+ EffectiveNodeType effective =
+ new EffectiveNodeType(this, getManager());
+ PropertyDefinition def = effective.getPropertyDefinition(
+ propertyName, true, type, false);
return !def.isProtected() &&
meetsTypeConstraints(values, def.getRequiredType()) &&
meetsValueConstraints(values, def.getValueConstraints());
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=1459821&r1=1459820&r2=1459821&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 Fri Mar 22 14:57:58 2013
@@ -16,12 +16,8 @@
*/
package org.apache.jackrabbit.oak.plugins.nodetype;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
-import java.util.Queue;
import java.util.Set;
import javax.annotation.CheckForNull;
@@ -32,7 +28,6 @@ import javax.jcr.RepositoryException;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
-import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.NodeDefinitionTemplate;
@@ -45,8 +40,6 @@ import javax.jcr.nodetype.PropertyDefini
import javax.jcr.nodetype.PropertyDefinitionTemplate;
import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Queues;
import com.google.common.collect.Sets;
import org.apache.jackrabbit.JcrConstants;
@@ -66,7 +59,6 @@ import static javax.jcr.PropertyType.UND
import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES;
import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
import static org.apache.jackrabbit.oak.api.Type.STRING;
-import static org.apache.jackrabbit.oak.api.Type.STRINGS;
import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.NODE_TYPES_PATH;
@@ -347,22 +339,16 @@ public abstract class ReadOnlyNodeTypeMa
* @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 EffectiveNodeType getEffectiveNodeType(Node node) throws RepositoryException {
- Queue<NodeType> queue = Queues.newArrayDeque();
- queue.add(node.getPrimaryNodeType());
- queue.addAll(Arrays.asList(node.getMixinNodeTypes()));
-
- return getEffectiveNodeType(queue);
+ public EffectiveNodeType getEffectiveNodeType(Node node)
+ throws RepositoryException {
+ return new EffectiveNodeType(
+ node.getPrimaryNodeType(), node.getMixinNodeTypes(), this);
}
@Override
public EffectiveNodeType getEffectiveNodeType(Tree tree) throws RepositoryException {
- Queue<NodeType> queue = Queues.newArrayDeque();
NodeType primaryType;
PropertyState jcrPrimaryType = tree.getProperty(JCR_PRIMARYTYPE);
@@ -372,18 +358,17 @@ public abstract class ReadOnlyNodeTypeMa
} else {
throw new RepositoryException("Node at "+tree.getPath()+" has no primary type.");
}
- queue.add(primaryType);
- List<NodeType> mixinTypes = Lists.newArrayList();
PropertyState jcrMixinType = tree.getProperty(JCR_MIXINTYPES);
- if (jcrMixinType != null) {
- for (String ntName : jcrMixinType.getValue(STRINGS)) {
- mixinTypes.add(internalGetNodeType(ntName));
+ if (jcrMixinType == null) {
+ return new EffectiveNodeType(primaryType, this);
+ } else {
+ NodeType[] mixinTypes = new NodeType[jcrMixinType.count()];
+ for (int i = 0; i < mixinTypes.length; i++) {
+ mixinTypes[i] = getNodeType(jcrMixinType.getValue(Type.NAME, i));
}
+ return new EffectiveNodeType(primaryType, mixinTypes, this);
}
- queue.addAll(mixinTypes);
-
- return getEffectiveNodeType(queue);
}
//-------------------------------------------------< DefinitionProvider >---
@@ -415,14 +400,6 @@ public abstract class ReadOnlyNodeTypeMa
}
@Override
- public NodeDefinition getDefinition(Iterable<NodeType> parentNodeTypes,
- String nodeName, NodeType nodeType)
- throws ConstraintViolationException {
- EffectiveNodeType eff = getEffectiveNodeType(Queues.newArrayDeque(parentNodeTypes));
- return eff.getNodeDefinition(nodeName, getEffectiveNodeType(Queues.newArrayDeque(Collections.singleton(nodeType))));
- }
-
- @Override
public PropertyDefinition getDefinition(Node parent, Property targetProperty) throws RepositoryException {
String name = targetProperty.getName();
boolean isMultiple = targetProperty.isMultiple();
@@ -460,15 +437,6 @@ public abstract class ReadOnlyNodeTypeMa
return effective.getPropertyDefinition(propertyName, isMultiple, type, exactTypeMatch);
}
- @Nonnull
- @Override
- public PropertyDefinition getDefinition(Iterable<NodeType> nodeTypes, String propertyName, boolean isMultiple,
- int type, boolean exactTypeMatch) throws RepositoryException {
- Queue<NodeType> queue = Queues.newArrayDeque(nodeTypes);
- EffectiveNodeType effective = getEffectiveNodeType(queue);
- return effective.getPropertyDefinition(propertyName, isMultiple, type, exactTypeMatch);
- }
-
//-----------------------------------------------------------< internal >---
NodeTypeImpl internalGetNodeType(String oakName) throws NoSuchNodeTypeException {
@@ -482,19 +450,4 @@ public abstract class ReadOnlyNodeTypeMa
throw new NoSuchNodeTypeException(getNamePathMapper().getJcrName(oakName));
}
- //------------------------------------------------------------< private >---
-
- private EffectiveNodeType getEffectiveNodeType(Queue<NodeType> queue) throws ConstraintViolationException {
- Map<String, NodeType> types = Maps.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 EffectiveNodeType.create(types.values(), this);
- }
-
}