Hi all,
I am implementing a programmatic solution to modify the ranking of "legacy"
filters with regard to the changed filter order in Sling Engine 2.3.3
(https://issues.apache.org/jira/browse/SLING-2920). I couldn't really figure
out a "clean" way to alter the service properties of arbitrary (including
on-managed) filter components programmatically, but I got it working with a bit
of reflection. That said, here is my solution sketch (it works) - does anyone
know of a cleaner way to adjust these properties at runtime?
@Component(immediate = true)
public class SlingEngineFilterOrderAdjuster {
private static final String PROPERTY_RANKING_ADJUSTED =
"aem61.ranking.adjusted";
private final Logger logger = LoggerFactory.getLogger(getClass());
private ServiceTracker tracker;
@Activate
@SuppressWarnings("unchecked")
protected void activate(ComponentContext context) {
Filter filter;
try {
filter = context.getBundleContext().createFilter(
"(&" +
"(objectClass=" +
javax.servlet.Filter.class.getName() + ")&(" +
"|(component.name=my.package.namesppace.*)(" +
BUNDLE_SYMBOLICNAME + "=my.bundle.namespace.*)))");
} catch (Exception e) {
logger.error(e.getMessage(), e);
return;
}
tracker = new ServiceTracker(context.getBundleContext(), filter, null) {
@Override
public Object addingService(ServiceReference reference) {
if (reference.getProperty(PROPERTY_RANKING_ADJUSTED) != null) {
return super.addingService(reference);
}
try {
Method getRegistration =
reference.getClass().getDeclaredMethod("getRegistration", (Class[]) null);
getRegistration.setAccessible(true);
ServiceRegistration registration = (ServiceRegistration)
getRegistration.invoke(reference);
Dictionary<String, Object> properties = new Hashtable<>();
for (String key : reference.getPropertyKeys()) {
if (SERVICE_RANKING.equals(key)) {
Integer value = (Integer)
reference.getProperty(key);
properties.put(key, -1 * value);
} else {
properties.put(key, reference.getProperty(key));
}
properties.put(PROPERTY_RANKING_ADJUSTED, true);
}
registration.setProperties(properties);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return super.addingService(reference);
}
};
tracker.open(true);
}
@Deactivate
protected void deactivate() {
tracker.close();
}
Regards,
Olaf