001
014
015 package com.liferay.portlet.layoutsadmin.util;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.language.LanguageUtil;
020 import com.liferay.portal.kernel.util.DateUtil;
021 import com.liferay.portal.kernel.util.GetterUtil;
022 import com.liferay.portal.kernel.util.LocaleUtil;
023 import com.liferay.portal.kernel.util.StringBundler;
024 import com.liferay.portal.kernel.util.StringPool;
025 import com.liferay.portal.kernel.util.StringUtil;
026 import com.liferay.portal.kernel.util.UnicodeProperties;
027 import com.liferay.portal.kernel.util.Validator;
028 import com.liferay.portal.kernel.workflow.WorkflowConstants;
029 import com.liferay.portal.kernel.xml.Document;
030 import com.liferay.portal.kernel.xml.Element;
031 import com.liferay.portal.kernel.xml.SAXReaderUtil;
032 import com.liferay.portal.model.Layout;
033 import com.liferay.portal.model.LayoutConstants;
034 import com.liferay.portal.service.GroupLocalServiceUtil;
035 import com.liferay.portal.service.LayoutLocalServiceUtil;
036 import com.liferay.portal.theme.ThemeDisplay;
037 import com.liferay.portal.util.PortalUtil;
038 import com.liferay.portal.util.PropsValues;
039 import com.liferay.portlet.journal.model.JournalArticle;
040 import com.liferay.portlet.journal.model.JournalArticleConstants;
041 import com.liferay.portlet.journal.service.JournalArticleServiceUtil;
042
043 import java.text.DateFormat;
044
045 import java.util.ArrayList;
046 import java.util.Date;
047 import java.util.List;
048 import java.util.Locale;
049
050
054 public class SitemapImpl implements Sitemap {
055
056 public String encodeXML(String input) {
057 return StringUtil.replace(
058 input,
059 new String[] {"&", "<", ">", "'", "\""},
060 new String[] {"&", "<", ">", "'", """});
061 }
062
063 public String getSitemap(
064 long groupId, boolean privateLayout, ThemeDisplay themeDisplay)
065 throws PortalException, SystemException {
066
067 Document document = SAXReaderUtil.createDocument();
068
069 document.setXMLEncoding(StringPool.UTF8);
070
071 Element rootElement = document.addElement(
072 "urlset", "http:
073
074 List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(
075 groupId, privateLayout, LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
076
077 visitLayouts(rootElement, layouts, themeDisplay);
078
079 return document.asXML();
080 }
081
082 protected void addURLElement(
083 Element element, String url, UnicodeProperties typeSettingsProperties,
084 Date modifiedDate) {
085
086 Element urlElement = element.addElement("url");
087
088 Element locElement = urlElement.addElement("loc");
089
090 locElement.addText(encodeXML(url));
091
092 if (typeSettingsProperties == null) {
093 if (Validator.isNotNull(
094 PropsValues.SITES_SITEMAP_DEFAULT_CHANGE_FREQUENCY)) {
095
096 Element changefreqElement = urlElement.addElement("changefreq");
097
098 changefreqElement.addText(
099 PropsValues.SITES_SITEMAP_DEFAULT_CHANGE_FREQUENCY);
100 }
101
102 if (Validator.isNotNull(
103 PropsValues.SITES_SITEMAP_DEFAULT_PRIORITY)) {
104
105 Element priorityElement = urlElement.addElement("priority");
106
107 priorityElement.addText(
108 PropsValues.SITES_SITEMAP_DEFAULT_PRIORITY);
109 }
110 }
111 else {
112 String changefreq = typeSettingsProperties.getProperty(
113 "sitemap-changefreq");
114
115 if (Validator.isNotNull(changefreq)) {
116 Element changefreqElement = urlElement.addElement("changefreq");
117
118 changefreqElement.addText(changefreq);
119 }
120 else if (Validator.isNotNull(
121 PropsValues.SITES_SITEMAP_DEFAULT_CHANGE_FREQUENCY)) {
122
123 Element changefreqElement = urlElement.addElement("changefreq");
124
125 changefreqElement.addText(
126 PropsValues.SITES_SITEMAP_DEFAULT_CHANGE_FREQUENCY);
127 }
128
129 String priority = typeSettingsProperties.getProperty(
130 "sitemap-priority");
131
132 if (Validator.isNotNull(priority)) {
133 Element priorityElement = urlElement.addElement("priority");
134
135 priorityElement.addText(priority);
136 }
137 else if (Validator.isNotNull(
138 PropsValues.SITES_SITEMAP_DEFAULT_PRIORITY)) {
139
140 Element priorityElement = urlElement.addElement("priority");
141
142 priorityElement.addText(
143 PropsValues.SITES_SITEMAP_DEFAULT_PRIORITY);
144 }
145 }
146
147 if (modifiedDate != null) {
148 Element modifiedDateElement = urlElement.addElement("lastmod");
149
150 DateFormat iso8601DateFormat = DateUtil.getISO8601Format();
151
152 modifiedDateElement.addText(iso8601DateFormat.format(modifiedDate));
153 }
154 }
155
156 protected void visitArticles(
157 Element element, Layout layout, ThemeDisplay themeDisplay)
158 throws PortalException, SystemException {
159
160 List<JournalArticle> journalArticles =
161 JournalArticleServiceUtil.getArticlesByLayoutUuid(
162 layout.getGroupId(), layout.getUuid());
163
164 if (journalArticles.isEmpty()) {
165 return;
166 }
167
168 List<String> processedArticleIds = new ArrayList<String>();
169
170 for (JournalArticle journalArticle : journalArticles) {
171 if (processedArticleIds.contains(
172 journalArticle.getArticleId()) ||
173 (journalArticle.getStatus() !=
174 WorkflowConstants.STATUS_APPROVED)) {
175
176 continue;
177 }
178
179 String portalURL = PortalUtil.getPortalURL(layout, themeDisplay);
180
181 String groupFriendlyURL = PortalUtil.getGroupFriendlyURL(
182 GroupLocalServiceUtil.getGroup(journalArticle.getGroupId()),
183 false, themeDisplay);
184
185 StringBundler sb = new StringBundler(4);
186
187 if (!groupFriendlyURL.startsWith(portalURL)) {
188 sb.append(portalURL);
189 }
190
191 sb.append(groupFriendlyURL);
192 sb.append(JournalArticleConstants.CANONICAL_URL_SEPARATOR);
193 sb.append(journalArticle.getUrlTitle());
194
195 String articleURL = PortalUtil.getCanonicalURL(
196 sb.toString(), themeDisplay, layout);
197
198 addURLElement(
199 element, articleURL, null, journalArticle.getModifiedDate());
200
201 Locale[] availableLocales = LanguageUtil.getAvailableLocales();
202
203 if (availableLocales.length > 1) {
204 Locale defaultLocale = LocaleUtil.getDefault();
205
206 for (Locale availableLocale : availableLocales) {
207 if (!availableLocale.equals(defaultLocale)) {
208 String alternateURL = PortalUtil.getAlternateURL(
209 articleURL, themeDisplay, availableLocale);
210
211 addURLElement(
212 element, alternateURL, null,
213 journalArticle.getModifiedDate());
214 }
215 }
216 }
217
218 processedArticleIds.add(journalArticle.getArticleId());
219 }
220 }
221
222 protected void visitLayout(
223 Element element, Layout layout, ThemeDisplay themeDisplay)
224 throws PortalException, SystemException {
225
226 UnicodeProperties typeSettingsProperties =
227 layout.getTypeSettingsProperties();
228
229 if (layout.isHidden() || !PortalUtil.isLayoutSitemapable(layout) ||
230 !GetterUtil.getBoolean(
231 typeSettingsProperties.getProperty("sitemap-include"), true)) {
232
233 return;
234 }
235
236 String layoutFullURL = PortalUtil.getLayoutFullURL(
237 layout, themeDisplay);
238
239 layoutFullURL = PortalUtil.getCanonicalURL(
240 layoutFullURL, themeDisplay, layout);
241
242 addURLElement(
243 element, layoutFullURL, typeSettingsProperties,
244 layout.getModifiedDate());
245
246 Locale[] availableLocales = LanguageUtil.getAvailableLocales();
247
248 if (availableLocales.length > 1) {
249 Locale defaultLocale = LocaleUtil.getDefault();
250
251 for (Locale availableLocale : availableLocales) {
252 if (availableLocale.equals(defaultLocale)) {
253 continue;
254 }
255
256 String alternateURL = PortalUtil.getAlternateURL(
257 layoutFullURL, themeDisplay, availableLocale);
258
259 addURLElement(
260 element, alternateURL, typeSettingsProperties,
261 layout.getModifiedDate());
262 }
263 }
264
265 visitArticles(element, layout, themeDisplay);
266 visitLayouts(element, layout.getChildren(), themeDisplay);
267 }
268
269 protected void visitLayouts(
270 Element element, List<Layout> layouts, ThemeDisplay themeDisplay)
271 throws PortalException, SystemException {
272
273 for (Layout layout : layouts) {
274 visitLayout(element, layout, themeDisplay);
275 }
276 }
277
278 }