This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.jcr.repoinit-1.0.2 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-jcr-repoinit.git
commit 552a1314e7881c9aad130248a5999cd542ec183d Author: Bertrand Delacretaz <[email protected]> AuthorDate: Tue Jul 19 15:54:38 2016 +0000 SLING-5842, SLING-5843 - implement the register namespace and nodetype operations in the jcr.repoinit module git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/jcr/repoinit@1753399 13f79535-47bb-0310-9956-ffa450edef68 --- .../sling/jcr/repoinit/impl/DoNothingVisitor.java | 87 ++++++++++++++++++++++ .../repoinit/impl/JcrRepoInitOpsProcessorImpl.java | 19 ++++- .../sling/jcr/repoinit/impl/NamespacesVisitor.java | 48 ++++++++++++ .../sling/jcr/repoinit/impl/NodetypesVisitor.java | 49 ++++++++++++ ...ationVisitor.java => ServiceAndAclVisitor.java} | 29 ++------ .../sling/jcr/repoinit/ExecutionOrderTest.java | 71 ++++++++++++++++++ .../sling/jcr/repoinit/RegisterNamespacesTest.java | 70 +++++++++++++++++ .../sling/jcr/repoinit/RegisterNodetypesTest.java | 69 +++++++++++++++++ .../apache/sling/jcr/repoinit/impl/TestUtil.java | 27 ++++++- 9 files changed, 440 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/apache/sling/jcr/repoinit/impl/DoNothingVisitor.java b/src/main/java/org/apache/sling/jcr/repoinit/impl/DoNothingVisitor.java new file mode 100644 index 0000000..3c4d08c --- /dev/null +++ b/src/main/java/org/apache/sling/jcr/repoinit/impl/DoNothingVisitor.java @@ -0,0 +1,87 @@ +/* + * 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.sling.jcr.repoinit.impl; + +import javax.jcr.Session; + +import org.apache.sling.repoinit.parser.operations.CreatePath; +import org.apache.sling.repoinit.parser.operations.CreateServiceUser; +import org.apache.sling.repoinit.parser.operations.DeleteServiceUser; +import org.apache.sling.repoinit.parser.operations.OperationVisitor; +import org.apache.sling.repoinit.parser.operations.RegisterNamespace; +import org.apache.sling.repoinit.parser.operations.RegisterNodetypes; +import org.apache.sling.repoinit.parser.operations.SetAclPaths; +import org.apache.sling.repoinit.parser.operations.SetAclPrincipals; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** Base class for specialized OperationVisitors. + */ +class DoNothingVisitor implements OperationVisitor { + + protected final Logger log = LoggerFactory.getLogger(getClass()); + + protected final Session session; + + /** Create a visitor using the supplied JCR Session. + * @param s must have sufficient rights to create users + * and set ACLs. + */ + protected DoNothingVisitor(Session s) { + session = s; + } + + protected void report(Exception e, String message) { + throw new RuntimeException(message, e); + } + + protected static String excerpt(String s, int maxLength) { + if(s.length() < maxLength) { + return s; + } else { + return s.substring(0, maxLength -1) + "..."; + } + } + + @Override + public void visitCreateServiceUser(CreateServiceUser s) { + } + + @Override + public void visitDeleteServiceUser(DeleteServiceUser s) { + } + + @Override + public void visitSetAclPrincipal(SetAclPrincipals s) { + } + + @Override + public void visitSetAclPaths(SetAclPaths s) { + } + + @Override + public void visitCreatePath(CreatePath cp) { + } + + @Override + public void visitRegisterNamespace(RegisterNamespace rn) { + } + + @Override + public void visitRegisterNodetypes(RegisterNodetypes rn) { + } +} diff --git a/src/main/java/org/apache/sling/jcr/repoinit/impl/JcrRepoInitOpsProcessorImpl.java b/src/main/java/org/apache/sling/jcr/repoinit/impl/JcrRepoInitOpsProcessorImpl.java index 4b633d2..bcf96b7 100644 --- a/src/main/java/org/apache/sling/jcr/repoinit/impl/JcrRepoInitOpsProcessorImpl.java +++ b/src/main/java/org/apache/sling/jcr/repoinit/impl/JcrRepoInitOpsProcessorImpl.java @@ -24,15 +24,28 @@ import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Service; import org.apache.sling.jcr.repoinit.JcrRepoInitOpsProcessor; import org.apache.sling.repoinit.parser.operations.Operation; +import org.apache.sling.repoinit.parser.operations.OperationVisitor; /** Apply Operations produced by the repoinit parser to a JCR Repository */ @Component @Service(JcrRepoInitOpsProcessor.class) public class JcrRepoInitOpsProcessorImpl implements JcrRepoInitOpsProcessor { + + /** Apply the supplied operations: first the namespaces and nodetypes + * registrations, then the service users, paths and ACLs. + */ public void apply(Session session, List<Operation> ops) { - final JcrRepoInitOperationVisitor v = new JcrRepoInitOperationVisitor(session); - for(Operation op : ops) { - op.accept(v); + + final OperationVisitor [] visitors = { + new NamespacesVisitor(session), + new NodetypesVisitor(session), + new ServiceAndAclVisitor(session) + }; + + for(OperationVisitor v : visitors) { + for(Operation op : ops) { + op.accept(v); + } } } } diff --git a/src/main/java/org/apache/sling/jcr/repoinit/impl/NamespacesVisitor.java b/src/main/java/org/apache/sling/jcr/repoinit/impl/NamespacesVisitor.java new file mode 100644 index 0000000..b4d0ebb --- /dev/null +++ b/src/main/java/org/apache/sling/jcr/repoinit/impl/NamespacesVisitor.java @@ -0,0 +1,48 @@ +/* + * 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.sling.jcr.repoinit.impl; + +import javax.jcr.NamespaceRegistry; +import javax.jcr.Session; + +import org.apache.sling.repoinit.parser.operations.RegisterNamespace; + +/** OperationVisitor which processes only operations related to + * namespaces and nodetypes. Having several such specialized visitors + * makes it easy to control the execution order. + */ +class NamespacesVisitor extends DoNothingVisitor { + + /** Create a visitor using the supplied JCR Session. + * @param s must have sufficient rights to create users + * and set ACLs. + */ + public NamespacesVisitor(Session s) { + super(s); + } + + @Override + public void visitRegisterNamespace(RegisterNamespace rn) { + try { + final NamespaceRegistry reg = session.getWorkspace().getNamespaceRegistry(); + log.info("Registering namespace from {}", rn); + reg.registerNamespace(rn.getPrefix(), rn.getURI()); + } catch(Exception e) { + report(e, "Unable to register namespace from " + rn); + } + } +} diff --git a/src/main/java/org/apache/sling/jcr/repoinit/impl/NodetypesVisitor.java b/src/main/java/org/apache/sling/jcr/repoinit/impl/NodetypesVisitor.java new file mode 100644 index 0000000..e1a4534 --- /dev/null +++ b/src/main/java/org/apache/sling/jcr/repoinit/impl/NodetypesVisitor.java @@ -0,0 +1,49 @@ +/* + * 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.sling.jcr.repoinit.impl; + +import java.io.StringReader; + +import javax.jcr.Session; + +import org.apache.jackrabbit.commons.cnd.CndImporter; +import org.apache.sling.repoinit.parser.operations.RegisterNodetypes; + +/** OperationVisitor which processes only operations related to + * namespaces and nodetypes. Having several such specialized visitors + * makes it easy to control the execution order. + */ +class NodetypesVisitor extends DoNothingVisitor { + + /** Create a visitor using the supplied JCR Session. + * @param s must have sufficient rights to create users + * and set ACLs. + */ + public NodetypesVisitor(Session s) { + super(s); + } + + @Override + public void visitRegisterNodetypes(RegisterNodetypes rn) { + try { + log.info("Registering nodetypes from {}", excerpt(rn.getCndStatements(), 100)); + CndImporter.registerNodeTypes(new StringReader(rn.getCndStatements()), session); + } catch(Exception e) { + report(e, "Unable to register nodetypes from " + rn); + } + } +} diff --git a/src/main/java/org/apache/sling/jcr/repoinit/impl/JcrRepoInitOperationVisitor.java b/src/main/java/org/apache/sling/jcr/repoinit/impl/ServiceAndAclVisitor.java similarity index 88% rename from src/main/java/org/apache/sling/jcr/repoinit/impl/JcrRepoInitOperationVisitor.java rename to src/main/java/org/apache/sling/jcr/repoinit/impl/ServiceAndAclVisitor.java index 53a2af5..4d71c6b 100644 --- a/src/main/java/org/apache/sling/jcr/repoinit/impl/JcrRepoInitOperationVisitor.java +++ b/src/main/java/org/apache/sling/jcr/repoinit/impl/ServiceAndAclVisitor.java @@ -38,23 +38,18 @@ import org.apache.sling.repoinit.parser.operations.SetAclPrincipals; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** JCR visitor for the Operations produced by the repoinit parser */ -class JcrRepoInitOperationVisitor implements OperationVisitor { +/** OperationVisitor which processes only operations related to + * service users and ACLs. Having several such specialized visitors + * makes it easy to control the execution order. + */ +class ServiceAndAclVisitor extends DoNothingVisitor { - private final Logger log = LoggerFactory.getLogger(getClass()); - - private Session session; - /** Create a visitor using the supplied JCR Session. * @param s must have sufficient rights to create users * and set ACLs. */ - public JcrRepoInitOperationVisitor(Session s) { - session = s; - } - - private void report(Exception e, String message) { - throw new RuntimeException(message, e); + public ServiceAndAclVisitor(Session s) { + super(s); } @Override @@ -141,14 +136,4 @@ class JcrRepoInitOperationVisitor implements OperationVisitor { throw new RuntimeException("Session.save failed: "+ e, e); } } - - @Override - public void visitRegisterNamespace(RegisterNamespace rn) { - throw new UnsupportedOperationException(rn.toString()); - } - - @Override - public void visitRegisterNodetypes(RegisterNodetypes b) { - throw new UnsupportedOperationException(b.getClass().getName()); - } } diff --git a/src/test/java/org/apache/sling/jcr/repoinit/ExecutionOrderTest.java b/src/test/java/org/apache/sling/jcr/repoinit/ExecutionOrderTest.java new file mode 100644 index 0000000..0369d88 --- /dev/null +++ b/src/test/java/org/apache/sling/jcr/repoinit/ExecutionOrderTest.java @@ -0,0 +1,71 @@ +/* + * 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.sling.jcr.repoinit; + +import static org.junit.Assert.assertEquals; +import java.util.UUID; + +import javax.jcr.Node; +import javax.jcr.PathNotFoundException; +import javax.jcr.RepositoryException; + +import org.apache.sling.jcr.repoinit.impl.TestUtil; +import org.apache.sling.repoinit.parser.RepoInitParsingException; +import org.apache.sling.testing.mock.sling.ResourceResolverType; +import org.apache.sling.testing.mock.sling.junit.SlingContext; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +/** Verify that namespaces and nodetypes are executed before path creation */ +public class ExecutionOrderTest { + + @Rule + public final SlingContext context = new SlingContext(ResourceResolverType.JCR_OAK); + + private TestUtil U; + + private static final String TEST_ID = UUID.randomUUID().toString(); + private static final String NS_PREFIX = ExecutionOrderTest.class.getSimpleName(); + private static final String NS_URI = "uri:" + NS_PREFIX + ":" + TEST_ID; + private static final String REL_PATH = ExecutionOrderTest.class.getSimpleName() + "-" + TEST_ID; + + @Before + public void setup() throws RepositoryException, RepoInitParsingException { + U = new TestUtil(context); + + final String stmt = + "create path (" + NS_PREFIX + ":foo) /" + REL_PATH + "\n" + + U.getTestCndStatement(NS_PREFIX, NS_URI) + "\n" + + "register namespace (" + NS_PREFIX + ") " + NS_URI + "\n"; + ; + + U.parseAndExecute(stmt); + } + + @After + public void cleanup() throws RepositoryException, RepoInitParsingException { + U.cleanup(); + } + + @Test + public void pathCreated() throws PathNotFoundException, RepositoryException { + final Node n = U.getAdminSession().getNode("/" + REL_PATH); + assertEquals(NS_PREFIX + ":foo", n.getProperty("jcr:primaryType").getString()); + } +} \ No newline at end of file diff --git a/src/test/java/org/apache/sling/jcr/repoinit/RegisterNamespacesTest.java b/src/test/java/org/apache/sling/jcr/repoinit/RegisterNamespacesTest.java new file mode 100644 index 0000000..03d1df9 --- /dev/null +++ b/src/test/java/org/apache/sling/jcr/repoinit/RegisterNamespacesTest.java @@ -0,0 +1,70 @@ +/* + * 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.sling.jcr.repoinit; + +import static org.junit.Assert.assertEquals; + +import java.util.UUID; + +import javax.jcr.NamespaceRegistry; +import javax.jcr.RepositoryException; + +import org.apache.sling.jcr.repoinit.impl.TestUtil; +import org.apache.sling.repoinit.parser.RepoInitParsingException; +import org.apache.sling.testing.mock.sling.ResourceResolverType; +import org.apache.sling.testing.mock.sling.junit.SlingContext; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +/** Test register namespace statements */ +public class RegisterNamespacesTest { + + @Rule + public final SlingContext context = new SlingContext(ResourceResolverType.JCR_OAK); + + private TestUtil U; + private NamespaceRegistry ns; + + private static final String TEST_ID = UUID.randomUUID().toString(); + private static final String NS1 = "uri:ns:test1:" + TEST_ID; + private static final String NS2 = "http://example.com/ns/" + TEST_ID; + + @Before + public void setup() throws RepositoryException, RepoInitParsingException { + U = new TestUtil(context); + U.parseAndExecute("register namespace (one) " + NS1); + U.parseAndExecute("register namespace (two) " + NS2); + ns = U.getAdminSession().getWorkspace().getNamespaceRegistry(); + } + + @After + public void cleanup() throws RepositoryException, RepoInitParsingException { + U.cleanup(); + } + + @Test + public void NS1registered() throws Exception { + assertEquals(NS1, ns.getURI("one")); + } + + @Test + public void NS2registered() throws Exception { + assertEquals(NS2, ns.getURI("two")); + } +} diff --git a/src/test/java/org/apache/sling/jcr/repoinit/RegisterNodetypesTest.java b/src/test/java/org/apache/sling/jcr/repoinit/RegisterNodetypesTest.java new file mode 100644 index 0000000..8b652d1 --- /dev/null +++ b/src/test/java/org/apache/sling/jcr/repoinit/RegisterNodetypesTest.java @@ -0,0 +1,69 @@ +/* + * 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.sling.jcr.repoinit; + +import static org.junit.Assert.assertEquals; + +import java.util.UUID; + +import javax.jcr.NamespaceRegistry; +import javax.jcr.RepositoryException; + +import org.apache.sling.jcr.repoinit.impl.TestUtil; +import org.apache.sling.repoinit.parser.RepoInitParsingException; +import org.apache.sling.testing.mock.sling.ResourceResolverType; +import org.apache.sling.testing.mock.sling.junit.SlingContext; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +/** Test register nodetypes statements. Also registers a namespace */ +public class RegisterNodetypesTest { + + @Rule + public final SlingContext context = new SlingContext(ResourceResolverType.JCR_OAK); + + private TestUtil U; + + private static final String TEST_ID = UUID.randomUUID().toString(); + private static final String NS_PREFIX = RegisterNodetypesTest.class.getSimpleName(); + private static final String NS_URI = "uri:" + NS_PREFIX + ":" + TEST_ID; + + @Before + public void setup() throws RepositoryException, RepoInitParsingException { + U = new TestUtil(context); + U.parseAndExecute("register namespace (" + NS_PREFIX + ") " + NS_URI); + U.parseAndExecute(U.getTestCndStatement(NS_PREFIX, NS_URI)); + } + + @After + public void cleanup() throws RepositoryException, RepoInitParsingException { + U.cleanup(); + } + + @Test + public void NSregistered() throws Exception { + final NamespaceRegistry ns = U.getAdminSession().getWorkspace().getNamespaceRegistry(); + assertEquals(NS_URI, ns.getURI(NS_PREFIX)); + } + + @Test + public void fooNodetypeRegistered() throws Exception { + U.getAdminSession().getRootNode().addNode("test_" + TEST_ID, NS_PREFIX + ":foo"); + } + } \ No newline at end of file diff --git a/src/test/java/org/apache/sling/jcr/repoinit/impl/TestUtil.java b/src/test/java/org/apache/sling/jcr/repoinit/impl/TestUtil.java index 2561ad1..615e5db 100644 --- a/src/test/java/org/apache/sling/jcr/repoinit/impl/TestUtil.java +++ b/src/test/java/org/apache/sling/jcr/repoinit/impl/TestUtil.java @@ -93,10 +93,8 @@ public class TestUtil { } public void parseAndExecute(String input) throws RepositoryException, RepoInitParsingException { - final JcrRepoInitOperationVisitor v = new JcrRepoInitOperationVisitor(adminSession); - for(Operation o : parse(input)) { - o.accept(v); - } + final JcrRepoInitOpsProcessorImpl p = new JcrRepoInitOpsProcessorImpl(); + p.apply(adminSession, parse(input)); adminSession.save(); } @@ -109,4 +107,25 @@ public class TestUtil { final SimpleCredentials cred = new SimpleCredentials(serviceUsername, new char[0]); return adminSession.impersonate(cred); } + + public Session getAdminSession() { + return adminSession; + } + + public void cleanup() { + adminSession.logout(); + } + + public String getTestCndStatement(String nsPrefix, String nsURI) throws RepositoryException, RepoInitParsingException { + return "register nodetypes\n" + + "<<===\n" + + getTestCND(nsPrefix, nsURI) + + "===>>\n" + ; + } + + public String getTestCND(String nsPrefix, String nsURI) { + return "<" + nsPrefix + "='" + nsURI + "'>\n" + + "[" + nsPrefix + ":foo] > nt:unstructured\n"; + } } -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
