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 package gov.nist.secauto.metaschema.core.model.constraint;
28
29 import gov.nist.secauto.metaschema.core.metapath.MetapathExpression;
30 import gov.nist.secauto.metaschema.core.metapath.MetapathExpression.ResultType;
31 import gov.nist.secauto.metaschema.core.metapath.item.node.IDefinitionNodeItem;
32 import gov.nist.secauto.metaschema.core.metapath.item.node.IModuleNodeItem;
33 import gov.nist.secauto.metaschema.core.metapath.item.node.INodeItem;
34 import gov.nist.secauto.metaschema.core.metapath.item.node.INodeItemFactory;
35 import gov.nist.secauto.metaschema.core.model.IDefinition;
36 import gov.nist.secauto.metaschema.core.model.IModule;
37 import gov.nist.secauto.metaschema.core.model.MetaschemaException;
38 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
39
40 import java.util.Collection;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.Set;
44 import java.util.stream.Collectors;
45 import java.util.stream.Stream;
46
47 import javax.xml.namespace.QName;
48
49 import edu.umd.cs.findbugs.annotations.NonNull;
50
51 public interface IConstraintSet {
52
53 @NonNull
54 static Set<IConstraintSet> resolveConstraintSets(@NonNull Set<IConstraintSet> constraintSets) {
55 return ObjectUtils.notNull(constraintSets.stream()
56 .flatMap(set -> resolveConstraintSet(ObjectUtils.notNull(set)))
57 .distinct()
58 .collect(Collectors.toUnmodifiableSet()));
59 }
60
61 @NonNull
62 private static Stream<IConstraintSet> resolveConstraintSet(@NonNull IConstraintSet constraintSet) {
63 return ObjectUtils.notNull(Stream.concat(
64 Stream.of(constraintSet),
65 constraintSet.getImportedConstraintSets().stream()));
66 }
67
68 @NonNull
69 static List<ITargetedConstaints> getTargetedConstraintsForMetaschema(
70 @NonNull Set<IConstraintSet> constraintSets,
71 @NonNull IModule module) {
72 return ObjectUtils.notNull(resolveConstraintSets(constraintSets).stream()
73 .flatMap(set -> set.getTargetedConstraintsForModule(module))
74 .collect(Collectors.toUnmodifiableList()));
75 }
76
77 @NonNull
78 Stream<ITargetedConstaints> getTargetedConstraintsForModule(@NonNull IModule module);
79
80 static void applyConstraintSetToModule(
81 @NonNull Set<IConstraintSet> constraintSets,
82 @NonNull IModule module) throws MetaschemaException {
83 Set<IConstraintSet> resolvedConstraintSets = resolveConstraintSets(constraintSets);
84
85 ConstraintComposingVisitor visitor = new ConstraintComposingVisitor();
86 IModuleNodeItem item = INodeItemFactory.instance().newModuleNodeItem(module);
87
88 for (ITargetedConstaints targeted : getTargetedConstraintsForMetaschema(resolvedConstraintSets, module)) {
89 MetapathExpression targetExpression = targeted.getTargetExpression();
90 INodeItem node = targetExpression.evaluateAs(item, ResultType.NODE);
91 if (node == null) {
92 throw new MetaschemaException(String.format("Target not found for expression '%s' on metaschema '%s'.",
93 targetExpression.getPath(),
94 module.getQName()));
95 } else if (node instanceof IDefinitionNodeItem) {
96 IDefinition nodeDefinition = ((IDefinitionNodeItem<?, ?>) node).getDefinition();
97 IModule nodeModule = nodeDefinition.getContainingModule();
98 if (!module.equals(nodeModule)) {
99 throw new MetaschemaException(
100 String.format("Target definition '%s' in metaschema '%s' is not in the scoped metaschema '%s'.",
101 nodeDefinition.getName(),
102 nodeModule.getQName(),
103 module.getQName()));
104 }
105 }
106 node.accept(visitor, targeted);
107 }
108
109 }
110
111 Collection<IConstraintSet> getImportedConstraintSets();
112
113
114
115
116
117
118
119 @NonNull
120 Map<QName, List<IScopedContraints>> getScopedContraints();
121 }