001: /*
002: * Copyright 2005-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005: * in compliance with the License. You may obtain a copy of the License at
006: *
007: * http://www.apache.org/licenses/LICENSE-2.0
008: *
009: * Unless required by applicable law or agreed to in writing, software distributed under the License
010: * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011: * or implied. See the License for the specific language governing permissions and limitations under
012: * the License.
013: */
014:
015: package org.strecks.validator.internal;
016:
017: import java.lang.reflect.Modifier;
018: import java.util.ArrayList;
019: import java.util.Collections;
020: import java.util.Iterator;
021: import java.util.List;
022:
023: import org.strecks.exceptions.ApplicationConfigurationException;
024: import org.strecks.util.Assert;
025:
026: /**
027: * Class used internally by <code>ValidationAnnotationReader</code> to check, for each form
028: * property, which validators use the converted value, and to perform additional type checking
029: * operations
030: * @author Phil Zoio
031: */
032: public class ConvertedTypeValidationChecker {
033:
034: private List<ValidatorWrapper> validators;
035:
036: private List<SortableValidator> sortableValidators;
037:
038: private OrderedProperty orderedProperty;
039:
040: private boolean usesConvertedValue;
041:
042: private Class<?> declaringClass;
043:
044: private Class<?> converterType;
045:
046: public ConvertedTypeValidationChecker(Class<?> declaringClass,
047: OrderedProperty orderedProperty,
048: List<ValidatorWrapper> validators) {
049: super ();
050: Assert.notNull(validators);
051: Assert.notNull(orderedProperty);
052: Assert.notNull(declaringClass);
053: this .validators = validators;
054: this .orderedProperty = orderedProperty;
055: this .declaringClass = declaringClass;
056: }
057:
058: public boolean checkConvertedValueTypes() {
059: if (checkUsesConvertedValue()) {
060: checkAllAreAssignable();
061: setConverterType();
062: return true;
063: }
064: return false;
065: }
066:
067: void setConverterType() {
068: // must be at least one element in iterator
069: SortableValidator next = sortableValidators.iterator().next();
070: ValidatorWrapper wrapper = next.getWrapper();
071: converterType = wrapper.getParameterizedType();
072:
073: if (converterType.isInterface()) {
074: throw new ApplicationConfigurationException(
075: "Class "
076: + declaringClass.getName()
077: + ", property "
078: + orderedProperty.getPropertyName()
079: + " uses validators for which the most concrete parameterized type "
080: + converterType.getName()
081: + " is an interface. It must be an instantiable concrete class");
082: }
083:
084: if (Modifier.isAbstract(converterType.getModifiers())) {
085: throw new ApplicationConfigurationException(
086: "Class "
087: + declaringClass.getName()
088: + ", property "
089: + orderedProperty.getPropertyName()
090: + " uses validators for which the most concrete parameterized type "
091: + converterType.getName()
092: + " is an abstract class. It must be an instantiable concrete class");
093: }
094:
095: }
096:
097: void checkAllAreAssignable() {
098: sortValidators();
099:
100: Iterator<SortableValidator> iterator = sortableValidators
101: .iterator();
102:
103: // must be at least one element in iterator
104: SortableValidator current = iterator.next();
105:
106: while (iterator.hasNext()) {
107: SortableValidator next = iterator.next();
108: Class<?> currentClass = current.getWrapper()
109: .getParameterizedType();
110: Class<?> nextClass = next.getWrapper()
111: .getParameterizedType();
112:
113: if (!nextClass.isAssignableFrom(currentClass)) {
114: throw new ApplicationConfigurationException("Class "
115: + declaringClass.getName() + ", property "
116: + orderedProperty.getPropertyName()
117: + " uses validators with parameterized types "
118: + currentClass.getName() + " and "
119: + nextClass.getName()
120: + " which are not type compatible");
121: }
122:
123: current = next;
124: }
125: }
126:
127: /* * ********************* package implementation methods * ********************* */
128:
129: void sortValidators() {
130: sortableValidators = new ArrayList<SortableValidator>();
131:
132: for (ValidatorWrapper wrapper : validators) {
133: // second check is probably redundant but lets be safe
134: if (wrapper.getUsesConvertedValue()
135: && wrapper.getParameterizedType() != null) {
136: sortableValidators.add(new SortableValidator(wrapper));
137: }
138: }
139:
140: Collections.sort(sortableValidators);
141: }
142:
143: boolean checkUsesConvertedValue() {
144: usesConvertedValue = false;
145: for (ValidatorWrapper wrapper : validators) {
146: if (wrapper.getUsesConvertedValue()) {
147: usesConvertedValue = true;
148: break;
149: }
150: }
151: return usesConvertedValue;
152: }
153:
154: List<SortableValidator> getSortableValidators() {
155: return sortableValidators;
156: }
157:
158: boolean getUsesConvertedValue() {
159: return usesConvertedValue;
160: }
161:
162: /*
163: * **************************************** public accessor methods
164: * ***************************************
165: */
166:
167: public Class<?> getConverterType() {
168: return converterType;
169: }
170:
171: }
|