1 31 32 package org.opencms.search; 33 34 import org.opencms.db.CmsPublishedResource; 35 import org.opencms.file.CmsObject; 36 import org.opencms.file.CmsResource; 37 import org.opencms.file.CmsResourceFilter; 38 import org.opencms.i18n.CmsMessageContainer; 39 import org.opencms.main.CmsEvent; 40 import org.opencms.main.CmsException; 41 import org.opencms.main.CmsIllegalArgumentException; 42 import org.opencms.main.CmsIllegalStateException; 43 import org.opencms.main.CmsLog; 44 import org.opencms.main.I_CmsEventListener; 45 import org.opencms.main.OpenCms; 46 import org.opencms.report.CmsLogReport; 47 import org.opencms.report.I_CmsReport; 48 import org.opencms.scheduler.I_CmsScheduledJob; 49 import org.opencms.search.documents.I_CmsDocumentFactory; 50 import org.opencms.search.documents.I_CmsTermHighlighter; 51 import org.opencms.security.CmsRole; 52 import org.opencms.security.CmsRoleViolationException; 53 import org.opencms.util.CmsStringUtil; 54 import org.opencms.util.CmsUUID; 55 56 import java.io.File ; 57 import java.io.IOException ; 58 import java.util.ArrayList ; 59 import java.util.Collections ; 60 import java.util.HashMap ; 61 import java.util.Iterator ; 62 import java.util.LinkedList ; 63 import java.util.List ; 64 import java.util.Map ; 65 66 import org.apache.commons.collections.map.LRUMap; 67 import org.apache.commons.logging.Log; 68 import org.apache.lucene.analysis.Analyzer; 69 import org.apache.lucene.index.IndexReader; 70 import org.apache.lucene.index.IndexWriter; 71 import org.apache.lucene.search.Similarity; 72 import org.apache.lucene.store.FSDirectory; 73 74 85 public class CmsSearchManager implements I_CmsScheduledJob, I_CmsEventListener { 86 87 88 public static final String JOB_PARAM_INDEXLIST = "indexList"; 89 90 91 public static final String JOB_PARAM_WRITELOG = "writeLog"; 92 93 94 private static final Log LOG = CmsLog.getLog(CmsSearchManager.class); 95 96 97 private CmsObject m_adminCms; 98 99 100 private HashMap m_analyzers; 101 102 103 private Map m_documentTypeConfigs; 104 105 106 private Map m_documentTypes; 107 108 109 private I_CmsTermHighlighter m_highlighter; 110 111 112 private List m_indexes; 113 114 115 private int m_indexLockMaxWaitSeconds = 10; 116 117 118 private Map m_indexSources; 119 120 121 private int m_maxExcerptLength; 122 123 124 private String m_path; 125 126 127 private Map m_resultCache; 128 129 130 private String m_resultCacheSize; 131 132 133 private String m_timeout; 134 135 138 public CmsSearchManager() { 139 140 m_documentTypes = new HashMap (); 141 m_documentTypeConfigs = new HashMap (); 142 m_analyzers = new HashMap (); 143 m_indexes = new ArrayList (); 144 m_indexSources = new HashMap (); 145 146 if (CmsLog.INIT.isInfoEnabled()) { 147 CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_START_SEARCH_CONFIG_0)); 148 } 149 } 150 151 156 public void addAnalyzer(CmsSearchAnalyzer analyzer) { 157 158 m_analyzers.put(analyzer.getLocale(), analyzer); 159 160 if (CmsLog.INIT.isInfoEnabled()) { 161 CmsLog.INIT.info(Messages.get().getBundle().key( 162 Messages.INIT_ADD_ANALYZER_2, 163 analyzer.getLocale(), 164 analyzer.getClassName())); 165 } 166 } 167 168 173 public void addDocumentTypeConfig(CmsSearchDocumentType documentType) { 174 175 m_documentTypeConfigs.put(documentType.getName(), documentType); 176 177 if (CmsLog.INIT.isInfoEnabled()) { 178 CmsLog.INIT.info(Messages.get().getBundle().key( 179 Messages.INIT_SEARCH_DOC_TYPES_2, 180 documentType.getName(), 181 documentType.getClassName())); 182 } 183 } 184 185 190 public void addSearchIndex(CmsSearchIndex searchIndex) { 191 192 if (searchIndex.getSources() == null || searchIndex.getPath() == null) { 193 if (OpenCms.getRunLevel() > OpenCms.RUNLEVEL_2_INITIALIZING) { 194 try { 195 searchIndex.initialize(); 196 } catch (CmsSearchException e) { 197 } 199 } 200 } 201 202 String name = searchIndex.getName(); 204 if (CmsStringUtil.isEmptyOrWhitespaceOnly(name)) { 205 throw new CmsIllegalArgumentException(Messages.get().container( 206 Messages.ERR_SEARCHINDEX_CREATE_MISSING_NAME_0)); 207 } 208 if (m_indexSources.keySet().contains(name)) { 209 throw new CmsIllegalArgumentException(Messages.get().container( 210 Messages.ERR_SEARCHINDEX_CREATE_INVALID_NAME_1, 211 name)); 212 } 213 214 m_indexes.add(searchIndex); 215 216 if (CmsLog.INIT.isInfoEnabled()) { 217 CmsLog.INIT.info(Messages.get().getBundle().key( 218 Messages.INIT_ADD_SEARCH_INDEX_2, 219 searchIndex.getName(), 220 searchIndex.getProject())); 221 } 222 } 223 224 229 public void addSearchIndexSource(CmsSearchIndexSource searchIndexSource) { 230 231 m_indexSources.put(searchIndexSource.getName(), searchIndexSource); 232 233 if (CmsLog.INIT.isInfoEnabled()) { 234 CmsLog.INIT.info(Messages.get().getBundle().key( 235 Messages.INIT_SEARCH_INDEX_SOURCE_2, 236 searchIndexSource.getName(), 237 searchIndexSource.getIndexerClassName())); 238 } 239 } 240 241 246 public void cmsEvent(CmsEvent event) { 247 248 switch (event.getType()) { 249 case I_CmsEventListener.EVENT_CLEAR_CACHES: 250 if (m_resultCache != null) { 251 m_resultCache.clear(); 252 } 253 if (LOG.isDebugEnabled()) { 254 LOG.debug(Messages.get().getBundle().key(Messages.LOG_EVENT_CLEAR_CACHES_0)); 255 } 256 break; 257 case I_CmsEventListener.EVENT_PUBLISH_PROJECT: 258 CmsUUID publishHistoryId = new CmsUUID((String )event.getData().get(I_CmsEventListener.KEY_PUBLISHID)); 260 if (LOG.isDebugEnabled()) { 261 LOG.debug(Messages.get().getBundle().key(Messages.LOG_EVENT_PUBLISH_PROJECT_1, publishHistoryId)); 262 } 263 I_CmsReport report = (I_CmsReport)event.getData().get(I_CmsEventListener.KEY_REPORT); 264 updateAllIndexes(m_adminCms, publishHistoryId, report); 265 if (LOG.isDebugEnabled()) { 266 LOG.debug(Messages.get().getBundle().key( 267 Messages.LOG_EVENT_PUBLISH_PROJECT_FINISHED_1, 268 publishHistoryId)); 269 } 270 break; 271 default: 272 } 274 } 275 276 281 public Map getAnalyzers() { 282 283 return Collections.unmodifiableMap(m_analyzers); 284 } 285 286 291 public CmsSearchAnalyzer getCmsSearchAnalyzer(String locale) { 292 293 return (CmsSearchAnalyzer)m_analyzers.get(locale); 294 } 295 296 301 public String getDirectory() { 302 303 return m_path; 304 } 305 306 312 public CmsSearchDocumentType getDocumentTypeConfig(String name) { 313 314 return (CmsSearchDocumentType)m_documentTypeConfigs.get(name); 315 } 316 317 322 public Map getDocumentTypeConfigs() { 323 324 return Collections.unmodifiableMap(m_documentTypeConfigs); 325 } 326 327 332 public I_CmsTermHighlighter getHighlighter() { 333 334 return m_highlighter; 335 } 336 337 344 public CmsSearchIndex getIndex(String indexName) { 345 346 for (int i = 0, n = m_indexes.size(); i < n; i++) { 347 CmsSearchIndex searchIndex = (CmsSearchIndex)m_indexes.get(i); 348 349 if (indexName.equalsIgnoreCase(searchIndex.getName())) { 350 return searchIndex; 351 } 352 } 353 354 return null; 355 } 356 357 362 public int getIndexLockMaxWaitSeconds() { 363 364 return m_indexLockMaxWaitSeconds; 365 } 366 367 372 public List getIndexNames() { 373 374 List indexNames = new ArrayList (); 375 for (int i = 0, n = m_indexes.size(); i < n; i++) { 376 indexNames.add(((CmsSearchIndex)m_indexes.get(i)).getName()); 377 } 378 379 return indexNames; 380 } 381 382 388 public CmsSearchIndexSource getIndexSource(String sourceName) { 389 390 return (CmsSearchIndexSource)m_indexSources.get(sourceName); 391 } 392 393 398 public int getMaxExcerptLength() { 399 400 return m_maxExcerptLength; 401 } 402 403 408 public String getResultCacheSize() { 409 410 return m_resultCacheSize; 411 } 412 413 418 public List getSearchIndexes() { 419 420 return Collections.unmodifiableList(m_indexes); 421 } 422 423 428 public Map getSearchIndexSources() { 429 430 return Collections.unmodifiableMap(m_indexSources); 431 } 432 433 438 public String getTimeout() { 439 440 return m_timeout; 441 } 442 443 450 public void initialize(CmsObject cms) throws CmsRoleViolationException { 451 452 cms.checkRole(CmsRole.SEARCH_MANAGER); 453 try { 454 m_adminCms = OpenCms.initCmsObject(cms); 456 } catch (CmsException e) { 457 } 459 m_adminCms.getRequestContext().setSiteRoot("/"); 461 462 LRUMap hashMap = new LRUMap(Integer.parseInt(m_resultCacheSize)); 464 m_resultCache = Collections.synchronizedMap(hashMap); 465 466 if (OpenCms.getMemoryMonitor().enabled()) { 467 OpenCms.getMemoryMonitor().register(getClass().getName() + ".m_resultCache", hashMap); 468 } 469 470 initializeIndexes(); 471 472 Similarity.setDefault(new CmsSearchSimilarity()); 474 475 OpenCms.addCmsEventListener(this, new int[] { 477 I_CmsEventListener.EVENT_CLEAR_CACHES, 478 I_CmsEventListener.EVENT_PUBLISH_PROJECT}); 479 } 480 481 486 public void initializeIndexes() { 487 488 initAvailableDocumentTypes(); 489 initSearchIndexes(); 490 } 491 492 504 public final String launch(CmsObject cms, Map parameters) throws Exception { 505 506 CmsSearchManager manager = OpenCms.getSearchManager(); 507 508 I_CmsReport report = null; 509 boolean writeLog = Boolean.valueOf((String )parameters.get(JOB_PARAM_WRITELOG)).booleanValue(); 510 511 if (writeLog) { 512 report = new CmsLogReport(cms.getRequestContext().getLocale(), CmsSearchManager.class); 513 } 514 515 List updateList = null; 516 String indexList = (String )parameters.get(JOB_PARAM_INDEXLIST); 517 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(indexList)) { 518 updateList = new ArrayList (); 520 String [] indexNames = CmsStringUtil.splitAsArray(indexList, '|'); 521 for (int i = 0; i < indexNames.length; i++) { 522 if (manager.getIndex(indexNames[i]) != null) { 524 updateList.add(indexNames[i]); 525 } else { 526 if (LOG.isWarnEnabled()) { 527 LOG.warn(Messages.get().getBundle().key(Messages.LOG_NO_INDEX_WITH_NAME_1, indexNames[i])); 528 } 529 } 530 } 531 } 532 533 long startTime = System.currentTimeMillis(); 534 535 if (updateList == null) { 536 manager.rebuildAllIndexes(report); 538 } else { 539 manager.rebuildIndexes(updateList, report); 541 } 542 543 long runTime = System.currentTimeMillis() - startTime; 544 545 String finishMessage = Messages.get().getBundle().key( 546 Messages.LOG_REBUILD_INDEXES_FINISHED_1, 547 CmsStringUtil.formatRuntime(runTime)); 548 549 if (LOG.isInfoEnabled()) { 550 LOG.info(finishMessage); 551 } 552 return finishMessage; 553 } 554 555 562 public void rebuildAllIndexes(I_CmsReport report) throws CmsException { 563 564 rebuildAllIndexes(report, false); 565 } 566 567 575 public void rebuildAllIndexes(I_CmsReport report, boolean wait) throws CmsException { 576 577 CmsMessageContainer container = null; 578 for (int i = 0, n = m_indexes.size(); i < n; i++) { 579 CmsSearchIndex searchIndex = (CmsSearchIndex)m_indexes.get(i); 581 try { 582 updateIndex(searchIndex, report, wait, null, null); 584 } catch (CmsException e) { 585 container = new CmsMessageContainer( 586 Messages.get(), 587 Messages.ERR_INDEX_REBUILD_ALL_1, 588 new Object [] {searchIndex.getName()}); 589 LOG.error(Messages.get().getBundle().key(Messages.ERR_INDEX_REBUILD_ALL_1, searchIndex.getName()), e); 590 } 591 } 592 if (container != null) { 593 throw new CmsSearchException(container); 595 } 596 } 597 598 606 public void rebuildIndex(String indexName, I_CmsReport report) throws CmsException { 607 608 CmsSearchIndex index = getIndex(indexName); 610 updateIndex(index, report, false, null, null); 612 } 613 614 622 public void rebuildIndexes(List indexNames, I_CmsReport report) throws CmsException { 623 624 Iterator i = indexNames.iterator(); 625 while (i.hasNext()) { 626 String indexName = (String )i.next(); 627 CmsSearchIndex index = getIndex(indexName); 629 if (index != null) { 630 updateIndex(index, report, false, null, null); 632 } else { 633 if (LOG.isWarnEnabled()) { 634 LOG.warn(Messages.get().getBundle().key(Messages.LOG_NO_INDEX_WITH_NAME_1, indexName)); 635 } 636 } 637 } 638 } 639 640 645 public void removeSearchIndex(CmsSearchIndex searchIndex) { 646 647 m_indexes.remove(searchIndex); 648 649 if (LOG.isInfoEnabled()) { 650 LOG.info(Messages.get().getBundle().key( 651 Messages.LOG_REMOVE_SEARCH_INDEX_2, 652 searchIndex.getName(), 653 searchIndex.getProject())); 654 } 655 } 656 657 662 public void removeSearchIndexes(List indexNames) { 663 664 Iterator i = indexNames.iterator(); 665 while (i.hasNext()) { 666 String indexName = (String )i.next(); 667 CmsSearchIndex index = getIndex(indexName); 669 if (index != null) { 670 removeSearchIndex(index); 672 } else { 673 if (LOG.isWarnEnabled()) { 674 LOG.warn(Messages.get().getBundle().key(Messages.LOG_NO_INDEX_WITH_NAME_1, indexName)); 675 } 676 } 677 } 678 } 679 680 694 public boolean removeSearchIndexSource(CmsSearchIndexSource indexsource) throws CmsIllegalStateException { 695 696 Iterator itIndexes = m_indexes.iterator(); 698 CmsSearchIndex idx; 699 List referrers = new LinkedList (); 701 List refsources; 703 while (itIndexes.hasNext()) { 704 idx = (CmsSearchIndex)itIndexes.next(); 705 refsources = idx.getSources(); 706 if (refsources != null) { 707 if (refsources.contains(indexsource)) { 708 referrers.add(idx); 709 } 710 } 711 } 712 if (referrers.size() > 0) { 713 throw new CmsIllegalStateException(Messages.get().container( 714 Messages.ERR_INDEX_SOURCE_DELETE_2, 715 indexsource.getName(), 716 referrers.toString())); 717 } 718 719 return m_indexSources.remove(indexsource.getName()) != null; 721 722 } 723 724 729 public void setDirectory(String value) { 730 731 m_path = value; 732 } 733 734 741 public void setHighlighter(String highlighter) { 742 743 try { 744 m_highlighter = (I_CmsTermHighlighter)Class.forName(highlighter).newInstance(); 745 } catch (Exception exc) { 746 m_highlighter = null; 747 } 748 } 749 750 755 public void setIndexLockMaxWaitSeconds(int value) { 756 757 m_indexLockMaxWaitSeconds = value; 758 } 759 760 765 public void setMaxExcerptLength(String maxExcerptLength) { 766 767 try { 768 m_maxExcerptLength = Integer.parseInt(maxExcerptLength); 769 } catch (Exception e) { 770 LOG.error(Messages.get().getBundle().key(Messages.LOG_PARSE_EXCERPT_LENGTH_FAILED_1, maxExcerptLength), e); 771 m_maxExcerptLength = 1024; 772 } 773 } 774 775 780 public void setResultCacheSize(String value) { 781 782 m_resultCacheSize = value; 783 } 784 785 790 public void setTimeout(String value) { 791 792 m_timeout = value; 793 } 794 795 805 protected boolean checkIndexLock(CmsSearchIndex index, I_CmsReport report) { 806 807 File indexPath = new File (index.getPath()); 808 if (!indexPath.exists()) { 810 return false; 812 } 813 814 boolean indexLocked = true; 816 try { 817 int lockSecs = 0; 818 while (indexLocked && (lockSecs < m_indexLockMaxWaitSeconds)) { 819 indexLocked = IndexReader.isLocked(index.getPath()); 820 if (indexLocked) { 821 report.println(Messages.get().container( 823 Messages.RPT_SEARCH_INDEXING_LOCK_WAIT_2, 824 index.getName(), 825 new Integer (m_indexLockMaxWaitSeconds - lockSecs)), I_CmsReport.FORMAT_ERROR); 826 Thread.sleep(1000); 828 lockSecs++; 829 } 830 } 831 } catch (Exception e) { 832 LOG.error(Messages.get().getBundle().key( 833 Messages.LOG_IO_INDEX_READER_OPEN_2, 834 index.getPath(), 835 index.getName()), e); 836 } 837 838 return indexLocked; 839 } 840 841 849 protected Analyzer getAnalyzer(String locale) throws CmsIndexException { 850 851 Analyzer analyzer = null; 852 String className = null; 853 854 CmsSearchAnalyzer analyzerConf = (CmsSearchAnalyzer)m_analyzers.get(locale); 855 if (analyzerConf == null) { 856 throw new CmsIndexException(Messages.get().container(Messages.ERR_ANALYZER_NOT_FOUND_1, locale)); 857 } 858 859 try { 860 className = analyzerConf.getClassName(); 861 Class analyzerClass = Class.forName(className); 862 863 String stemmerAlgorithm = analyzerConf.getStemmerAlgorithm(); 865 if (stemmerAlgorithm != null) { 866 analyzer = (Analyzer)analyzerClass.getDeclaredConstructor(new Class [] {String .class}).newInstance( 867 new Object [] {stemmerAlgorithm}); 868 } else { 869 analyzer = (Analyzer)analyzerClass.newInstance(); 870 } 871 872 } catch (Exception e) { 873 throw new CmsIndexException(Messages.get().container(Messages.ERR_LOAD_ANALYZER_1, className), e); 874 } 875 876 return analyzer; 877 } 878 879 887 protected I_CmsDocumentFactory getDocumentFactory(A_CmsIndexResource resource) { 888 889 String documentTypeKey = resource.getDocumentKey(true); 890 891 I_CmsDocumentFactory factory = (I_CmsDocumentFactory)m_documentTypes.get(documentTypeKey); 892 if (factory == null) { 893 factory = (I_CmsDocumentFactory)m_documentTypes.get(resource.getDocumentKey(false)); 894 } 895 896 return factory; 897 } 898 899 904 protected List getDocumentTypes() { 905 906 List names = new ArrayList (); 907 for (Iterator i = m_documentTypes.values().iterator(); i.hasNext();) { 908 I_CmsDocumentFactory factory = (I_CmsDocumentFactory)i.next(); 909 names.add(factory.getName()); 910 } 911 912 return names; 913 } 914 915 920 protected Map getResultCache() { 921 922 return m_resultCache; 923 } 924 925 937 protected void initAvailableDocumentTypes() { 938 939 CmsSearchDocumentType documenttype = null; 940 String className = null; 941 String name = null; 942 I_CmsDocumentFactory documentFactory = null; 943 List resourceTypes = null; 944 List mimeTypes = null; 945 Class c = null; 946 947 m_documentTypes = new HashMap (); 948 949 List keys = new ArrayList (m_documentTypeConfigs.keySet()); 950 for (int i = 0, n = keys.size(); i < n; i++) { 951 952 documenttype = (CmsSearchDocumentType)(m_documentTypeConfigs.get(keys.get(i))); 953 name = documenttype.getName(); 954 955 try { 956 className = documenttype.getClassName(); 957 resourceTypes = documenttype.getResourceTypes(); 958 mimeTypes = documenttype.getMimeTypes(); 959 960 if (name == null) { 961 throw new CmsIndexException(Messages.get().container(Messages.ERR_DOCTYPE_NO_NAME_0)); 962 } 963 if (className == null) { 964 throw new CmsIndexException(Messages.get().container(Messages.ERR_DOCTYPE_NO_CLASS_DEF_0)); 965 } 966 if (resourceTypes.size() == 0) { 967 throw new CmsIndexException(Messages.get().container(Messages.ERR_DOCTYPE_NO_RESOURCETYPE_DEF_0)); 968 } 969 970 try { 971 c = Class.forName(className); 972 documentFactory = (I_CmsDocumentFactory)c.getConstructor(new Class [] {String .class}).newInstance( 973 new Object [] {name}); 974 } catch (ClassNotFoundException exc) { 975 throw new CmsIndexException( 976 Messages.get().container(Messages.ERR_DOCCLASS_NOT_FOUND_1, className), 977 exc); 978 } catch (Exception exc) { 979 throw new CmsIndexException(Messages.get().container(Messages.ERR_DOCCLASS_INIT_1, className), exc); 980 } 981 982 for (Iterator key = documentFactory.getDocumentKeys(resourceTypes, mimeTypes).iterator(); key.hasNext();) { 983 m_documentTypes.put(key.next(), documentFactory); 984 } 985 986 } catch (CmsException e) { 987 if (LOG.isWarnEnabled()) { 988 LOG.warn(Messages.get().getBundle().key(Messages.LOG_DOCTYPE_CONFIG_FAILED_1, name), e); 989 } 990 } 991 } 992 } 993 994 1000 protected void initSearchIndexes() { 1001 1002 CmsSearchIndex index = null; 1003 for (int i = 0, n = m_indexes.size(); i < n; i++) { 1004 index = (CmsSearchIndex)m_indexes.get(i); 1005 index.setEnabled(true); 1007 if (index.checkConfiguration(m_adminCms)) { 1009 try { 1011 index.initialize(); 1012 } catch (CmsException e) { 1013 if (CmsLog.INIT.isInfoEnabled()) { 1015 CmsLog.INIT.info(Messages.get().getBundle().key( 1016 Messages.INIT_SEARCH_INIT_FAILED_1, 1017 index.getName()), e); 1018 } 1019 } 1020 } 1021 if (CmsLog.INIT.isInfoEnabled()) { 1022 if (index.isEnabled()) { 1024 CmsLog.INIT.info(Messages.get().getBundle().key( 1025 Messages.INIT_INDEX_CONFIGURED_2, 1026 index.getName(), 1027 index.getProject())); 1028 } else { 1029 CmsLog.INIT.info(Messages.get().getBundle().key( 1030 Messages.INIT_INDEX_NOT_CONFIGURED_2, 1031 index.getName(), 1032 index.getProject())); 1033 } 1034 } 1035 } 1036 } 1037 1038 1046 protected synchronized void updateAllIndexes(CmsObject adminCms, CmsUUID publishHistoryId, I_CmsReport report) { 1047 1048 List publishedResources; 1049 try { 1050 publishedResources = adminCms.readPublishedResources(publishHistoryId); 1052 } catch (CmsException e) { 1053 LOG.error( 1054 Messages.get().getBundle().key(Messages.LOG_READING_CHANGED_RESOURCES_FAILED_1, publishHistoryId), 1055 e); 1056 return; 1057 } 1058 1059 List updateResources = new ArrayList (); 1060 Iterator itPubRes = publishedResources.iterator(); 1061 while (itPubRes.hasNext()) { 1062 CmsPublishedResource res = (CmsPublishedResource)itPubRes.next(); 1063 if (res.isFolder() || res.isUnChanged() || !res.isVfsResource()) { 1064 continue; 1066 } 1067 if (res.isDeleted() || res.isNew() || res.isChanged()) { 1068 if (updateResources.contains(res)) { 1069 updateResources.remove(res); 1072 updateResources.add(res); 1075 } else { 1076 updateResources.add(res); 1078 if (!res.isDeleted() && (res.getSiblingCount() > 1)) { 1080 try { 1082 List siblings = adminCms.readSiblings(res.getRootPath(), CmsResourceFilter.ALL); 1084 Iterator itSib = siblings.iterator(); 1085 while (itSib.hasNext()) { 1086 CmsResource sibling = (CmsResource)itSib.next(); 1088 CmsPublishedResource sib = new CmsPublishedResource(sibling); 1089 if (!updateResources.contains(sib)) { 1090 updateResources.add(sib); 1092 } 1093 } 1094 } catch (CmsException e) { 1095 if (LOG.isWarnEnabled()) { 1097 LOG.warn(Messages.get().getBundle().key( 1098 Messages.LOG_UNABLE_TO_READ_SIBLINGS_1, 1099 res.getRootPath()), e); 1100 } 1101 } 1102 } 1103 } 1104 } 1105 } 1106 1107 Map documentCache = Collections.synchronizedMap(new LRUMap(256)); 1109 1110 if (!updateResources.isEmpty()) { 1111 Collections.sort(updateResources); 1113 Iterator i = m_indexes.iterator(); 1115 while (i.hasNext()) { 1116 CmsSearchIndex index = (CmsSearchIndex)i.next(); 1117 if (CmsSearchIndex.REBUILD_MODE_AUTO.equals(index.getRebuildMode())) { 1118 try { 1120 updateIndex(index, report, false, updateResources, documentCache); 1121 } catch (CmsException e) { 1122 LOG.error( 1123 Messages.get().getBundle().key(Messages.LOG_UPDATE_INDEX_FAILED_1, index.getName()), 1124 e); 1125 } 1126 } 1127 } 1128 } 1129 } 1130 1131 1146 protected synchronized void updateIndex( 1147 CmsSearchIndex index, 1148 I_CmsReport report, 1149 boolean wait, 1150 List resourcesToIndex, 1151 Map documentCache) throws CmsException { 1152 1153 CmsObject cms = OpenCms.initCmsObject(m_adminCms); 1155 if (report == null) { 1157 report = new CmsLogReport(cms.getRequestContext().getLocale(), CmsSearchManager.class); 1158 } 1159 1160 if (!index.checkConfiguration(cms)) { 1162 return; 1164 } 1165 1166 cms.getRequestContext().setSiteRoot("/"); 1168 cms.getRequestContext().setCurrentProject(cms.readProject(index.getProject())); 1170 1171 if ((resourcesToIndex == null) || resourcesToIndex.isEmpty()) { 1172 1174 if (checkIndexLock(index, report)) { 1175 try { 1177 IndexReader.unlock(FSDirectory.getDirectory(index.getPath(), false)); 1179 } catch (Exception e) { 1180 CmsMessageContainer msg = Messages.get().container( 1182 Messages.ERR_INDEX_LOCK_FAILED_1, 1183 index.getName()); 1184 report.println(msg, I_CmsReport.FORMAT_ERROR); 1185 throw new CmsIndexException(msg, e); 1186 } 1187 } 1188 1189 CmsIndexingThreadManager threadManager = new CmsIndexingThreadManager( 1194 report, 1195 Long.parseLong(m_timeout), 1196 index.getName(), 1197 null); 1198 1199 IndexWriter writer = null; 1200 try { 1201 writer = index.getIndexWriter(true); 1203 1204 report.println( 1206 Messages.get().container(Messages.RPT_SEARCH_INDEXING_REBUILD_BEGIN_1, index.getName()), 1207 I_CmsReport.FORMAT_HEADLINE); 1208 1209 Iterator sources = index.getSources().iterator(); 1211 while (sources.hasNext()) { 1212 CmsSearchIndexSource source = (CmsSearchIndexSource)sources.next(); 1214 I_CmsIndexer indexer = source.getIndexer().newInstance(cms, report, index); 1216 indexer.rebuildIndex(writer, threadManager, source); 1218 } 1219 1220 while (wait && threadManager.isRunning()) { 1222 try { 1223 Thread.sleep(1000); 1224 } catch (InterruptedException e) { 1225 } 1227 } 1228 try { 1230 writer.optimize(); 1231 } catch (IOException e) { 1232 if (LOG.isWarnEnabled()) { 1233 LOG.warn(Messages.get().getBundle().key( 1234 Messages.LOG_IO_INDEX_WRITER_OPTIMIZE_1, 1235 index.getPath(), 1236 index.getName()), e); 1237 } 1238 } 1239 1240 report.println( 1242 Messages.get().container(Messages.RPT_SEARCH_INDEXING_REBUILD_END_1, index.getName()), 1243 I_CmsReport.FORMAT_HEADLINE); 1244 1245 } finally { 1246 if (writer != null) { 1247 try { 1248 writer.close(); 1249 } catch (IOException e) { 1250 if (LOG.isWarnEnabled()) { 1251 LOG.warn(Messages.get().getBundle().key( 1252 Messages.LOG_IO_INDEX_WRITER_CLOSE_2, 1253 index.getPath(), 1254 index.getName()), e); 1255 } 1256 } 1257 } 1258 } 1259 1260 threadManager.reportStatistics(); 1262 1263 } else { 1264 1266 List updateCollections = new ArrayList (); 1267 1268 boolean hasResourcesToDelete = false; 1269 boolean hasResourcesToUpdate = false; 1270 1271 Iterator sources = index.getSources().iterator(); 1273 while (sources.hasNext()) { 1274 CmsSearchIndexSource source = (CmsSearchIndexSource)sources.next(); 1276 I_CmsIndexer indexer = source.getIndexer().newInstance(cms, report, index); 1278 CmsSearchIndexUpdateData updateData = indexer.getUpdateData(source, resourcesToIndex); 1280 if (!updateData.isEmpty()) { 1281 updateCollections.add(updateData); 1283 hasResourcesToDelete = hasResourcesToDelete | updateData.hasResourcesToDelete(); 1284 hasResourcesToUpdate = hasResourcesToUpdate | updateData.hasResourceToUpdate(); 1285 } 1286 } 1287 1288 if (hasResourcesToDelete || hasResourcesToUpdate) { 1289 report.println( 1291 Messages.get().container(Messages.RPT_SEARCH_INDEXING_UPDATE_BEGIN_1, index.getName()), 1292 I_CmsReport.FORMAT_HEADLINE); 1293 } 1294 1295 if (checkIndexLock(index, report)) { 1296 CmsMessageContainer msg = Messages.get().container(Messages.ERR_INDEX_LOCK_FAILED_1, index.getName()); 1298 report.println(msg, I_CmsReport.FORMAT_ERROR); 1299 throw new CmsIndexException(msg); 1300 } 1301 1302 if (hasResourcesToDelete) { 1303 IndexReader reader = null; 1305 try { 1306 reader = IndexReader.open(index.getPath()); 1307 } catch (IOException e) { 1308 LOG.error(Messages.get().getBundle().key( 1309 Messages.LOG_IO_INDEX_READER_OPEN_2, 1310 index.getPath(), 1311 index.getName()), e); 1312 } 1313 if (reader != null) { 1314 try { 1315 Iterator i = updateCollections.iterator(); 1316 while (i.hasNext()) { 1317 CmsSearchIndexUpdateData updateCollection = (CmsSearchIndexUpdateData)i.next(); 1318 if (updateCollection.hasResourcesToDelete()) { 1319 updateCollection.getIndexer().deleteResources( 1320 reader, 1321 updateCollection.getResourcesToDelete()); 1322 } 1323 } 1324 } finally { 1325 try { 1326 reader.close(); 1328 } catch (IOException e) { 1329 LOG.error(Messages.get().getBundle().key( 1330 Messages.LOG_IO_INDEX_READER_CLOSE_2, 1331 index.getPath(), 1332 index.getName()), e); 1333 } 1334 } 1335 } 1336 } 1337 1338 if (hasResourcesToUpdate) { 1339 1340 CmsIndexingThreadManager threadManager = new CmsIndexingThreadManager( 1342 report, 1343 Long.parseLong(m_timeout), 1344 index.getName(), 1345 documentCache); 1346 1347 IndexWriter writer = null; 1348 try { 1349 1350 writer = index.getIndexWriter(false); 1352 1353 Iterator i = updateCollections.iterator(); 1354 while (i.hasNext()) { 1355 CmsSearchIndexUpdateData updateCollection = (CmsSearchIndexUpdateData)i.next(); 1356 if (updateCollection.hasResourceToUpdate()) { 1357 updateCollection.getIndexer().updateResources( 1358 writer, 1359 threadManager, 1360 updateCollection.getResourcesToUpdate()); 1361 } 1362 } 1363 1364 while (wait && threadManager.isRunning()) { 1366 try { 1367 Thread.sleep(1000); 1368 } catch (InterruptedException e) { 1369 } 1371 } 1372 1373 } finally { 1374 if (writer != null) { 1375 try { 1376 writer.close(); 1377 } catch (IOException e) { 1378 LOG.error(Messages.get().getBundle().key( 1379 Messages.LOG_IO_INDEX_WRITER_CLOSE_2, 1380 index.getPath(), 1381 index.getName()), e); 1382 } 1383 } 1384 } 1385 } 1386 1387 if (hasResourcesToDelete || hasResourcesToUpdate) { 1388 report.println( 1390 Messages.get().container(Messages.RPT_SEARCH_INDEXING_UPDATE_END_1, index.getName()), 1391 I_CmsReport.FORMAT_HEADLINE); 1392 } 1393 } 1394 1395 m_resultCache.clear(); 1397 } 1398} | Popular Tags |