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.Tag; 035import org.ametys.cms.tag.Tag.TagVisibility; 036import org.ametys.cms.tag.TagHelper; 037import org.ametys.cms.tag.TagProviderExtensionPoint; 038import org.ametys.plugins.blog.BlogCacheManager; 039import org.ametys.plugins.blog.BlogCacheManager.Post; 040import org.ametys.plugins.blog.BlogPageHandler; 041import org.ametys.plugins.blog.repository.VirtualMonthPage; 042import org.ametys.plugins.blog.repository.VirtualPostPage; 043import org.ametys.plugins.blog.repository.VirtualTagPage; 044import org.ametys.plugins.blog.repository.VirtualTagsPage; 045import org.ametys.plugins.blog.repository.VirtualYearPage; 046import org.ametys.plugins.repository.UnknownAmetysObjectException; 047import org.ametys.web.repository.page.Page; 048import org.ametys.web.repository.page.PagesContainer; 049 050/** 051 * Blog pages generator. 052 */ 053public class BlogPagesGenerator extends ServiceableGenerator 054{ 055 /** The blog cache manager. */ 056 private BlogPageHandler _blogRootPageHandler; 057 058 /** The blog cache manager */ 059 private BlogCacheManager _blogCacheManager; 060 061 /** The extension point for tag providers. */ 062 private TagProviderExtensionPoint _tagProviderExtensionPoint; 063 064 @Override 065 public void service(ServiceManager serviceManager) throws ServiceException 066 { 067 super.service(serviceManager); 068 _blogRootPageHandler = (BlogPageHandler) serviceManager.lookup(BlogPageHandler.ROLE); 069 _blogCacheManager = (BlogCacheManager) serviceManager.lookup(BlogCacheManager.ROLE); 070 _tagProviderExtensionPoint = (TagProviderExtensionPoint) serviceManager.lookup(TagProviderExtensionPoint.ROLE); 071 } 072 073 @Override 074 public void generate() throws IOException, SAXException, ProcessingException 075 { 076 Request request = ObjectModelHelper.getRequest(objectModel); 077 Page currentPage = (Page) request.getAttribute(Page.class.getName()); 078 079 String site = parameters.getParameter("site", currentPage.getSiteName()); 080 String language = parameters.getParameter("lang", currentPage.getSitemapName()); 081 String pagePath = parameters.getParameter("page-path", ""); 082 int depth = parameters.getParameterAsInteger("depth", -1); 083 084 // Service parameters 085 String excludePrivateAsString = parameters.getParameter("excludePrivateTags", request.getParameter("excludePrivateTags")); 086 boolean excludePrivate = Boolean.parseBoolean(excludePrivateAsString); 087 088 String rootTagName = parameters.getParameter("tag", request.getParameter("tag")); 089 090 PagesContainer container = null; 091 if (StringUtils.isEmpty(pagePath)) 092 { 093 // SAX all pages 094 container = _blogRootPageHandler.getBlogRootPage(site, language); 095 } 096 else 097 { 098 container = _blogRootPageHandler.getBlogPage(site, language, pagePath); 099 100 if (StringUtils.isNotEmpty(rootTagName) && container instanceof VirtualTagsPage) 101 { 102 // SAX from the specified tag virtual page => find the corresponding container 103 Map<String, Object> params = new HashMap<>(); 104 params.put("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 Tag 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 tag : page.getTags()) 208 { 209 attrs.addCDATAAttribute("PLUGIN_TAGS_" + tag, "empty"); 210 } 211 212 XMLUtils.startElement(contentHandler, "page", attrs); 213 214 _saxPagesContainer(page, depth - 1, siteName, excludePrivate); 215 216 XMLUtils.endElement(contentHandler, "page"); 217 } 218 } 219 } 220} 221