// start by getting field information.
List<ValueReference> params = Lists.newArrayList();
List<WorkspaceReference> workspaceFields = Lists.newArrayList();
ValueReference outputField = null;
for (Field field : clazz.getDeclaredFields()) {
Param param = field.getAnnotation(Param.class);
Output output = field.getAnnotation(Output.class);
Workspace workspace = field.getAnnotation(Workspace.class);
Inject inject = field.getAnnotation(Inject.class);
int i =0;
if (param != null) {
i++;
}
if (output != null) {
i++;
}
if (workspace != null) {
i++;
}
if (inject != null) {
i++;
}
if (i == 0) {
return failure("The field must be either a @Param, @Output, @Inject or @Workspace field.", clazz, field);
} else if(i > 1) {
return failure("The field must be only one of @Param, @Output, @Inject or @Workspace. It currently has more than one of these annotations.", clazz, field);
}
if (param != null || output != null) {
// Special processing for @Param FieldReader
if (param != null && FieldReader.class.isAssignableFrom(field.getType())) {
params.add(ValueReference.createFieldReaderRef(field.getName()));
continue;
}
// Special processing for @Output ComplexWriter
if (output != null && ComplexWriter.class.isAssignableFrom(field.getType())) {
if (outputField != null) {
return failure("You've declared more than one @Output field. You must declare one and only @Output field per Function class.", clazz, field);
}else{
outputField = ValueReference.createComplexWriterRef(field.getName());
}
continue;
}
// check that param and output are value holders.
if (!ValueHolder.class.isAssignableFrom(field.getType())) {
return failure(String.format("The field doesn't holds value of type %s which does not implement the ValueHolder interface. All fields of type @Param or @Output must extend this interface..", field.getType()), clazz, field);
}
// get the type field from the value holder.
MajorType type = null;
try {
type = getStaticFieldValue("TYPE", field.getType(), MajorType.class);
} catch (Exception e) {
return failure("Failure while trying to access the ValueHolder's TYPE static variable. All ValueHolders must contain a static TYPE variable that defines their MajorType.", e, clazz, field.getName());
}
ValueReference p = new ValueReference(type, field.getName());
if (param != null) {
if (param.constant()) {
p.setConstant(true);
}
params.add(p);
} else {
if (outputField != null) {
return failure("You've declared more than one @Output field. You must declare one and only @Output field per Function class.", clazz, field);