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-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  8.  * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
  9.  * <p>
  10.  * @version $Revision$, $LastChangedDate$, by $Author$, initial version 11 sep. 2017 <br>
  11.  * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
  12.  * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
  13.  * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
  14.  * @param <T> value type
  15.  */
  16. public class MultiConstraint<T> implements Constraint<T>
  17. {

  18.     /** Set of constraints. */
  19.     private final Set<Constraint<T>> constraints;

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

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

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

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

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

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

  74.     /** {@inheritDoc} */
  75.     @Override
  76.     public String toString()
  77.     {
  78.         return this.stringRepresentation;
  79.     }

  80. }