001/* 002 * Copyright 2015 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.blog.posts; 017 018import java.io.IOException; 019import java.util.HashMap; 020import java.util.Map; 021import java.util.Set; 022 023import org.apache.avalon.framework.service.ServiceException; 024import org.apache.avalon.framework.service.ServiceManager; 025import org.apache.cocoon.ProcessingException; 026import org.apache.cocoon.environment.ObjectModelHelper; 027import org.apache.cocoon.environment.Request; 028import org.apache.cocoon.generation.ServiceableGenerator; 029import org.apache.cocoon.xml.AttributesImpl; 030import org.apache.cocoon.xml.XMLUtils; 031import org.apache.commons.lang.StringUtils; 032import org.xml.sax.SAXException; 033 034import org.ametys.cms.tag.CMSTag; 035import org.ametys.cms.tag.CMSTag.TagVisibility; 036import org.ametys.cms.tag.Tag; 037import org.ametys.cms.tag.TagHelper; 038import org.ametys.cms.tag.TagProviderExtensionPoint; 039import org.ametys.plugins.blog.BlogCacheManager; 040import org.ametys.plugins.blog.BlogCacheManager.Post; 041import org.ametys.plugins.blog.BlogPageHandler; 042import org.ametys.plugins.blog.repository.VirtualMonthPage; 043import org.ametys.plugins.blog.repository.VirtualPostPage; 044import org.ametys.plugins.blog.repository.VirtualTagPage; 045import org.ametys.plugins.blog.repository.VirtualTagsPage; 046import org.ametys.plugins.blog.repository.VirtualYearPage; 047import org.ametys.plugins.repository.UnknownAmetysObjectException; 048import org.ametys.web.repository.page.Page; 049import org.ametys.web.repository.page.PagesContainer; 050 051/** 052 * Blog pages generator. 053 */ 054public class BlogPagesGenerator extends ServiceableGenerator 055{ 056 /** The blog cache manager. */ 057 private BlogPageHandler _blogRootPageHandler; 058 059 /** The blog cache manager */ 060 private BlogCacheManager _blogCacheManager; 061 062 /** The extension point for tag providers. */ 063 private TagProviderExtensionPoint _tagProviderExtensionPoint; 064 065 @Override 066 public void service(ServiceManager serviceManager) throws ServiceException 067 { 068 super.service(serviceManager); 069 _blogRootPageHandler = (BlogPageHandler) serviceManager.lookup(BlogPageHandler.ROLE); 070 _blogCacheManager = (BlogCacheManager) serviceManager.lookup(BlogCacheManager.ROLE); 071 _tagProviderExtensionPoint = (TagProviderExtensionPoint) serviceManager.lookup(TagProviderExtensionPoint.ROLE); 072 } 073 074 @Override 075 public void generate() throws IOException, SAXException, ProcessingException 076 { 077 Request request = ObjectModelHelper.getRequest(objectModel); 078 Page currentPage = (Page) request.getAttribute(Page.class.getName()); 079 080 String site = parameters.getParameter("site", currentPage.getSiteName()); 081 String language = parameters.getParameter("lang", currentPage.getSitemapName()); 082 String pagePath = parameters.getParameter("page-path", ""); 083 int depth = parameters.getParameterAsInteger("depth", -1); 084 085 // Service parameters 086 String excludePrivateAsString = parameters.getParameter("excludePrivateTags", request.getParameter("excludePrivateTags")); 087 boolean excludePrivate = Boolean.parseBoolean(excludePrivateAsString); 088 089 String rootTagName = parameters.getParameter("tag", request.getParameter("tag")); 090 091 PagesContainer container = null; 092 if (StringUtils.isEmpty(pagePath)) 093 { 094 // SAX all pages 095 container = _blogRootPageHandler.getBlogRootPage(site, language); 096 } 097 else 098 { 099 container = _blogRootPageHandler.getBlogPage(site, language, pagePath); 100 101 if (StringUtils.isNotEmpty(rootTagName) && container instanceof VirtualTagsPage) 102 { 103 // SAX from the specified tag virtual page => find the corresponding container 104 Map<String, Object> params = Map.of("siteName", site); 105 Tag tag = _tagProviderExtensionPoint.getTag(rootTagName, params); 106 107 if (tag != null) 108 { 109 Set<String> ancestorNames = TagHelper.getAncestorNames(tag, true); 110 try 111 { 112 container = container.getChild(StringUtils.join(ancestorNames, "/")); 113 } 114 catch (UnknownAmetysObjectException e) 115 { 116 // There is no virtual tag page for this tag (= no post) 117 container = null; 118 } 119 } 120 else 121 { 122 // Tag does not exist anymore 123 getLogger().error("Navigation by tags can not be displayed with the unexisting tag '" + rootTagName + "'."); 124 container = null; 125 } 126 } 127 } 128 129 contentHandler.startDocument(); 130 131 XMLUtils.startElement(contentHandler, "pages"); 132 133 if (container != null) 134 { 135 _saxPagesContainer(container, depth, site, excludePrivate); 136 } 137 138 XMLUtils.endElement(contentHandler, "pages"); 139 140 contentHandler.endDocument(); 141 } 142 143 /** 144 * SAX the pages 145 * @param pagesContainer the page or sitemap from which we start to SAX 146 * @param depth the remaining levels of pages to SAX 147 * @param siteName the site's name 148 * @param excludePrivate true to exclude private pages, false otherwise 149 * @throws SAXException if an error occurs while SAXing the pages' information 150 */ 151 private void _saxPagesContainer(PagesContainer pagesContainer, int depth, String siteName, boolean excludePrivate) throws SAXException 152 { 153 if (depth != 0) 154 { 155 for (Page page : pagesContainer.getChildrenPages()) 156 { 157 AttributesImpl attrs = new AttributesImpl (); 158 attrs.addCDATAAttribute("name", page.getName()); 159 attrs.addCDATAAttribute("title", page.getTitle()); 160 attrs.addCDATAAttribute("long-title", page.getLongTitle()); 161 attrs.addCDATAAttribute("path", page.getPathInSitemap()); 162 attrs.addCDATAAttribute("id", page.getId()); 163 164 if (page instanceof VirtualPostPage) 165 { 166 attrs.addCDATAAttribute("type", "post"); 167 } 168 else if (page instanceof VirtualTagPage) 169 { 170 VirtualTagPage tagPage = (VirtualTagPage) page; 171 String tagName = tagPage.getTagName(); 172 173 Map<String, Object> contextualParams = new HashMap<>(); 174 contextualParams.put("siteName", siteName); 175 176 CMSTag tag = _tagProviderExtensionPoint.getTag(tagName, contextualParams); 177 178 if (!excludePrivate || !tag.getVisibility().equals(TagVisibility.PRIVATE)) 179 { 180 // no test on tag visibility 181 attrs.addCDATAAttribute("type", "tag"); 182 183 String language = tagPage.getSitemapName(); 184 Map<String, Post> postsByTag = _blogCacheManager.getPostsByTag(siteName, language, tagName); 185 186 attrs.addCDATAAttribute("entries", String.valueOf(postsByTag.keySet().size())); 187 } 188 } 189 else if (page instanceof VirtualYearPage) 190 { 191 attrs.addCDATAAttribute("type", "year"); 192 } 193 else if (page instanceof VirtualMonthPage) 194 { 195 attrs.addCDATAAttribute("type", "month"); 196 197 VirtualMonthPage monthPage = (VirtualMonthPage) page; 198 String language = monthPage.getSitemapName(); 199 int year = monthPage.getYear(); 200 int month = monthPage.getMonth(); 201 202 Map<String, Post> postsByMonth = _blogCacheManager.getPostsByMonth(siteName, language, year, month); 203 204 attrs.addCDATAAttribute("entries", String.valueOf(postsByMonth.keySet().size())); 205 } 206 207 for (String tagName : page.getTags()) 208 { 209 Map<String, Object> params = Map.of("siteName", siteName); 210 Tag tag = _tagProviderExtensionPoint.getTag(tagName, params); 211 212 if (tag != null) 213 { 214 attrs.addCDATAAttribute("PLUGIN_TAGS_" + tagName, "empty"); 215 } 216 } 217 218 XMLUtils.startElement(contentHandler, "page", attrs); 219 220 _saxPagesContainer(page, depth - 1, siteName, excludePrivate); 221 222 XMLUtils.endElement(contentHandler, "page"); 223 } 224 } 225 } 226} 227