X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=server%2Fruntime%2Forg.argeo.server.jcr%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fjcr%2FJcrUtils.java;h=6871e60c76a57a1f1479aff03003f246596315b9;hb=7fe4a16dad045373bb014724733c1bbb175d44b5;hp=d70a51669f7dcf8bfa78f5b691cd1ed9e85a15e2;hpb=5b81c294ae7541cc6a2a5867d1e1e8aa7f4358b5;p=lgpl%2Fargeo-commons.git diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java index d70a51669..6871e60c7 100644 --- a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java +++ b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java @@ -16,15 +16,20 @@ 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.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; @@ -33,6 +38,7 @@ import javax.jcr.PropertyIterator; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.Value; +import javax.jcr.nodetype.NodeType; import javax.jcr.query.Query; import javax.jcr.query.QueryResult; @@ -96,6 +102,27 @@ 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 + String[] hostTokens = u.getHost().split("\\."); + for (int i = hostTokens.length - 1; i >= 0; i--) + path.append(hostTokens[i]).append('/'); + // 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); + } + } + /** * The provided data as a path ('/' at the end, not the beginning) * @@ -164,12 +191,30 @@ 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. */ + public static Node mkdirs(Session session, String path, String type, + String intermediaryNodeType, Boolean versioning) { try { if (path.equals('/')) return session.getRootNode(); @@ -194,12 +239,15 @@ 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 { @@ -260,7 +308,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; } @@ -425,6 +473,56 @@ public class JcrUtils { } } + /** + * Compare only a restricted list of properties of two nodes. No + * recursivity. + * + */ + public static Map diffProperties(Node reference, + Node observed, List properties) { + Map diffs = new TreeMap(); + try { + Iterator pit = properties.iterator(); + + props: while (pit.hasNext()) { + String name = pit.next(); + if (!reference.hasProperty(name)) { + if (!observed.hasProperty(name)) + continue props; + Value val = observed.getProperty(name).getValue(); + try { + // empty String but not null + if ("".equals(val.getString())) + continue props; + } catch (Exception e) { + // not parseable as String, silent + } + PropertyDiff pDiff = new PropertyDiff(PropertyDiff.ADDED, + name, null, val); + diffs.put(name, pDiff); + } else if (!observed.hasProperty(name)) { + PropertyDiff pDiff = new PropertyDiff(PropertyDiff.REMOVED, + name, reference.getProperty(name).getValue(), null); + diffs.put(name, pDiff); + } else { + Value referenceValue = reference.getProperty(name) + .getValue(); + Value newValue = observed.getProperty(name).getValue(); + if (!referenceValue.equals(newValue)) { + PropertyDiff pDiff = new PropertyDiff( + PropertyDiff.MODIFIED, name, referenceValue, + newValue); + diffs.put(name, pDiff); + } + } + } + } catch (RepositoryException e) { + throw new ArgeoException("Cannot diff " + reference + " and " + + observed, e); + } + return diffs; + } + /** Builds a property relPath to be used in the diff. */ private static String propertyRelPath(String baseRelPath, String propertyName) { @@ -433,4 +531,18 @@ 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(':', '_'); + } + + public static void closeQuietly(Binary binary) { + if (binary == null) + return; + binary.dispose(); + } }