/* * ModeShape (http://www.modeshape.org) * * Licensed 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.modeshape.jcr; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsNull.notNullValue; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import java.io.InputStream; import java.util.Collections; import java.util.Set; import java.util.concurrent.TimeUnit; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.RepositoryException; import javax.jcr.nodetype.ConstraintViolationException; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.modeshape.common.FixFor; import org.modeshape.jcr.cache.SiblingCounter; import org.modeshape.jcr.value.Name; import org.modeshape.jcr.value.NamespaceRegistry; import org.modeshape.jcr.value.basic.BasicName; public class RepositoryNodeTypeManagerTest { private RepositoryConfiguration config; private JcrRepository repository; private ExecutionContext context; private RepositoryNodeTypeManager repoTypeManager; private JcrSession session; @Before public void beforeEach() throws Exception { config = new RepositoryConfiguration("repoName").with(new TestingEnvironment()); repository = new JcrRepository(config); repository.start(); context = repository.runningState().context(); repoTypeManager = repository.nodeTypeManager(); session = repository.login(); } @After public void afterEach() throws Exception { try { repository.shutdown().get(3L, TimeUnit.SECONDS); } finally { repository = null; config = null; } } @Test public void shouldOnlyHaveOneNamespacesNode() throws Exception { NamespaceRegistry registry = context.getNamespaceRegistry(); Node rootNode = session.getRootNode(); assertThat(rootNode, is(notNullValue())); Node systemNode = rootNode.getNode(JcrLexicon.SYSTEM.getString(registry)); assertThat(systemNode, is(notNullValue())); NodeIterator namespacesNodes = systemNode.getNodes(ModeShapeLexicon.NAMESPACES.getString(registry)); assertThat(namespacesNodes.getSize(), is(1L)); } @Test public void shouldOnlyHaveOneNodeTypesNode() throws Exception { NamespaceRegistry registry = context.getNamespaceRegistry(); Node rootNode = session.getRootNode(); assertThat(rootNode, is(notNullValue())); Node systemNode = rootNode.getNode(JcrLexicon.SYSTEM.getString(registry)); assertThat(systemNode, is(notNullValue())); NodeIterator nodeTypesNodes = systemNode.getNodes(JcrLexicon.NODE_TYPES.getString(registry)); assertThat(nodeTypesNodes.getSize(), is(1L)); } @Test public void shouldAllowMultipleSiblingsDefinitionIfOneSibling() throws Exception { NamespaceRegistry registry = context.getNamespaceRegistry(); // There's no definition for this node or for a * child node that does not allow SNS JcrNodeDefinition def = repoTypeManager.getNodeTypes() .findChildNodeDefinitions(JcrNtLexicon.NODE_TYPE, null) .findBestDefinitionForChild(JcrLexicon.PROPERTY_DEFINITION, JcrNtLexicon.PROPERTY_DEFINITION, false, SiblingCounter.oneSibling()); assertThat(def, is(notNullValue())); assertThat(def.getName(), is(JcrLexicon.PROPERTY_DEFINITION.getString(registry))); } @Test @FixFor( "MODE-1807" ) public void shouldAllowOverridingChildDefinitionWithSubtypeOfOriginalDefinition() throws Exception { InputStream cndStream = getClass().getResourceAsStream("/cnd/orc.cnd"); assertThat(cndStream, is(notNullValue())); nodeTypeManager().registerNodeTypes(cndStream, true); } @Test @FixFor( "MODE-1857" ) public void shouldAllowOverridingOfPropertyDefinitions() throws Exception { InputStream cnd = getClass().getClassLoader().getResourceAsStream("cnd/overridingPropertyDefinition.cnd"); assertThat(cnd, is(notNullValue())); session.getWorkspace().getNodeTypeManager().registerNodeTypes(cnd, true); Node car = session.getRootNode().addNode("car", "car"); car.setProperty("engine", "4CYL"); Node cycle = session.getRootNode().addNode("cycle", "motorcycle"); cycle.setProperty("engine", "2CYL"); session.save(); try { car.setProperty("engine", "2CYL"); fail("Should not have allowed setting the 'engine' property on a node of type 'car' to \"2CYL\""); } catch (ConstraintViolationException e) { // expected ... } try { cycle.setProperty("engine", "4CYL"); fail("Should not have allowed setting the 'engine' property on a node of type 'car' to \"2CYL\""); } catch (ConstraintViolationException e) { // expected ... } } @Test @FixFor( "MODE-1857" ) public void shouldAllowOverridingOfPropertyDefinitionsWithResidualDefinitions() throws Exception { InputStream cnd = getClass().getClassLoader().getResourceAsStream("cnd/overridingPropertyDefinitionWithResidual.cnd"); assertThat(cnd, is(notNullValue())); session.getWorkspace().getNodeTypeManager().registerNodeTypes(cnd, true); Node car = session.getRootNode().addNode("car", "car"); car.setProperty("engine", "4CYL"); Node cycle = session.getRootNode().addNode("cycle", "motorcycle"); cycle.setProperty("engine", "2CYL"); session.save(); try { car.setProperty("engine", "2CYL"); fail("Should not have allowed setting the 'engine' property on a node of type 'car' to \"2CYL\""); } catch (ConstraintViolationException e) { // expected ... } try { cycle.setProperty("engine", "4CYL"); fail("Should not have allowed setting the 'engine' property on a node of type 'car' to \"2CYL\""); } catch (ConstraintViolationException e) { // expected ... } } @Test @FixFor( "MODE-1916" ) public void shouldFindPublicChildNodeDefinitionsWhenBothPublicAndProtectedAreDefined() throws Exception { InputStream cndStream = getClass().getResourceAsStream("/cnd/protectedDefinitions.cnd"); assertThat(cndStream, is(notNullValue())); nodeTypeManager().registerNodeTypes(cndStream, true); Name parking = new BasicName(null, "parking"); Name level = new BasicName(null, "level"); Set<Name> garage = Collections.<Name>singleton(new BasicName(null, "garage")); JcrNodeDefinition def = repoTypeManager.getNodeTypes().findChildNodeDefinitions(parking, garage) .findBestDefinitionForChild(level, level, true, SiblingCounter.noSiblings()); assertNotNull(def); Name car = new BasicName(null, "car"); def = repoTypeManager.getNodeTypes().findChildNodeDefinitions(parking, garage) .findBestDefinitionForChild(car, car, true, SiblingCounter.noSiblings()); assertNotNull(def); } private JcrNodeTypeManager nodeTypeManager() throws RepositoryException { return session.getWorkspace().getNodeTypeManager(); } }