jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r655554 - /jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/RepositoryServiceImpl.java
Date Mon, 12 May 2008 16:40:39 GMT
Author: jukka
Date: Mon May 12 09:40:39 2008
New Revision: 655554

URL: http://svn.apache.org/viewvc?rev=655554&view=rev
Log:
JCR-1564: JSR 283 namespace handling
    - RepositoryServiceImpl now works with overlapping namespace mappings for queries

Modified:
    jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/RepositoryServiceImpl.java

Modified: jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/RepositoryServiceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/RepositoryServiceImpl.java?rev=655554&r1=655553&r2=655554&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/RepositoryServiceImpl.java
(original)
+++ jackrabbit/trunk/jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/RepositoryServiceImpl.java
Mon May 12 09:40:39 2008
@@ -1436,23 +1436,80 @@
                               String language,
                               Map namespaces)
             throws InvalidQueryException, RepositoryException {
-        NamespaceRegistry nsReg = session.getWorkspace().getNamespaceRegistry();
         QueryManager qMgr = session.getWorkspace().getQueryManager();
+
+        // apply namespace mappings to session
+        Map previous = setNamespaceMappings(session, namespaces);
         try {
-            // apply namespace mappings to session
-            for (Iterator it = namespaces.keySet().iterator(); it.hasNext(); ) {
-                String prefix = (String) it.next();
-                String uri = (String) namespaces.get(prefix);
-                session.setNamespacePrefix(prefix, uri);
-            }
             return qMgr.createQuery(statement, language);
         } finally {
             // reset namespace mappings
-            for (Iterator it = namespaces.values().iterator(); it.hasNext(); ) {
-                String uri = (String) it.next();
-                session.setNamespacePrefix(nsReg.getPrefix(uri), uri);
+            setNamespaceMappings(session, previous);
+        }
+    }
+
+    /**
+     * Utility method that changes the namespace mappings of the
+     * given sessions to include the given prefix to URI mappings.
+     * 
+     * @param session current session
+     * @param namespaces prefix to URI mappings
+     * @return the previous namespace mappings that were modified
+     * @throws RepositoryException if a repository error occurs
+     */
+    private Map setNamespaceMappings(Session session, Map namespaces)
+            throws RepositoryException {
+        Map previous = new HashMap();
+
+        Iterator iterator = namespaces.entrySet().iterator();
+        while (iterator.hasNext()) {
+            Map.Entry entry = (Map.Entry) iterator.next();
+            String uri = (String) entry.getValue();
+            String prefix = (String) entry.getKey();
+
+            // Get the previous prefix for this URI, throws if
+            // URI not found (which is OK, as that's an error)
+            String oldPrefix = session.getNamespacePrefix(uri);
+            // If the prefixes are different, we need to remap the namespace
+            if (!prefix.equals(oldPrefix)) {
+                // Check if the new prefix is mapped to some other URI
+                String oldURI = safeGetURI(session, prefix);
+                if (oldURI != null) {
+                    // Find an unused prefix and map the old URI to it
+                    int i = 2;
+                    String tmpPrefix = oldPrefix + i++;
+                    while (safeGetURI(session, tmpPrefix) != null
+                            || namespaces.containsKey(tmpPrefix)) {
+                        tmpPrefix = oldPrefix + i++;
+                    }
+                    session.setNamespacePrefix(tmpPrefix, oldURI);
+                    previous.put(prefix, oldURI); // remember the old URI
+                }
+                // It's now safe to remap
+                session.setNamespacePrefix(prefix, uri);
+                previous.put(oldPrefix, uri); // remember the old prefix
             }
         }
+
+        return previous;
+    }
+
+    /**
+     * Utility method that returns the namespace URI mapped to the given
+     * prefix, or <code>null</code> if the prefix is not mapped.
+     *
+     * @param session current session
+     * @param prefix namespace prefix
+     * @return namespace URI or <code>null</code>
+     * @throws RepositoryException if a repository error occurs
+     */
+    private String safeGetURI(Session session, String prefix)
+            throws RepositoryException {
+        try {
+            return session.getNamespaceURI(prefix);
+        } catch (NamespaceException e) {
+            return null;
+        }
     }
 
     private Object executeWithLocalEvents(Callable call, SessionInfoImpl sInfo)



Mime
View raw message