Search in sources :

Example 1 with DataBoundConstructor

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;
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) Attribute(io.jenkins.plugins.casc.Attribute) DescribableAttribute(io.jenkins.plugins.casc.impl.attributes.DescribableAttribute) DataBoundConstructor(org.kohsuke.stapler.DataBoundConstructor) Constructor(java.lang.reflect.Constructor) Mapping(io.jenkins.plugins.casc.model.Mapping) Parameter(java.lang.reflect.Parameter) Collection(java.util.Collection) CheckForNull(javax.annotation.CheckForNull)

Aggregations

Attribute (io.jenkins.plugins.casc.Attribute)1 DescribableAttribute (io.jenkins.plugins.casc.impl.attributes.DescribableAttribute)1 Mapping (io.jenkins.plugins.casc.model.Mapping)1 Constructor (java.lang.reflect.Constructor)1 Parameter (java.lang.reflect.Parameter)1 Collection (java.util.Collection)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1 CheckForNull (javax.annotation.CheckForNull)1 DataBoundConstructor (org.kohsuke.stapler.DataBoundConstructor)1