blob: f6808f11533b037fd24fe25f458d29efc7cea254 [file] [log] [blame]
/*
* 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.resourceresolver.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.sling.resourceresolver.impl.mapping.MapConfigurationProvider.VanityPathConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class VanityPathConfigurer {
public @interface DeprecatedVanityConfig {
/** This is the deprecated fallback configuration for resource_resolver_vanitypath_allowlist() */
String[] resource_resolver_vanitypath_whitelist();
/** This is the deprecated fallback configuration for resource_resolver_vanitypath_denylist() */
String[] resource_resolver_vanitypath_blacklist();
}
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private volatile ResourceResolverFactoryConfig config;
private volatile List<VanityPathConfig> vanityPathConfig;
public void setConfiguration(final ResourceResolverFactoryConfig c, final DeprecatedVanityConfig deprecatedConfig) {
this.config = c;
this.vanityPathConfig = null;
final List<String> includes = this.configureVanityPathPrefixes(c.resource_resolver_vanitypath_allowlist(),
deprecatedConfig == null ? null : deprecatedConfig.resource_resolver_vanitypath_whitelist(),
"resource.resolver.vanitypath.allowlist",
"resource.resolver.vanitypath.whitelist");
final List<String> excludes = this.configureVanityPathPrefixes(c.resource_resolver_vanitypath_denylist(),
deprecatedConfig == null ? null : deprecatedConfig.resource_resolver_vanitypath_blacklist(),
"resource.resolver.vanitypath.denylist",
"resource.resolver.vanitypath.blacklist");
if ( includes != null || excludes != null ) {
this.vanityPathConfig = new ArrayList<>();
if ( includes != null ) {
for(final String val : includes) {
this.vanityPathConfig.add(new VanityPathConfig(val, false));
}
}
if ( excludes != null ) {
for(final String val : excludes) {
this.vanityPathConfig.add(new VanityPathConfig(val, true));
}
}
Collections.sort(this.vanityPathConfig);
}
}
public int getDefaultVanityPathRedirectStatus() {
return config.resource_resolver_default_vanity_redirect_status();
}
public boolean isVanityPathEnabled() {
return this.config.resource_resolver_enable_vanitypath();
}
public boolean isVanityPathCacheInitInBackground() {
return this.config.resource_resolver_vanitypath_cache_in_background();
}
public List<VanityPathConfig> getVanityPathConfig() {
return this.vanityPathConfig;
}
public boolean hasVanityPathPrecedence() {
return this.config.resource_resolver_vanity_precedence();
}
public long getMaxCachedVanityPathEntries() {
return this.config.resource_resolver_vanitypath_maxEntries();
}
public boolean isMaxCachedVanityPathEntriesStartup() {
return this.config.resource_resolver_vanitypath_maxEntries_startup();
}
public int getVanityBloomFilterMaxBytes() {
return this.config.resource_resolver_vanitypath_bloomfilter_maxBytes();
}
private boolean isDefined(final String[] value) {
return value != null && value.length > 0;
}
List<String> configureVanityPathPrefixes(final String[] pathPrefixes, final String[] pathPrefixesFallback,
String pathPrefixesPropertyName, String pathPrefixesFallbackPropertyName) {
if (isDefined(pathPrefixes) && isDefined(pathPrefixesFallback) ) {
logger.error("Both properties, " + pathPrefixesPropertyName + " and " + pathPrefixesFallbackPropertyName
+ ", were defined. Using " + pathPrefixesPropertyName + " for configuring vanity paths. "
+ "Please remove the other property from your configuration.");
return filterVanityPathPrefixes(pathPrefixes);
} else if (isDefined(pathPrefixes)) {
return filterVanityPathPrefixes(pathPrefixes);
} else if (isDefined(pathPrefixesFallback)) {
logger.warn("The property " + pathPrefixesPropertyName + " was not set. Using the " +
pathPrefixesFallbackPropertyName + " instead. Please update your configuration to use " + pathPrefixesPropertyName);
return filterVanityPathPrefixes(pathPrefixesFallback);
}
return null;
}
private static List<String> filterVanityPathPrefixes(final String[] vanityPathPrefixes) {
final List<String> prefixList = new ArrayList<>();
for (final String value : vanityPathPrefixes) {
if (value.trim().length() > 0) {
if (value.trim().endsWith("/")) {
prefixList.add(value.trim());
} else {
prefixList.add(value.trim().concat("/"));
}
}
}
return prefixList.isEmpty() ? null : prefixList;
}
}