jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ste...@apache.org
Subject svn commit: r314827 - in /incubator/jackrabbit/trunk/src: java/org/apache/jackrabbit/core/ java/org/apache/jackrabbit/core/nodetype/xml/ java/org/apache/jackrabbit/core/query/lucene/ java/org/apache/jackrabbit/core/xml/ java/org/apache/jackrabbit/name/...
Date Wed, 12 Oct 2005 09:04:48 GMT
Author: stefan
Date: Wed Oct 12 02:04:31 2005
New Revision: 314827

URL: http://svn.apache.org/viewcvs?rev=314827&view=rev
Log: (empty)

Added:
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/AbstractNamespaceResolver.java
  (with props)
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/CachingNamespaceResolver.java
  (with props)
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/NamespaceListener.java
  (with props)
Modified:
    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/core/NodeImpl.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/PropertyImpl.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SessionImpl.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/AdditionalNamespaceResolver.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/NamespaceMappings.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/ImportHandler.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/NamespaceResolver.java
    incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/SessionNamespaceResolver.java
    incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/name/PathTest.java
    incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/name/QNameTest.java

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=314827&r1=314826&r2=314827&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
Wed Oct 12 02:04:31 2005
@@ -18,6 +18,10 @@
 
 import org.apache.jackrabbit.name.NamespaceResolver;
 import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.IllegalNameException;
+import org.apache.jackrabbit.name.UnknownPrefixException;
+import org.apache.jackrabbit.name.NoPrefixDeclaredException;
+import org.apache.jackrabbit.name.CachingNamespaceResolver;
 import org.apache.xerces.util.XMLChar;
 
 import javax.jcr.NamespaceException;
@@ -40,7 +44,7 @@
  * looking up the local namespace mapping and then backing to the
  * underlying namespace registry.
  */
-class LocalNamespaceMappings implements NamespaceResolver {
+class LocalNamespaceMappings extends CachingNamespaceResolver {
 
     /** The underlying global and persistent namespace registry. */
     private final NamespaceRegistryImpl nsReg;
@@ -61,6 +65,7 @@
      * @param nsReg namespace registry
      */
     LocalNamespaceMappings(NamespaceRegistryImpl nsReg) {
+        super(nsReg, 100);
         this.nsReg = nsReg;
     }
 
@@ -151,6 +156,9 @@
             uriToPrefix.put(uri, prefix);
             hiddenPrefixes.add(globalPrefix);
         }
+
+        // invalidate cache
+        super.prefixRemapped(prefix, uri);
     }
 
     /**
@@ -189,8 +197,9 @@
             return nsReg.getURI(prefix);
         }
         // check local mappings
-        if (prefixToURI.containsKey(prefix)) {
-            return (String) prefixToURI.get(prefix);
+        String uri = (String) prefixToURI.get(prefix);
+        if (uri != null) {
+            return uri;
         }
 
         // check global mappings
@@ -211,11 +220,68 @@
         }
 
         // check local mappings
-        if (uriToPrefix.containsKey(uri)) {
-            return (String) uriToPrefix.get(uri);
+        String prefix = (String) uriToPrefix.get(uri);
+        if (prefix != null) {
+            return prefix;
         }
 
         // check global mappings
         return nsReg.getPrefix(uri);
+    }
+
+    /**
+     * {@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()) {
+            // shortcut
+            return nsReg.getJCRName(name);
+        }
+        if (uriToPrefix.containsKey(name.getNamespaceURI())) {
+            // locally re-mappped
+            return super.getJCRName(name);
+        } else {
+            // use global mapping
+            return nsReg.getJCRName(name);
+        }
+    }
+
+    /**
+     * @inheritDoc
+     * This method gets called when the NamespaceRegistry remapped a namespace
+     * to a new prefix or if a new namespace is registered.
+     */
+    public void prefixRemapped(String prefix, String uri) {
+        // todo check overlayed mappings and adjust prefixes if necessary
+        super.prefixRemapped(prefix, uri);
     }
 }

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=314827&r1=314826&r2=314827&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
Wed Oct 12 02:04:31 2005
@@ -18,8 +18,12 @@
 
 import org.apache.jackrabbit.core.fs.FileSystem;
 import org.apache.jackrabbit.core.fs.FileSystemResource;
