1
2
3
4
5
6 package gov.nist.secauto.oscal.lib.profile.resolver.policy;
7
8 import gov.nist.secauto.metaschema.core.metapath.format.IPathFormatter;
9 import gov.nist.secauto.metaschema.core.metapath.item.node.IModelNodeItem;
10 import gov.nist.secauto.metaschema.core.util.CustomCollectors;
11 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
12 import gov.nist.secauto.oscal.lib.model.Property;
13 import gov.nist.secauto.oscal.lib.profile.resolver.support.IEntityItem;
14
15 import org.apache.logging.log4j.LogManager;
16 import org.apache.logging.log4j.Logger;
17
18 import java.net.URI;
19 import java.util.List;
20 import java.util.Locale;
21
22 import edu.umd.cs.findbugs.annotations.NonNull;
23
24 public class PropertyReferencePolicy
25 extends AbstractMultiItemTypeReferencePolicy<Property> {
26 private static final Logger LOGGER = LogManager.getLogger(PropertyReferencePolicy.class);
27
28 @NonNull
29 public static PropertyReferencePolicy create(@NonNull IIdentifierParser identifierParser,
30 @NonNull IEntityItem.ItemType itemType) {
31 return create(identifierParser, ObjectUtils.notNull(List.of(itemType)));
32 }
33
34 @NonNull
35 public static PropertyReferencePolicy create(@NonNull IIdentifierParser identifierParser,
36 @NonNull List<IEntityItem.ItemType> itemTypes) {
37 return new PropertyReferencePolicy(identifierParser, itemTypes);
38 }
39
40 public PropertyReferencePolicy(
41 @NonNull IIdentifierParser identifierParser,
42 @NonNull List<IEntityItem.ItemType> itemTypes) {
43 super(identifierParser, itemTypes);
44 }
45
46 @Override
47 public String getReferenceText(@NonNull Property property) {
48 return property.getValue();
49 }
50
51 @Override
52 public void setReferenceText(@NonNull Property property, @NonNull String newValue) {
53 property.setValue(newValue);
54 }
55
56 @Override
57 protected void handleUnselected(
58 @NonNull IModelNodeItem<?, ?> contextItem,
59 @NonNull Property property,
60 @NonNull IEntityItem item,
61 @NonNull ReferenceCountingVisitor.Context visitorContext) {
62 URI linkHref = URI.create(property.getValue());
63 URI sourceUri = item.getSource();
64
65 URI resolved = sourceUri.resolve(linkHref);
66 if (LOGGER.isDebugEnabled()) {
67 LOGGER.atTrace().log("At path '{}', remapping orphaned URI '{}' to '{}'",
68 contextItem.toPath(IPathFormatter.METAPATH_PATH_FORMATER),
69 linkHref.toString(),
70 resolved.toString());
71 }
72 property.setValue(resolved.toString());
73 }
74
75 @Override
76 protected boolean handleIndexMiss(
77 @NonNull IModelNodeItem<?, ?> contextItem,
78 @NonNull Property property,
79 @NonNull List<IEntityItem.ItemType> itemTypes,
80 @NonNull String identifier,
81 @NonNull ReferenceCountingVisitor.Context visitorContext) {
82 if (LOGGER.isWarnEnabled()) {
83 LOGGER.atWarn().log(
84 "The property '{}' at '{}' should reference a {} identified by '{}',"
85 + " but the identifier was not found in the index.",
86 property.getQName(),
87 contextItem.toPath(IPathFormatter.METAPATH_PATH_FORMATER),
88 itemTypes.stream()
89 .map(en -> en.name().toLowerCase(Locale.ROOT))
90 .collect(CustomCollectors.joiningWithOxfordComma("or")),
91 identifier);
92 }
93 return true;
94 }
95 }