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