private void refreshDispatcher()

in src/main/java/org/apache/sling/servlets/resolver/internal/bundle/BundledScriptTracker.java [492:569]


    private void refreshDispatcher(List<ServiceRegistration<Servlet>> regs) {
        BundleContext bc = bundleContext.get();
        Map<Bundle, List<ServiceRegistration<Servlet>>> tracked;
        BundleTracker<List<ServiceRegistration<Servlet>>> bt = tracker.get();
        if (bt != null) {
            tracked = bt.getTracked();
        } else {
            tracked = Collections.emptyMap();
        }
        Map<Set<String>, ServiceRegistration<Servlet>> oldDispatchers = dispatchers.get();
        Map<Set<String>, ServiceRegistration<Servlet>> newDispatchers = new HashMap<>();
        final Converter c = Converters.standardConverter();
        Stream.concat(tracked.values().stream(), Stream.of(regs))
                .flatMap(List::stream)
                .filter(ref -> getResourceTypeVersion(ref.getReference()) != null)
                .map(this::toProperties)
                .collect(Collectors.groupingBy(BundledScriptTracker::getResourceTypes))
                .forEach((rt, propList) -> {
                    Hashtable<String, Object> properties = new Hashtable<>(); // NOSONAR
                    properties.put(
                            ServletResolverConstants.SLING_SERVLET_NAME,
                            String.format("%s (%s)", DispatcherServlet.class.getSimpleName(), rt));
                    properties.put(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES, rt.toArray());
                    Set<String> methods = propList.stream()
                            .map(props -> props.getOrDefault(
                                    ServletResolverConstants.SLING_SERVLET_METHODS, new String[] {"GET", "HEAD"}))
                            .map(v -> c.convert(v).to(String[].class))
                            .map(Arrays::asList)
                            .flatMap(List::stream)
                            .collect(Collectors.toSet());
                    Set<String> extensions = propList.stream()
                            .map(props -> props.getOrDefault(
                                    ServletResolverConstants.SLING_SERVLET_EXTENSIONS, new String[] {"html"}))
                            .map(v -> c.convert(v).to(String[].class))
                            .map(Arrays::asList)
                            .flatMap(List::stream)
                            .collect(Collectors.toSet());
                    properties.put(
                            ServletResolverConstants.SLING_SERVLET_EXTENSIONS, extensions.toArray(new String[0]));
                    if (!methods.equals(new HashSet<>(Arrays.asList("GET", "HEAD")))) {
                        properties.put(ServletResolverConstants.SLING_SERVLET_METHODS, methods.toArray(new String[0]));
                    }

                    ServiceRegistration<Servlet> reg = oldDispatchers.remove(rt);
                    if (reg == null) {
                        Optional<BundleContext> registeringBundle = propList.stream()
                                .map(props -> {
                                    Bundle bundle = (Bundle) props.get(REGISTERING_BUNDLE);
                                    if (bundle != null) {
                                        return bundle.getBundleContext();
                                    }
                                    return null;
                                })
                                .findFirst();
                        properties.put(
                                Constants.SERVICE_DESCRIPTION,
                                DispatcherServlet.class.getName() + "{"
                                        + ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES + "="
                                        + rt + "; " + ServletResolverConstants.SLING_SERVLET_EXTENSIONS
                                        + "=" + extensions + "; " + ServletResolverConstants.SLING_SERVLET_METHODS
                                        + "=" + methods + "}");
                        properties.put(BundledHooks.class.getName(), "true");

                        reg = register(registeringBundle.orElse(bc), new DispatcherServlet(rt), properties);
                    } else {
                        if (!new HashSet<>(Arrays.asList(Converters.standardConverter()
                                        .convert(reg.getReference()
                                                .getProperty(ServletResolverConstants.SLING_SERVLET_METHODS))
                                        .to(String[].class)))
                                .equals(methods)) {
                            reg.setProperties(properties);
                        }
                    }
                    newDispatchers.put(rt, reg);
                });
        oldDispatchers.values().forEach(ServiceRegistration::unregister);
        dispatchers.set(newDispatchers);
    }