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