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