1
2
3
4
5
6 package gov.nist.secauto.oscal.lib.metapath.function.library;
7
8 import gov.nist.secauto.metaschema.core.metapath.DynamicContext;
9 import gov.nist.secauto.metaschema.core.metapath.ISequence;
10 import gov.nist.secauto.metaschema.core.metapath.MetapathConstants;
11 import gov.nist.secauto.metaschema.core.metapath.MetapathException;
12 import gov.nist.secauto.metaschema.core.metapath.function.FunctionUtils;
13 import gov.nist.secauto.metaschema.core.metapath.function.IArgument;
14 import gov.nist.secauto.metaschema.core.metapath.function.IFunction;
15 import gov.nist.secauto.metaschema.core.metapath.item.IItem;
16 import gov.nist.secauto.metaschema.core.metapath.item.node.IDocumentNodeItem;
17 import gov.nist.secauto.metaschema.core.metapath.item.node.INodeItem;
18 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
19 import gov.nist.secauto.oscal.lib.OscalModelConstants;
20 import gov.nist.secauto.oscal.lib.model.Catalog;
21 import gov.nist.secauto.oscal.lib.profile.resolver.ProfileResolutionException;
22 import gov.nist.secauto.oscal.lib.profile.resolver.ProfileResolver;
23
24 import java.io.IOException;
25 import java.util.List;
26
27 import edu.umd.cs.findbugs.annotations.NonNull;
28
29 public final class ResolveProfile {
30
31 @NonNull
32 static final IFunction SIGNATURE_NO_ARG = IFunction.builder()
33 .name("resolve-profile")
34 .namespace(OscalModelConstants.NS_OSCAL)
35 .returnType(INodeItem.type())
36 .focusDependent()
37 .contextDependent()
38 .deterministic()
39 .returnOne()
40 .functionHandler(ResolveProfile::executeNoArg)
41 .build();
42
43 @NonNull
44 static final IFunction SIGNATURE_ONE_ARG = IFunction.builder()
45 .name("resolve-profile")
46 .namespace(OscalModelConstants.NS_OSCAL)
47 .argument(IArgument.builder()
48 .name("profile")
49 .type(INodeItem.type())
50 .zeroOrOne()
51 .build())
52 .focusDependent()
53 .contextDependent()
54 .deterministic()
55 .returnType(INodeItem.type())
56 .returnOne()
57 .functionHandler(ResolveProfile::executeOneArg)
58 .build();
59
60 @NonNull
61 static final IFunction SIGNATURE_NO_ARG_METAPATH = IFunction.builder()
62 .name("resolve-profile")
63 .namespace(MetapathConstants.NS_METAPATH_FUNCTIONS)
64 .returnType(INodeItem.type())
65 .focusDependent()
66 .contextDependent()
67 .deterministic()
68 .returnOne()
69 .functionHandler(ResolveProfile::executeNoArg)
70 .build();
71
72 @NonNull
73 static final IFunction SIGNATURE_ONE_ARG_METAPATH = IFunction.builder()
74 .name("resolve-profile")
75 .namespace(MetapathConstants.NS_METAPATH_FUNCTIONS)
76 .argument(IArgument.builder()
77 .name("profile")
78 .type(INodeItem.type())
79 .zeroOrOne()
80 .build())
81 .focusDependent()
82 .contextDependent()
83 .deterministic()
84 .returnType(INodeItem.type())
85 .returnOne()
86 .functionHandler(ResolveProfile::executeOneArg)
87 .build();
88
89 private ResolveProfile() {
90
91 }
92
93 @SuppressWarnings({ "unused",
94 "PMD.OnlyOneReturn"
95 })
96 @NonNull
97 public static ISequence<?> executeNoArg(
98 @NonNull IFunction function,
99 @NonNull List<ISequence<?>> arguments,
100 @NonNull DynamicContext dynamicContext,
101 IItem focus) {
102
103 if (focus == null) {
104 return ISequence.empty();
105 }
106 return ISequence.of(resolveProfile(FunctionUtils.asType(focus), dynamicContext));
107 }
108
109 @SuppressWarnings({ "unused",
110 "PMD.OnlyOneReturn"
111 })
112 @NonNull
113 public static ISequence<?> executeOneArg(
114 @NonNull IFunction function,
115 @NonNull List<ISequence<?>> arguments,
116 @NonNull DynamicContext dynamicContext,
117 IItem focus) {
118 ISequence<? extends IDocumentNodeItem> arg = FunctionUtils.asType(
119 ObjectUtils.notNull(arguments.get(0)));
120
121 IItem item = arg.getFirstItem(true);
122 if (item == null) {
123 return ISequence.empty();
124 }
125
126 return ISequence.of(resolveProfile(FunctionUtils.asType(item), dynamicContext));
127 }
128
129 @NonNull
130 public static IDocumentNodeItem resolveProfile(
131 @NonNull IDocumentNodeItem profile,
132 @NonNull DynamicContext dynamicContext) {
133 Object profileObject = INodeItem.toValue(profile);
134
135 IDocumentNodeItem retval;
136 if (profileObject instanceof Catalog) {
137 retval = profile;
138 } else {
139
140 ProfileResolver resolver = new ProfileResolver(dynamicContext);
141 try {
142 retval = resolver.resolve(profile);
143 } catch (IOException | ProfileResolutionException ex) {
144 throw new MetapathException(String.format("Fun: Unable to resolve profile '%s'", profile.getBaseUri()), ex);
145 }
146 }
147 return retval;
148 }
149 }