1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.oscal.lib.profile.resolver.policy;
7   
8   import java.util.Objects;
9   import java.util.regex.Matcher;
10  import java.util.regex.Pattern;
11  
12  import dev.metaschema.core.util.ObjectUtils;
13  import dev.metaschema.oscal.lib.profile.resolver.ProfileResolutionEvaluationException;
14  import edu.umd.cs.findbugs.annotations.NonNull;
15  
16  public class PatternIdentifierParser implements IIdentifierParser {
17    private final Pattern pattern;
18    private final int identifierGroup;
19  
20    @SuppressWarnings("null")
21    public PatternIdentifierParser(@NonNull String pattern, int identifierGroup) {
22      this(Pattern.compile(pattern), identifierGroup);
23    }
24  
25    public PatternIdentifierParser(@NonNull Pattern pattern, int identifierGroup) {
26      this.pattern = Objects.requireNonNull(pattern, "pattern");
27      this.identifierGroup = identifierGroup;
28    }
29  
30    public Pattern getPattern() {
31      return pattern;
32    }
33  
34    public int getIdentifierGroup() {
35      return identifierGroup;
36    }
37  
38    @Override
39    public String parse(@NonNull String referenceText) {
40      Matcher matcher = getPattern().matcher(referenceText);
41  
42      String retval = null;
43      if (matcher.matches()) {
44        retval = matcher.group(getIdentifierGroup());
45      }
46      return retval;
47    }
48  
49    @Override
50    public String update(@NonNull String referenceText, @NonNull String newIdentifier) {
51      Matcher matcher = getPattern().matcher(referenceText);
52      if (!matcher.matches()) {
53        throw new ProfileResolutionEvaluationException(
54            String.format("The original reference '%s' did not match the pattern '%s'.",
55                referenceText, getPattern().pattern()));
56      }
57  
58      return ObjectUtils.notNull(new StringBuilder(referenceText)
59          .replace(
60              matcher.start(getIdentifierGroup()),
61              matcher.end(getIdentifierGroup()),
62              newIdentifier)
63          .toString());
64    }
65  }