| 1 |  |  package org.apache.ojb.broker.metadata; | 
  | 2 |  |   | 
  | 3 |  |   | 
  | 4 |  |   | 
  | 5 |  |   | 
  | 6 |  |   | 
  | 7 |  |   | 
  | 8 |  |   | 
  | 9 |  |   | 
  | 10 |  |   | 
  | 11 |  |   | 
  | 12 |  |   | 
  | 13 |  |   | 
  | 14 |  |   | 
  | 15 |  |   | 
  | 16 |  |   | 
  | 17 |  |   | 
  | 18 |  |  import java.io.Serializable; | 
  | 19 |  |  import java.util.*; | 
  | 20 |  |   | 
  | 21 |  |  import org.apache.commons.lang.SystemUtils; | 
  | 22 |  |  import org.apache.commons.lang.builder.ToStringBuilder; | 
  | 23 |  |  import org.apache.commons.lang.builder.ToStringStyle; | 
  | 24 |  |  import org.apache.ojb.broker.OJBRuntimeException; | 
  | 25 |  |  import org.apache.ojb.broker.PersistenceBrokerException; | 
  | 26 |  |  import org.apache.ojb.broker.locking.IsolationLevels; | 
  | 27 |  |  import org.apache.ojb.broker.util.ClassHelper; | 
  | 28 |  |  import org.apache.ojb.broker.util.logging.LoggerFactory; | 
  | 29 |  |  import org.apache.ojb.broker.util.logging.Logger; | 
  | 30 |  |   | 
  | 31 |  |   | 
  | 32 |  |   | 
  | 33 |  |   | 
  | 34 |  |   | 
  | 35 |  |   | 
  | 36 |  |   | 
  | 37 |  |   | 
  | 38 |  |   | 
  | 39 |  |   | 
  | 40 |  |   | 
  | 41 |  |   | 
  | 42 |  |  @SuppressWarnings("unchecked") | 
  | 43 |  |  public final class DescriptorRepository extends DescriptorBase | 
  | 44 |  |          implements Serializable, XmlCapable, IsolationLevels | 
  | 45 |  |  { | 
  | 46 |  |      static final long serialVersionUID = -1556339982311359524L; | 
  | 47 |  |      private Logger log = LoggerFactory.getLogger(DescriptorRepository.class); | 
  | 48 |  |   | 
  | 49 |  |       | 
  | 50 |  |   | 
  | 51 |  |   | 
  | 52 |  |   | 
  | 53 |  |      private static final String VERSION = "1.0"; | 
  | 54 |  |       | 
  | 55 |  |   | 
  | 56 |  |   | 
  | 57 |  |      private int defaultIsolationLevel = IsolationLevels.IL_DEFAULT; | 
  | 58 |  |       | 
  | 59 |  |   | 
  | 60 |  |   | 
  | 61 |  |   | 
  | 62 |  |          private final HashMap descriptorTable; | 
  | 63 |  |       | 
  | 64 |  |   | 
  | 65 |  |   | 
  | 66 |  |   | 
  | 67 |  |   | 
  | 68 |  |      private Map extentTable; | 
  | 69 |  |   | 
  | 70 |  |      private Map superClassMultipleJoinedTablesMap; | 
  | 71 |  |   | 
  | 72 |  |      private transient Map m_multiMappedTableMap; | 
  | 73 |  |      private transient Map m_topLevelClassTable; | 
  | 74 |  |      private transient Map m_firstConcreteClassMap; | 
  | 75 |  |      private transient Map m_allConcreteSubClass; | 
  | 76 |  |   | 
  | 77 |  |       | 
  | 78 |  |   | 
  | 79 |  |   | 
  | 80 |  |      public DescriptorRepository() throws PersistenceBrokerException | 
  | 81 |  |      { | 
  | 82 |  |          descriptorTable = new HashMap(); | 
  | 83 |  |          extentTable = new HashMap(); | 
  | 84 |  |          superClassMultipleJoinedTablesMap = new HashMap(); | 
  | 85 |  |      } | 
  | 86 |  |   | 
  | 87 |  |      public static String getVersion() | 
  | 88 |  |      { | 
  | 89 |  |          return VERSION; | 
  | 90 |  |      } | 
  | 91 |  |   | 
  | 92 |  |       | 
  | 93 |  |   | 
  | 94 |  |   | 
  | 95 |  |   | 
  | 96 |  |   | 
  | 97 |  |   | 
  | 98 |  |      void addExtent(String classname, ClassDescriptor cld) | 
  | 99 |  |      { | 
  | 100 |  |          synchronized (extentTable) | 
  | 101 |  |          { | 
  | 102 |  |              extentTable.put(classname, cld); | 
  | 103 |  |          } | 
  | 104 |  |      } | 
  | 105 |  |   | 
  | 106 |  |       | 
  | 107 |  |   | 
  | 108 |  |   | 
  | 109 |  |   | 
  | 110 |  |      void removeExtent(String classname) | 
  | 111 |  |      { | 
  | 112 |  |          synchronized (extentTable) | 
  | 113 |  |          { | 
  | 114 |  |               | 
  | 115 |  |              ClassDescriptor cld = (ClassDescriptor) extentTable.remove(classname); | 
  | 116 |  |              if(cld != null && m_topLevelClassTable != null) | 
  | 117 |  |              { | 
  | 118 |  |                  Class extClass = null; | 
  | 119 |  |                  try | 
  | 120 |  |                  { | 
  | 121 |  |                      extClass = ClassHelper.getClass(classname); | 
  | 122 |  |                  } | 
  | 123 |  |                  catch (ClassNotFoundException e) | 
  | 124 |  |                  { | 
  | 125 |  |                       | 
  | 126 |  |                      throw new MetadataException("Can't instantiate class object for needed extent remove", e); | 
  | 127 |  |                  } | 
  | 128 |  |                   | 
  | 129 |  |                  cld.removeExtentClass(classname); | 
  | 130 |  |                  m_topLevelClassTable.remove(extClass); | 
  | 131 |  |                   | 
  | 132 |  |                   | 
  | 133 |  |                  m_firstConcreteClassMap = null; | 
  | 134 |  |              } | 
  | 135 |  |          } | 
  | 136 |  |      } | 
  | 137 |  |   | 
  | 138 |  |       | 
  | 139 |  |   | 
  | 140 |  |   | 
  | 141 |  |   | 
  | 142 |  |   | 
  | 143 |  |   | 
  | 144 |  |   | 
  | 145 |  |   | 
  | 146 |  |   | 
  | 147 |  |      public Class getTopLevelClass(Class clazz) throws ClassNotPersistenceCapableException | 
  | 148 |  |      { | 
  | 149 |  |          if(m_topLevelClassTable == null) | 
  | 150 |  |          { | 
  | 151 |  |              m_topLevelClassTable = new HashMap(); | 
  | 152 |  |          } | 
  | 153 |  |           | 
  | 154 |  |          Class retval = (Class) m_topLevelClassTable.get(clazz); | 
  | 155 |  |          if (retval == null) | 
  | 156 |  |          { | 
  | 157 |  |              synchronized (extentTable) | 
  | 158 |  |              { | 
  | 159 |  |                  ClassDescriptor cld = (ClassDescriptor) extentTable.get(clazz.getName()); | 
  | 160 |  |                  if (cld == null) | 
  | 161 |  |                  { | 
  | 162 |  |                       | 
  | 163 |  |                      cld = getDescriptorFor(clazz).getSuperClassDescriptor(); | 
  | 164 |  |                  } | 
  | 165 |  |                   | 
  | 166 |  |                  if (cld != null) | 
  | 167 |  |                  { | 
  | 168 |  |                       | 
  | 169 |  |                       | 
  | 170 |  |                      retval = getTopLevelClass(cld.getClassOfObject()); | 
  | 171 |  |                       | 
  | 172 |  |                      if (retval == null) | 
  | 173 |  |                      { | 
  | 174 |  |                          retval = clazz; | 
  | 175 |  |                      } | 
  | 176 |  |                  } | 
  | 177 |  |                  else | 
  | 178 |  |                  { | 
  | 179 |  |                       | 
  | 180 |  |                       | 
  | 181 |  |                       | 
  | 182 |  |                       | 
  | 183 |  |                      ClassDescriptor temp = getDescriptorFor(clazz); | 
  | 184 |  |                      retval = temp.getClassOfObject(); | 
  | 185 |  |                  } | 
  | 186 |  |                  m_topLevelClassTable.put(clazz, retval); | 
  | 187 |  |              } | 
  | 188 |  |          } | 
  | 189 |  |          return retval; | 
  | 190 |  |      } | 
  | 191 |  |   | 
  | 192 |  |       | 
  | 193 |  |   | 
  | 194 |  |   | 
  | 195 |  |   | 
  | 196 |  |   | 
  | 197 |  |      public synchronized FieldDescriptor[] getFieldDescriptorsForMultiMappedTable(ClassDescriptor targetCld) | 
  | 198 |  |      { | 
  | 199 |  |          if (m_multiMappedTableMap == null) | 
  | 200 |  |          { | 
  | 201 |  |              m_multiMappedTableMap = new HashMap(); | 
  | 202 |  |          } | 
  | 203 |  |   | 
  | 204 |  |          FieldDescriptor[] retval = (FieldDescriptor[]) m_multiMappedTableMap.get(targetCld.getClassNameOfObject()); | 
  | 205 |  |          if (retval == null) | 
  | 206 |  |          { | 
  | 207 |  |              retval = getAllMappedColumns(getClassesMappedToSameTable(targetCld)); | 
  | 208 |  |              m_multiMappedTableMap.put(targetCld.getClassNameOfObject(), retval); | 
  | 209 |  |          } | 
  | 210 |  |          return retval; | 
  | 211 |  |      } | 
  | 212 |  |   | 
  | 213 |  |      private FieldDescriptor[] getAllMappedColumns(List classDescriptors) | 
  | 214 |  |      { | 
  | 215 |  |           | 
  | 216 |  |   | 
  | 217 |  |   | 
  | 218 |  |   | 
  | 219 |  |   | 
  | 220 |  |   | 
  | 221 |  |          List allFieldDescriptors = new Vector(); | 
  | 222 |  |   | 
  | 223 |  |          Set visitedColumns = new HashSet(); | 
  | 224 |  |          Iterator it = classDescriptors.iterator(); | 
  | 225 |  |          ClassDescriptor temp = null; | 
  | 226 |  |          FieldDescriptor[] fields; | 
  | 227 |  |          while (it.hasNext()) | 
  | 228 |  |          { | 
  | 229 |  |              temp = (ClassDescriptor) it.next(); | 
  | 230 |  |              fields = temp.getFieldDescriptions(); | 
  | 231 |  |              if (fields != null) | 
  | 232 |  |              { | 
  | 233 |  |                  for (int i = 0; i < fields.length; i++) | 
  | 234 |  |                  { | 
  | 235 |  |                       | 
  | 236 |  |   | 
  | 237 |  |   | 
  | 238 |  |   | 
  | 239 |  |   | 
  | 240 |  |   | 
  | 241 |  |   | 
  | 242 |  |   | 
  | 243 |  |   | 
  | 244 |  |   | 
  | 245 |  |   | 
  | 246 |  |                      final String columnName = fields[i].getColumnName(); | 
  | 247 |  |                      if (!visitedColumns.contains(columnName)) | 
  | 248 |  |                      { | 
  | 249 |  |                          visitedColumns.add(columnName); | 
  | 250 |  |                          allFieldDescriptors.add(fields[i]); | 
  | 251 |  |                      } | 
  | 252 |  |                  } | 
  | 253 |  |              } | 
  | 254 |  |          } | 
  | 255 |  |          FieldDescriptor[] retval = new FieldDescriptor[allFieldDescriptors.size()]; | 
  | 256 |  |          allFieldDescriptors.toArray(retval); | 
  | 257 |  |          return retval; | 
  | 258 |  |      } | 
  | 259 |  |   | 
  | 260 |  |      private List getClassesMappedToSameTable(ClassDescriptor targetCld) | 
  | 261 |  |      { | 
  | 262 |  |           | 
  | 263 |  |   | 
  | 264 |  |   | 
  | 265 |  |   | 
  | 266 |  |   | 
  | 267 |  |          Iterator iter = ((HashMap)descriptorTable.clone()).values().iterator(); | 
  | 268 |  |          List retval = new ArrayList(); | 
  | 269 |  |           | 
  | 270 |  |          retval.add(targetCld); | 
  | 271 |  |          while (iter.hasNext()) | 
  | 272 |  |          { | 
  | 273 |  |              ClassDescriptor cld = (ClassDescriptor) iter.next(); | 
  | 274 |  |              if (cld.getFullTableName() != null) | 
  | 275 |  |              { | 
  | 276 |  |                  if (cld.getFullTableName().equals(targetCld.getFullTableName()) | 
  | 277 |  |                          && !targetCld.getClassOfObject().equals(cld.getClassOfObject())) | 
  | 278 |  |                  { | 
  | 279 |  |                      retval.add(cld); | 
  | 280 |  |                  } | 
  | 281 |  |              } | 
  | 282 |  |          } | 
  | 283 |  |          return retval; | 
  | 284 |  |      } | 
  | 285 |  |   | 
  | 286 |  |      public Map getDescriptorTable() | 
  | 287 |  |      { | 
  | 288 |  |          return descriptorTable; | 
  | 289 |  |      } | 
  | 290 |  |   | 
  | 291 |  |       | 
  | 292 |  |   | 
  | 293 |  |   | 
  | 294 |  |   | 
  | 295 |  |   | 
  | 296 |  |   | 
  | 297 |  |   | 
  | 298 |  |      public ClassDescriptor findFirstConcreteClass(ClassDescriptor cld) | 
  | 299 |  |      { | 
  | 300 |  |          if(m_firstConcreteClassMap == null) | 
  | 301 |  |          { | 
  | 302 |  |              m_firstConcreteClassMap = new HashMap(); | 
  | 303 |  |          } | 
  | 304 |  |          ClassDescriptor result = (ClassDescriptor) m_firstConcreteClassMap.get(cld.getClassNameOfObject()); | 
  | 305 |  |          if (result == null) | 
  | 306 |  |          { | 
  | 307 |  |              if(cld.isInterface() || cld.isAbstract()) | 
  | 308 |  |              { | 
  | 309 |  |                  if(cld.isExtent()) | 
  | 310 |  |                  { | 
  | 311 |  |                      List extents = cld.getExtentClasses(); | 
  | 312 |  |                      for (int i = 0; i < extents.size(); i++) | 
  | 313 |  |                      { | 
  | 314 |  |                          Class ext = (Class) extents.get(i); | 
  | 315 |  |                          result = findFirstConcreteClass(getDescriptorFor(ext)); | 
  | 316 |  |                          if(result != null) break; | 
  | 317 |  |                      } | 
  | 318 |  |                  } | 
  | 319 |  |                  else | 
  | 320 |  |                  { | 
  | 321 |  |                      LoggerFactory.getDefaultLogger().error("["+this.getClass().getName()+"] Found interface/abstract class" + | 
  | 322 |  |                              " in metadata declarations without concrete class: "+cld.getClassNameOfObject()); | 
  | 323 |  |                  } | 
  | 324 |  |                  m_firstConcreteClassMap.put(cld.getClassNameOfObject(), result); | 
  | 325 |  |              } | 
  | 326 |  |              else | 
  | 327 |  |              { | 
  | 328 |  |                  result = cld; | 
  | 329 |  |              } | 
  | 330 |  |          } | 
  | 331 |  |          return result; | 
  | 332 |  |      } | 
  | 333 |  |   | 
  | 334 |  |       | 
  | 335 |  |   | 
  | 336 |  |   | 
  | 337 |  |   | 
  | 338 |  |   | 
  | 339 |  |   | 
  | 340 |  |   | 
  | 341 |  |      public Collection getAllConcreteSubclassDescriptors(ClassDescriptor aCld) | 
  | 342 |  |      { | 
  | 343 |  |          if(m_allConcreteSubClass == null) | 
  | 344 |  |          { | 
  | 345 |  |              m_allConcreteSubClass = new HashMap(); | 
  | 346 |  |          } | 
  | 347 |  |          Collection concreteSubclassClds = (Collection) m_allConcreteSubClass.get(aCld.getClassOfObject()); | 
  | 348 |  |   | 
  | 349 |  |          if (concreteSubclassClds == null) | 
  | 350 |  |          { | 
  | 351 |  |               | 
  | 352 |  |               | 
  | 353 |  |               | 
  | 354 |  |              concreteSubclassClds = new ArrayList(); | 
  | 355 |  |              Iterator iter = aCld.getExtentClasses().iterator(); | 
  | 356 |  |   | 
  | 357 |  |              while (iter.hasNext()) | 
  | 358 |  |              { | 
  | 359 |  |                  Class extentClass = (Class) iter.next(); | 
  | 360 |  |                  ClassDescriptor extCld = getDescriptorFor(extentClass); | 
  | 361 |  |                  if (aCld.equals(extCld)) | 
  | 362 |  |                  { | 
  | 363 |  |                       | 
  | 364 |  |                      continue; | 
  | 365 |  |                  } | 
  | 366 |  |                  if (!extCld.isInterface() && !extCld.isAbstract()) | 
  | 367 |  |                  { | 
  | 368 |  |                      if (!concreteSubclassClds.contains(extCld)) | 
  | 369 |  |                      { | 
  | 370 |  |                          concreteSubclassClds.add(extCld); | 
  | 371 |  |                      } | 
  | 372 |  |                  } | 
  | 373 |  |   | 
  | 374 |  |                   | 
  | 375 |  |                  Iterator subIter = getAllConcreteSubclassDescriptors(extCld).iterator(); | 
  | 376 |  |                  while (subIter.hasNext()) | 
  | 377 |  |                  { | 
  | 378 |  |                      ClassDescriptor subCld = (ClassDescriptor)subIter.next(); | 
  | 379 |  |                      if (!concreteSubclassClds.contains(subCld)) | 
  | 380 |  |                      { | 
  | 381 |  |                          concreteSubclassClds.add(subCld); | 
  | 382 |  |                      } | 
  | 383 |  |                  } | 
  | 384 |  |              } | 
  | 385 |  |              m_allConcreteSubClass.put(aCld.getClassOfObject(), concreteSubclassClds); | 
  | 386 |  |          } | 
  | 387 |  |   | 
  | 388 |  |          return concreteSubclassClds; | 
  | 389 |  |      } | 
  | 390 |  |   | 
  | 391 |  |   | 
  | 392 |  |       | 
  | 393 |  |   | 
  | 394 |  |   | 
  | 395 |  |      public boolean hasDescriptorFor(Class c) | 
  | 396 |  |      { | 
  | 397 |  |          return descriptorTable.containsKey(c.getName()); | 
  | 398 |  |      } | 
  | 399 |  |   | 
  | 400 |  |       | 
  | 401 |  |   | 
  | 402 |  |   | 
  | 403 |  |   | 
  | 404 |  |      public ClassDescriptor getDescriptorFor(String strClassName) throws ClassNotPersistenceCapableException | 
  | 405 |  |      { | 
  | 406 |  |          ClassDescriptor result = discoverDescriptor(strClassName); | 
  | 407 |  |          if (result == null) | 
  | 408 |  |          { | 
  | 409 |  |              throw new ClassNotPersistenceCapableException(strClassName + " not found in OJB Repository"); | 
  | 410 |  |          } | 
  | 411 |  |          else | 
  | 412 |  |          { | 
  | 413 |  |              return result; | 
  | 414 |  |          } | 
  | 415 |  |      } | 
  | 416 |  |   | 
  | 417 |  |       | 
  | 418 |  |   | 
  | 419 |  |   | 
  | 420 |  |      public ClassDescriptor getDescriptorFor(Class c) throws ClassNotPersistenceCapableException | 
  | 421 |  |      { | 
  | 422 |  |          return this.getDescriptorFor(c.getName()); | 
  | 423 |  |      } | 
  | 424 |  |   | 
  | 425 |  |       | 
  | 426 |  |   | 
  | 427 |  |   | 
  | 428 |  |      public void setClassDescriptor(ClassDescriptor cld) | 
  | 429 |  |      { | 
  | 430 |  |          this.put(cld.getClassNameOfObject(), cld); | 
  | 431 |  |      } | 
  | 432 |  |   | 
  | 433 |  |       | 
  | 434 |  |   | 
  | 435 |  |   | 
  | 436 |  |   | 
  | 437 |  |      public void put(Class c, ClassDescriptor cld) | 
  | 438 |  |      { | 
  | 439 |  |          this.put(c.getName(), cld); | 
  | 440 |  |      } | 
  | 441 |  |   | 
  | 442 |  |       | 
  | 443 |  |   | 
  | 444 |  |   | 
  | 445 |  |   | 
  | 446 |  |      public void put(String classname, ClassDescriptor cld) | 
  | 447 |  |      { | 
  | 448 |  |          cld.setRepository(this);  | 
  | 449 |  |          synchronized (descriptorTable) | 
  | 450 |  |          { | 
  | 451 |  |              descriptorTable.put(classname, cld); | 
  | 452 |  |              List extentClasses = cld.getExtentClasses(); | 
  | 453 |  |              for (int i = 0; i < extentClasses.size(); ++i) | 
  | 454 |  |              { | 
  | 455 |  |                  addExtent(((Class) extentClasses.get(i)).getName(), cld); | 
  | 456 |  |              } | 
  | 457 |  |              changeDescriptorEvent(); | 
  | 458 |  |          } | 
  | 459 |  |      } | 
  | 460 |  |   | 
  | 461 |  |      public void remove(String className) | 
  | 462 |  |      { | 
  | 463 |  |          synchronized (descriptorTable) | 
  | 464 |  |          { | 
  | 465 |  |              ClassDescriptor cld = (ClassDescriptor) descriptorTable.remove(className); | 
  | 466 |  |              if(cld != null) | 
  | 467 |  |              { | 
  | 468 |  |                   | 
  | 469 |  |                  Iterator it = descriptorTable.values().iterator(); | 
  | 470 |  |                  while (it.hasNext()) | 
  | 471 |  |                  { | 
  | 472 |  |                      ((ClassDescriptor) it.next()).removeExtentClass(className); | 
  | 473 |  |                  } | 
  | 474 |  |                  removeExtent(className); | 
  | 475 |  |                  List extentClasses = cld.getExtentClasses(); | 
  | 476 |  |                  for (int i = 0; i < extentClasses.size(); ++i) | 
  | 477 |  |                  { | 
  | 478 |  |                      removeExtent(((Class) extentClasses.get(i)).getName()); | 
  | 479 |  |                  } | 
  | 480 |  |                  changeDescriptorEvent(); | 
  | 481 |  |                   | 
  | 482 |  |                   | 
  | 483 |  |                  deregisterSuperClassMultipleJoinedTables(cld); | 
  | 484 |  |              } | 
  | 485 |  |          } | 
  | 486 |  |      } | 
  | 487 |  |   | 
  | 488 |  |      public void remove(Class clazz) | 
  | 489 |  |      { | 
  | 490 |  |          remove(clazz.getName()); | 
  | 491 |  |      } | 
  | 492 |  |   | 
  | 493 |  |      private synchronized void changeDescriptorEvent() | 
  | 494 |  |      { | 
  | 495 |  |          m_multiMappedTableMap = null; | 
  | 496 |  |          m_topLevelClassTable = null; | 
  | 497 |  |          m_firstConcreteClassMap = null; | 
  | 498 |  |          m_allConcreteSubClass = null; | 
  | 499 |  |      } | 
  | 500 |  |   | 
  | 501 |  |       | 
  | 502 |  |   | 
  | 503 |  |   | 
  | 504 |  |      public Iterator iterator() | 
  | 505 |  |      { | 
  | 506 |  |           | 
  | 507 |  |   | 
  | 508 |  |   | 
  | 509 |  |          return ((HashMap)descriptorTable.clone()).values().iterator(); | 
  | 510 |  |      } | 
  | 511 |  |   | 
  | 512 |  |       | 
  | 513 |  |   | 
  | 514 |  |   | 
  | 515 |  |   | 
  | 516 |  |      public int getDefaultIsolationLevel() | 
  | 517 |  |      { | 
  | 518 |  |          return defaultIsolationLevel; | 
  | 519 |  |      } | 
  | 520 |  |   | 
  | 521 |  |       | 
  | 522 |  |   | 
  | 523 |  |   | 
  | 524 |  |   | 
  | 525 |  |      public void setDefaultIsolationLevel(int defaultIsolationLevel) | 
  | 526 |  |      { | 
  | 527 |  |          this.defaultIsolationLevel = defaultIsolationLevel; | 
  | 528 |  |      } | 
  | 529 |  |   | 
  | 530 |  |       | 
  | 531 |  |   | 
  | 532 |  |   | 
  | 533 |  |      public String toString() | 
  | 534 |  |      { | 
  | 535 |  |           | 
  | 536 |  |   | 
  | 537 |  |   | 
  | 538 |  |              synchronized (descriptorTable) {                         | 
  | 539 |  |           | 
  | 540 |  |   | 
  | 541 |  |   | 
  | 542 |  |                  Iterator it = descriptorTable.entrySet().iterator(); | 
  | 543 |  |                  ToStringBuilder buf = new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE); | 
  | 544 |  |                  String className = "class name: "; | 
  | 545 |  |                  String tableName = "> table name: "; | 
  | 546 |  |                  while (it.hasNext()) | 
  | 547 |  |                  { | 
  | 548 |  |                      Map.Entry me = (Map.Entry) it.next(); | 
  | 549 |  |                      ClassDescriptor descriptor = (ClassDescriptor) me.getValue(); | 
  | 550 |  |                      buf.append(className + me.getKey() + " =", tableName + descriptor.getFullTableName()); | 
  | 551 |  |                  } | 
  | 552 |  |                  return buf.toString(); | 
  | 553 |  |           | 
  | 554 |  |   | 
  | 555 |  |   | 
  | 556 |  |                  } | 
  | 557 |  |           | 
  | 558 |  |   | 
  | 559 |  |   | 
  | 560 |  |      } | 
  | 561 |  |   | 
  | 562 |  |       | 
  | 563 |  |   | 
  | 564 |  |   | 
  | 565 |  |      public String toXML() | 
  | 566 |  |      { | 
  | 567 |  |          String eol = SystemUtils.LINE_SEPARATOR; | 
  | 568 |  |          StringBuffer buf = new StringBuffer(); | 
  | 569 |  |   | 
  | 570 |  |           | 
  | 571 |  |          Iterator i = this.iterator(); | 
  | 572 |  |          while (i.hasNext()) | 
  | 573 |  |          { | 
  | 574 |  |              buf.append(((XmlCapable) i.next()).toXML() + eol); | 
  | 575 |  |          } | 
  | 576 |  |          return buf.toString(); | 
  | 577 |  |      } | 
  | 578 |  |   | 
  | 579 |  |       | 
  | 580 |  |   | 
  | 581 |  |   | 
  | 582 |  |   | 
  | 583 |  |   | 
  | 584 |  |      protected String getIsolationLevelAsString() | 
  | 585 |  |      { | 
  | 586 |  |          if (defaultIsolationLevel == IL_READ_UNCOMMITTED) | 
  | 587 |  |          { | 
  | 588 |  |              return LITERAL_IL_READ_UNCOMMITTED; | 
  | 589 |  |          } | 
  | 590 |  |          else if (defaultIsolationLevel == IL_READ_COMMITTED) | 
  | 591 |  |          { | 
  | 592 |  |              return LITERAL_IL_READ_COMMITTED; | 
  | 593 |  |          } | 
  | 594 |  |          else if (defaultIsolationLevel == IL_REPEATABLE_READ) | 
  | 595 |  |          { | 
  | 596 |  |              return LITERAL_IL_REPEATABLE_READ; | 
  | 597 |  |          } | 
  | 598 |  |          else if (defaultIsolationLevel == IL_SERIALIZABLE) | 
  | 599 |  |          { | 
  | 600 |  |              return LITERAL_IL_SERIALIZABLE; | 
  | 601 |  |          } | 
  | 602 |  |          else if (defaultIsolationLevel == IL_OPTIMISTIC) | 
  | 603 |  |          { | 
  | 604 |  |              return LITERAL_IL_OPTIMISTIC; | 
  | 605 |  |          } | 
  | 606 |  |          return LITERAL_IL_READ_UNCOMMITTED; | 
  | 607 |  |      } | 
  | 608 |  |   | 
  | 609 |  |       | 
  | 610 |  |   | 
  | 611 |  |   | 
  | 612 |  |   | 
  | 613 |  |   | 
  | 614 |  |   | 
  | 615 |  |   | 
  | 616 |  |   | 
  | 617 |  |   | 
  | 618 |  |   | 
  | 619 |  |   | 
  | 620 |  |   | 
  | 621 |  |   | 
  | 622 |  |   | 
  | 623 |  |   | 
  | 624 |  |   | 
  | 625 |  |   | 
  | 626 |  |   | 
  | 627 |  |      protected ClassDescriptor discoverDescriptor(String className) | 
  | 628 |  |      { | 
  | 629 |  |          ClassDescriptor result = (ClassDescriptor) descriptorTable.get(className); | 
  | 630 |  |          if (result == null) | 
  | 631 |  |          { | 
  | 632 |  |              Class clazz; | 
  | 633 |  |              try | 
  | 634 |  |              { | 
  | 635 |  |                  clazz = ClassHelper.getClass(className, true); | 
  | 636 |  |              } | 
  | 637 |  |              catch (ClassNotFoundException e) | 
  | 638 |  |              { | 
  | 639 |  |                  throw new OJBRuntimeException("Class, " + className + ", could not be found.", e); | 
  | 640 |  |              } | 
  | 641 |  |              result = discoverDescriptor(clazz); | 
  | 642 |  |           } | 
  | 643 |  |          return result; | 
  | 644 |  |      } | 
  | 645 |  |   | 
  | 646 |  |       | 
  | 647 |  |   | 
  | 648 |  |   | 
  | 649 |  |   | 
  | 650 |  |   | 
  | 651 |  |   | 
  | 652 |  |   | 
  | 653 |  |   | 
  | 654 |  |      private ClassDescriptor discoverDescriptor(Class clazz) | 
  | 655 |  |      { | 
  | 656 |  |          ClassDescriptor result = (ClassDescriptor) descriptorTable.get(clazz.getName()); | 
  | 657 |  |   | 
  | 658 |  |          if (result == null) | 
  | 659 |  |          { | 
  | 660 |  |              Class superClass = clazz.getSuperclass(); | 
  | 661 |  |               | 
  | 662 |  |              if (superClass != null) | 
  | 663 |  |              { | 
  | 664 |  |                  result = discoverDescriptor(superClass); | 
  | 665 |  |              } | 
  | 666 |  |              if (result == null) | 
  | 667 |  |              { | 
  | 668 |  |                   | 
  | 669 |  |                   | 
  | 670 |  |                   | 
  | 671 |  |                  Class[] interfaces = clazz.getInterfaces(); | 
  | 672 |  |   | 
  | 673 |  |                  if ((interfaces != null) && (interfaces.length > 0)) | 
  | 674 |  |                  { | 
  | 675 |  |                      for (int idx = 0; (idx < interfaces.length) && (result == null); idx++) | 
  | 676 |  |                      { | 
  | 677 |  |                          result = discoverDescriptor(interfaces[idx]); | 
  | 678 |  |                      } | 
  | 679 |  |                  } | 
  | 680 |  |              } | 
  | 681 |  |   | 
  | 682 |  |              if (result != null) | 
  | 683 |  |              { | 
  | 684 |  |                   | 
  | 685 |  |   | 
  | 686 |  |   | 
  | 687 |  |                      synchronized (descriptorTable) { | 
  | 688 |  |                   | 
  | 689 |  |   | 
  | 690 |  |   | 
  | 691 |  |                              descriptorTable.put(clazz.getName(), result); | 
  | 692 |  |                   | 
  | 693 |  |   | 
  | 694 |  |   | 
  | 695 |  |                      } | 
  | 696 |  |                   | 
  | 697 |  |   | 
  | 698 |  |   | 
  | 699 |  |              } | 
  | 700 |  |          } | 
  | 701 |  |          return result; | 
  | 702 |  |      } | 
  | 703 |  |   | 
  | 704 |  |       | 
  | 705 |  |   | 
  | 706 |  |   | 
  | 707 |  |   | 
  | 708 |  |   | 
  | 709 |  |   | 
  | 710 |  |   | 
  | 711 |  |      protected void registerSuperClassMultipleJoinedTables(ClassDescriptor cld) | 
  | 712 |  |      { | 
  | 713 |  |           | 
  | 714 |  |   | 
  | 715 |  |   | 
  | 716 |  |   | 
  | 717 |  |   | 
  | 718 |  |          if(cld.getBaseClass() != null) | 
  | 719 |  |          { | 
  | 720 |  |              try | 
  | 721 |  |              { | 
  | 722 |  |                  Class superClass = ClassHelper.getClass(cld.getBaseClass()); | 
  | 723 |  |                  Class currentClass = cld.getClassOfObject(); | 
  | 724 |  |                  synchronized(descriptorTable) | 
  | 725 |  |                  { | 
  | 726 |  |                      List subClasses = (List) superClassMultipleJoinedTablesMap.get(superClass); | 
  | 727 |  |                      if(subClasses == null) | 
  | 728 |  |                      { | 
  | 729 |  |                          subClasses = new ArrayList(); | 
  | 730 |  |                          superClassMultipleJoinedTablesMap.put(superClass,  subClasses); | 
  | 731 |  |                      } | 
  | 732 |  |                      if(!subClasses.contains(currentClass)) | 
  | 733 |  |                      { | 
  | 734 |  |                          if(log.isDebugEnabled()) | 
  | 735 |  |                          { | 
  | 736 |  |                              log.debug("(MultipleJoinedTables): Register sub-class '" + currentClass | 
  | 737 |  |                                      + "' for class '" + superClass); | 
  | 738 |  |                          } | 
  | 739 |  |                          subClasses.add(currentClass); | 
  | 740 |  |                      } | 
  | 741 |  |                  } | 
  | 742 |  |              } | 
  | 743 |  |              catch(Exception e) | 
  | 744 |  |              { | 
  | 745 |  |                  throw new MetadataException("Can't register super class '" + cld.getBaseClass() | 
  | 746 |  |                          + "' for class-descriptor: " + cld, e); | 
  | 747 |  |              } | 
  | 748 |  |          } | 
  | 749 |  |      } | 
  | 750 |  |   | 
  | 751 |  |       | 
  | 752 |  |   | 
  | 753 |  |   | 
  | 754 |  |   | 
  | 755 |  |   | 
  | 756 |  |   | 
  | 757 |  |      protected void deregisterSuperClassMultipleJoinedTables(ClassDescriptor cld) | 
  | 758 |  |      { | 
  | 759 |  |          try | 
  | 760 |  |          { | 
  | 761 |  |              Class currentClass = cld.getClassOfObject(); | 
  | 762 |  |              synchronized(descriptorTable) | 
  | 763 |  |              { | 
  | 764 |  |                   | 
  | 765 |  |                  List subClasses = (List) superClassMultipleJoinedTablesMap.remove(currentClass); | 
  | 766 |  |                  if(subClasses != null && log.isDebugEnabled()) | 
  | 767 |  |                  { | 
  | 768 |  |                      log.debug("(MultipleJoinedTables): Deregister class " + currentClass | 
  | 769 |  |                              + " with sub classes " + subClasses); | 
  | 770 |  |                  } | 
  | 771 |  |                  if(cld.getBaseClass() != null) | 
  | 772 |  |                  { | 
  | 773 |  |                       | 
  | 774 |  |                      Class superClass = ClassHelper.getClass(cld.getBaseClass()); | 
  | 775 |  |                      subClasses = (List) superClassMultipleJoinedTablesMap.get(superClass); | 
  | 776 |  |                      if(subClasses != null) | 
  | 777 |  |                      { | 
  | 778 |  |                          boolean removed = subClasses.remove(currentClass); | 
  | 779 |  |                          if(removed && log.isDebugEnabled()) | 
  | 780 |  |                          { | 
  | 781 |  |                              log.debug("(MultipleJoinedTables): Remove sub-class entry '" + currentClass | 
  | 782 |  |                              + "' in mapping for class '" + superClass + "'"); | 
  | 783 |  |                          } | 
  | 784 |  |                      } | 
  | 785 |  |                  } | 
  | 786 |  |              } | 
  | 787 |  |          } | 
  | 788 |  |          catch(Exception e) | 
  | 789 |  |          { | 
  | 790 |  |              throw new MetadataException("Can't deregister super class '" + cld.getBaseClass() | 
  | 791 |  |                      + "' for class-descriptor: " + cld, e); | 
  | 792 |  |          } | 
  | 793 |  |      } | 
  | 794 |  |   | 
  | 795 |  |       | 
  | 796 |  |   | 
  | 797 |  |   | 
  | 798 |  |   | 
  | 799 |  |   | 
  | 800 |  |   | 
  | 801 |  |   | 
  | 802 |  |   | 
  | 803 |  |   | 
  | 804 |  |      public Class[] getSubClassesMultipleJoinedTables(ClassDescriptor cld, boolean wholeTree) | 
  | 805 |  |      { | 
  | 806 |  |          ArrayList result = new ArrayList(); | 
  | 807 |  |          createResultSubClassesMultipleJoinedTables(result, cld, wholeTree); | 
  | 808 |  |          return (Class[]) result.toArray(new Class[result.size()]); | 
  | 809 |  |      } | 
  | 810 |  |   | 
  | 811 |  |       | 
  | 812 |  |   | 
  | 813 |  |   | 
  | 814 |  |   | 
  | 815 |  |   | 
  | 816 |  |   | 
  | 817 |  |   | 
  | 818 |  |   | 
  | 819 |  |      private void createResultSubClassesMultipleJoinedTables(List result, ClassDescriptor cld, boolean wholeTree) | 
  | 820 |  |      { | 
  | 821 |  |          List tmp = (List) superClassMultipleJoinedTablesMap.get(cld.getClassOfObject()); | 
  | 822 |  |          if(tmp != null) | 
  | 823 |  |          { | 
  | 824 |  |              result.addAll(tmp); | 
  | 825 |  |              if(wholeTree) | 
  | 826 |  |              { | 
  | 827 |  |                  for(int i = 0; i < tmp.size(); i++) | 
  | 828 |  |                  { | 
  | 829 |  |                      Class subClass = (Class) tmp.get(i); | 
  | 830 |  |                      ClassDescriptor subCld = getDescriptorFor(subClass); | 
  | 831 |  |                      createResultSubClassesMultipleJoinedTables(result, subCld, wholeTree); | 
  | 832 |  |                  } | 
  | 833 |  |              } | 
  | 834 |  |          } | 
  | 835 |  |      } | 
  | 836 |  |   | 
  | 837 |  |      protected void finalize() throws Throwable | 
  | 838 |  |      { | 
  | 839 |  |          log.info("# finalize DescriptorRepository instance #"); | 
  | 840 |  |          super.finalize(); | 
  | 841 |  |      } | 
  | 842 |  |  } |