001/* 002 * Copyright 2017 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.calendar.events; 017 018import java.io.IOException; 019import java.time.LocalDate; 020import java.time.ZonedDateTime; 021import java.time.format.DateTimeFormatter; 022import java.util.ArrayList; 023import java.util.Collection; 024import java.util.List; 025import java.util.Optional; 026 027import org.apache.avalon.framework.service.ServiceException; 028import org.apache.avalon.framework.service.ServiceManager; 029import org.apache.cocoon.components.source.impl.SitemapSource; 030import org.apache.cocoon.generation.ServiceableGenerator; 031import org.apache.cocoon.xml.AttributesImpl; 032import org.apache.cocoon.xml.XMLUtils; 033import org.apache.excalibur.source.SourceResolver; 034import org.xml.sax.ContentHandler; 035import org.xml.sax.SAXException; 036 037import org.ametys.cms.repository.Content; 038import org.ametys.core.util.IgnoreRootHandler; 039import org.ametys.runtime.i18n.I18nizableText; 040import org.ametys.runtime.model.type.ModelItemType; 041import org.ametys.runtime.model.type.ModelItemTypeConstants; 042import org.ametys.web.filter.ContentFilterHelper; 043import org.ametys.web.filter.WebContentFilter; 044import org.ametys.web.repository.content.WebContent; 045import org.ametys.web.repository.page.Page; 046 047/** 048 * Abstract generator provinding methods to sax an event content 049 */ 050public abstract class AbstractEventGenerator extends ServiceableGenerator 051{ 052 /** The source resolver. */ 053 protected SourceResolver _resolver; 054 055 /** The content filter helper. */ 056 protected ContentFilterHelper _filterHelper; 057 058 @Override 059 public void service(ServiceManager serviceManager) throws ServiceException 060 { 061 super.service(serviceManager); 062 _resolver = (SourceResolver) serviceManager.lookup(SourceResolver.ROLE); 063 _filterHelper = (ContentFilterHelper) serviceManager.lookup(ContentFilterHelper.ROLE); 064 } 065 066 /** 067 * SAX a content 068 * 069 * @param handler The content handler to SAX into 070 * @param content The content. 071 * @param saxContentItSelf true to sax the content, false will only sax some meta 072 * @param filter The filter. Can be null if saxContentItSelf is false 073 * @param checkUserAccess True to check user access when saxing the content itself 074 * @throws SAXException If an error occurs while SAXing 075 * @throws IOException If an error occurs while retrieving content. 076 */ 077 public void saxContent(ContentHandler handler, Content content, boolean saxContentItSelf, WebContentFilter filter, boolean checkUserAccess) throws SAXException, IOException 078 { 079 List<String> params = new ArrayList<>(); 080 params.add(content.getTitle()); 081 082 AttributesImpl attrs = new AttributesImpl(); 083 084 String start = _getFormatedDateAttribute(content, EventsFilterHelper.START_DATE_META); 085 if (start != null) 086 { 087 params.add(start); 088 attrs.addCDATAAttribute("start", start); 089 } 090 091 String end = _getFormatedDateAttribute(content, EventsFilterHelper.END_DATE_META); 092 if (end != null) 093 { 094 params.add(end); 095 attrs.addCDATAAttribute("end", end); 096 } 097 098 XMLUtils.startElement(handler, "event", attrs); 099 100 String key = end == null ? "CALENDAR_SERVICE_AGENDA_EVENT_TITLE_SINGLE_DAY" : "CALENDAR_SERVICE_AGENDA_FROM_TO"; 101 I18nizableText description = new I18nizableText(null, key, params); 102 103 description.toSAX(handler, "description"); 104 105 if (saxContentItSelf) 106 { 107 // Link view. 108 XMLUtils.startElement(handler, "view"); 109 _filterHelper.saxContent(handler, content, filter.getView(), checkUserAccess); 110 XMLUtils.endElement(handler, "view"); 111 } 112 113 // XML full view. 114 saxXMLContent(handler, content, "main"); 115 116 if (content instanceof WebContent) 117 { 118 WebContent webContent = (WebContent) content; 119 120 XMLUtils.startElement(handler, "pages"); 121 Collection<Page> pages = webContent.getReferencingPages(); 122 for (Page page : pages) 123 { 124 AttributesImpl atts = new AttributesImpl(); 125 atts.addCDATAAttribute("id", page.getId()); 126 atts.addCDATAAttribute("name", page.getName()); 127 atts.addCDATAAttribute("lang", page.getSitemapName()); 128 atts.addCDATAAttribute("site", page.getSiteName()); 129 atts.addCDATAAttribute("path", page.getPathInSitemap()); 130 atts.addCDATAAttribute("title", page.getTitle()); 131 XMLUtils.createElement(handler, "page", atts); 132 } 133 XMLUtils.endElement(handler, "pages"); 134 } 135 XMLUtils.endElement(handler, "event"); 136 } 137 138 /** 139 * Retrieves the formated value of the date attribute of the given content 140 * @param content the content 141 * @param attributePath the path of the attribute. The attribute must be date or date time 142 * @return the formated value 143 */ 144 protected String _getFormatedDateAttribute(Content content, String attributePath) 145 { 146 ModelItemType attributeType = content.getType(attributePath); 147 148 if (ModelItemTypeConstants.DATE_TYPE_ID.equals(attributeType.getId())) 149 { 150 LocalDate date = content.getValue(attributePath); 151 return Optional.ofNullable(date).map(d -> d.atStartOfDay().format(DateTimeFormatter.ISO_LOCAL_DATE)).orElse(null); 152 } 153 else 154 { 155 ZonedDateTime date = content.getValue(attributePath); 156 return Optional.ofNullable(date).map(d -> d.format(DateTimeFormatter.ISO_LOCAL_DATE)).orElse(null); 157 } 158 } 159 160 /** 161 * SAX a content in XML mode. 162 * 163 * @param handler The content handler to SAX into 164 * @param content The content to SAX 165 * @param viewName The view to use 166 * @throws SAXException If an error occurs while SAXing 167 * @throws IOException If an error occurs while retrieving content. 168 */ 169 public void saxXMLContent(ContentHandler handler, Content content, String viewName) throws SAXException, IOException 170 { 171 String uri = "cocoon://_content.xml?contentId=" + content.getId() + "&viewName=" + viewName; 172 SitemapSource src = null; 173 174 try 175 { 176 src = (SitemapSource) _resolver.resolveURI(uri); 177 src.toSAX(new IgnoreRootHandler(handler)); 178 } 179 finally 180 { 181 _resolver.release(src); 182 } 183 } 184}