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 }