You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2008/05/12 19:15:01 UTC
svn commit: r655567 -
/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractSession.java
Author: jukka
Date: Mon May 12 10:15:01 2008
New Revision: 655567
URL: http://svn.apache.org/viewvc?rev=655567&view=rev
Log:
JCR-1564: JSR 283 namespace handling
- JSR 283 -based namespace handling in AbstractSession
Modified:
jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractSession.java
Modified: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractSession.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractSession.java?rev=655567&r1=655566&r2=655567&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractSession.java (original)
+++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/AbstractSession.java Mon May 12 10:15:01 2008
@@ -19,10 +19,15 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
import javax.jcr.Credentials;
import javax.jcr.InvalidSerializedDataException;
import javax.jcr.Item;
+import javax.jcr.NamespaceException;
+import javax.jcr.NamespaceRegistry;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.Repository;
@@ -38,6 +43,7 @@
import javax.xml.transform.stream.StreamResult;
import org.apache.jackrabbit.commons.xml.ParsingContentHandler;
+import org.apache.jackrabbit.util.XMLChar;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
@@ -47,6 +53,159 @@
public abstract class AbstractSession implements Session {
/**
+ * Local namespace mappings. Prefixes as keys and namespace URIs as values.
+ */
+ private final Map namespaces = new HashMap();
+
+ //------------------------------------------------< Namespace handling >--
+
+ /**
+ * Returns the namespace prefix mapped to the given URI. The mapping is
+ * added to the set of session-local namespace mappings unless it already
+ * exists there.
+ * <p>
+ * This behaviour is based on JSR 283 (JCR 2.0), but remains backwards
+ * compatible with JCR 1.0.
+ *
+ * @param uri namespace URI
+ * @return namespace prefix
+ * @throws NamespaceException if the namespace is not found
+ * @throws RepositoryException if a repository error occurs
+ */
+ public String getNamespacePrefix(String uri)
+ throws NamespaceException, RepositoryException {
+ Iterator iterator = namespaces.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry entry = (Map.Entry) iterator.next();
+ if (entry.getValue().equals(uri)) {
+ return (String) entry.getKey();
+ }
+ }
+
+ // The following throws an exception if the URI is not found, that's OK
+ String prefix = getWorkspace().getNamespaceRegistry().getPrefix(uri);
+
+ // Generate a new prefix if the global mapping is already taken
+ String base = prefix;
+ for (int i = 2; namespaces.containsKey(prefix); i++) {
+ prefix = base + i;
+ }
+
+ namespaces.put(prefix, uri);
+ return prefix;
+ }
+
+ /**
+ * Returns the namespace URI mapped to the given prefix. The mapping is
+ * added to the set of session-local namespace mappings unless it already
+ * exists there.
+ * <p>
+ * This behaviour is based on JSR 283 (JCR 2.0), but remains backwards
+ * compatible with JCR 1.0.
+ *
+ * @param prefix namespace prefix
+ * @return namespace URI
+ * @throws NamespaceException if the namespace is not found
+ * @throws RepositoryException if a repository error occurs
+ */
+ public String getNamespaceURI(String prefix)
+ throws NamespaceException, RepositoryException {
+ String uri = (String) namespaces.get(prefix);
+
+ if (uri == null) {
+ // Not in local mappings, try the global ones
+ uri = getWorkspace().getNamespaceRegistry().getURI(prefix);
+ if (namespaces.containsValue(uri)) {
+ // The global URI is locally mapped to some other prefix,
+ // so there are no mappings for this prefix
+ throw new NamespaceException("Namespace not found: " + prefix);
+ }
+ // Add the mapping to the local set, we already know that
+ // the prefix is not taken
+ namespaces.put(prefix, uri);
+ }
+
+ return uri;
+ }
+
+ /**
+ * Returns the prefixes of all known namespace mappings. All global
+ * mappings not already included in the local set of namespace mappings
+ * are added there.
+ * <p>
+ * This behaviour is based on JSR 283 (JCR 2.0), but remains backwards
+ * compatible with JCR 1.0.
+ *
+ * @return namespace prefixes
+ * @throws RepositoryException if a repository error occurs
+ */
+ public String[] getNamespacePrefixes() throws RepositoryException {
+ NamespaceRegistry registry = getWorkspace().getNamespaceRegistry();
+ String[] uris = registry.getURIs();
+ for (int i = 0; i < uris.length; i++) {
+ getNamespacePrefix(uris[i]);
+ }
+
+ return (String[])
+ namespaces.keySet().toArray(new String[namespaces.size()]);
+ }
+
+ /**
+ * Modifies the session local namespace mappings to contain the given
+ * prefix to URI mapping.
+ * <p>
+ * This behaviour is based on JSR 283 (JCR 2.0), but remains backwards
+ * compatible with JCR 1.0.
+ *
+ * @param prefix namespace prefix
+ * @param uri namespace URI
+ * @throws NamespaceException if the mapping is illegal
+ * @throws RepositoryException if a repository error occurs
+ */
+ public void setNamespacePrefix(String prefix, String uri)
+ throws NamespaceException, RepositoryException {
+ if (prefix == null) {
+ throw new IllegalArgumentException("Prefix must not be null");
+ } else if (uri == null) {
+ throw new IllegalArgumentException("Namespace must not be null");
+ } else if (prefix.length() == 0) {
+ throw new NamespaceException(
+ "Empty prefix is reserved and can not be remapped");
+ } else if (uri.length() == 0) {
+ throw new NamespaceException(
+ "Default namespace is reserved and can not be remapped");
+ } else if (prefix.toLowerCase().startsWith("xml")) {
+ throw new NamespaceException(
+ "XML prefixes are reserved: " + prefix);
+ } else if (!XMLChar.isValidNCName(prefix)) {
+ throw new NamespaceException(
+ "Prefix is not a valid XML NCName: " + prefix);
+ }
+
+ // FIXME Figure out how this should be handled
+ // Currently JSR 283 does not specify this exception, but for
+ // compatibility with JCR 1.0 TCK it probably should.
+ // Note that the solution here also affects the remove() code below
+ String previous = (String) namespaces.get(prefix);
+ if (previous != null && !previous.equals(uri)) {
+ throw new NamespaceException("Namespace already mapped");
+ }
+
+ namespaces.remove(prefix);
+ Iterator iterator = namespaces.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry entry = (Map.Entry) iterator.next();
+ if (entry.getValue().equals(uri)) {
+ iterator.remove();
+ }
+ }
+
+ namespaces.put(prefix, uri);
+ }
+
+ //---------------------------------------------< XML export and import >--
+
+ /**
* Calls {@link Session#exportDocumentView(String, ContentHandler, boolean, boolean)}
* with the given arguments and a {@link ContentHandler} that serializes
* SAX events to the given output stream.
@@ -142,6 +301,8 @@
}
}
+ //-----------------------------------------------------< Item handling >--
+
/**
* Returns the node or property at the given path.
* <p>
@@ -200,6 +361,8 @@
}
}
+ //--------------------------------------------------< Session handling >--
+
/**
* Logs in the same workspace with the given credentials.
* <p>