in src/main/java/org/apache/sling/servlets/post/impl/operations/AbstractCreateOperation.java [533:620]
protected Resource deepGetOrCreateResource(final ResourceResolver resolver,
final String path,
final Map<String, RequestProperty> reqProperties,
final List<Modification> changes,
final VersioningConfiguration versioningConfiguration)
throws PersistenceException {
if (log.isDebugEnabled()) {
log.debug("Deep-creating resource '{}'", path);
}
if (path == null || !path.startsWith("/")) {
throw new IllegalArgumentException("path must be an absolute path.");
}
// get the starting resource
String startingResourcePath = path;
Resource startingResource = null;
while (startingResource == null) {
if (startingResourcePath.equals("/")) {
startingResource = resolver.getResource("/");
if (startingResource == null){
throw new PersistenceException("Access denied for root resource, resource can't be created: " + path);
}
} else {
final Resource r = resolver.getResource(startingResourcePath);
if ( r != null && !ResourceUtil.isSyntheticResource(r)) {
startingResource = resolver.getResource(startingResourcePath);
updateNodeType(resolver, startingResourcePath, reqProperties, changes, versioningConfiguration);
updateMixins(resolver, startingResourcePath, reqProperties, changes, versioningConfiguration);
} else {
int pos = startingResourcePath.lastIndexOf('/');
if (pos > 0) {
startingResourcePath = startingResourcePath.substring(0, pos);
} else {
startingResourcePath = "/";
}
}
}
}
// is the searched resource already existing?
if (startingResourcePath.length() == path.length()) {
return startingResource;
}
// create nodes
int from = (startingResourcePath.length() == 1
? 1
: startingResourcePath.length() + 1);
Resource resource = startingResource;
while (from > 0) {
final int to = path.indexOf('/', from);
final String name = to < 0 ? path.substring(from) : path.substring(
from, to);
// although the resource should not exist (according to the first test
// above)
// we do a sanety check.
final Resource child = resource.getChild(name);
if (child != null && !ResourceUtil.isSyntheticResource(child)) {
resource = child;
updateNodeType(resolver, resource.getPath(), reqProperties, changes, versioningConfiguration);
updateMixins(resolver, resource.getPath(), reqProperties, changes, versioningConfiguration);
} else {
final String tmpPath = to < 0 ? path : path.substring(0, to);
// check for node type
final String nodeType = getPrimaryType(reqProperties, tmpPath);
this.jcrSupport.checkoutIfNecessary(resource, changes, versioningConfiguration);
try {
final Map<String, Object> props = new HashMap<>();
if (nodeType != null) {
props.put("jcr:primaryType", nodeType);
}
// check for mixin types
final String[] mixinTypes = getMixinTypes(reqProperties,
tmpPath);
if (mixinTypes != null) {
props.put("jcr:mixinTypes", mixinTypes);
}
resource = resolver.create(resource, name, props);
} catch (final PersistenceException e) {
log.error("Unable to create resource named " + name + " in " + resource.getPath());
throw e;
}
changes.add(Modification.onCreated(resource.getPath()));
}
from = to + 1;
}
return resource;
}