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 al...@apache.org on 2015/08/24 16:58:38 UTC

svn commit: r1697423 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/

Author: alexparvulescu
Date: Mon Aug 24 14:58:37 2015
New Revision: 1697423

URL: http://svn.apache.org/r1697423
Log:
OAK-2875 Namespaces keep references to old node states


Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/GlobalNameMapper.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/LocalNameMapper.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/package-info.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/SessionContext.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/SessionNamespaces.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/GlobalNameMapper.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/GlobalNameMapper.java?rev=1697423&r1=1697422&r2=1697423&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/GlobalNameMapper.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/GlobalNameMapper.java Mon Aug 24 14:58:37 2015
@@ -18,7 +18,8 @@ package org.apache.jackrabbit.oak.namepa
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
-import static org.apache.jackrabbit.oak.api.Type.STRING;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.emptyMap;
 import static org.apache.jackrabbit.oak.api.Type.STRINGS;
 import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
 import static org.apache.jackrabbit.oak.plugins.name.NamespaceConstants.NAMESPACES_PATH;
@@ -26,8 +27,11 @@ import static org.apache.jackrabbit.oak.
 import static org.apache.jackrabbit.oak.plugins.name.NamespaceConstants.REP_PREFIXES;
 import static org.apache.jackrabbit.oak.plugins.name.NamespaceConstants.REP_URIS;
 import static org.apache.jackrabbit.oak.plugins.name.Namespaces.encodeUri;
+import static org.apache.jackrabbit.oak.plugins.tree.RootFactory.createReadOnlyRoot;
+import static org.apache.jackrabbit.oak.plugins.tree.TreeFactory.createReadOnlyTree;
+import static org.apache.jackrabbit.oak.util.TreeUtil.getString;
+import static org.apache.jackrabbit.oak.util.TreeUtil.getStrings;
 
-import java.util.Collections;
 import java.util.Map;
 import java.util.Map.Entry;
 
@@ -35,11 +39,8 @@ import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 import javax.jcr.RepositoryException;
 
-import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.Tree;
-import org.apache.jackrabbit.oak.plugins.tree.RootFactory;
-import org.apache.jackrabbit.oak.plugins.tree.TreeFactory;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 
@@ -71,16 +72,24 @@ public class GlobalNameMapper implements
         }
     }
 
-    protected final Tree namespaces;
-    protected final Tree nsdata;
+    private final Root root;
+    private Tree namespaces;
+    private Tree nsdata;
 
     public GlobalNameMapper(Root root) {
-        this.namespaces = root.getTree(NAMESPACES_PATH);
-        this.nsdata = namespaces.getChild(REP_NSDATA);
+        this.root = root;
+        init();
     }
 
     public GlobalNameMapper(NodeState root) {
-        this(RootFactory.createReadOnlyRoot(root));
+        this(createReadOnlyRoot(root));
+    }
+
+    private void init() {
+        if (root != null) {
+            this.namespaces = root.getTree(NAMESPACES_PATH);
+            this.nsdata = namespaces.getChild(REP_NSDATA);
+        }
     }
 
     public GlobalNameMapper(Map<String, String> mappings) {
@@ -98,8 +107,9 @@ public class GlobalNameMapper implements
         reverse.setProperty(REP_PREFIXES, mappings.keySet(), STRINGS);
         reverse.setProperty(REP_URIS, mappings.values(), STRINGS);
 
-        this.namespaces = TreeFactory.createReadOnlyTree(forward.getNodeState());
-        this.nsdata = TreeFactory.createReadOnlyTree(reverse.getNodeState());
+        this.root = null;
+        this.namespaces = createReadOnlyTree(forward.getNodeState());
+        this.nsdata = createReadOnlyTree(reverse.getNodeState());
     }
 
     @Override @Nonnull
@@ -133,7 +143,7 @@ public class GlobalNameMapper implements
     @Nonnull
     @Override
     public Map<String, String> getSessionLocalMappings() {
-        return Collections.emptyMap();
+        return emptyMap();
     }
 
     @CheckForNull
@@ -165,12 +175,7 @@ public class GlobalNameMapper implements
             return uri;
         }
 
-        PropertyState mapping = nsdata.getProperty(encodeUri(uri));
-        if (mapping != null && mapping.getType() == STRING) {
-            return mapping.getValue(STRING);
-        }
-
-        return null;
+        return getNsData(encodeUri(uri));
     }
 
     @CheckForNull
@@ -179,12 +184,28 @@ public class GlobalNameMapper implements
             return prefix;
         }
 
