in vault-core/src/main/java/org/apache/jackrabbit/vault/util/RepositoryCopier.java [284:504]
private void copy(AutoSave autoSave, Node src, Node dstParent, String dstName, boolean recursive)
throws RepositoryException {
if (abort) {
return;
}
String path = src.getPath();
currentPath = path;
String dstPath = dstParent.getPath() + "/" + dstName;
if (srcFilter != null && !srcFilter.contains(path)) {
track(path, "------ I");
return;
}
boolean skip = false;
if (resumeFrom != null) {
if (path.equals(resumeFrom)) {
// found last node, resuming
resumeFrom = null;
} else {
skip = true;
}
}
// check for special node that need sysview import handling
boolean useSysView = src.getDefinition().isProtected();
Node dst;
boolean isNew = false;
boolean overwrite = update;
if (dstParent.hasNode(dstName)) {
dst = dstParent.getNode(dstName);
if (skip) {
track(path, "------ S");
} else if (overwrite) {
if (onlyNewer && dstName.equals("jcr:content")) {
if (isNewer(src, dst)) {
track(dstPath, "%06d U", ++totalNodes);
} else {
overwrite = false;
recursive = false;
track(dstPath, "%06d -", ++totalNodes);
}
} else {
track(dstPath, "%06d U", ++totalNodes);
}
if (useSysView) {
dst = sysCopy(src, dstParent, dstName);
}
} else {
track(dstPath, "%06d -", ++totalNodes);
}
} else {
try {
if (skip) {
track(path, "------ S");
dst = null;
} else if (useSysView) {
dst = sysCopy(src, dstParent, dstName);
} else {
dst = dstParent.addNode(dstName, src.getPrimaryNodeType().getName());
}
track(dstPath, "%06d A", ++totalNodes);
isNew = true;
} catch (RepositoryException e) {
if (log.isDebugEnabled()) {
log.debug("Error while adding node {} (ignored)", dstPath, e);
} else {
log.warn("Error while adding node {} (ignored): {}", dstPath, e.getMessage());
}
return;
}
}
if (useSysView) {
if (!skip) {
// track changes
trackTree(dst, isNew);
}
} else {
Set<String> names = new HashSet<String>();
if (!skip && (overwrite || isNew)) {
if (!isNew) {
for (NodeType nt: dst.getMixinNodeTypes()) {
names.add(nt.getName());
}
// add mixins
for (NodeType nt: src.getMixinNodeTypes()) {
String mixName = checkNameSpace(nt.getName(), src.getSession(), dst.getSession());
if (!names.remove(mixName)) {
dst.addMixin(nt.getName());
}
}
// handle removed mixins
for (String mix: names) {
dst.removeMixin(mix);
}
} else {
// add mixins
for (NodeType nt: src.getMixinNodeTypes()) {
dst.addMixin(checkNameSpace(nt.getName(), src.getSession(), dst.getSession()));
}
}
// add properties
names.clear();
if (!isNew) {
PropertyIterator iter = dst.getProperties();
while (iter.hasNext()) {
names.add(checkNameSpace(iter.nextProperty().getName(), src.getSession(), dst.getSession()));
}
}
PropertyIterator iter = src.getProperties();
while (iter.hasNext()) {
Property p = iter.nextProperty();
String pName = checkNameSpace(p.getName(), src.getSession(), dst.getSession());
names.remove(pName);
// ignore protected
if (p.getDefinition().isProtected()) {
continue;
}
// remove destination property to avoid type clashes
if (dst.hasProperty(pName)) {
dst.getProperty(pName).remove();
}
if (p.getDefinition().isMultiple()) {
Value[] vs = p.getValues();
dst.setProperty(pName, vs);
for (long s: p.getLengths()) {
totalSize+=s;
currentSize+=s;
}
} else {
Value v = p.getValue();
dst.setProperty(pName, v);
long s= p.getLength();
totalSize+=s;
currentSize+=s;
}
}
// remove obsolete properties
for (String pName: names) {
try {
// ignore protected. should not happen, unless the primary node type changes.
Property dstP = dst.getProperty(pName);
if (dstP.getDefinition().isProtected()) {
continue;
}
dstP.remove();
} catch (RepositoryException e) {
// ignore
}
}
}
// descend
if (recursive && dst != null) {
names.clear();
if (overwrite && !isNew) {
NodeIterator niter = dst.getNodes();
while (niter.hasNext()) {
names.add(checkNameSpace(niter.nextNode().getName(), src.getSession(), dst.getSession()));
}
}
NodeIterator niter = src.getNodes();
while (niter.hasNext()) {
Node child = niter.nextNode();
String cName = checkNameSpace(child.getName(), src.getSession(), dst.getSession());
names.remove(cName);
copy(autoSave, child, dst, cName, true);
}
if (resumeFrom == null) {
// check if we need to order
if (overwrite && !isNew && !noOrdering && src.getPrimaryNodeType().hasOrderableChildNodes()) {
niter = src.getNodes();
while (niter.hasNext()) {
Node child = niter.nextNode();
String name = child.getName();
if (dst.hasNode(name)) {
dst.orderBefore(name, null);
}
}
}
// remove obsolete child nodes
for (String name: names) {
try {
Node cNode = dst.getNode(name);
track(cNode.getPath(), "%06d D", ++totalNodes);
cNode.remove();
} catch (RepositoryException e) {
// ignore
}
}
}
}
}
if (!skip) {
numNodes++;
autoSave.modified(1);
}
// check for save
if (autoSave.needsSave()) {
track("", "Intermediate saving %d nodes (%d kB)...", numNodes, currentSize/1000);
long now = System.currentTimeMillis();
autoSave.save(dst.getSession(), true);
long end = System.currentTimeMillis();
track("", "Done in %d ms. Total time: %d, total nodes %d, %d kB", end-now, end-start, totalNodes, totalSize/1000);
lastKnownGood = currentPath;
numNodes = 0;
currentSize = 0;
if (throttle > 0) {
track("", "Throttling enabled. Waiting %d second%s...", throttle, throttle == 1 ? "" : "s");
try {
Thread.sleep(throttle * 1000);
} catch (InterruptedException e) {
log.warn("Interrupted while waiting", e);
Thread.currentThread().interrupt();
}
}
}
}