package io.neba.core.blueprint; import org.eclipse.gemini.blueprint.context.BundleContextAware; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.Version; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.stereotype.Service; import static org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME; /** * In Sling Engine 2.3.3, the semantics of the <code>service.ranking</code> property was adjusted * to align to the overall use of service rankings (SLING-2920). * Prior to 2.3.3 a low (e.g. negative) value indicated a <em>higher</em> filter priority, i.e. an earlier place in the filter chain. * Since 2.3.3, the opposite is the case. Thus, the ranking of filters published by the NEBA must be adjusted * with regard to the sling engine version. This is what this post processor does. * * @author Olaf Otto */ @Service public class SlingEngineVersionSpecificFilterOrderConfiguration implements BeanFactoryPostProcessor, BundleContextAware { // This property is automatically converted to "service.ranking" by the gemini blueprint service factory. private static final String PROPERTY_RANKING = "ranking"; private BundleContext context; @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { BeanDefinition requestScopedResourceModelCacheService = configurableListableBeanFactory.getBeanDefinition("requestScopedResourceModelCacheService"); if (requestScopedResourceModelCacheService == null) { throw new IllegalStateException("Unable to adjust the service.ranking property of the requestScopedResourceModelCache. " + "Could not locate the bean definition fo the corresponding service in the application context."); } BeanDefinition requestContextFilterService = configurableListableBeanFactory.getBeanDefinition("requestContextFilterService"); if (requestContextFilterService == null) { throw new IllegalStateException("Unable to adjust the service.ranking property of the requestContextFilter. " + "Could not locate the bean definition fo the corresponding service in the application context."); } if (isSlingEngineGreater232()) { requestContextFilterService.getPropertyValues().add(PROPERTY_RANKING, 10000); requestScopedResourceModelCacheService.getPropertyValues().add(PROPERTY_RANKING, 9999); } else { requestContextFilterService.getPropertyValues().add(PROPERTY_RANKING, -10000); requestScopedResourceModelCacheService.getPropertyValues().add(PROPERTY_RANKING, -9999); } } private boolean isSlingEngineGreater232() { for (Bundle bundle : this.context.getBundles()) { if ("org.apache.sling.engine".equals(bundle.getHeaders().get(BUNDLE_SYMBOLICNAME))) { return bundle.getVersion().compareTo(new Version(2, 3, 2)) > 0; } } return false; } @Override public void setBundleContext(BundleContext bundleContext) { this.context = bundleContext; } }