1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package Torello.Browser;

import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;

import Torello.Browser.CommandDescriptor;

class BuildScript
{
    @SuppressWarnings("unchecked")
    static <RET> RET build(
            final CommandDescriptor<?>  descriptor,
            final Object[]              assignments,
            final boolean[]             assigned
        )
    {
        if (descriptor.size != assignments.length) throw new BuildScriptError(
            "descriptor.size    = " + descriptor.size + '\n' +
            "assignments.length = " + assignments.length + '\n',
            descriptor
        );

        if (assignments.length != assigned.length) throw new BuildScriptError(
            "assignments.length = " + assignments.length + '\n' +
            "assigned.legth     = " + assigned.length,
            descriptor
        );

        for (int i=0; i < descriptor.size; i++)
            if (assigned[i] == false)
                if (descriptor.optionals.get(i) == false)
                    throw new NullNonOptionalException(
                        "Parameter '" + descriptor.names.get(i) + "' is not optional, " +
                        "but it hasn't been assigned a value either."
                    );

        try
            { return (RET) descriptor.method().invoke(null, assignments); }

        catch (IllegalAccessException | InvocationTargetException | ExceptionInInitializerError e)
        {
            throw new BuildScriptError
                ("There was an error invoking this command method", descriptor, e);
        }
    }

    private static class BuildScriptError extends Error
    {
        protected static final long serialVersionUID = 1;

        private BuildScriptError(
                final String                message,
                final CommandDescriptor<?>  descriptor
            )
        {
            super(
                message + '\n' +
                "Currently Building Command: " +
                descriptor.domain + '.' + descriptor.name
            );
        }

        private BuildScriptError(
                final String                message,
                final CommandDescriptor<?>  descriptor,
                final Throwable             cause
            )
        {
            super(
                message + '\n' +
                "Currently Building Command: " +
                descriptor.domain + '.' + descriptor.name,
                cause
            );
        }
    }
}