1use crate::errors::err_invalid_item_definition_type;
4use crate::type_ref::type_ref_to_feel_type;
5use dmntk_common::{HRef, Result};
6use dmntk_feel::{Name, QualifiedName};
7use dmntk_model::*;
8use std::collections::HashMap;
9use std::fmt;
10
11#[derive(Clone)]
13pub enum InvocableType {
14 Decision(
16 DefKey,
18 ),
19 BusinessKnowledgeModel(
21 DefKey,
23 Name,
25 ),
26 DecisionService(
28 DefKey,
30 ),
31}
32
33#[derive(Default)]
34pub struct Invocables {
35 items: HashMap<(String, String), InvocableType>,
36}
37
38impl Invocables {
39 pub fn add_decision(&mut self, namespace: String, name: String, def_key: DefKey) {
40 let invocable_type = InvocableType::Decision(def_key);
41 self.items.insert((namespace, name), invocable_type);
42 }
43
44 pub fn add_bkm(&mut self, namespace: String, name: String, def_key: DefKey, output_variable_name: Name) {
45 let invocable_type = InvocableType::BusinessKnowledgeModel(def_key, output_variable_name);
46 self.items.insert((namespace, name), invocable_type);
47 }
48
49 pub fn add_decision_service(&mut self, namespace: String, name: String, def_key: DefKey) {
50 let invocable_type = InvocableType::DecisionService(def_key);
51 self.items.insert((namespace, name), invocable_type);
52 }
53
54 pub fn by_name(&self, namespace: &str, name: &str) -> Option<&InvocableType> {
55 self.items.get(&(namespace.to_string(), name.to_string()))
56 }
57
58 pub fn list(&self) -> Vec<(String, String)> {
59 let mut items = vec![];
60 for (namespace, name) in self.items.keys() {
61 items.push((namespace.clone(), name.clone()));
62 }
63 items.sort();
64 items
65 }
66
67 pub fn len(&self) -> usize {
68 self.items.len()
69 }
70}
71
72#[derive(Debug, Clone, Hash, PartialEq, Eq)]
78pub struct DefKey(String, String);
79
80impl DefKey {
81 pub fn new(namespace: &str, id: &str) -> Self {
83 Self(namespace.to_string(), id.to_string())
84 }
85}
86
87impl fmt::Display for DefKey {
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 write!(f, "{}#{}", self.0, self.1)
91 }
92}
93
94impl From<&DefHRef> for DefKey {
95 fn from(value: &DefHRef) -> Self {
96 Self::new(value.namespace(), value.id())
97 }
98}
99
100impl DefKey {
101 pub fn namespace(&self) -> &str {
102 &self.0
103 }
104 pub fn id(&self) -> &str {
105 &self.1
106 }
107}
108
109pub struct DefInformationItem {
111 namespace: String,
113 name: Name,
115 type_ref: String,
117}
118
119impl DefInformationItem {
120 pub fn new(information_item: &InformationItem, imports: &[DefImport]) -> Self {
122 let type_ref_name = Name::from(information_item.type_ref().clone());
123 let qname = QualifiedName::from(type_ref_name);
124 if qname.len() == 2 {
125 let import_name = qname.first().unwrap(); let namespace = get_import_namespace(import_name, imports).unwrap_or(information_item.namespace().to_string());
128 let name = information_item.feel_name().clone();
129 let type_ref = qname.get(1).unwrap().to_string(); Self { namespace, name, type_ref }
131 } else {
132 let namespace = information_item.namespace().to_string();
134 let type_ref = information_item.type_ref().clone();
135 let name = information_item.feel_name().clone();
136 Self { namespace, name, type_ref }
137 }
138 }
139}
140
141impl DefInformationItem {
142 pub fn namespace(&self) -> &str {
144 &self.namespace
145 }
146
147 pub fn name(&self) -> &Name {
149 &self.name
150 }
151
152 pub fn type_ref(&self) -> &String {
154 &self.type_ref
155 }
156}
157
158pub struct DefInputData {
159 namespace: String,
160 id: String,
161 name: String,
162 variable: DefInformationItem,
163}
164
165impl DefInputData {
166 pub fn new(input_data: &InputData, imports: &[DefImport]) -> Self {
168 Self {
169 namespace: input_data.namespace().to_string(),
170 id: input_data.id().to_string(),
171 name: input_data.name().to_string(),
172 variable: DefInformationItem::new(input_data.variable(), imports),
173 }
174 }
175}
176
177impl DefInputData {
178 pub fn namespace(&self) -> &str {
180 &self.namespace
181 }
182
183 pub fn id(&self) -> &str {
185 &self.id
186 }
187
188 pub fn name(&self) -> &str {
190 &self.name
191 }
192
193 pub fn variable(&self) -> &DefInformationItem {
195 &self.variable
196 }
197}
198
199pub struct DefItemDefinition {
200 namespace: String,
201 id: String,
202 name: String,
203 feel_name: Name,
204 type_ref: Option<String>,
205 allowed_values: Option<UnaryTests>,
206 item_components: Vec<DefItemDefinition>,
207 function_item: Option<FunctionItem>,
208 is_collection: bool,
209}
210
211impl DefItemDefinition {
212 pub fn new(item_definition: &ItemDefinition) -> Self {
213 Self {
214 namespace: item_definition.namespace().to_string(),
215 id: item_definition.id().to_string(),
216 name: item_definition.name().to_string(),
217 feel_name: item_definition.feel_name().clone(),
218 type_ref: item_definition.type_ref().clone(),
219 allowed_values: item_definition.allowed_values().clone(),
220 item_components: item_definition.item_components().iter().map(DefItemDefinition::new).collect(),
221 function_item: item_definition.function_item().clone(),
222 is_collection: item_definition.is_collection(),
223 }
224 }
225}
226
227impl DefItemDefinition {
228 pub fn namespace(&self) -> &str {
230 &self.namespace
231 }
232
233 pub fn id(&self) -> &str {
235 &self.id
236 }
237
238 pub fn name(&self) -> &str {
240 &self.name
241 }
242
243 pub fn feel_name(&self) -> &Name {
245 &self.feel_name
246 }
247
248 pub fn type_ref(&self) -> &Option<String> {
250 &self.type_ref
251 }
252
253 pub fn allowed_values(&self) -> &Option<UnaryTests> {
256 &self.allowed_values
257 }
258
259 pub fn item_components(&self) -> &Vec<DefItemDefinition> {
261 &self.item_components
262 }
263
264 pub fn function_item(&self) -> &Option<FunctionItem> {
266 &self.function_item
267 }
268
269 pub fn is_collection(&self) -> bool {
271 self.is_collection
272 }
273
274 pub fn item_definition_type(&self) -> Result<ItemDefinitionType> {
276 let simple_type_ref = if let Some(type_ref) = self.type_ref() { type_ref_to_feel_type(type_ref) } else { None };
277 let condition = (
278 self.type_ref().is_some(),
279 simple_type_ref.is_some(),
280 !self.item_components().is_empty(),
281 self.is_collection(),
282 self.function_item().is_some(),
283 );
284 match condition {
285 (_, true, false, false, false) => Ok(ItemDefinitionType::SimpleType(simple_type_ref.unwrap().clone())),
286 (true, false, false, false, false) => Ok(ItemDefinitionType::ReferencedType(self.namespace.clone(), self.type_ref().as_ref().unwrap().clone())),
287 (false, false, true, false, false) => Ok(ItemDefinitionType::ComponentType),
288 (_, true, false, true, false) => Ok(ItemDefinitionType::CollectionOfSimpleType(simple_type_ref.unwrap().clone())),
289 (false, false, true, true, false) => Ok(ItemDefinitionType::CollectionOfComponentType),
290 (true, false, false, true, false) => Ok(ItemDefinitionType::CollectionOfReferencedType(
291 self.namespace.clone(),
292 self.type_ref().as_ref().unwrap().clone(),
293 )),
294 (false, false, false, false, true) => Ok(ItemDefinitionType::FunctionType),
295 _ => Err(err_invalid_item_definition_type(self.name())),
296 }
297 }
298}
299
300pub struct DefBusinessKnowledgeModel {
301 namespace: String,
302 id: String,
303 name: String,
304 variable: DefInformationItem,
305 encapsulated_logic: Option<FunctionDefinition>,
306 knowledge_requirements: Vec<DefKnowledgeRequirement>,
307}
308
309impl DefBusinessKnowledgeModel {
310 pub fn new(business_knowledge_model: &BusinessKnowledgeModel, imports: &[DefImport]) -> Self {
312 Self {
313 namespace: business_knowledge_model.namespace().to_string(),
314 id: business_knowledge_model.id().to_string(),
315 name: business_knowledge_model.name().to_string(),
316 variable: DefInformationItem::new(business_knowledge_model.variable(), imports),
317 encapsulated_logic: business_knowledge_model.encapsulated_logic().clone(),
318 knowledge_requirements: business_knowledge_model
319 .knowledge_requirements()
320 .iter()
321 .map(|knowledge_requirements| DefKnowledgeRequirement::new(knowledge_requirements, imports))
322 .collect(),
323 }
324 }
325}
326
327impl DefBusinessKnowledgeModel {
328 pub fn namespace(&self) -> &str {
330 &self.namespace
331 }
332
333 pub fn id(&self) -> &str {
335 &self.id
336 }
337
338 pub fn name(&self) -> &str {
340 &self.name
341 }
342
343 pub fn variable(&self) -> &DefInformationItem {
345 &self.variable
346 }
347
348 pub fn encapsulated_logic(&self) -> &Option<FunctionDefinition> {
350 &self.encapsulated_logic
351 }
352
353 pub fn knowledge_requirements(&self) -> &Vec<DefKnowledgeRequirement> {
355 &self.knowledge_requirements
356 }
357}
358
359pub struct DefHRef {
360 namespace: String,
362 id: String,
364 import_name: Option<Name>,
366}
367
368impl DefHRef {
369 pub fn new(namespace: &str, href: &HRef, imports: &[DefImport]) -> Self {
370 let namespace = href.namespace().cloned().unwrap_or(namespace.to_string());
371 let import_name = get_import_name(&namespace, imports);
372 Self {
373 namespace,
374 id: href.id().to_string(),
375 import_name,
376 }
377 }
378
379 pub fn namespace(&self) -> &str {
380 &self.namespace
381 }
382
383 pub fn id(&self) -> &str {
384 &self.id
385 }
386
387 pub fn import_name(&self) -> Option<&Name> {
388 self.import_name.as_ref()
389 }
390}
391
392pub struct DefInformationRequirement {
393 required_decision: Option<DefHRef>,
394 required_input: Option<DefHRef>,
395}
396
397impl DefInformationRequirement {
398 pub fn new(information_requirement: &InformationRequirement, imports: &[DefImport]) -> Self {
399 Self {
400 required_decision: information_requirement
401 .required_decision()
402 .as_ref()
403 .map(|href| DefHRef::new(information_requirement.namespace(), href, imports)),
404 required_input: information_requirement
405 .required_input()
406 .as_ref()
407 .map(|href| DefHRef::new(information_requirement.namespace(), href, imports)),
408 }
409 }
410
411 pub fn required_decision(&self) -> Option<&DefHRef> {
412 self.required_decision.as_ref()
413 }
414
415 pub fn required_input(&self) -> Option<&DefHRef> {
416 self.required_input.as_ref()
417 }
418}
419
420pub struct DefKnowledgeRequirement {
421 required_knowledge: DefHRef,
422}
423
424impl DefKnowledgeRequirement {
425 pub fn new(knowledge_requirement: &KnowledgeRequirement, imports: &[DefImport]) -> Self {
426 Self {
427 required_knowledge: DefHRef::new(knowledge_requirement.namespace(), knowledge_requirement.required_knowledge(), imports),
428 }
429 }
430
431 pub fn required_knowledge(&self) -> &DefHRef {
432 &self.required_knowledge
433 }
434}
435
436pub struct DefDecision {
437 namespace: String,
438 id: String,
439 name: String,
440 variable: DefInformationItem,
441 decision_logic: Option<ExpressionInstance>,
442 information_requirements: Vec<DefInformationRequirement>,
443 knowledge_requirements: Vec<DefKnowledgeRequirement>,
444}
445
446impl DefDecision {
447 pub fn new(decision: &Decision, imports: &[DefImport]) -> Self {
449 Self {
450 namespace: decision.namespace().to_string(),
451 id: decision.id().to_string(),
452 name: decision.name().to_string(),
453 variable: DefInformationItem::new(decision.variable(), imports),
454 decision_logic: decision.decision_logic().clone(),
455 information_requirements: decision
456 .information_requirements()
457 .iter()
458 .map(|knowledge_requirements| DefInformationRequirement::new(knowledge_requirements, imports))
459 .collect(),
460 knowledge_requirements: decision
461 .knowledge_requirements()
462 .iter()
463 .map(|knowledge_requirements| DefKnowledgeRequirement::new(knowledge_requirements, imports))
464 .collect(),
465 }
466 }
467}
468
469impl DefDecision {
470 pub fn namespace(&self) -> &str {
472 &self.namespace
473 }
474
475 pub fn id(&self) -> &str {
477 &self.id
478 }
479
480 pub fn name(&self) -> &str {
482 &self.name
483 }
484
485 pub fn variable(&self) -> &DefInformationItem {
487 &self.variable
488 }
489
490 pub fn decision_logic(&self) -> &Option<ExpressionInstance> {
492 &self.decision_logic
493 }
494
495 pub fn information_requirements(&self) -> &Vec<DefInformationRequirement> {
497 &self.information_requirements
498 }
499
500 pub fn knowledge_requirements(&self) -> &Vec<DefKnowledgeRequirement> {
502 &self.knowledge_requirements
503 }
504}
505
506pub struct DefDecisionService {
507 namespace: String,
508 id: String,
509 name: String,
510 variable: DefInformationItem,
511 input_decisions: Vec<DefHRef>,
512 output_decisions: Vec<DefHRef>,
513 encapsulated_decisions: Vec<DefHRef>,
514 input_data: Vec<DefHRef>,
515}
516
517impl DefDecisionService {
518 pub fn new(decision_service: &DecisionService, imports: &[DefImport]) -> Self {
520 let namespace = decision_service.namespace();
521 Self {
522 namespace: namespace.to_string(),
523 id: decision_service.id().to_string(),
524 name: decision_service.name().to_string(),
525 variable: DefInformationItem::new(decision_service.variable(), imports),
526 input_decisions: decision_service.input_decisions().iter().map(|href| DefHRef::new(namespace, href, imports)).collect(),
527 output_decisions: decision_service.output_decisions().iter().map(|href| DefHRef::new(namespace, href, imports)).collect(),
528 encapsulated_decisions: decision_service
529 .encapsulated_decisions()
530 .iter()
531 .map(|href| DefHRef::new(namespace, href, imports))
532 .collect(),
533 input_data: decision_service.input_data().iter().map(|href| DefHRef::new(namespace, href, imports)).collect(),
534 }
535 }
536}
537
538impl DefDecisionService {
539 pub fn namespace(&self) -> &str {
541 &self.namespace
542 }
543
544 pub fn id(&self) -> &str {
546 &self.id
547 }
548
549 pub fn name(&self) -> &str {
551 &self.name
552 }
553
554 pub fn variable(&self) -> &DefInformationItem {
556 &self.variable
557 }
558
559 pub fn input_decisions(&self) -> &Vec<DefHRef> {
561 &self.input_decisions
562 }
563
564 pub fn encapsulated_decisions(&self) -> &Vec<DefHRef> {
566 &self.encapsulated_decisions
567 }
568 pub fn output_decisions(&self) -> &Vec<DefHRef> {
570 &self.output_decisions
571 }
572
573 pub fn input_data(&self) -> &Vec<DefHRef> {
575 &self.input_data
576 }
577}
578
579#[derive(Default)]
580pub struct DefImport {
581 namespace: String,
582 name: Name,
583}
584
585impl DefImport {
586 pub fn new(import: &Import) -> Self {
588 Self {
589 namespace: import.namespace().to_string(),
590 name: import.feel_name().clone(),
591 }
592 }
593}
594
595#[derive(Default)]
597pub struct DefDefinitions {
598 imports: Vec<DefImport>,
600 item_definitions: Vec<DefItemDefinition>,
602 input_data: HashMap<DefKey, DefInputData>,
604 business_knowledge_models: HashMap<DefKey, DefBusinessKnowledgeModel>,
606 decisions: HashMap<DefKey, DefDecision>,
608 decision_services: HashMap<DefKey, DefDecisionService>,
610}
611
612impl DefDefinitions {
613 pub fn add_model(&mut self, definitions: &Definitions) {
615 self.imports.append(&mut definitions.imports().iter().map(DefImport::new).collect());
616 self
617 .item_definitions
618 .append(&mut definitions.item_definitions().iter().map(DefItemDefinition::new).collect());
619 for drg_element in definitions.drg_elements() {
620 match drg_element {
621 DrgElement::InputData(inner) => {
622 self.input_data.insert(DefKey::new(inner.namespace(), inner.id()), DefInputData::new(inner, &self.imports));
623 }
624 DrgElement::BusinessKnowledgeModel(inner) => {
625 self
626 .business_knowledge_models
627 .insert(DefKey::new(inner.namespace(), inner.id()), DefBusinessKnowledgeModel::new(inner, &self.imports));
628 }
629 DrgElement::Decision(inner) => {
630 self.decisions.insert(DefKey::new(inner.namespace(), inner.id()), DefDecision::new(inner, &self.imports));
631 }
632 DrgElement::DecisionService(inner) => {
633 self
634 .decision_services
635 .insert(DefKey::new(inner.namespace(), inner.id()), DefDecisionService::new(inner, &self.imports));
636 }
637 _ => {}
638 }
639 }
640 }
641
642 pub fn item_definitions(&self) -> &Vec<DefItemDefinition> {
644 &self.item_definitions
645 }
646
647 pub fn decisions(&self) -> Vec<&DefDecision> {
649 self.decisions.values().collect()
650 }
651
652 pub fn decision_by_key(&self, namespace: &str, id: &str) -> Option<&DefDecision> {
655 self.decisions.get(&DefKey::new(namespace, id))
656 }
657
658 pub fn business_knowledge_models(&self) -> Vec<&DefBusinessKnowledgeModel> {
660 self.business_knowledge_models.values().collect()
661 }
662
663 pub fn business_knowledge_model_by_key(&self, namespace: &str, id: &str) -> Option<&DefBusinessKnowledgeModel> {
666 self.business_knowledge_models.get(&DefKey::new(namespace, id))
667 }
668
669 pub fn decision_services(&self) -> Vec<&DefDecisionService> {
671 self.decision_services.values().collect()
672 }
673
674 pub fn decision_service_by_id(&self, namespace: &str, id: &str) -> Option<&DefDecisionService> {
677 self.decision_services.get(&DefKey::new(namespace, id))
678 }
679
680 pub fn input_data(&self) -> Vec<&DefInputData> {
682 self.input_data.values().collect()
683 }
684
685 pub fn input_data_by_key(&self, namespace: &str, id: &str) -> Option<&DefInputData> {
689 self.input_data.get(&DefKey::new(namespace, id))
690 }
691}
692
693fn get_import_name(namespace: &str, imports: &[DefImport]) -> Option<Name> {
695 imports
696 .iter()
697 .filter_map(|def_import| if def_import.namespace == namespace { Some(def_import.name.clone()) } else { None })
698 .collect::<Vec<Name>>()
699 .first()
700 .cloned()
701}
702
703fn get_import_namespace(name: &Name, imports: &[DefImport]) -> Option<String> {
705 imports
706 .iter()
707 .filter_map(|def_import| if &def_import.name == name { Some(def_import.namespace.clone()) } else { None })
708 .collect::<Vec<String>>()
709 .first()
710 .cloned()
711}