001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package dev.metaschema.oscal.lib.profile.resolver.policy;
007
008import java.util.Objects;
009import java.util.regex.Matcher;
010import java.util.regex.Pattern;
011
012import dev.metaschema.core.util.ObjectUtils;
013import dev.metaschema.oscal.lib.profile.resolver.ProfileResolutionEvaluationException;
014import edu.umd.cs.findbugs.annotations.NonNull;
015
016public class PatternIdentifierParser implements IIdentifierParser {
017  private final Pattern pattern;
018  private final int identifierGroup;
019
020  @SuppressWarnings("null")
021  public PatternIdentifierParser(@NonNull String pattern, int identifierGroup) {
022    this(Pattern.compile(pattern), identifierGroup);
023  }
024
025  public PatternIdentifierParser(@NonNull Pattern pattern, int identifierGroup) {
026    this.pattern = Objects.requireNonNull(pattern, "pattern");
027    this.identifierGroup = identifierGroup;
028  }
029
030  public Pattern getPattern() {
031    return pattern;
032  }
033
034  public int getIdentifierGroup() {
035    return identifierGroup;
036  }
037
038  @Override
039  public String parse(@NonNull String referenceText) {
040    Matcher matcher = getPattern().matcher(referenceText);
041
042    String retval = null;
043    if (matcher.matches()) {
044      retval = matcher.group(getIdentifierGroup());
045    }
046    return retval;
047  }
048
049  @Override
050  public String update(@NonNull String referenceText, @NonNull String newIdentifier) {
051    Matcher matcher = getPattern().matcher(referenceText);
052    if (!matcher.matches()) {
053      throw new ProfileResolutionEvaluationException(
054          String.format("The original reference '%s' did not match the pattern '%s'.",
055              referenceText, getPattern().pattern()));
056    }
057
058    return ObjectUtils.notNull(new StringBuilder(referenceText)
059        .replace(
060            matcher.start(getIdentifierGroup()),
061            matcher.end(getIdentifierGroup()),
062            newIdentifier)
063        .toString());
064  }
065}