1 10 11 package com.triactive.jdo.store; 12 13 import com.triactive.jdo.PersistenceManager; 14 import com.triactive.jdo.util.Imports; 15 import java.sql.ResultSet ; 16 import java.util.ArrayList ; 17 import java.util.Collection ; 18 import java.util.HashSet ; 19 import java.util.HashMap ; 20 import java.util.List ; 21 import java.util.Map ; 22 import java.util.StringTokenizer ; 23 import javax.jdo.Extent; 24 import javax.jdo.JDOUserException; 25 26 27 36 37 public abstract class Query implements javax.jdo.Query 38 { 39 protected final transient PersistenceManager pm; 40 protected final transient StoreManager storeMgr; 41 protected final transient DatabaseAdapter dba; 42 43 protected Class candidateClass; 44 protected String filter; 45 protected String imports; 46 protected String variables; 47 protected String parameters; 48 protected String ordering; 49 50 protected transient boolean isCompiled = false; 51 protected transient Imports parsedImports = null; 52 protected transient List parameterNames = null; 53 protected transient Map parameterTypesByName = null; 54 protected transient List variableNames = null; 55 protected transient Map variableTypesByName = null; 56 57 protected transient HashSet queryResults = new HashSet (); 58 59 60 65 66 public Query(PersistenceManager pm, StoreManager storeMgr) 67 { 68 this.pm = pm; 69 this.storeMgr = storeMgr; 70 71 dba = storeMgr == null ? null : storeMgr.getDatabaseAdapter(); 72 } 73 74 75 protected void discardCompiled() 76 { 77 isCompiled = false; 78 parsedImports = null; 79 parameterNames = null; 80 parameterTypesByName = null; 81 variableNames = null; 82 variableTypesByName = null; 83 } 84 85 86 public boolean equals(Object obj) 87 { 88 if (obj == this) 89 return true; 90 91 if (!(obj instanceof Query)) 92 return false; 93 94 Query q = (Query)obj; 95 96 if (candidateClass == null) { if (q.candidateClass != null) return false; } 97 else if (!candidateClass.equals(q.candidateClass)) return false; 98 99 if (filter == null) { if (q.filter != null) return false; } 100 else if (!filter.equals(q.filter)) return false; 101 102 if (imports == null) { if (q.imports != null) return false; } 103 else if (!imports.equals(q.imports)) return false; 104 105 if (parameters == null) { if (q.parameters != null) return false; } 106 else if (!parameters.equals(q.parameters)) return false; 107 108 if (variables == null) { if (q.variables != null) return false; } 109 else if (!variables.equals(q.variables)) return false; 110 111 if (ordering == null) { if (q.ordering != null) return false; } 112 else if (!ordering.equals(q.ordering)) return false; 113 114 return true; 115 } 116 117 118 public int hashCode() 119 { 120 return (candidateClass == null ? 0 : candidateClass.hashCode()) 121 ^ (filter == null ? 0 : filter.hashCode()) 122 ^ (imports == null ? 0 : imports.hashCode()) 123 ^ (parameters == null ? 0 : parameters.hashCode()) 124 ^ (variables == null ? 0 : variables.hashCode()) 125 ^ (ordering == null ? 0 : ordering.hashCode()); 126 } 127 128 129 134 135 public StoreManager getStoreManager() 136 { 137 return storeMgr; 138 } 139 140 141 148 149 public javax.jdo.PersistenceManager getPersistenceManager() 150 { 151 return pm; 152 } 153 154 155 162 163 public Class getCandidateClass() 164 { 165 return candidateClass; 166 } 167 168 169 176 177 public void setClass(Class candidateClass) 178 { 179 discardCompiled(); 180 181 this.candidateClass = candidateClass; 182 } 183 184 185 192 193 public abstract void setCandidates(Extent pcs); 194 195 196 203 204 public abstract void setCandidates(Collection pcs); 205 206 207 214 215 public void setFilter(String filter) 216 { 217 discardCompiled(); 218 219 this.filter = filter; 220 } 221 222 223 231 232 public void declareImports(String imports) 233 { 234 discardCompiled(); 235 236 this.imports = imports; 237 } 238 239 246 247 public void declareParameters(String parameters) 248 { 249 discardCompiled(); 250 251 this.parameters = parameters; 252 } 253 254 255 262 263 public void declareVariables(String variables) 264 { 265 discardCompiled(); 266 267 this.variables = variables; 268 } 269 270 271 278 279 public void setOrdering(String ordering) 280 { 281 discardCompiled(); 282 283 this.ordering = ordering; 284 } 285 286 287 297 298 public void setIgnoreCache(boolean ignoreCache) 299 { 300 discardCompiled(); 301 302 return; 303 } 304 305 306 317 318 public boolean getIgnoreCache() 319 { 320 return false; 321 } 322 323 324 330 331 public void compile() 332 { 333 if (isCompiled) 334 return; 335 336 if (pm == null) 337 throw new JDOUserException("Query has no associated PersistenceManager"); 338 339 boolean done = false; 340 341 try 342 { 343 346 347 parsedImports = new Imports(); 348 parsedImports.importPackage(candidateClass); 349 350 if (imports != null) 351 parsedImports.parseImports(imports); 352 353 356 357 parameterNames = new ArrayList (); 358 parameterTypesByName = new HashMap (); 359 360 if (parameters != null && parameters.length() > 0) 361 { 362 StringTokenizer t1 = new StringTokenizer (parameters, ","); 363 364 while (t1.hasMoreTokens()) 365 { 366 StringTokenizer t2 = new StringTokenizer (t1.nextToken(), " "); 367 368 if (t2.countTokens() != 2) 369 throw new JDOUserException("Invalid parameter list: \"" + parameters + '"'); 370 371 String classDecl = t2.nextToken(); 372 String parameterName = t2.nextToken(); 373 374 if (!isValidJavaIdentifier(parameterName)) 375 throw new JDOUserException("Illegal parameter name \"" + parameterName + '"'); 376 377 if (parameterNames.contains(parameterName)) 378 throw new JDOUserException("Duplicate parameter name \"" + parameterName + '"'); 379 380 parameterNames.add(parameterName); 381 parameterTypesByName.put(parameterName, resolveClassDeclaration(classDecl)); 382 } 383 } 384 385 388 389 variableNames = new ArrayList (); 390 variableTypesByName = new HashMap (); 391 392 if (variables != null && variables.length() > 0) 393 { 394 StringTokenizer t1 = new StringTokenizer (variables, ";"); 395 396 while (t1.hasMoreTokens()) 397 { 398 StringTokenizer t2 = new StringTokenizer (t1.nextToken(), " "); 399 400 if (t2.countTokens() != 2) 401 throw new JDOUserException("Invalid variable list: \"" + variables + '"'); 402 403 String classDecl = t2.nextToken(); 404 String variableName = t2.nextToken(); 405 406 if (!isValidJavaIdentifier(variableName)) 407 throw new JDOUserException("Illegal variable name \"" + variableName + '"'); 408 409 if (parameterNames.contains(variableName)) 410 throw new JDOUserException("Variable name conflicts with parameter name \"" + variableName + '"'); 411 412 if (variableNames.contains(variableName)) 413 throw new JDOUserException("Duplicate variable name \"" + variableName + '"'); 414 415 variableNames.add(variableName); 416 variableTypesByName.put(variableName, resolveClassDeclaration(classDecl)); 417 } 418 } 419 420 done = true; 421 } 422 finally 423 { 424 if (!done) 425 discardCompiled(); 426 } 427 } 428 429 430 protected static boolean isValidJavaIdentifier(String s) 431 { 432 int len = s.length(); 433 434 if (len < 1) 435 return false; 436 437 char[] c = new char[len]; 438 s.getChars(0, len, c, 0); 439 440 if (!Character.isJavaIdentifierStart(c[0])) 441 return false; 442 443 for (int i = 1; i < len; ++i) 444 { 445 if (!Character.isJavaIdentifierPart(c[i])) 446 return false; 447 } 448 449 return true; 450 } 451 452 453 public Class resolveClassDeclaration(String classDecl) 454 { 455 try 456 { 457 return parsedImports.resolveClassDeclaration(classDecl); 458 } 459 catch (ClassNotFoundException e) 460 { 461 throw new JDOUserException("Declared parameter or variable type not found: " + classDecl); 462 } 463 } 464 465 466 474 475 public Object execute() 476 { 477 return executeWithArray(new Object [0]); 478 } 479 480 481 491 492 public Object execute(Object p1) 493 { 494 return executeWithArray(new Object [] { p1 }); 495 } 496 497 498 509 510 public Object execute(Object p1, Object p2) 511 { 512 return executeWithArray(new Object [] { p1, p2 }); 513 } 514 515 516 528 529 public Object execute(Object p1, Object p2, Object p3) 530 { 531 return executeWithArray(new Object [] { p1, p2, p3 }); 532 } 533 534 535 544 545 public Object executeWithArray(Object [] parameters) 546 { 547 compile(); 548 549 if (parameters.length != parameterNames.size()) 550 throw new JDOUserException("Incorrect number of parameters: " + parameters.length + ", s/b " + parameterNames.size()); 551 552 HashMap parameterMap = new HashMap (); 553 554 for (int i = 0; i < parameters.length; ++i) 555 parameterMap.put(parameterNames.get(i), parameters[i]); 556 557 return executeWithMap(parameterMap); 558 } 559 560 561 571 572 public abstract Object executeWithMap(Map parameters); 573 574 575 582 583 public void close(Object queryResult) 584 { 585 if (queryResult != null) 586 { 587 ((QueryResult)queryResult).close(); 588 queryResults.remove(queryResult); 589 } 590 } 591 592 593 599 600 public void closeAll() 601 { 602 QueryResult[] qrs = (QueryResult[])queryResults.toArray(new QueryResult[queryResults.size()]); 603 604 for (int i = 0; i < qrs.length; ++i) 605 close(qrs[i]); 606 } 607 608 609 618 619 public static interface ResultObjectFactory 620 { 621 631 632 Object getObject(ResultSet rs); 633 } 634 } 635 | Popular Tags |