View Javadoc
1   /*******************************************************************************
2    * Portions created by Sebastian Thomschke are copyright (c) 2005-2011 Sebastian
3    * Thomschke.
4    * 
5    * All Rights Reserved. This program and the accompanying materials
6    * are made available under the terms of the Eclipse Public License v1.0
7    * which accompanies this distribution, and is available at
8    * http://www.eclipse.org/legal/epl-v10.html
9    * 
10   * Contributors:
11   *     Sebastian Thomschke - initial implementation.
12   *******************************************************************************/
13  package net.sf.oval.constraint;
14  
15  import static net.sf.oval.Validator.getCollectionFactory;
16  
17  import java.lang.reflect.Field;
18  import java.lang.reflect.Method;
19  import java.util.Map;
20  
21  import net.sf.oval.Validator;
22  import net.sf.oval.configuration.annotation.AbstractAnnotationCheck;
23  import net.sf.oval.context.OValContext;
24  import net.sf.oval.exception.FieldNotFoundException;
25  import net.sf.oval.exception.InvokingMethodFailedException;
26  import net.sf.oval.exception.MethodNotFoundException;
27  import net.sf.oval.internal.ContextCache;
28  import net.sf.oval.internal.util.ReflectionUtils;
29  
30  /**
31   * @author Sebastian Thomschke
32   */
33  public class EqualToFieldCheck extends AbstractAnnotationCheck<EqualToField>
34  {
35  	private static final long serialVersionUID = 1L;
36  
37  	private boolean useGetter;
38  
39  	private String fieldName;
40  
41  	private Class< ? > declaringClass;
42  
43  	/**
44  	 * {@inheritDoc}
45  	 */
46  	@Override
47  	public void configure(final EqualToField constraintAnnotation)
48  	{
49  		super.configure(constraintAnnotation);
50  		setFieldName(constraintAnnotation.value());
51  		setDeclaringClass(constraintAnnotation.declaringClass());
52  		setUseGetter(constraintAnnotation.useGetter());
53  	}
54  
55  	/**
56  	 * {@inheritDoc}
57  	 */
58  	@Override
59  	protected Map<String, String> createMessageVariables()
60  	{
61  		final Map<String, String> messageVariables = getCollectionFactory().createMap(2);
62  		messageVariables.put("fieldName", fieldName);
63  		messageVariables.put("declaringClass", declaringClass == null || declaringClass == Void.class ? null
64  				: declaringClass.getName());
65  		messageVariables.put("useGetter", Boolean.toString(useGetter));
66  		return messageVariables;
67  	}
68  
69  	/**
70  	 * @return the declaringClass
71  	 */
72  	public Class< ? > getDeclaringClass()
73  	{
74  		return declaringClass;
75  	}
76  
77  	/**
78  	 * @return the fieldName
79  	 */
80  	public String getFieldName()
81  	{
82  		return fieldName;
83  	}
84  
85  	/**
86  	 * {@inheritDoc}
87  	 */
88  	public boolean isSatisfied(final Object validatedObject, final Object valueToValidate, final OValContext context,
89  			final Validator validator)
90  	{
91  		if (valueToValidate == null) return true;
92  
93  		final Class< ? > clazz = validatedObject.getClass();
94  
95  		final Object valueToCompare;
96  		if (useGetter)
97  		{
98  			final Method getter = ReflectionUtils.getGetterRecursive(clazz, fieldName);
99  			if (getter == null)
100 				throw new MethodNotFoundException("Getter for field <" + fieldName + "> not found in class <" + clazz
101 						+ "> or it's super classes.");
102 
103 			try
104 			{
105 				valueToCompare = getter.invoke(validatedObject);
106 			}
107 			catch (final Exception ex)
108 			{
109 				throw new InvokingMethodFailedException(getter.getName(), validatedObject,
110 						ContextCache.getMethodReturnValueContext(getter), ex);
111 			}
112 		}
113 		else
114 		{
115 			final Field field = ReflectionUtils.getFieldRecursive(clazz, fieldName);
116 
117 			if (field == null)
118 				throw new FieldNotFoundException("Field <" + fieldName + "> not found in class <" + clazz
119 						+ "> or it's super classes.");
120 
121 			valueToCompare = ReflectionUtils.getFieldValue(field, validatedObject);
122 		}
123 
124 		if (valueToCompare == null) return false;
125 
126 		return valueToValidate.equals(valueToCompare);
127 	}
128 
129 	/**
130 	 * @return the useGetter
131 	 */
132 	public boolean isUseGetter()
133 	{
134 		return useGetter;
135 	}
136 
137 	/**
138 	 * @param declaringClass the declaringClass to set
139 	 */
140 	public void setDeclaringClass(final Class< ? > declaringClass)
141 	{
142 		this.declaringClass = declaringClass == Void.class ? null : declaringClass;
143 		requireMessageVariablesRecreation();
144 	}
145 
146 	/**
147 	 * @param fieldName the fieldName to set
148 	 */
149 	public void setFieldName(final String fieldName)
150 	{
151 		this.fieldName = fieldName;
152 		requireMessageVariablesRecreation();
153 	}
154 
155 	/**
156 	 * @param useGetter the useGetter to set
157 	 */
158 	public void setUseGetter(final boolean useGetter)
159 	{
160 		this.useGetter = useGetter;
161 		requireMessageVariablesRecreation();
162 	}
163 }