Repository: open-telemetry/opentelemetry-java
File: sdk/common/src/main/java/io/opentelemetry/sdk/internal/IncludeExcludePredicate.java (Java)

Code before:
 */

package io.opentelemetry.sdk.internal;

import static io.opentelemetry.sdk.internal.GlobUtil.toGlobPatternPredicate;
import static java.util.stream.Collectors.joining;

import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.StringJoiner;
import java.util.function.Predicate;
import javax.annotation.Nullable;

/**
 * A predicate that evaluates if a string matches a configurable set of {@code included} and {@code
 * excluded} string.
 *
 * <p>Supports optional glob pattern matching. See {@link GlobUtil}.
 *
 * <p>String equality is evaluated using {@link String#equalsIgnoreCase(String)}.
 *
 * <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
 * at any time.
 */
public final class IncludeExcludePredicate implements Predicate<String> {

  private final boolean globMatchingEnabled;
  @Nullable private final Set<String> included;
  @Nullable private final Set<String> excluded;
  private final Predicate<String> predicate;

  private IncludeExcludePredicate(
      @Nullable Collection<String> included,
      @Nullable Collection<String> excluded,
      boolean globMatchingEnabled) {
    this.globMatchingEnabled = globMatchingEnabled;
    this.included = included == null ? null : new LinkedHashSet<>(included);
    this.excluded = excluded == null ? null : new LinkedHashSet<>(excluded);
    if (this.included != null && this.excluded != null) {
      this.predicate =
          includedPredicate(this.included, globMatchingEnabled)
              .and(excludedPredicate(this.excluded, globMatchingEnabled));
    } else if (this.included == null && this.excluded != null) {
      this.predicate = excludedPredicate(this.excluded, globMatchingEnabled);
    } else if (this.excluded == null && this.included != null) {
      this.predicate = includedPredicate(this.included, globMatchingEnabled);
    } else {
      throw new IllegalArgumentException(
          "At least one of includedPatterns or excludedPatterns must not be null");
    }

Review comment (refactor):
We have a recurring pattern of needing to match strings against a configurable allow / deny list, with optional glob pattern matching. In all these cases, its beneficial to have a useful `toString()` implementation.

This PR refactors the places this pattern occurs with a common implementation.

Code after:
 */

package io.opentelemetry.sdk.internal;

import static io.opentelemetry.sdk.internal.GlobUtil.createGlobPatternPredicate;
import static java.util.stream.Collectors.joining;

import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.StringJoiner;
import java.util.function.Predicate;
import javax.annotation.Nullable;

/**
 * A predicate that evaluates if a string matches a configurable set of {@code included} and {@code
 * excluded} string.
 *
 * <p>Supports optional glob pattern matching. See {@link GlobUtil}.
 *
 * <p>String equality is evaluated using {@link String#equalsIgnoreCase(String)}.
 *
 * <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
 * at any time.
 */
public final class IncludeExcludePredicate implements Predicate<String> {

  private final boolean globMatchingEnabled;
  @Nullable private final Set<String> included;
  @Nullable private final Set<String> excluded;
  private final Predicate<String> predicate;

  private IncludeExcludePredicate(
      @Nullable Collection<String> included,
      @Nullable Collection<String> excluded,
      boolean globMatchingEnabled) {
    this.globMatchingEnabled = globMatchingEnabled;
    this.included = included == null ? null : new LinkedHashSet<>(included);
    this.excluded = excluded == null ? null : new LinkedHashSet<>(excluded);
    if (this.included != null && this.excluded != null) {
      this.predicate =
          includedPredicate(this.included, globMatchingEnabled)
              .and(excludedPredicate(this.excluded, globMatchingEnabled));
    } else if (this.included == null && this.excluded != null) {
      this.predicate = excludedPredicate(this.excluded, globMatchingEnabled);
    } else if (this.excluded == null && this.included != null) {
      this.predicate = includedPredicate(this.included, globMatchingEnabled);
    } else {
      throw new IllegalArgumentException(
          "At least one of includedPatterns or excludedPatterns must not be null");
    }