Author: cziegeler Date: Wed Sep 16 08:30:46 2009 New Revision: 815665 URL: http://svn.apache.org/viewvc?rev=815665&view=rev Log: Allow global transformers to specify conditions when they apply
Modified: sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/FactoryCache.java sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/PipelineImpl.java sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/ProcessorConfigurationImpl.java Modified: sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/FactoryCache.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/FactoryCache.java?rev=815665&r1=815664&r2=815665&view=diff ============================================================================== --- sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/FactoryCache.java (original) +++ sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/FactoryCache.java Wed Sep 16 08:30:46 2009 @@ -21,9 +21,12 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import org.apache.sling.commons.osgi.OsgiUtil; import org.apache.sling.rewriter.Generator; import org.apache.sling.rewriter.GeneratorFactory; +import org.apache.sling.rewriter.ProcessingContext; import org.apache.sling.rewriter.Processor; +import org.apache.sling.rewriter.ProcessorConfiguration; import org.apache.sling.rewriter.ProcessorFactory; import org.apache.sling.rewriter.Serializer; import org.apache.sling.rewriter.SerializerFactory; @@ -43,6 +46,27 @@ */ public class FactoryCache { + /** The required property containing the component type. */ + private static final String PROPERTY_TYPE = "pipeline.type"; + + /** The optional property for the pipeline mode (global) */ + private static final String PROPERTY_MODE = "pipeline.mode"; + + /** The global mode. */ + private static final String MODE_GLOBAL = "global"; + + /** The optional property for the paths the component should apply to */ + private static final String PROPERTY_PATHS = "pipeline.paths"; + + /** The optional property for the paths the component should apply to */ + private static final String PROPERTY_EXTENSIONS = "pipeline.extensions"; + + /** The optional property for the paths the component should apply to */ + private static final String PROPERTY_CONTENT_TYPES = "pipeline.contentTypes"; + + /** The optional property for the paths the component should apply to */ + private static final String PROPERTY_RESOURCE_TYPES = "pipeline.resourceTypes"; + /** The logger. */ protected static final Logger LOGGER = LoggerFactory.getLogger(FactoryCache.class); @@ -150,37 +174,45 @@ private static final Transformer[][] EMPTY_DOUBLE_ARRAY = new Transformer[][] {EMPTY_ARRAY, EMPTY_ARRAY}; /** - * Lookup all factory components for rewriter transformers and return - * new rewriter transformer instances in two arrays. + * Lookup all global transformers that apply to the current request and return + * the transformer instances in two arrays. * The first array contains all pre transformers and the second one contains * all post transformers. + * @param context The current processing context. */ - public Transformer[][] getRewriterTransformers() { - final TransformerFactory[][] factories = this.transformerTracker.getTransformerFactories(); + public Transformer[][] getGlobalTransformers(final ProcessingContext context) { + final TransformerFactory[][] factories = this.transformerTracker.getGlobalTransformerFactories(context); return createTransformers(factories); } + /** + * Create new instances from the factories + * @param factories The transformer factories + * @return The transformer instances + */ protected Transformer[][] createTransformers(final TransformerFactory[][] factories) { if ( factories == EMPTY_DOUBLE_ARRAY ) { return FactoryCache.EMPTY_DOUBLE_ARRAY; } final Transformer[][] transformers = new Transformer[2][]; - if ( factories[0].length == 0 ) { - transformers[0] = FactoryCache.EMPTY_ARRAY; - } else { - transformers[0] = new Transformer[factories[0].length]; - for(int i=0; i < factories[0].length; i++) { - transformers[0][i] = factories[0][i].createTransformer(); + for(int arrayIndex = 0; arrayIndex < 2; arrayIndex++) { + int count = factories[arrayIndex].length; + for(final TransformerFactory factory : factories[arrayIndex]) { + if ( factory == null ) count--; } - } - if ( factories[1].length == 0 ) { - transformers[1] = FactoryCache.EMPTY_ARRAY; - } else { - transformers[1] = new Transformer[factories[1].length]; - for(int i=0; i < factories[1].length; i++) { - transformers[1][i] = factories[1][i].createTransformer(); + if ( count == 0 ) { + transformers[arrayIndex] = FactoryCache.EMPTY_ARRAY; + } else { + transformers[arrayIndex] = new Transformer[count]; + for(int i=0; i < factories[arrayIndex].length; i++) { + final TransformerFactory factory = factories[arrayIndex][i]; + if ( factory != null ) { + transformers[arrayIndex][i] = factory.createTransformer(); + } + } } } + return transformers; } @@ -205,7 +237,7 @@ } private String getType(final ServiceReference ref) { - final String type = (String) ref.getProperty("pipeline.type"); + final String type = (String) ref.getProperty(PROPERTY_TYPE); return type; } @@ -239,18 +271,21 @@ protected static final class TransformerFactoryServiceTracker<T> extends HashingServiceTrackerCustomizer<T> { private String getMode(final ServiceReference ref) { - final String mode = (String) ref.getProperty("pipeline.mode"); + final String mode = (String) ref.getProperty(PROPERTY_MODE); return mode; } private boolean isGlobal(final ServiceReference ref) { - return "global".equalsIgnoreCase(this.getMode(ref)); + return MODE_GLOBAL.equalsIgnoreCase(this.getMode(ref)); } - public static final TransformerFactory[] EMPTY_ARRAY = new TransformerFactory[0]; - public static final TransformerFactory[][] EMPTY_DOUBLE_ARRAY = new TransformerFactory[][] {EMPTY_ARRAY, EMPTY_ARRAY}; + public static final TransformerFactoryEntry[] EMPTY_ENTRY_ARRAY = new TransformerFactoryEntry[0]; + public static final TransformerFactoryEntry[][] EMPTY_DOUBLE_ENTRY_ARRAY = new TransformerFactoryEntry[][] {EMPTY_ENTRY_ARRAY, EMPTY_ENTRY_ARRAY}; + + public static final TransformerFactory[] EMPTY_FACTORY_ARRAY = new TransformerFactory[0]; + public static final TransformerFactory[][] EMPTY_DOUBLE_FACTORY_ARRAY = new TransformerFactory[][] {EMPTY_FACTORY_ARRAY, EMPTY_FACTORY_ARRAY}; - private TransformerFactory[][] cached = EMPTY_DOUBLE_ARRAY; + private TransformerFactoryEntry[][] cached = EMPTY_DOUBLE_ENTRY_ARRAY; /** flag for cache. */ private boolean cacheIsValid = true; @@ -291,13 +326,17 @@ super.removedService(reference, service); } - public TransformerFactory[][] getTransformerFactories() { + /** + * Get all global transformer factories. + * @return Two arrays of transformer factories + */ + public TransformerFactoryEntry[][] getGlobalTransformerFactories() { if ( !this.cacheIsValid ) { synchronized ( this ) { if ( !this.cacheIsValid ) { final ServiceReference[] refs = this.getServiceReferences(); if ( refs == null || refs.length == 0 ) { - this.cached = EMPTY_DOUBLE_ARRAY; + this.cached = EMPTY_DOUBLE_ENTRY_ARRAY; } else { Arrays.sort(refs, ServiceReferenceComparator.INSTANCE); @@ -314,36 +353,65 @@ } } } - final TransformerFactory[][] rewriters = new TransformerFactory[2][]; + final TransformerFactoryEntry[][] globalFactories = new TransformerFactoryEntry[2][]; if ( preCount == 0 ) { - rewriters[0] = EMPTY_ARRAY; + globalFactories[0] = EMPTY_ENTRY_ARRAY; } else { - rewriters[0] = new TransformerFactory[preCount]; + globalFactories[0] = new TransformerFactoryEntry[preCount]; } if ( postCount == 0) { - rewriters[1] = EMPTY_ARRAY; + globalFactories[1] = EMPTY_ENTRY_ARRAY; } else { - rewriters[1] = new TransformerFactory[postCount]; + globalFactories[1] = new TransformerFactoryEntry[postCount]; } int index = 0; for(final ServiceReference ref : refs) { if ( isGlobal(ref) ) { if ( index < preCount ) { - rewriters[0][index] = (TransformerFactory) this.getService(ref); + globalFactories[0][index] = new TransformerFactoryEntry((TransformerFactory) this.getService(ref), ref); } else { - rewriters[1][index - preCount] = (TransformerFactory) this.getService(ref); + globalFactories[1][index - preCount] = new TransformerFactoryEntry((TransformerFactory) this.getService(ref), ref); } index++; } } - this.cached = rewriters; + this.cached = globalFactories; } } this.cacheIsValid = true; } } + return this.cached; } + + /** + * Get all global transformer factories that apply to the current request. + * @param context The current processing context. + * @return Two arrays containing the transformer factories. + */ + public TransformerFactory[][] getGlobalTransformerFactories(final ProcessingContext context) { + final TransformerFactoryEntry[][] globalFactoryEntries = this.getGlobalTransformerFactories(); + // quick check + if ( globalFactoryEntries == EMPTY_DOUBLE_ENTRY_ARRAY ) { + return EMPTY_DOUBLE_FACTORY_ARRAY; + } + final TransformerFactory[][] factories = new TransformerFactory[2][]; + for(int i=0; i<2; i++) { + if ( globalFactoryEntries[i] == EMPTY_ENTRY_ARRAY ) { + factories[i] = EMPTY_FACTORY_ARRAY; + } else { + factories[i] = new TransformerFactory[globalFactoryEntries[i].length]; + for(int m=0; m<globalFactoryEntries[i].length; m++) { + final TransformerFactoryEntry entry = globalFactoryEntries[i][m]; + if ( entry.match(context) ) { + factories[i][m] = entry.factory; + } + } + } + } + return factories; + } } /** @@ -385,4 +453,34 @@ return (id.compareTo(otherId) < 0) ? 1 : -1; } } + + protected static final class TransformerFactoryEntry { + public final TransformerFactory factory; + + private final ProcessorConfiguration configuration; + + public TransformerFactoryEntry(final TransformerFactory factory, final ServiceReference ref) { + this.factory = factory; + final String[] paths = OsgiUtil.toStringArray(ref.getProperty(PROPERTY_PATHS), null); + final String[] extensions = OsgiUtil.toStringArray(ref.getProperty(PROPERTY_EXTENSIONS), null); + final String[] contentTypes = OsgiUtil.toStringArray(ref.getProperty(PROPERTY_CONTENT_TYPES), null); + final String[] resourceTypes = OsgiUtil.toStringArray(ref.getProperty(PROPERTY_RESOURCE_TYPES), null); + final boolean noCheckRequired = (paths == null || paths.length == 0) && + (extensions == null || extensions.length == 0) && + (contentTypes == null || contentTypes.length == 0) && + (resourceTypes == null || resourceTypes.length == 0); + if ( !noCheckRequired ) { + this.configuration = new ProcessorConfigurationImpl(contentTypes, paths, extensions, resourceTypes); + } else { + this.configuration = null; + } + } + + public boolean match(final ProcessingContext context) { + if ( configuration == null ) { + return true; + } + return configuration.match(context); + } + } } Modified: sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/PipelineImpl.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/PipelineImpl.java?rev=815665&r1=815664&r2=815665&view=diff ============================================================================== --- sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/PipelineImpl.java (original) +++ sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/PipelineImpl.java Wed Sep 16 08:30:46 2009 @@ -79,7 +79,7 @@ // create components and initialize them // lets get custom rewriter transformers - final Transformer[][] rewriters = this.factoryCache.getRewriterTransformers(); + final Transformer[][] rewriters = this.factoryCache.getGlobalTransformers(processingContext); final ProcessingComponentConfiguration generatorConfig = config.getGeneratorConfiguration(); this.generator = this.getPipelineComponent(Generator.class, generatorConfig.getType()); Modified: sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/ProcessorConfigurationImpl.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/ProcessorConfigurationImpl.java?rev=815665&r1=815664&r2=815665&view=diff ============================================================================== --- sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/ProcessorConfigurationImpl.java (original) +++ sling/trunk/contrib/extensions/rewriter/src/main/java/org/apache/sling/rewriter/impl/ProcessorConfigurationImpl.java Wed Sep 16 08:30:46 2009 @@ -123,6 +123,16 @@ } /** + * This is the constructor for a pipeline + */ + public ProcessorConfigurationImpl(String[] contentTypes, + String[] paths, + String[] extensions, + String[] resourceTypes) { + this(contentTypes, paths, extensions, resourceTypes, 0, null, null, null, false); + } + + /** * Constructor. * This constructor reads the configuration from the specified resource. */