jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ste...@apache.org
Subject svn commit: r327199 - in /incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit: core/CachingNamespaceResolver.java core/LocalNamespaceMappings.java core/NamespaceRegistryImpl.java name/AbstractNamespaceResolver.java name/NamespaceListener.java
Date Fri, 21 Oct 2005 14:29:03 GMT
Author: stefan
Date: Fri Oct 21 07:28:53 2005
New Revision: 327199

URL: http://svn.apache.org/viewcvs?rev=327199&view=rev
Log:
JCR-242: locally remap conflicting prefix if the registration of a new global prefix collides
with a session-local prefix

Modified:
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/CachingNamespaceResolver.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/LocalNamespaceMappings.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NamespaceRegistryImpl.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/AbstractNamespaceResolver.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/NamespaceListener.java

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/CachingNamespaceResolver.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/CachingNamespaceResolver.java?rev=327199&r1=327198&r2=327199&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/CachingNamespaceResolver.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/CachingNamespaceResolver.java
Fri Oct 21 07:28:53 2005
@@ -113,12 +113,19 @@
     }
 
     //----------------------------------------------------< NamespaceListener >
+    /**
+     * @inheritDoc
+     */
+    public void namespaceAdded(String prefix, String uri) {
+        // since it is a new namespace there's no need to flush the
+        // cached mappings 
+    }
 
     /**
      * @inheritDoc
      * Invalidates all cached mappings.
      */
