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=760e6600969e9e5666468e47afe1cd230be7bc1b;hb=70538e1286a2b47ecd58cb1cfb7ede8dddff5859;hp=1cecd7100611744524da8e08296dbc49f00b935a;hpb=e890c9d9d57069b464b406405797f38e7263f3b1;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 1cecd7100..760e66009 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,6 +16,9 @@ package org.argeo.jcr; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.text.DateFormat; @@ -52,6 +55,7 @@ import javax.jcr.query.qom.QueryObjectModelFactory; import javax.jcr.query.qom.Selector; import javax.jcr.query.qom.StaticOperand; +import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.ArgeoException; @@ -225,8 +229,9 @@ public class JcrUtils implements ArgeoJcrConstants { } /** - * @deprecated use {@link #mkdirs(Session, String, String, String, Boolean)} - * instead. + * use {@link #mkdirs(Session, String, String, String, Boolean)} instead. + * + * @deprecated */ @Deprecated public static Node mkdirs(Session session, String path, String type, @@ -659,6 +664,43 @@ public class JcrUtils implements ArgeoJcrConstants { binary.dispose(); } + /** Retrieve a {@link Binary} as a byte array */ + public static byte[] getBinaryAsBytes(Property property) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + InputStream in = null; + Binary binary = null; + try { + binary = property.getBinary(); + in = binary.getStream(); + IOUtils.copy(in, out); + return out.toByteArray(); + } catch (Exception e) { + throw new ArgeoException("Cannot read binary " + property + + " as bytes", e); + } finally { + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(in); + closeQuietly(binary); + } + } + + /** Writes a {@link Binary} from a byte array */ + public static void setBinaryAsBytes(Node node, String property, byte[] bytes) { + InputStream in = null; + Binary binary = null; + try { + in = new ByteArrayInputStream(bytes); + binary = node.getSession().getValueFactory().createBinary(in); + node.setProperty(property, binary); + } catch (Exception e) { + throw new ArgeoException("Cannot read binary " + property + + " as bytes", e); + } finally { + IOUtils.closeQuietly(in); + closeQuietly(binary); + } + } + /** * Creates depth from a string (typically a username) by adding levels based * on its first characters: "aBcD",2 => a/aB @@ -847,15 +889,35 @@ public class JcrUtils implements ArgeoJcrConstants { if (session.hasPendingChanges()) throw new ArgeoException( "Session has pending changes, save them first"); + String homePath = homeBasePath + '/' + firstCharsToPath(username, 2) + '/' + username; - Node userHome = JcrUtils.mkdirs(session, homePath); - Node userProfile = userHome.addNode(ArgeoNames.ARGEO_PROFILE); - userProfile.addMixin(ArgeoTypes.ARGEO_USER_PROFILE); - userProfile.setProperty(ArgeoNames.ARGEO_USER_ID, username); - session.save(); - // we need to save the profile before adding the user home type + if (session.itemExists(homePath)) { + try { + throw new ArgeoException( + "Trying to create a user home that already exists"); + } catch (Exception e) { + // we use this workaround to be sure to get the stack trace + // to identify the sink of the bug. + log.warn("trying to create an already existing userHome at path:" + + homePath + ". Stack trace : "); + e.printStackTrace(); + } + } + + Node userHome = JcrUtils.mkdirs(session, homePath); + Node userProfile; + if (userHome.hasNode(ArgeoNames.ARGEO_PROFILE)) { + log.warn("userProfile node already exists for userHome path: " + + homePath + ". We do not add a new one"); + } else { + userProfile = userHome.addNode(ArgeoNames.ARGEO_PROFILE); + userProfile.addMixin(ArgeoTypes.ARGEO_USER_PROFILE); + userProfile.setProperty(ArgeoNames.ARGEO_USER_ID, username); + session.save(); + // we need to save the profile before adding the user home type + } userHome.addMixin(ArgeoTypes.ARGEO_USER_HOME); // see // http://jackrabbit.510166.n4.nabble.com/Jackrabbit-2-0-beta-6-Problem-adding-a-Mixin-type-with-mandatory-properties-after-setting-propertiesn-td1290332.html @@ -921,4 +983,65 @@ public class JcrUtils implements ArgeoJcrConstants { throw new ArgeoException("Cannot update last modified", e); } } + + /** + * Returns a String representing the short version (see Node type + * Notation attributes grammar) of the main business attributes of this + * property definition + * + * @param prop + */ + public static String getPropertyDefinitionAsString(Property prop) { + StringBuffer sbuf = new StringBuffer(); + try { + if (prop.getDefinition().isAutoCreated()) + sbuf.append("a"); + if (prop.getDefinition().isMandatory()) + sbuf.append("m"); + if (prop.getDefinition().isProtected()) + sbuf.append("p"); + if (prop.getDefinition().isMultiple()) + sbuf.append("*"); + } catch (RepositoryException re) { + throw new ArgeoException( + "unexpected error while getting property definition as String", + re); + } + return sbuf.toString(); + } + + /** + * Estimate the sub tree size from current node. Computation is based on the + * Jcr {@link Property.getLength()} method. Note : it is not the exact size + * used on the disk by the current part of the JCR Tree. + */ + + public static long getNodeApproxSize(Node node) { + long curNodeSize = 0; + try { + PropertyIterator pi = node.getProperties(); + while (pi.hasNext()) { + Property prop = pi.nextProperty(); + if (prop.isMultiple()) { + int nb = prop.getLengths().length; + for (int i = 0; i < nb; i++) { + curNodeSize += (prop.getLengths()[i] > 0 ? prop + .getLengths()[i] : 0); + } + } else + curNodeSize += (prop.getLength() > 0 ? prop.getLength() : 0); + } + + NodeIterator ni = node.getNodes(); + while (ni.hasNext()) + curNodeSize += getNodeApproxSize(ni.nextNode()); + log.debug(node + ": " + curNodeSize); + return curNodeSize; + } catch (RepositoryException re) { + throw new ArgeoException( + "Unexpected error while recursively determining node size.", + re); + } + } }