private static List constructParameterizedInterceptorReferences()

in core/src/main/java/org/apache/struts2/config/providers/InterceptorBuilder.java [106:217]


    private static List<InterceptorMapping> constructParameterizedInterceptorReferences(
            InterceptorLocator interceptorLocator,
            InterceptorStackConfig stackConfig,
            Map<String,String> refParams,
            ObjectFactory objectFactory) {
        List<InterceptorMapping> result;
        Map<String, Map<String, String>> params = new LinkedHashMap<>();

        /*
         * We strip
         *
         * <interceptor-ref name="someStack">
         *    <param name="interceptor1.param1">someValue</param>
         *    <param name="interceptor1.param2">anotherValue</param>
         * </interceptor-ref>
         *
         * down to map
         *  interceptor1 -> [param1 -> someValue, param2 -> anotherValue]
         *
         * or
         * <interceptor-ref name="someStack">
         *    <param name="interceptorStack1.interceptor1.param1">someValue</param>
         *    <param name="interceptorStack1.interceptor1.param2">anotherValue</param>
         * </interceptor-ref>
         *
         * down to map
         *  interceptorStack1 -> [interceptor1.param1 -> someValue, interceptor1.param2 -> anotherValue]
         *
         */
        for (Map.Entry<String, String> entry : refParams.entrySet()) {
            String key = entry.getKey();

            try {
                String name = key.substring(0, key.indexOf('.'));
                key = key.substring(key.indexOf('.') + 1);

                Map<String, String> map;
                if (params.containsKey(name)) {
                    map = params.get(name);
                } else {
                    map = new LinkedHashMap<>();
                }

                map.put(key, entry.getValue());
                params.put(name, map);

            } catch (Exception e) {
                LOG.warn("No interceptor found for name = {}", key);
            }
        }

        result = new ArrayList<>(stackConfig.getInterceptors());

        for (Map.Entry<String, Map<String, String>> entry : params.entrySet()) {
            String key = entry.getKey();
            Map<String, String> map = entry.getValue();


            Object interceptorCfgObj = interceptorLocator.getInterceptorConfig(key);

            /*
             * Now we attempt to separate out param that refers to Interceptor
             * and Interceptor stack, eg.
             *
             * <interceptor-ref name="someStack">
             *    <param name="interceptor1.param1">someValue</param>
             *    ...
             * </interceptor-ref>
             *
             *  vs
             *
             *  <interceptor-ref name="someStack">
             *    <param name="interceptorStack1.interceptor1.param1">someValue</param>
             *    ...
             *  </interceptor-ref>
             */
            if (interceptorCfgObj instanceof InterceptorConfig cfg) {  //  interceptor-ref param refer to an interceptor
                Interceptor interceptor = objectFactory.buildInterceptor(cfg, map);

                InterceptorMapping mapping = new InterceptorMapping(key, interceptor);
                if (result.contains(mapping)) {
                    for (int index = 0; index < result.size(); index++) {
                        InterceptorMapping interceptorMapping = result.get(index);
                        if (interceptorMapping.getName().equals(key)) {
                            LOG.debug("Overriding interceptor config [{}] with new mapping {} using new params {}", key, interceptorMapping, map);
                            result.set(index, mapping);
                        }
                    }
                } else {
                    result.add(mapping);
                }
            } else
            if (interceptorCfgObj instanceof InterceptorStackConfig stackCfg) {  // interceptor-ref param refer to an interceptor stack

                // If its an interceptor-stack, we call this method recursively until,
                // all the params (eg. interceptorStack1.interceptor1.param etc.)
                // are resolved down to a specific interceptor.

                List<InterceptorMapping> tmpResult = constructParameterizedInterceptorReferences(interceptorLocator, stackCfg, map, objectFactory);
                for (InterceptorMapping tmpInterceptorMapping : tmpResult) {
                    if (result.contains(tmpInterceptorMapping)) {
                        int index = result.indexOf(tmpInterceptorMapping);
                        result.set(index, tmpInterceptorMapping);
                    } else {
                        result.add(tmpInterceptorMapping);
                    }
                }
            }
        }

        return result;
    }