You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by tr...@apache.org on 2018/06/21 03:52:06 UTC
svn commit: r1833974 - in /jackrabbit/commons/filevault/trunk/vault-core/src:
main/java/org/apache/jackrabbit/vault/fs/impl/io/
main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/
test/java/org/apache/jackrabbit/vault/packaging/integration/
Author: tripod
Date: Thu Jun 21 03:52:06 2018
New Revision: 1833974
URL: http://svn.apache.org/viewvc?rev=1833974&view=rev
Log:
JCRVLT-303 Register namespace under a unique prefix in case of clash
Added:
jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JcrNamespaceHelper.java
jackrabbit/commons/filevault/trunk/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/TestNamespaceImport.java
Modified:
jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXImporter.java
jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JackrabbitPrivilegeInstaller.java
jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JcrNodeTypeInstaller.java
Modified: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXImporter.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXImporter.java?rev=1833974&r1=1833973&r2=1833974&view=diff
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXImporter.java (original)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewSAXImporter.java Thu Jun 21 03:52:06 2018
@@ -62,6 +62,7 @@ import org.apache.jackrabbit.vault.fs.io
import org.apache.jackrabbit.vault.fs.spi.ACLManagement;
import org.apache.jackrabbit.vault.fs.spi.ServiceProviderFactory;
import org.apache.jackrabbit.vault.fs.spi.UserManagement;
+import org.apache.jackrabbit.vault.fs.spi.impl.jcr20.JcrNamespaceHelper;
import org.apache.jackrabbit.vault.util.DocViewNode;
import org.apache.jackrabbit.vault.util.DocViewProperty;
import org.apache.jackrabbit.vault.util.JcrConstants;
@@ -225,6 +226,11 @@ public class DocViewSAXImporter extends
private final boolean snsSupported;
/**
+ * helper for namespace registration
+ */
+ private final JcrNamespaceHelper nsHelper;
+
+ /**
* Creates a new importer that will receive SAX events and imports the
* items below the given root.
*
@@ -247,6 +253,7 @@ public class DocViewSAXImporter extends
this.userManagement = ServiceProviderFactory.getProvider().getUserManagement();
this.snsSupported = session.getRepository().
getDescriptorValue(Repository.NODE_TYPE_MANAGEMENT_SAME_NAME_SIBLINGS_SUPPORTED).getBoolean();
+ this.nsHelper = new JcrNamespaceHelper(session, null);
String rootPath = parentNode.getPath();
if (!rootPath.equals("/")) {
@@ -506,11 +513,10 @@ public class DocViewSAXImporter extends
} catch (NamespaceException e) {
// assume uri never registered
try {
- session.getWorkspace().getNamespaceRegistry().registerNamespace(prefix, uri);
+ oldPrefix = nsHelper.registerNamespace(prefix, uri);
} catch (RepositoryException e1) {
throw new SAXException(e);
}
- oldPrefix = prefix;
} catch (RepositoryException e) {
throw new SAXException(e);
}
Modified: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JackrabbitPrivilegeInstaller.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JackrabbitPrivilegeInstaller.java?rev=1833974&r1=1833973&r2=1833974&view=diff
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JackrabbitPrivilegeInstaller.java (original)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JackrabbitPrivilegeInstaller.java Thu Jun 21 03:52:06 2018
@@ -21,7 +21,6 @@ import java.io.IOException;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@@ -73,21 +72,10 @@ public class JackrabbitPrivilegeInstalle
mode = tracker.setMode(ProgressTrackerListener.Mode.TEXT);
}
+ JcrNamespaceHelper nsHelper = new JcrNamespaceHelper(session, tracker);
+
// register namespaces
- Map<String, String> pfxToURI = defs.getNamespaceMapping().getPrefixToURIMapping();
- if (!pfxToURI.isEmpty()) {
- for (Object o : pfxToURI.keySet()) {
- String prefix = (String) o;
- String uri = pfxToURI.get(prefix);
- try {
- session.getNamespacePrefix(uri);
- track(tracker, "-", prefix + " -> " + uri);
- } catch (RepositoryException e) {
- session.getWorkspace().getNamespaceRegistry().registerNamespace(prefix, uri);
- track(tracker, "A", prefix + " -> " + uri);
- }
- }
- }
+ nsHelper.registerNamespaces(defs.getNamespaceMapping().getPrefixToURIMapping());
// register node types
List<Privilege> registeredPrivs = new LinkedList<Privilege>();
Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JcrNamespaceHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JcrNamespaceHelper.java?rev=1833974&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JcrNamespaceHelper.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JcrNamespaceHelper.java Thu Jun 21 03:52:06 2018
@@ -0,0 +1,99 @@
+/*
+ * 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.jackrabbit.vault.fs.spi.impl.jcr20;
+
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.jcr.NamespaceException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.jackrabbit.vault.fs.spi.ProgressTracker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class JcrNamespaceHelper {
+
+ /**
+ * default logger
+ */
+ private static final Logger log = LoggerFactory.getLogger(JcrNamespaceHelper.class);
+
+ private final Session session;
+
+ private final ProgressTracker tracker;
+
+ public JcrNamespaceHelper(@Nonnull Session session, @Nullable ProgressTracker tracker) {
+ this.session = session;
+ this.tracker = tracker;
+ }
+
+ /**
+ * Registers a map of namespaces
+ * @param pfxToURI map from prefix to uri mappings
+ * @throws RepositoryException if an error occurs
+ */
+ public void registerNamespaces(@Nonnull Map<String, String> pfxToURI) throws RepositoryException {
+ if (!pfxToURI.isEmpty()) {
+ for (Object o : pfxToURI.keySet()) {
+ String prefix = (String) o;
+ String uri = pfxToURI.get(prefix);
+ try {
+ session.getNamespacePrefix(uri);
+ track(tracker, "-", prefix + " -> " + uri);
+ } catch (RepositoryException e) {
+ registerNamespace(prefix, uri);
+ }
+ }
+ }
+ }
+
+ /**
+ * Attempts to register a namespace
+ * @param pfxHint prefix to use if possible
+ * @param uri uri to register
+ * @return the registered prefix
+ * @throws RepositoryException if an error occurs
+ */
+ @Nonnull
+ public String registerNamespace(@Nonnull String pfxHint, @Nonnull String uri) throws RepositoryException {
+ int i = 0;
+ String pfx = pfxHint;
+ Throwable error = null;
+ while (i < 1000) {
+ try {
+ session.getWorkspace().getNamespaceRegistry().registerNamespace(pfx, uri);
+ track(tracker, "A", pfx + " -> " + uri);
+ return pfx;
+ } catch (NamespaceException e) {
+ pfx = pfxHint + i++;
+ error = e;
+ }
+ }
+ throw new RepositoryException("Giving up automatic namespace registration after 1000 attempts.", error);
+ }
+
+ private void track(ProgressTracker tracker, String action, String path) {
+ log.debug("{} {}", action, path);
+ if (tracker != null) {
+ tracker.track(action, path);
+ }
+ }
+}
Modified: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JcrNodeTypeInstaller.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JcrNodeTypeInstaller.java?rev=1833974&r1=1833973&r2=1833974&view=diff
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JcrNodeTypeInstaller.java (original)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JcrNodeTypeInstaller.java Thu Jun 21 03:52:06 2018
@@ -21,7 +21,6 @@ import java.io.IOException;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
@@ -67,6 +66,8 @@ public class JcrNodeTypeInstaller implem
// register node types
NodeTypeManager ntMgr = session.getWorkspace().getNodeTypeManager();
+ JcrNamespaceHelper nsHelper = new JcrNamespaceHelper(session, tracker);
+
// filter out registered
DefaultNodeTypeSet set;
if (types instanceof DefaultNodeTypeSet) {
@@ -88,20 +89,7 @@ public class JcrNodeTypeInstaller implem
}
// register namespaces
- Map<String, String> pfxToURI = set.getNamespaceMapping().getPrefixToURIMapping();
- if (!pfxToURI.isEmpty()) {
- for (Object o : pfxToURI.keySet()) {
- String prefix = (String) o;
- String uri = (String) pfxToURI.get(prefix);
- try {
- session.getNamespacePrefix(uri);
- track(tracker, "-", prefix + " -> " + uri);
- } catch (RepositoryException e) {
- session.getWorkspace().getNamespaceRegistry().registerNamespace(prefix, uri);
- track(tracker, "A", prefix + " -> " + uri);
- }
- }
- }
+ nsHelper.registerNamespaces(set.getNamespaceMapping().getPrefixToURIMapping());
// register node types
NodeTypeDefinitionFactory fac = new NodeTypeDefinitionFactory(session);
Added: jackrabbit/commons/filevault/trunk/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/TestNamespaceImport.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/TestNamespaceImport.java?rev=1833974&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/TestNamespaceImport.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/TestNamespaceImport.java Thu Jun 21 03:52:06 2018
@@ -0,0 +1,170 @@
+/*
+ * 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.jackrabbit.vault.packaging.integration;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+
+import org.apache.jackrabbit.oak.jcr.Jcr;
+import org.apache.jackrabbit.vault.fs.api.PathFilterSet;
+import org.apache.jackrabbit.vault.fs.config.DefaultMetaInf;
+import org.apache.jackrabbit.vault.fs.config.DefaultWorkspaceFilter;
+import org.apache.jackrabbit.vault.fs.io.Archive;
+import org.apache.jackrabbit.vault.fs.io.ImportOptions;
+import org.apache.jackrabbit.vault.packaging.ExportOptions;
+import org.apache.jackrabbit.vault.packaging.PackageException;
+import org.apache.jackrabbit.vault.packaging.VaultPackage;
+import org.apache.jackrabbit.vault.packaging.impl.JcrPackageManagerImpl;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+public class TestNamespaceImport {
+
+ private final static String PREFIX = "prefix";
+
+ private final static String URI1 = "http://one.namespace.io";
+
+ private final static String URI2 = "http://two.namespace.io";
+
+ private Instance i1;
+
+ private Instance i2;
+
+ @Before
+ public void setup() throws RepositoryException {
+ i1 = new Instance();
+ i2 = new Instance();
+
+ // Register namespaces with same prefix but different URIs
+ // on different instances, i1, i2
+ i1.registerNamespace(PREFIX, URI1);
+ i2.registerNamespace(PREFIX, URI2);
+ }
+
+ @Test
+ public void importClashingNamespace() throws RepositoryException, IOException, PackageException {
+
+ // Set a property with the namespace prefix on instance i1
+ i1.getRootNode().addNode("tmp").setProperty("{" + URI1 + "}prop1", "value1");
+ i1.admin.save();
+
+ // Export the property from instance i1 in a content package archive
+
+ ExportOptions opts = new ExportOptions();
+ DefaultMetaInf inf = new DefaultMetaInf();
+ DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+ filter.add(new PathFilterSet("/tmp"));
+ inf.setFilter(filter);
+ Properties props = new Properties();
+ props.setProperty(VaultPackage.NAME_GROUP, "jackrabbit/test");
+ props.setProperty(VaultPackage.NAME_NAME, "test-package");
+ inf.setProperties(props);
+ opts.setMetaInf(inf);
+
+ File tmpFile = File.createTempFile("vaulttest", "zip");
+ VaultPackage pkg = i1.packMgr.assemble(i1.admin, opts, tmpFile);
+ Archive archive = pkg.getArchive();
+
+ // Import the archive in the instance i2, with strict mode enabled
+
+ ImportOptions io = new ImportOptions();
+ io.setStrict(true);
+ i2.packMgr.extract(archive, io, true);
+
+ assertEquals(i2.getRootNode().getNode("tmp").getProperty("{" + URI1 + "}prop1").getString(), "value1");
+
+ }
+
+ @Test
+ public void importClashingNamespaceOnPath() throws RepositoryException, IOException, PackageException {
+
+ // Set a property with the namespace prefix on instance i1
+ i1.getRootNode().addNode("tmp").addNode("{" + URI1 + "}node1").setProperty("test", "value1");
+ i1.admin.save();
+
+ // Export the property from instance i1 in a content package archive
+
+ ExportOptions opts = new ExportOptions();
+ DefaultMetaInf inf = new DefaultMetaInf();
+ DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+ filter.add(new PathFilterSet("/tmp"));
+ inf.setFilter(filter);
+ Properties props = new Properties();
+ props.setProperty(VaultPackage.NAME_GROUP, "jackrabbit/test");
+ props.setProperty(VaultPackage.NAME_NAME, "test-package");
+ inf.setProperties(props);
+ opts.setMetaInf(inf);
+
+ File tmpFile = File.createTempFile("vaulttest", "zip");
+ VaultPackage pkg = i1.packMgr.assemble(i1.admin, opts, tmpFile);
+ Archive archive = pkg.getArchive();
+
+ // Import the archive in the instance i2, with strict mode enabled
+
+ ImportOptions io = new ImportOptions();
+ io.setStrict(true);
+ i2.packMgr.extract(archive, io, true);
+
+ assertEquals(i2.getRootNode().getProperty("tmp/{" + URI1 + "}node1/test").getString(), "value1");
+
+ i2.relogin();
+ assertNotEquals(PREFIX, i2.admin.getNamespacePrefix(URI1));
+ }
+
+ private static final class Instance {
+
+ final Repository repository;
+
+ Session admin;
+
+ final JcrPackageManagerImpl packMgr;
+
+ private Instance()
+ throws RepositoryException {
+ repository = new Jcr().createRepository();
+ admin = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
+ packMgr = new JcrPackageManagerImpl(admin, new String[0]);
+ }
+
+ Node getRootNode()
+ throws RepositoryException {
+ return admin.getRootNode();
+ }
+
+ void registerNamespace(String prefix, String uri)
+ throws RepositoryException {
+ admin.getWorkspace().getNamespaceRegistry().registerNamespace(prefix, uri);
+ }
+
+ void relogin() throws RepositoryException {
+ admin.logout();
+ admin = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
+
+ }
+ }
+
+}