use of org.kohsuke.stapler.DataBoundConstructor in project configuration-as-code-plugin by jenkinsci.
the class DataBoundConfigurator method describe.
@CheckForNull
@Override
public CNode describe(T instance, ConfigurationContext context) throws Exception {
// Here we assume a correctly designed DataBound Object will have required attributes set by DataBoundConstructor
// and all others using DataBoundSetters. So constructor parameters for sure are part of the description, others
// need to be compared with default values.
// Build same object with only constructor parameters
final Constructor constructor = getDataBoundConstructor();
final Parameter[] parameters = constructor.getParameters();
final String[] names = ClassDescriptor.loadParameterNames(constructor);
final Attribute[] attributes = new Attribute[parameters.length];
final Object[] args = new Object[parameters.length];
for (int i = 0; i < parameters.length; i++) {
final Parameter p = parameters[i];
final Attribute a = createAttribute(names[i], TypePair.of(p));
if (a != null) {
Object value = a.getValue(instance);
if (value != null) {
Object converted = Stapler.CONVERT_UTILS.convert(value, a.getType());
if (converted instanceof Collection || p.getType().isArray() || !a.isMultiple()) {
args[i] = converted;
} else if (Set.class.isAssignableFrom(p.getType())) {
args[i] = Collections.singleton(converted);
} else {
args[i] = Collections.singletonList(converted);
}
}
if (args[i] == null && p.getType().isPrimitive()) {
args[i] = defaultPrimitiveValue(p.getType());
}
attributes[i] = a;
}
}
T ref = (T) constructor.newInstance(args);
// compare instance with this "default" object
Mapping mapping = compare(instance, ref, context);
// add constructor parameters
for (int i = 0; i < parameters.length; i++) {
if (args[i] == null)
continue;
mapping.put(names[i], attributes[i].describe(instance, context));
}
return mapping;
}
Aggregations