
com.adobe.cq.editor.model.inplaceediting.config.Plugin Maven / Gradle / Ivy
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2016 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
*
**************************************************************************/
package com.adobe.cq.editor.model.inplaceediting.config;
import java.util.Arrays;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
import com.day.cq.commons.jcr.JcrConstants;
import org.apache.commons.lang.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.request.RequestParameter;
import org.apache.sling.api.resource.AbstractResource;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.Optional;
import org.apache.sling.models.annotations.Via;
import org.apache.sling.models.annotations.injectorspecific.Self;
import org.apache.sling.models.annotations.injectorspecific.SlingObject;
/**
* Representation suitable for configuring a plugin resource in the context of the In Place Editors
*/
@Model(adaptables = SlingHttpServletRequest.class)
public class Plugin extends AbstractResource {
private static final String PN_POLICY_CONTENT_RESOURCE_TYPE = "policyContentResourceType";
private static final String SLING_RESOURCE_SUPER_TYPE = "sling:resourceSuperType";
private static final String PLUGIN_CLASS_NAMES = "js-cq-IPEPlugin coral-Form-field";
private static final String PLUGIN_CONFIGURATION_PATH = "plugins/";
private static final String RTE_PLUGIN_CONFIGURATION_PATH = "rtePlugins/";
private static final String COMPONENT_RELATIVE_IPE_CONFIG = "/cq:editConfig/cq:inplaceEditing";
private static final String COMPONENT_RELATIVE_CONFIG = COMPONENT_RELATIVE_IPE_CONFIG + "/config";
private static final String COMPONENT_RELATIVE_IPE_PLUGINS_CONFIG = COMPONENT_RELATIVE_CONFIG + "/plugins/";
private static final String COMPONENT_RELATIVE_IPE_RTE_PLUGINS_CONFIG = COMPONENT_RELATIVE_CONFIG + "/rtePlugins/";
private static final String CONFIG_PATH = "configPath";
private static final String PLUGINS_NODE_NAME = "/plugins/";
private static final String RTE_PLUGINS_NODE_NAME = "/rtePlugins/";
private static final String POLICY_RESOURCE_TYPE = "wcm/core/components/policy/policy";
protected static final String FEATURE_LIST_SEPARATOR = ",";
protected static final String CONFIGURATION_ALL_PLUGINS = "*";
protected static final String CONFIGURATION_NO_PLUGIN = "-";
protected static final String PLUGIN_CONFIGURATION_FEATURES_PROPERTY = "features";
@Self
protected SlingHttpServletRequest slingRequest;
/**
* Title of the plugin
*/
@Inject
@Named(JcrConstants.JCR_TITLE)
@Via("resource")
private String title;
@Inject
@SlingObject
Resource resource;
/**
* Name of the plugin
*/
@Inject
@Via("resource")
String name;
/**
* List of features represented as a comma separated list
*
*
* - "*": Enable all the features of the plugin
* - "-": Disables the plugin
*
*/
@Inject
@Via("resource")
@Optional
String features;
@Inject
ResourceResolver resolver;
/**
* List of plugin
*/
@Inject
@Named("class")
@Via("resource")
@Optional
String classNames;
@Inject
@Via("resource")
@Optional
boolean defaultEnabled;
private Resource pluginContainerConfiguration;
/**
* Resource type of the component concerned by the design dialog
*/
private String targetComponentResourceType;
@PostConstruct
protected void initModel() {
RequestParameter policyContentResourceType = slingRequest.getRequestParameter(PN_POLICY_CONTENT_RESOURCE_TYPE);
if (policyContentResourceType != null) {
targetComponentResourceType = policyContentResourceType.getString();
} else {
RequestParameter[] resourceTypesRP = slingRequest.getRequestParameters("resourceType");
if (resourceTypesRP != null) {
for (RequestParameter resourceTypeRP : resourceTypesRP) {
if (resourceTypeRP != null && !POLICY_RESOURCE_TYPE.equals(resourceTypeRP.getString())) {
targetComponentResourceType = resourceTypeRP.getString();
}
}
}
}
}
/**
* Title of the plugin
*
* @return Title of the plugin
*/
public String getTitle() {
return title;
}
/**
* Name of the plugin
*
* @return
*/
public String getPluginName() {
return name;
}
/**
* Name of the plugin
*
* @return Name of the plugin
*/
@Override
public String getName() {
return resource.getName();
}
public String getPath() {
return resource.getPath();
}
public String getResourceType() {
return resource.getResourceType();
}
public String getResourceSuperType() {
return resource.getResourceSuperType();
}
public ResourceMetadata getResourceMetadata() {
return resource.getResourceMetadata();
}
public ResourceResolver getResourceResolver() {
return resource.getResourceResolver();
}
/**
* List of features provided by the current Plugin
*
* @return The features value
*/
public String getFeatures() {
return features;
}
/**
* Are the current widget features contained in the given configuration
*
* @param featuresValue String representation of the features
* @return The current plugin features exist in the given list of features
*/
private boolean featuresExist(String[] featuresValue) {
if (featuresValue == null || featuresValue.length == 0) {
return false;
}
// All the plugins are enabled
if (CONFIGURATION_ALL_PLUGINS.equals(featuresValue[0])) {
return true;
}
// Verify the current features are contained in the given list of features
List configFeatureList;
if (featuresValue.length > 1) {
// Multi-valued list of features
configFeatureList = Arrays.asList(featuresValue);
} else {
// Comma separated list of features
configFeatureList = Arrays.asList(featuresValue[0].split(FEATURE_LIST_SEPARATOR));
}
List featureList = Arrays.asList(features.split(FEATURE_LIST_SEPARATOR));
if (configFeatureList.containsAll(featureList)) {
return true;
}
return false;
}
/**
* Does the given configuration resource contains any features configuration
*
* @param pluginConfig Configuration resource where to look for the current features
* @return The features exist in the given configuration resource
*/
protected Boolean hasFeatures(Resource pluginConfig) {
if (pluginConfig == null) {
return null;
}
String[] featuresValue = pluginConfig.getValueMap().get(PLUGIN_CONFIGURATION_FEATURES_PROPERTY, String[].class);
if (featuresValue == null || featuresValue.length == 0 || CONFIGURATION_NO_PLUGIN.equals(featuresValue[0])) {
return Boolean.FALSE;
}
if (featuresExist(featuresValue)) {
return Boolean.TRUE;
}
return Boolean.FALSE;
}
/**
* Is the plugin enabled
*
* @param pluginName Name of the plugin to verify
* @return Status of the plugin
*/
Boolean isPluginEnabled(String pluginName) {
if (StringUtils.isEmpty(pluginName)) {
return null;
}
Resource designResource = slingRequest.getRequestPathInfo().getSuffixResource();
if (designResource != null) {
if (StringUtils.isEmpty(name)) {
return null;
}
Boolean hasDesignFeatureConfig = null;
Resource designPluginConfig = null;
String pluginRootName = getPluginRootName();
// Optional value set on the granite:data plugin-root-name
if (StringUtils.isNotEmpty(pluginRootName)) {
designPluginConfig = designResource.getChild(pluginRootName + "/" + pluginName);
if (designPluginConfig != null) {
hasDesignFeatureConfig = hasFeatures(designPluginConfig);
}
}
// Look for a plugins node
if (designPluginConfig == null) {
designPluginConfig = designResource.getChild(PLUGIN_CONFIGURATION_PATH + pluginName);
if (designPluginConfig != null) {
hasDesignFeatureConfig = hasFeatures(designPluginConfig);
}
}
// Look for a rtePlugins node
if (designPluginConfig == null) {
designPluginConfig = designResource.getChild(RTE_PLUGIN_CONFIGURATION_PATH + pluginName);
if (designPluginConfig != null) {
hasDesignFeatureConfig = hasFeatures(designPluginConfig);
}
}
// A Design configuration exists
if (hasDesignFeatureConfig != null) {
return hasDesignFeatureConfig;
}
}
if (StringUtils.isEmpty(pluginName) || StringUtils.isEmpty(targetComponentResourceType)) {
return null;
}
Resource componentIPEConfigPlugins = getInheritedPluginConfiguration(targetComponentResourceType, pluginName);
Boolean hasFeatures = hasFeatures(componentIPEConfigPlugins);
if (hasFeatures == null) {
return defaultEnabled;
}
return hasFeatures;
}
/**
* Returns the optional configuration resource of the container
*
* @return
*/
Resource getPluginContainerConfiguration() {
if (pluginContainerConfiguration == null) {
// Features are stored under an intermediary items node
// We have to go up 2 levels to get the granite:data node
Resource pluginConfig = resource.getParent();
if (pluginConfig == null) {
return null;
}
pluginConfig = pluginConfig.getParent();
if (pluginConfig == null) {
return null;
}
pluginContainerConfiguration = pluginConfig.getChild("granite:data");
}
return pluginContainerConfiguration;
}
/**
* Returns the optional plugin root name set on the configuration resource of the container
*
* @return
*/
private String getPluginRootName() {
Resource pluginContainerConfiguration = getPluginContainerConfiguration();
if (pluginContainerConfiguration == null) {
return "";
}
String pluginRootName = pluginContainerConfiguration.getValueMap().get("plugin-root-name", String.class);
return pluginRootName;
}
/**
* Should the plugin be enabled
*
* @return Status of the plugin
*/
public Boolean isEnabled() {
return isPluginEnabled(name);
}
/**
* Returns the inherited IPE plugin configuration for the given component resource and plugin
*
* @param componentResourceType Path to the component resource
* @param pluginName Name of the plugin
* @return Inherited resource representing a plugin configuration
*/
private Resource getInheritedPluginConfiguration(String componentResourceType, String pluginName) {
if (StringUtils.isEmpty(componentResourceType) || StringUtils.isEmpty(pluginName)) {
return null;
}
Resource configResource = null;
// Component local configuration
// The plugin name is provided
String pluginResourceName = getPluginRootName();
if (StringUtils.isNotEmpty(pluginResourceName)) {
configResource = resolver.getResource(componentResourceType + COMPONENT_RELATIVE_CONFIG + "/" + pluginResourceName + "/" + pluginName);
} else {
// Look for plugin under "plugins"
configResource = resolver.getResource(componentResourceType + COMPONENT_RELATIVE_IPE_PLUGINS_CONFIG + pluginName);
// Look for plugin under "rtePlugins"
if (configResource == null) {
configResource = resolver.getResource(componentResourceType + COMPONENT_RELATIVE_IPE_RTE_PLUGINS_CONFIG + pluginName);
}
}
// Returns a local configuration
if (configResource != null) {
return configResource;
}
// The configuration is located somewhere else
// configPath property and relocated configuration
Resource inPlaceEditConfig = resolver.getResource(componentResourceType + COMPONENT_RELATIVE_IPE_CONFIG);
if (inPlaceEditConfig != null) {
String configPath = inPlaceEditConfig.getValueMap().get(CONFIG_PATH, String.class);
if (StringUtils.isNotEmpty(configPath)) {
// The plugin name is provided
if (StringUtils.isNotEmpty(pluginResourceName)) {
configResource = resolver.getResource(componentResourceType + COMPONENT_RELATIVE_IPE_CONFIG + "/" + configPath + "/" + pluginResourceName + "/" + pluginName);
} else {
// Look for plugin under "plugins"
configResource = resolver.getResource(componentResourceType + COMPONENT_RELATIVE_IPE_CONFIG + "/" + configPath + PLUGINS_NODE_NAME + pluginName);
// Look for plugin under "rtePlugins"
if (configResource == null) {
configResource = resolver.getResource(componentResourceType + COMPONENT_RELATIVE_IPE_CONFIG + "/" + configPath + RTE_PLUGINS_NODE_NAME + pluginName);
}
}
}
if (configResource != null) {
return configResource;
}
}
// Get Resource Super Type
// And repeat
Resource component = resolver.getResource(componentResourceType);
String superResourceTypePath = component.getValueMap().get(SLING_RESOURCE_SUPER_TYPE, String.class);
if (StringUtils.isEmpty(superResourceTypePath)) {
return null;
}
return getInheritedPluginConfiguration(superResourceTypePath, pluginName);
}
/**
* List of default and provided class names
*
* @return Concatenated class names
*/
public String getClassNames() {
if (StringUtils.isEmpty(classNames)) {
return PLUGIN_CLASS_NAMES;
}
return PLUGIN_CLASS_NAMES + " " + classNames;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy