You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by mr...@apache.org on 2013/04/02 14:32:16 UTC

svn commit: r1463500 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/ oak-core/src/test/java/org/apache/jackrabbit/oak/ oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/ oak-jcr/src/main/java/org/apache/ja...

Author: mreutegg
Date: Tue Apr  2 12:32:16 2013
New Revision: 1463500

URL: http://svn.apache.org/r1463500
Log:
OAK-715: Don't share name space map between SessionImpl and LocalNameMapper

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/LocalNameMapper.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/TestNameMapper.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionContext.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionNamespaces.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/xml/TargetImportHandler.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/LocalNameMapper.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/LocalNameMapper.java?rev=1463500&r1=1463499&r2=1463500&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/LocalNameMapper.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/LocalNameMapper.java Tue Apr  2 12:32:16 2013
@@ -28,12 +28,6 @@ import javax.annotation.CheckForNull;
  */
 public abstract class LocalNameMapper extends GlobalNameMapper {
 
-    private final Map<String, String> local;
-
-    protected LocalNameMapper(Map<String, String> local) {
-        this.local = local;
-    }
-
     @Override @CheckForNull
     public String getJcrName(String oakName) {
         checkNotNull(oakName);
@@ -50,27 +44,26 @@ public abstract class LocalNameMapper ex
                             "No namespace mapping found for " + oakName);
                 }
 