-import org.apache.jackrabbit.name.NamespaceResolver;
 import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.AbstractNamespaceResolver;
+import org.apache.jackrabbit.name.IllegalNameException;
+import org.apache.jackrabbit.name.UnknownPrefixException;
+import org.apache.jackrabbit.name.NoPrefixDeclaredException;
+import org.apache.jackrabbit.name.CachingNamespaceResolver;
 import org.apache.log4j.Logger;
 import org.apache.xerces.util.XMLChar;
 
@@ -38,8 +42,8 @@
 /**
  * A <code>NamespaceRegistryImpl</code> ...
  */
-public class NamespaceRegistryImpl implements NamespaceRegistry,
-        NamespaceResolver {
+public class NamespaceRegistryImpl extends AbstractNamespaceResolver
+        implements NamespaceRegistry {
 
     private static Logger log = Logger.getLogger(NamespaceRegistryImpl.class);
 
@@ -72,6 +76,8 @@
     private HashMap prefixToURI = new HashMap();
     private HashMap uriToPrefix = new HashMap();
 
+    private final CachingNamespaceResolver resolver;
+
     private final FileSystem nsRegStore;
 
     /**
@@ -80,13 +86,17 @@
      * @param nsRegStore
      * @throws RepositoryException
      */
-    protected NamespaceRegistryImpl(FileSystem nsRegStore) throws RepositoryException {
+    protected NamespaceRegistryImpl(FileSystem nsRegStore)
+            throws RepositoryException {
+        super(true); // enable listener support
         this.nsRegStore = nsRegStore;
+        resolver = new CachingNamespaceResolver(this, 1000);
         load();
     }
 
     private void load() throws RepositoryException {
-        FileSystemResource propFile = new FileSystemResource(nsRegStore, NS_REG_RESOURCE);
+        FileSystemResource propFile =
+                new FileSystemResource(nsRegStore, NS_REG_RESOURCE);
         try {
             if (!propFile.exists()) {
                 // clear existing mappings
@@ -150,7 +160,8 @@
     }
 
     private void store() throws RepositoryException {
-        FileSystemResource propFile = new FileSystemResource(nsRegStore, NS_REG_RESOURCE);
+        FileSystemResource propFile =
+                new FileSystemResource(nsRegStore, NS_REG_RESOURCE);
         try {
             propFile.makeParentDirs();
             OutputStream os = propFile.getOutputStream();
@@ -249,7 +260,8 @@
              * (in names of nodes/properties/node types etc.) we simply don't allow it.
              */
             throw new NamespaceException("failed to register namespace "
-                    + prefix + " -> " + uri + ": remapping existing prefixes is not supported.");
+                    + prefix + " -> " + uri
+                    + ": remapping existing prefixes is not supported.");
         }
 
         prefixToURI.put(prefix, uri);
@@ -257,6 +269,9 @@
 
         // persist mappings
         store();
+
+        // notify listeners
+        notifyPrefixRemapped(prefix, uri);
     }
 
     /**
@@ -298,19 +313,38 @@
      * {@inheritDoc}
      */
     public String getURI(String prefix) throws NamespaceException {
-        if (!prefixToURI.containsKey(prefix)) {
-            throw new NamespaceException(prefix + ": is not a registered namespace prefix.");
+        String uri = (String) prefixToURI.get(prefix);
+        if (uri == null) {
+            throw new NamespaceException(prefix
+                    + ": is not a registered namespace prefix.");
         }
-        return (String) prefixToURI.get(prefix);
+        return uri;
     }
 
     /**
      * {@inheritDoc}
      */
     public String getPrefix(String uri) throws NamespaceException {
-        if (!uriToPrefix.containsKey(uri)) {
-            throw new NamespaceException(uri + ": is not a registered namespace uri.");
+        String prefix = (String) uriToPrefix.get(uri);
+        if (prefix == null) {
+            throw new NamespaceException(uri
+                    + ": is not a registered namespace uri.");
         }
-        return (String) uriToPrefix.get(uri);
+        return prefix;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public QName getQName(String name)
+            throws IllegalNameException, UnknownPrefixException {
+        return resolver.getQName(name);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getJCRName(QName name) throws NoPrefixDeclaredException {
+        return resolver.getJCRName(name);
     }
 }

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java?rev=314827&r1=314826&r2=314827&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/NodeImpl.java Wed Oct 12
02:04:31 2005
@@ -159,30 +159,21 @@
              * first check if relPath is just a name (in which case we don't
              * have to build & resolve absolute path)
              */
-            Path p = Path.create(relPath, session.getNamespaceResolver(), false);
-            if (p.getLength() == 1) {
-                Path.PathElement pe = p.getNameElement();
-                if (pe.denotesName()) {
-                    if (pe.getIndex() > 0) {
-                        // property name can't have subscript
-                        String msg = relPath + " is not a valid property path";
-                        log.debug(msg);
-                        throw new RepositoryException(msg);
-                    }
-                    // check if property entry exists
-                    NodeState thisState = (NodeState) state;
-                    if (thisState.hasPropertyName(pe.getName())) {
-                        return new PropertyId(thisState.getUUID(), pe.getName());
-                    } else {
-                        // there's no property with that name
-                        return null;
-                    }
+            if (relPath.indexOf('/') == -1) {
+                QName propName = session.getNamespaceResolver().getQName(relPath);
+                // check if property entry exists
+                NodeState thisState = (NodeState) state;
+                if (thisState.hasPropertyName(propName)) {
+                    return new PropertyId(thisState.getUUID(), propName);
+                } else {
+                    // there's no property with that name
+                    return null;
                 }
             }
             /**
              * build and resolve absolute path
              */
-            p = Path.create(getPrimaryPath(), relPath, session.getNamespaceResolver(), true);
+            Path p = Path.create(getPrimaryPath(), relPath, session.getNamespaceResolver(),
true);
             try {
                 ItemId id = session.getHierarchyManager().resolvePath(p);
                 if (!id.denotesNode()) {
@@ -194,7 +185,7 @@
             } catch (PathNotFoundException pnfe) {
                 return null;
             }
-        } catch (MalformedPathException e) {
+        } catch (BaseException e) {
             String msg = "failed to resolve path " + relPath + " relative to " + safeGetJCRPath();
             log.debug(msg);
             throw new RepositoryException(msg, e);
@@ -402,7 +393,7 @@
             throws ConstraintViolationException, RepositoryException {
         QName qName;
         try {
-            qName = QName.fromJCRName(name, session.getNamespaceResolver());
+            qName = session.getNamespaceResolver().getQName(name);
         } catch (IllegalNameException ine) {
             throw new RepositoryException("invalid property name: " + name, ine);
         } catch (UnknownPrefixException upe) {
@@ -560,7 +551,7 @@
     protected void removeChildProperty(String propName) throws RepositoryException {
         QName qName;
         try {
-            qName = QName.fromJCRName(propName, session.getNamespaceResolver());
+            qName = session.getNamespaceResolver().getQName(propName);
         } catch (IllegalNameException ine) {
             throw new RepositoryException("invalid property name: "
                     + propName, ine);
@@ -1683,7 +1674,7 @@
 
         QName name = session.getHierarchyManager().getName(id);
         try {
-            return name.toJCRName(session.getNamespaceResolver());
+            return session.getNamespaceResolver().getJCRName(name);
         } catch (NoPrefixDeclaredException npde) {
             // should never get here...
             String msg = "internal error: encountered unregistered namespace "
@@ -2372,7 +2363,7 @@
     public boolean isNodeType(String nodeTypeName) throws RepositoryException {
         QName ntName;
         try {
-            ntName = QName.fromJCRName(nodeTypeName, session.getNamespaceResolver());
+            ntName = session.getNamespaceResolver().getQName(nodeTypeName);
         } catch (IllegalNameException ine) {
             throw new RepositoryException("invalid node type name: " + nodeTypeName, ine);
         } catch (UnknownPrefixException upe) {
@@ -2419,7 +2410,7 @@
             ConstraintViolationException, LockException, RepositoryException {
         QName ntName;
         try {
-            ntName = QName.fromJCRName(mixinName, session.getNamespaceResolver());
+            ntName = session.getNamespaceResolver().getQName(mixinName);
         } catch (IllegalNameException ine) {
             throw new RepositoryException("invalid mixin type name: " + mixinName, ine);
         } catch (UnknownPrefixException upe) {
@@ -2437,7 +2428,7 @@
             ConstraintViolationException, LockException, RepositoryException {
         QName ntName;
         try {
-            ntName = QName.fromJCRName(mixinName, session.getNamespaceResolver());
+            ntName = session.getNamespaceResolver().getQName(mixinName);
         } catch (IllegalNameException ine) {
             throw new RepositoryException("invalid mixin type name: " + mixinName, ine);
         } catch (UnknownPrefixException upe) {
@@ -2472,7 +2463,7 @@
 
         QName ntName;
         try {
-            ntName = QName.fromJCRName(mixinName, session.getNamespaceResolver());
+            ntName = session.getNamespaceResolver().getQName(mixinName);
         } catch (IllegalNameException ine) {
             throw new RepositoryException("invalid mixin type name: "
                     + mixinName, ine);

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/PropertyImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/PropertyImpl.java?rev=314827&r1=314826&r2=314827&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/PropertyImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/PropertyImpl.java Wed Oct
12 02:04:31 2005
@@ -160,7 +160,7 @@
             case PropertyType.NAME:
                 QName name = (QName) value.internalValue();
                 try {
-                    return name.toJCRName(session.getNamespaceResolver()).length();
+                    return session.getNamespaceResolver().getJCRName(name).length();
                 } catch (NoPrefixDeclaredException npde) {
                     // should never happen...
                     String msg = safeGetJCRPath()
@@ -1116,7 +1116,7 @@
         PropertyId propId = (PropertyId) id;
         QName name = propId.getName();
         try {
-            return name.toJCRName(session.getNamespaceResolver());
+            return session.getNamespaceResolver().getJCRName(name);
         } catch (NoPrefixDeclaredException npde) {
             // should never get here...
             String msg = "internal error: encountered unregistered namespace " + name.getNamespaceURI();

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SessionImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SessionImpl.java?rev=314827&r1=314826&r2=314827&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SessionImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SessionImpl.java Wed Oct
12 02:04:31 2005
@@ -1117,6 +1117,8 @@
         // notify listeners that session is about to be closed
         notifyLoggingOut();
 
+        // dispose name resolver
+        nsMappings.dispose();
         // dispose session item state manager
         itemStateMgr.dispose();
         // dispose item manager

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/AdditionalNamespaceResolver.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/AdditionalNamespaceResolver.java?rev=314827&r1=314826&r2=314827&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/AdditionalNamespaceResolver.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/nodetype/xml/AdditionalNamespaceResolver.java
Wed Oct 12 02:04:31 2005
@@ -16,7 +16,7 @@
  */
 package org.apache.jackrabbit.core.nodetype.xml;
 
-import org.apache.jackrabbit.name.NamespaceResolver;
+import org.apache.jackrabbit.name.AbstractNamespaceResolver;
 
 import javax.jcr.NamespaceException;
 import javax.jcr.NamespaceRegistry;
@@ -28,7 +28,7 @@
  * A simple namespace resolver implementation, that uses the additional
  * namespaces declared in an XML element.
  */
-public class AdditionalNamespaceResolver implements NamespaceResolver {
+public class AdditionalNamespaceResolver extends AbstractNamespaceResolver {
 
     /** Map from namespace prefixes to namespace URIs. */
     private final Properties prefixToURI = new Properties();

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/NamespaceMappings.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/NamespaceMappings.java?rev=314827&r1=314826&r2=314827&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/NamespaceMappings.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/query/lucene/NamespaceMappings.java
Wed Oct 12 02:04:31 2005
@@ -21,6 +21,7 @@
 import org.apache.jackrabbit.name.NoPrefixDeclaredException;
 import org.apache.jackrabbit.name.QName;
 import org.apache.jackrabbit.name.UnknownPrefixException;
+import org.apache.jackrabbit.name.AbstractNamespaceResolver;
 import org.apache.log4j.Logger;
 
 import javax.jcr.NamespaceException;
@@ -46,7 +47,7 @@
  * prefix is created on the fly and associated with the namespace. Known
  * namespace mappings are stored in a properties file.
  */
-public class NamespaceMappings implements NamespaceResolver {
+public class NamespaceMappings extends AbstractNamespaceResolver {
 
     /**
      * Default logger instance for this class

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/ImportHandler.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/ImportHandler.java?rev=314827&r1=314826&r2=314827&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/ImportHandler.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/xml/ImportHandler.java
Wed Oct 12 02:04:31 2005
@@ -19,6 +19,7 @@
 import org.apache.jackrabbit.core.NamespaceRegistryImpl;
 import org.apache.jackrabbit.name.NamespaceResolver;
 import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.AbstractNamespaceResolver;
 import org.apache.log4j.Logger;
 import org.xml.sax.Attributes;
 import org.xml.sax.ContentHandler;
@@ -264,7 +265,7 @@
     /**
      * <code>NamespaceContext</code> supports scoped namespace declarations.
      */
-    class NamespaceContext implements NamespaceResolver {
+    class NamespaceContext extends AbstractNamespaceResolver {
 
         private final NamespaceSupport nsContext;
 

Added: 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=314827&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/AbstractNamespaceResolver.java
(added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/AbstractNamespaceResolver.java
Wed Oct 12 02:04:31 2005
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.name;
+
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Iterator;
+
+/**
+ * Provides default implementations for the methods:
+ * <ul>
+ * <li>{@link #getQName(String)}</li>
+ * <li>{@link #getJCRName(QName)}</li>
+ * </ul>
+ * Subclasses may overwrite those methods with more efficient implementations
+ * e.g. using caching. This class also adds optional support for
+ * {@link NamespaceListener}s. To enable listener support call the constructor
+ * with <code>supportListeners</code> set to <code>true</code>. The
default
+ * constructor will not enable listener support and all listener related
+ * methods will throw an {@link UnsupportedOperationException} in that case.
+ */
+public abstract class AbstractNamespaceResolver implements NamespaceResolver {
+
+    private final Set listeners;
+
+    /**
+     * @inheritDoc
+     */
+    public QName getQName(String name)
+            throws IllegalNameException, UnknownPrefixException {
+        return QName.fromJCRName(name, this);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public String getJCRName(QName name) throws NoPrefixDeclaredException {
+        return name.toJCRName(this);
+    }
+
+    /**
+     * Creates a <code>AbstractNamespaceResolver</code> without listener
+     * support.
+     */
+    public AbstractNamespaceResolver() {
+        this(false);
+    }
+
+    /**
+     * Creates a <code>AbstractNamespaceResolver</code> with listener support
if
+     * <code>supportListeners</code> is set to <code>true</code>.
+     *
+     * @param supportListeners if <code>true</code> listener are supported by
+     *                         this instance.
+     */
+    public AbstractNamespaceResolver(boolean supportListeners) {
+        if (supportListeners) {
+            listeners = new HashSet();
+        } else {
+            listeners = null;
+        }
+    }
+
+    //--------------------------------------------< NamespaceListener support >
+
+    /**
+     * Registers <code>listener</code> to get notifications when namespace
+     * mappings change.
+     *
+     * @param listener the listener to register.
+     * @throws UnsupportedOperationException if listener support is not enabled
+     *                                       for this <code>AbstractNamespaceResolver</code>.
+     */
+    public void addListener(NamespaceListener listener) {
+        if (listeners == null) {
+            throw new UnsupportedOperationException("addListener");
+        }
+        synchronized (listeners) {
+            listeners.add(listener);
+        }
+    }
+
+    /**
+     * Removes the <code>listener</code> from this <code>NamespaceRegistery</code>.
+     *
+     * @param listener the listener to remove.
+     * @throws UnsupportedOperationException if listener support is not enabled
+     *                                       for this <code>AbstractNamespaceResolver</code>.
+     */
+    public void removeListener(NamespaceListener listener) {
+        if (listeners == null) {
+            throw new UnsupportedOperationException("removeListener");
+        }
+        synchronized (listeners) {
+            listeners.remove(listener);
+        }
+    }
+
+    /**
+     * Notifies listeners that a prefix has been remapped.
+     *
+     * @param prefix the new prefix.
+     * @param uri the according namespace uri.
+     */
+    protected void notifyPrefixRemapped(String prefix, String uri) {
+        if (listeners == null) {
+            throw new UnsupportedOperationException("notifyPrefixRemapped");
+        }
+        // remapping 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].prefixRemapped(prefix, uri);
+        }
+    }
+}

Propchange: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/AbstractNamespaceResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/CachingNamespaceResolver.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/CachingNamespaceResolver.java?rev=314827&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/CachingNamespaceResolver.java
(added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/CachingNamespaceResolver.java
Wed Oct 12 02:04:31 2005
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.name;
+
+import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.IllegalNameException;
+import org.apache.jackrabbit.name.UnknownPrefixException;
+import org.apache.jackrabbit.name.NoPrefixDeclaredException;
+import org.apache.jackrabbit.name.NamespaceResolver;
+import org.apache.jackrabbit.name.NamespaceListener;
+import org.apache.jackrabbit.name.AbstractNamespaceResolver;
+import org.apache.commons.collections.map.LRUMap;
+
+import javax.jcr.NamespaceException;
+import java.util.Map;
+
+/**
+ * Implements a {@link NamespaceResolver} that caches QName to resolved jcr names
+ * and vice versa. The cache is invalidated when a namespace uri to prefix
+ * mapping is changed.
+ */
+public class CachingNamespaceResolver
+        implements NamespaceResolver, NamespaceListener {
+
+    /**
+     * The base namespace resolver.
+     */
+    private final AbstractNamespaceResolver base;
+
+    /**
+     * Maps QName instances to resolved jcr name Strings.
+     */
+    private final Map qnameToJCRName;
+
+    /**
+     * Maps resolved jcr name Strings to QName instances.
+     */
+    private final Map jcrNameToQName;
+
+    /**
+     * Creates a new <code>CachingNamespaceResolver</code>.
+     *
+     * @param base      a base namespace resolver with support for listener
+     *                  registration.
+     * @param cacheSize number of mappings this resolver may cache.
+     */
+    public CachingNamespaceResolver(AbstractNamespaceResolver base, int cacheSize) {
+        this.base = base;
+        qnameToJCRName = new LRUMap(cacheSize);
+        jcrNameToQName = new LRUMap(cacheSize);
+        this.base.addListener(this);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public String getURI(String prefix) throws NamespaceException {
+        return base.getURI(prefix);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public String getPrefix(String uri) throws NamespaceException {
+        return base.getPrefix(uri);
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public synchronized QName getQName(String name)
+            throws IllegalNameException, UnknownPrefixException {
+        QName qName = (QName) jcrNameToQName.get(name);
+        if (qName == null) {
+            qName = QName.fromJCRName(name, this);
+            jcrNameToQName.put(name, qName);
+        }
+        return qName;
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public synchronized String getJCRName(QName name)
+            throws NoPrefixDeclaredException {
+        String jcrName = (String) qnameToJCRName.get(name);
+        if (jcrName == null) {
+            jcrName = name.toJCRName(this);
+            qnameToJCRName.put(name, jcrName);
+        }
+        return jcrName;
+    }
+
+    /**
+     * Disposes this <code>CachingNamespaceResolver</code>.
+     */
+    public void dispose() {
+        base.removeListener(this);
+    }
+
+    //----------------------------------------------------< NamespaceListener >
+
+    /**
+     * @inheritDoc
+     * Invalidates all cached mappings.
+     */
+    public synchronized void prefixRemapped(String prefix, String uri) {
+        qnameToJCRName.clear();
+        jcrNameToQName.clear();
+    }
+}

Propchange: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/CachingNamespaceResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 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=314827&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/NamespaceListener.java
(added)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/NamespaceListener.java
Wed Oct 12 02:04:31 2005
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ *                     as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.name;
+
+/**
+ * Receives notifications when a namespace mapping changes.
+ */
+public interface NamespaceListener {
+
+    /**
+     * Notifies the listener that the namespace <code>uri</code> has been
+     * re-mapped to the new <code>prefix</code>.
+     *
+     * @param prefix the new prefix for <code>uri</code>.
+     * @param uri    the namespace uri.
+     */
+    public void prefixRemapped(String prefix, String uri);
+}

Propchange: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/NamespaceListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/NamespaceResolver.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/NamespaceResolver.java?rev=314827&r1=314826&r2=314827&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/NamespaceResolver.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/NamespaceResolver.java
Wed Oct 12 02:04:31 2005
@@ -46,4 +46,22 @@
      */
     String getPrefix(String uri) throws NamespaceException;
 
+    /**
+     * Parses the given prefixed JCR name into a qualified name.
+     *
+     * @param name the raw name, potentially prefixed.
+     * @return the QName instance for the raw name.
+     * @throws IllegalNameException   if the given name is not a valid JCR name
+     * @throws UnknownPrefixException if the JCR name prefix does not resolve
+     */
+    public QName getQName(String name)
+            throws IllegalNameException, UnknownPrefixException;
+
+    /**
+     * Returns the qualified name in the prefixed JCR name format.
+     *
+     * @return name the qualified name
+     * @throws NoPrefixDeclaredException if the namespace can not be resolved
+     */
+    public String getJCRName(QName name) throws NoPrefixDeclaredException;
 }

Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/SessionNamespaceResolver.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/SessionNamespaceResolver.java?rev=314827&r1=314826&r2=314827&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/SessionNamespaceResolver.java
(original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/name/SessionNamespaceResolver.java
Wed Oct 12 02:04:31 2005
@@ -24,7 +24,7 @@
  * helper class that exposes the <code>NamespaceResolver</code>
  * interface on a <code>Session</code>
  */
-public class SessionNamespaceResolver implements NamespaceResolver {
+public class SessionNamespaceResolver extends AbstractNamespaceResolver {
 
     /**
      * the session for the namespace lookups

Modified: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/name/PathTest.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/name/PathTest.java?rev=314827&r1=314826&r2=314827&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/name/PathTest.java (original)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/name/PathTest.java Wed Oct 12
02:04:31 2005
@@ -43,7 +43,7 @@
     public PathTest() {
 
         // create dummy namespace resolver
-        resolver = new NamespaceResolver(){
+        resolver = new AbstractNamespaceResolver(){
             public String getURI(String prefix) {
                 return prefix;
             }

Modified: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/name/QNameTest.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/name/QNameTest.java?rev=314827&r1=314826&r2=314827&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/name/QNameTest.java (original)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/name/QNameTest.java Wed Oct
12 02:04:31 2005
@@ -37,7 +37,7 @@
     public QNameTest() {
 
         // create dummy namespace resolver
-        resolver = new NamespaceResolver(){
+        resolver = new AbstractNamespaceResolver(){
             public String getURI(String prefix) {
                 return prefix;
             }



Mime
View raw message