-    public synchronized void prefixRemapped(String prefix, String uri) {
+    public void namespaceRemapped(String oldPrefix, String newPrefix, String uri) {
         qnameToJCRName.clear();
         jcrNameToQName.clear();
     }

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/LocalNamespaceMappings.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/LocalNamespaceMappings.java?rev=327199&r1=327198&r2=327199&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/LocalNamespaceMappings.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/LocalNamespaceMappings.java
Fri Oct 21 07:28:53 2005
@@ -46,7 +46,7 @@
  * underlying namespace registry.
  */
 class LocalNamespaceMappings extends AbstractNamespaceResolver
-        implements NamespaceListener{
+        implements NamespaceListener {
 
     /** The underlying global and persistent namespace registry. */
     private final NamespaceRegistryImpl nsReg;
@@ -124,7 +124,9 @@
                 // we don't allow to hide a namespace because we can't
                 // guarantee that there are no references to it
                 // (in names of nodes/properties/node types etc.)
-                throw new NamespaceException(prefix + ": prefix is already mapped to the
namespace: " + globalURI);
+                throw new NamespaceException(prefix
+                        + ": prefix is already mapped to the namespace: "
+                        + globalURI);
             }
         }
 
@@ -193,6 +195,34 @@
         nsReg.removeListener(this);
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    public QName getQName(String name)
+            throws IllegalNameException, UnknownPrefixException {
+        if (prefixToURI.isEmpty()) {
+            // shortcut
+            return nsReg.getQName(name);
+        }
+        try {
+            // first try registry, this might result in a wrong QName because
+            // of locally overlayed mappings
+            QName candidate = nsReg.getQName(name);
+            // check if valid
+            String prefix = nsReg.getPrefix(candidate.getNamespaceURI());
+            if (!hiddenPrefixes.contains(prefix)) {
+                return candidate;
+            }
+        } catch (UnknownPrefixException e) {
+            // try using local mappings
+        } catch (NamespaceException e) {
+            // may be thrown by nsReg.getPrefix() but should never happend
+            // because we got the namespace from the nsReg itself
+            throw new UnknownPrefixException(name);
+        }
+        return super.getQName(name);
+    }
+
     //----------------------------------------------------< NamespaceResolver >
     /**
      * {@inheritDoc}
@@ -238,34 +268,6 @@
     /**
      * {@inheritDoc}
      */
-    public QName getQName(String name)
-            throws IllegalNameException, UnknownPrefixException {
-        if (prefixToURI.isEmpty()) {
-            // shortcut
-            return nsReg.getQName(name);
-        }
-        try {
-            // first try registry, this might result in a wrong QName because
-            // of locally overlayed mappings
-            QName candidate = nsReg.getQName(name);
-            // check if valid
-            String prefix = nsReg.getPrefix(candidate.getNamespaceURI());
-            if (!hiddenPrefixes.contains(prefix)) {
-                return candidate;
-            }
-        } catch (UnknownPrefixException e) {
-            // try using local mappings
-        } catch (NamespaceException e) {
-            // may be thrown by nsReg.getPrefix() but should never happend
-            // because we got the namespace from the nsReg itself
-            throw new UnknownPrefixException(name);
-        }
-        return super.getQName(name);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
     public String getJCRName(QName name)
             throws NoPrefixDeclaredException {
         if (uriToPrefix.isEmpty()) {
@@ -281,12 +283,52 @@
         }
     }
 
+    //----------------------------------------------------< NamespaceListener >
+    /**
+     * @inheritDoc
+     * This method gets called when a new namespace is registered in
+     * the global NamespaceRegistry. Overridden in order to check for/resolve
+     * collision of new global prefix with existing local prefix.
+     */
+    public void namespaceAdded(String prefix, String uri) {
+        if (prefixToURI.containsKey(prefix)) {
+            // the new global prefix is already in use locally;
+            // need to change it locally by appending underscore(s)
+            // in order to guarantee unambiguous mappings
+            String uniquePrefix = prefix + "_";
+            while (prefixToURI.containsKey(uniquePrefix)) {
+                uniquePrefix += "_";
+            }
+            // add new local mapping
+            prefixToURI.put(uniquePrefix, uri);
+            uriToPrefix.put(uri, uniquePrefix);
+        }
+    }
+
     /**
      * @inheritDoc
-     * This method gets called when the NamespaceRegistry remapped a namespace
-     * to a new prefix or if a new namespace is registered.
+     * This method gets called when an existing namespace is remapped to a new
+     * prefix in the global NamespaceRegistry. Overridden in order to check
+     * for/resolve collision of new global prefix with existing local prefix.
      */
-    public void prefixRemapped(String prefix, String uri) {
-        // todo check overlayed mappings and adjust prefixes if necessary
+    public void namespaceRemapped(String oldPrefix, String newPrefix, String uri) {
+        if (prefixToURI.containsKey(newPrefix)) {
+            // the new global prefix is already in use locally;
+            // check uri
+            if (uriToPrefix.containsKey(uri)) {
+                // since namespace is already remapped locally to
+                // a different prefix there's no collision
+                return;
+            }
+            // need to change enw prefix locally by appending underscore(s)
+            // in order to guarantee unambiguous mappings
+            String uniquePrefix = newPrefix + "_";
+            while (prefixToURI.containsKey(uniquePrefix)) {
+                uniquePrefix += "_";
+            }
+            // add new local mapping
+            prefixToURI.put(uniquePrefix, uri);
+            uriToPrefix.put(uri, uniquePrefix);
+        }
     }
 }

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NamespaceRegistryImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NamespaceRegistryImpl.java?rev=327199&r1=327198&r2=327199&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NamespaceRegistryImpl.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NamespaceRegistryImpl.java
Fri Oct 21 07:28:53 2005
@@ -270,7 +270,13 @@
         store();
 
         // notify listeners
-        notifyPrefixRemapped(prefix, uri);
+        if (oldPrefix != null) {
+            // remapped existing namespace uri to new prefix
+            notifyNamespaceRemapped(oldPrefix, prefix, uri);
+        } else {
+            // added new namespace uri mapped to prefix
+            notifyNamespaceAdded(prefix, uri);
+        }
     }
 
     /**

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/AbstractNamespaceResolver.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/AbstractNamespaceResolver.java?rev=327199&r1=327198&r2=327199&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/AbstractNamespaceResolver.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/AbstractNamespaceResolver.java
Fri Oct 21 07:28:53 2005
@@ -111,14 +111,44 @@
     }
 
     /**
-     * Notifies listeners that a prefix has been remapped.
+     * Notifies the listeners that a new namespace <code>uri</code> has been
+     * added and mapped to <code>prefix</code>.
      *
-     * @param prefix the new prefix.
-     * @param uri the according namespace uri.
+     * @param prefix the prefix.
+     * @param uri    the namespace uri.
      */
-    protected void notifyPrefixRemapped(String prefix, String uri) {
+    protected void notifyNamespaceAdded(String prefix, String uri) {
         if (listeners == null) {
-            throw new UnsupportedOperationException("notifyPrefixRemapped");
+            throw new UnsupportedOperationException("notifyNamespaceAdded");
+        }
+        // addition is infrequent compared to listener registration
+        // -> use copy-on-read
+        NamespaceListener[] currentListeners;
+        synchronized (listeners) {
+            int i = 0;
+            currentListeners = new NamespaceListener[listeners.size()];
+            for (Iterator it = listeners.iterator(); it.hasNext(); ) {
+                currentListeners[i++] = (NamespaceListener) it.next();
+            }
+        }
+        for (int i = 0; i < currentListeners.length; i++) {
+            currentListeners[i].namespaceAdded(prefix, uri);
+        }
+    }
+
+    /**
+     * Notifies listeners that an existing namespace uri has been remapped
+     * to a new prefix.
+     *
+     * @param oldPrefix the old prefix.
+     * @param newPrefix the new prefix.
+     * @param uri the associated namespace uri.
+     */
+    protected void notifyNamespaceRemapped(String oldPrefix,
+                                           String newPrefix,
+                                           String uri) {
+        if (listeners == null) {
+            throw new UnsupportedOperationException("notifyNamespaceRemapped");
         }
         // remapping is infrequent compared to listener registration
         // -> use copy-on-read
@@ -131,7 +161,7 @@
             }
         }
         for (int i = 0; i < currentListeners.length; i++) {
-            currentListeners[i].prefixRemapped(prefix, uri);
+            currentListeners[i].namespaceRemapped(oldPrefix, newPrefix, uri);
         }
     }
 }

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/NamespaceListener.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/NamespaceListener.java?rev=327199&r1=327198&r2=327199&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/NamespaceListener.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/NamespaceListener.java
Fri Oct 21 07:28:53 2005
@@ -22,11 +22,21 @@
 public interface NamespaceListener {
 
     /**
-     * Notifies the listener that the namespace <code>uri</code> has been
-     * re-mapped to the new <code>prefix</code>.
+     * Notifies the listeners that an existing namespace <code>uri</code> has
+     * been re-mapped from <code>oldPrefix</code> to <code>newPrefix</code>.
      *
-     * @param prefix the new prefix for <code>uri</code>.
+     * @param oldPrefix the old prefix.
+     * @param newPrefix the new prefix.
+     * @param uri       the associated namespace uri.
+     */
+    public void namespaceRemapped(String oldPrefix, String newPrefix, String uri);
+
+    /**
+     * Notifies the listeners that a new namespace <code>uri</code> has been
+     * added and mapped to <code>prefix</code>.
+     *
+     * @param prefix the prefix.
      * @param uri    the namespace uri.
      */
-    public void prefixRemapped(String prefix, String uri);
+    public void namespaceAdded(String prefix, String uri);
 }



Mime
View raw message