1 40 41 package org.jahia.services.containers; 42 43 import java.util.*; 44 45 import javax.servlet.http.HttpSession ; 46 47 import org.apache.log4j.Logger; 48 import org.jahia.data.containers.ContainerFilters; 49 import org.jahia.data.containers.ContainerSorterBean; 50 import org.jahia.data.containers.ContainerSorterInterface; 51 import org.jahia.data.containers.ContainersChangeEventListener; 52 import org.jahia.data.containers.JahiaContainer; 53 import org.jahia.data.containers.JahiaContainerList; 54 import org.jahia.data.containers.JahiaContainerListPagination; 55 import org.jahia.data.fields.JahiaField; 56 import org.jahia.data.search.JahiaSearchResult; 57 import org.jahia.exceptions.JahiaException; 58 import org.jahia.params.ParamBean; 59 import org.jahia.registries.JahiaListenersRegistry; 60 import org.jahia.registries.ServicesRegistry; 61 import org.jahia.services.acl.JahiaACLManagerService; 62 import org.jahia.services.acl.JahiaBaseACL; 63 import org.jahia.services.cache.Cache; 64 import org.jahia.services.cache.CacheFactory; 65 import org.jahia.services.search.ChainedJahiaSearcher; 66 import org.jahia.services.search.ContainerSearcher; 67 import org.jahia.services.search.JahiaSearcher; 68 import org.jahia.services.usermanager.JahiaUser; 69 import org.jahia.services.version.EntryLoadRequest; 70 71 72 78 79 public class ContainerFactory { 80 81 private static Logger logger = Logger.getLogger (ContainerFactory.class); 82 83 private static ContainerFactory instance = null; 84 85 public static final String PRELOADED_CTNR_ACLID_BY_CTNRLIST_CACHE = "PreloadedCtnrACLByCtnrListCache"; 87 private static Cache preloadedCtnrACLIDByCtnrListCache; 88 89 private JahiaContainerUtilsDB c_utils; 90 91 95 private ContainerFactory () { 96 97 c_utils = JahiaContainerUtilsDB.getInstance(); 98 99 try { 100 preloadedCtnrACLIDByCtnrListCache = CacheFactory 101 .createCache(PRELOADED_CTNR_ACLID_BY_CTNRLIST_CACHE); 102 } catch ( JahiaException je ){ 103 logger.debug("Error creating cache ",je); 104 } 105 } 106 107 public static synchronized ContainerFactory getInstance () { 108 if (instance == null) { 109 instance = new ContainerFactory (); 110 } 111 return instance; 112 } 113 114 126 public void fullyLoadContainer (JahiaContainer container, int loadFlag, 127 ParamBean jParams, EntryLoadRequest loadRequest, 128 Hashtable cachedFieldsFromContainers, 129 Hashtable cachedContainersFromContainerLists, 130 Hashtable cachedContainerListsFromContainers) 131 throws JahiaException { 132 133 if (container == null) { 134 return; 135 } 136 137 if (!container.isFieldsLoaded()) { 138 synchronized (container) { 139 if (!container.isFieldsLoaded()) { 140 container.clearFields(); 141 Vector fieldIDs = null; 142 if (cachedFieldsFromContainers != null) { 143 fieldIDs = (Vector) cachedFieldsFromContainers 144 .get(new Integer (container.getID())); 145 } 146 if (fieldIDs == null) { 148 fieldIDs = ServicesRegistry.getInstance() 149 .getJahiaContainersService() 150 .getFieldIDsInContainer(container.getID(), 151 loadRequest); 152 } 153 for (int i = 0; i < fieldIDs.size(); i++) { 154 int fieldID = ((Integer ) fieldIDs.elementAt(i)) 155 .intValue(); 156 JahiaField aField = ServicesRegistry.getInstance() 157 .getJahiaFieldService().loadField(fieldID, 158 loadFlag, jParams, loadRequest); 159 if (aField != null) { 160 container.addField(aField); 161 } 162 } 163 container.setFieldsLoaded(true); 164 } 165 } 166 } 167 168 if (!container.isContainerListsLoaded()) { 169 synchronized (container) { 170 if (!container.isContainerListsLoaded()) { 171 container.clearContainerLists(); 172 JahiaContainersService ctnServ = ServicesRegistry 173 .getInstance().getJahiaContainersService(); 174 175 Vector listIDs = null; 179 if (cachedContainerListsFromContainers != null) { 180 listIDs = (Vector) cachedContainerListsFromContainers 181 .get(new Integer (container.getID())); 182 } 183 if (listIDs == null) { 184 listIDs = JahiaContainerUtilsDB.getInstance() 185 .getContainerSubContainerListIDs( 186 container.getID(), loadRequest); 187 } 188 int size = listIDs.size(); 189 Integer listID = null; 190 for (int i = 0; i < size; i++) { 191 listID = (Integer ) listIDs.get(i); 192 JahiaContainerList cList = ctnServ.loadContainerList( 193 listID.intValue(), loadFlag, jParams, 194 loadRequest, cachedFieldsFromContainers, 195 cachedContainersFromContainerLists, 196 cachedContainerListsFromContainers); 197 198 if (cList != null) { 199 container.addContainerList(cList); 200 } 201 } 202 container.setContainerListsLoaded(true); 203 } 204 } 205 } 206 } 207 208 220 public JahiaField loadContainerField (JahiaContainer container, int fieldDefID, int loadFlag, 221 ParamBean jParams, EntryLoadRequest loadRequest, 222 Map cachedFieldsAndDefsFromContainers) 223 throws JahiaException { 224 225 if (container == null) { 226 return null; 227 } 228 JahiaField aField = null; 229 230 Map fieldIDs = null; 231 if (cachedFieldsAndDefsFromContainers != null) { 232 fieldIDs = (Map) cachedFieldsAndDefsFromContainers.get(new Integer ( 233 container.getID())); 234 } 235 if (fieldIDs == null) { 237 fieldIDs = ServicesRegistry.getInstance() 238 .getJahiaContainersService().getFieldIDsAndDefsInContainer( 239 container.getID(), loadRequest); 240 cachedFieldsAndDefsFromContainers.put( 241 new Integer (container.getID()), fieldIDs); 242 } 243 Integer fieldID = (Integer ) fieldIDs.get(new Integer (fieldDefID)); 244 if (fieldID != null) { 245 aField = container.isFieldsLoaded() ? container.getField(fieldID 246 .intValue()) : ServicesRegistry.getInstance() 247 .getJahiaFieldService().loadField(fieldID.intValue(), 248 loadFlag, jParams, loadRequest); 249 } 250 251 return aField; 252 } 253 254 266 public JahiaContainerList fullyLoadContainerList (JahiaContainerList cList, int loadFlag, 267 ParamBean jParams, 268 EntryLoadRequest loadRequest, 269 Hashtable cachedFieldsFromContainers, 270 Hashtable cachedContainersFromContainerLists, 271 Hashtable cachedContainerListsFromContainers) 272 throws JahiaException { 273 if (cList == null) { 274 return null; 275 } 276 if (!cList.isContainersLoaded ()) { 277 cList.clearContainers(); 278 cList.setIsContainersLoaded (true); 279 if (jParams != null) { JahiaUser currentUser = jParams.getUser(); 282 if (currentUser != null) { 283 logger.debug("loadContainerList(): checking rights..."); 284 if (!cList.checkReadAccess(currentUser)) { 286 logger.debug("loadContainerList(): NO read rights! -> returning empty list"); 287 return cList; 288 } 289 logger.debug("loadContainerList(): read rights OK"); 290 } else { 291 throw new JahiaException("No user present !", 292 "No current user defined in the params in loadContainerList() method.", 293 JahiaException.USER_ERROR, JahiaException.ERROR_SEVERITY); 294 } 295 Vector ctnids = doContainerFilterSearchSort(jParams, loadRequest, 296 cList.getDefinition().getName(), cList, 297 cachedContainersFromContainerLists); 298 299 if (ctnids == null) { 300 ctnids = ServicesRegistry.getInstance().getJahiaContainersService() 301 .getctnidsInList(cList.getID(), loadRequest); 302 } 303 if (ctnids == null) { 304 ctnids = new Vector(); 305 } 306 loadContainerListWithContainers(cList, ctnids, loadFlag, 307 jParams, loadRequest, cachedFieldsFromContainers, 308 cachedContainersFromContainerLists, 309 cachedContainerListsFromContainers,currentUser); 310 } 311 } 312 313 return cList; 314 } 315 316 329 public JahiaContainerList fullyLoadContainerList (int ctnListID, int loadFlag, 330 ParamBean jParams, 331 EntryLoadRequest loadRequest, 332 Hashtable cachedFieldsFromContainers, 333 Hashtable cachedContainersFromContainerLists, 334 Hashtable cachedContainerListsFromContainers) 335 throws JahiaException { 336 JahiaContainerList cList = ServicesRegistry.getInstance ().getJahiaContainersService () 337 .loadContainerListInfo (ctnListID, loadRequest); 338 cList = fullyLoadContainerList(cList, loadFlag, jParams, loadRequest, 339 cachedFieldsFromContainers, cachedContainersFromContainerLists, 340 cachedContainerListsFromContainers); 341 342 if ( cList != null ){ 343 ContainerListFactoryProxy cListFactory = 344 new ContainerListFactoryProxy(loadFlag, 345 jParams, 346 loadRequest, 347 cachedFieldsFromContainers, 348 cachedContainersFromContainerLists, 349 cachedContainerListsFromContainers); 350 cList.setFactoryProxy(cListFactory); 351 } 352 return cList; 353 } 354 355 356 368 private Vector doContainerFilterSearchSort (ParamBean params, 369 EntryLoadRequest loadVersion, 370 String containerListName, 371 JahiaContainerList clist, 372 Hashtable cachedContainersFromContainerLists) 373 throws JahiaException { 374 375 if (params == null || containerListName == null || clist.getID() == -1) { 376 return null; 377 } 378 379 try { 380 381 BitSet resultBitSet = null; 382 BitSet filterBitSet = null; 383 JahiaSearcher cSearcher = null; 384 JahiaSearchResult searchResult = null; 385 ContainerFilters cFilters = null; 386 boolean resultHasChanged = false; 387 388 cSearcher = getCtnListSearcher (params, containerListName, clist.getID()); 390 if (cSearcher != null) { 391 searchResult = (JahiaSearchResult) cSearcher.getResult (); 392 } 393 if (searchResult != null) { 394 if (searchResult.bits () != null) { 395 resultBitSet = (BitSet) searchResult.bits ().clone (); 396 } 397 } 398 399 if ((searchResult == null) || 401 !(searchResult != null && searchResult.getHitCount () == 0)) { 402 cFilters = getCtnListFilters (params, containerListName, clist.getID()); 403 if (cFilters != null) { 404 if (cFilters.bits () != null) { 405 filterBitSet = (BitSet) cFilters.bits ().clone (); 406 } 407 } 408 } 409 410 HttpSession session = params.getSession (); 412 BitSet cachedResultBitSet = null; 413 if (session != null) { 414 cachedResultBitSet = 415 (BitSet) session.getAttribute (clist + 416 "_searchfiltering_result_bitset" + "_" + params.getEntryLoadRequest().toString()); 417 418 } 419 423 resultHasChanged = ((cSearcher != null) || 424 (cFilters != null && cFilters.getUpdateStatus ())); 425 426 if (resultHasChanged) { 427 if (resultBitSet != null) { 428 if (filterBitSet != null) { 429 resultBitSet.and (filterBitSet); 430 } 431 } else if (filterBitSet != null) { 432 resultBitSet = filterBitSet; 433 } 434 resultHasChanged = true; 435 } else { 436 resultBitSet = cachedResultBitSet; 437 } 438 439 if (session != null) { 440 session.setAttribute (clist + "_searchfiltering_result_bitset" + "_" + params.getEntryLoadRequest().toString(), 441 resultBitSet); 442 } 443 444 if (resultBitSet != null && resultBitSet.length () == 0) { 445 return (new Vector ()); 446 } 447 448 ContainerSorterInterface sorter = getContainerSorter (params, 450 containerListName, 451 clist, 452 resultHasChanged, 453 resultBitSet); 454 if (sorter != null && sorter.result () != null) { 455 return sorter.result (); 456 } else { 457 460 try { 461 Vector ctnIds = null; 462 463 468 469 if (resultBitSet == null) { 470 ctnIds = 471 ServicesRegistry.getInstance () 472 .getJahiaContainersService () 473 .getctnidsInList (clist.getID(), loadVersion); 474 475 return ctnIds; 476 } else { 477 ctnIds = ServicesRegistry.getInstance () 478 .getJahiaContainersService ().getCtnIds (true); 479 480 Vector v = new Vector (); 481 int size = ctnIds.size (); 482 for (int i = 0; i < size; i++) { 483 int ctnid = ((Integer ) ctnIds.elementAt (i)). 484 intValue (); 485 if (resultBitSet.get (ctnid)) { 486 v.add (ctnIds.elementAt (i)); 487 } 488 } 489 return v; 490 } 491 } catch (Throwable t) { 492 logger.warn (t); 493 } 494 } 495 496 } catch (Throwable t) { 497 logger.warn (t); 498 499 t.printStackTrace (); 500 } 501 return null; } 504 505 517 private JahiaSearcher getCtnListSearcher (ParamBean params, 518 String containerListName, 519 int clistID) 520 throws JahiaException { 521 522 JahiaSearcher cSearcher = (JahiaSearcher) params.getRequest () 523 .getAttribute (containerListName + 524 "_search_handler"); 525 526 537 544 545 if (cSearcher == null || cSearcher.getQuery() == null || "".equals(cSearcher.getQuery().trim())) { 546 cSearcher = new ContainerSearcher (clistID, "", 548 params.getEntryLoadRequest ()); 549 ((ContainerSearcher)cSearcher).setUpdateStatus(); 550 } else { 551 552 boolean doNewSearch = true; 553 554 JahiaSearcher customSearcher = null; 555 if ( cSearcher instanceof ContainerSearcher ){ 556 ContainerSearcher cs = (ContainerSearcher)cSearcher; 557 if (!cs.isSiteModeSearching ()) { 558 customSearcher = new ContainerSearcher (clistID, 559 cs.getContainerLevel (), 560 cs.getQuery (), 561 cs.getEntryLoadRequest ()); 562 } else { 563 customSearcher = cs; 564 } 565 } else if ( cSearcher instanceof ChainedJahiaSearcher ){ 566 JahiaSearcher[] ar = ((ChainedJahiaSearcher)cSearcher).getChain(); 567 ContainerSearcher cs = null; 568 for ( int i=0; i<ar.length; i++ ){ 569 cs = (ContainerSearcher)ar[i]; 570 if (!cs.isSiteModeSearching ()) { 571 customSearcher = new ContainerSearcher (clistID, 572 cs.getContainerLevel (), 573 cs.getQuery (), 574 cs.getEntryLoadRequest ()); 575 ar[i] = customSearcher; 576 } 577 } 578 customSearcher = cSearcher; 579 } 580 581 606 607 if (doNewSearch) { 608 613 customSearcher.search (customSearcher.getQuery (), params); 614 logger.debug ("Container Searcher launched new search"); 615 cSearcher = customSearcher; 616 617 } 618 } 619 620 629 return cSearcher; 630 } 631 632 644 private ContainerFilters getCtnListFilters (ParamBean params, 645 String containerListName, 646 int clistID) 647 throws JahiaException { 648 649 if (logger.isDebugEnabled()) 650 logger.debug ("Started for container list : " + 651 containerListName + "[" + clistID + "]"); 652 653 ContainerFilters cFilters = (ContainerFilters) params.getRequest () 654 .getAttribute (containerListName + 655 "_filter_handler"); 656 657 ContainerFilters cachedContainerFilters = null; 659 HttpSession session = params.getSession (); 660 if (session != null) { 661 cachedContainerFilters = 662 (ContainerFilters) session.getAttribute (clistID + "_" 663 + params.getPageID () + "_" + containerListName + 664 "_filter_handler" + "_" + params.getEntryLoadRequest().toString()); 665 } 666 667 if (cFilters == null || !cFilters.isQueryValid ()) { 668 669 logger.debug ("create fake filter"); 670 671 cFilters = new ContainerFilters (clistID, new Vector ()); 673 cFilters.setUpdateStatus(); 674 } else { 675 676 boolean doNewFiltering = true; 677 678 cFilters.setCtnListID (clistID); 680 686 687 688 if (cachedContainerFilters != null 689 && (cachedContainerFilters.getQuery () != null) 690 && 691 cachedContainerFilters.getQuery ().equals (cFilters.getQuery ())) { 692 long lastFilteringTime = cachedContainerFilters. 694 getLastFilteringTime (); 695 ContainersChangeEventListener listener = ( 696 ContainersChangeEventListener)JahiaListenersRegistry. 697 getInstance () 698 .getListener (ContainersChangeEventListener.class.getName ()); 699 if (listener != null) { 700 long lastCtnChangeTime = listener.getContainerLastChangeTime(); 701 if (lastCtnChangeTime <= lastFilteringTime) { 702 cFilters = cachedContainerFilters; 703 cFilters.resetUpdateStatus (); logger.debug ("Container Filters found in session with same query and ctnlList did not change -> no need to run filtering again."); 705 doNewFiltering = false; 706 } 707 } 708 } 709 710 711 if (doNewFiltering) { 712 cFilters.doFilter (); 713 logger.debug ("Container Filters launched new filtering"); 714 } 715 } 716 717 if (session != null && cFilters != null) { 719 session.setAttribute (clistID + "_" + params.getPageID () + "_" + 720 containerListName + "_filter_handler" + "_" + params.getEntryLoadRequest().toString(), cFilters); 721 } 722 return cFilters; 723 } 724 725 740 private ContainerSorterInterface getContainerSorter (ParamBean params, 741 String containerListName, 742 JahiaContainerList clist, 743 boolean resultHasChanged, 744 BitSet resultBitSet) 745 throws JahiaException { 746 ContainerSorterInterface sorter = (ContainerSorterInterface) params.getRequest () 747 .getAttribute (containerListName + 748 "_sort_handler"); 749 750 ContainerSorterInterface cachedSorter = null; 752 HttpSession session = params.getSession (); 753 if (session != null) { 754 cachedSorter = 755 (ContainerSorterInterface) session.getAttribute (clist + "_" 756 + params.getPageID () + "_" + containerListName + "_sort_handler" + "_" + params.getEntryLoadRequest().toString()); 757 } 758 759 if (sorter == null || !sorter.isValid ()) { 760 761 sorter = new ContainerSorterBean (clist.getID(), "", 763 params.getEntryLoadRequest ()); sorter.setUpdateStatus(); 765 } else { 766 767 logger.debug ("Found sort hanlder on field [" + 768 sorter.getSortingFieldName () + "]"); 769 770 boolean doNewSorting = true; 771 772 775 785 786 sorter.setCtnListID(clist.getID()); 787 788 if (cachedSorter != null 789 && !resultHasChanged 790 && cachedSorter.getEntryLoadRequest().toString().equals(sorter.getEntryLoadRequest().toString()) 791 && cachedSorter.isValid () 792 && cachedSorter.getSortingFieldName ().equals (sorter.getSortingFieldName ()) 793 && (cachedSorter.isAscOrdering () == sorter.isAscOrdering ()) 794 ) { 795 long lastSortingTime = cachedSorter.getLastSortingTime (); 797 ContainersChangeEventListener listener = ( 798 ContainersChangeEventListener)JahiaListenersRegistry. 799 getInstance () 800 .getListener (ContainersChangeEventListener.class.getName ()); 801 if (listener != null) { 802 long lastCtnChangeTime = listener.getContainerLastChangeTime(); 803 if (lastCtnChangeTime <= lastSortingTime) { 804 sorter = cachedSorter; 805 sorter.resetUpdateStatus (); logger.debug ("Container Sorter found in session with same sorting field and ctnlList did not change -> no need to run sorting again."); 807 doNewSorting = false; 808 } 809 } 810 } 811 812 if (doNewSorting) { 813 sorter.doSort (resultBitSet); 814 logger.debug ("Container Sorter launched new sort"); 815 } 816 } 817 818 if (session != null && sorter != null) { 820 session.setAttribute (clist + "_" + params.getPageID () + "_" 821 + containerListName + "_sort_handler" + "_" + params.getEntryLoadRequest().toString(), sorter); 822 } 823 return sorter; 824 } 825 826 842 protected void loadContainerListWithContainers ( 843 JahiaContainerList theContainerList, 844 Vector ctnids, 845 int loadFlag, 846 ParamBean jParams, 847 EntryLoadRequest loadVersion, 848 Hashtable cachedFieldsInContainer, 849 Hashtable cachedContainersFromContainerLists, 850 Hashtable cachedContainerListsFromContainers, 851 JahiaUser currentUser) 852 throws JahiaException { 853 854 if (theContainerList == null) { 855 return; 856 } 857 858 if (jParams != null) { 861 Map acls = new Hashtable(); 863 if (ctnids.size () > 0) { 864 865 JahiaACLManagerService.getInstance() 866 .preloadContainerACLsByPage(theContainerList.getPageID()); 867 868 Integer listID = new Integer (theContainerList.getID()); 871 if ( (theContainerList.getID() > 0) && 872 !ContainerFactory.preloadedCtnrACLIDByCtnrListCache 873 .containsKey(listID) ){ 874 acls = c_utils.db_get_all_containers_aclid(theContainerList.getID()); 875 if ( acls != null ){ 876 ContainerFactory.preloadedCtnrACLIDByCtnrListCache.put(listID, acls); 877 } 878 } else { 879 acls = (Hashtable)ContainerFactory.preloadedCtnrACLIDByCtnrListCache 880 .get(listID); 881 } 882 if ( acls == null ){ 883 acls = new Hashtable(); 884 } 885 Vector v = new Vector (); 886 int size = ctnids.size (); 887 Integer ctnID = null; 888 Integer aclID = null; 889 for (int i = 0; i < size; i++) { 890 try { 891 ctnID = (Integer ) ctnids.get (i); 892 aclID = (Integer ) acls.get (ctnID); 893 if ( aclID == null ){ 894 aclID = new Integer (c_utils.getContainerACLID(ctnID.intValue())); 895 } 896 JahiaBaseACL acl = new JahiaBaseACL (aclID.intValue()); 897 if (acl != null && 898 acl.getPermission (currentUser, 899 JahiaBaseACL.READ_RIGHTS)) { 900 v.add (ctnID); 901 } 902 } catch (Throwable t) { 903 logger.error("Exception when loading container list", t); 904 } 905 } 906 ctnids = v; 907 } 908 } 909 910 913 Vector v = new Vector(); 914 JahiaContainer thisContainer = null; 915 List listOfContainer = new ArrayList(ctnids.size()); 916 final JahiaContainersService jahiaContainersService = ServicesRegistry.getInstance().getJahiaContainersService(); 917 for (int i = 0; i < ctnids.size(); i++) { 918 int ctnid = ((Integer ) ctnids.elementAt (i)).intValue (); 919 try { 920 thisContainer = jahiaContainersService.loadContainer( ctnid, loadFlag, jParams, loadVersion, 921 cachedFieldsInContainer, 922 cachedContainerListsFromContainers, 923 cachedContainerListsFromContainers); 924 if (thisContainer != null && thisContainer.getID () != -1) { v.add(new Integer (ctnid)); 926 listOfContainer.add(thisContainer); 927 } 928 } catch (Throwable t) { 929 String errorMsg = "Error loading container [" + ctnid + "]"; 930 if (loadVersion != null) { 931 errorMsg += " loadVersion=" + loadVersion.toString (); 932 } 933 logger.debug (errorMsg); 934 } 935 } 936 ctnids = v; 937 938 theContainerList.setFullSize (ctnids.size ()); 940 941 JahiaContainerListPagination cListPagination = new 943 JahiaContainerListPagination (theContainerList, jParams, -1); 944 theContainerList.setCtnListPagination (cListPagination); 945 946 int startPos = 0; 947 int endPos = cListPagination.getSize (); 948 949 if (cListPagination.isValid ()) { 950 startPos = cListPagination.getFirstItemIndex (); 951 endPos = cListPagination.getLastItemIndex (); 952 } 953 if (endPos < cListPagination.getSize ()) { 954 endPos += 1; 955 } 956 for (int i = startPos; i < endPos; i++) { 957 theContainerList.addContainer ((JahiaContainer) listOfContainer.get(i)); 958 } 959 if (theContainerList != null) { 960 theContainerList.setIsContainersLoaded (true); 961 } 962 963 } 964 } 965 | Popular Tags |