Index: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/NodeTypeTemplateImpl.java =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/NodeTypeTemplateImpl.java (revision 1733007) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/write/NodeTypeTemplateImpl.java (working copy) @@ -182,7 +182,7 @@ int index = 1; if (itemDefTemplates != null) { for (ItemDefinitionTemplate template : itemDefTemplates) { - String name = (index == 1) ? nodeName : nodeName + '[' + index + ']'; + String name = nodeName(nodeName, index); tree = nodeTypeTree.getChild(name); if (!tree.exists()) { tree = nodeTypeTree.addChild(name); @@ -193,13 +193,17 @@ index++; } } - tree = nodeTypeTree.getChild(nodeName + '[' + index++ + ']'); + tree = nodeTypeTree.getChild(nodeName(nodeName, index++)); while (tree.exists()) { tree.remove(); - tree = nodeTypeTree.getChild(nodeName + '[' + index++ + ']'); + tree = nodeTypeTree.getChild(nodeName(nodeName, index++)); } } + private static String nodeName(String name, int index) { + return (index == 1) ? name : name + '[' + index + ']'; + } + //------------------------------------------------------------< public >-- @Override Index: oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeTest.java =================================================================== --- oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeTest.java (revision 1733013) +++ oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/nodetype/NodeTypeTest.java (working copy) @@ -20,6 +20,7 @@ import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.fail; +import static org.junit.Assert.assertFalse; import java.io.StringReader; import java.util.ArrayList; @@ -40,7 +41,6 @@ import org.apache.jackrabbit.commons.cnd.CndImporter; import org.apache.jackrabbit.oak.fixture.NodeStoreFixture; import org.apache.jackrabbit.oak.jcr.AbstractRepositoryTest; -import org.junit.Ignore; import org.junit.Test; public class NodeTypeTest extends AbstractRepositoryTest { @@ -244,7 +244,6 @@ session.save(); } - @Ignore("OAK-4077") @Test public void removeMandatoryProperty() throws Exception { Session session = getAdminSession(); @@ -283,4 +282,45 @@ n.getProperty("test:mandatory").remove(); session.save(); } + + @Test + public void removeMandatoryPropertyFlag() throws Exception { + Session session = getAdminSession(); + Node root = session.getRootNode(); + NodeTypeManager manager = session.getWorkspace().getNodeTypeManager(); + + String cnd = "<'test'='http://www.apache.org/jackrabbit/test'>\n" + + "[test:MyType] > nt:unstructured\n" + + " - test:mandatory (string) mandatory"; + + CndImporter.registerNodeTypes(new StringReader(cnd), session); + + Node n = root.addNode("test", "test:MyType"); + n.setProperty("test:mandatory", "value"); + session.save(); + + try { + n.getProperty("test:mandatory").remove(); + session.save(); + fail("Must fail with ConstraintViolationException"); + } catch (ConstraintViolationException e) { + // expected + session.refresh(false); + } + + // remove the mandatory property flag + cnd = "<'test'='http://www.apache.org/jackrabbit/test'>\n" + + "[test:MyType] > nt:unstructured\n" + + " - test:mandatory (string)"; + CndImporter.registerNodeTypes(new StringReader(cnd), session, true); + + // check node type + NodeTypeDefinition ntd = manager.getNodeType("test:MyType"); + assertEquals(1, ntd.getDeclaredPropertyDefinitions().length); + assertFalse(ntd.getDeclaredPropertyDefinitions()[0].isMandatory()); + + // now we should be able to remove the property + n.getProperty("test:mandatory").remove(); + session.save(); + } }