Index: oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java =================================================================== --- oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java (revision 1462128) +++ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionImpl.java (working copy) @@ -19,7 +19,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.Locale; import java.util.Map; @@ -33,6 +34,7 @@ import javax.jcr.Item; import javax.jcr.ItemNotFoundException; import javax.jcr.NamespaceException; +import javax.jcr.NamespaceRegistry; import javax.jcr.Node; import javax.jcr.PathNotFoundException; import javax.jcr.Property; @@ -80,6 +82,12 @@ private final SessionDelegate sd; /** + * A snapshot of the namespace registry on first usage. See + * JCR 2.0 (3.5.1) + */ + private Map namespacesSnapshot; + + /** * Local namespace remappings. Prefixes as keys and namespace URIs as values. *

* This map is only accessed from synchronized methods (see @@ -642,11 +650,12 @@ public String[] getNamespacePrefixes() throws RepositoryException { synchronized (namespaces) { if (namespaces.isEmpty()) { - return getWorkspace().getNamespaceRegistry().getPrefixes(); + Set prefixes = getNamespaceSnapshot().keySet(); + return prefixes.toArray(new String[prefixes.size()]); } } Set uris = new HashSet(); - uris.addAll(Arrays.asList(getWorkspace().getNamespaceRegistry().getURIs())); + uris.addAll(getNamespaceSnapshot().values()); synchronized (namespaces) { // Add namespace uris only visible to session uris.addAll(namespaces.values()); @@ -664,12 +673,16 @@ String uri = namespaces.get(prefix); if (uri == null) { - // Not in local mappings, try the global ones - uri = getWorkspace().getNamespaceRegistry().getURI(prefix); - if (namespaces.containsValue(uri)) { - // The global URI is locally mapped to some other prefix, - // so there are no mappings for this prefix - throw new NamespaceException("Namespace not found: " + prefix); + // Not in local mappings, try snapshot ones + uri = getNamespaceSnapshot().get(prefix); + if (uri == null) { + // Not in snapshot mappings, try the global ones + uri = getWorkspace().getNamespaceRegistry().getURI(prefix); + if (namespaces.containsValue(uri)) { + // The global URI is locally mapped to some other prefix, + // so there are no mappings for this prefix + throw new NamespaceException("Namespace not found: " + prefix); + } } } @@ -686,6 +699,13 @@ } } + // try namespace snapshot + for (Map.Entry entry : getNamespaceSnapshot().entrySet()) { + if (entry.getValue().equals(uri)) { + return entry.getKey(); + } + } + // The following throws an exception if the URI is not found, that's OK String prefix = getWorkspace().getNamespaceRegistry().getPrefix(uri); @@ -702,6 +722,19 @@ } } + private Map getNamespaceSnapshot() + throws RepositoryException { + if (namespacesSnapshot == null) { + Map map = new HashMap(); + NamespaceRegistry registry = getWorkspace().getNamespaceRegistry(); + for (String prefix : registry.getPrefixes()) { + map.put(prefix, registry.getURI(prefix)); + } + namespacesSnapshot = Collections.unmodifiableMap(map); + } + return namespacesSnapshot; + } + //--------------------------------------------------< JackrabbitSession >--- @Override