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