package org.jboss.windup.reporting.ruleexecution;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import org.jboss.windup.config.AbstractRuleProvider;
import org.jboss.windup.config.GraphRewrite;
import org.jboss.windup.config.RuleLifecycleListener;
import org.jboss.windup.config.metadata.RuleProviderRegistry;
import org.ocpsoft.rewrite.config.Rule;
import org.ocpsoft.rewrite.context.EvaluationContext;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.util.wrappers.event.listener.GraphChangedListener;
/**
* Manages recording the history of {@link Rule}s executed by Windup.
*
* @author <a href="mailto:jesse.sightler@gmail.com">Jesse Sightler</a>
* @author <a href="mailto:zizka@seznam.cz">Ondrej Zizka</a>
*/
public class RuleExecutionResultsListener implements RuleLifecycleListener
{
private final IdentityHashMap<Rule, RuleExecutionInformation> ruleExecutionInformation = new IdentityHashMap<>();
private GraphRewrite event;
private Rule currentRule = null;
/**
* Returns the {@link RuleExecutionResultsListener} for this execution of Windup.
*/
public static RuleExecutionResultsListener instance(GraphRewrite event)
{
return (RuleExecutionResultsListener) event.getRewriteContext().get(RuleExecutionResultsListener.class);
}
/**
*
*/
public List<RuleExecutionInformation> getRuleExecutionInformation(AbstractRuleProvider provider)
{
RuleProviderRegistry ruleExecutionMetadata = RuleProviderRegistry.instance(event);
List<Rule> rules = ruleExecutionMetadata.getRules(provider);
List<RuleExecutionInformation> allRuleExecutions = new ArrayList<>();
for (Rule rule : rules)
{
allRuleExecutions.add(ruleExecutionInformation.get(rule));
}
return allRuleExecutions;
}
@Override
public void beforeExecution(GraphRewrite event)
{
ruleExecutionInformation.clear();
this.event = event;
event.getRewriteContext().put(RuleExecutionResultsListener.class, this);
event.getGraphContext().getGraph().addListener(new GraphChangeListener());
}
@Override
public boolean beforeRuleEvaluation(GraphRewrite event, Rule rule, EvaluationContext context)
{
ruleExecutionInformation.put(rule, new RuleExecutionInformation(rule));
RuleExecutionResultsListener.this.currentRule = rule;
return false; // Don't request a stop.
}
@Override
public boolean ruleEvaluationProgress(GraphRewrite event, String name, int currentPosition, int total, int timeRemainingInSeconds)
{
return false; // Don't request a stop.
}
@Override
public void afterRuleConditionEvaluation(GraphRewrite event, EvaluationContext context, Rule rule,
boolean result)
{
ruleExecutionInformation.get(rule).setEvaluationResult(result);
if (!result)
{
RuleExecutionResultsListener.this.currentRule = null;
}
}
@Override
public boolean beforeRuleOperationsPerformed(GraphRewrite event, EvaluationContext context, Rule rule)
{
return false; // Don't request a stop.
}
@Override
public void afterRuleOperationsPerformed(GraphRewrite event, EvaluationContext context, Rule rule)
{
ruleExecutionInformation.get(rule).setExecuted(true);
RuleExecutionResultsListener.this.currentRule = null;
}
@Override
public void afterRuleExecutionFailed(GraphRewrite event, EvaluationContext context, Rule rule, Throwable failureCause)
{
ruleExecutionInformation.get(rule).setFailed(true);
ruleExecutionInformation.get(rule).setFailureCause(failureCause);
RuleExecutionResultsListener.this.currentRule = null;
}
@Override
public void afterExecution(GraphRewrite event)
{
}
/**
* Stores or counts the information about graph changes, especially which rules created which elements.
*/
private class GraphChangeListener implements GraphChangedListener
{
@Override
public synchronized void vertexAdded(Vertex vertex)
{
if (currentRule != null)
{
ruleExecutionInformation.get(currentRule).addVertexIDAdded(vertex.getId());
}
}
@Override
public synchronized void vertexRemoved(Vertex vertex, Map<String, Object> props)
{
if (currentRule != null)
{
ruleExecutionInformation.get(currentRule).addVertexIDRemoved(vertex.getId());
}
}
@Override
public synchronized void edgeAdded(Edge edge)
{
if (currentRule != null)
{
ruleExecutionInformation.get(currentRule).addEdgeIDAdded(edge.getId());
}
}
@Override
public synchronized void edgeRemoved(Edge edge, Map<String, Object> props)
{
if (currentRule != null)
{
ruleExecutionInformation.get(currentRule).addVertexIDRemoved(edge.getId());
}
}
@Override
public void edgePropertyRemoved(Edge edge, String key, Object removedValue)
{
}
@Override
public void vertexPropertyChanged(Vertex vertex, String key, Object oldValue, Object setValue)
{
}
@Override
public void vertexPropertyRemoved(Vertex vertex, String key, Object removedValue)
{
}
@Override
public void edgePropertyChanged(Edge edge, String key, Object oldValue, Object setValue)
{
}
}
}