/*
* #%L
* wcm.io
* %%
* Copyright (C) 2014 wcm.io
* %%
* Licensed 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.
* #L%
*/
package io.wcm.wcm.parsys.componentinfo.impl;
import java.util.HashSet;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import com.day.cq.commons.jcr.JcrConstants;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.google.common.collect.ImmutableSet;
import io.wcm.wcm.parsys.componentinfo.AllowedComponentsProvider;
import io.wcm.wcm.parsys.componentinfo.ParsysConfig;
import io.wcm.wcm.parsys.componentinfo.ParsysConfigManager;
/**
* Detects allowed components for authoring for a given page/resource context.
*/
@Component(service = AllowedComponentsProvider.class, immediate = true)
public final class AllowedComponentsProviderImpl implements AllowedComponentsProvider {
@Reference
private ParsysConfigManager parsysConfigManager;
/**
* Get allowed components for given resource path
* @param resourcePath Resource path inside content page
* @return Set of component paths (absolute resource types)
*/
@Override
public Set<String> getAllowedComponents(String resourcePath, ResourceResolver resolver) {
Set<String> allowedComponents = new HashSet<>();
Set<String> deniedComponents = new HashSet<>();
PageManager pageManager = resolver.adaptTo(PageManager.class);
Page page = pageManager.getContainingPage(resourcePath);
if (page == null && StringUtils.contains(resourcePath, "/" + JcrConstants.JCR_CONTENT)) {
// if resource does not exist (e.g. inherited parsys) get page from resource path manually
page = pageManager.getPage(StringUtils.substringBefore(resourcePath, "/" + JcrConstants.JCR_CONTENT));
}
if (page != null) {
String pageComponentPath = page.getContentResource().getResourceType();
String relativePath = resourcePath.substring(page.getPath().length() + 1);
Iterable<ParsysConfig> parSysConfigs = parsysConfigManager.getParsysConfigs(pageComponentPath, relativePath, resolver);
Resource parentResource = null;
Resource grandParentResource = null;
for (ParsysConfig pathDef : parSysConfigs) {
boolean includePathDef = false;
if (pathDef.getAllowedParents().size() == 0) {
includePathDef = true;
}
else {
Resource checkResource = null;
if (pathDef.getParentAncestorLevel() == 1) {
if (parentResource == null) {
parentResource = resolver.getResource(resourcePath);
}
checkResource = parentResource;
}
if (pathDef.getParentAncestorLevel() == 2) {
if (grandParentResource == null) {
grandParentResource = resolver.getResource(resourcePath + "/..");
}
checkResource = grandParentResource;
}
if (checkResource != null) {
String resourceType = checkResource.getResourceType();
includePathDef = pathDef.getAllowedParents().contains(resourceType);
}
}
if (includePathDef) {
allowedComponents.addAll(pathDef.getAllowedChildren());
deniedComponents.addAll(pathDef.getDeniedChildren());
}
}
}
// filter out denied components
allowedComponents.removeAll(deniedComponents);
return allowedComponents;
}
/**
* Get all allowed components for a template (not respecting any path constraints)
* @param pageComponentPath Path of template's page component
* @return Set of component paths (absolute resource types)
*/
@Override
public Set<String> getAllowedComponentsForTemplate(String pageComponentPath, ResourceResolver resolver) {
Resource pageComponentResource = resolver.getResource(pageComponentPath);
if (pageComponentResource != null) {
Iterable<ParsysConfig> parSysConfigs = parsysConfigManager.getParsysConfigs(pageComponentResource.getPath(), resolver);
SortedSet<String> allowedChildren = new TreeSet<>();
for (ParsysConfig parSysConfig : parSysConfigs) {
allowedChildren.addAll(parSysConfig.getAllowedChildren());
}
return allowedChildren;
}
// fallback
return ImmutableSet.of();
}
}