001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.search.solr; 029 030import org.opencms.ade.configuration.CmsADEConfigData; 031import org.opencms.file.CmsFile; 032import org.opencms.file.CmsObject; 033import org.opencms.file.CmsResource; 034import org.opencms.main.CmsException; 035import org.opencms.main.CmsLog; 036import org.opencms.main.OpenCms; 037import org.opencms.search.CmsIndexException; 038import org.opencms.search.I_CmsSearchIndex; 039import org.opencms.search.documents.Messages; 040import org.opencms.search.extractors.CmsExtractionResult; 041import org.opencms.search.extractors.I_CmsExtractionResult; 042import org.opencms.xml.containerpage.CmsContainerElementBean; 043import org.opencms.xml.containerpage.CmsContainerPageBean; 044import org.opencms.xml.containerpage.CmsFormatterConfiguration; 045import org.opencms.xml.containerpage.CmsXmlContainerPage; 046import org.opencms.xml.containerpage.CmsXmlContainerPageFactory; 047 048import java.util.ArrayList; 049import java.util.HashMap; 050import java.util.LinkedHashMap; 051import java.util.List; 052import java.util.Locale; 053import java.util.Map; 054 055import org.apache.commons.logging.Log; 056 057/** 058 * Lucene document factory class to extract index data from a resource 059 * of type <code>CmsResourceTypeContainerPage</code>.<p> 060 * 061 * @since 8.5.0 062 */ 063public class CmsSolrDocumentContainerPage extends CmsSolrDocumentXmlContent { 064 065 /** The log object for this class. */ 066 private static final Log LOG = CmsLog.getLog(CmsSolrDocumentContainerPage.class); 067 068 /** The solr document type name for xml-contents. */ 069 public static final String TYPE_CONTAINERPAGE_SOLR = "containerpage-solr"; 070 071 /** 072 * Creates a new instance of this lucene document factory.<p> 073 * 074 * @param name name of the document type 075 */ 076 public CmsSolrDocumentContainerPage(String name) { 077 078 super(name); 079 } 080 081 /** 082 * Returns the raw text content of a VFS resource of type <code>CmsResourceTypeContainerPage</code>.<p> 083 * 084 * @see org.opencms.search.documents.I_CmsSearchExtractor#extractContent(CmsObject, CmsResource, I_CmsSearchIndex) 085 */ 086 @Override 087 public I_CmsExtractionResult extractContent(CmsObject cms, CmsResource resource, I_CmsSearchIndex index) 088 throws CmsException { 089 090 return extractContent(cms, resource, index, null); 091 } 092 093 /** 094 * Extracts the content of a given index resource according to the resource file type and the 095 * configuration of the given index.<p> 096 * 097 * @param cms the cms object 098 * @param resource the resource to extract the content from 099 * @param index the index to extract the content for 100 * @param forceLocale if set, only the content values for the given locale will be extracted 101 * 102 * @return the extracted content of the resource 103 * 104 * @throws CmsException if something goes wrong 105 */ 106 public I_CmsExtractionResult extractContent( 107 CmsObject cms, 108 CmsResource resource, 109 I_CmsSearchIndex index, 110 Locale forceLocale) 111 throws CmsException { 112 113 logContentExtraction(resource, index); 114 I_CmsExtractionResult ex = null; 115 try { 116 CmsFile file = readFile(cms, resource); 117 CmsXmlContainerPage containerPage = CmsXmlContainerPageFactory.unmarshal(cms, file); 118 119 List<I_CmsExtractionResult> all = new ArrayList<I_CmsExtractionResult>(); 120 CmsContainerPageBean containerBean = containerPage.getContainerPage(cms); 121 if (containerBean != null) { 122 for (CmsContainerElementBean element : containerBean.getElements()) { 123 // check all elements in this container 124 // get the formatter configuration for this element 125 try { 126 element.initResource(cms); 127 CmsResource elementResource = element.getResource(); 128 if (!(cms.readProject(index.getProject()).isOnlineProject() 129 && elementResource.isExpired(System.currentTimeMillis()))) { 130 CmsADEConfigData adeConfig = OpenCms.getADEManager().lookupConfiguration( 131 cms, 132 file.getRootPath()); 133 CmsFormatterConfiguration formatters = adeConfig.getFormatters(cms, element.getResource()); 134 if ((formatters != null) 135 && (element.getFormatterId() != null) 136 && formatters.isSearchContent(element.getFormatterId())) { 137 // the content of this element must be included for the container page 138 all.add( 139 CmsSolrDocumentXmlContent.extractXmlContent( 140 cms, 141 elementResource, 142 index, 143 forceLocale)); 144 } 145 } 146 } catch (CmsException e) { 147 LOG.debug( 148 Messages.get().getBundle().key( 149 Messages.LOG_SKIPPING_CONTAINERPAGE_ELEMENT_WITH_UNREADABLE_RESOURCE_2, 150 file.getRootPath(), 151 element.getId()), 152 e); 153 } 154 } 155 } 156 // we have to overwrite the resource and content locales with the one from this container page 157 // TODO: Is this really the wanted behavior? It seems to be done like this before. 158 Map<String, String> fieldMappings = new HashMap<String, String>(1); 159 // Add to each container page the contents in all available locales, 160 // in case one containerpage is used in multiple languages. 161 List<Locale> localesAvailable = OpenCms.getLocaleManager().getAvailableLocales(cms, resource); 162 Map<Locale, LinkedHashMap<String, String>> multilingualValues = new HashMap<Locale, LinkedHashMap<String, String>>( 163 localesAvailable.size()); 164 for (Locale localeAvailable : localesAvailable) { 165 multilingualValues.put(localeAvailable, new LinkedHashMap<String, String>()); 166 } 167 Locale locale = forceLocale != null 168 ? forceLocale 169 : index.getLocaleForResource(cms, resource, containerPage.getLocales()); 170 ex = new CmsExtractionResult(locale, multilingualValues, fieldMappings); 171 ex = ex.merge(all); 172 return ex; 173 } catch (Exception e) { 174 throw new CmsIndexException( 175 Messages.get().container(Messages.ERR_TEXT_EXTRACTION_1, resource.getRootPath()), 176 e); 177 } 178 } 179 180 /** 181 * @see org.opencms.search.documents.I_CmsDocumentFactory#isLocaleDependend() 182 */ 183 @Override 184 public boolean isLocaleDependend() { 185 186 return true; 187 } 188 189 /** 190 * @see org.opencms.search.documents.I_CmsDocumentFactory#isUsingCache() 191 */ 192 @Override 193 public boolean isUsingCache() { 194 195 return true; 196 } 197}