DecisionTableValidator::validateHitPolicy()   B
last analyzed

Complexity

Conditions 7
Paths 9

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 14
nc 9
nop 0
dl 0
loc 21
rs 8.8333
c 0
b 0
f 0
1
<?php
2
3
namespace SteffenBrand\DmnDecisionTables\Validator;
4
5
use SteffenBrand\DmnDecisionTables\Constant\CollectOperator;
6
use SteffenBrand\DmnDecisionTables\Constant\ExpressionLanguage;
7
use SteffenBrand\DmnDecisionTables\Constant\HitPolicy;
8
use SteffenBrand\DmnDecisionTables\Constant\VariableType;
9
use SteffenBrand\DmnDecisionTables\DecisionTableBuilderInterface;
10
use SteffenBrand\DmnDecisionTables\Model\Rule;
11
12
/**
13
 * Class DecisionTableValidator
14
 * @package SteffenBrand\DmnDecisionTables\Validator
15
 */
16
class DecisionTableValidator implements DecisionTableValidatorInterface
17
{
18
    /**
19
     * @var bool
20
     */
21
    private $valid;
22
23
    /**
24
     * @var array
25
     */
26
    private $errors;
27
28
    /**
29
     * @var DecisionTableBuilderInterface
30
     */
31
    private $builder;
32
33
    /**
34
     * DmnTableValidator constructor.
35
     * @param DecisionTableBuilderInterface $builder
36
     */
37
    public function __construct($builder)
38
    {
39
        $this->valid = false;
40
        $this->errors = [];
41
        $this->builder = $builder;
42
    }
43
44
    /**
45
     * Validates a DecisionTableBuilder instance.
46
     *
47
     * @return DecisionTableValidator
48
     */
49
    public function validate()
50
    {
51
        $this->validateName();
52
        $this->validateDefinitionKey();
53
        $this->validateHitPolicy();
54
        $this->validateInputs();
55
        $this->validateOutputs();
56
        $this->validateRules();
57
        
58
        if (empty($this->errors) === true) {
59
            $this->valid = true;
60
        }
61
62
        return $this;
63
    }
64
65
    /**
66
     * @return bool
67
     */
68
    public function isValid()
69
    {
70
        return $this->valid;
71
    }
72
73
    /**
74
     * @return array
75
     */
76
    public function getErrors()
77
    {
78
        return $this->errors;
79
    }
80
81
    /**
82
     * @return void
83
     */
84
    private function validateName()
85
    {
86
        if (empty($this->builder->getName()) === true) {
87
            $this->errors[] = 'name of decision table is required';
88
        }
89
    }
90
91
    /**
92
     * @return void
93
     */
94
    private function validateDefinitionKey()
95
    {
96
        if (empty($this->builder->getDefinitionKey()) === true) {
97
            $this->errors[] = 'definition key of decision table is required';
98
        }
99
    }
100
101
    /**
102
     * @return void
103
     */
104
    private function validateHitPolicy()
105
    {
106
        if (empty($this->builder->getHitPolicy()) === true) {
107
            $this->errors[] = 'hit policy of decision table is required';
108
        } else if (in_array($this->builder->getHitPolicy(), HitPolicy::ALLOWED_HIT_POLICIES) === false) {
109
            $this->errors[] = sprintf(
110
                'hit policy of decision table must be one of: %s',
111
                implode(', ', HitPolicy::ALLOWED_HIT_POLICIES)
112
            );
113
        }
114
115
        if (HitPolicy::COLLECT_POLICY === $this->builder->getHitPolicy() &&
116
            empty($this->builder->getCollectOperator()) === true)
117
        {
118
            $this->errors[] = 'hit policy COLLECT requires a collect operator.';
119
        } else if (HitPolicy::COLLECT_POLICY === $this->builder->getHitPolicy() &&
120
            in_array($this->builder->getCollectOperator(), CollectOperator::ALLOWED_COLLECT_OPERATORS) === false)
121
        {
122
            $this->errors[] = sprintf(
123
                'collect operator must be one of: %s',
124
                implode(', ', CollectOperator::ALLOWED_COLLECT_OPERATORS)
125
            );
126
        }
127
    }
128
129
    /**
130
     * @return void
131
     */
132
    private function validateInputs()
133
    {
134
        if (empty($this->builder->getInputs()) === true) {
135
            $this->errors[] = 'at least one input is required';
136
            return;
137
        }
138
        
139
        $i = 1;
140
        foreach ($this->builder->getInputs() as $input) {
141
            if (empty($input->getLabel()) === true) {
142
                $this->errors[] = sprintf('input no. %s: label is required', (string) $i);
143
            }
144
            
145
            if (empty($input->getName()) === true) {
146
                $this->errors[] = sprintf('input no. %s: name is required', (string) $i);
147
            }
148
            
149
            if (empty($input->getType()) === true) {
150
                $this->errors[] = sprintf('input no. %s: type is required', (string) $i);
151
            } else if (in_array($input->getType(), VariableType::ALLOWED_VARIABLE_TYPES) === false) {
152
                $this->errors[] = sprintf(
153
                    'input no. %s: type must be one of: %s',
154
                    (string) $i,
155
                    implode(', ', VariableType::ALLOWED_VARIABLE_TYPES)
156
                );
157
            }
158
            
159
            $i++;
160
        }
161
    }
162
163
    /**
164
     * @return void
165
     */
166
    private function validateOutputs()
167
    {
168
        if (empty($this->builder->getOutputs()) === true) {
169
            $this->errors[] = 'at least one output is required';
170
            return;
171
        }
172
        
173
        $i = 1;
174
        foreach ($this->builder->getOutputs() as $output) {
175
            if (empty($output->getLabel()) === true) {
176
                $this->errors[] = sprintf('output no. %s: label is required', (string) $i);
177
            }
178
            
179
            if (empty($output->getName()) === true) {
180
                $this->errors[] = sprintf('output no. %s: name is required', (string) $i);
181
            }
182
            
183
            if (empty($output->getType()) === true) {
184
                $this->errors[] = sprintf('output no. %s: type is required', (string) $i);
185
            } else if (in_array($output->getType(), VariableType::ALLOWED_VARIABLE_TYPES) === false) {
186
                $this->errors[] = sprintf(
187
                    'output no. %s: type must be one of: %s',
188
                    (string) $i,
189
                    implode(', ', VariableType::ALLOWED_VARIABLE_TYPES)
190
                );
191
            }
192
            
193
            $i++;
194
        }
195
    }
196
197
    /**
198
     * @return void
199
     */
200
    private function validateRules()
201
    {
202
        if (empty($this->builder->getRules()) === true) {
203
            return;
204
        }
205
        
206
        $i = 1;
207
        foreach ($this->builder->getRules() as $rule) {
208
            $this->validateInputEntries($rule, $i);
209
            $i++;
210
        }
211
212
        $i = 1;
213
        foreach ($this->builder->getRules() as $rule) {
214
            $this->validateOutputEntries($rule, $i);
215
            $i++;
216
        }
217
    }
218
219
    /**
220
     * @param Rule $rule
221
     * @param $i
222
     * @return void
223
     */
224
    private function validateInputEntries($rule, $i)
225
    {
226
        if (empty($rule->getInputEntries()) === true) {
227
            $this->errors[] = sprintf('rule no. %s: at least one input entry is required', (string) $i);
228
            return;
229
        }
230
231
        $k = 1;
232
        foreach ($rule->getInputEntries() as $inputEntry) {
233
            if (empty($inputEntry->getExpressionLanguage()) === true) {
234
                $this->errors[] = sprintf(
235
                    'rule no. %s, input entry no. %s: expression language is required',
236
                    (string) $i,
237
                    (string) $k
238
                );
239
            } else if (in_array($inputEntry->getExpressionLanguage(), ExpressionLanguage::ALLOWED_EXPRESSION_LANGUAGES) === false) {
240
                $this->errors[] = sprintf(
241
                    'rule no. %s, input entry no. %s: expression language must be one of: %s',
242
                    (string) $i,
243
                    (string) $k,
244
                    implode(', ', ExpressionLanguage::ALLOWED_EXPRESSION_LANGUAGES)
245
                );
246
            }
247
248
            $k++;
249
        }
250
    }
251
252
    /**
253
     * @param Rule $rule
254
     * @param $i
255
     * @return void
256
     */
257
    private function validateOutputEntries($rule, $i)
258
    {
259
        if (empty($rule->getOutputEntries()) === true) {
260
            $this->errors[] = sprintf('rule no. %s: at least one output entry is required', (string) $i);
261
            return;
262
        }
263
264
        $k = 1;
265
        foreach ($rule->getOutputEntries() as $outputEntry) {
266
            if (empty($outputEntry->getExpressionLanguage()) === true) {
267
                $this->errors[] = sprintf(
268
                    'rule no. %s, output entry no. %s: expression language is required',
269
                    (string) $i,
270
                    (string) $k
271
                );
272
            } else if (in_array($outputEntry->getExpressionLanguage(), ExpressionLanguage::ALLOWED_EXPRESSION_LANGUAGES) === false) {
273
                $this->errors[] = sprintf(
274
                    'rule no. %s, output entry no. %s: expression language must be one of: %s',
275
                    (string) $i,
276
                    (string) $k,
277
                    implode(', ', ExpressionLanguage::ALLOWED_EXPRESSION_LANGUAGES)
278
                );
279
            }
280
281
            $k++;
282
        }
283
    }
284
}