001 /*--------------------------------------------------------------------------+
002 $Id: ConstraintValidator.java 26283 2010-02-18 11:18:57Z juergens $
003 | |
004 | Copyright 2005-2010 Technische Universitaet Muenchen |
005 | |
006 | Licensed under the Apache License, Version 2.0 (the "License"); |
007 | you may not use this file except in compliance with the License. |
008 | You may obtain a copy of the License at |
009 | |
010 | http://www.apache.org/licenses/LICENSE-2.0 |
011 | |
012 | Unless required by applicable law or agreed to in writing, software |
013 | distributed under the License is distributed on an "AS IS" BASIS, |
014 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
015 | See the License for the specific language governing permissions and |
016 | limitations under the License. |
017 +--------------------------------------------------------------------------*/
018 package edu.tum.cs.commons.constraint;
019
020 import edu.tum.cs.commons.collections.PairList;
021 import edu.tum.cs.commons.error.IExceptionHandler;
022 import edu.tum.cs.commons.error.RethrowingExceptionHandler;
023 import edu.tum.cs.commons.visitor.IMeshWalker;
024 import edu.tum.cs.commons.visitor.ITreeWalker;
025 import edu.tum.cs.commons.visitor.IVisitor;
026 import edu.tum.cs.commons.visitor.VisitorUtils;
027
028 /**
029 * A class for storing constraints in the context of classes for which the
030 * constraint applies. Additionally it provides methods for checking all
031 * matching constraints for a given class.
032 *
033 * @author hummelb
034 * @author $Author: juergens $
035 * @version $Rev: 26283 $
036 * @levd.rating GREEN Hash: 161B52F22D19EF2632D009F5148C7727
037 */
038 public class ConstraintValidator {
039
040 /** Storage for constraints in conjunction with the class they apply to. */
041 private final PairList<Class<?>, ILocalConstraint<?>> localConstraints = new PairList<Class<?>, ILocalConstraint<?>>();
042
043 /** Adds a constraint for a class. */
044 public <T> void addConstraint(Class<? extends T> clazz,
045 ILocalConstraint<T> constraint) {
046 localConstraints.add(clazz, constraint);
047 }
048
049 /**
050 * Checks all constraints to the given object which are applicable to it.
051 *
052 * @throws ConstraintViolationException
053 * if any constraint is violated
054 */
055 public void checkConstaints(Object o) throws ConstraintViolationException {
056 checkConstaints(o, RethrowingExceptionHandler
057 .<ConstraintViolationException> getInstance());
058 }
059
060 /**
061 * Checks all constraints to the given object which are applicable to it. If
062 * a constraint is violated, the thrown exception is handled by the given
063 * provider.
064 */
065 @SuppressWarnings("unchecked")
066 public <X extends Exception> void checkConstaints(Object o,
067 IExceptionHandler<ConstraintViolationException, X> handler)
068 throws X {
069 Class<?> clazz = o.getClass();
070 for (int i = 0; i < localConstraints.size(); ++i) {
071 if (localConstraints.getFirst(i).isAssignableFrom(clazz)) {
072 ILocalConstraint<?> constraint = localConstraints.getSecond(i);
073 try {
074 ((ILocalConstraint) constraint).checkLocalConstraint(o);
075 } catch (ConstraintViolationException e) {
076 handler.handleException(e);
077 }
078 }
079 }
080 }
081
082 /**
083 * Validates all nodes of a tree. The first violation found is propagated to
084 * the top using a {@link ConstraintViolationException}.
085 *
086 * @param root
087 * the root of the tree.
088 * @param walker
089 * the walker used to navigate the tree.
090 * @throws ConstraintViolationException
091 * if a constraint violation was found.
092 * @throws X_WALKER
093 * if the walker throws an exception.
094 */
095 public <T, X_WALKER extends Exception> void validateTree(T root,
096 ITreeWalker<T, X_WALKER> walker)
097 throws ConstraintViolationException, X_WALKER {
098
099 validateTree(root, walker, RethrowingExceptionHandler
100 .<ConstraintViolationException> getInstance());
101 }
102
103 /**
104 * Validates all nodes of a tree.
105 *
106 * @param root
107 * the root of the tree.
108 * @param walker
109 * the walker used to navigate the tree.
110 * @param handler
111 * the exception handler used for dealing with constraint
112 * violations.
113 * @throws X
114 * if the constraint violation handler throws it.
115 * @throws X_WALKER
116 * if the walker throws an exception.
117 */
118 public <T, X extends Exception, X_WALKER extends Exception> void validateTree(
119 T root, ITreeWalker<T, X_WALKER> walker,
120 IExceptionHandler<ConstraintViolationException, X> handler)
121 throws X, X_WALKER {
122
123 VisitorUtils.visitAllPreOrder(root, walker, new CheckVisitor<T, X>(
124 handler));
125 }
126
127 /**
128 * Validates all reachable elements of a mesh. The first violation found is
129 * propagated to the top using a {@link ConstraintViolationException}.
130 *
131 * @param start
132 * the start element of the mesh.
133 * @param walker
134 * the walker used to navigate the mesh.
135 * @throws ConstraintViolationException
136 * if a constraint violation was found.
137 * @throws X_WALKER
138 * if the walker throws an exception.
139 */
140 public <T, X_WALKER extends Exception> void validateMesh(T start,
141 IMeshWalker<T, X_WALKER> walker)
142 throws ConstraintViolationException, X_WALKER {
143
144 validateMesh(start, walker, RethrowingExceptionHandler
145 .<ConstraintViolationException> getInstance());
146 }
147
148 /**
149 * Validates all reachable elements of a mesh.
150 *
151 * @param start
152 * the start element of the mesh.
153 * @param walker
154 * the walker used to navigate the mesh.
155 * @param handler
156 * the exception handler used for dealing with constraint
157 * violations.
158 * @throws X
159 * if the constraint violation handler throws it.
160 * @throws X_WALKER
161 * if the walker throws an exception.
162 */
163 public <T, X extends Exception, X_WALKER extends Exception> void validateMesh(
164 T start, IMeshWalker<T, X_WALKER> walker,
165 IExceptionHandler<ConstraintViolationException, X> handler)
166 throws X, X_WALKER {
167
168 VisitorUtils.visitAllDepthFirst(start, walker, new CheckVisitor<T, X>(
169 handler));
170 }
171
172 /**
173 * A simple visitor checking each element with the
174 * {@link ConstraintValidator#checkConstaints(Object, IExceptionHandler)}
175 * method.
176 */
177 private class CheckVisitor<T, X extends Exception> implements
178 IVisitor<T, X> {
179
180 /** The handler used. */
181 private final IExceptionHandler<ConstraintViolationException, X> handler;
182
183 /** Constructor. */
184 public CheckVisitor(
185 IExceptionHandler<ConstraintViolationException, X> handler) {
186 this.handler = handler;
187 }
188
189 /** {@inheritDoc} */
190 public void visit(T element) throws X {
191 checkConstaints(element, handler);
192 }
193
194 }
195 }