1 | |
package org.apache.commons.contract; |
2 | |
|
3 | |
import java.util.Map; |
4 | |
|
5 | |
import org.apache.commons.contract.constraints.Constraints; |
6 | |
import org.apache.commons.contract.constraints.ValidationException; |
7 | |
import org.apache.commons.contract.descriptor.ParameterDescriptor; |
8 | |
import org.apache.commons.contract.descriptor.RequiredEnvironmentDescriptor; |
9 | |
import org.apache.commons.contract.descriptor.ResultDescriptor; |
10 | |
import org.apache.commons.contract.descriptor.ResultEntryDescriptor; |
11 | |
import org.apache.commons.i18n.XMLMessageProvider; |
12 | |
import org.apache.commons.i18n.bundles.ErrorBundle; |
13 | |
|
14 | 0 | public class Executor { |
15 | |
static { |
16 | |
|
17 | |
|
18 | |
|
19 | 0 | } |
20 | |
|
21 | 0 | public static void init() {}; |
22 | |
|
23 | |
public static Result process(Processor processor, Map parameters, Context context) throws Exception { |
24 | 0 | prepareValues(processor.getParameterDescriptors(), parameters, context); |
25 | 0 | if ( processor instanceof EnvironmentConsumer ) { |
26 | 0 | checkRequirements((EnvironmentConsumer)processor, context); |
27 | |
} |
28 | 0 | Result result = processor.process(parameters, context); |
29 | 0 | validateResult(processor.getResultDescriptors(), result, context); |
30 | 0 | return result; |
31 | |
} |
32 | |
|
33 | |
public static void prepareValues(ParameterDescriptor[] parameterDescriptors, Map parameters, Context context) throws ContractViolationException { |
34 | 0 | for ( int i = 0; i < parameterDescriptors.length; i++ ) { |
35 | 0 | String parameterName = parameterDescriptors[i].getName(); |
36 | 0 | Object parameterValue = parameters.get(parameterName); |
37 | 0 | Object preparedValue = prepareValue(parameterDescriptors[i], parameterValue, context); |
38 | 0 | parameters.put(parameterName, preparedValue); |
39 | |
} |
40 | 0 | } |
41 | |
|
42 | |
public static Object prepareValue(ParameterDescriptor parameterDescriptor, Object value, Context context) throws ContractViolationException { |
43 | |
Object preparedValue; |
44 | 0 | if ( value == null ) { |
45 | 0 | if ( parameterDescriptor.isRequired() ) { |
46 | 0 | throw new ContractViolationException(new ErrorBundle("requiredParameterMissing", new String[] { parameterDescriptor.getName() })); |
47 | |
} else { |
48 | 0 | preparedValue = parameterDescriptor.getDefaultValue(); |
49 | |
} |
50 | |
} else { |
51 | |
try { |
52 | 0 | preparedValue = parameterDescriptor.getConstraints().cast(value, context); |
53 | 0 | parameterDescriptor.getConstraints().validate(preparedValue, context); |
54 | 0 | } catch ( ContractViolationException exception ) { |
55 | 0 | throw new ContractViolationException(new ErrorBundle("invalidParameter", new Object[] { parameterDescriptor.getName() }), exception); |
56 | 0 | } |
57 | |
} |
58 | 0 | return preparedValue; |
59 | |
} |
60 | |
|
61 | |
public static void checkRequirements(EnvironmentConsumer processor, Context context) throws ContractViolationException { |
62 | 0 | RequiredEnvironmentDescriptor[] requirementDescriptor = processor.getRequiredEnvironmentDescriptors(); |
63 | 0 | for ( int i = 0; i < requirementDescriptor.length; i++ ) { |
64 | 0 | Store store = context.getStore(requirementDescriptor[i].getStore()); |
65 | |
try { |
66 | 0 | Object value = store.get(requirementDescriptor[i].getName(), context); |
67 | 0 | if ( value == null ) { |
68 | 0 | if ( requirementDescriptor[i].isRequired() ) { |
69 | 0 | throw new ValidationException(new ErrorBundle("requiredContextMissing", new Object[] { requirementDescriptor[i].getName(), requirementDescriptor[i].getStore()})); |
70 | |
} else { |
71 | 0 | value = requirementDescriptor[i].getDefaultValue(); |
72 | 0 | store.put(requirementDescriptor[i].getName(), value, context); |
73 | |
} |
74 | |
} |
75 | 0 | Object castedValue = requirementDescriptor[i].getConstraints().cast(value, context); |
76 | 0 | requirementDescriptor[i].getConstraints().validate(castedValue, context); |
77 | 0 | if ( castedValue != value ) { |
78 | 0 | store.put(requirementDescriptor[i].getName(), castedValue, context); |
79 | |
} |
80 | 0 | } catch ( StoreException exception ) { |
81 | 0 | throw new ContractViolationException(new ErrorBundle("storeUnaccessable", new Object[] { requirementDescriptor[i].getName(), requirementDescriptor[i].getStore()})); |
82 | 0 | } |
83 | |
} |
84 | 0 | } |
85 | |
|
86 | |
|
87 | |
public static void validateResult(ResultDescriptor[] resultDescriptors, Result result, Context context) throws ContractViolationException { |
88 | 0 | ResultEntryDescriptor []entryDescriptors = getResultDescriptorByState(resultDescriptors, result.getState()).getResultEntryDescriptors(); |
89 | 0 | Map resultEntries = result.getResultEntries(); |
90 | 0 | String name = null; |
91 | 0 | Object value = null; |
92 | |
try { |
93 | 0 | for ( int i = 0; i < entryDescriptors.length; i++ ) { |
94 | 0 | ResultEntryDescriptor entryDescriptor = entryDescriptors[i]; |
95 | 0 | name = entryDescriptor.getName(); |
96 | 0 | value = resultEntries.get(name); |
97 | 0 | if ( value == null ) throw new ContractViolationException(new ErrorBundle("missingResultEntry", new String[] { name })); |
98 | 0 | Constraints constraints = entryDescriptor.getConstraints(); |
99 | 0 | if ( constraints == null ) throw new ContractViolationException(new ErrorBundle("undefinedResultEntryConstraints", new String[] { name })); |
100 | 0 | value = constraints.cast(value, context); |
101 | 0 | entryDescriptor.getConstraints().validate(value, context); |
102 | 0 | resultEntries.put(name, value); |
103 | |
} |
104 | 0 | } catch ( ValidationException exception ) { |
105 | 0 | throw new ContractViolationException(new ErrorBundle("invalidResultEntry", new Object[] { name, value }), exception); |
106 | 0 | } |
107 | 0 | } |
108 | |
|
109 | |
public static ResultDescriptor getResultDescriptorByState(ResultDescriptor[] resultDescriptors, String state) throws ContractViolationException { |
110 | 0 | for ( int i = 0; i < resultDescriptors.length; i++ ) { |
111 | 0 | if ( resultDescriptors[i].getStateDescriptor().getState().equals(state)) { |
112 | 0 | return resultDescriptors[i]; |
113 | |
} |
114 | |
} |
115 | 0 | throw new ContractViolationException(new ErrorBundle("stateNotDefined", new Object[] { state })); |
116 | |
} |
117 | |
} |