1 package org.apache.ojb.broker.util.sequence; 2 3 17 18 import java.sql.ResultSet ; 19 import java.sql.Statement ; 20 import java.util.Collection ; 21 import java.util.Iterator ; 22 import java.util.Properties ; 23 import java.util.Vector ; 24 25 import org.apache.ojb.broker.PersistenceBroker; 26 import org.apache.ojb.broker.PersistenceBrokerException; 27 import org.apache.ojb.broker.accesslayer.StatementManagerIF; 28 import org.apache.ojb.broker.metadata.ClassDescriptor; 29 import org.apache.ojb.broker.metadata.FieldDescriptor; 30 import org.apache.ojb.broker.query.Query; 31 import org.apache.ojb.broker.util.logging.Logger; 32 import org.apache.ojb.broker.util.logging.LoggerFactory; 33 34 40 public class SequenceManagerHelper 41 { 42 private static Logger log = LoggerFactory.getLogger(SequenceManagerHelper.class); 43 44 47 public static final String PROP_SEQ_AS = "seq.as"; 48 52 public static final String PROP_SEQ_START_OLD = "sequenceStart"; 53 56 public static final String PROP_SEQ_START = "seq.start"; 57 60 public static final String PROP_SEQ_INCREMENT_BY = "seq.incrementBy"; 61 64 public static final String PROP_SEQ_MAX_VALUE = "seq.maxValue"; 65 68 public static final String PROP_SEQ_MIN_VALUE = "seq.minValue"; 69 72 public static final String PROP_SEQ_CYCLE = "seq.cycle"; 73 76 public static final String PROP_SEQ_CACHE = "seq.cache"; 77 80 public static final String PROP_SEQ_ORDER = "seq.order"; 81 82 private static final String SEQ_PREFIX = "SEQ_"; 83 private static final String SEQ_UNASSIGNED = "UNASSIGNED"; 84 private static final String SM_SELECT_MAX = "SELECT MAX("; 85 private static final String SM_FROM = ") FROM "; 86 87 90 91 113 public static String buildSequenceName(PersistenceBroker brokerForClass, 114 FieldDescriptor field, boolean autoNaming) 115 throws SequenceManagerException 116 { 117 String seqName = field.getSequenceName(); 118 122 if (seqName != null && seqName.trim().length() != 0) 123 { 124 return seqName; 125 } 126 else if (!autoNaming) 127 { 128 133 throw new SequenceManagerException("Could not find sequence-name for field '" + 134 field + "' of class '" + field.getClassDescriptor().getClassNameOfObject() + 135 "', property 'autoNaming' in sequence-manager element in repository was '" + 136 autoNaming + "'. Set autoNaming true in sequence-descriptor or define a " + 137 " sequence-name in field-descriptor."); 138 } 139 140 ClassDescriptor cldTargetClass = field.getClassDescriptor(); 141 144 cldTargetClass = findInheritanceRoot(cldTargetClass); 145 Class topLevel = brokerForClass.getTopLevelClass(cldTargetClass.getClassOfObject()); 146 ClassDescriptor cldTopLevel = brokerForClass.getClassDescriptor(topLevel); 147 161 if (cldTopLevel.isExtent()) 162 { 163 172 seqName = firstFoundTableName(brokerForClass, cldTopLevel); 175 } 176 else 177 { 178 seqName = cldTargetClass.getFullTableName(); 179 } 180 if (seqName == null) 182 { 183 seqName = SEQ_UNASSIGNED; 184 log.warn("Too complex structure, can not assign automatic sequence name for field '" + 185 field.getAttributeName() + "' in class '" + 186 field.getClassDescriptor().getClassNameOfObject() + 187 "'. Use a default sequence name instead: " + (SEQ_PREFIX + seqName)); 188 } 189 seqName = SEQ_PREFIX + seqName; 191 if (log.isDebugEnabled()) 192 log.debug("Set automatic generated sequence-name for field '" + 193 field.getAttributeName() + "' in class '" + 194 field.getClassDescriptor().getClassNameOfObject() + 195 "'."); 196 field.setSequenceName(seqName); 197 return seqName; 198 } 199 200 205 private static ClassDescriptor findInheritanceRoot(ClassDescriptor cld) 206 { 207 ClassDescriptor result = cld; 208 if(cld.getSuperClassDescriptor() != null) 209 { 210 result = findInheritanceRoot(cld.getSuperClassDescriptor()); 211 } 212 return result; 213 } 214 215 220 private static String firstFoundTableName(PersistenceBroker brokerForClass, ClassDescriptor cld) 221 { 222 String name = null; 223 if (!cld.isInterface() && cld.getFullTableName() != null) 224 { 225 return cld.getFullTableName(); 226 } 227 if (cld.isExtent()) 228 { 229 Collection extentClasses = cld.getExtentClasses(); 230 for (Iterator iterator = extentClasses.iterator(); iterator.hasNext();) 231 { 232 name = firstFoundTableName(brokerForClass, brokerForClass.getClassDescriptor((Class ) iterator.next())); 233 if (name != null) break; 235 } 236 } 237 return name; 238 } 239 240 248 public static long getMaxForExtent(PersistenceBroker brokerForClass, FieldDescriptor field) throws PersistenceBrokerException 249 { 250 if (field == null) 251 { 252 log.error("Given FieldDescriptor was null, could not detect max value across all extents"); 253 return 0; 254 } 256 Class topLevel = brokerForClass.getTopLevelClass(field.getClassDescriptor().getClassOfObject()); 258 return getMaxId(brokerForClass, topLevel, field); 259 } 260 261 265 public static long getMaxId(PersistenceBroker brokerForClass, Class topLevel, FieldDescriptor original) throws PersistenceBrokerException 266 { 267 long max = 0; 268 long tmp; 269 ClassDescriptor cld = brokerForClass.getClassDescriptor(topLevel); 270 271 if (!cld.isInterface() && !cld.isAbstract()) 273 { 274 tmp = getMaxIdForClass(brokerForClass, cld, original); 275 if (tmp > max) 276 { 277 max = tmp; 278 } 279 } 280 if (cld.isExtent()) 282 { 283 Vector extentClasses = cld.getExtentClasses(); 284 for (int i = 0; i < extentClasses.size(); i++) 285 { 286 Class extentClass = (Class ) extentClasses.get(i); 287 if (cld.getClassOfObject().equals(extentClass)) 288 { 289 throw new PersistenceBrokerException("Circular extent in " + extentClass + 290 ", please check the repository"); 291 } 292 else 293 { 294 tmp = getMaxId(brokerForClass, extentClass, original); 297 } 298 if (tmp > max) 299 { 300 max = tmp; 301 } 302 } 303 } 304 return max; 305 } 306 307 311 public static long getMaxIdForClass( 312 PersistenceBroker brokerForClass, ClassDescriptor cldForOriginalOrExtent, FieldDescriptor original) 313 throws PersistenceBrokerException 314 { 315 FieldDescriptor field = null; 316 if (!original.getClassDescriptor().equals(cldForOriginalOrExtent)) 317 { 318 if (!original.getClassDescriptor().getFullTableName().equals( 320 cldForOriginalOrExtent.getFullTableName())) 321 { 322 field = cldForOriginalOrExtent.getFieldDescriptorByName(original.getAttributeName()); 324 } 325 } 326 else 327 { 328 field = original; 329 } 330 if (field == null) 331 { 332 return 0; 334 } 335 336 String column = field.getColumnName(); 337 long result = 0; 338 ResultSet rs = null; 339 Statement stmt = null; 340 StatementManagerIF sm = brokerForClass.serviceStatementManager(); 341 String table = cldForOriginalOrExtent.getFullTableName(); 342 String sql = SM_SELECT_MAX + column + SM_FROM + table; 344 try 345 { 346 stmt = sm.getGenericStatement(cldForOriginalOrExtent, Query.NOT_SCROLLABLE); 348 rs = stmt.executeQuery(sql); 349 rs.next(); 350 result = rs.getLong(1); 351 } 352 catch (Exception e) 353 { 354 log.warn("Cannot lookup max value from table " + table + " for column " + column + 355 ", PB was " + brokerForClass + ", using jdbc-descriptor " + 356 brokerForClass.serviceConnectionManager().getConnectionDescriptor(), e); 357 } 358 finally 359 { 360 try 361 { 362 sm.closeResources(stmt, rs); 363 } 364 catch (Exception ignore) 365 { 366 } 368 } 369 return result; 370 } 371 372 380 public static Long getSeqStart(Properties prop) 381 { 382 String result = prop.getProperty(PROP_SEQ_START, null); 383 if(result == null) 384 { 385 result = prop.getProperty(PROP_SEQ_START_OLD, null); 386 } 387 if(result != null) 388 { 389 return new Long (Long.parseLong(result)); 390 } 391 else 392 { 393 return null; 394 } 395 } 396 397 405 public static Long getSeqIncrementBy(Properties prop) 406 { 407 String result = prop.getProperty(PROP_SEQ_INCREMENT_BY, null); 408 if(result != null) 409 { 410 return new Long (Long.parseLong(result)); 411 } 412 else 413 { 414 return null; 415 } 416 } 417 418 426 public static Long getSeqMaxValue(Properties prop) 427 { 428 String result = prop.getProperty(PROP_SEQ_MAX_VALUE, null); 429 if(result != null) 430 { 431 return new Long (Long.parseLong(result)); 432 } 433 else 434 { 435 return null; 436 } 437 } 438 439 447 public static Long getSeqMinValue(Properties prop) 448 { 449 String result = prop.getProperty(PROP_SEQ_MIN_VALUE, null); 450 if(result != null) 451 { 452 return new Long (Long.parseLong(result)); 453 } 454 else 455 { 456 return null; 457 } 458 } 459 460 468 public static Long getSeqCacheValue(Properties prop) 469 { 470 String result = prop.getProperty(PROP_SEQ_CACHE, null); 471 if(result != null) 472 { 473 return new Long (Long.parseLong(result)); 474 } 475 else 476 { 477 return null; 478 } 479 } 480 481 489 public static Boolean getSeqCycleValue(Properties prop) 490 { 491 String result = prop.getProperty(PROP_SEQ_CYCLE, null); 492 if(result != null) 493 { 494 return Boolean.valueOf(result); 495 } 496 else 497 { 498 return null; 499 } 500 } 501 502 510 public static Boolean getSeqOrderValue(Properties prop) 511 { 512 String result = prop.getProperty(PROP_SEQ_ORDER, null); 513 if(result != null) 514 { 515 return Boolean.valueOf(result); 516 } 517 else 518 { 519 return null; 520 } 521 } 522 523 531 public static String getSeqAsValue(Properties prop) 532 { 533 return prop.getProperty(PROP_SEQ_AS, null); 534 } 535 } 536 | Popular Tags |