in src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java [265:451]
protected void activate(final BundleContext bundleContext, final ResourceResolverFactoryConfig config) {
this.bundleContext = bundleContext;
this.config = config;
final BidiMap<String, String> virtuals = new TreeBidiMap<>();
for (int i = 0; config.resource_resolver_virtual() != null && i < config.resource_resolver_virtual().length; i++) {
final String[] parts = Mapping.split(config.resource_resolver_virtual()[i]);
virtuals.put(parts[0], parts[2]);
}
virtualURLMap = virtuals;
final List<Mapping> maps = new ArrayList<>();
for (int i = 0; config.resource_resolver_mapping() != null && i < config.resource_resolver_mapping().length; i++) {
maps.add(new Mapping(config.resource_resolver_mapping()[i]));
}
final Mapping[] tmp = maps.toArray(new Mapping[maps.size()]);
// check whether direct mappings are allowed
if (config.resource_resolver_allowDirect()) {
final Mapping[] tmp2 = new Mapping[tmp.length + 1];
tmp2[0] = Mapping.DIRECT;
System.arraycopy(tmp, 0, tmp2, 1, tmp.length);
mappings = tmp2;
} else {
mappings = tmp;
}
// from configuration if available
final List<String> searchPathList = new ArrayList<>();
if (config.resource_resolver_searchpath() != null && config.resource_resolver_searchpath().length > 0) {
for(String path : config.resource_resolver_searchpath()) {
// ensure leading slash
if (!path.startsWith("/")) {
path = "/".concat(path);
}
// ensure trailing slash
if (!path.endsWith("/")) {
path = path.concat("/");
}
searchPathList.add(path);
}
}
if (searchPathList.isEmpty()) {
searchPathList.add("/");
}
this.searchPath = Collections.unmodifiableList(searchPathList);
// the root of the resolver mappings
mapRoot = config.resource_resolver_map_location();
mapRootPrefix = mapRoot + '/';
final String[] paths = config.resource_resolver_map_observation();
this.observationPaths = new Path[paths.length];
for(int i=0;i<paths.length;i++) {
this.observationPaths[i] = new Path(paths[i]);
}
// optimize alias path allow list
String[] aliasLocationsPrefix = config.resource_resolver_allowed_alias_locations();
if ( aliasLocationsPrefix != null ) {
final Set<String> prefixSet = new TreeSet<>();
for(final String prefix : aliasLocationsPrefix) {
String value = prefix.trim();
if (!value.isEmpty()) {
if (value.startsWith("/")) { // absolute path should be given
// path must not end with "/" to be valid absolute path
prefixSet.add(StringUtils.removeEnd(value, "/"));
}else{
logger.warn("Path [{}] is ignored. As only absolute paths are allowed for alias optimization", value);
}
}
}
if ( !prefixSet.isEmpty()) {
this.allowedAliasLocations = Collections.unmodifiableSet(prefixSet);
}
}
// vanity path white list
this.vanityPathWhiteList = null;
String[] vanityPathPrefixes = config.resource_resolver_vanitypath_whitelist();
if ( vanityPathPrefixes != null ) {
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() + "/");
}
}
}
if ( prefixList.size() > 0 ) {
this.vanityPathWhiteList = prefixList.toArray(new String[prefixList.size()]);
}
}
// vanity path black list
this.vanityPathBlackList = null;
vanityPathPrefixes = config.resource_resolver_vanitypath_blacklist();
if ( vanityPathPrefixes != null ) {
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() + "/");
}
}
}
if ( prefixList.size() > 0 ) {
this.vanityPathBlackList = prefixList.toArray(new String[prefixList.size()]);
}
}
// check for required property
Set<String> requiredResourceProvidersLegacy = getStringSet(config.resource_resolver_required_providers());
Set<String> requiredResourceProviderNames = getStringSet(config.resource_resolver_required_providernames());
boolean hasLegacyRequiredProvider = false;
if ( requiredResourceProvidersLegacy != null ) {
hasLegacyRequiredProvider = requiredResourceProvidersLegacy.remove(ResourceResolverFactoryConfig.LEGACY_REQUIRED_PROVIDER_PID);
if ( !requiredResourceProvidersLegacy.isEmpty() ) {
logger.error("ResourceResolverFactory is using deprecated required providers configuration (resource.resolver.required.providers" +
"). Please change to use the property resource.resolver.required.providernames for values: " + requiredResourceProvidersLegacy);
} else {
requiredResourceProvidersLegacy = null;
}
}
if ( hasLegacyRequiredProvider ) {
final boolean hasRequiredProvider;
if ( requiredResourceProviderNames != null ) {
hasRequiredProvider = !requiredResourceProviderNames.add(ResourceResolverFactoryConfig.REQUIRED_PROVIDER_NAME);
} else {
hasRequiredProvider = false;
requiredResourceProviderNames = Collections.singleton(ResourceResolverFactoryConfig.REQUIRED_PROVIDER_NAME);
}
if ( hasRequiredProvider ) {
logger.warn("ResourceResolverFactory is using deprecated required providers configuration (resource.resolver.required.providers" +
") with value '" + ResourceResolverFactoryConfig.LEGACY_REQUIRED_PROVIDER_PID + ". Please remove this configuration property. " +
ResourceResolverFactoryConfig.REQUIRED_PROVIDER_NAME + " is already contained in the property resource.resolver.required.providernames.");
} else {
logger.warn("ResourceResolverFactory is using deprecated required providers configuration (resource.resolver.required.providers" +
") with value '" + ResourceResolverFactoryConfig.LEGACY_REQUIRED_PROVIDER_PID + ". Please remove this configuration property and add " +
ResourceResolverFactoryConfig.REQUIRED_PROVIDER_NAME + " to the property resource.resolver.required.providernames.");
}
}
// for testing: if we run unit test, both trackers are set from the outside
if ( this.resourceProviderTracker == null ) {
this.resourceProviderTracker = new ResourceProviderTracker();
this.changeListenerWhiteboard = new ResourceChangeListenerWhiteboard();
this.preconds.activate(this.bundleContext,
requiredResourceProvidersLegacy,
requiredResourceProviderNames,
resourceProviderTracker);
this.changeListenerWhiteboard.activate(this.bundleContext,
this.resourceProviderTracker, searchPath);
this.resourceProviderTracker.activate(this.bundleContext,
this.eventAdmin,
new ChangeListener() {
@Override
public void providerAdded() {
if ( factoryRegistration == null ) {
checkFactoryPreconditions(null, null);
}
}
@Override
public void providerRemoved(final String name, final String pid, final boolean stateful, final boolean isUsed) {
if ( factoryRegistration != null ) {
if ( isUsed && (stateful || config.resource_resolver_providerhandling_paranoid()) ) {
unregisterFactory();
}
checkFactoryPreconditions(name, pid);
}
}
});
} else {
this.preconds.activate(this.bundleContext,
requiredResourceProvidersLegacy,
requiredResourceProviderNames,
resourceProviderTracker);
this.checkFactoryPreconditions(null, null);
}
}