MultiConstraint.java

  1. package org.opentrafficsim.base.parameters.constraint;

  2. import java.util.LinkedHashSet;
  3. import java.util.Set;

  4. /**
  5.  * Constraint containing multiple constraints.
  6.  * <p>
  7.  * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  8.  * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  9.  * </p>
  10.  * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
  11.  * @author <a href="https://github.com/peter-knoppers">Peter Knoppers</a>
  12.  * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
  13.  * @param <T> value type
  14.  */
  15. public class MultiConstraint<T> implements Constraint<T>
  16. {

  17.     /** Set of constraints. */
  18.     private final Set<Constraint<? super T>> constraints;

  19.     /** Message of the latest failed constrained. */
  20.     private String failedConstraintMessage = null;

  21.     /** String representation. */
  22.     private final String stringRepresentation;

  23.     /**
  24.      * Creates a {@code MultiConstraint} from given constraints.
  25.      * @param constraints constraints
  26.      * @param <T> value type
  27.      * @return {@code MultiConstraint}
  28.      */
  29.     @SafeVarargs
  30.     public static final <T> MultiConstraint<T> create(final Constraint<? super T>... constraints)
  31.     {
  32.         Set<Constraint<? super T>> set = new LinkedHashSet<>();
  33.         for (Constraint<? super T> constraint : constraints)
  34.         {
  35.             set.add(constraint);
  36.         }
  37.         return new MultiConstraint<>(set);
  38.     }

  39.     /**
  40.      * Constructor.
  41.      * @param constraints constraints
  42.      */
  43.     public MultiConstraint(final Set<Constraint<? super T>> constraints)
  44.     {
  45.         this.constraints = constraints;
  46.         this.stringRepresentation = String.format("MultiConstraint [contains %d constraints]", this.constraints.size());
  47.     }

  48.     @Override
  49.     public boolean accept(final T value)
  50.     {
  51.         for (Constraint<? super T> constraint : this.constraints)
  52.         {
  53.             if (!constraint.accept(value))
  54.             {
  55.                 this.failedConstraintMessage = constraint.failMessage();
  56.                 return false;
  57.             }
  58.         }
  59.         return true;
  60.     }

  61.     @Override
  62.     public String failMessage()
  63.     {
  64.         if (this.failedConstraintMessage == null)
  65.         {
  66.             return "A constraint failed for parameter '%s'.";
  67.         }
  68.         // note that we do not synchronize, nor can't we be assured that after accept()=false, this method is (directly) invoked
  69.         return "A constraint failed, most likely: " + this.failedConstraintMessage;
  70.     }

  71.     @Override
  72.     public String toString()
  73.     {
  74.         return this.stringRepresentation;
  75.     }

  76. }