You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jackrabbit.apache.org by Stefan Guggisberg <st...@gmail.com> on 2005/10/12 11:08:57 UTC
Re: 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
sorry, forgot the commit msg:
JCR-235 Cache jcr name to QName mappings
On 10/12/05, stefan@apache.org <st...@apache.org> wrote:
> 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;
> }
>
>
>
Re: 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
Posted by Stefan Guggisberg <st...@gmail.com>.
On 10/12/05, Marcel Reutegger <ma...@gmail.com> wrote:
> LOL
:-)
>
> thanks for applying the patch...
>
> btw. what's the feeling about caching remapped namespace uris in the
> session? I think we should remove it again, because it adds complexity
> for a feature which is not used in most cases.
i agree, +1 for removing it.
cheers
stefan
>
> regards
> marcel
>
> Stefan Guggisberg wrote:
> > sorry, forgot the commit msg:
> >
> > JCR-235 Cache jcr name to QName mappings
>
Re: 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
Posted by Marcel Reutegger <ma...@gmail.com>.
LOL
thanks for applying the patch...
btw. what's the feeling about caching remapped namespace uris in the
session? I think we should remove it again, because it adds complexity
for a feature which is not used in most cases.
regards
marcel
Stefan Guggisberg wrote:
> sorry, forgot the commit msg:
>
> JCR-235 Cache jcr name to QName mappings