/** * <p>Gets the parameter values to be used for this field. In most cases this will be the values declared * in the {@code @Param} annotation.</p> * * <p>For an enum field type, an empty parameter list will be resolved to be the full list of enum constants * of that type.</p> * * @param fi type of the field for which to find parameters * @return string values representing the actual parameters */ private static String[] toParameterValues(FieldInfo fi) { String[] annotatedValues = fi.getAnnotation(Param.class).value(); boolean isBlankEnum = (annotatedValues.length == 1) && Param.BLANK_ARGS.equals(annotatedValues[0]) && fi.getType().isEnum(); if (isBlankEnum) { Collection<String> enumConstants = fi.getType().getEnumConstants(); if (enumConstants.isEmpty()) { throw new GenerationException("Enum type of field had no constants. " + "Declare some constants or remove the @" + Param.class.getSimpleName() + ".", fi); } return enumConstants.toArray(new String[enumConstants.size()]); } else { return annotatedValues; } }
/** * Compute the parameter space given by {@code @Param} annotations and add all them to the group. * * @param host type of the state {@code @State} in which to find {@code @Param}s * @param group method group */ static void addParameterValuesToGroup(ClassInfo host, MethodGroup group) { // Add all inherited @Param fields for (FieldInfo fi : getAllFields(host)) { if (fi.getAnnotation(Param.class) != null) { String[] values = toParameterValues(fi); group.addParamValues(fi.getName(), values); } } // Add all @Param fields reachable through the dependencies. // This recursive approach always converges because @State dependency graph is DAG. for (MethodInfo mi : getAllMethods(host)) { if (mi.getAnnotation(Setup.class) != null || mi.getAnnotation(TearDown.class) != null) { for (ParameterInfo pi : mi.getParameters()) { addParameterValuesToGroup(pi.getType(), group); } } } }
public Optional<Map<String, String[]>> getParams() { Map<String, String[]> map = new TreeMap<String, String[]>(); for (Map.Entry<String, String[]> e : params.entrySet()) { String key = e.getKey(); String[] values = e.getValue(); if (values.length == 1 && values[0].equalsIgnoreCase(Param.BLANK_ARGS)) { map.put(key, new String[0]); } else { map.put(key, values); } } if (params.isEmpty()) { return Optional.none(); } else { return Optional.of(map); } }
private void checkParam(FieldInfo fi) { if (fi.isStatic()) { throw new GenerationException( "@" + Param.class.getSimpleName() + " annotation is not acceptable on static fields.", fi); } if (BenchmarkGeneratorUtils.getAnnSyntax(fi.getDeclaringClass(), State.class) == null) { throw new GenerationException( "@" + Param.class.getSimpleName() + " annotation should be placed in @" + State.class.getSimpleName() + "-annotated class.", fi); } ClassInfo type = fi.getType(); if (!isParamTypeAcceptable(type)) { throw new GenerationException( "@" + Param.class.getSimpleName() + " can only be placed over the annotation-compatible types:" + " primitives, primitive wrappers, Strings, or enums.", fi); } String[] values = fi.getAnnotation(Param.class).value(); if (values.length == 1 && values[0].equalsIgnoreCase(Param.BLANK_ARGS)) { if (!fi.getType().isEnum()) { throw new GenerationException( "@" + Param.class.getSimpleName() + " should provide the default parameters.", fi); } else { // if type is enum then don't need to check conformity } } else { for (String val : values) { if (!isParamValueConforming(fi, val, type)) { throw new GenerationException( "Some @" + Param.class.getSimpleName() + " values can not be converted to target type: " + "\"" + val + "\" can not be converted to " + type, fi ); } } } }