[dna-commits] DNA SVN: r1049 - in trunk/dna-jcr/src: main/resources/org/jboss/dna/jcr and 1 other directories.
dna-commits at lists.jboss.org
dna-commits at lists.jboss.org
Sat Jun 13 11:56:00 EDT 2009
Author: bcarothers
Date: 2009-06-13 11:56:00 -0400 (Sat, 13 Jun 2009)
New Revision: 1049
Modified:
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNode.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeType.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeTypeManager.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/RepositoryNodeTypeManager.java
trunk/dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/TypeRegistrationTest.java
Log:
Committed most of unregisterTypes method. Still need to add check that the type is not in use on any nodes, but this should be much easier after queries are implemented. Leaving this open until that piece of the issue is corrected.
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java 2009-06-12 01:28:17 UTC (rev 1048)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java 2009-06-13 15:56:00 UTC (rev 1049)
@@ -115,6 +115,7 @@
// Type registration messages
public static I18n invalidNodeTypeName;
+ public static I18n noSuchNodeType;
public static I18n nodeTypeAlreadyExists;
public static I18n invalidPrimaryTypeName;
public static I18n invalidSupertypeName;
@@ -139,6 +140,10 @@
public static I18n nodeNotReferenceable;
public static I18n noPendingChangesAllowed;
+ public static I18n cannotUnregisterSupertype;
+ public static I18n cannotUnregisterRequiredPrimaryType;
+ public static I18n cannotUnregisterDefaultPrimaryType;
+
static {
try {
I18n.initialize(JcrI18n.class);
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNode.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNode.java 2009-06-12 01:28:17 UTC (rev 1048)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNode.java 2009-06-13 15:56:00 UTC (rev 1049)
@@ -94,5 +94,4 @@
public void remove() throws RepositoryException {
editorForParent().destroyChild(nodeUuid);
}
-
}
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeType.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeType.java 2009-06-12 01:28:17 UTC (rev 1048)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeType.java 2009-06-13 15:56:00 UTC (rev 1049)
@@ -165,6 +165,10 @@
return thisAndAllSupertypes;
}
+ List<JcrNodeType> supertypes() {
+ return allSupertypes;
+ }
+
/**
* Get the child definitions defined on this node type (excluding inherited definitions).
*
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeTypeManager.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeTypeManager.java 2009-06-12 01:28:17 UTC (rev 1048)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNodeTypeManager.java 2009-06-13 15:56:00 UTC (rev 1049)
@@ -39,6 +39,7 @@
import net.jcip.annotations.Immutable;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.NameFactory;
import org.jboss.dna.jcr.nodetype.InvalidNodeTypeDefinitionException;
import org.jboss.dna.jcr.nodetype.NodeDefinitionTemplate;
import org.jboss.dna.jcr.nodetype.NodeTypeDefinition;
@@ -416,6 +417,32 @@
}
/**
+ * Allows the collection of node types to be unregistered if they are not referenced by other node types as supertypes,
+ * default primary types of child nodes, or required primary types of child nodes.
+ * <p>
+ * <b>NOTE: This method does not check to see if any of the node types are currently being used. Unregistering a node type
+ * that is being used will cause the system to become unstable</b>
+ * </p>
+ *
+ * @param nodeTypeNames the names of the node types to be unregistered
+ * @throws NoSuchNodeTypeException if any of the node type names do not correspond to a registered node type
+ * @throws InvalidNodeTypeDefinitionException if any of the node types with the given names cannot be unregistered because
+ * they are the supertype, one of the required primary types, or a default primary type of a node type that is not
+ * being unregistered.
+ * @throws RepositoryException if any other error occurs
+ */
+ public void unregisterNodeType( Collection<String> nodeTypeNames )
+ throws NoSuchNodeTypeException, InvalidNodeTypeDefinitionException, RepositoryException {
+ NameFactory nameFactory = this.context.getValueFactories().getNameFactory();
+
+ Collection<Name> names = new ArrayList<Name>(nodeTypeNames.size());
+ for (String name : nodeTypeNames) {
+ names.add(nameFactory.create(name));
+ }
+ repositoryTypeManager.unregisterNodeType(names);
+ }
+
+ /**
* Returns an empty {@code NodeTypeTemplate} which can then be used to define a node type and passed to
* {@link JcrNodeTypeManager#registerNodeType(NodeTypeDefinition, boolean)}
*
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/RepositoryNodeTypeManager.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/RepositoryNodeTypeManager.java 2009-06-12 01:28:17 UTC (rev 1048)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/RepositoryNodeTypeManager.java 2009-06-13 15:56:00 UTC (rev 1049)
@@ -38,6 +38,7 @@
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.PropertyDefinition;
@@ -46,6 +47,7 @@
import net.jcip.annotations.ThreadSafe;
import org.jboss.dna.common.text.TextEncoder;
import org.jboss.dna.common.text.XmlNameEncoder;
+import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.Graph;
import org.jboss.dna.graph.Location;
@@ -1100,6 +1102,89 @@
}
/**
+ * Allows the collection of node types to be unregistered if they are not referenced by other node types as supertypes,
+ * default primary types of child nodes, or required primary types of child nodes.
+ * <p>
+ * <b>NOTE: This method does not check to see if any of the node types are currently being used. Unregistering a node type
+ * that is being used will cause the system to become unstable</b>
+ * </p>
+ *
+ * @param nodeTypeNames the names of the node types to be unregistered
+ * @throws NoSuchNodeTypeException if any of the node type names do not correspond to a registered node type
+ * @throws InvalidNodeTypeDefinitionException if any of the node types with the given names cannot be unregistered because
+ * they are the supertype, one of the required primary types, or a default primary type of a node type that is not
+ * being unregistered.
+ * @throws RepositoryException if any other error occurs
+ */
+ void unregisterNodeType( Collection<Name> nodeTypeNames )
+ throws NoSuchNodeTypeException, InvalidNodeTypeDefinitionException, RepositoryException {
+ CheckArg.isNotNull(nodeTypeNames, "nodeTypeNames");
+ try {
+ /*
+ * Grab an exclusive lock on this data to keep other nodes from being added/saved while the unregistration checks are occurring
+ */
+ nodeTypeManagerLock.writeLock().lock();
+
+ for (Name nodeTypeName : nodeTypeNames) {
+ /*
+ * Check that the type names are valid
+ */
+ if (nodeTypeName == null) {
+ throw new NoSuchNodeTypeException(JcrI18n.invalidNodeTypeName.text());
+ }
+ String name = nodeTypeName.getString(context.getNamespaceRegistry());
+
+ if (!this.nodeTypes.containsKey(nodeTypeName)) {
+ throw new NoSuchNodeTypeException(JcrI18n.noSuchNodeType.text(name));
+ }
+
+ /*
+ * Check that no other node definitions have dependencies on any of the named types
+ */
+ for (JcrNodeType nodeType : nodeTypes.values()) {
+ // If this node is also being unregistered, don't run checks against it
+ if (nodeTypeNames.contains(nodeType.getInternalName())) {
+ continue;
+ }
+
+ for (JcrNodeType supertype : nodeType.supertypes()) {
+ if (nodeTypeName.equals(supertype.getInternalName())) {
+ throw new InvalidNodeTypeDefinitionException(
+ JcrI18n.cannotUnregisterSupertype.text(name,
+ supertype.getName()));
+ }
+ }
+
+ for (JcrNodeDefinition childNode : nodeType.childNodeDefinitions()) {
+ NodeType defaultPrimaryType = childNode.getDefaultPrimaryType();
+ if (defaultPrimaryType != null && name.equals(defaultPrimaryType.getName())) {
+ throw new InvalidNodeTypeDefinitionException(
+ JcrI18n.cannotUnregisterDefaultPrimaryType.text(name,
+ nodeType.getName(),
+ childNode.getName()));
+ }
+ if (childNode.getRequiredPrimaryTypeNames().contains(nodeTypeName)) {
+ throw new InvalidNodeTypeDefinitionException(
+ JcrI18n.cannotUnregisterRequiredPrimaryType.text(name,
+ nodeType.getName(),
+ childNode.getName()));
+ }
+ }
+ }
+ }
+
+ /*
+ * Do a full recursive search over the content graph to make sure that this type isn't being used
+ */
+ // TODO: replace this with a query after queries work
+ this.nodeTypes.keySet().removeAll(nodeTypeNames);
+
+ } finally {
+ nodeTypeManagerLock.writeLock().unlock();
+ }
+ }
+
+ /**
* Registers a new node type or updates an existing node type using the specified definition and returns the resulting {@code
* NodeType} object.
* <p>
@@ -1803,15 +1888,13 @@
for (JcrNodeDefinition ancestor : ancestors) {
if (ancestor.isProtected()) {
throw new InvalidNodeTypeDefinitionException(
- JcrI18n.cannotOverrideProtectedDefinition.text(ancestor.getDeclaringNodeType()
- .getName(),
+ JcrI18n.cannotOverrideProtectedDefinition.text(ancestor.getDeclaringNodeType().getName(),
"child node"));
}
if (ancestor.isMandatory() && !node.isMandatory()) {
throw new InvalidNodeTypeDefinitionException(
- JcrI18n.cannotMakeMandatoryDefinitionOptional.text(ancestor.getDeclaringNodeType()
- .getName(),
+ JcrI18n.cannotMakeMandatoryDefinitionOptional.text(ancestor.getDeclaringNodeType().getName(),
"child node"));
}
@@ -1876,16 +1959,15 @@
Value[] defaultValues = prop.getDefaultValues();
if (prop.isAutoCreated() && !prop.isProtected() && (defaultValues == null || defaultValues.length == 0)) {
- throw new InvalidNodeTypeDefinitionException(JcrI18n.autocreatedPropertyNeedsDefault.text(prop.getName(),
- prop.getDeclaringNodeType()
- .getName()));
+ throw new InvalidNodeTypeDefinitionException(
+ JcrI18n.autocreatedPropertyNeedsDefault.text(prop.getName(),
+ prop.getDeclaringNodeType().getName()));
}
if (!prop.isMultiple() && (defaultValues != null && defaultValues.length > 1)) {
throw new InvalidNodeTypeDefinitionException(
JcrI18n.singleValuedPropertyNeedsSingleValuedDefault.text(prop.getName(),
- prop.getDeclaringNodeType()
- .getName()));
+ prop.getDeclaringNodeType().getName()));
}
Name propName = context.getValueFactories().getNameFactory().create(prop.getName());
@@ -1899,15 +1981,13 @@
for (JcrPropertyDefinition ancestor : ancestors) {
if (ancestor.isProtected()) {
throw new InvalidNodeTypeDefinitionException(
- JcrI18n.cannotOverrideProtectedDefinition.text(ancestor.getDeclaringNodeType()
- .getName(),
+ JcrI18n.cannotOverrideProtectedDefinition.text(ancestor.getDeclaringNodeType().getName(),
"property"));
}
if (ancestor.isMandatory() && !prop.isMandatory()) {
throw new InvalidNodeTypeDefinitionException(
- JcrI18n.cannotMakeMandatoryDefinitionOptional.text(ancestor.getDeclaringNodeType()
- .getName(),
+ JcrI18n.cannotMakeMandatoryDefinitionOptional.text(ancestor.getDeclaringNodeType().getName(),
"property"));
}
@@ -1918,16 +1998,14 @@
&& !Arrays.equals(ancestor.getValueConstraints(), prop.getValueConstraints())) {
throw new InvalidNodeTypeDefinitionException(
JcrI18n.constraintsChangedInSubtype.text(propName,
- ancestor.getDeclaringNodeType()
- .getName()));
+ ancestor.getDeclaringNodeType().getName()));
}
if (!isAlwaysSafeConversion(prop.getRequiredType(), ancestor.getRequiredType())) {
throw new InvalidNodeTypeDefinitionException(
JcrI18n.cannotRedefineProperty.text(propName,
PropertyType.nameFromValue(prop.getRequiredType()),
- ancestor.getDeclaringNodeType()
- .getName(),
+ ancestor.getDeclaringNodeType().getName(),
PropertyType.nameFromValue(ancestor.getRequiredType())));
}
Modified: trunk/dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties
===================================================================
--- trunk/dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties 2009-06-12 01:28:17 UTC (rev 1048)
+++ trunk/dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties 2009-06-13 15:56:00 UTC (rev 1049)
@@ -100,6 +100,7 @@
invalidQueryLanguage="{0}" is not a valid query langauge. Supported languages are\: {1}
invalidNodeTypeName=Node types cannot have a null or empty name
+noSuchNodeType=Type named '{0}' does not exist
nodeTypeAlreadyExists=Node type '{0}' already exists
invalidPrimaryTypeName=Required primary type '{0}' in type '{1}' does not exist
invalidSupertypeName=Supertype '{0}' from type '{1}' does not exist
@@ -123,3 +124,7 @@
nodeNotReferenceable=Only referenceable nodes may be the value of reference properties
noPendingChangesAllowed=This operation cannot be performed when the session has pending changes
+
+cannotUnregisterSupertype=Cannot unregister type '{0}' which is supertype of type '{1}'
+cannotUnregisterRequiredPrimaryType=Cannot unregister type '{0}' which is the required primary type for child node '{2}' on type '{1}'
+cannotUnregisterDefaultPrimaryType=Cannot unregister type '{0}' which is the default primary type for child node '{2}' of type '{1}'
\ No newline at end of file
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/TypeRegistrationTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/TypeRegistrationTest.java 2009-06-12 01:28:17 UTC (rev 1048)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/TypeRegistrationTest.java 2009-06-13 15:56:00 UTC (rev 1049)
@@ -25,12 +25,15 @@
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.notNullValue;
+import static org.hamcrest.core.IsNull.nullValue;
import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.PropertyDefinition;
import org.jboss.dna.graph.ExecutionContext;
@@ -41,6 +44,7 @@
import org.jboss.dna.jcr.nodetype.NodeDefinitionTemplate;
import org.jboss.dna.jcr.nodetype.NodeTypeDefinition;
import org.jboss.dna.jcr.nodetype.NodeTypeExistsException;
+import org.jboss.dna.jcr.nodetype.NodeTypeTemplate;
import org.jboss.dna.jcr.nodetype.PropertyDefinitionTemplate;
import org.junit.Before;
import org.junit.Test;
@@ -703,6 +707,103 @@
compareTemplatesToNodeTypes(templates, repoTypeManager.registerNodeTypes(templates, false));
}
+ /*
+ * Unregistration tests
+ */
+
+ @Test (expected=IllegalArgumentException.class)
+ public void shouldNotAllowUnregisteringNullCollection() throws Exception {
+ repoTypeManager.unregisterNodeType(null);
+ }
+
+ @Test (expected=NoSuchNodeTypeException.class)
+ public void shouldNotAllowUnregisteringInvalidTypeNames() throws Exception {
+ repoTypeManager.unregisterNodeType(Arrays.asList(new Name[] { JcrNtLexicon.FILE, JcrLexicon.DATA}));
+ }
+
+ @Test (expected=InvalidNodeTypeDefinitionException.class)
+ public void shouldNotAllowUnregisteringSupertype() throws Exception {
+ repoTypeManager.unregisterNodeType(Arrays.asList(new Name[] { JcrNtLexicon.HIERARCHY_NODE, }));
+
+ }
+
+ @Test (expected=InvalidNodeTypeDefinitionException.class)
+ public void shouldNotAllowUnregisteringRequiredPrimaryType() throws Exception {
+ repoTypeManager.unregisterNodeType(Arrays.asList(new Name[] { JcrNtLexicon.FROZEN_NODE, }));
+ }
+
+ @Test (expected=InvalidNodeTypeDefinitionException.class)
+ public void shouldNotAllowUnregisteringDefaultPrimaryType() throws Exception {
+ ntTemplate.setName(TEST_TYPE_NAME);
+
+ JcrNodeDefinitionTemplate childNode = new JcrNodeDefinitionTemplate(this.context);
+ childNode.setDefaultPrimaryType(JcrNtLexicon.FILE.getString(this.registry));
+ ntTemplate.getNodeDefinitionTemplates().add(childNode);
+
+ try {
+ repoTypeManager.registerNodeType(ntTemplate, false);
+ }
+ catch (Exception ex) {
+ fail(ex.getMessage());
+ }
+
+ repoTypeManager.unregisterNodeType(Arrays.asList(new Name[] { JcrNtLexicon.FILE, }));
+ }
+
+ @Test
+ public void shouldAllowUnregisteringUnusedType() throws Exception {
+ ntTemplate.setName(TEST_TYPE_NAME);
+
+ JcrNodeDefinitionTemplate childNode = new JcrNodeDefinitionTemplate(this.context);
+ childNode.setDefaultPrimaryType(JcrNtLexicon.FILE.getString(this.registry));
+ ntTemplate.getNodeDefinitionTemplates().add(childNode);
+
+ try {
+ repoTypeManager.registerNodeType(ntTemplate, false);
+ }
+ catch (Exception ex) {
+ fail(ex.getMessage());
+ }
+
+ Name typeNameAsName = nameFactory.create(TEST_TYPE_NAME);
+ int nodeTypeCount = repoTypeManager.getAllNodeTypes().size();
+ repoTypeManager.unregisterNodeType(Arrays.asList(new Name[] { typeNameAsName }));
+ assertThat(repoTypeManager.getAllNodeTypes().size(), is(nodeTypeCount - 1));
+ assertThat(repoTypeManager.getNodeType(typeNameAsName), is(nullValue()));
+ }
+
+ @Test
+ public void shouldAllowUnregisteringUnusedTypesWithMutualDependencies() throws Exception {
+ ntTemplate.setName(TEST_TYPE_NAME);
+
+ JcrNodeDefinitionTemplate childNode = new JcrNodeDefinitionTemplate(this.context);
+ childNode.setDefaultPrimaryType(TEST_TYPE_NAME2);
+ ntTemplate.getNodeDefinitionTemplates().add(childNode);
+
+ NodeTypeTemplate ntTemplate2 = new JcrNodeTypeTemplate(this.context);
+ ntTemplate2.setName(TEST_TYPE_NAME2);
+
+ JcrNodeDefinitionTemplate childNode2 = new JcrNodeDefinitionTemplate(this.context);
+ childNode2.setDefaultPrimaryType(TEST_TYPE_NAME);
+ ntTemplate2.getNodeDefinitionTemplates().add(childNode2);
+
+ try {
+ repoTypeManager.registerNodeTypes(Arrays.asList(new NodeTypeDefinition[] { ntTemplate, ntTemplate2 }), false);
+ }
+ catch (Exception ex) {
+ fail(ex.getMessage());
+ }
+
+ Name typeNameAsName = nameFactory.create(TEST_TYPE_NAME);
+ Name type2NameAsName = nameFactory.create(TEST_TYPE_NAME2);
+ int nodeTypeCount = repoTypeManager.getAllNodeTypes().size();
+ repoTypeManager.unregisterNodeType(Arrays.asList(new Name[] { typeNameAsName, type2NameAsName }));
+ assertThat(repoTypeManager.getAllNodeTypes().size(), is(nodeTypeCount - 2));
+ assertThat(repoTypeManager.getNodeType(typeNameAsName), is(nullValue()));
+ assertThat(repoTypeManager.getNodeType(type2NameAsName), is(nullValue()));
+
+ }
+
private void compareTemplatesToNodeTypes( List<NodeTypeDefinition> templates,
List<JcrNodeType> nodeTypes ) {
assertThat(templates.size(), is(nodeTypes.size()));
@@ -826,4 +927,5 @@
// assertThat(template.getRequiredPrimaryTypeNames(), is(definition.getRequiredPrimaryTypeNames()));
}
+
}
More information about the dna-commits
mailing list