in src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCopyMoveOperation.java [42:139]
protected final void doRun(
final SlingJakartaHttpServletRequest request,
final JakartaPostResponse response,
final List<Modification> changes)
throws PersistenceException {
final VersioningConfiguration versioningConfiguration = getVersioningConfiguration(request);
final Resource resource = request.getResource();
final String source = resource.getPath();
// ensure dest is not empty/null and is absolute
String dest = request.getParameter(SlingPostConstants.RP_DEST);
if (dest == null || dest.length() == 0) {
throw new IllegalArgumentException("Unable to process " + getOperationName() + ". Missing destination");
}
// register whether the path ends with a trailing slash
final boolean trailingSlash = dest.endsWith("/");
// ensure destination is an absolute and normalized path
if (!dest.startsWith("/")) {
dest = ResourceUtil.getParent(source) + "/" + dest;
}
dest = ResourceUtil.normalize(dest);
// destination parent and name
final String dstParent = trailingSlash ? dest : ResourceUtil.getParent(dest);
// delete destination if already exists
if (!trailingSlash && request.getResourceResolver().getResource(dest) != null) {
final String replaceString = request.getParameter(SlingPostConstants.RP_REPLACE);
final boolean isReplace = "true".equalsIgnoreCase(replaceString);
if (!isReplace) {
response.setStatus(
HttpServletResponse.SC_PRECONDITION_FAILED,
"Cannot " + getOperationName() + " " + resource + " to " + dest + ": destination exists");
return;
} else {
this.jcrSupport.checkoutIfNecessary(
request.getResourceResolver().getResource(dstParent), changes, versioningConfiguration);
}
} else {
// check if path to destination exists and create it, but only
// if it's a descendant of the current node
if (!dstParent.equals("")) {
final Resource parentResource = request.getResourceResolver().getResource(dstParent);
if (parentResource != null) {
this.jcrSupport.checkoutIfNecessary(parentResource, changes, versioningConfiguration);
} else {
response.setStatus(
HttpServletResponse.SC_PRECONDITION_FAILED,
"Cannot " + getOperationName() + " " + resource + " to " + dest
+ ": parent of destination does not exist");
return;
}
}
// the destination is newly created, hence a create request
response.setCreateRequest(true);
}
final Iterator<Resource> resources = getApplyToResources(request);
final Resource destResource;
if (resources == null) {
final String dstName = trailingSlash ? null : ResourceUtil.getName(dest);
destResource = execute(changes, resource, dstParent, dstName, versioningConfiguration);
} else {
// multiple applyTo requires trailing slash on destination
if (!trailingSlash) {
throw new IllegalArgumentException("Applying "
+ getOperationName()
+ " to multiple resources requires a trailing slash on the destination");
}
// multiple copy will never return 201/CREATED
response.setCreateRequest(false);
while (resources.hasNext()) {
final Resource applyTo = resources.next();
execute(changes, applyTo, dstParent, null, versioningConfiguration);
}
destResource = request.getResourceResolver().getResource(dest);
}
if (destResource == null) {
response.setStatus(
HttpServletResponse.SC_NOT_FOUND, "Missing source " + resource + " for " + getOperationName());
return;
}
// finally apply the ordering parameter
this.orderResource(request, destResource, changes);
}