| /*- |
| * 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.dynamicinclude; |
| |
| import java.util.Arrays; |
| import java.util.List; |
| |
| import org.apache.commons.lang3.ArrayUtils; |
| import org.apache.commons.lang3.StringUtils; |
| import org.apache.sling.api.SlingHttpServletRequest; |
| import org.apache.sling.commons.osgi.PropertiesUtil; |
| import org.apache.sling.dynamicinclude.pathmatcher.PathMatcher; |
| import org.apache.sling.dynamicinclude.pathmatcher.PrefixPathMatcher; |
| import org.apache.sling.dynamicinclude.pathmatcher.RegexPathMatcher; |
| import org.osgi.framework.Constants; |
| import org.osgi.service.component.annotations.Activate; |
| import org.osgi.service.component.annotations.Component; |
| import org.osgi.service.component.annotations.ConfigurationPolicy; |
| import org.osgi.service.metatype.annotations.AttributeDefinition; |
| import org.osgi.service.metatype.annotations.Designate; |
| import org.osgi.service.metatype.annotations.ObjectClassDefinition; |
| import org.osgi.service.metatype.annotations.Option; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| /** |
| * Include filter configuration. |
| */ |
| @Component(service = Configuration.class, |
| immediate = true, |
| configurationPolicy = ConfigurationPolicy.REQUIRE, |
| property = { |
| Constants.SERVICE_VENDOR + "=The Apache Software Foundation", |
| "webconsole.configurationFactory.nameHint={include-filter.config.include-type} for [{include-filter.config.resource-types}] at path: {include-filter.config.path}" |
| }) |
| @Designate(ocd = Configuration.Config.class, factory = true) |
| public class Configuration { |
| |
| @ObjectClassDefinition(name = "Apache Sling Dynamic Include - Configuration") |
| public @interface Config { |
| @AttributeDefinition(name="Enabled", description="Check to enable the filter") |
| boolean include$_$filter_config_enabled() default false; |
| |
| @AttributeDefinition(name="Base path regular expression", description="This SDI configuration will work only for paths matching this value. If value starts with \\\"^\\\" sign, regex matching will be performed. Otherwise it will check for path prefix.") |
| String include$_$filter_config_path() default "/content"; |
| |
| @AttributeDefinition(name="Resource types", description="Filter will replace components with selected resource types", cardinality = Integer.MAX_VALUE) |
| String include$_$filter_config_resource$_$types() default ""; |
| |
| @AttributeDefinition(name = "Include type", description = "Type of generated include tags", options = { |
| @Option(label = "Apache SSI", value = "SSI"), |
| @Option(label = "ESI", value = "ESI"), |
| @Option(label = "Javascript", value = "JSI") |
| }) |
| String include$_$filter_config_include$_$type() default "SSI"; |
| |
| @AttributeDefinition(name="Add comment", description = "Add comment to included components") |
| boolean include$_$filter_config_add__comment() default false; |
| |
| @AttributeDefinition(name = "Filter selector", description = "Selector used to mark included resources") |
| String include$_$filter_config_selector() default "nocache"; |
| |
| @AttributeDefinition(name = "Extension", description = "Extension to append to virtual resources to make caching possible") |
| String include$_$filter_config_extension() default ""; |
| |
| @AttributeDefinition(name = "Component TTL", description = "\"Time to live\" cache header for rendered component (in seconds)") |
| String include$_$filter_config_ttl() default ""; |
| |
| @AttributeDefinition(name = "Required header", description = "SDI will work only for requests with given header") |
| String include$_$filter_config_required__header() default "Server-Agent=Communique-Dispatcher"; |
| |
| @AttributeDefinition(name = "Ignore URL params", description = "SDI will process the request even if it contains configured GET parameters", cardinality = Integer.MAX_VALUE) |
| String include$_$filter_config_ignoreUrlParams() default ""; |
| |
| @AttributeDefinition(name = "Include path rewriting", description = "Check to enable include path rewriting") |
| boolean include$_$filter_config_rewrite() default false; |
| |
| @AttributeDefinition(name = "Append suffix to dynamic includes", description = "Check to append the suffix of the parent request to the dynamic include.") |
| boolean include$_$filter_config_appendSuffix() default true; |
| |
| @AttributeDefinition(name = "Disable ignore URL params check", description = "Disable the check in the Ignore URL Params setting.") |
| boolean include$_$filter_config_disableIgnoreUrlParams() default false; |
| } |
| |
| private static final Logger LOG = LoggerFactory.getLogger(Configuration.class); |
| |
| private PathMatcher pathMatcher; |
| |
| private boolean isEnabled; |
| |
| private String includeSelector; |
| |
| private String extension; |
| |
| private int ttl; |
| |
| private List<String> resourceTypes; |
| |
| private boolean addComment; |
| |
| private String includeTypeName; |
| |
| private String requiredHeader; |
| |
| private boolean disableIgnoreUrlParams; |
| |
| private List<String> ignoreUrlParams; |
| |
| private boolean rewritePath; |
| |
| private boolean appendSuffix; |
| |
| @Activate |
| public void activate(Config cfg) { |
| isEnabled = cfg.include$_$filter_config_enabled(); |
| String pathPattern = cfg.include$_$filter_config_path(); |
| pathMatcher = choosePathMatcher(pathPattern); |
| String[] resourceTypeList; |
| resourceTypeList = PropertiesUtil.toStringArray(cfg.include$_$filter_config_resource$_$types(), new String[0]); |
| for (int i = 0; i < resourceTypeList.length; i++) { |
| String[] s = resourceTypeList[i].split(";"); |
| String name = s[0].trim(); |
| resourceTypeList[i] = name; |
| } |
| this.resourceTypes = Arrays.asList(resourceTypeList); |
| |
| includeSelector = cfg.include$_$filter_config_selector(); |
| extension = cfg.include$_$filter_config_extension(); |
| ttl = PropertiesUtil.toInteger(cfg.include$_$filter_config_ttl(), -1); |
| addComment = cfg.include$_$filter_config_add__comment(); |
| includeTypeName = cfg.include$_$filter_config_include$_$type(); |
| requiredHeader = cfg.include$_$filter_config_required__header(); |
| ignoreUrlParams = Arrays.asList(PropertiesUtil.toStringArray(cfg.include$_$filter_config_ignoreUrlParams(), |
| new String[0])); |
| rewritePath = cfg.include$_$filter_config_rewrite(); |
| appendSuffix = cfg.include$_$filter_config_appendSuffix(); |
| disableIgnoreUrlParams = cfg.include$_$filter_config_disableIgnoreUrlParams(); |
| } |
| |
| private PathMatcher choosePathMatcher(String pathPattern) { |
| PathMatcher result; |
| if (pathPattern.startsWith("^")) { |
| LOG.debug("Configured path value: {} is a regexp - will use a RegexPathMatcher.", pathPattern); |
| result = new RegexPathMatcher(pathPattern); |
| } else { |
| LOG.debug("Configured path value: {} is NOT a regexp - will use a PrefixPathMatcher.", pathPattern); |
| result = new PrefixPathMatcher(pathPattern); |
| } |
| return result; |
| } |
| |
| public PathMatcher getPathMatcher() { |
| return pathMatcher; |
| } |
| |
| public boolean hasIncludeSelector(SlingHttpServletRequest request) { |
| return ArrayUtils.contains(request.getRequestPathInfo().getSelectors(), includeSelector); |
| } |
| |
| public String getIncludeSelector() { |
| return includeSelector; |
| } |
| |
| public boolean hasExtension(final SlingHttpServletRequest request) { |
| final String suffix = request.getRequestPathInfo().getSuffix(); |
| return suffix.endsWith("." + this.extension); |
| } |
| |
| public boolean hasExtensionSet() { |
| return StringUtils.isNotBlank(this.extension); |
| } |
| |
| public String getExtension() { |
| return this.extension; |
| } |
| |
| public boolean hasTtlSet() { |
| return ttl >= 0; |
| } |
| |
| public int getTtl() { |
| return ttl; |
| } |
| |
| public boolean isSupportedResourceType(String resourceType) { |
| return StringUtils.isNotBlank(resourceType) && resourceTypes.contains(resourceType); |
| } |
| |
| public boolean getAddComment() { |
| return addComment; |
| } |
| |
| public String getIncludeTypeName() { |
| return includeTypeName; |
| } |
| |
| public boolean isEnabled() { |
| return isEnabled; |
| } |
| |
| public String getRequiredHeader() { |
| return requiredHeader; |
| } |
| |
| public List<String> getIgnoreUrlParams() { |
| return ignoreUrlParams; |
| } |
| |
| public boolean isDisableIgnoreUrlParams() { |
| return disableIgnoreUrlParams; |
| } |
| |
| public boolean isRewritePath() { |
| return rewritePath; |
| } |
| |
| public boolean isAppendSuffix() { |
| return appendSuffix; |
| } |
| } |