-        PropertyState mapping = namespaces.getProperty(prefix);
-        if (mapping != null && mapping.getType() == STRING) {
-            return mapping.getValue(STRING);
+        return getNamespacesProperty(prefix);
+    }
+
+    protected String getNamespacesProperty(String prefix) {
+        return getString(namespaces, prefix);
+    }
+
+    private String getNsData(String uri) {
+        return getString(nsdata, uri);
+    }
+
+    protected Iterable<String> getPrefixes() {
+        Iterable<String> prefs = getStrings(nsdata, REP_PREFIXES);
+        if (prefs != null) {
+            return prefs;
+        } else {
+            return emptyList();
         }
+    }
 
-        return null;
+    public void onSessionRefresh() {
+        init();
     }
 
 }

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=1697423&r1=1697422&r2=1697423&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 Mon Aug 24 14:58:37 2015
@@ -18,14 +18,12 @@ package org.apache.jackrabbit.oak.namepa
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
-import static org.apache.jackrabbit.oak.api.Type.STRING;
 
 import java.util.Map;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 
-import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Root;
 
 /**
@@ -61,12 +59,11 @@ public class LocalNameMapper extends Glo
             int colon = oakName.indexOf(':');
             if (colon > 0) {
                 String oakPrefix = oakName.substring(0, colon);
-                PropertyState mapping = namespaces.getProperty(oakPrefix);
-                if (mapping == null || mapping.getType() != STRING) {
+                String uri = getNamespacesProperty(oakPrefix);
+                if (uri == null) {
                     throw new IllegalStateException(
                             "No namespace mapping found for " + oakName);
                 }
-                String uri = mapping.getValue(STRING);
 
                 for (Map.Entry<String, String> entry : local.entrySet()) {
                     if (uri.equals(entry.getValue())) {
@@ -123,10 +120,9 @@ public class LocalNameMapper extends Glo
                 }
 
                 // Check that a global mapping is present and not remapped
-                PropertyState mapping = namespaces.getProperty(jcrPrefix);
+                String mapping = getNamespacesProperty(jcrPrefix);
                 if (mapping != null
-                        && mapping.getType() == STRING
-                        && local.values().contains(mapping.getValue(STRING))) {
+                        && local.values().contains(mapping)) {
                     return null;
                 }
             }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/package-info.java?rev=1697423&r1=1697422&r2=1697423&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/namepath/package-info.java Mon Aug 24 14:58:37 2015
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("1.0")
+@Version("2.0")
 @Export(optional = "provide:=true")
 package org.apache.jackrabbit.oak.namepath;
 

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java?rev=1697423&r1=1697422&r2=1697423&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/delegate/SessionDelegate.java Mon Aug 24 14:58:37 2015
@@ -43,6 +43,7 @@ import javax.jcr.RepositoryException;
 import javax.jcr.nodetype.ConstraintViolationException;
 
 import com.google.common.collect.ImmutableMap;
+
 import org.apache.jackrabbit.oak.api.AuthInfo;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.ContentSession;
@@ -52,6 +53,8 @@ import org.apache.jackrabbit.oak.api.Tre
 import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.jcr.observation.EventFactory;
 import org.apache.jackrabbit.oak.jcr.session.RefreshStrategy;
+import org.apache.jackrabbit.oak.jcr.session.RefreshStrategy.Composite;
+import org.apache.jackrabbit.oak.jcr.session.SessionNamespaces;
 import org.apache.jackrabbit.oak.jcr.session.SessionStats;
 import org.apache.jackrabbit.oak.jcr.session.SessionStats.Counters;
 import org.apache.jackrabbit.oak.jcr.session.operation.SessionOperation;
@@ -112,6 +115,8 @@ public class SessionDelegate {
      */
     private final WarningLock lock = new WarningLock(new ReentrantLock());
 
