001: /*
002: * $Header: /cvsroot/jvalidate/jvalidate-framework/jvalidate/src/main/java/nl/knowlogy/validation/ClassValidatorImpl.java,v 1.13 2007/11/13 15:35:45 roberthofstra Exp $
003: * $Revision: 1.13 $
004: * $Date: 2007/11/13 15:35:45 $
005: *
006: *
007: * Copyright 2004 - 2005 Knowlogy, the Netherlands, www.knowlogy.nl
008: *
009: * Licensed under the Apache License, Version 2.0 (the "License");
010: * you may not use this file except in compliance with the License.
011: * You may obtain a copy of the License at
012: *
013: * http://www.apache.org/licenses/LICENSE-2.0
014: *
015: * Unless required by applicable law or agreed to in writing, software
016: * distributed under the License is distributed on an "AS IS" BASIS,
017: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018: * See the License for the specific language governing permissions and
019: * limitations under the License.
020: */
021: package nl.knowlogy.validation;
022:
023: import java.util.ArrayList;
024: import java.util.Iterator;
025: import java.util.List;
026: import java.util.StringTokenizer;
027:
028: import nl.knowlogy.validation.metadata.ClassMetadata;
029: import nl.knowlogy.validation.metadata.PropertyMetadata;
030: import nl.knowlogy.validation.metadata.PropertyMetadataImpl;
031: import nl.knowlogy.validation.validators.IsValidValidator;
032:
033: import org.apache.commons.beanutils.PropertyUtils;
034: import org.apache.commons.collections.FastArrayList;
035: import org.apache.commons.collections.FastHashMap;
036: import org.apache.log4j.Logger;
037:
038: /**
039: * ClassValidatorImpl implements the <tt>ClassValidator</tt> interface
040: * for validation of objects and the <tt>ClassMetadata<tt> interface for
041: * providing metadata of that class.
042: *
043: * @author <a href="mailto:robert.hofstra@knowlogy.nl">Robert Hofstra, Knowlogy</a>
044: */
045: public class ClassValidatorImpl implements ClassValidator,
046: ClassMetadata {
047:
048: private final static Logger logger = Logger
049: .getLogger(ClassValidatorImpl.class);
050:
051: /**
052: * Map with property name as key and a propertyEntry object as value.
053: * A propertyEntry has a list of validators and a propertyMetaData object.
054: *
055: */
056: private FastHashMap propertyEntryMap = new FastHashMap();
057:
058: /**
059: * Map with group name as key and as
060: * value a list with propertyName's
061: *
062: */
063: private FastHashMap groups = new FastHashMap();
064:
065: private Class clazz;
066:
067: public ClassValidatorImpl(Class clazz) {
068: this .clazz = clazz;
069: }
070:
071: public Class getClazz() {
072: return clazz;
073: }
074:
075: /*
076: * (non-Javadoc)
077: *
078: * @see nl.knowlogy.validation.metadata.ClassMetadata#getPropertyMetadata(java.lang.String)
079: */
080: public PropertyMetadata getPropertyMetadata(String propertyName) {
081:
082: PropertyEntry propertyEntry = (PropertyEntry) propertyEntryMap
083: .get(propertyName);
084:
085: if (propertyEntry != null) {
086: return propertyEntry.getPropertyMetadata();
087: }
088: return null;
089: }
090:
091: public List getPropertyMetadata() {
092:
093: List propertyMetaDataList = new ArrayList();
094:
095: for (Iterator iter = propertyEntryMap.values().iterator(); iter
096: .hasNext();) {
097: PropertyEntry propertyEntry = (PropertyEntry) iter.next();
098: propertyMetaDataList.add(propertyEntry
099: .getPropertyMetadata());
100: }
101: return propertyMetaDataList;
102: }
103:
104: public void add(PropertyValidation propertyValidation) {
105: PropertyMetadataSuplier propertyMetadataSuplier = null;
106: if (propertyValidation instanceof PropertyMetadataSuplier) {
107: propertyMetadataSuplier = (PropertyMetadataSuplier) propertyValidation;
108: }
109: add(propertyValidation, propertyMetadataSuplier);
110: }
111:
112: public void add(PropertyValidation propertyValidation,
113: PropertyMetadataSuplier propertyMetadataSuplier) {
114:
115: PropertyEntry propertyEntry = (PropertyEntry) propertyEntryMap
116: .get(propertyValidation.getPropertyName());
117:
118: if (propertyEntry == null) {
119: propertyEntry = new PropertyEntry(propertyValidation
120: .getPropertyName());
121: propertyEntryMap.setFast(false);
122: propertyEntryMap.put(propertyValidation.getPropertyName(),
123: propertyEntry);
124: propertyEntryMap.setFast(true);
125: }
126: propertyEntry.addPropertyValidation(propertyValidation);
127:
128: if (propertyMetadataSuplier != null) {
129: PropertyMetadata propertyMetadata = propertyEntry
130: .getPropertyMetadata();
131: synchronized (propertyMetadata) {
132: propertyMetadataSuplier
133: .supplyMetaData(propertyMetadata);
134: }
135: }
136: if (logger.isDebugEnabled()) {
137: logger.debug("added propertyValidation to [" + this
138: + "] ,propertyValidaton " + propertyValidation);
139: }
140: }
141:
142: public void addPropertyToGroups(String groupNames,
143: String propertyName) {
144: StringTokenizer stringTokenizer = new StringTokenizer(
145: groupNames, ",");
146: FastArrayList propertyNames;
147:
148: while (stringTokenizer.hasMoreTokens()) {
149: String groupName = stringTokenizer.nextToken();
150: propertyNames = (FastArrayList) groups.get(groupName);
151:
152: if (propertyNames == null) {
153: propertyNames = new FastArrayList();
154: groups.setFast(false);
155: groups.put(groupName, propertyNames);
156: groups.setFast(true);
157: }
158: ;
159: propertyNames.setFast(false);
160: propertyNames.add(propertyName);
161: propertyNames.setFast(true);
162: }
163:
164: }
165:
166: public void validate(Object toValidate) {
167: Messages messages = new MessagesImpl();
168: validate(toValidate, messages);
169:
170: if (messages.getNumberOfMessages(MessageType.ERROR) > 0) {
171: throw new ValidationException(messages);
172: }
173:
174: }
175:
176: protected Object getValue(Object toValidate, String propertyName) {
177: try {
178: return PropertyUtils.getSimpleProperty(toValidate,
179: propertyName);
180: } catch (Exception e) {
181: throw new RuntimeException(e);
182: }
183: }
184:
185: private void doValidateProperties(Object toValidate,
186: Messages messages) {
187:
188: for (Iterator propertyEntryIterator = propertyEntryMap.values()
189: .iterator(); propertyEntryIterator.hasNext();) {
190:
191: PropertyEntry propertyEntry = (PropertyEntry) propertyEntryIterator
192: .next();
193:
194: for (Iterator validatorsIterator = propertyEntry
195: .getValidatorList().iterator(); validatorsIterator
196: .hasNext();) {
197:
198: PropertyValidation propertyValidation = (PropertyValidation) validatorsIterator
199: .next();
200:
201: propertyValidation.doValidatePropertyValue(toValidate,
202: getValue(toValidate, propertyValidation
203: .getPropertyName()), messages);
204: }
205:
206: }
207: }
208:
209: public void validate(Object toValidate, Messages messages) {
210: doValidateProperties(toValidate, messages);
211: if (toValidate instanceof ExposesValidates) {
212: ((ExposesValidates) toValidate).internalValidate(messages);
213: }
214: }
215:
216: public void validateGroup(Object toValidate, String groupName,
217: Messages errors) {
218: if (groups.containsKey(groupName)) {
219: FastArrayList propertyNames = (FastArrayList) groups
220: .get(groupName);
221: validateProperties(toValidate, propertyNames, errors);
222: }
223: validateGroupForIsValidValidators(toValidate, groupName, errors);
224: }
225:
226: private void validateGroupForIsValidValidators(Object toValidate,
227: String groupName, Messages messages) {
228: for (Iterator propertyEntryIterator = propertyEntryMap.values()
229: .iterator(); propertyEntryIterator.hasNext();) {
230:
231: PropertyEntry propertyEntry = (PropertyEntry) propertyEntryIterator
232: .next();
233:
234: for (Iterator validatorsIterator = propertyEntry
235: .getValidatorList().iterator(); validatorsIterator
236: .hasNext();) {
237:
238: PropertyValidation propertyValidation = (PropertyValidation) validatorsIterator
239: .next();
240:
241: if (propertyValidation instanceof IsValidValidator) {
242: ((IsValidValidator) propertyValidation)
243: .doValidatePropertyValue(
244: toValidate,
245: getValue(toValidate,
246: propertyValidation
247: .getPropertyName()),
248: groupName, messages);
249: }
250: }
251:
252: }
253: }
254:
255: public void validateProperties(Object toValidate,
256: List propertyNames, Messages messages) {
257:
258: for (Iterator propertyNamesIterator = propertyNames.iterator(); propertyNamesIterator
259: .hasNext();) {
260: String propertyName = (String) propertyNamesIterator.next();
261: Object value = getValue(toValidate, propertyName);
262: validatePropertyValue(toValidate, propertyName, value,
263: messages);
264: }
265:
266: }
267:
268: public void validatePropertyValue(Object toValidate,
269: String propertyName, Object value, Messages messages) {
270: PropertyEntry propertyEntry = (PropertyEntry) propertyEntryMap
271: .get(propertyName);
272: if (propertyEntry != null) {
273: for (Iterator validatorsIterator = propertyEntry
274: .getValidatorList().iterator(); validatorsIterator
275: .hasNext();) {
276: PropertyValidation propertyValidation = (PropertyValidation) validatorsIterator
277: .next();
278: if (logger.isDebugEnabled()) {
279: logger.debug("validate property [" + propertyName
280: + "], value [" + value + "], for class ["
281: + clazz.getName() + "] with "
282: + propertyValidation);
283: }
284: propertyValidation.doValidatePropertyValue(toValidate,
285: value, messages);
286: }
287: }
288: }
289:
290: public void validatePropertyValue(String propertyName,
291: Object value, Messages messages) {
292: validatePropertyValue(null, propertyName, value, messages);
293: }
294:
295: class PropertyEntry {
296:
297: private FastArrayList validatorList;
298: private PropertyMetadata propertyMetadata;
299: private String propertyName;
300:
301: public PropertyEntry(String propertyName) {
302: this .propertyName = propertyName;
303: validatorList = new FastArrayList();
304: validatorList.setFast(true);
305: }
306:
307: public FastArrayList getValidatorList() {
308: return validatorList;
309: }
310:
311: public PropertyMetadata getPropertyMetadata() {
312: if (propertyMetadata == null) {
313: propertyMetadata = new PropertyMetadataImpl(
314: propertyName);
315: }
316: return propertyMetadata;
317: }
318:
319: public void addPropertyValidation(
320: PropertyValidation propertyValidation) {
321: validatorList.setFast(false);
322: validatorList.add(propertyValidation);
323: validatorList.setFast(true);
324: }
325: }
326: }
|