+ private void copyTimestamp(Node sourceNode, Node targetNode, String property)
+ throws RepositoryException {
+ if (sourceNode.hasProperty(property)) {
+ Property p = sourceNode.getProperty(property);
+ if (p.getDefinition().isProtected())
+ return;
+ if (targetNode.hasProperty(property)
+ && targetNode
+ .getProperty(property)
+ .getValue()
+ .equals(sourceNode.getProperty(property).getValue()))
+ return;
+ targetNode.setProperty(property, sourceNode.getProperty(property)
+ .getValue());
+ }
+ }
+
+ private void copyProperties(Node sourceNode, Node targetNode)
+ throws RepositoryException {
+ properties: for (PropertyIterator pi = sourceNode.getProperties(); pi
+ .hasNext();) {
+ Property p = pi.nextProperty();
+ if (p.getDefinition().isProtected())
+ continue properties;
+ if (p.getName().equals(Property.JCR_CREATED)
+ || p.getName().equals(Property.JCR_CREATED_BY)
+ || p.getName().equals(Property.JCR_LAST_MODIFIED)
+ || p.getName().equals(Property.JCR_LAST_MODIFIED_BY))
+ continue properties;
+
+ if (p.getType() == PropertyType.BINARY) {
+ copyBinary(p, targetNode);
+ } else {
+
+ if (p.isMultiple()) {
+ if (!targetNode.hasProperty(p.getName())
+ || !Arrays.equals(
+ targetNode.getProperty(p.getName())
+ .getValues(), p.getValues()))
+ targetNode.setProperty(p.getName(), p.getValues());
+ } else {
+ if (!targetNode.hasProperty(p.getName())
+ || !targetNode.getProperty(p.getName()).getValue()
+ .equals(p.getValue()))
+ targetNode.setProperty(p.getName(), p.getValue());
+ }
+ }
+ }
+ }
+
+ private static void copyBinary(Property p, Node targetNode)
+ throws RepositoryException {
+ InputStream in = null;
+ Binary sourceBinary = null;
+ Binary targetBinary = null;
+ try {
+ sourceBinary = p.getBinary();
+ if (targetNode.hasProperty(p.getName()))
+ targetBinary = targetNode.getProperty(p.getName()).getBinary();
+
+ // optim FIXME make it more configurable
+ if (targetBinary != null)
+ if (sourceBinary.getSize() == targetBinary.getSize()) {
+ if (log.isTraceEnabled())
+ log.trace("Skipped " + p.getPath());
+ return;
+ }
+
+ in = sourceBinary.getStream();
+ targetBinary = targetNode.getSession().getValueFactory()
+ .createBinary(in);
+ targetNode.setProperty(p.getName(), targetBinary);
+ } catch (Exception e) {
+ throw new SlcException("Could not transfer " + p, e);
+ } finally {
+ IOUtils.closeQuietly(in);
+ JcrUtils.closeQuietly(sourceBinary);
+ JcrUtils.closeQuietly(targetBinary);
+ }
+ }
+
+ /** factorizes monitor management */
+ private void updateMonitor(String msg, Boolean doLog) {
+ if (doLog && log.isDebugEnabled())
+ log.debug(msg);
+ if (monitor != null) {
+ monitor.worked(1);
+ monitor.subTask(msg);
+ }
+ }
+
+ // private void syncNode_old(Node sourceNode, Node targetParentNode)
+ // throws RepositoryException, SAXException {
+ //
+ // // enable cancelation of the current fetch process
+ // // FIXME insure the repository stays in a stable state
+ // if (monitor != null && monitor.isCanceled()) {
+ // updateMonitor("Fetched has been canceled, "
+ // + "process is terminating");
+ // return;
+ // }
+ //
+ // Boolean noRecurse = singleLevel(sourceNode);
+ // Calendar sourceLastModified = null;
+ // if (sourceNode.isNodeType(NodeType.MIX_LAST_MODIFIED)) {
+ // sourceLastModified = sourceNode.getProperty(
+ // Property.JCR_LAST_MODIFIED).getDate();
+ // }
+ //
+ // if (sourceNode.getDefinition().isProtected())
+ // log.warn(sourceNode + " is protected.");
+ //
+ // if (!targetParentNode.hasNode(sourceNode.getName())) {
+ // String msg = "Adding " + sourceNode.getPath();
+ // updateMonitor(msg);
+ // if (log.isDebugEnabled())
+ // log.debug(msg);
+ // ContentHandler contentHandler = targetParentNode
+ // .getSession()
+ // .getWorkspace()
+ // .getImportContentHandler(targetParentNode.getPath(),
+ // ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
+ // sourceNode.getSession().exportSystemView(sourceNode.getPath(),
+ // contentHandler, false, noRecurse);
+ // } else {
+ // Node targetNode = targetParentNode.getNode(sourceNode.getName());
+ // if (sourceLastModified != null) {
+ // Calendar targetLastModified = null;
+ // if (targetNode.isNodeType(NodeType.MIX_LAST_MODIFIED)) {
+ // targetLastModified = targetNode.getProperty(
+ // Property.JCR_LAST_MODIFIED).getDate();
+ // }
+ //
+ // if (targetLastModified == null
+ // || targetLastModified.before(sourceLastModified)) {
+ // String msg = "Updating " + targetNode.getPath();
+ // updateMonitor(msg);
+ // if (log.isDebugEnabled())
+ // log.debug(msg);
+ // ContentHandler contentHandler = targetParentNode
+ // .getSession()
+ // .getWorkspace()
+ // .getImportContentHandler(
+ // targetParentNode.getPath(),
+ // ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING);
+ // sourceNode.getSession().exportSystemView(
+ // sourceNode.getPath(), contentHandler, false,
+ // noRecurse);
+ // } else {
+ // String msg = "Skipped up to date " + targetNode.getPath();
+ // updateMonitor(msg);
+ // if (log.isDebugEnabled())
+ // log.debug(msg);
+ // return;
+ // }
+ // }
+ // }
+ //
+ // if (noRecurse) {
+ // // recurse
+ // Node targetNode = targetParentNode.getNode(sourceNode.getName());
+ // if (sourceLastModified != null) {
+ // Calendar zero = new GregorianCalendar();
+ // zero.setTimeInMillis(0);
+ // targetNode.setProperty(Property.JCR_LAST_MODIFIED, zero);
+ // targetNode.getSession().save();
+ // }
+ //
+ // for (NodeIterator it = sourceNode.getNodes(); it.hasNext();) {
+ // syncNode_old(it.nextNode(), targetNode);
+ // }
+ //
+ // if (sourceLastModified != null) {
+ // targetNode.setProperty(Property.JCR_LAST_MODIFIED,
+ // sourceLastModified);
+ // targetNode.getSession().save();
+ // }
+ // }
+ // }
+
+ protected Boolean singleLevel(Node sourceNode) throws RepositoryException {
+ if (sourceNode.isNodeType(NodeType.NT_FILE))
+ return false;
+ return true;
+ }
+
+ /**
+ * Synchronises only one workspace, retrieved by name without changing its
+ * name.
+ */