001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
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.util.GetterUtil;
020    import com.liferay.portal.kernel.util.StringBundler;
021    import com.liferay.portal.kernel.util.StringPool;
022    import com.liferay.portal.kernel.util.StringUtil;
023    import com.liferay.portal.kernel.util.UnicodeProperties;
024    import com.liferay.portal.kernel.util.Validator;
025    import com.liferay.portal.kernel.workflow.WorkflowConstants;
026    import com.liferay.portal.kernel.xml.Document;
027    import com.liferay.portal.kernel.xml.Element;
028    import com.liferay.portal.kernel.xml.SAXReaderUtil;
029    import com.liferay.portal.model.Layout;
030    import com.liferay.portal.model.LayoutConstants;
031    import com.liferay.portal.service.GroupLocalServiceUtil;
032    import com.liferay.portal.service.LayoutLocalServiceUtil;
033    import com.liferay.portal.theme.ThemeDisplay;
034    import com.liferay.portal.util.PortalUtil;
035    import com.liferay.portlet.journal.model.JournalArticle;
036    import com.liferay.portlet.journal.model.JournalArticleConstants;
037    import com.liferay.portlet.journal.service.JournalArticleServiceUtil;
038    
039    import java.util.ArrayList;
040    import java.util.List;
041    
042    /**
043     * @author Jorge Ferrer
044     */
045    public class SitemapImpl implements Sitemap {
046    
047            public String encodeXML(String input) {
048                    return StringUtil.replace(
049                            input,
050                            new String[] {"&", "<", ">", "'", "\""},
051                            new String[] {"&amp;", "&lt;", "&gt;", "&apos;", "&quot;"});
052            }
053    
054            public String getSitemap(
055                            long groupId, boolean privateLayout, ThemeDisplay themeDisplay)
056                    throws PortalException, SystemException {
057    
058                    Document document = SAXReaderUtil.createDocument();
059    
060                    document.setXMLEncoding(StringPool.UTF8);
061    
062                    Element rootElement = document.addElement(
063                            "urlset", "http://www.google.com/schemas/sitemap/0.84");
064    
065                    List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(
066                            groupId, privateLayout, LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
067    
068                    visitLayouts(rootElement, layouts, themeDisplay);
069    
070                    return document.asXML();
071            }
072    
073            protected void visitArticles(
074                            Element element, Layout layout, ThemeDisplay themeDisplay)
075                    throws PortalException, SystemException {
076    
077                    List<JournalArticle> journalArticles =
078                            JournalArticleServiceUtil.getArticlesByLayoutUuid(
079                                    layout.getGroupId(), layout.getUuid());
080    
081                    if (journalArticles.isEmpty()) {
082                            return;
083                    }
084    
085                    List<String> processedArticleIds = new ArrayList<String>();
086    
087                    for (JournalArticle journalArticle : journalArticles) {
088                            if (processedArticleIds.contains(
089                                            journalArticle.getArticleId()) ||
090                                    (journalArticle.getStatus() !=
091                                            WorkflowConstants.STATUS_APPROVED)) {
092    
093                                    continue;
094                            }
095    
096                            String portalURL = PortalUtil.getPortalURL(layout, themeDisplay);
097    
098                            String groupFriendlyURL = PortalUtil.getGroupFriendlyURL(
099                                    GroupLocalServiceUtil.getGroup(journalArticle.getGroupId()),
100                                    false, themeDisplay);
101    
102                            StringBundler sb = new StringBundler(4);
103    
104                            sb.append(portalURL);
105                            sb.append(groupFriendlyURL);
106                            sb.append(JournalArticleConstants.CANONICAL_URL_SEPARATOR);
107                            sb.append(journalArticle.getUrlTitle());
108    
109                            String articleURL = sb.toString();
110    
111                            Element urlElement = element.addElement("url");
112    
113                            Element locElement = urlElement.addElement("loc");
114    
115                            locElement.addText(encodeXML(articleURL));
116    
117                            processedArticleIds.add(journalArticle.getArticleId());
118                    }
119            }
120    
121            protected void visitLayout(
122                            Element element, Layout layout, ThemeDisplay themeDisplay)
123                    throws PortalException, SystemException {
124    
125                    UnicodeProperties typeSettingsProperties =
126                            layout.getTypeSettingsProperties();
127    
128                    if (layout.isHidden() || !PortalUtil.isLayoutSitemapable(layout) ||
129                            !GetterUtil.getBoolean(
130                                    typeSettingsProperties.getProperty("sitemap-include"),
131                                    true)) {
132    
133                            return;
134                    }
135    
136                    Element urlElement = element.addElement("url");
137    
138                    String layoutFullURL = PortalUtil.getLayoutFullURL(
139                            layout, themeDisplay);
140    
141                    Element locElement = urlElement.addElement("loc");
142    
143                    locElement.addText(encodeXML(layoutFullURL));
144    
145                    String changefreq = typeSettingsProperties.getProperty(
146                            "sitemap-changefreq");
147    
148                    if (Validator.isNotNull(changefreq)) {
149                            Element changefreqElement = urlElement.addElement("changefreq");
150    
151                            changefreqElement.addText(changefreq);
152                    }
153    
154                    String priority = typeSettingsProperties.getProperty(
155                            "sitemap-priority");
156    
157                    if (Validator.isNotNull(priority)) {
158                            Element priorityElement = urlElement.addElement("priority");
159    
160                            priorityElement.addText(priority);
161                    }
162    
163                    visitArticles(element, layout, themeDisplay);
164    
165                    List<Layout> children = layout.getChildren();
166    
167                    visitLayouts(element, children, themeDisplay);
168            }
169    
170            protected void visitLayouts(
171                            Element element, List<Layout> layouts, ThemeDisplay themeDisplay)
172                    throws PortalException, SystemException {
173    
174                    for (Layout layout : layouts) {
175                            visitLayout(element, layout,  themeDisplay);
176                    }
177            }
178    
179    }