package org.jboss.windup.rules.apps.java.condition.annotation;
import java.util.HashMap;
import java.util.Map;
import org.jboss.windup.config.GraphRewrite;
import org.jboss.windup.config.condition.EvaluationStrategy;
import org.jboss.windup.rules.apps.java.scan.ast.annotations.JavaAnnotationTypeReferenceModel;
import org.jboss.windup.rules.apps.java.scan.ast.annotations.JavaAnnotationTypeValueModel;
import org.ocpsoft.rewrite.context.EvaluationContext;
import org.ocpsoft.rewrite.param.ParameterizedPatternResult;
import org.ocpsoft.rewrite.param.RegexParameterizedPatternParser;
/**
* Matches on an Annotation type. For example, this would be used if the value of an annotation element
* is itself another annotation.
*
* @author <a href="mailto:jesse.sightler@gmail.com">Jesse Sightler</a>
*/
public class AnnotationTypeCondition extends AnnotationCondition
{
private RegexParameterizedPatternParser pattern;
private Map<String, AnnotationCondition> conditions = new HashMap<>();
/**
* Creates an {@link AnnotationTypeCondition} with the provided pattern.
*/
public AnnotationTypeCondition(String pattern)
{
this.pattern = new RegexParameterizedPatternParser(pattern);
}
/**
* Adds another condition for an element within this annotation.
*/
public AnnotationTypeCondition addCondition(String element, AnnotationCondition condition)
{
this.conditions.put(element, condition);
return this;
}
@Override
public String toString()
{
return "AnnotationTypeCondition{" +
"pattern=" + pattern +
", conditions=" + conditions +
'}';
}
public boolean evaluate(GraphRewrite event, EvaluationContext context, EvaluationStrategy strategy, JavaAnnotationTypeValueModel value)
{
if (!(value instanceof JavaAnnotationTypeReferenceModel))
return false;
JavaAnnotationTypeReferenceModel typeReferenceModel = (JavaAnnotationTypeReferenceModel) value;
// submit the value to the value pattern
if (pattern != null)
{
String annotationValue = typeReferenceModel.getResolvedSourceSnippit();
ParameterizedPatternResult referenceResult = pattern.parse(annotationValue);
if (!referenceResult.matches())
return false;
referenceResult.submit(event, context);
}
return evaluateChildConditions(event, context, strategy, typeReferenceModel);
}
protected boolean evaluateChildConditions(GraphRewrite event, EvaluationContext context, EvaluationStrategy strategy,
JavaAnnotationTypeReferenceModel annotation)
{
// recursively scan additional conditions
for (Map.Entry<String, AnnotationCondition> conditionEntry : conditions.entrySet())
{
JavaAnnotationTypeValueModel subValue = annotation.getAnnotationValues().get(conditionEntry.getKey());
if (subValue == null)
return false;
if (!conditionEntry.getValue().evaluate(event, context, strategy, subValue))
return false;
}
return true;
}
}