+    private final SessionNamespaces namespaces;
+
     /**
      * Create a new session delegate for a {@code ContentSession}. The refresh behaviour of the
      * session is governed by the value of the {@code refreshInterval} argument: if the session
@@ -134,10 +139,12 @@ public class SessionDelegate {
             @Nonnull Clock clock) {
         this.contentSession = checkNotNull(contentSession);
         this.securityProvider = checkNotNull(securityProvider);
-        this.saveCountRefresh = new SaveCountRefresh(checkNotNull(threadSaveCount));
-        this.refreshStrategy = RefreshStrategy.Composite.create(
-                checkNotNull(refreshStrategy), refreshAtNextAccess, saveCountRefresh);
         this.root = contentSession.getLatestRoot();
+        this.namespaces = new SessionNamespaces(this.root);
+        this.saveCountRefresh = new SaveCountRefresh(checkNotNull(threadSaveCount));
+        this.refreshStrategy = Composite.create(checkNotNull(refreshStrategy),
+                refreshAtNextAccess, saveCountRefresh, new RefreshNamespaces(
+                        namespaces));
         this.idManager = new IdentifierManager(root);
         this.clock = checkNotNull(clock);
         this.sessionStats = new SessionStats(contentSession.toString(),
@@ -886,4 +893,31 @@ public class SessionDelegate {
         }
     }
 
+    /**
+     * Read-only RefreshStrategy responsible for notifying the SessionNamespaces
+     * instance that a refresh was called
+     */
+    private static class RefreshNamespaces implements RefreshStrategy {
+
+        private final SessionNamespaces namespaces;
+
+        public RefreshNamespaces(SessionNamespaces namespaces) {
+            this.namespaces = namespaces;
+        }
+
+        @Override
+        public boolean needsRefresh(long secondsSinceLastAccess) {
+            return false;
+        }
+
+        @Override
+        public void refreshed() {
+            this.namespaces.onSessionRefresh();
+        }
+    }
+
+    public SessionNamespaces getNamespaces() {
+        return namespaces;
+    }
+
 }

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/SessionContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/SessionContext.java?rev=1697423&r1=1697422&r2=1697423&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/SessionContext.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/SessionContext.java Mon Aug 24 14:58:37 2015
@@ -88,7 +88,6 @@ public class SessionContext implements N
     private final int observationQueueLength;
     private final CommitRateLimiter commitRateLimiter;
 
-    private final SessionNamespaces namespaces;
     private final NamePathMapper namePathMapper;
     private final ValueFactory valueFactory;
 
@@ -137,9 +136,8 @@ public class SessionContext implements N
         SessionStats sessionStats = delegate.getSessionStats();
         sessionStats.setAttributes(attributes);
 
-        this.namespaces = new SessionNamespaces(delegate.getRoot());
         this.namePathMapper = new NamePathMapperImpl(
-                namespaces, delegate.getIdManager());
+                delegate.getNamespaces(), delegate.getIdManager());
         this.valueFactory = new ValueFactoryImpl(
                 delegate.getRoot(), namePathMapper);
         this.fastQueryResultSize = fastQueryResultSize;
@@ -206,13 +204,13 @@ public class SessionContext implements N
     }
 
     SessionNamespaces getNamespaces() {
-        return namespaces;
+        return delegate.getNamespaces();
     }
 
     @Override
     @Nonnull
     public Map<String, String> getSessionLocalMappings() {
-        return namespaces.getSessionLocalMappings();
+        return getNamespaces().getSessionLocalMappings();
     }
 
     public ValueFactory getValueFactory() {
@@ -392,7 +390,7 @@ public class SessionContext implements N
         if (observationManager != null) {
             observationManager.dispose();
         }
-        namespaces.clear();
+        getNamespaces().clear();
     }
 
     /**

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/SessionNamespaces.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/SessionNamespaces.java?rev=1697423&r1=1697422&r2=1697423&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/SessionNamespaces.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/SessionNamespaces.java Mon Aug 24 14:58:37 2015
@@ -18,9 +18,6 @@ package org.apache.jackrabbit.oak.jcr.se
 
 import static com.google.common.collect.Iterables.toArray;
 import static com.google.common.collect.Sets.newHashSet;
-import static java.util.Collections.emptyList;
-import static org.apache.jackrabbit.oak.api.Type.STRINGS;
-import static org.apache.jackrabbit.oak.plugins.name.NamespaceConstants.REP_PREFIXES;
 
 import java.util.HashSet;
 import java.util.Locale;
@@ -31,7 +28,6 @@ import javax.annotation.Nonnull;
 import javax.jcr.NamespaceException;
 import javax.jcr.Session;
 
-import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.namepath.LocalNameMapper;
 import org.apache.jackrabbit.util.XMLChar;
@@ -44,9 +40,9 @@ import com.google.common.collect.Maps;
  * re-mappings and takes a snapshot of the namespace registry when initialized
  * (see JCR 2.0 specification, section 3.5.1).
  */
-class SessionNamespaces extends LocalNameMapper {
+public class SessionNamespaces extends LocalNameMapper {
 
-    SessionNamespaces(@Nonnull Root root) {
+    public SessionNamespaces(@Nonnull Root root) {
         super(root, Maps.<String, String>newHashMap());
     }
 
@@ -97,11 +93,7 @@ class SessionNamespaces extends LocalNam
      */
     synchronized String[] getNamespacePrefixes() {
         // get registered namespace prefixes
-        Iterable<String> global = emptyList();
-        PropertyState property = nsdata.getProperty(REP_PREFIXES);
-        if (property != null && property.getType() == STRINGS) {
-            global = property.getValue(STRINGS);
-        }
+        Iterable<String> global = getPrefixes();
 
         // unless there are local remappings just use the registered ones
         if (local.isEmpty()) {