/******************************************************************************* * Copyright (c) 2013 Rene Schneider, GEBIT Solutions GmbH and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package de.gebit.integrity.annotation; import java.lang.annotation.Annotation; import org.eclipse.xtext.common.types.JvmAnnotationReference; import org.eclipse.xtext.common.types.JvmAnnotationValue; import org.eclipse.xtext.common.types.JvmFormalParameter; import org.eclipse.xtext.util.Pair; import com.google.common.base.Function; import com.google.common.base.Preconditions; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableSet; import de.gebit.integrity.fixtures.FixtureParameter; import de.gebit.integrity.forker.ForkerParameter; /** * Convenience accessment for the {@link FixtureParameter} or {@link ForkerParameter} annotation, which eagerly load the * requested values from the annotation. * * @author tilois - Initial API and Implementation */ public class FixtureParameterAssessment { /** Name of the parameter. */ private final String name; /** Is the parameter optional? */ private final boolean mandatory; /** List of acceptable annotation classes. */ public static final ImmutableSet<Class<? extends Annotation>> ACCEPTED_ANNOTATION = ImmutableSet.of( FixtureParameter.class, ForkerParameter.class); /** List of annotation names. */ protected static final ImmutableSet<String> ACCEPTED_ANNOTATION_NAMES; static { ImmutableSet.Builder<String> tempBuilder = new ImmutableSet.Builder<String>(); for (Class<? extends Annotation> tempAnnotation : ACCEPTED_ANNOTATION) { tempBuilder.add(tempAnnotation.getCanonicalName()); } ACCEPTED_ANNOTATION_NAMES = tempBuilder.build(); } /** * List of types known as primitive types. */ protected static final ImmutableSet<String> PRIMITIVE_TYPE_NAMES = ImmutableSet.of("byte", "short", "int", "long", "boolean", "float", "double", "char"); /** * Checks if the given annotation is a valid annotation that can be wrapped. * * @param anAnnotation * Annotation to check. * @return <code>true</code> if it can be wrapped, <code>false</code> otherwise. */ public static boolean isAssignable(JvmAnnotationReference anAnnotation) { return ACCEPTED_ANNOTATION_NAMES.contains(anAnnotation.getAnnotation().getQualifiedName()); } /** Predicate to match optional parameters. */ public static final Predicate<FixtureParameterAssessment> IS_MANDATORY = new Predicate<FixtureParameterAssessment>() { public boolean apply(FixtureParameterAssessment anParameter) { return anParameter.isMandatory(); }; }; /** Function which maps a parameter to its name. */ public static final Function<FixtureParameterAssessment, String> NAME = new Function<FixtureParameterAssessment, String>() { public String apply(FixtureParameterAssessment aParameter) { return aParameter.getName(); }; }; /** * Wraps the given parameter/annotation tuple with the help of the evaluation object. * * @param anEvaluation * Evaluation which provides access to the annotation * @param aParameterTuple * Parameter/annotation to wrap */ public FixtureParameterAssessment(JvmFixtureEvaluation anEvaluation, Pair<JvmFormalParameter, JvmAnnotationReference> aParameterTuple) { Preconditions.checkNotNull(aParameterTuple); Preconditions.checkNotNull(anEvaluation); JvmFormalParameter tempParameter = aParameterTuple.getFirst(); JvmAnnotationReference tempAnnotation = aParameterTuple.getSecond(); Preconditions.checkArgument(isAssignable(aParameterTuple.getSecond())); JvmAnnotationValue tempName = anEvaluation.getValueByName(tempAnnotation, "name"); JvmAnnotationValue tempOptional = anEvaluation.getValueByName(tempAnnotation, "mandatory"); name = anEvaluation.evaluateSingle(tempName, String.class); boolean tempMandatory = anEvaluation.evaluateSingle(tempOptional, Boolean.class); if (!tempMandatory && tempParameter.getParameterType() != null) { // Primitive types are automatically mandatory; they can technically not be made optional. tempMandatory = PRIMITIVE_TYPE_NAMES.contains(tempParameter.getParameterType().getQualifiedName()); } mandatory = tempMandatory; } public String getName() { return name; } public boolean isMandatory() { return mandatory; } }