1 package org.opentrafficsim.base.parameters.constraint;
2
3 import java.util.HashSet;
4 import java.util.Set;
5
6 /**
7 * Constraint containing multiple constraints.
8 * <p>
9 * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
10 * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
11 * <p>
12 * @version $Revision$, $LastChangedDate$, by $Author$, initial version 11 sep. 2017 <br>
13 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
14 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
15 * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
16 * @param <T> value type
17 */
18 public class MultiConstraint<T> implements Constraint<T>
19 {
20
21 /** Set of constraints. */
22 private final Set<Constraint<T>> constraints;
23
24 /** Message of the latest failed constrained. */
25 private String failedConstraintMessage = null;
26
27 /** String representation. */
28 private final String stringRepresentation;
29
30 /**
31 * Creates a {@code MultiConstraint} from given constraints.
32 * @param constraints Constraint<T>...; constraints
33 * @param <T> value type
34 * @return {@code MultiConstraint}
35 */
36 @SafeVarargs
37 public static final <T> MultiConstraint<T> create(final Constraint<T>... constraints)
38 {
39 Set<Constraint<T>> set = new HashSet<>();
40 for (Constraint<T> constraint : constraints)
41 {
42 set.add(constraint);
43 }
44 return new MultiConstraint<>(set);
45 }
46
47 /**
48 * Constructor.
49 * @param constraints Set<Constraint<T>>; constraints
50 */
51 public MultiConstraint(final Set<Constraint<T>> constraints)
52 {
53 this.constraints = constraints;
54 this.stringRepresentation = String.format("MultiConstraint [contains %d constraints]", this.constraints.size());
55 }
56
57 /** {@inheritDoc} */
58 @Override
59 public boolean accept(final T value)
60 {
61 for (Constraint<T> constraint : this.constraints)
62 {
63 if (!constraint.accept(value))
64 {
65 this.failedConstraintMessage = constraint.failMessage();
66 return false;
67 }
68 }
69 return true;
70 }
71
72 /** {@inheritDoc} */
73 @Override
74 public String failMessage()
75 {
76 if (this.failedConstraintMessage == null)
77 {
78 return "A constraint failed for parameter '%s'.";
79 }
80 // note that we do not synchronize, nor can't we be assured that after accept()=false, this method is (directly) invoked
81 return "A constraint failed, most likely: " + this.failedConstraintMessage;
82 }
83
84 /** {@inheritDoc} */
85 @Override
86 public String toString()
87 {
88 return this.stringRepresentation;
89 }
90
91 }