-                synchronized (local) {
-                    for (Map.Entry<String, String> entry : local.entrySet()) {
-                        if (uri.equals(entry.getValue())) {
-                            String jcrPrefix = entry.getKey();
-                            if (jcrPrefix.equals(oakPrefix)) {
-                                return oakName;
-                            } else {
-                                return jcrPrefix + oakName.substring(colon);
-                            }
+                Map<String, String> local = getSessionLocalMappings();
+                for (Map.Entry<String, String> entry : local.entrySet()) {
+                    if (uri.equals(entry.getValue())) {
+                        String jcrPrefix = entry.getKey();
+                        if (jcrPrefix.equals(oakPrefix)) {
+                            return oakName;
+                        } else {
+                            return jcrPrefix + oakName.substring(colon);
                         }
                     }
+                }
 
-                    // local mapping not found for this URI, make sure there
-                    // is no conflicting local mapping for the prefix
-                    if (local.containsKey(oakPrefix)) {
-                        for (int i = 2; true; i++) {
-                            String jcrPrefix = oakPrefix + i;
-                            if (!local.containsKey(jcrPrefix)) {
-                                local.put(jcrPrefix, uri);
-                                return jcrPrefix + oakName.substring(colon);
-                            }
+                // local mapping not found for this URI, make sure there
+                // is no conflicting local mapping for the prefix
+                if (local.containsKey(oakPrefix)) {
+                    for (int i = 2; true; i++) {
+                        String jcrPrefix = oakPrefix + i;
+                        if (!local.containsKey(jcrPrefix)) {
+                            local.put(jcrPrefix, uri);
+                            return jcrPrefix + oakName.substring(colon);
                         }
                     }
                 }
@@ -91,26 +84,25 @@ public abstract class LocalNameMapper ex
         if (hasSessionLocalMappings()) {
             int colon = jcrName.indexOf(':');
             if (colon > 0) {
-                synchronized (local) {
-                    String jcrPrefix = jcrName.substring(0, colon);
-                    String uri = local.get(jcrPrefix);
-                    if (uri != null) {
-                        String oakPrefix = getOakPrefixOrNull(uri);
-                        if (jcrPrefix.equals(oakPrefix)) {
-                            return jcrName;
-                        } else if (oakPrefix != null) {
-                            return oakPrefix + jcrName.substring(colon);
-                        } else {
-                            return null;
-                        }
-                    }
-
-                    // Check that a global mapping is present and not remapped
-                    uri = getNamespaceMap().get(jcrPrefix);
-                    if (uri == null || local.values().contains(uri)) {
+                Map<String, String> local = getSessionLocalMappings();
+                String jcrPrefix = jcrName.substring(0, colon);
+                String uri = local.get(jcrPrefix);
+                if (uri != null) {
+                    String oakPrefix = getOakPrefixOrNull(uri);
+                    if (jcrPrefix.equals(oakPrefix)) {
+                        return jcrName;
+                    } else if (oakPrefix != null) {
+                        return oakPrefix + jcrName.substring(colon);
+                    } else {
                         return null;
                     }
                 }
+
+                // Check that a global mapping is present and not remapped
+                uri = getNamespaceMap().get(jcrPrefix);
+                if (uri == null || local.values().contains(uri)) {
+                    return null;
+                }
             }
         }
 
@@ -119,9 +111,8 @@ public abstract class LocalNameMapper ex
 
     @Override
     public boolean hasSessionLocalMappings() {
-        synchronized (local) {
-            return !local.isEmpty();
-        }
+        return !getSessionLocalMappings().isEmpty();
     }
 
+    protected abstract Map<String, String> getSessionLocalMappings();
 }

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/TestNameMapper.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/TestNameMapper.java?rev=1463500&r1=1463499&r2=1463500&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/TestNameMapper.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/TestNameMapper.java Tue Apr  2 12:32:16 2013
@@ -35,29 +35,35 @@ public final class TestNameMapper extend
     public static final Map<String, String> LOCAL_MAPPING = Collections.singletonMap(TEST_LOCAL_PREFIX, TEST_URI);
 
     private final Map<String, String> global;
+    private final Map<String, String> local;
 
     public TestNameMapper() {
-        super(LOCAL_MAPPING);
         this.global = Collections.singletonMap(TEST_PREFIX, TEST_URI);
+        this.local = LOCAL_MAPPING;
     }
 
     public TestNameMapper(Map<String, String> global, Map<String, String> local) {
-        super(local);
         this.global = global;
+        this.local = local;
     }
 
     public TestNameMapper(Map<String, String> global) {
-        super(global);
         this.global = global;
+        this.local = global;
     }
 
     public TestNameMapper(TestNameMapper base, Map<String, String> local) {
-        super(local);
         this.global = base.global;
+        this.local = local;
     }
 
     @Override
     protected Map<String, String> getNamespaceMap() {
         return global;
     }
+
+    @Override
+    protected Map<String, String> getSessionLocalMappings() {
+        return local;
+    }
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java?rev=1463500&r1=1463499&r2=1463500&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/namepath/NamePathMapperImplTest.java Tue Apr  2 12:32:16 2013
@@ -47,11 +47,16 @@ public class NamePathMapperImplTest {
             "foo", "http://www.example.com/foo",
             "quu", "http://www.example.com/quu");
 
-    private NameMapper mapper = new LocalNameMapper(LOCAL) {
+    private NameMapper mapper = new LocalNameMapper() {
         @Override
         protected Map<String, String> getNamespaceMap() {
             return GLOBAL;
         }
+
+        @Override
+        protected Map<String, String> getSessionLocalMappings() {
+            return LOCAL;
+        }
     };
 
     private NamePathMapper npMapper = new NamePathMapperImpl(mapper);

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionContext.java?rev=1463500&r1=1463499&r2=1463500&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionContext.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionContext.java Tue Apr  2 12:32:16 2013
@@ -36,11 +36,9 @@ import javax.jcr.observation.Observation
 import javax.jcr.security.AccessControlManager;
 import javax.jcr.version.VersionManager;
 
-import com.google.common.collect.Maps;
 import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
 import org.apache.jackrabbit.api.security.principal.PrincipalManager;
 import org.apache.jackrabbit.api.security.user.UserManager;
-import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate;
 import org.apache.jackrabbit.oak.namepath.LocalNameMapper;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
@@ -64,6 +62,7 @@ import org.apache.jackrabbit.oak.spi.xml
 public abstract class SessionContext implements NamePathMapper {
     private final RepositoryImpl repository;
     private final SessionDelegate delegate;
+    private final SessionNamespaces namespaces;
     private final NamePathMapper namePathMapper;
     private final ValueFactory valueFactory;
 
@@ -74,31 +73,31 @@ public abstract class SessionContext imp
     private PrivilegeManager privilegeManager;
     private ObservationManagerImpl observationManager;
 
-    private SessionContext(RepositoryImpl repository, SessionDelegate delegate,
-            NamePathMapper namePathMapper, ValueFactory valueFactory) {
+    private SessionContext(RepositoryImpl repository,
+                           final SessionDelegate delegate) {
         this.delegate = delegate;
         this.repository = repository;
-        this.namePathMapper = namePathMapper;
-        this.valueFactory = valueFactory;
-    }
-
-    public static SessionContext create(final SessionDelegate delegate, RepositoryImpl repository) {
-        // FIXME don't rely on a naked map. See OAK-715
-        final Map<String, String> namespaces = Maps.newHashMap();
-        final Root root = checkNotNull(delegate).getRoot();
-
-        LocalNameMapper nameMapper = new LocalNameMapper(namespaces) {
+        this.namespaces = new SessionNamespaces(this);
+        LocalNameMapper nameMapper = new LocalNameMapper() {
             @Override
             protected Map<String, String> getNamespaceMap() {
-                return Namespaces.getNamespaceMap(root.getTree("/"));
+                return Namespaces.getNamespaceMap(delegate.getRoot().getTree("/"));
             }
-        };
 
-        NamePathMapperImpl namePathMapper = new NamePathMapperImpl(nameMapper, delegate.getIdManager());
-        ValueFactoryImpl valueFactory = new ValueFactoryImpl(root.getBlobFactory(), namePathMapper);
+            @Override
+            protected Map<String, String> getSessionLocalMappings() {
+                return namespaces.getSessionLocalMappings();
+            }
+        };
+        this.namePathMapper = new NamePathMapperImpl(
+                nameMapper, delegate.getIdManager());
+        this.valueFactory = new ValueFactoryImpl(
+                delegate.getRoot().getBlobFactory(), namePathMapper);
+    }
 
-        return new SessionContext(checkNotNull(repository), delegate, namePathMapper, valueFactory){
-            private final SessionImpl session = new SessionImpl(this, namespaces);
+    public static SessionContext create(final SessionDelegate delegate, RepositoryImpl repository) {
+        return new SessionContext(checkNotNull(repository), checkNotNull(delegate)) {
+            private final SessionImpl session = new SessionImpl(this);
             private final WorkspaceImpl workspace = new WorkspaceImpl(this);
 
             @Override
@@ -146,6 +145,10 @@ public abstract class SessionContext imp
         return delegate;
     }
 
+    SessionNamespaces getNamespaces() {
+        return namespaces;
+    }
+
     public abstract Session getSession();
 
     public abstract Workspace getWorkspace();
@@ -250,7 +253,7 @@ public abstract class SessionContext imp
 
     @Override
     public boolean hasSessionLocalMappings() {
-        return namePathMapper.hasSessionLocalMappings();
+        return !namespaces.getSessionLocalMappings().isEmpty();
     }
 
     @Override
@@ -318,6 +321,7 @@ public abstract class SessionContext imp
         if (observationManager != null) {
             observationManager.dispose();
         }
+        namespaces.clear();
     }
 
     void refresh() {

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java?rev=1463500&r1=1463499&r2=1463500&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java Tue Apr  2 12:32:16 2013
@@ -19,7 +19,6 @@ package org.apache.jackrabbit.oak.jcr;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.Map;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
@@ -73,12 +72,9 @@ public class SessionImpl implements Jack
     private final SessionContext sessionContext;
     private final SessionDelegate sd;
 
-    private final SessionNamespaces namespaces;
-
-    SessionImpl(SessionContext sessionContext, Map<String, String> namespaces) {
+    SessionImpl(SessionContext sessionContext) {
         this.sessionContext = sessionContext;
         this.sd = sessionContext.getSessionDelegate();
-        this.namespaces = new SessionNamespaces(namespaces, sessionContext);
     }
 
     static void checkProtectedNodes(Session session, String... absJcrPaths) throws RepositoryException {
@@ -398,7 +394,6 @@ public class SessionImpl implements Jack
         if (sd.isAlive()) {
             sessionContext.dispose();
             sd.logout();
-            namespaces.clear();
         }
     }
 
@@ -586,22 +581,22 @@ public class SessionImpl implements Jack
 
     @Override
     public void setNamespacePrefix(String prefix, String uri) throws RepositoryException {
-        namespaces.setNamespacePrefix(prefix, uri);
+        sessionContext.getNamespaces().setNamespacePrefix(prefix, uri);
     }
 
     @Override
     public String[] getNamespacePrefixes() throws RepositoryException {
-        return namespaces.getNamespacePrefixes();
+        return sessionContext.getNamespaces().getNamespacePrefixes();
     }
 
     @Override
     public String getNamespaceURI(String prefix) throws RepositoryException {
-        return namespaces.getNamespaceURI(prefix);
+        return sessionContext.getNamespaces().getNamespaceURI(prefix);
     }
 
     @Override
     public String getNamespacePrefix(String uri) throws RepositoryException {
-        return namespaces.getNamespacePrefix(uri);
+        return sessionContext.getNamespaces().getNamespacePrefix(uri);
     }
 
     //--------------------------------------------------< JackrabbitSession >---

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionNamespaces.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionNamespaces.java?rev=1463500&r1=1463499&r2=1463500&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionNamespaces.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionNamespaces.java Tue Apr  2 12:32:16 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.oak.jcr;
 
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Locale;
@@ -30,6 +31,8 @@ import javax.jcr.Session;
 
 import org.apache.jackrabbit.util.XMLChar;
 
+import com.google.common.collect.Maps;
+
 import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
@@ -56,9 +59,8 @@ class SessionNamespaces {
 
     private final SessionContext sessionContext;
 
-    SessionNamespaces(@Nonnull Map<String, String> namespaces,
-                      @Nonnull SessionContext sessionContext) {
-        this.namespaces = checkNotNull(namespaces);
+    SessionNamespaces(@Nonnull SessionContext sessionContext) {
+        this.namespaces = Maps.newHashMap();
         this.sessionContext = checkNotNull(sessionContext);
     }
 
@@ -192,10 +194,25 @@ class SessionNamespaces {
     }
 
     /**
+     * @return the session local namespaces that were remapped.
+     */
+    public Map<String, String> getSessionLocalMappings() {
+        synchronized (namespaces) {
+            if (namespaces.isEmpty()) {
+                return Collections.emptyMap();
+            } else {
+                return new HashMap<String, String>(namespaces);
+            }
+        }
+    }
+
+    /**
      * Clears the re-mapped namespaces map.
      */
     void clear() {
-        namespaces.clear();
+        synchronized (namespaces) {
+            namespaces.clear();
+        }
     }
 
     private NamespaceRegistry getNamespaceRegistry()

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/xml/TargetImportHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/xml/TargetImportHandler.java?rev=1463500&r1=1463499&r2=1463500&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/xml/TargetImportHandler.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/xml/TargetImportHandler.java Tue Apr  2 12:32:16 2013
@@ -106,7 +106,7 @@ public abstract class TargetImportHandle
     //--------------------------------------------------------
 
     public NamePathMapper currentNamePathMapper() {
-        return new NamePathMapperImpl(new LocalNameMapper(documentPrefixMap) {
+        return new NamePathMapperImpl(new LocalNameMapper() {
             @Override
             protected Map<String, String> getNamespaceMap() {
                 try {
@@ -115,6 +115,11 @@ public abstract class TargetImportHandle
                     return Collections.emptyMap();
                 }
             }
+
+            @Override
+            protected Map<String, String> getSessionLocalMappings() {
+                return documentPrefixMap;
+            }
         });
     }