AllowedComponentsProviderImpl.java

  1. /*
  2.  * #%L
  3.  * wcm.io
  4.  * %%
  5.  * Copyright (C) 2014 wcm.io
  6.  * %%
  7.  * Licensed under the Apache License, Version 2.0 (the "License");
  8.  * you may not use this file except in compliance with the License.
  9.  * You may obtain a copy of the License at
  10.  *
  11.  *      http://www.apache.org/licenses/LICENSE-2.0
  12.  *
  13.  * Unless required by applicable law or agreed to in writing, software
  14.  * distributed under the License is distributed on an "AS IS" BASIS,
  15.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16.  * See the License for the specific language governing permissions and
  17.  * limitations under the License.
  18.  * #L%
  19.  */
  20. package io.wcm.wcm.parsys.componentinfo.impl;

  21. import java.util.Collections;
  22. import java.util.HashSet;
  23. import java.util.Set;
  24. import java.util.SortedSet;
  25. import java.util.TreeSet;

  26. import org.apache.commons.lang3.StringUtils;
  27. import org.apache.sling.api.resource.Resource;
  28. import org.apache.sling.api.resource.ResourceResolver;
  29. import org.jetbrains.annotations.NotNull;
  30. import org.jetbrains.annotations.Nullable;
  31. import org.osgi.service.component.annotations.Component;
  32. import org.osgi.service.component.annotations.Reference;

  33. import com.day.cq.commons.jcr.JcrConstants;
  34. import com.day.cq.wcm.api.Page;
  35. import com.day.cq.wcm.api.PageManager;

  36. import io.wcm.sling.commons.adapter.AdaptTo;
  37. import io.wcm.wcm.parsys.componentinfo.AllowedComponentsProvider;
  38. import io.wcm.wcm.parsys.componentinfo.ParsysConfig;
  39. import io.wcm.wcm.parsys.componentinfo.ParsysConfigManager;

  40. /**
  41.  * Detects allowed components for authoring for a given page/resource context.
  42.  */
  43. @Component(service = AllowedComponentsProvider.class, immediate = true)
  44. public final class AllowedComponentsProviderImpl implements AllowedComponentsProvider {

  45.   @Reference
  46.   private ParsysConfigManager parsysConfigManager;

  47.   /**
  48.    * Get allowed components for given resource path
  49.    * @param resourcePath Resource path inside content page
  50.    * @return Set of component paths (absolute resource types)
  51.    */
  52.   @Override
  53.   public @NotNull Set<String> getAllowedComponents(@NotNull String resourcePath, @NotNull ResourceResolver resolver) {
  54.     PageManager pageManager = AdaptTo.notNull(resolver, PageManager.class);
  55.     Page page = pageManager.getContainingPage(resourcePath);
  56.     if (page == null && StringUtils.contains(resourcePath, "/" + JcrConstants.JCR_CONTENT)) {
  57.       // if resource does not exist (e.g. inherited parsys) get page from resource path manually
  58.       page = pageManager.getPage(StringUtils.substringBefore(resourcePath, "/" + JcrConstants.JCR_CONTENT));
  59.     }
  60.     if (page == null) {
  61.       return Collections.emptySet();
  62.     }
  63.     String relativePath = StringUtils.substringAfter(resourcePath, page.getPath() + "/");
  64.     return getAllowedComponents(page, relativePath, null, resolver);
  65.   }

  66.   /**
  67.    * Get allowed components for a specific resource path inside a page.
  68.    * @param page Page
  69.    * @param relativeResourcePath Relative resource path inside the page
  70.    * @param resourceType Resource type of the paragraph system
  71.    * @param resolver Resource resolver
  72.    * @return Component paths
  73.    */
  74.   @Override
  75.   public @NotNull Set<String> getAllowedComponents(@NotNull Page page, @NotNull String relativeResourcePath,
  76.       @Nullable String resourceType, @NotNull ResourceResolver resolver) {
  77.     Set<String> allowedComponents = new HashSet<>();
  78.     Set<String> deniedComponents = new HashSet<>();

  79.     String pageComponentPath = page.getContentResource().getResourceType();

  80.     Iterable<ParsysConfig> parSysConfigs = parsysConfigManager.getParsysConfigs(pageComponentPath, relativeResourcePath, resolver);

  81.     Resource parentResource = null;
  82.     Resource grandParentResource = null;

  83.     for (ParsysConfig pathDef : parSysConfigs) {

  84.       boolean includePathDef = false;
  85.       if (pathDef.getAllowedParents().isEmpty()) {
  86.         includePathDef = true;
  87.       }
  88.       else {
  89.         String checkResourceType = null;
  90.         if (pathDef.getParentAncestorLevel() == 1) {
  91.           if (resourceType != null) {
  92.             checkResourceType = resourceType;
  93.           }
  94.           else if (parentResource == null) {
  95.             parentResource = resolver.getResource(page.getPath() + "/" + relativeResourcePath);
  96.             if (parentResource != null) {
  97.               checkResourceType = parentResource.getResourceType();
  98.             }
  99.           }
  100.         }
  101.         else if (pathDef.getParentAncestorLevel() == 2) {
  102.           if (grandParentResource == null) {
  103.             grandParentResource = resolver.getResource(page.getPath() + "/" + relativeResourcePath + "/..");
  104.           }
  105.           if (grandParentResource != null) {
  106.             checkResourceType = grandParentResource.getResourceType();
  107.           }
  108.         }
  109.         if (checkResourceType != null) {
  110.           includePathDef = pathDef.getAllowedParents().contains(checkResourceType);
  111.         }
  112.       }

  113.       if (includePathDef) {
  114.         allowedComponents.addAll(pathDef.getAllowedChildren());
  115.         deniedComponents.addAll(pathDef.getDeniedChildren());
  116.       }

  117.     }

  118.     // filter out denied components
  119.     allowedComponents.removeAll(deniedComponents);

  120.     return allowedComponents;
  121.   }

  122.   /**
  123.    * Get all allowed components for a template (not respecting any path constraints)
  124.    * @param pageComponentPath Path of template's page component
  125.    * @return Set of component paths (absolute resource types)
  126.    */
  127.   @Override
  128.   public @NotNull Set<String> getAllowedComponentsForTemplate(@NotNull String pageComponentPath, @NotNull ResourceResolver resolver) {
  129.     Resource pageComponentResource = resolver.getResource(pageComponentPath);
  130.     if (pageComponentResource != null) {
  131.       Iterable<ParsysConfig> parSysConfigs = parsysConfigManager.getParsysConfigs(pageComponentResource.getPath(), resolver);

  132.       SortedSet<String> allowedChildren = new TreeSet<>();
  133.       for (ParsysConfig parSysConfig : parSysConfigs) {
  134.         allowedChildren.addAll(parSysConfig.getAllowedChildren());
  135.       }

  136.       return allowedChildren;
  137.     }
  138.     // fallback
  139.     return Collections.emptySet();
  140.   }

  141. }