| /* |
| * 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; |
| |
| /** |
| * Unique path part |
| */ |
| protected final String uniquePathPart; |
| |
| private Resource contentRoot; |
| private Resource appsRoot; |
| private Resource libsRoot; |
| |
| private static final Logger log = LoggerFactory.getLogger(UniqueRoot.class); |
| |
| /** |
| * @param context Sling context |
| */ |
| 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); |
| } |
| } |
| } |