Index: java/org/apache/jackrabbit/core/SessionImpl.java
===================================================================
--- java/org/apache/jackrabbit/core/SessionImpl.java (revision 293275)
+++ java/org/apache/jackrabbit/core/SessionImpl.java (working copy)
@@ -171,6 +171,11 @@
protected final LocalNamespaceMappings nsMappings;
/**
+ * The QName resolver for this session.
+ */
+ protected final CachingQNameResolver nameResolver;
+
+ /**
* The version manager for this session
*/
protected final VersionManager versionMgr;
@@ -235,6 +240,7 @@
}
this.subject = subject;
nsMappings = new LocalNamespaceMappings(rep.getNamespaceRegistry());
+ nameResolver = new CachingQNameResolver(rep.getNamespaceRegistry(), nsMappings, 1000);
ntMgr = new NodeTypeManagerImpl(rep.getNodeTypeRegistry(), getNamespaceResolver());
String wspName = wspConfig.getName();
wsp = createWorkspaceInstance(wspConfig,
@@ -376,6 +382,15 @@
}
/**
+ * Returns the QNameResolver of this session.
+ *
+ * @return the QNameResolver of this session.
+ */
+ public QNameResolver getQNameResolver() {
+ return nameResolver;
+ }
+
+ /**
* Returns the SessionItemStateManager associated with this session.
*
* @return the SessionItemStateManager associated with this session
@@ -1117,6 +1132,8 @@
// notify listeners that session is about to be closed
notifyLoggingOut();
+ // dispose caching name resolver
+ nameResolver.dispose();
// dispose session item state manager
itemStateMgr.dispose();
// dispose item manager
@@ -1192,6 +1209,7 @@
public void setNamespacePrefix(String prefix, String uri)
throws NamespaceException, RepositoryException {
nsMappings.setNamespacePrefix(prefix, uri);
+ nameResolver.prefixRemapped(prefix, uri);
}
/**
Index: java/org/apache/jackrabbit/core/PropertyImpl.java
===================================================================
--- java/org/apache/jackrabbit/core/PropertyImpl.java (revision 293275)
+++ java/org/apache/jackrabbit/core/PropertyImpl.java (working copy)
@@ -160,7 +160,7 @@
case PropertyType.NAME:
QName name = (QName) value.internalValue();
try {
- return name.toJCRName(session.getNamespaceResolver()).length();
+ return session.getQNameResolver().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.getQNameResolver().getJCRName(name);
} catch (NoPrefixDeclaredException npde) {
// should never get here...
String msg = "internal error: encountered unregistered namespace " + name.getNamespaceURI();
Index: java/org/apache/jackrabbit/core/NodeImpl.java
===================================================================
--- java/org/apache/jackrabbit/core/NodeImpl.java (revision 293275)
+++ java/org/apache/jackrabbit/core/NodeImpl.java (working copy)
@@ -402,7 +402,7 @@
throws ConstraintViolationException, RepositoryException {
QName qName;
try {
- qName = QName.fromJCRName(name, session.getNamespaceResolver());
+ qName = session.getQNameResolver().getQName(name);
} catch (IllegalNameException ine) {
throw new RepositoryException("invalid property name: " + name, ine);
} catch (UnknownPrefixException upe) {
@@ -560,7 +560,7 @@
protected void removeChildProperty(String propName) throws RepositoryException {
QName qName;
try {
- qName = QName.fromJCRName(propName, session.getNamespaceResolver());
+ qName = session.getQNameResolver().getQName(propName);
} catch (IllegalNameException ine) {
throw new RepositoryException("invalid property name: "
+ propName, ine);
@@ -1674,7 +1674,7 @@
QName name = session.getHierarchyManager().getName(id);
try {
- return name.toJCRName(session.getNamespaceResolver());
+ return session.getQNameResolver().getJCRName(name);
} catch (NoPrefixDeclaredException npde) {
// should never get here...
String msg = "internal error: encountered unregistered namespace "
@@ -2363,7 +2363,7 @@
public boolean isNodeType(String nodeTypeName) throws RepositoryException {
QName ntName;
try {
- ntName = QName.fromJCRName(nodeTypeName, session.getNamespaceResolver());
+ ntName = session.getQNameResolver().getQName(nodeTypeName);
} catch (IllegalNameException ine) {
throw new RepositoryException("invalid node type name: " + nodeTypeName, ine);
} catch (UnknownPrefixException upe) {
@@ -2410,7 +2410,7 @@
ConstraintViolationException, LockException, RepositoryException {
QName ntName;
try {
- ntName = QName.fromJCRName(mixinName, session.getNamespaceResolver());
+ ntName = session.getQNameResolver().getQName(mixinName);
} catch (IllegalNameException ine) {
throw new RepositoryException("invalid mixin type name: " + mixinName, ine);
} catch (UnknownPrefixException upe) {
@@ -2428,7 +2428,7 @@
ConstraintViolationException, LockException, RepositoryException {
QName ntName;
try {
- ntName = QName.fromJCRName(mixinName, session.getNamespaceResolver());
+ ntName = session.getQNameResolver().getQName(mixinName);
} catch (IllegalNameException ine) {
throw new RepositoryException("invalid mixin type name: " + mixinName, ine);
} catch (UnknownPrefixException upe) {
@@ -2463,7 +2463,7 @@
QName ntName;
try {
- ntName = QName.fromJCRName(mixinName, session.getNamespaceResolver());
+ ntName = session.getQNameResolver().getQName(mixinName);
} catch (IllegalNameException ine) {
throw new RepositoryException("invalid mixin type name: "
+ mixinName, ine);
Index: java/org/apache/jackrabbit/core/NamespaceRegistryImpl.java
===================================================================
--- java/org/apache/jackrabbit/core/NamespaceRegistryImpl.java (revision 293275)
+++ java/org/apache/jackrabbit/core/NamespaceRegistryImpl.java (working copy)
@@ -34,6 +34,7 @@
import java.util.HashSet;
import java.util.Iterator;
import java.util.Properties;
+import java.util.Set;
/**
* A NamespaceRegistryImpl ...
@@ -72,6 +73,8 @@
private HashMap prefixToURI = new HashMap();
private HashMap uriToPrefix = new HashMap();
+ private Set listeners = new HashSet();
+
private final FileSystem nsRegStore;
/**
@@ -197,6 +200,51 @@
return "_pre" + (prefixToURI.size() + 1);
}
+ //----------------------< NamespaceRegistryListener support >---------------
+
+ /**
+ * Registers listener to get notifications when namespace
+ * mappings change.
+ *
+ * @param listener the listener to register.
+ */
+ public void addListener(NamespaceRegistryListener listener) {
+ synchronized (listeners) {
+ listeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes the listener from this NamespaceRegistery.
+ *
+ * @param listener the listener to remove.
+ */
+ public void removeListener(NamespaceRegistryListener listener) {
+ 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) {
+ NamespaceRegistryListener[] currentListeners;
+ synchronized (listeners) {
+ int i = 0;
+ currentListeners = new NamespaceRegistryListener[listeners.size()];
+ for (Iterator it = listeners.iterator(); it.hasNext(); ) {
+ currentListeners[i++] = (NamespaceRegistryListener) it.next();
+ }
+ }
+ for (int i = 0; i < currentListeners.length; i++) {
+ currentListeners[i].prefixRemapped(prefix, uri);
+ }
+ }
+
//----------------------------------------------------< NamespaceRegistry >
/**
* {@inheritDoc}
@@ -257,6 +305,9 @@
// persist mappings
store();
+
+ // notify listeners
+ notifyPrefixRemapped(prefix, uri);
}
/**
Index: java/org/apache/jackrabbit/core/QNameResolver.java
===================================================================
--- java/org/apache/jackrabbit/core/QNameResolver.java (revision 0)
+++ java/org/apache/jackrabbit/core/QNameResolver.java (revision 0)
@@ -0,0 +1,47 @@
+/*
+ * 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.core;
+
+import org.apache.jackrabbit.name.QName;
+import org.apache.jackrabbit.name.IllegalNameException;
+import org.apache.jackrabbit.name.UnknownPrefixException;
+import org.apache.jackrabbit.name.NoPrefixDeclaredException;
+
+/**
+ * Maps QNames to resolved jcr names and vice versa.
+ */
+public interface QNameResolver {
+
+ /**
+ * 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;
+}
Property changes on: java/org/apache/jackrabbit/core/QNameResolver.java
___________________________________________________________________
Name: svn:eol-style
+ native
Index: java/org/apache/jackrabbit/core/CachingQNameResolver.java
===================================================================
--- java/org/apache/jackrabbit/core/CachingQNameResolver.java (revision 0)
+++ java/org/apache/jackrabbit/core/CachingQNameResolver.java (revision 0)
@@ -0,0 +1,117 @@
+/*
+ * 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.core;
+
+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.commons.collections.map.LRUMap;
+
+import java.util.Map;
+
+/**
+ * Implements a {@link QNameResolver} that caches QName to resolved jcr names
+ * and vice versa. The cache is invalidated when a namespace uri to prefix
+ * mapping is changed.
+ */
+class CachingQNameResolver implements QNameResolver, NamespaceRegistryListener {
+
+ /**
+ * The namespace registry.
+ */
+ private final NamespaceRegistryImpl nsRegistry;
+
+ /**
+ * The namespace resolver of current session.
+ */
+ private final NamespaceResolver resolver;
+
+ /**
+ * 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 CachingQNameResolver.
+ *
+ * @param nsReg the global namespace registry.
+ * @param resolver the namespace resolver of the current session.
+ * @param cacheSize number of mappings this resolver may cache.
+ */
+ CachingQNameResolver(NamespaceRegistryImpl nsReg, NamespaceResolver resolver, int cacheSize) {
+ this.nsRegistry = nsReg;
+ this.resolver = resolver;
+ qnameToJCRName = new LRUMap(cacheSize);
+ jcrNameToQName = new LRUMap(cacheSize);
+ nsRegistry.addListener(this);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public synchronized QName getQName(String name) throws IllegalNameException, UnknownPrefixException {
+ if (false) {
+ return QName.fromJCRName(name, resolver);
+ }
+ QName qName = (QName) jcrNameToQName.get(name);
+ if (qName == null) {
+ qName = QName.fromJCRName(name, resolver);
+ jcrNameToQName.put(name, qName);
+ }
+ return qName;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public synchronized String getJCRName(QName name) throws NoPrefixDeclaredException {
+ if (false) {
+ return name.toJCRName(resolver);
+ }
+ String jcrName = (String) qnameToJCRName.get(name);
+ if (jcrName == null) {
+ jcrName = name.toJCRName(resolver);
+ qnameToJCRName.put(name, jcrName);
+ }
+ return jcrName;
+ }
+
+ /**
+ * Disposes this CachingQNameResolver.
+ */
+ public void dispose() {
+ nsRegistry.removeListener(this);
+ }
+
+ //---------------------< NamespaceRegistryListener >------------------------
+
+ /**
+ * @inheritDoc
+ * Invalidates all cached mappings.
+ */
+ public synchronized void prefixRemapped(String prefix, String uri) {
+ qnameToJCRName.clear();
+ jcrNameToQName.clear();
+ }
+}
Property changes on: java/org/apache/jackrabbit/core/CachingQNameResolver.java
___________________________________________________________________
Name: svn:eol-style
+ native
Index: java/org/apache/jackrabbit/core/NamespaceRegistryListener.java
===================================================================
--- java/org/apache/jackrabbit/core/NamespaceRegistryListener.java (revision 0)
+++ java/org/apache/jackrabbit/core/NamespaceRegistryListener.java (revision 0)
@@ -0,0 +1,33 @@
+/*
+ * 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.core;
+
+/**
+ * Receives notifications when a namespace mapping changes in a namespace
+ * registry.
+ */
+public interface NamespaceRegistryListener {
+
+ /**
+ * Informs that the namespace registry has remapped the uri to
+ * the new prefix.
+ *
+ * @param prefix the new prefix for uri.
+ * @param uri the namespace uri.
+ */
+ public void prefixRemapped(String prefix, String uri);
+}
Property changes on: java/org/apache/jackrabbit/core/NamespaceRegistryListener.java
___________________________________________________________________
Name: svn:eol-style
+ native