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.configuration.annotation;
14  
15  import java.lang.annotation.Annotation;
16  import java.lang.reflect.Method;
17  
18  import net.sf.oval.AbstractCheck;
19  import net.sf.oval.ConstraintTarget;
20  import net.sf.oval.internal.Log;
21  import net.sf.oval.internal.util.ReflectionUtils;
22  
23  /**
24   * Partial implementation of check classes configurable via annotations.
25   * 
26   * @author Sebastian Thomschke
27   */
28  public abstract class AbstractAnnotationCheck<ConstraintAnnotation extends Annotation> extends AbstractCheck
29  		implements
30  			AnnotationCheck<ConstraintAnnotation>
31  {
32  	private static final long serialVersionUID = 1L;
33  
34  	private static final Log LOG = Log.getLog(AbstractAnnotationCheck.class);
35  
36  	/**
37  	 * {@inheritDoc}
38  	 */
39  	public void configure(final ConstraintAnnotation constraintAnnotation)
40  	{
41  		final Class< ? > constraintClazz = constraintAnnotation.getClass();
42  
43  		/*
44  		 * Retrieve the message value from the constraint annotation via reflection.
45  		 * Using reflection is required because annotations do not support inheritance and 
46  		 * therefore cannot implement an interface that could be used for a down cast here.
47  		 */
48  		final Method getMessage = ReflectionUtils.getMethod(constraintClazz, "message", (Class< ? >[]) null);
49  		if (getMessage == null)
50  			LOG.debug(
51  					"Cannot determine constraint error message based on annotation {1} since attribtue message() is not defined.",
52  					constraintClazz.getName());
53  		else
54  			try
55  			{
56  				setMessage((String) getMessage.invoke(constraintAnnotation, (Object[]) null));
57  			}
58  			catch (final Exception ex)
59  			{
60  				LOG.warn("Cannot determine constraint error message based on annotation {1}",
61  						constraintClazz.getName(), ex);
62  
63  				try
64  				{
65  					setMessage(constraintClazz.getName() + ".violated");
66  				}
67  				catch (final UnsupportedOperationException uex)
68  				{
69  					// ignore
70  				}
71  			}
72  
73  		/*
74  		 * Retrieve the appliesTo value from the constraint annotation via reflection.
75  		 */
76  		final Method getAppliesTo = ReflectionUtils.getMethod(constraintClazz, "appliesTo", (Class< ? >[]) null);
77  		if (getAppliesTo == null)
78  			LOG.debug(
79  					"Cannot determine constraint targets based on annotation {1} since attribtue appliesTo() is not defined.",
80  					constraintClazz.getName());
81  		else
82  			try
83  			{
84  				setAppliesTo((ConstraintTarget[]) getAppliesTo.invoke(constraintAnnotation, (Object[]) null));
85  			}
86  			catch (final Exception ex)
87  			{
88  				LOG.warn("Cannot determine constraint targets based on annotation {1}", constraintClazz.getName(), ex);
89  			}
90  
91  		/*
92  		 * Retrieve the error code value from the constraint annotation via reflection.
93  		 */
94  		final Method getErrorCode = ReflectionUtils.getMethod(constraintClazz, "errorCode", (Class< ? >[]) null);
95  		if (getErrorCode == null)
96  			LOG.debug(
97  					"Cannot determine constraint error code based on annotation {1} since attribtue errorCode() is not defined.",
98  					constraintClazz.getName());
99  		else
100 			try
101 			{
102 				setErrorCode((String) getErrorCode.invoke(constraintAnnotation, (Object[]) null));
103 			}
104 			catch (final Exception ex)
105 			{
106 				LOG.warn("Cannot determine constraint error code based on annotation {1}", constraintClazz.getName(),
107 						ex);
108 				try
109 				{
110 					setErrorCode(constraintClazz.getName());
111 				}
112 				catch (final UnsupportedOperationException uex)
113 				{
114 					// ignore
115 				}
116 			}
117 
118 		/*
119 		 * Retrieve the severity value from the constraint annotation via reflection.
120 		 */
121 		final Method getSeverity = ReflectionUtils.getMethod(constraintClazz, "severity", (Class< ? >[]) null);
122 		if (getSeverity == null)
123 			LOG.debug(
124 					"Cannot determine constraint severity based on annotation {1} since attribtue severity() is not defined.",
125 					constraintClazz.getName());
126 		else
127 			try
128 			{
129 				setSeverity(((Number) getSeverity.invoke(constraintAnnotation, (Object[]) null)).intValue());
130 			}
131 			catch (final Exception ex)
132 			{
133 				LOG.warn("Cannot determine constraint severity based on annotation {1}", constraintClazz.getName(), ex);
134 			}
135 
136 		/*
137 		 * Retrieve the profiles value from the constraint annotation via reflection.
138 		 */
139 		final Method getProfiles = ReflectionUtils.getMethod(constraintClazz, "profiles", (Class< ? >[]) null);
140 		if (getProfiles == null)
141 			LOG.debug(
142 					"Cannot determine constraint profiles based on annotation {1} since attribtue profiles() is not defined.",
143 					constraintClazz.getName());
144 		else
145 			try
146 			{
147 				setProfiles((String[]) getProfiles.invoke(constraintAnnotation, (Object[]) null));
148 			}
149 			catch (final Exception ex)
150 			{
151 				LOG.warn("Cannot determine constraint profiles based on annotation {1}", constraintClazz.getName(), ex);
152 			}
153 
154 		/*
155 		 * Retrieve the profiles value from the constraint annotation via reflection.
156 		 */
157 		final Method getTarget = ReflectionUtils.getMethod(constraintClazz, "target", (Class< ? >[]) null);
158 		if (getTarget == null)
159 			LOG.debug(
160 					"Cannot determine constraint target based on annotation {1} since attribtue target() is not defined.",
161 					constraintClazz.getName());
162 		else
163 			try
164 			{
165 				setTarget((String) getTarget.invoke(constraintAnnotation, (Object[]) null));
166 			}
167 			catch (final Exception ex)
168 			{
169 				LOG.warn("Cannot determine constraint target based on annotation {1}", constraintClazz.getName(), ex);
170 			}
171 
172 		/*
173 		 * Retrieve the when formula from the constraint annotation via reflection.
174 		 */
175 		final Method getWhen = ReflectionUtils.getMethod(constraintClazz, "when", (Class< ? >[]) null);
176 		if (getWhen == null)
177 			LOG.debug(
178 					"Cannot determine constraint when formula based on annotation {1} since attribtue when() is not defined.",
179 					constraintClazz.getName());
180 		else
181 			try
182 			{
183 				setWhen((String) getWhen.invoke(constraintAnnotation, (Object[]) null));
184 			}
185 			catch (final Exception ex)
186 			{
187 				LOG.warn("Cannot determine constraint when formula based on annotation {1}", constraintClazz.getName(),
188 						ex);
189 			}
190 	}
191 }