1 22 package org.jboss.ejb.plugins.cmp.jdbc; 23 24 import java.lang.reflect.Method ; 25 import java.sql.PreparedStatement ; 26 import java.util.ArrayList ; 27 import java.util.List ; 28 import java.util.StringTokenizer ; 29 import java.util.Collections ; 30 import javax.ejb.EJBLocalObject ; 31 import javax.ejb.EJBObject ; 32 33 import org.jboss.ejb.plugins.cmp.ejbql.Catalog; 34 import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCFieldBridge; 35 import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCAbstractEntityBridge; 36 37 40 import org.jboss.logging.Logger; 41 42 public final class QueryParameter 43 { 44 public static List createParameters(int argNum, JDBCFieldBridge field) 45 { 46 List parameters; 47 JDBCType type = field.getJDBCType(); 48 if(type instanceof JDBCTypeComplex) 49 { 50 JDBCTypeComplexProperty[] props = ((JDBCTypeComplex)type).getProperties(); 51 parameters = new ArrayList (props.length); 52 for(int i = 0; i < props.length; i++) 53 { 54 QueryParameter param = new QueryParameter( 55 argNum, 56 false, 57 null, 58 props[i], 59 props[i].getJDBCType()); 60 parameters.add(param); 61 } 62 } 63 else 64 { 65 QueryParameter param = new QueryParameter(argNum, type); 66 parameters = Collections.singletonList(param); 67 } 68 return parameters; 69 } 70 71 public static List createParameters(int argNum, JDBCAbstractEntityBridge entity) 72 { 73 List parameters = new ArrayList (); 74 JDBCFieldBridge[] pkFields = entity.getPrimaryKeyFields(); 75 for(int i = 0; i < pkFields.length; ++i) 76 { 77 JDBCFieldBridge pkField = pkFields[i]; 78 79 JDBCType type = pkField.getJDBCType(); 80 if(type instanceof JDBCTypeComplex) 81 { 82 JDBCTypeComplexProperty[] props = 83 ((JDBCTypeComplex)type).getProperties(); 84 for(int j = 0; j < props.length; j++) 85 { 86 QueryParameter param = new QueryParameter( 87 argNum, 88 false, 89 pkField, 90 props[j], 91 props[j].getJDBCType()); 92 parameters.add(param); 93 } 94 } 95 else 96 { 97 QueryParameter param = new QueryParameter( 98 argNum, 99 false, 100 pkField, 101 null, 102 type.getJDBCTypes()[0]); 103 param.type = type; 104 parameters.add(param); 105 } 106 } 107 return parameters; 108 } 109 110 public static List createPrimaryKeyParameters(int argNum, JDBCAbstractEntityBridge entity) 111 { 112 List parameters = new ArrayList (); 113 JDBCFieldBridge[] pkFields = entity.getPrimaryKeyFields(); 114 for(int i = 0; i < pkFields.length; ++i) 115 { 116 JDBCFieldBridge pkField = pkFields[i]; 117 118 JDBCType type = pkField.getJDBCType(); 119 if(type instanceof JDBCTypeComplex) 120 { 121 JDBCTypeComplexProperty[] props = ((JDBCTypeComplex)type).getProperties(); 122 for(int j = 0; j < props.length; j++) 123 { 124 QueryParameter param = new QueryParameter( 125 argNum, 126 true, 127 pkField, 128 props[j], 129 props[j].getJDBCType()); 130 parameters.add(param); 131 } 132 } 133 else 134 { 135 QueryParameter param = new QueryParameter( 136 argNum, 137 true, 138 pkField, 139 null, 140 type.getJDBCTypes()[0]); 141 param.type = type; 142 parameters.add(param); 143 } 144 } 145 return parameters; 146 } 147 148 private int argNum; 149 private final boolean isPrimaryKeyParameter; 150 private JDBCFieldBridge field; 151 private JDBCTypeComplexProperty property; 152 private String parameterString; 153 154 private int jdbcType; 155 private JDBCType type; 156 157 public QueryParameter( 158 JDBCEntityPersistenceStore manager, 159 Method method, 160 String parameterString) 161 { 162 163 this.isPrimaryKeyParameter = false; 166 167 this.parameterString = parameterString; 168 169 if(parameterString == null || parameterString.length() == 0) 170 { 171 throw new IllegalArgumentException ("Parameter string is empty"); 172 } 173 174 StringTokenizer tok = new StringTokenizer (parameterString, "."); 175 176 try 178 { 179 argNum = Integer.parseInt(tok.nextToken()); 180 } 181 catch(NumberFormatException e) 182 { 183 throw new IllegalArgumentException ("The parameter must begin with a number"); 184 } 185 186 if(argNum > method.getParameterTypes().length) 188 { 189 throw new IllegalArgumentException ("The parameter index is " + argNum + 190 " but the query method only has " + 191 method.getParameterTypes().length + "parameter(s)"); 192 } 193 Class argType = method.getParameterTypes()[argNum]; 194 195 JDBCType type; 197 198 if(EJBObject .class.isAssignableFrom(argType) || 200 EJBLocalObject .class.isAssignableFrom(argType)) 201 { 202 if(!tok.hasMoreTokens()) 205 { 206 throw new IllegalArgumentException ("When the parameter is an ejb a field name must be supplied."); 207 } 208 String fieldName = tok.nextToken(); 209 210 field = getCMPField(manager, argType, fieldName); 212 if(!field.isPrimaryKeyMember()) 213 { 214 throw new IllegalArgumentException ("The specified field must be a primay key field"); 215 } 216 217 type = field.getJDBCType(); 219 } 220 else 221 { 222 type = manager.getJDBCTypeFactory().getJDBCType(argType); 224 } 225 226 if(type instanceof JDBCTypeSimple) 227 { 228 if(tok.hasMoreTokens()) 229 { 230 throw new IllegalArgumentException ("Parameter is NOT a known " + 231 "dependent value class, so a properties cannot supplied."); 232 } 233 jdbcType = type.getJDBCTypes()[0]; 234 this.type = type; 235 } 236 else 237 { 238 if(!tok.hasMoreTokens()) 239 { 240 throw new IllegalArgumentException ("Parmeter is a known " + 241 "dependent value class, so a property must be supplied"); 242 } 243 244 StringBuffer propertyName = new StringBuffer (parameterString.length()); 246 propertyName.append(tok.nextToken()); 247 while(tok.hasMoreTokens()) 248 { 249 propertyName.append('.').append(tok.nextToken()); 250 } 251 property = ((JDBCTypeComplex)type).getProperty(propertyName.toString()); 252 jdbcType = property.getJDBCType(); 253 } 254 } 255 256 public QueryParameter(int argNum, JDBCType type) 257 { 258 this.argNum = argNum; 259 this.type = type; 260 this.jdbcType = type.getJDBCTypes()[0]; 261 this.isPrimaryKeyParameter = false; 262 initToString(); 263 } 264 265 public QueryParameter( 266 int argNum, 267 boolean isPrimaryKeyParameter, 268 JDBCFieldBridge field, 269 JDBCTypeComplexProperty property, 270 int jdbcType) 271 { 272 273 this.argNum = argNum; 274 this.isPrimaryKeyParameter = isPrimaryKeyParameter; 275 this.field = field; 276 this.property = property; 277 this.jdbcType = jdbcType; 278 279 initToString(); 280 } 281 282 private void initToString() 283 { 284 StringBuffer parameterBuf = new StringBuffer (); 285 parameterBuf.append(argNum); 286 if(field != null) 287 { 288 parameterBuf.append('.').append(field.getFieldName()); 289 } 290 if(property != null) 291 { 292 parameterBuf.append('.').append(property.getPropertyName()); 293 } 294 parameterString = parameterBuf.toString(); 295 } 296 297 public void set(Logger log, PreparedStatement ps, int index, Object [] args) 298 throws Exception 299 { 300 Object arg = args[argNum]; 301 JDBCParameterSetter param; 302 if(field != null) 303 { 304 if(!isPrimaryKeyParameter) 305 { 306 if(arg instanceof EJBObject ) 307 { 308 arg = ((EJBObject )arg).getPrimaryKey(); 309 } 310 else if(arg instanceof EJBLocalObject ) 311 { 312 arg = ((EJBLocalObject )arg).getPrimaryKey(); 313 } 314 else 315 { 316 throw new IllegalArgumentException ("Expected an instanc of " + 317 "EJBObject or EJBLocalObject, but got an instance of " + 318 arg.getClass().getName()); 319 } 320 } 321 arg = field.getPrimaryKeyValue(arg); 322 323 final JDBCType jdbcType = field.getJDBCType(); 325 arg = jdbcType.getColumnValue(0, arg); 326 param = jdbcType.getParameterSetter()[0]; 327 } 328 else if(property != null) 329 { 330 arg = property.getColumnValue(arg); 331 param = property.getParameterSetter(); 332 } 333 else 334 { 335 if(type != null) 336 { 337 arg = type.getColumnValue(0, arg); 338 param = type.getParameterSetter()[0]; 339 } 340 else 341 { 342 param = JDBCUtil.getParameterSetter(jdbcType, arg == null ? null : arg.getClass()); 343 } 344 } 345 346 param.set(ps, index, jdbcType, arg, log); 347 } 349 350 private static JDBCFieldBridge getCMPField( 351 JDBCEntityPersistenceStore manager, 352 Class intf, 353 String fieldName) 354 { 355 Catalog catalog = manager.getCatalog(); 356 JDBCAbstractEntityBridge entityBridge = (JDBCAbstractEntityBridge)catalog.getEntityByInterface(intf); 357 if(entityBridge == null) 358 { 359 throw new IllegalArgumentException ("Entity not found in application " + 360 "catalog with interface=" + intf.getName()); 361 } 362 363 JDBCFieldBridge cmpField = (JDBCFieldBridge)entityBridge.getFieldByName(fieldName); 364 if(cmpField == null) 365 { 366 throw new IllegalArgumentException ("cmpField not found:" + 367 " cmpFieldName=" + fieldName + 368 " entityName=" + entityBridge.getEntityName()); 369 } 370 return cmpField; 371 } 372 373 public String toString() 374 { 375 return parameterString; 376 } 377 } 378 | Popular Tags |