blob: 373d2eb3022e97c701db1d6fb21e116420a5eb6d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.sling.testing.mock.sling.context;
import java.util.UUID;
import org.apache.jackrabbit.JcrConstants;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.testing.mock.sling.builder.ImmutableValueMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.osgi.annotation.versioning.ConsumerType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Manages unique root paths in JCR repository.
* This is important for resource resolver types like JCR_JACKRABBIT
* where the repository is not cleaned for each test run. This class provides
* unique root paths for each run, and cleans them up when done.
*/
@ConsumerType
public class UniqueRoot {
private final SlingContextImpl context;
protected final String uniquePathPart;
private Resource contentRoot;
private Resource appsRoot;
private Resource libsRoot;
private static final Logger log = LoggerFactory.getLogger(UniqueRoot.class);
protected UniqueRoot(@NotNull SlingContextImpl context) {
this.context = context;
// generate unique path part by using a UUID
uniquePathPart = UUID.randomUUID().toString();
}
/**
* Get or create resource with given JCR primary type
* @param path Path
* @param primaryType JCR primary type
* @return Resource (never null)
*/
protected final Resource getOrCreateResource(@NotNull String path, @NotNull String primaryType) {
try {
return ResourceUtil.getOrCreateResource(context.resourceResolver(), path,
ImmutableValueMap.of(JcrConstants.JCR_PRIMARYTYPE, primaryType),
null, true);
}
catch (PersistenceException ex) {
throw new RuntimeException("Unable to create resource at " + path + ": " + ex.getMessage(), ex);
}
}
/**
* Gets (and creates if required) a unique path at <code>/content/xxx</code>.
* The path (incl. all children) is automatically removed when the unit test completes.
* @return Unique content path
*/
public final @NotNull String content() {
if (contentRoot == null) {
contentRoot = getOrCreateResource("/content/" + uniquePathPart, "sling:OrderedFolder");
}
return contentRoot.getPath();
}
/**
* Gets (and creates if required) a unique path at <code>/apps/xxx</code>.
* The path (incl. all children) is automatically removed when the unit test completes.
* @return Unique content path
*/
public final @NotNull String apps() {
if (appsRoot == null) {
appsRoot = getOrCreateResource("/apps/" + uniquePathPart, "sling:OrderedFolder");
}
return appsRoot.getPath();
}
/**
* Gets (and creates if required) a unique path at <code>/libs/xxx</code>.
* The path (incl. all children) is automatically removed when the unit test completes.
* @return Unique content path
*/
public final @NotNull String libs() {
if (libsRoot == null) {
libsRoot = getOrCreateResource("/libs/" + uniquePathPart, "sling:OrderedFolder");
}
return libsRoot.getPath();
}
/**
* Cleanup is called when the unit test rule completes a unit test run.
* All resources created have to be removed.
*/
protected void cleanUp() {
deleteResources(contentRoot, appsRoot, libsRoot);
}
/**
* Deletes the given set of resources and commits afterwards.
* @param resources Resources to be deleted
*/
protected final void deleteResources(@Nullable Resource @NotNull ... resources) {
for (Resource resource : resources) {
if (resource != null && context.resourceResolver.getResource(resource.getPath()) != null) {
try {
context.resourceResolver().delete(resource);
}
catch (PersistenceException ex) {
log.warn("Unable to delete root path " + resource.getPath(), ex);
}
}
}
try {
context.resourceResolver().commit();
}
catch (PersistenceException ex) {
log.warn("Unable to commit root path deletions.", ex);
}
}
}