All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opencms.site.xmlsitemap.CmsDetailPageDuplicateEliminatingSitemapGenerator Maven / Gradle / Ivy

Go to download

OpenCms is an enterprise-ready, easy to use website content management system based on Java and XML technology. Offering a complete set of features, OpenCms helps content managers worldwide to create and maintain beautiful websites fast and efficiently.

There is a newer version: 18.0
Show newest version
/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.opencms.site.xmlsitemap;

import org.opencms.ade.configuration.CmsADEConfigData.DetailInfo;
import org.opencms.file.CmsProperty;
import org.opencms.file.CmsResource;
import org.opencms.file.CmsResourceFilter;
import org.opencms.file.types.I_CmsResourceType;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.util.CmsFileUtil;
import org.opencms.util.CmsPathMap;
import org.opencms.util.CmsStringUtil;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import org.apache.commons.logging.Log;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;

/**
 * Sitemap generator class which tries to eliminate duplicate detail pages for the same content and locale.

* * In principle, any detail page for a type somewhere in the system could be used to display contents anywhere * else in the system. This sitemap generator, instead of generating all detail page URLs that could possibly be generated, * instead tries to find only the best candidate URL for each content / locale combination. */ public class CmsDetailPageDuplicateEliminatingSitemapGenerator extends CmsXmlSitemapGenerator { /** The logger instance for this class. */ private static final Log LOG = CmsLog.getLog(CmsDetailPageDuplicateEliminatingSitemapGenerator.class); /** The detail page information. */ protected List m_detailInfos = new ArrayList(); /** Multimap of detail infos with the detail page as key. */ private Multimap m_detailInfosByPage; /** Cache for path maps containing the content resources. */ private HashMap> m_pathMapsByType = Maps.newHashMap(); /** * Constructor.

* * @param sitemapPath the sitemap path * @throws CmsException if something goes wrong */ public CmsDetailPageDuplicateEliminatingSitemapGenerator(String sitemapPath) throws CmsException { super(sitemapPath); List rawDetailInfo = OpenCms.getADEManager().getDetailInfo(m_guestCms); List filteredDetailInfo = Lists.newArrayList(); for (DetailInfo item : rawDetailInfo) { String path = item.getFolderPath(); if (OpenCms.getSiteManager().startsWithShared(path) || CmsStringUtil.isPrefixPath(m_siteRoot, path)) { filteredDetailInfo.add(item); } else { if (LOG.isDebugEnabled()) { LOG.debug("Filtered detail info: " + item); } } } m_detailInfos = filteredDetailInfo; } /** * @see org.opencms.site.xmlsitemap.CmsXmlSitemapGenerator#generateSitemapBeans() */ @Override public List generateSitemapBeans() throws CmsException { List parentResult = super.generateSitemapBeans(); List result = Lists.newArrayList(); Multimap detailPageBeans = ArrayListMultimap.create(); // We want to eliminate duplicate detail pages for the same detail content and locale, // so first we group the XML sitemap beans belonging to detail pages by their locale/content combination, // and then we sort each group by the sitemap configuration where the detail page is coming from, // and then only take the last element in each group. for (CmsXmlSitemapUrlBean urlBean : parentResult) { if (urlBean.getDetailPageResource() == null) { result.add(urlBean); } else { String localeKey = urlBean.getOriginalResource().getStructureId() + "_" + urlBean.getLocale(); detailPageBeans.put(localeKey, urlBean); } } Comparator pathComparator = new Comparator() { public int compare(CmsXmlSitemapUrlBean urlbean1, CmsXmlSitemapUrlBean urlbean2) { String subsite1 = urlbean1.getSubsite(); if (subsite1 == null) { subsite1 = ""; } String subsite2 = urlbean2.getSubsite(); if (subsite2 == null) { subsite2 = ""; } return subsite1.compareTo(subsite2); } }; for (String key : detailPageBeans.keySet()) { result.add(Collections.max(detailPageBeans.get(key), pathComparator)); } return result; } /** * @see org.opencms.site.xmlsitemap.CmsXmlSitemapGenerator#addDetailLinks(org.opencms.file.CmsResource, java.util.Locale) */ @Override protected void addDetailLinks(CmsResource containerPage, Locale locale) throws CmsException { Collection detailInfos = getDetailInfosForPage(containerPage); for (DetailInfo info : detailInfos) { List contents = getContents(info.getFolderPath(), info.getType()); for (CmsResource detailRes : contents) { List detailProps = m_guestCms.readPropertyObjects(detailRes, true); String detailLink = getDetailLink(containerPage, detailRes, locale); detailLink = CmsFileUtil.removeTrailingSeparator(detailLink); CmsXmlSitemapUrlBean detailUrlBean = new CmsXmlSitemapUrlBean( replaceServerUri(detailLink), detailRes.getDateLastModified(), getChangeFrequency(detailProps), getPriority(detailProps)); detailUrlBean.setLocale(locale); detailUrlBean.setOriginalResource(detailRes); detailUrlBean.setDetailPageResource(containerPage); detailUrlBean.setSubsite(info.getBasePath()); addResult(detailUrlBean, 2); } } } /** * Gets the contents for the given folder path and type name.

* * @param folderPath the content folder path * @param type the type name * @return the list of contents * * @throws CmsException if something goes wrong */ private List getContents(String folderPath, String type) throws CmsException { CmsPathMap pathMap = getPathMapForType(type); return pathMap.getChildValues(folderPath); } /** * Gets the detail information for the given container page.

* * @param containerPage the container page * @return the detail information */ private Collection getDetailInfosForPage(CmsResource containerPage) { if (m_detailInfosByPage == null) { m_detailInfosByPage = ArrayListMultimap.create(); for (DetailInfo detailInfo : m_detailInfos) { m_detailInfosByPage.put(detailInfo.getDetailPageInfo().getUri(), detailInfo); } } String folderPath = CmsResource.getParentFolder(containerPage.getRootPath()); Collection result = m_detailInfosByPage.get(containerPage.getRootPath()); if (result.isEmpty()) { result = m_detailInfosByPage.get(folderPath); } return result; } /** * Gets the path map containing the contents for the given type.

* * @param typeName the type name * @return the path map with the content resources * * @throws CmsException if something goes wrong */ private CmsPathMap getPathMapForType(String typeName) throws CmsException { if (!m_pathMapsByType.containsKey(typeName)) { CmsPathMap pathMap = readPathMapForType( OpenCms.getResourceManager().getResourceType(typeName)); m_pathMapsByType.put(typeName, pathMap); } return m_pathMapsByType.get(typeName); } /** * Reads the contents of a given type and stores them in a path map.

* * @param type the type for which to read the contents * @return the path map containing the contents */ private CmsPathMap readPathMapForType(I_CmsResourceType type) { List result = new ArrayList(); CmsResourceFilter filter = CmsResourceFilter.DEFAULT_FILES.addRequireType(type); try { List siteFiles = m_guestCms.readResources(m_siteRoot, filter, true); result.addAll(siteFiles); } catch (CmsException e) { LOG.error("XML sitemap generator error: " + e.getLocalizedMessage(), e); } String shared = CmsFileUtil.removeTrailingSeparator(OpenCms.getSiteManager().getSharedFolder()); if (shared != null) { try { List sharedFiles = m_guestCms.readResources(shared, filter, true); result.addAll(sharedFiles); } catch (CmsException e) { LOG.error("XML sitemap generator error: " + e.getLocalizedMessage(), e); } } CmsPathMap resultMap = new CmsPathMap(); for (CmsResource resource : result) { resultMap.add(resource.getRootPath(), resource); } return resultMap; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy