1 package org.apache.ojb.broker.metadata; 2 3 17 18 import java.io.FileNotFoundException ; 19 import java.io.InputStream ; 20 import java.util.Hashtable ; 21 import java.util.Iterator ; 22 import java.util.List ; 23 24 import org.apache.commons.lang.SerializationUtils; 25 import org.apache.ojb.broker.PBKey; 26 import org.apache.ojb.broker.core.PersistenceBrokerConfiguration; 27 import org.apache.ojb.broker.util.configuration.impl.OjbConfigurator; 28 import org.apache.ojb.broker.util.logging.Logger; 29 import org.apache.ojb.broker.util.logging.LoggerFactory; 30 31 121 public class MetadataManager 122 { 123 private static Logger log = LoggerFactory.getLogger(MetadataManager.class); 124 125 private static final String MSG_STR = "* Can't find DescriptorRepository for current thread, use default one *"; 126 private static ThreadLocal threadedRepository = new ThreadLocal (); 127 private static ThreadLocal currentProfileKey = new ThreadLocal (); 128 private static MetadataManager singleton; 129 130 private Hashtable metadataProfiles; 131 private DescriptorRepository globalRepository; 132 private ConnectionRepository connectionRepository; 133 private boolean enablePerThreadChanges; 134 private PBKey defaultPBKey; 135 136 private MetadataManager() 138 { 139 init(); 140 } 141 142 private void init() 143 { 144 metadataProfiles = new Hashtable (); 145 final String repository = ((PersistenceBrokerConfiguration) OjbConfigurator.getInstance() 146 .getConfigurationFor(null)).getRepositoryFilename(); 147 try 148 { 149 globalRepository = new RepositoryPersistor().readDescriptorRepository(repository); 150 connectionRepository = new RepositoryPersistor().readConnectionRepository(repository); 151 } 152 catch (FileNotFoundException ex) 153 { 154 log.warn("Could not access '" + repository + "' or a DOCTYPE/DTD-dependency. " 155 + "(Check letter case for file names and HTTP-access if using DOCTYPE PUBLIC)" 156 + " Starting with empty metadata and connection configurations.", ex); 157 globalRepository = new DescriptorRepository(); 158 connectionRepository = new ConnectionRepository(); 159 } 160 catch (Exception ex) 161 { 162 throw new MetadataException("Can't read repository file '" + repository + "'", ex); 163 } 164 } 165 166 public void shutdown() 167 { 168 threadedRepository = null; 169 currentProfileKey = null; 170 globalRepository = null; 171 metadataProfiles = null; 172 singleton = null; 173 } 174 175 178 public static synchronized MetadataManager getInstance() 179 { 180 if (singleton == null) 182 { 183 singleton = new MetadataManager(); 184 } 185 return singleton; 186 } 187 188 200 public DescriptorRepository getRepository() 201 { 202 DescriptorRepository repository; 203 if (enablePerThreadChanges) 204 { 205 repository = (DescriptorRepository) threadedRepository.get(); 206 if (repository == null) 207 { 208 repository = getGlobalRepository(); 209 log.info(MSG_STR); 210 } 211 return repository; 219 } 220 else 221 { 222 return globalRepository; 223 } 224 } 225 226 233 public DescriptorRepository getGlobalRepository() 234 { 235 return globalRepository; 236 } 237 238 241 public ConnectionRepository connectionRepository() 242 { 243 return connectionRepository; 244 } 245 246 251 public void mergeConnectionRepository(ConnectionRepository repository) 252 { 253 mergeConnectionRepository(connectionRepository(), repository, false); 254 } 255 256 268 public void mergeConnectionRepository( 269 ConnectionRepository targetRepository, ConnectionRepository sourceRepository, boolean deep) 270 { 271 List list = sourceRepository.getAllDescriptor(); 272 for (Iterator iterator = list.iterator(); iterator.hasNext();) 273 { 274 JdbcConnectionDescriptor jcd = (JdbcConnectionDescriptor) iterator.next(); 275 if (deep) 276 { 277 jcd = (JdbcConnectionDescriptor) SerializationUtils.clone(jcd); 279 } 280 targetRepository.addDescriptor(jcd); 281 } 282 } 283 284 293 public void mergeDescriptorRepository(DescriptorRepository repository) 294 { 295 mergeDescriptorRepository(getRepository(), repository, false); 296 } 297 298 313 public void mergeDescriptorRepository( 314 DescriptorRepository targetRepository, DescriptorRepository sourceRepository, boolean deep) 315 { 316 Iterator it = sourceRepository.iterator(); 317 while (it.hasNext()) 318 { 319 ClassDescriptor cld = (ClassDescriptor) it.next(); 320 if (deep) 321 { 322 cld = (ClassDescriptor) SerializationUtils.clone(cld); 324 } 325 targetRepository.put(cld.getClassOfObject(), cld); 326 cld.setRepository(targetRepository); 327 } 328 } 329 330 334 public DescriptorRepository readDescriptorRepository(String fileName) 335 { 336 try 337 { 338 RepositoryPersistor persistor = new RepositoryPersistor(); 339 return persistor.readDescriptorRepository(fileName); 340 } 341 catch (Exception e) 342 { 343 throw new MetadataException("Can not read repository " + fileName, e); 344 } 345 } 346 347 351 public DescriptorRepository readDescriptorRepository(InputStream inst) 352 { 353 try 354 { 355 RepositoryPersistor persistor = new RepositoryPersistor(); 356 return persistor.readDescriptorRepository(inst); 357 } 358 catch (Exception e) 359 { 360 throw new MetadataException("Can not read repository " + inst, e); 361 } 362 } 363 364 369 public ConnectionRepository readConnectionRepository(String fileName) 370 { 371 try 372 { 373 RepositoryPersistor persistor = new RepositoryPersistor(); 374 return persistor.readConnectionRepository(fileName); 375 } 376 catch (Exception e) 377 { 378 throw new MetadataException("Can not read repository " + fileName, e); 379 } 380 } 381 382 387 public ConnectionRepository readConnectionRepository(InputStream inst) 388 { 389 try 390 { 391 RepositoryPersistor persistor = new RepositoryPersistor(); 392 return persistor.readConnectionRepository(inst); 393 } 394 catch (Exception e) 395 { 396 throw new MetadataException("Can not read repository from " + inst, e); 397 } 398 } 399 400 408 public void setDescriptor(DescriptorRepository repository, boolean global) 409 { 410 if (global) 411 { 412 if (log.isDebugEnabled()) log.debug("Set new global repository: " + repository); 413 globalRepository = repository; 414 } 415 else 416 { 417 if (log.isDebugEnabled()) log.debug("Set new threaded repository: " + repository); 418 threadedRepository.set(repository); 419 } 420 } 421 422 427 public void setDescriptor(DescriptorRepository repository) 428 { 429 setDescriptor(repository, false); 430 } 431 432 437 public void setPerThreadDescriptor(DescriptorRepository repository) 438 { 439 setDescriptor(repository, false); 440 } 441 442 452 public DescriptorRepository copyOfGlobalRepository() 453 { 454 return (DescriptorRepository) SerializationUtils.clone(globalRepository); 455 } 456 457 468 public boolean isEnablePerThreadChanges() 469 { 470 return enablePerThreadChanges; 471 } 472 473 479 public void setEnablePerThreadChanges(boolean enablePerThreadChanges) 480 { 481 this.enablePerThreadChanges = enablePerThreadChanges; 482 } 483 484 488 public void addProfile(Object key, DescriptorRepository repository) 489 { 490 if (metadataProfiles.contains(key)) 491 { 492 throw new MetadataException("Duplicate profile key. Key '" + key + "' already exists."); 493 } 494 metadataProfiles.put(key, repository); 495 } 496 497 501 public void loadProfile(Object key) 502 { 503 if (!isEnablePerThreadChanges()) 504 { 505 throw new MetadataException("Can not load profile with disabled per thread mode"); 506 } 507 DescriptorRepository rep = (DescriptorRepository) metadataProfiles.get(key); 508 if (rep == null) 509 { 510 throw new MetadataException("Can not find profile for key '" + key + "'"); 511 } 512 currentProfileKey.set(key); 513 setDescriptor(rep); 514 } 515 516 522 public Object getCurrentProfileKey() throws MetadataException 523 { 524 if (!isEnablePerThreadChanges()) 525 { 526 throw new MetadataException("Call to this method is undefined, since per-thread mode is disabled."); 527 } 528 return currentProfileKey.get(); 529 } 530 531 534 public DescriptorRepository removeProfile(Object key) 535 { 536 return (DescriptorRepository) metadataProfiles.remove(key); 537 } 538 539 542 public void clearProfiles() 543 { 544 metadataProfiles.clear(); 545 currentProfileKey.set(null); 546 } 547 548 554 public void removeAllProfiles() 555 { 556 metadataProfiles.clear(); 557 currentProfileKey.set(null); 558 } 559 560 570 public PBKey getDefaultPBKey() 571 { 572 if(defaultPBKey == null) 573 { 574 defaultPBKey = buildDefaultKey(); 575 } 576 return defaultPBKey; 577 } 578 579 592 public void setDefaultPBKey(PBKey defaultPBKey) 593 { 594 if(this.defaultPBKey != null) 595 { 596 log.warn("The used default PBKey change. Current key is " + this.defaultPBKey + ", new key will be " + defaultPBKey); 597 } 598 this.defaultPBKey = defaultPBKey; 599 log.info("Set default PBKey for convenience broker creation: " + defaultPBKey); 600 } 601 602 608 private PBKey buildDefaultKey() 609 { 610 List descriptors = connectionRepository().getAllDescriptor(); 611 JdbcConnectionDescriptor descriptor; 612 PBKey result = null; 613 for (Iterator iterator = descriptors.iterator(); iterator.hasNext();) 614 { 615 descriptor = (JdbcConnectionDescriptor) iterator.next(); 616 if (descriptor.isDefaultConnection()) 617 { 618 if(result != null) 619 { 620 log.error("Found additional connection descriptor with enabled 'default-connection' " 621 + descriptor.getPBKey() + ". This is NOT allowed. Will use the first found descriptor " + result 622 + " as default connection"); 623 } 624 else 625 { 626 result = descriptor.getPBKey(); 627 } 628 } 629 } 630 631 if(result == null) 632 { 633 log.info("No 'default-connection' attribute set in jdbc-connection-descriptors," + 634 " thus it's currently not possible to use 'defaultPersistenceBroker()' " + 635 " convenience method to lookup PersistenceBroker instances. But it's possible"+ 636 " to enable this at runtime using 'setDefaultKey' method."); 637 } 638 return result; 639 } 640 } 641 | Popular Tags |