]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java
Integrate LDAP and JCR
[lgpl/argeo-commons.git] / server / runtime / org.argeo.server.jcr / src / main / java / org / argeo / jcr / JcrUtils.java
index b862e8fc4da2fec04be3bb76a25b6e015cdb37a5..ad6ca0eddb10dd32d95eba289cd8c42bd4435c77 100644 (file)
 
 package org.argeo.jcr;
 
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.GregorianCalendar;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
 import java.util.TreeMap;
 
+import javax.jcr.Binary;
 import javax.jcr.NamespaceRegistry;
 import javax.jcr.Node;
 import javax.jcr.NodeIterator;
 import javax.jcr.Property;
 import javax.jcr.PropertyIterator;
+import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
+import javax.jcr.RepositoryFactory;
 import javax.jcr.Session;
 import javax.jcr.Value;
+import javax.jcr.nodetype.NodeType;
 import javax.jcr.query.Query;
 import javax.jcr.query.QueryResult;
 
@@ -43,7 +50,7 @@ import org.apache.commons.logging.LogFactory;
 import org.argeo.ArgeoException;
 
 /** Utility methods to simplify common JCR operations. */
-public class JcrUtils {
+public class JcrUtils implements ArgeoJcrConstants {
        private final static Log log = LogFactory.getLog(JcrUtils.class);
 
        /**
@@ -98,6 +105,40 @@ public class JcrUtils {
                return dateAsPath(cal, false);
        }
 
+       /**
+        * Creates a deep path based on a URL:
+        * http://subdomain.example.com/to/content?args =>
+        * com/example/subdomain/to/content
+        */
+       public static String urlAsPath(String url) {
+               try {
+                       URL u = new URL(url);
+                       StringBuffer path = new StringBuffer(url.length());
+                       // invert host
+                       path.append(hostAsPath(u.getHost()));
+                       // we don't put port since it may not always be there and may change
+                       path.append(u.getPath());
+                       return path.toString();
+               } catch (MalformedURLException e) {
+                       throw new ArgeoException("Cannot generate URL path for " + url, e);
+               }
+       }
+
+       /**
+        * Creates a path from a FQDN, inverting the order of the component:
+        * www.argeo.org => org.argeo.www
+        */
+       public static String hostAsPath(String host) {
+               StringBuffer path = new StringBuffer(host.length());
+               String[] hostTokens = host.split("\\.");
+               for (int i = hostTokens.length - 1; i >= 0; i--) {
+                       path.append(hostTokens[i]);
+                       if (i != 0)
+                               path.append('/');
+               }
+               return path.toString();
+       }
+
        /**
         * The provided data as a path ('/' at the end, not the beginning)
         * 
@@ -146,13 +187,6 @@ public class JcrUtils {
 
        }
 
-       /** Converts the FQDN of an host into a path (converts '.' into '/'). */
-       public static String hostAsPath(String host) {
-               // TODO : inverse order of the elements (to have org/argeo/test IO
-               // test/argeo/org
-               return host.replace('.', '/');
-       }
-
        /** The last element of a path. */
        public static String lastPathElement(String path) {
                if (path.charAt(path.length() - 1) == '/')
@@ -166,12 +200,33 @@ public class JcrUtils {
 
        /** Creates the nodes making path, if they don't exist. */
        public static Node mkdirs(Session session, String path) {
-               return mkdirs(session, path, null, false);
+               return mkdirs(session, path, null, null, false);
        }
 
-       /** Creates the nodes making path, if they don't exist. */
+       /**
+        * @deprecated use {@link #mkdirs(Session, String, String, String, Boolean)}
+        *             instead.
+        */
+       @Deprecated
        public static Node mkdirs(Session session, String path, String type,
                        Boolean versioning) {
+               return mkdirs(session, path, type, type, false);
+       }
+
+       /**
+        * @param type
+        *            the type of the leaf node
+        */
+       public static Node mkdirs(Session session, String path, String type) {
+               return mkdirs(session, path, type, null, false);
+       }
+
+       /**
+        * Creates the nodes making path, if they don't exist. This is up to the
+        * caller to save the session.
+        */
+       public static Node mkdirs(Session session, String path, String type,
+                       String intermediaryNodeType, Boolean versioning) {
                try {
                        if (path.equals('/'))
                                return session.getRootNode();
@@ -196,19 +251,22 @@ public class JcrUtils {
                                String part = st.nextToken();
                                current.append(part).append('/');
                                if (!session.itemExists(current.toString())) {
-                                       if (type != null)
+                                       if (!st.hasMoreTokens() && type != null)
                                                currentNode = currentNode.addNode(part, type);
+                                       else if (st.hasMoreTokens() && intermediaryNodeType != null)
+                                               currentNode = currentNode.addNode(part,
+                                                               intermediaryNodeType);
                                        else
                                                currentNode = currentNode.addNode(part);
                                        if (versioning)
-                                               currentNode.addMixin(ArgeoJcrConstants.MIX_VERSIONABLE);
+                                               currentNode.addMixin(NodeType.MIX_VERSIONABLE);
                                        if (log.isTraceEnabled())
                                                log.debug("Added folder " + part + " as " + current);
                                } else {
                                        currentNode = (Node) session.getItem(current.toString());
                                }
                        }
-                       session.save();
+                       // session.save();
                        return currentNode;
                } catch (RepositoryException e) {
                        throw new ArgeoException("Cannot mkdirs " + path, e);
@@ -262,7 +320,7 @@ public class JcrUtils {
                        // First output the node path
                        log.debug(node.getPath());
                        // Skip the virtual (and large!) jcr:system subtree
-                       if (node.getName().equals(ArgeoJcrConstants.JCR_SYSTEM)) {
+                       if (node.getName().equals("jcr:system")) {
                                return;
                        }
 
@@ -485,4 +543,74 @@ public class JcrUtils {
                else
                        return baseRelPath + '/' + propertyName;
        }
+
+       /**
+        * Normalize a name so taht it can be stores in contexts not supporting
+        * names with ':' (typically databases). Replaces ':' by '_'.
+        */
+       public static String normalize(String name) {
+               return name.replace(':', '_');
+       }
+
+       /** Cleanly disposes a {@link Binary} even if it is null. */
+       public static void closeQuietly(Binary binary) {
+               if (binary == null)
+                       return;
+               binary.dispose();
+       }
+
+       /**
+        * Creates depth from a string (typically a username) by adding levels based
+        * on its first characters: "aBcD",2 => a/aB
+        */
+       public static String firstCharsToPath(String str, Integer nbrOfChars) {
+               if (str.length() < nbrOfChars)
+                       throw new ArgeoException("String " + str
+                                       + " length must be greater or equal than " + nbrOfChars);
+               StringBuffer path = new StringBuffer("");
+               StringBuffer curr = new StringBuffer("");
+               for (int i = 0; i < nbrOfChars; i++) {
+                       curr.append(str.charAt(i));
+                       path.append(curr);
+                       if (i < nbrOfChars - 1)
+                               path.append('/');
+               }
+               return path.toString();
+       }
+
+       /**
+        * Wraps the call to the repository factory based on parameter
+        * {@link ArgeoJcrConstants#JCR_REPOSITORY_ALIAS} in order to simplify it
+        * and protect against future API changes.
+        */
+       public static Repository getRepositoryByAlias(
+                       RepositoryFactory repositoryFactory, String alias) {
+               try {
+                       Map<String, String> parameters = new HashMap<String, String>();
+                       parameters.put(JCR_REPOSITORY_ALIAS, alias);
+                       return repositoryFactory.getRepository(parameters);
+               } catch (RepositoryException e) {
+                       throw new ArgeoException(
+                                       "Unexpected exception when trying to retrieve repository with alias "
+                                                       + alias, e);
+               }
+       }
+
+       /**
+        * Wraps the call to the repository factory based on parameter
+        * {@link ArgeoJcrConstants#JCR_REPOSITORY_URI} in order to simplify it and
+        * protect against future API changes.
+        */
+       public static Repository getRepositoryByUri(
+                       RepositoryFactory repositoryFactory, String uri) {
+               try {
+                       Map<String, String> parameters = new HashMap<String, String>();
+                       parameters.put(JCR_REPOSITORY_URI, uri);
+                       return repositoryFactory.getRepository(parameters);
+               } catch (RepositoryException e) {
+                       throw new ArgeoException(
+                                       "Unexpected exception when trying to retrieve repository with uri "
+                                                       + uri, e);
+               }
+       }
 }