/**
* 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());
}
}
}
}