package org.jboss.windup.config.phase; import org.jboss.windup.config.AbstractRuleProvider; import org.jboss.windup.config.RuleProvider; import org.jboss.windup.config.loader.RuleLoaderContext; import org.jboss.windup.config.metadata.MetadataBuilder; import org.jboss.windup.config.metadata.RuleProviderMetadata; import org.ocpsoft.rewrite.config.Configuration; import org.ocpsoft.rewrite.config.ConfigurationBuilder; import org.ocpsoft.rewrite.config.Rule; /** * Provides a shorthand for stating the order of execution of {@link Rule}s within Windup. When a {@link AbstractRuleProvider} specifies a * {@link RulePhase}, the results of calling {@link RulePhase#getExecuteAfter()} and {@link RulePhase#getExecuteBefore()} on the rule will appended to * the results of {@link RuleProviderMetadata#getExecuteAfter()} and {@link RulePhase#getExecuteBefore()}. * * In this way, most {@link AbstractRuleProvider}s will be able to simply specify a {@link RulePhase} in order to determine their approximate * placement within the execution lifecycle. * * @author <a href="mailto:jesse.sightler@gmail.com">Jesse Sightler</a> */ public abstract class RulePhase extends AbstractRuleProvider { private final Class<? extends RulePhase> thisPhase; private Class<? extends RulePhase> previousPhase; private Class<? extends RulePhase> nextPhase; public RulePhase(Class<? extends RulePhase> implementationType) { super(implementationType, implementationType.getSimpleName()); this.thisPhase = implementationType; } /** * This will always return an empty {@link Configuration} as these are just barriers that do not provide additional * {@link Rule}s. */ @Override public final Configuration getConfiguration(RuleLoaderContext ruleLoaderContext) { return ConfigurationBuilder.begin(); } @Override public final RuleProviderMetadata getMetadata() { return MetadataBuilder.forProvider(thisPhase, thisPhase.getSimpleName()) /** * We set {@link DependentPhase} because it has no executeBefore/executeAfter conditions of its own. * The phase should provide it's own dependencies and not a recursive call to "getPhase()", so * returning a value that has no dependencies of its own is necessary here. */ .setPhase(DependentPhase.class) .addExecuteAfter(_getExecuteAfter()) .addExecuteBefore(_getExecuteBefore()); } private Class<? extends RuleProvider> _getExecuteBefore() { return nextPhase == null ? getExecuteBefore() : nextPhase; } private Class<? extends RuleProvider> _getExecuteAfter() { return previousPhase == null ? getExecuteAfter() : previousPhase; } /** * This allows the {@link RulePhase} implementation to specify the {@link RulePhase} implementation that it should * be executed after. */ public abstract Class<? extends RulePhase> getExecuteAfter(); /** * This allows the {@link RulePhase} implementation to specify the {@link RulePhase} implementation that it should * be executed before. */ public abstract Class<? extends RulePhase> getExecuteBefore(); /** * This allows the sorter to link {@link RulePhase}s to each other, without them having to explicitly specify both * the executeAfter and executeBefore. */ public final void setExecuteAfter(Class<? extends RulePhase> previousPhase) { this.previousPhase = previousPhase; } /** * This allows the sorter to link {@link RulePhase}s to each other, without them having to explicitly specify both * the executeAfter and executeBefore. */ public final void setExecuteBefore(Class<? extends RulePhase> nextPhase) { this.nextPhase = nextPhase; } }