/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * 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. */ package com.liferay.portlet.layoutsadmin.util; import com.liferay.layouts.admin.kernel.util.Sitemap; import com.liferay.layouts.admin.kernel.util.SitemapURLProvider; import com.liferay.layouts.admin.kernel.util.SitemapURLProviderRegistryUtil; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.model.Layout; import com.liferay.portal.kernel.model.LayoutSet; import com.liferay.portal.kernel.model.LayoutTypeController; import com.liferay.portal.kernel.security.pacl.DoPrivileged; import com.liferay.portal.kernel.service.LayoutLocalServiceUtil; import com.liferay.portal.kernel.service.LayoutSetLocalServiceUtil; import com.liferay.portal.kernel.theme.ThemeDisplay; import com.liferay.portal.kernel.util.DateUtil; import com.liferay.portal.kernel.util.LocaleUtil; import com.liferay.portal.kernel.util.PortalUtil; import com.liferay.portal.kernel.util.StringBundler; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.kernel.util.UnicodeProperties; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.kernel.xml.Document; import com.liferay.portal.kernel.xml.Element; import com.liferay.portal.kernel.xml.SAXReaderUtil; import com.liferay.portal.util.LayoutTypeControllerTracker; import com.liferay.portal.util.PropsValues; import java.text.DateFormat; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Map; /** * @author Jorge Ferrer * @author Vilmos Papp */ @DoPrivileged public class SitemapImpl implements Sitemap { @Override public void addURLElement( Element element, String url, UnicodeProperties typeSettingsProperties, Date modifiedDate, String canonicalURL, Map<Locale, String> alternateURLs) { Element urlElement = element.addElement("url"); Element locElement = urlElement.addElement("loc"); locElement.addText(encodeXML(url)); if (typeSettingsProperties == null) { if (Validator.isNotNull( PropsValues.SITES_SITEMAP_DEFAULT_CHANGE_FREQUENCY)) { Element changefreqElement = urlElement.addElement("changefreq"); changefreqElement.addText( PropsValues.SITES_SITEMAP_DEFAULT_CHANGE_FREQUENCY); } if (Validator.isNotNull( PropsValues.SITES_SITEMAP_DEFAULT_PRIORITY)) { Element priorityElement = urlElement.addElement("priority"); priorityElement.addText( PropsValues.SITES_SITEMAP_DEFAULT_PRIORITY); } } else { String changefreq = typeSettingsProperties.getProperty( "sitemap-changefreq"); if (Validator.isNotNull(changefreq)) { Element changefreqElement = urlElement.addElement("changefreq"); changefreqElement.addText(changefreq); } else if (Validator.isNotNull( PropsValues.SITES_SITEMAP_DEFAULT_CHANGE_FREQUENCY)) { Element changefreqElement = urlElement.addElement("changefreq"); changefreqElement.addText( PropsValues.SITES_SITEMAP_DEFAULT_CHANGE_FREQUENCY); } String priority = typeSettingsProperties.getProperty( "sitemap-priority"); if (Validator.isNotNull(priority)) { Element priorityElement = urlElement.addElement("priority"); priorityElement.addText(priority); } else if (Validator.isNotNull( PropsValues.SITES_SITEMAP_DEFAULT_PRIORITY)) { Element priorityElement = urlElement.addElement("priority"); priorityElement.addText( PropsValues.SITES_SITEMAP_DEFAULT_PRIORITY); } } if (modifiedDate != null) { Element modifiedDateElement = urlElement.addElement("lastmod"); DateFormat iso8601DateFormat = DateUtil.getISO8601Format(); modifiedDateElement.addText(iso8601DateFormat.format(modifiedDate)); } if (alternateURLs != null) { for (Map.Entry<Locale, String> entry : alternateURLs.entrySet()) { Locale locale = entry.getKey(); String href = entry.getValue(); Element alternateURLElement = urlElement.addElement( "xhtml:link", "http://www.w3.org/1999/xhtml"); alternateURLElement.addAttribute("href", href); alternateURLElement.addAttribute( "hreflang", LocaleUtil.toW3cLanguageId(locale)); alternateURLElement.addAttribute("rel", "alternate"); } Element alternateURLElement = urlElement.addElement( "xhtml:link", "http://www.w3.org/1999/xhtml"); alternateURLElement.addAttribute("rel", "alternate"); alternateURLElement.addAttribute("hreflang", "x-default"); alternateURLElement.addAttribute("href", canonicalURL); } } @Override public String encodeXML(String input) { return StringUtil.replace( input, new char[] {'&', '<', '>', '\'', '\"'}, new String[] {"&", "<", ">", "'", """}); } @Override public Map<Locale, String> getAlternateURLs( String canonicalURL, ThemeDisplay themeDisplay, Layout layout) throws PortalException { return PortalUtil.getAlternateURLs(canonicalURL, themeDisplay, layout); } @Override public String getSitemap( long groupId, boolean privateLayout, ThemeDisplay themeDisplay) throws PortalException { return getSitemap(null, groupId, privateLayout, themeDisplay); } @Override public String getSitemap( String layoutUuid, long groupId, boolean privateLayout, ThemeDisplay themeDisplay) throws PortalException { Document document = SAXReaderUtil.createDocument(); document.setXMLEncoding(StringPool.UTF8); Element rootElement = null; if (Validator.isNull(layoutUuid)) { rootElement = document.addElement( "sitemapindex", "http://www.sitemaps.org/schemas/sitemap/0.9"); } else { rootElement = document.addElement( "urlset", "http://www.sitemaps.org/schemas/sitemap/0.9"); } rootElement.addAttribute("xmlns:xhtml", "http://www.w3.org/1999/xhtml"); LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet( groupId, privateLayout); if (Validator.isNull(layoutUuid)) { visitLayoutSet(rootElement, layoutSet, themeDisplay); return document.asXML(); } List<SitemapURLProvider> sitemapURLProviders = SitemapURLProviderRegistryUtil.getSitemapURLProviders(); for (SitemapURLProvider sitemapURLProvider : sitemapURLProviders) { sitemapURLProvider.visitLayout( rootElement, layoutUuid, layoutSet, themeDisplay); } return document.asXML(); } protected void visitLayoutSet( Element element, LayoutSet layoutSet, ThemeDisplay themeDisplay) { if (layoutSet.isPrivateLayout()) { return; } String portalURL = themeDisplay.getPortalURL(); Map<String, LayoutTypeController> layoutTypeControllers = LayoutTypeControllerTracker.getLayoutTypeControllers(); for (Map.Entry<String, LayoutTypeController> entry : layoutTypeControllers.entrySet()) { LayoutTypeController layoutTypeController = entry.getValue(); if (!layoutTypeController.isSitemapable()) { continue; } List<Layout> layouts = LayoutLocalServiceUtil.getLayouts( layoutSet.getGroupId(), layoutSet.getPrivateLayout(), entry.getKey()); for (Layout layout : layouts) { Element sitemapElement = element.addElement("sitemap"); Element locationElement = sitemapElement.addElement("loc"); StringBundler sb = new StringBundler(8); sb.append(portalURL); sb.append(PortalUtil.getPathContext()); sb.append("/sitemap.xml?layoutUuid="); sb.append(layout.getUuid()); sb.append("&groupId="); sb.append(layoutSet.getGroupId()); sb.append("&privateLayout="); sb.append(layout.getPrivateLayout()); locationElement.addText(sb.toString()); } } } }