1 18 19 package org.apache.beehive.controls.system.jdbc; 20 21 import com.sun.mirror.apt.AnnotationProcessorEnvironment; 22 import com.sun.mirror.declaration.Declaration; 23 import com.sun.mirror.declaration.FieldDeclaration; 24 import com.sun.mirror.declaration.MethodDeclaration; 25 import com.sun.mirror.declaration.TypeDeclaration; 26 import com.sun.mirror.type.ArrayType; 27 import com.sun.mirror.type.DeclaredType; 28 import com.sun.mirror.type.InterfaceType; 29 import com.sun.mirror.type.MirroredTypeException; 30 import com.sun.mirror.type.PrimitiveType; 31 import com.sun.mirror.type.TypeMirror; 32 import com.sun.mirror.type.VoidType; 33 import org.apache.beehive.controls.api.ControlException; 34 import org.apache.beehive.controls.api.bean.ControlChecker; 35 import org.apache.beehive.controls.system.jdbc.parser.ParameterChecker; 36 import org.apache.beehive.controls.system.jdbc.parser.SqlParser; 37 import org.apache.beehive.controls.system.jdbc.parser.SqlStatement; 38 39 import java.util.Collection ; 40 import java.sql.SQLException ; 41 42 45 public class JdbcControlChecker implements ControlChecker { 46 47 52 public void check(Declaration decl, AnnotationProcessorEnvironment env) { 53 54 if (decl instanceof TypeDeclaration) { 55 56 checkConnectionDataSource((TypeDeclaration) decl, env); 60 checkConnectionDriver((TypeDeclaration) decl, env); 61 checkConnectionOptions((TypeDeclaration) decl, env); 62 63 Collection <? extends MethodDeclaration> methods = ((TypeDeclaration) decl).getMethods(); 67 for (MethodDeclaration method : methods) { 68 checkSQL(method, env); 69 70 } 71 } else if (decl instanceof FieldDeclaration) { 72 73 } else { 77 78 } 82 } 83 84 90 private void checkConnectionDataSource(TypeDeclaration decl, AnnotationProcessorEnvironment env) { 91 final JdbcControl.ConnectionDataSource cds = 92 decl.getAnnotation(JdbcControl.ConnectionDataSource.class); 93 if (cds == null) { 94 return; 95 } 96 97 } 101 102 108 private void checkConnectionDriver(TypeDeclaration decl, AnnotationProcessorEnvironment env) { 109 final JdbcControl.ConnectionDriver cd = decl.getAnnotation(JdbcControl.ConnectionDriver.class); 110 if (cd == null) { 111 return; 112 } 113 114 } 118 119 125 private void checkConnectionOptions(TypeDeclaration decl, AnnotationProcessorEnvironment env) { 126 final JdbcControl.ConnectionOptions co = decl.getAnnotation(JdbcControl.ConnectionOptions.class); 127 if (co == null) { 128 return; 129 } 130 131 } 135 136 142 private void checkSQL(MethodDeclaration method, AnnotationProcessorEnvironment env) { 143 144 final JdbcControl.SQL methodSQL = method.getAnnotation(JdbcControl.SQL.class); 145 if (methodSQL == null) { 146 return; 147 } 148 149 if (methodSQL.statement() == null || methodSQL.statement().length() == 0) { 153 env.getMessager().printError(method.getPosition(), "@SQL annotation on method: " + method.getSimpleName() 154 + " contains an empty statement member."); 155 return; 156 } 157 158 int maxRows = methodSQL.maxRows(); 162 if (maxRows < JdbcControl.MAXROWS_ALL) { 163 env.getMessager().printError(method.getPosition(), "@SQL annotation on method: " + method.getSimpleName() 164 + " maxRows set to invalid value: " + maxRows); 165 return; 166 } 167 168 int arrayMax = methodSQL.arrayMaxLength(); 172 if (arrayMax < 1) { 173 env.getMessager().printError(method.getPosition(), "@SQL annotation on method: " + method.getSimpleName() 174 + " arrayMaxLength set to invalid value (must be greater than 0): " 175 + arrayMax); 176 return; 177 } 178 179 180 SqlParser _p = new SqlParser(); 186 SqlStatement _statement = null; 187 try { 188 _statement = _p.parse(methodSQL.statement()); 189 } catch (ControlException ce) { 190 env.getMessager().printError(method.getPosition(), "Error parsing SQL statment on method: " + method.getSimpleName() + ": " + ce.toString()); 191 return; 192 } 193 194 try { 201 ParameterChecker.checkReflectionParameters(_statement, method); 202 } catch (ControlException e) { 203 env.getMessager().printError(method.getPosition(), e.getMessage()); 204 return; 205 } 206 207 final boolean getGeneratedKeys = methodSQL.getGeneratedKeys(); 211 final String [] generatedKeyColumnNames = methodSQL.generatedKeyColumnNames(); 212 final int[] generatedKeyIndexes = methodSQL.generatedKeyColumnIndexes(); 213 if (getGeneratedKeys == false && (generatedKeyColumnNames.length != 0 || generatedKeyIndexes.length != 0)) { 214 env.getMessager().printError(method.getPosition(), "@SQL annotation on method: " + method.getSimpleName() 215 + " getGeneratedKeys must be set to true in order to specify generatedKeyColumnNames or generatedKeyColumnIndexes."); 216 return; 217 } 218 219 if (generatedKeyColumnNames.length > 0 && generatedKeyIndexes.length > 0) { 222 env.getMessager().printError(method.getPosition(), "@SQL annotation on method: " + method.getSimpleName() 223 + " only one of generatedKeyColumnNames or generatedKeyColumnIndexes may be set in the method annotation."); 224 225 return; 226 } 227 228 final boolean batchUpdate = methodSQL.batchUpdate(); 232 final TypeMirror returnType = method.getReturnType(); 233 if (batchUpdate) { 234 if (returnType instanceof ArrayType == true) { 235 final TypeMirror aType = ((ArrayType) returnType).getComponentType(); 236 if (aType instanceof PrimitiveType == false || ((PrimitiveType) aType).getKind() != PrimitiveType.Kind.INT) { 237 env.getMessager().printError(method.getPosition(), "@SQL annotation on method: " + method.getSimpleName() 238 + " if batchUpdate is set to true, method must return void or an array of integers."); 239 return; 240 } 241 } else if (returnType instanceof VoidType == false) { 242 env.getMessager().printError(method.getPosition(), "@SQL annotation on method: " + method.getSimpleName() 243 + " if batchUpdate is set to true, method must return void or an array of integers."); 244 245 return; 246 } 247 248 } 249 250 if (returnType instanceof InterfaceType) { 254 String iName = ((InterfaceType) returnType).getDeclaration().getQualifiedName(); 255 if ("java.util.Iterator".equals(iName)) { 256 String iteratorClassName = null; 257 try { 258 methodSQL.iteratorElementType(); 260 } catch (MirroredTypeException mte) { 261 iteratorClassName = mte.getQualifiedName(); 262 } 263 264 if ("org.apache.beehive.controls.system.jdbc.JdbcControl.UndefinedIteratorType".equals(iteratorClassName)) { 265 env.getMessager().printError(method.getPosition(), "@SQL annotation on method: " + method.getSimpleName() 266 + " iteratorElementType must be specified if method returns an Iterator."); 267 return; 268 269 } 270 } 271 } 272 273 final JdbcControl.ScrollType scrollable = methodSQL.scrollableResultSet(); 277 switch (scrollable) { 278 case SCROLL_INSENSITIVE: 279 case SCROLL_SENSITIVE: 280 case SCROLL_INSENSITIVE_UPDATABLE: 281 case SCROLL_SENSITIVE_UPDATABLE: 282 case FORWARD_ONLY_UPDATABLE: 283 String typeName = null; 284 if (returnType instanceof DeclaredType) { 285 typeName = ((DeclaredType) returnType).getDeclaration().getQualifiedName(); 286 } 287 288 if (typeName == null || "java.sql.ResultSet".equals(typeName) == false) { 289 env.getMessager().printError(method.getPosition(), "@SQL annotation on method: " + method.getSimpleName() 290 + " element scrollableResultSet specified but method does not return a ResultSet."); 291 break; 292 } 293 case FORWARD_ONLY: 294 default: 295 break; 296 } 297 } } 299 | Popular Tags |