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