1 23 24 package org.infoglue.deliver.util; 25 26 import java.io.IOException ; 28 import java.util.ArrayList ; 29 import java.util.Collections ; 30 import java.util.Date ; 31 import java.util.HashMap ; 32 import java.util.Iterator ; 33 import java.util.List ; 34 import java.util.Map ; 35 36 import javax.servlet.http.HttpServletRequest ; 37 import javax.servlet.http.HttpSession ; 38 39 import org.apache.log4j.Logger; 40 import org.apache.pluto.portalImpl.services.ServiceManager; 41 import org.apache.pluto.portalImpl.services.portletentityregistry.PortletEntityRegistry; 42 import org.exolab.castor.jdo.CacheManager; 43 import org.exolab.castor.jdo.Database; 44 import org.infoglue.cms.controllers.kernel.impl.simple.CastorDatabaseService; 45 import org.infoglue.cms.controllers.kernel.impl.simple.ContentVersionController; 46 import org.infoglue.cms.entities.content.ContentVersionVO; 47 import org.infoglue.cms.entities.content.impl.simple.ContentCategoryImpl; 48 import org.infoglue.cms.entities.content.impl.simple.ContentImpl; 49 import org.infoglue.cms.entities.content.impl.simple.ContentRelationImpl; 50 import org.infoglue.cms.entities.content.impl.simple.ContentVersionImpl; 51 import org.infoglue.cms.entities.content.impl.simple.DigitalAssetImpl; 52 import org.infoglue.cms.entities.content.impl.simple.MediumContentImpl; 53 import org.infoglue.cms.entities.content.impl.simple.SmallContentImpl; 54 import org.infoglue.cms.entities.management.impl.simple.AccessRightImpl; 55 import org.infoglue.cms.entities.management.impl.simple.AvailableServiceBindingImpl; 56 import org.infoglue.cms.entities.management.impl.simple.CategoryImpl; 57 import org.infoglue.cms.entities.management.impl.simple.ContentTypeDefinitionImpl; 58 import org.infoglue.cms.entities.management.impl.simple.GroupContentTypeDefinitionImpl; 59 import org.infoglue.cms.entities.management.impl.simple.GroupImpl; 60 import org.infoglue.cms.entities.management.impl.simple.GroupPropertiesImpl; 61 import org.infoglue.cms.entities.management.impl.simple.InterceptionPointImpl; 62 import org.infoglue.cms.entities.management.impl.simple.InterceptorImpl; 63 import org.infoglue.cms.entities.management.impl.simple.LanguageImpl; 64 import org.infoglue.cms.entities.management.impl.simple.PropertiesCategoryImpl; 65 import org.infoglue.cms.entities.management.impl.simple.RedirectImpl; 66 import org.infoglue.cms.entities.management.impl.simple.RegistryImpl; 67 import org.infoglue.cms.entities.management.impl.simple.RepositoryImpl; 68 import org.infoglue.cms.entities.management.impl.simple.RepositoryLanguageImpl; 69 import org.infoglue.cms.entities.management.impl.simple.RoleContentTypeDefinitionImpl; 70 import org.infoglue.cms.entities.management.impl.simple.RoleImpl; 71 import org.infoglue.cms.entities.management.impl.simple.RolePropertiesImpl; 72 import org.infoglue.cms.entities.management.impl.simple.ServerNodeImpl; 73 import org.infoglue.cms.entities.management.impl.simple.ServiceDefinitionImpl; 74 import org.infoglue.cms.entities.management.impl.simple.SiteNodeTypeDefinitionImpl; 75 import org.infoglue.cms.entities.management.impl.simple.SmallAvailableServiceBindingImpl; 76 import org.infoglue.cms.entities.management.impl.simple.SystemUserImpl; 77 import org.infoglue.cms.entities.management.impl.simple.UserContentTypeDefinitionImpl; 78 import org.infoglue.cms.entities.management.impl.simple.UserPropertiesImpl; 79 import org.infoglue.cms.entities.publishing.impl.simple.PublicationDetailImpl; 80 import org.infoglue.cms.entities.publishing.impl.simple.PublicationImpl; 81 import org.infoglue.cms.entities.structure.impl.simple.QualifyerImpl; 82 import org.infoglue.cms.entities.structure.impl.simple.ServiceBindingImpl; 83 import org.infoglue.cms.entities.structure.impl.simple.SiteNodeImpl; 84 import org.infoglue.cms.entities.structure.impl.simple.SiteNodeVersionImpl; 85 import org.infoglue.cms.entities.structure.impl.simple.SmallSiteNodeImpl; 86 import org.infoglue.cms.entities.workflow.impl.simple.ActionDefinitionImpl; 87 import org.infoglue.cms.entities.workflow.impl.simple.ActionImpl; 88 import org.infoglue.cms.entities.workflow.impl.simple.ActorImpl; 89 import org.infoglue.cms.entities.workflow.impl.simple.ConsequenceDefinitionImpl; 90 import org.infoglue.cms.entities.workflow.impl.simple.ConsequenceImpl; 91 import org.infoglue.cms.entities.workflow.impl.simple.EventImpl; 92 import org.infoglue.cms.entities.workflow.impl.simple.WorkflowDefinitionImpl; 93 import org.infoglue.cms.entities.workflow.impl.simple.WorkflowImpl; 94 import org.infoglue.cms.exception.SystemException; 95 import org.infoglue.cms.security.InfoGlueAuthenticationFilter; 96 import org.infoglue.cms.util.CmsPropertyHandler; 97 import org.infoglue.cms.util.NotificationMessage; 98 import org.infoglue.deliver.applications.databeans.CacheEvictionBean; 99 import org.infoglue.deliver.applications.databeans.DatabaseWrapper; 100 import org.infoglue.deliver.controllers.kernel.impl.simple.DigitalAssetDeliveryController; 101 import org.infoglue.deliver.controllers.kernel.impl.simple.TemplateController; 102 import org.infoglue.deliver.portal.ServletConfigContainer; 103 104 import sun.reflect.ReflectionFactory.GetReflectionFactoryAction; 105 106 import com.opensymphony.oscache.base.CacheEntry; 107 import com.opensymphony.oscache.base.NeedsRefreshException; 108 import com.opensymphony.oscache.base.events.CacheEntryEventListener; 109 import com.opensymphony.oscache.base.events.CacheMapAccessEventListener; 110 import com.opensymphony.oscache.extra.CacheEntryEventListenerImpl; 111 import com.opensymphony.oscache.extra.CacheMapAccessEventListenerImpl; 112 import com.opensymphony.oscache.general.GeneralCacheAdministrator; 113 114 115 public class CacheController extends Thread 116 { 117 public final static Logger logger = Logger.getLogger(CacheController.class.getName()); 118 119 public static final String SETTINGSPROPERTIESCACHENAME = "serverNodePropertiesCache"; 120 public static final String SETTINGSPROPERTIESDOCUMENTCACHENAME = "serverNodePropertiesDocumentCache"; 121 122 public static List notifications = Collections.synchronizedList(new ArrayList ()); 123 124 private static Map eventListeners = new HashMap (); 125 private static Map caches = Collections.synchronizedMap(new HashMap ()); 126 private boolean expireCacheAutomatically = false; 127 private int cacheExpireInterval = 1800000; 128 private boolean continueRunning = true; 129 130 private static GeneralCacheAdministrator generalCache = new GeneralCacheAdministrator(); 131 132 public static Date expireDateTime = null; 133 public static Date publishDateTime = null; 134 135 136 public CacheController() 137 { 138 super(); 139 } 140 141 public void setCacheExpireInterval(int cacheExpireInterval) 142 { 143 this.cacheExpireInterval = cacheExpireInterval; 144 } 145 146 public static void renameCache(String cacheName, String newCacheName) 147 { 148 synchronized(caches) 149 { 150 Object cacheInstance = caches.get(cacheName); 151 152 if(cacheInstance != null) 153 { 154 synchronized(cacheInstance) 155 { 156 caches.put(newCacheName, cacheInstance); 157 caches.remove(cacheName); 158 } 159 } 160 } 161 } 162 163 public static void clearServerNodeProperty() 164 { 165 clearCache("serverNodePropertiesCache"); 166 } 167 168 public static void cacheObject(String cacheName, Object key, Object value) 169 { 170 synchronized(caches) 171 { 172 if(!caches.containsKey(cacheName)) 173 caches.put(cacheName, Collections.synchronizedMap(new HashMap ())); 174 } 175 176 synchronized(caches) 177 { 178 Map cacheInstance = (Map )caches.get(cacheName); 179 if(cacheInstance != null && key != null && value != null) 180 { 181 synchronized(cacheInstance) 182 { 183 cacheInstance.put(key, value); 184 } 185 } 186 } 187 } 188 189 public static Object getCachedObject(String cacheName, Object key) 190 { 191 synchronized(caches) 192 { 193 Map cacheInstance = (Map )caches.get(cacheName); 194 if(cacheInstance != null) 195 { 196 synchronized(cacheInstance) 197 { 198 return cacheInstance.get(key); 199 } 200 } 201 } 202 203 return null; 204 } 205 206 public static void cacheObjectInAdvancedCache(String cacheName, Object key, Object value, String [] groups, boolean useGroups) 207 { 208 synchronized(caches) 209 { 210 if(!caches.containsKey(cacheName)) 211 { 212 GeneralCacheAdministrator cacheAdministrator = new GeneralCacheAdministrator(); 213 214 CacheEntryEventListenerImpl cacheEntryEventListener = new ExtendedCacheEntryEventListenerImpl(); 215 CacheMapAccessEventListenerImpl cacheMapAccessEventListener = new CacheMapAccessEventListenerImpl(); 216 217 cacheAdministrator.getCache().addCacheEventListener(cacheEntryEventListener, CacheEntryEventListener.class); 218 cacheAdministrator.getCache().addCacheEventListener(cacheMapAccessEventListener, CacheMapAccessEventListener.class); 219 caches.put(cacheName, cacheAdministrator); 220 eventListeners.put(cacheName + "_cacheEntryEventListener", cacheEntryEventListener); 221 eventListeners.put(cacheName + "_cacheMapAccessEventListener", cacheMapAccessEventListener); 222 } 223 224 GeneralCacheAdministrator cacheAdministrator = (GeneralCacheAdministrator)caches.get(cacheName); 225 synchronized(cacheAdministrator) 226 { 227 if(useGroups) 228 cacheAdministrator.putInCache(key.toString(), value, groups); 229 else 230 cacheAdministrator.putInCache(key.toString(), value); 231 } 232 } 233 234 } 236 237 public static Object getCachedObjectFromAdvancedCache(String cacheName, Object key) 238 { 239 241 Object value = null; 242 243 synchronized(caches) 244 { 245 GeneralCacheAdministrator cacheAdministrator = (GeneralCacheAdministrator)caches.get(cacheName); 246 if(cacheAdministrator != null) 247 { 248 synchronized(cacheAdministrator) 249 { 250 try 251 { 252 value = (cacheAdministrator == null) ? null : cacheAdministrator.getFromCache(key.toString(), CacheEntry.INDEFINITE_EXPIRY); 253 } 254 catch (NeedsRefreshException nre) 255 { 256 cacheAdministrator.cancelUpdate(key.toString()); 257 } 258 } 259 } 260 261 } 263 264 return value; 265 } 266 267 public static Object getCachedObjectFromAdvancedCache(String cacheName, Object key, int updateInterval) 268 { 269 if(cacheName == null || key == null) 270 return null; 271 272 274 Object value = null; 276 277 synchronized(caches) 278 { 279 GeneralCacheAdministrator cacheAdministrator = (GeneralCacheAdministrator)caches.get(cacheName); 280 if(cacheAdministrator != null) 281 { 282 synchronized(cacheAdministrator) 283 { 284 try 285 { 286 value = (cacheAdministrator == null) ? null : cacheAdministrator.getFromCache(key.toString(), updateInterval); 287 } 288 catch (NeedsRefreshException nre) 289 { 290 cacheAdministrator.cancelUpdate(key.toString()); 291 } 292 } 293 } 294 } 296 297 return value; 298 } 299 300 public static void clearCache(String cacheName) 301 { 302 logger.info("Clearing the cache called " + cacheName); 303 synchronized(caches) 304 { 305 if(caches.containsKey(cacheName)) 306 { 307 Object object = caches.get(cacheName); 308 if(object instanceof Map ) 309 { 310 Map cacheInstance = (Map )object; 311 synchronized(cacheInstance) 312 { 313 cacheInstance.clear(); 314 } 315 } 316 else 317 { 318 GeneralCacheAdministrator cacheInstance = (GeneralCacheAdministrator)object; 319 synchronized(cacheInstance) 320 { 321 cacheInstance.flushAll(); 322 } 323 } 324 caches.remove(cacheName); 325 eventListeners.remove(cacheName + "_cacheEntryEventListener"); 326 eventListeners.remove(cacheName + "_cacheMapAccessEventListener"); 327 328 logger.info("clearCache stop..."); 329 } 330 } 331 } 332 333 public static void clearCaches(String entity, String entityId, String [] cachesToSkip) throws Exception 334 { 335 long wait = 0; 336 while(RequestAnalyser.getRequestAnalyser().getNumberOfCurrentRequests() > 0) 337 { 338 if(wait == 3000) 340 { 341 logger.warn("The clearCache method waited over " + ((wait * 10) / 1000) + " seconds but there seems to be " + RequestAnalyser.getRequestAnalyser().getNumberOfCurrentRequests() + " requests blocking all the time. Continuing anyway."); 342 break; 344 } 345 346 Thread.sleep(10); 347 wait++; 348 } 349 350 logger.info("clearCaches start in " + CmsPropertyHandler.getContextRootPath()); 351 if(entity == null) 352 { 353 logger.info("Clearing the caches"); 354 synchronized(caches) 355 { 356 for (Iterator i = caches.entrySet().iterator(); i.hasNext(); ) 357 { 358 Map.Entry e = (Map.Entry ) i.next(); 359 logger.info("e:" + e.getKey()); 360 boolean skip = false; 361 if(cachesToSkip != null) 362 { 363 for(int index=0; index<cachesToSkip.length; index++) 364 { 365 if(e.getKey().equals(cachesToSkip[index])) 366 { 367 skip = true; 368 break; 369 } 370 } 371 } 372 373 if(!skip) 374 { 375 Object object = e.getValue(); 376 if(object instanceof Map ) 377 { 378 Map cacheInstance = (Map )e.getValue(); 379 synchronized(cacheInstance) 380 { 381 cacheInstance.clear(); 382 } 383 } 384 else 385 { 386 GeneralCacheAdministrator cacheInstance = (GeneralCacheAdministrator)e.getValue(); 387 synchronized(cacheInstance) 388 { 389 cacheInstance.flushAll(); 390 } 391 eventListeners.clear(); 392 } 393 logger.info("Cleared cache:" + e.getKey()); 394 395 i.remove(); 396 } 397 } 398 } 399 } 400 else 401 { 402 logger.info("Clearing some caches"); 403 logger.info("entity:" + entity); 404 405 synchronized(caches) 406 { 407 for (Iterator i = caches.entrySet().iterator(); i.hasNext(); ) 408 { 409 Map.Entry e = (Map.Entry ) i.next(); 410 logger.info("e:" + e.getKey()); 411 boolean clear = false; 412 boolean selectiveCacheUpdate = false; 413 String cacheName = e.getKey().toString(); 414 415 if(cacheName.equalsIgnoreCase("serviceDefinitionCache") && entity.indexOf("ServiceBinding") > 0) 416 { 417 clear = true; 418 } 419 if(cacheName.equalsIgnoreCase("qualifyerListCache") && (entity.indexOf("Qualifyer") > 0 || entity.indexOf("ServiceBinding") > 0)) 420 { 421 clear = true; 422 } 423 if(cacheName.equalsIgnoreCase("availableServiceBindingCache") && entity.indexOf("AvailableServiceBinding") > 0) 424 { 425 clear = true; 426 } 427 if(cacheName.equalsIgnoreCase("languageCache") && entity.indexOf("Language") > 0) 428 { 429 clear = true; 430 } 431 if(cacheName.equalsIgnoreCase("localeCache") && entity.indexOf("Language") > 0) 432 { 433 clear = true; 434 } 435 if((cacheName.equalsIgnoreCase("latestSiteNodeVersionCache") || cacheName.equalsIgnoreCase("pageCacheLatestSiteNodeVersions") || cacheName.equalsIgnoreCase("pageCacheSiteNodeTypeDefinition")) && entity.indexOf("SiteNode") > 0) 436 { 437 clear = true; 438 } 439 if((cacheName.equalsIgnoreCase("parentSiteNodeCache") || cacheName.equalsIgnoreCase("pageCacheParentSiteNodeCache")) && entity.indexOf("SiteNode") > 0) 440 { 441 clear = true; 442 } 443 if(cacheName.equalsIgnoreCase("NavigationCache") && (entity.indexOf("SiteNode") > 0 || entity.indexOf("Content") > 0)) 444 { 445 clear = true; 446 } 447 if(cacheName.equalsIgnoreCase("pagePathCache") && (entity.indexOf("SiteNode") > 0 || entity.indexOf("Content") > 0)) 448 { 449 clear = true; 450 } 451 if(cacheName.equalsIgnoreCase("componentEditorCache") && (entity.indexOf("SiteNode") > 0 || entity.indexOf("Content") > 0)) 452 { 453 clear = true; 454 } 455 if(cacheName.equalsIgnoreCase("masterLanguageCache") && (entity.indexOf("Repository") > 0 || entity.indexOf("Language") > 0)) 456 { 457 clear = true; 458 } 459 if(cacheName.equalsIgnoreCase("parentRepository") && entity.indexOf("Repository") > 0) 460 { 461 clear = true; 462 } 463 if(cacheName.equalsIgnoreCase("contentAttributeCache") && (entity.indexOf("ContentVersion") > -1 || entity.indexOf("AccessRight") > 0 || entity.indexOf("SystemUser") > 0 || entity.indexOf("Role") > 0 || entity.indexOf("Group") > 0)) 464 { 465 clear = true; 466 selectiveCacheUpdate = true; 467 } 468 if(cacheName.equalsIgnoreCase("contentVersionCache") && (entity.indexOf("Content") > -1 || entity.indexOf("AccessRight") > 0 || entity.indexOf("SystemUser") > 0 || entity.indexOf("Role") > 0 || entity.indexOf("Group") > 0)) 469 { 470 clear = true; 471 selectiveCacheUpdate = true; 472 } 473 if(cacheName.equalsIgnoreCase("boundSiteNodeCache") && (entity.indexOf("ServiceBinding") > 0 || entity.indexOf("Qualifyer") > 0 || entity.indexOf("SiteNodeVersion") > 0 || entity.indexOf("SiteNodeVersion") > 0 || entity.indexOf("SiteNode") > 0 || entity.indexOf("AccessRight") > 0 || entity.indexOf("SystemUser") > 0 || entity.indexOf("Role") > 0 || entity.indexOf("Group") > 0)) 474 { 475 clear = true; 476 } 477 if(cacheName.equalsIgnoreCase("boundContentCache") && (entity.indexOf("ServiceBinding") > 0 || entity.indexOf("Qualifyer") > 0 || entity.indexOf("SiteNodeVersion") > 0 || entity.indexOf("ContentVersion") > 0 || entity.indexOf("Content") > 0 || entity.indexOf("AccessRight") > 0 || entity.indexOf("SystemUser") > 0 || entity.indexOf("Role") > 0 || entity.indexOf("Group") > 0)) 478 { 479 clear = true; 480 } 481 if(cacheName.equalsIgnoreCase("pageCache") && entity.indexOf("Registry") == -1) 482 { 483 clear = true; 484 selectiveCacheUpdate = true; 485 } 486 if(cacheName.equalsIgnoreCase("componentCache") && entity.indexOf("Registry") == -1) 487 { 488 clear = true; 489 } 491 if(cacheName.equalsIgnoreCase("componentPropertyCache") && (entity.indexOf("ContentVersion") > -1 || entity.indexOf("AccessRight") > 0 || entity.indexOf("SystemUser") > 0 || entity.indexOf("Role") > 0 || entity.indexOf("Group") > 0)) 492 { 493 clear = true; 494 selectiveCacheUpdate = true; 495 } 496 if(cacheName.equalsIgnoreCase("includeCache")) 497 { 498 clear = true; 499 } 500 if(cacheName.equalsIgnoreCase("authorizationCache") && (entity.indexOf("AccessRight") > 0 || entity.indexOf("SystemUser") > 0 || entity.indexOf("Role") > 0 || entity.indexOf("Group") > 0 || entity.indexOf("Intercept") > 0)) 501 { 502 clear = true; 503 } 504 if(cacheName.equalsIgnoreCase("componentPaletteDivCache") && (entity.indexOf("AccessRight") > 0 || entity.indexOf("SystemUser") > 0 || entity.indexOf("Role") > 0 || entity.indexOf("Group") > 0)) 505 { 506 clear = true; 507 } 508 if(cacheName.equalsIgnoreCase("userCache") && (entity.indexOf("AccessRight") > 0 || entity.indexOf("SystemUser") > 0 || entity.indexOf("Role") > 0 || entity.indexOf("Group") > 0)) 509 { 510 clear = true; 511 } 512 if(cacheName.equalsIgnoreCase("principalCache") && (entity.indexOf("SystemUser") > 0 || entity.indexOf("Role") > 0 || entity.indexOf("Group") > 0)) 513 { 514 clear = true; 515 } 516 if((cacheName.equalsIgnoreCase("assetUrlCache") || cacheName.equalsIgnoreCase("assetThumbnailUrlCache")) && (entity.indexOf("DigitalAsset") > 0 || entity.indexOf("ContentVersion") > 0 || entity.indexOf("AccessRight") > 0 || entity.indexOf("SystemUser") > 0 || entity.indexOf("Role") > 0 || entity.indexOf("Group") > 0)) 517 { 518 clear = true; 519 } 520 if(cacheName.equalsIgnoreCase("sortedChildContentsCache") && (entity.indexOf("Content") > 0 || entity.indexOf("ContentVersion") > 0 || entity.indexOf("AccessRight") > 0 || entity.indexOf("SystemUser") > 0 || entity.indexOf("Role") > 0 || entity.indexOf("Group") > 0)) 521 { 522 clear = true; 523 } 524 if(cacheName.equalsIgnoreCase("workflowCache") && entity.indexOf("WorkflowDefinition") > 0) 525 { 526 clear = true; 527 } 528 if(cacheName.equalsIgnoreCase("rootSiteNodeCache") && entity.indexOf("SiteNode") > 0) 529 { 530 clear = true; 531 } 532 if(cacheName.equalsIgnoreCase("childSiteNodesCache") && entity.indexOf("SiteNode") > 0) 533 { 534 clear = true; 535 } 536 if(cacheName.equalsIgnoreCase("propertySetCache") && entity.indexOf("SiteNode") > 0) 537 { 538 clear = true; 539 } 540 if(cacheName.equalsIgnoreCase("groupVOListCache") && entity.indexOf("Group") > 0) 541 { 542 clear = true; 543 } 544 if(cacheName.equalsIgnoreCase("roleListCache") && entity.indexOf("Role") > 0) 545 { 546 clear = true; 547 } 548 if(cacheName.equalsIgnoreCase("groupPropertiesCache") && entity.indexOf("Group") > 0) 549 { 550 clear = true; 551 } 552 if(cacheName.equalsIgnoreCase("rolePropertiesCache") && entity.indexOf("Role") > 0) 553 { 554 clear = true; 555 } 556 if(cacheName.equalsIgnoreCase("principalPropertyValueCache") && (entity.indexOf("Group") > 0 || entity.indexOf("Role") > 0 || entity.indexOf("User") > 0)) 557 { 558 clear = true; 559 } 560 if(cacheName.equalsIgnoreCase("relatedCategoriesCache") && (entity.indexOf("Group") > 0 || entity.indexOf("Role") > 0 || entity.indexOf("User") > 0)) 561 { 562 clear = true; 563 } 564 if(cacheName.equalsIgnoreCase("redirectCache") && entity.indexOf("Redirect") > 0) 565 { 566 clear = true; 567 } 568 if(cacheName.equalsIgnoreCase("interceptorsCache") && entity.indexOf("Intercept") > 0) 569 { 570 clear = true; 571 } 572 if(cacheName.equalsIgnoreCase("interceptionPointCache") && entity.indexOf("Intercept") > 0) 573 { 574 clear = true; 575 } 576 if(cacheName.equalsIgnoreCase("siteNodeLanguageCache") && (entity.indexOf("Repository") > 0 || entity.indexOf("Language") > 0 || entity.indexOf("SiteNode") > 0)) 577 { 578 clear = true; 579 } 580 if(cacheName.equalsIgnoreCase("contentTypeDefinitionCache") && entity.indexOf("ContentTypeDefinition") > 0) 581 { 582 clear = true; 583 } 584 if(cacheName.equalsIgnoreCase("ServerNodeProperties")) 585 { 586 clear = true; 587 } 588 589 logger.info("clear:" + clear); 590 591 if(clear) 592 { 593 logger.info("clearing:" + e.getKey()); 594 Object object = e.getValue(); 595 596 if(object instanceof Map ) 597 { 598 Map cacheInstance = (Map )e.getValue(); 599 synchronized(cacheInstance) 600 { 601 cacheInstance.clear(); 602 } 603 } 604 else 605 { 606 String useSelectivePageCacheUpdateString = CmsPropertyHandler.getUseSelectivePageCacheUpdate(); 607 boolean useSelectivePageCacheUpdate = false; 608 if(useSelectivePageCacheUpdateString != null && useSelectivePageCacheUpdateString.equalsIgnoreCase("true")) 609 useSelectivePageCacheUpdate = true; 610 611 GeneralCacheAdministrator cacheInstance = (GeneralCacheAdministrator)e.getValue(); 612 synchronized(cacheInstance) 613 { 614 if(selectiveCacheUpdate && entity.indexOf("SiteNode") > 0) 615 { 616 cacheInstance.flushAll(); 617 eventListeners.remove(cacheName + "_cacheEntryEventListener"); 618 eventListeners.remove(cacheName + "_cacheMapAccessEventListener"); 619 logger.info("clearing:" + e.getKey()); 620 } 621 else if(selectiveCacheUpdate && entity.indexOf("ContentVersion") > 0 && useSelectivePageCacheUpdate) 622 { 623 logger.info("Getting eventListeners..."); 624 Object cacheEntryEventListener = eventListeners.get(e.getKey() + "_cacheEntryEventListener"); 625 Object cacheMapAccessEventListener = eventListeners.get(e.getKey() + "_cacheMapAccessEventListener"); 626 627 logger.info("Before flushGroup..."); 628 629 cacheInstance.flushGroup("contentVersion_" + entityId); 630 cacheInstance.flushGroup("selectiveCacheUpdateNonApplicable"); 631 logger.info("clearing " + e.getKey() + " with group " + "contentVersion_" + entityId); 632 634 try 635 { 636 logger.info("Before contentVersionVO..."); 637 Integer contentId = ContentVersionController.getContentVersionController().getContentIdForContentVersion(new Integer (entityId)); 638 if(contentId != null) 639 { 640 logger.info("Before flushGroup2..."); 641 cacheInstance.flushGroup("content_" + contentId); 642 logger.info("After flushGroup2..."); 643 } 645 656 } 657 catch(SystemException se) 658 { 659 logger.info("Missing content version: " + se.getMessage()); 660 } 661 662 } 663 else if(selectiveCacheUpdate && (entity.indexOf("Content") > 0 && entity.indexOf("ContentTypeDefinition") == -1) && useSelectivePageCacheUpdate) 664 { 665 cacheInstance.flushGroup("content_" + entityId); 666 cacheInstance.flushGroup("selectiveCacheUpdateNonApplicable"); 667 logger.info("clearing " + e.getKey() + " with group " + "content_" + entityId); 668 } 670 else 671 { 672 cacheInstance.flushAll(); 673 eventListeners.remove(cacheName + "_cacheEntryEventListener"); 674 eventListeners.remove(cacheName + "_cacheMapAccessEventListener"); 675 logger.info("clearing:" + e.getKey()); 676 } 677 } 678 } 679 680 logger.info("Cleared cache:" + e.getKey()); 681 682 if(!selectiveCacheUpdate) 683 i.remove(); 684 685 } 686 else 687 { 688 logger.info("Did not clear " + e.getKey()); 689 } 690 } 691 } 692 } 693 694 logger.info("clearCaches stop"); 695 } 696 697 private static void printThreads() 698 { 699 ThreadGroup tg = Thread.currentThread().getThreadGroup(); 700 int n = tg.activeCount(); 701 logger.warn("Number of active threads: " + n); 702 Thread [] threadArray = new Thread [n]; 703 n = tg.enumerate(threadArray, false); 704 for (int i=0; i<n; i++) 705 { 706 String currentThreadId = "" + threadArray[i].getId(); 707 Thread t = threadArray[i]; 708 Map stacks = t.getAllStackTraces(); 709 710 Iterator stacksIterator = stacks.values().iterator(); 711 while(stacksIterator.hasNext()) 712 { 713 StackTraceElement [] el = (StackTraceElement [])stacksIterator.next(); 714 715 String stackString = ""; 716 if (el != null && el.length != 0) 717 { 718 for (int j = 0; j < el.length; j++) 719 { 720 StackTraceElement frame = el[j]; 721 if (frame == null) 722 stackString += " null stack frame" + "<br/>"; 723 else 724 stackString += " null stack frame" + frame.toString() + "<br/>"; 725 } 726 logger.warn("\n\nThreads:\n\n " + stackString); 727 } 728 } 729 } 730 } 731 732 public static synchronized void clearCastorCaches() throws Exception 733 { 734 logger.info("Emptying the Castor Caches"); 735 736 while(RequestAnalyser.getRequestAnalyser().getNumberOfCurrentRequests() > 0) 737 { 738 Thread.sleep(10); 740 } 741 742 Database db = CastorDatabaseService.getDatabase(); 743 745 try 746 { 747 749 clearCache(db, SmallContentImpl.class); 750 clearCache(db, MediumContentImpl.class); 751 clearCache(db, ContentImpl.class); 752 clearCache(db, ContentRelationImpl.class); 753 clearCache(db, ContentVersionImpl.class); 754 clearCache(db, DigitalAssetImpl.class); 755 clearCache(db, SmallAvailableServiceBindingImpl.class); 756 clearCache(db, AvailableServiceBindingImpl.class); 757 clearCache(db, ContentTypeDefinitionImpl.class); 758 clearCache(db, LanguageImpl.class); 759 clearCache(db, RepositoryImpl.class); 760 clearCache(db, RepositoryLanguageImpl.class); 761 clearCache(db, RoleImpl.class); 762 clearCache(db, GroupImpl.class); 763 clearCache(db, ServiceDefinitionImpl.class); 764 clearCache(db, SiteNodeTypeDefinitionImpl.class); 765 clearCache(db, SystemUserImpl.class); 766 clearCache(db, QualifyerImpl.class); 767 clearCache(db, ServiceBindingImpl.class); 768 clearCache(db, SmallSiteNodeImpl.class); 769 clearCache(db, SiteNodeImpl.class); 770 clearCache(db, SiteNodeVersionImpl.class); 771 clearCache(db, PublicationImpl.class); 772 clearCache(db, ActionImpl.class); 774 clearCache(db, ActionDefinitionImpl.class); 775 clearCache(db, ActorImpl.class); 776 clearCache(db, ConsequenceImpl.class); 777 clearCache(db, ConsequenceDefinitionImpl.class); 778 clearCache(db, EventImpl.class); 779 clearCache(db, WorkflowImpl.class); 780 clearCache(db, WorkflowDefinitionImpl.class); 781 clearCache(db, CategoryImpl.class); 782 clearCache(db, ContentCategoryImpl.class); 783 clearCache(db, RegistryImpl.class); 784 clearCache(db, RedirectImpl.class); 785 786 clearCache(db, InterceptionPointImpl.class); 787 clearCache(db, InterceptorImpl.class); 788 clearCache(db, AccessRightImpl.class); 789 790 clearCache(db, RolePropertiesImpl.class); 791 clearCache(db, UserPropertiesImpl.class); 792 clearCache(db, GroupPropertiesImpl.class); 793 clearCache(db, UserContentTypeDefinitionImpl.class); 794 clearCache(db, RoleContentTypeDefinitionImpl.class); 795 clearCache(db, GroupContentTypeDefinitionImpl.class); 796 797 clearCache(db, PropertiesCategoryImpl.class); 798 799 clearCache(db, ServerNodeImpl.class); 800 801 803 logger.info("Emptied the Castor Caches"); 804 } 805 catch(Exception e) 806 { 807 logger.error("Exception when tried empty the Castor Caches"); 808 rollbackTransaction(db); 809 } 810 finally 811 { 812 db.close(); 813 } 815 } 816 817 818 public static synchronized void clearCache(Class type, Object [] ids) throws Exception 819 { 820 long wait = 0; 821 while(RequestAnalyser.getRequestAnalyser().getNumberOfCurrentRequests() > 0) 822 { 823 logger.warn("Number of requests: " + RequestAnalyser.getRequestAnalyser().getNumberOfCurrentRequests() + " was more than 0 - lets wait a bit."); 824 if(wait == 3000) 825 { 826 logger.warn("The clearCache method waited over " + ((wait * 10) / 1000) + " seconds but there seems to be " + RequestAnalyser.getRequestAnalyser().getNumberOfCurrentRequests() + " requests blocking all the time. Continuing anyway."); 827 break; 829 } 830 831 Thread.sleep(10); 832 wait++; 833 } 834 835 Database db = CastorDatabaseService.getDatabase(); 836 837 try 838 { 839 CacheManager manager = db.getCacheManager(); 840 manager.expireCache(type, ids); 841 844 if(type.getName().equalsIgnoreCase(SmallContentImpl.class.getName()) || 845 type.getName().equalsIgnoreCase(MediumContentImpl.class.getName()) || 846 type.getName().equalsIgnoreCase(ContentImpl.class.getName()) || 847 type.getName().equalsIgnoreCase(SmallSiteNodeImpl.class.getName()) || 848 type.getName().equalsIgnoreCase(SiteNodeImpl.class.getName())) 849 { 850 expireDateTime = null; 851 publishDateTime = null; 852 } 853 } 854 catch(Exception e) 855 { 856 e.printStackTrace(); 857 } 858 finally 859 { 860 db.close(); 861 } 862 } 863 864 865 public static void clearCache(Class type, Object [] ids, Database db) throws Exception 866 { 867 long wait = 0; 868 while(RequestAnalyser.getRequestAnalyser().getNumberOfCurrentRequests() > 0) 869 { 870 if(wait == 3000) 871 { 872 logger.warn("The clearCache method waited over " + ((wait * 10) / 1000) + " seconds but there seems to be " + RequestAnalyser.getRequestAnalyser().getNumberOfCurrentRequests() + " requests blocking all the time. Continuing anyway."); 873 break; 875 } 876 877 Thread.sleep(10); 878 wait++; 879 } 880 881 CacheManager manager = db.getCacheManager(); 882 manager.expireCache(type, ids); 883 886 if(type.getName().equalsIgnoreCase(SmallContentImpl.class.getName()) || 887 type.getName().equalsIgnoreCase(MediumContentImpl.class.getName()) || 888 type.getName().equalsIgnoreCase(ContentImpl.class.getName()) || 889 type.getName().equalsIgnoreCase(SmallSiteNodeImpl.class.getName()) || 890 type.getName().equalsIgnoreCase(SiteNodeImpl.class.getName())) 891 { 892 expireDateTime = null; 893 publishDateTime = null; 894 } 895 } 896 897 916 917 private static synchronized void clearCache(Database db, Class c) throws Exception 918 { 919 Class [] types = {c}; 920 Class [] ids = {null}; 921 CacheManager manager = db.getCacheManager(); 922 manager.expireCache(types); 923 925 if(c.getName().equalsIgnoreCase(SmallContentImpl.class.getName()) || 926 c.getName().equalsIgnoreCase(MediumContentImpl.class.getName()) || 927 c.getName().equalsIgnoreCase(ContentImpl.class.getName()) || 928 c.getName().equalsIgnoreCase(SmallSiteNodeImpl.class.getName()) || 929 c.getName().equalsIgnoreCase(SiteNodeImpl.class.getName())) 930 { 931 expireDateTime = null; 932 publishDateTime = null; 933 } 934 } 935 936 937 public void run() 938 { 939 while(this.continueRunning && expireCacheAutomatically) 940 { 941 logger.info("Clearing caches"); 942 try 943 { 944 clearCastorCaches(); 945 } 946 catch(Exception e) 947 { 948 logger.error("Error clearing cache in expireCacheAutomatically thread:" + e.getMessage(), e); 949 } 950 logger.info("Castor cache cleared"); 951 try 952 { 953 clearCaches(null, null, null); 954 } 955 catch(Exception e) 956 { 957 logger.error("Error clearing other caches in expireCacheAutomatically thread:" + e.getMessage(), e); 958 } 959 logger.info("All other caches cleared"); 960 961 try 962 { 963 sleep(cacheExpireInterval); 964 } 965 catch (InterruptedException e){} 966 } 967 } 968 969 public static synchronized void cacheCentralCastorCaches() throws Exception 970 { 971 Database db = CastorDatabaseService.getDatabase(); 972 973 DatabaseWrapper dbWrapper = new DatabaseWrapper(db); 974 975 try 976 { 977 978 beginTransaction(db); 979 980 String siteNodesToRecacheOnPublishing = CmsPropertyHandler.getSiteNodesToRecacheOnPublishing(); 981 String recachePublishingMethod = CmsPropertyHandler.getRecachePublishingMethod(); 982 logger.info("siteNodesToRecacheOnPublishing:" + siteNodesToRecacheOnPublishing); 983 if(siteNodesToRecacheOnPublishing != null && !siteNodesToRecacheOnPublishing.equals("") && !siteNodesToRecacheOnPublishing.equals("siteNodesToRecacheOnPublishing")) 984 { 985 String [] siteNodeIdArray = siteNodesToRecacheOnPublishing.split(","); 986 for(int i=0; i<siteNodeIdArray.length; i++) 987 { 988 Integer siteNodeId = new Integer (siteNodeIdArray[i]); 989 logger.info("siteNodeId to recache:" + siteNodeId); 990 if(recachePublishingMethod != null && recachePublishingMethod.equalsIgnoreCase("contentCentric")) 991 new ContentCentricCachePopulator().recache(dbWrapper, siteNodeId); 992 else if(recachePublishingMethod != null && recachePublishingMethod.equalsIgnoreCase("requestCentric")) 993 new RequestCentricCachePopulator().recache(dbWrapper, siteNodeId); 994 else if(recachePublishingMethod != null && recachePublishingMethod.equalsIgnoreCase("requestAndMetaInfoCentric")) 995 new RequestAndMetaInfoCentricCachePopulator().recache(dbWrapper, siteNodeId); 996 else 997 logger.warn("No recaching was made during publishing - set the parameter recachePublishingMethod to 'contentCentric' or 'requestCentric' to recache."); 998 } 999 } 1000 1001 commitTransaction(db); 1002 } 1003 catch(Exception e) 1004 { 1005 logger.error("An error occurred when we tried to rebuild the castor cache:" + e.getMessage(), e); 1006 rollbackTransaction(db); 1007 } 1008 finally 1009 { 1010 closeDatabase(db); 1011 } 1012 } 1013 1014 1015 public void stopThread() 1016 { 1017 this.continueRunning = false; 1018 } 1019 1020 public boolean getExpireCacheAutomatically() 1021 { 1022 return expireCacheAutomatically; 1023 } 1024 1025 public void setExpireCacheAutomatically(boolean expireCacheAutomatically) 1026 { 1027 this.expireCacheAutomatically = expireCacheAutomatically; 1028 } 1029 1030 public static Map getCaches() 1031 { 1032 return caches; 1033 } 1034 1035 public static Map getEventListeners() 1036 { 1037 return eventListeners; 1038 } 1039 1040 public static GeneralCacheAdministrator getGeneralCache() 1041 { 1042 return generalCache; 1043 } 1044 1045 public static void evictWaitingCache() throws Exception 1046 { 1047 String operatingMode = CmsPropertyHandler.getOperatingMode(); 1048 synchronized(RequestAnalyser.getRequestAnalyser()) 1049 { 1050 if(RequestAnalyser.getRequestAnalyser().getBlockRequests()) 1051 { 1052 logger.info("evictWaitingCache allready in progress - returning to avoid conflict"); 1053 return; 1054 } 1055 1056 RequestAnalyser.getRequestAnalyser().setBlockRequests(true); 1057 } 1058 1059 logger.info("evictWaitingCache starting"); 1060 logger.info("blocking"); 1061 1062 WorkingPublicationThread wpt = new WorkingPublicationThread(); 1063 1064 List localNotifications = new ArrayList (); 1065 1066 boolean startedThread = false; 1067 logger.info("before notifications"); 1068 synchronized(notifications) 1069 { 1070 localNotifications.addAll(notifications); 1071 notifications.clear(); 1072 } 1073 1074 Iterator i = localNotifications.iterator(); 1075 while(i.hasNext()) 1076 { 1077 CacheEvictionBean cacheEvictionBean = (CacheEvictionBean)i.next(); 1078 String className = cacheEvictionBean.getClassName(); 1079 String objectId = cacheEvictionBean.getObjectId(); 1080 String objectName = cacheEvictionBean.getObjectName(); 1081 String typeId = cacheEvictionBean.getTypeId(); 1082 1083 wpt.getCacheEvictionBeans().add(cacheEvictionBean); 1084 1085 try 1086 { 1087 if(className != null && className.equalsIgnoreCase("ServerNodeProperties")) 1089 { 1090 try 1091 { 1092 logger.info("clearing InfoGlueAuthenticationFilter"); 1093 clearServerNodeProperty(); 1094 logger.info("cleared InfoGlueAuthenticationFilter"); 1095 InfoGlueAuthenticationFilter.initializeProperties(); 1096 logger.info("initialized InfoGlueAuthenticationFilter"); 1097 } 1098 catch (SystemException e1) 1099 { 1100 logger.warn("Could not refresh authentication filter:" + e1.getMessage(), e1); 1101 } 1102 } 1103 1104 if(CmsPropertyHandler.getOperatingMode() != null && !CmsPropertyHandler.getOperatingMode().equalsIgnoreCase("3") && className != null && className.equalsIgnoreCase("PortletRegistry")) 1105 { 1106 logger.info("clearing portletRegistry"); 1107 clearPortlets(); 1108 logger.info("cleared portletRegistry"); 1109 } 1110 1111 1112 if(CmsPropertyHandler.getOperatingMode() != null && CmsPropertyHandler.getOperatingMode().equalsIgnoreCase("3")) { 1115 logger.info("Starting publication thread..."); 1116 PublicationThread pt = new PublicationThread(); 1117 pt.setPriority(Thread.MIN_PRIORITY); 1118 pt.start(); 1119 startedThread = true; 1120 logger.info("Done starting publication thread..."); 1121 } 1122 } 1123 catch(Exception e) 1124 { 1125 logger.error("Cache eviction reported an error:" + e.getMessage(), e); 1126 } 1127 1128 logger.info("Cache evicted.."); 1129 1130 i.remove(); 1131 } 1132 1133 if(CmsPropertyHandler.getOperatingMode() != null && !CmsPropertyHandler.getOperatingMode().equalsIgnoreCase("3")) 1134 { 1135 logger.info("Starting the work method"); 1136 wpt.work(); 1139 startedThread = true; 1140 logger.info("Done starting working publication thread..."); 1141 } 1142 1143 if(!startedThread) 1144 RequestAnalyser.getRequestAnalyser().setBlockRequests(false); 1145 1146 logger.info("evictWaitingCache stop"); 1147 } 1148 1149 public static void clearPortlets() 1150 { 1151 String [] svcs = 1153 { 1154 "org.apache.pluto.portalImpl.services.portletdefinitionregistry.PortletDefinitionRegistryService", 1155 "org.apache.pluto.portalImpl.services.portletentityregistry.PortletEntityRegistryService" 1156 }; 1157 1158 int len = svcs.length; 1159 for (int i = 0; i < len; i++) 1160 { 1161 try 1162 { 1163 ServiceManager.hotInit(ServletConfigContainer.getContainer().getServletConfig(), svcs[i]); 1164 } 1165 catch (Throwable e) 1166 { 1167 String svc = svcs[i].substring(svcs[i].lastIndexOf('.') + 1); 1168 String msg = "Initialization of " + svc + " service for hot deployment failed!"; 1169 System.out.println(msg); 1170 break; 1171 } 1172 1173 try 1174 { 1175 ServiceManager.postHotInit(ServletConfigContainer.getContainer().getServletConfig(), svcs[i]); 1176 } 1177 catch (Throwable e) 1178 { 1179 String svc = svcs[i].substring(svcs[i].lastIndexOf('.') + 1); 1180 String msg = "Post initialization of " + svc + " service for hot deployment failed!"; 1181 System.out.println(msg); 1182 break; 1183 } 1184 } 1185 1186 try 1187 { 1188 PortletEntityRegistry.load(); 1189 } 1190 catch (IOException e) 1191 { 1192 e.printStackTrace(); 1193 } 1194 1195 } 1196 1197 1198 1208 1209 public static String getPageCacheKey(HttpSession session, HttpServletRequest request, Integer siteNodeId, Integer languageId, Integer contentId, String userAgent, String queryString, String extra) 1210 { 1211 String originalRequestURL = request.getParameter("originalRequestURL"); 1212 if(originalRequestURL == null || originalRequestURL.length() == 0) 1213 originalRequestURL = request.getRequestURL().toString(); 1214 1215 String pageKey = null; 1216 String pageKeyProperty = CmsPropertyHandler.getPageKey(); 1217 if(pageKeyProperty != null && pageKeyProperty.length() > 0) 1218 { 1219 pageKey = pageKeyProperty; 1220 pageKey = pageKey.replaceAll("\\$siteNodeId", "" + siteNodeId); 1221 pageKey = pageKey.replaceAll("\\$languageId", "" + languageId); 1222 pageKey = pageKey.replaceAll("\\$contentId", "" + contentId); 1223 pageKey = pageKey.replaceAll("\\$useragent", "" + userAgent); 1224 pageKey = pageKey.replaceAll("\\$queryString", "" + queryString); 1225 1226 int sessionAttributeStartIndex = pageKey.indexOf("$session."); 1227 while(sessionAttributeStartIndex > -1) 1228 { 1229 int sessionAttributeEndIndex = pageKey.indexOf("_", sessionAttributeStartIndex); 1230 String sessionAttribute = null; 1231 if(sessionAttributeEndIndex > -1) 1232 sessionAttribute = pageKey.substring(sessionAttributeStartIndex + 9, sessionAttributeEndIndex); 1233 else 1234 sessionAttribute = pageKey.substring(sessionAttributeStartIndex + 9); 1235 1236 pageKey = pageKey.replaceAll("\\$session." + sessionAttribute, "" + session.getAttribute(sessionAttribute)); 1237 1238 sessionAttributeStartIndex = pageKey.indexOf("$session."); 1239 } 1240 1241 int cookieAttributeStartIndex = pageKey.indexOf("$cookie."); 1242 while(cookieAttributeStartIndex > -1) 1243 { 1244 int cookieAttributeEndIndex = pageKey.indexOf("_", cookieAttributeStartIndex); 1245 String cookieAttribute = null; 1246 if(cookieAttributeEndIndex > -1) 1247 cookieAttribute = pageKey.substring(cookieAttributeStartIndex + 8, cookieAttributeEndIndex); 1248 else 1249 cookieAttribute = pageKey.substring(cookieAttributeStartIndex + 8); 1250 1251 HttpHelper httpHelper = new HttpHelper(); 1252 pageKey = pageKey.replaceAll("\\$cookie." + cookieAttribute, "" + httpHelper.getCookie(request, cookieAttribute)); 1253 1254 cookieAttributeStartIndex = pageKey.indexOf("$cookie."); 1255 } 1256 1257 } 1258 else 1259 pageKey = "" + siteNodeId + "_" + languageId + "_" + contentId + "_" + userAgent + "_" + queryString; 1260 1261 return originalRequestURL + "_" + pageKey + extra; 1262 } 1263 1264 1265 1268 1275 1276 1279 1280 public static void beginTransaction(Database db) throws SystemException 1281 { 1282 try 1283 { 1284 db.begin(); 1285 } 1286 catch(Exception e) 1287 { 1288 logger.error("An error occurred when we tried to begin an transaction. Reason:" + e.getMessage()); 1289 throw new SystemException("An error occurred when we tried to begin an transaction. Reason:" + e.getMessage(), e); 1290 } 1291 } 1292 1293 1296 1297 private static void commitTransaction(Database db) throws SystemException 1298 { 1299 try 1300 { 1301 if (db.isActive()) 1302 { 1303 db.commit(); 1304 } 1305 } 1306 catch(Exception e) 1307 { 1308 logger.error("An error occurred when we tried to commit an transaction. Reason:" + e.getMessage()); 1309 throw new SystemException("An error occurred when we tried to commit an transaction. Reason:" + e.getMessage(), e); 1310 } 1311 } 1312 1313 1314 1317 1318 public static void rollbackTransaction(Database db) 1319 { 1320 try 1321 { 1322 if (db.isActive()) 1323 { 1324 db.rollback(); 1325 } 1326 } 1327 catch(Exception e) 1328 { 1329 logger.error("An error occurred when we tried to rollback an transaction. Reason:" + e.getMessage()); 1330 } 1331 } 1332 1333 1336 1337 public static void closeDatabase(Database db) 1338 { 1339 try 1340 { 1341 db.close(); 1342 } 1343 catch(Exception e) 1344 { 1345 logger.error("An error occurred when we tried to close a database. Reason:" + e.getMessage(), e); 1346 } 1347 } 1348} 1349 1350 | Popular Tags |