protected void activate()

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);
         }
    }