1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package gov.nist.secauto.oscal.lib.profile.resolver.policy;
7   
8   import com.vladsch.flexmark.util.sequence.BasedSequence;
9   
10  import gov.nist.secauto.metaschema.core.datatype.markup.flexmark.InsertAnchorExtension.InsertAnchorNode;
11  import gov.nist.secauto.metaschema.core.metapath.format.IPathFormatter;
12  import gov.nist.secauto.metaschema.core.metapath.item.node.IModelNodeItem;
13  import gov.nist.secauto.metaschema.core.util.CollectionUtil;
14  import gov.nist.secauto.metaschema.core.util.CustomCollectors;
15  import gov.nist.secauto.metaschema.core.util.ObjectUtils;
16  import gov.nist.secauto.oscal.lib.profile.resolver.support.IEntityItem;
17  
18  import org.apache.logging.log4j.LogManager;
19  import org.apache.logging.log4j.Logger;
20  
21  import java.util.List;
22  import java.util.Locale;
23  
24  import edu.umd.cs.findbugs.annotations.NonNull;
25  
26  public class InsertReferencePolicy
27      extends AbstractCustomReferencePolicy<InsertAnchorNode> {
28    private static final Logger LOGGER = LogManager.getLogger(InsertReferencePolicy.class);
29  
30    public InsertReferencePolicy() {
31      super(IIdentifierParser.IDENTITY_PARSER);
32    }
33  
34    @Override
35    protected List<IEntityItem.ItemType> getEntityItemTypes(@NonNull InsertAnchorNode insert) {
36      String type = insert.getType().toString();
37  
38      if (!"param".equals(type)) {
39        throw new UnsupportedOperationException("unrecognized insert type: " + type);
40      }
41      return CollectionUtil.singletonList(IEntityItem.ItemType.PARAMETER);
42    }
43  
44    @Override
45    public String getReferenceText(@NonNull InsertAnchorNode insert) {
46      return insert.getIdReference().toString();
47    }
48  
49    @Override
50    public void setReferenceText(@NonNull InsertAnchorNode insert, @NonNull String newReference) {
51      insert.setIdReference(ObjectUtils.notNull(BasedSequence.of(newReference)));
52    }
53  
54    @Override
55    protected boolean handleIndexMiss(
56        @NonNull IModelNodeItem<?, ?> contextItem,
57        @NonNull InsertAnchorNode insert,
58        @NonNull List<IEntityItem.ItemType> itemTypes,
59        @NonNull String identifier,
60        @NonNull ReferenceCountingVisitor.Context visitorContext) {
61      if (LOGGER.isErrorEnabled()) {
62        LOGGER.atError().log(
63            "The '{}' insert at '{}' should reference a '{}' identified by '{}'."
64                + " The index did not contain the identifier.",
65            insert.getType().toString(),
66            contextItem.toPath(IPathFormatter.METAPATH_PATH_FORMATER),
67            itemTypes.stream()
68                .map(type -> type.name().toLowerCase(Locale.ROOT))
69                .collect(CustomCollectors.joiningWithOxfordComma("or")),
70            identifier);
71      }
72      return true;
73    }
74  
75  }