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/16 14:20:55 UTC

svn commit: r657026 - /jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/NamespaceHelper.java

Author: jukka
Date: Fri May 16 05:20:54 2008
New Revision: 657026

URL: http://svn.apache.org/viewvc?rev=657026&view=rev
Log:
JCR-1607: Add a NamespaceHelper in jcr-commons
    - Added the NamespaceHelper class

Added:
    jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/NamespaceHelper.java

Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/NamespaceHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/NamespaceHelper.java?rev=657026&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/NamespaceHelper.java (added)
+++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/NamespaceHelper.java Fri May 16 05:20:54 2008
@@ -0,0 +1,243 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.commons;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.jcr.NamespaceException;
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.jackrabbit.util.XMLChar;
+
+/**
+ * Helper class for working with JCR namespaces.
+ *
+ * @since Jackrabbit JCR Commons 1.5
+ */
+public class NamespaceHelper {
+
+    /**
+     * The <code>jcr</code> namespace URI.
+     */
+    public static final String JCR = "http://www.jcp.org/jcr/1.0";
+
+    /**
+     * The <code>nt</code> namespace URI.
+     */
+    public static final String NT = "http://www.jcp.org/jcr/nt/1.0";
+
+    /**
+     * The <code>mix</code> namespace URI.
+     */
+    public static final String MIX = "http://www.jcp.org/jcr/mix/1.0";
+
+    /**
+     * Current session.
+     */
+    private final Session session;
+
+    /**
+     * Creates a namespace helper for the given session.
+     *
+     * @param session current session
+     */
+    public NamespaceHelper(Session session) {
+        this.session = session;
+    }
+
+    /**
+     * Returns a map containing all prefix to namespace URI mappings of
+     * the current session. The returned map is newly allocated and can
+     * can be freely modified by the caller.
+     *
+     * @see Session#getNamespacePrefixes()
+     * @return namespace mappings
+     * @throws RepositoryException if the namespaces could not be retrieved
+     */
+    public Map getNamespaces() throws RepositoryException {
+        Map namespaces = new HashMap();
+        String[] prefixes = session.getNamespacePrefixes();
+        for (int i = 0; i < prefixes.length; i++) {
+            namespaces.put(prefixes[i], session.getNamespaceURI(prefixes[i]));
+        }
+        return namespaces;
+    }
+
+    /**
+     * Returns the prefix mapped to the given namespace URI in the current
+     * session, or <code>null</code> if the namespace does not exist.
+     *
+     * @see Session#getNamespacePrefix(String)
+     * @param uri namespace URI
+     * @return namespace prefix, or <code>null</code>
+     * @throws RepositoryException if the namespace could not be retrieved
+     */
+    public String getPrefix(String uri) throws RepositoryException {
+        try {
+            return session.getNamespacePrefix(uri);
+        } catch (NamespaceException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the namespace URI mapped to the given prefix in the current
+     * session, or <code>null</code> if the namespace does not exist.
+     *
+     * @see Session#getNamespaceURI(String)
+     * @param uri namespace URI
+     * @return namespace prefix, or <code>null</code>
+     * @throws RepositoryException if the namespace could not be retrieved
+     */
+    public String getURI(String prefix) throws RepositoryException {
+        try {
+            return session.getNamespaceURI(prefix);
+        } catch (NamespaceException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the prefixed JCR name for the given namespace URI and local
+     * name in the current session.
+     *
+     * @param uri namespace URI
+     * @param name local name
+     * @return prefixed JCR name
+     * @throws NamespaceException if the namespace does not exist
+     * @throws RepositoryException if the namespace could not be retrieved
+     */
+    public String getJcrName(String uri, String name)
+            throws NamespaceException, RepositoryException {
+        if (uri != null && uri.length() > 0) {
+            return session.getNamespacePrefix(uri) + ":" + name;
+        } else {
+            return name;
+        }
+    }
+
+    /**
+     * Replaces the standard <code>jcr</code>, <code>nt</code>, or
+     * <code>mix</code> prefix in the given name with the prefix
+     * mapped to that namespace in the current session.
+     * <p>
+     * The purpose of this method is to make it easier to write
+     * namespace-aware code that uses names in the standard JCR namespaces.
+     * For example:
+     * <pre>
+     *     node.getProperty(helper.getName("jcr:data"));
+     * </pre>
+     *
+     * @param name prefixed name using the standard JCR prefixes
+     * @return prefixed name using the current session namespace mappings
+     * @throws IllegalArgumentException if the prefix is unknown
+     * @throws RepositoryException if the namespace could not be retrieved
+     */
+    public String getJcrName(String name)
+            throws IllegalArgumentException, RepositoryException {
+        String standardPrefix;
+        String currentPrefix;
+
+        if (name.startsWith("jcr:")) {
+            standardPrefix = "jcr";
+            currentPrefix = session.getNamespacePrefix(JCR);
+        } else if (name.startsWith("nt:")) {
+            standardPrefix = "nt";
+            currentPrefix = session.getNamespacePrefix(NT);
+        } else if (name.startsWith("mix:")) {
+            standardPrefix = "mix";
+            currentPrefix = session.getNamespacePrefix(MIX);
+        } else {
+            throw new IllegalArgumentException("Unknown prefix: " + name);
+        }
+
+        if (currentPrefix.equals(standardPrefix)) {
+            return name;
+        } else {
+            return currentPrefix + name.substring(standardPrefix.length());
+        }
+    }
+
+    /**
+     * Safely registers the given namespace. If the namespace already exists,
+     * then the prefix mapped to the namespace in the current session is
+     * returned. Otherwise the namespace is registered to the namespace
+     * registry. If the given prefix is already registered for some other
+     * namespace or otherwise invalid, then another prefix is automatically
+     * generated. After the namespace has been registered, the prefix mapped
+     * to it in the current session is returned.
+     *
+     * @see NamespaceRegistry#registerNamespace(String, String)
+     * @param prefix namespace prefix
+     * @param uri namespace URI
+     * @return namespace prefix in the current session
+     * @throws RepositoryException if the namespace could not be registered
+     */
+    public String registerNamespace(String prefix, String uri)
+            throws RepositoryException {
+        NamespaceRegistry registry =
+            session.getWorkspace().getNamespaceRegistry();
+        try {
+            // Check if the namespace is registered
+            registry.getPrefix(uri);
+        } catch (NamespaceException e1) {
+             // Replace troublesome prefix hints
+            if (prefix == null || prefix.length() == 0
+                    || prefix.toLowerCase().startsWith("xml")
+                    || !XMLChar.isValidNCName(prefix)) {
+                prefix = "ns"; // ns, ns2, ns3, ns4, ...
+            }
+
+            // Loop until an unused prefix is found
+            try {
+                String base = prefix;
+                for (int i = 2; true; i++) {
+                    registry.getURI(prefix);
+                    prefix = base + i;
+                }
+            } catch (NamespaceException e2) {
+                // Exit the loop
+            } 
+
+            // Register the namespace
+            registry.registerNamespace(prefix, uri);
+        }
+
+        return session.getNamespacePrefix(uri);
+    }
+
+    /**
+     * Safely registers all namespaces in the given map from
+     * prefixes to namespace URIs.
+     *
+     * @param namespaces namespace mappings
+     * @throws RepositoryException if the namespaces could not be registered
+     */
+    public void registerNamespaces(Map namespaces) throws RepositoryException {
+        Iterator iterator = namespaces.entrySet().iterator();
+        while (iterator.hasNext()) {
+            Map.Entry entry = (Map.Entry) iterator.next();
+            registerNamespace(
+                    (String) entry.getKey(), (String) entry.getValue());
+        }
+    }
+
+}