001 /******************************************************************************* 002 * Portions created by Sebastian Thomschke are copyright (c) 2005-2011 Sebastian 003 * Thomschke. 004 * 005 * All Rights Reserved. This program and the accompanying materials 006 * are made available under the terms of the Eclipse Public License v1.0 007 * which accompanies this distribution, and is available at 008 * http://www.eclipse.org/legal/epl-v10.html 009 * 010 * Contributors: 011 * Sebastian Thomschke - initial implementation. 012 *******************************************************************************/ 013 package net.sf.oval.configuration.annotation; 014 015 import java.lang.annotation.Annotation; 016 import java.lang.reflect.Method; 017 018 import net.sf.oval.AbstractCheck; 019 import net.sf.oval.ConstraintTarget; 020 import net.sf.oval.internal.Log; 021 import net.sf.oval.internal.util.ReflectionUtils; 022 023 /** 024 * Partial implementation of check classes configurable via annotations. 025 * 026 * @author Sebastian Thomschke 027 */ 028 public abstract class AbstractAnnotationCheck<ConstraintAnnotation extends Annotation> extends AbstractCheck 029 implements 030 AnnotationCheck<ConstraintAnnotation> 031 { 032 private static final long serialVersionUID = 1L; 033 034 private static final Log LOG = Log.getLog(AbstractAnnotationCheck.class); 035 036 /** 037 * {@inheritDoc} 038 */ 039 public void configure(final ConstraintAnnotation constraintAnnotation) 040 { 041 final Class< ? > constraintClazz = constraintAnnotation.getClass(); 042 043 /* 044 * Retrieve the message value from the constraint annotation via reflection. 045 * Using reflection is required because annotations do not support inheritance and 046 * therefore cannot implement an interface that could be used for a down cast here. 047 */ 048 final Method getMessage = ReflectionUtils.getMethod(constraintClazz, "message", (Class< ? >[]) null); 049 if (getMessage == null) 050 LOG.debug( 051 "Cannot determine constraint error message based on annotation {1} since attribtue message() is not defined.", 052 constraintClazz.getName()); 053 else 054 try 055 { 056 setMessage((String) getMessage.invoke(constraintAnnotation, (Object[]) null)); 057 } 058 catch (final Exception ex) 059 { 060 LOG.warn("Cannot determine constraint error message based on annotation {1}", 061 constraintClazz.getName(), ex); 062 063 try 064 { 065 setMessage(constraintClazz.getName() + ".violated"); 066 } 067 catch (final UnsupportedOperationException uex) 068 { 069 // ignore 070 } 071 } 072 073 /* 074 * Retrieve the appliesTo value from the constraint annotation via reflection. 075 */ 076 final Method getAppliesTo = ReflectionUtils.getMethod(constraintClazz, "appliesTo", (Class< ? >[]) null); 077 if (getAppliesTo == null) 078 LOG.debug( 079 "Cannot determine constraint targets based on annotation {1} since attribtue appliesTo() is not defined.", 080 constraintClazz.getName()); 081 else 082 try 083 { 084 setAppliesTo((ConstraintTarget[]) getAppliesTo.invoke(constraintAnnotation, (Object[]) null)); 085 } 086 catch (final Exception ex) 087 { 088 LOG.warn("Cannot determine constraint targets based on annotation {1}", constraintClazz.getName(), ex); 089 } 090 091 /* 092 * Retrieve the error code value from the constraint annotation via reflection. 093 */ 094 final Method getErrorCode = ReflectionUtils.getMethod(constraintClazz, "errorCode", (Class< ? >[]) null); 095 if (getErrorCode == null) 096 LOG.debug( 097 "Cannot determine constraint error code based on annotation {1} since attribtue errorCode() is not defined.", 098 constraintClazz.getName()); 099 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 }