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.oscal.lib.profile.resolver.policy;
28
29 import gov.nist.secauto.metaschema.model.common.metapath.format.IPathFormatter;
30 import gov.nist.secauto.metaschema.model.common.metapath.item.IRequiredValueModelNodeItem;
31 import gov.nist.secauto.metaschema.model.common.util.CustomCollectors;
32 import gov.nist.secauto.metaschema.model.common.util.ObjectUtils;
33 import gov.nist.secauto.oscal.lib.model.Property;
34 import gov.nist.secauto.oscal.lib.profile.resolver.support.IEntityItem;
35
36 import org.apache.logging.log4j.LogManager;
37 import org.apache.logging.log4j.Logger;
38
39 import java.net.URI;
40 import java.util.List;
41 import java.util.Locale;
42
43 import edu.umd.cs.findbugs.annotations.NonNull;
44
45 public class PropertyReferencePolicy
46 extends AbstractMultiItemTypeReferencePolicy<Property> {
47 private static final Logger LOGGER = LogManager.getLogger(PropertyReferencePolicy.class);
48
49 @NonNull
50 public static PropertyReferencePolicy create(@NonNull IIdentifierParser identifierParser,
51 @NonNull IEntityItem.ItemType itemType) {
52 return create(identifierParser, ObjectUtils.notNull(List.of(itemType)));
53 }
54
55 @NonNull
56 public static PropertyReferencePolicy create(@NonNull IIdentifierParser identifierParser,
57 @NonNull List<IEntityItem.ItemType> itemTypes) {
58 return new PropertyReferencePolicy(identifierParser, itemTypes);
59 }
60
61 public PropertyReferencePolicy(
62 @NonNull IIdentifierParser identifierParser,
63 @NonNull List<IEntityItem.ItemType> itemTypes) {
64 super(identifierParser, itemTypes);
65 }
66
67 @Override
68 public String getReferenceText(@NonNull Property property) {
69 return property.getValue();
70 }
71
72 @Override
73 public void setReferenceText(@NonNull Property property, @NonNull String newValue) {
74 property.setValue(newValue);
75 }
76
77 @Override
78 protected void handleUnselected(
79 @NonNull IRequiredValueModelNodeItem contextItem,
80 @NonNull Property property,
81 @NonNull IEntityItem item,
82 @NonNull ReferenceCountingVisitor.Context visitorContext) {
83 URI linkHref = URI.create(property.getValue());
84 URI sourceUri = item.getSource();
85
86 URI resolved = sourceUri.resolve(linkHref);
87 if (LOGGER.isDebugEnabled()) {
88 LOGGER.atTrace().log("At path '{}', remapping orphaned URI '{}' to '{}'",
89 contextItem.toPath(IPathFormatter.METAPATH_PATH_FORMATER),
90 linkHref.toString(),
91 resolved.toString());
92 }
93 property.setValue(resolved.toString());
94 }
95
96 @Override
97 protected boolean handleIndexMiss(
98 @NonNull IRequiredValueModelNodeItem contextItem,
99 @NonNull Property property,
100 @NonNull List<IEntityItem.ItemType> itemTypes,
101 @NonNull String identifier,
102 @NonNull ReferenceCountingVisitor.Context visitorContext) {
103 if (LOGGER.isWarnEnabled()) {
104 LOGGER.atWarn().log(
105 "The property '{}' at '{}' should reference a {} identified by '{}',"
106 + " but the identifier was not found in the index.",
107 property.getQName(),
108 contextItem.toPath(IPathFormatter.METAPATH_PATH_FORMATER),
109 itemTypes.stream()
110 .map(en -> en.name().toLowerCase(Locale.ROOT))
111 .collect(CustomCollectors.joiningWithOxfordComma("or")),
112 identifier);
113 }
114 return true;
115 }
116 }