in src/main/java/org/apache/sling/servlets/resolver/internal/bundle/BundledScriptTracker.java [441:499]
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<>();
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(PropertiesUtil::toStringArray).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(PropertiesUtil::toStringArray).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(PropertiesUtil
.toStringArray(reg.getReference().getProperty(ServletResolverConstants.SLING_SERVLET_METHODS), new String[0])))
.equals(methods)) {
reg.setProperties(properties);
}
}
newDispatchers.put(rt, reg);
});
oldDispatchers.values().forEach(ServiceRegistration::unregister);
dispatchers.set(newDispatchers);
}