001/* 002 * Copyright 2014 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.explorer.calendars.generators; 017 018import java.io.IOException; 019import java.time.ZonedDateTime; 020import java.time.format.DateTimeFormatter; 021import java.util.Date; 022import java.util.GregorianCalendar; 023import java.util.HashMap; 024import java.util.List; 025import java.util.Map; 026 027import org.apache.avalon.framework.service.ServiceException; 028import org.apache.avalon.framework.service.ServiceManager; 029import org.apache.cocoon.ProcessingException; 030import org.apache.cocoon.environment.ObjectModelHelper; 031import org.apache.cocoon.environment.Request; 032import org.apache.cocoon.generation.ServiceableGenerator; 033import org.apache.cocoon.xml.AttributesImpl; 034import org.apache.cocoon.xml.XMLUtils; 035import org.apache.commons.lang.StringUtils; 036import org.xml.sax.SAXException; 037 038import org.ametys.core.user.User; 039import org.ametys.core.user.UserIdentity; 040import org.ametys.core.user.UserManager; 041import org.ametys.plugins.explorer.calendars.Calendar; 042import org.ametys.plugins.explorer.calendars.CalendarEvent; 043import org.ametys.plugins.explorer.workflow.AbstractExplorerNodeWorkflowComponent; 044import org.ametys.plugins.repository.AmetysObject; 045import org.ametys.plugins.repository.AmetysObjectResolver; 046import org.ametys.plugins.repository.ModifiableAmetysObject; 047import org.ametys.plugins.repository.RemovableAmetysObject; 048import org.ametys.plugins.workflow.support.WorkflowHelper; 049import org.ametys.plugins.workflow.support.WorkflowProvider; 050import org.ametys.runtime.i18n.I18nizableText; 051import org.ametys.runtime.parameter.ParameterHelper; 052import org.ametys.runtime.parameter.ParameterHelper.ParameterType; 053 054import com.opensymphony.workflow.Workflow; 055import com.opensymphony.workflow.spi.Step; 056 057/** 058 * Generate all the needed calendar's informations 059 */ 060public class CalendarEventInfoGenerator extends ServiceableGenerator 061{ 062 /** The object resolver */ 063 protected AmetysObjectResolver _resolver; 064 /** The ametys users manager */ 065 protected UserManager _userManager; 066 /** The workflow provider */ 067 protected WorkflowProvider _workflowProvider; 068 /** The workflow helper */ 069 protected WorkflowHelper _workflowHelper; 070 071 @Override 072 public void service(ServiceManager serviceManager) throws ServiceException 073 { 074 super.service(serviceManager); 075 _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE); 076 _userManager = (UserManager) serviceManager.lookup(UserManager.ROLE); 077 _workflowProvider = (WorkflowProvider) serviceManager.lookup(WorkflowProvider.ROLE); 078 _workflowHelper = (WorkflowHelper) serviceManager.lookup(WorkflowHelper.ROLE); 079 } 080 081 public void generate() throws IOException, SAXException, ProcessingException 082 { 083 Request request = ObjectModelHelper.getRequest(objectModel); 084 085 String startDateString = request.getParameter("start"); 086 Date startDate = (Date) ParameterHelper.castValue(startDateString, ParameterType.DATE); 087 088 String endDateString = request.getParameter("end"); 089 Date endDate = (Date) ParameterHelper.castValue(endDateString, ParameterType.DATE); 090 091 String handleWorkflowInit = request.getParameter("handleWorkflowInit"); 092 093 contentHandler.startDocument(); 094 XMLUtils.startElement(contentHandler, "infos"); 095 096 String ids = request.getParameter("ids"); 097 String occurrencesDate = request.getParameter("occurrencesDate"); 098 099 if (StringUtils.isNotBlank(ids) && StringUtils.isNotBlank(occurrencesDate)) 100 { 101 String[] eventsIds = StringUtils.split(ids, ","); 102 String[] eventOccurrencesDate = StringUtils.split(occurrencesDate, ","); 103 104 XMLUtils.startElement(contentHandler, "events"); 105 for (int i = 0; i < eventsIds.length; i++) 106 { 107 String id = eventsIds[i]; 108 String occurrenceDate = eventOccurrencesDate[i]; 109 110 long date = ZonedDateTime.parse(occurrenceDate, DateTimeFormatter.ISO_DATE_TIME).toInstant().toEpochMilli(); 111 CalendarEvent event = _resolver.resolveById(id); 112 _saxEvent(event, new Date(date)); 113 } 114 XMLUtils.endElement(contentHandler, "events"); 115 } 116 else 117 { 118 String calendarId = request.getParameter("calendarId"); 119 if (calendarId != null) 120 { 121 Calendar calendar = _resolver.resolveById(calendarId); 122 123 if ("true".equals(request.getParameter("fromRootCalendar"))) 124 { 125 AmetysObject parent = calendar; 126 127 while (parent instanceof Calendar) 128 { 129 calendar = (Calendar) parent; 130 parent = parent.getParent(); 131 } 132 } 133 134 _saxCalendar(calendar, "true".equals(request.getParameter("recursive")), "true".equals(request.getParameter("sax-events")), startDate, endDate, handleWorkflowInit); 135 } 136 } 137 138 XMLUtils.endElement(contentHandler, "infos"); 139 contentHandler.endDocument(); 140 } 141 142 private void _saxCalendar(Calendar calendar, boolean recursive, boolean saxEvents, Date startDate, Date endDate, String handleWorkflowInit) throws SAXException 143 { 144 AttributesImpl attr = new AttributesImpl(); 145 attr.addCDATAAttribute("id", calendar.getId()); 146 attr.addCDATAAttribute("title", calendar.getName()); 147 attr.addCDATAAttribute("desc", calendar.getDescription()); 148 attr.addCDATAAttribute("templateDesc", calendar.getTemplateDescription()); 149 attr.addCDATAAttribute("color", calendar.getColor()); 150 attr.addCDATAAttribute("workflowName", calendar.getWorkflowName()); 151 attr.addCDATAAttribute("modifiable", calendar instanceof ModifiableAmetysObject ? "true" : "false"); 152 attr.addCDATAAttribute("hasRight", "true"); 153 attr.addCDATAAttribute("removable", calendar instanceof RemovableAmetysObject ? "true" : "false"); 154 155 HashMap<String, Object> inputs = new HashMap<>(); 156 inputs.put(AbstractExplorerNodeWorkflowComponent.EXPLORERNODE_KEY, calendar); 157 if (handleWorkflowInit == null) 158 { 159 Workflow workflow = _workflowProvider.getAmetysObjectWorkflow(); 160 attr.addCDATAAttribute("canInitWorkflow", workflow.canInitialize(calendar.getWorkflowName(), 1, inputs) ? "true" : "false"); 161 } 162 else 163 { 164 attr.addCDATAAttribute("canInitWorkflow", "true"); 165 } 166 XMLUtils.startElement(contentHandler, "calendar", attr); 167 168 if (recursive) 169 { 170 XMLUtils.startElement(contentHandler, "calendars"); 171 for (AmetysObject object : calendar.getChildren()) 172 { 173 if (object instanceof Calendar) 174 { 175 Calendar subCalendar = (Calendar) object; 176 _saxCalendar(subCalendar, recursive, saxEvents, startDate, endDate, handleWorkflowInit); 177 } 178 } 179 XMLUtils.endElement(contentHandler, "calendars"); 180 } 181 182 if (saxEvents) 183 { 184 XMLUtils.startElement(contentHandler, "events"); 185 186 for (Map.Entry<CalendarEvent, List<Date>> entry : calendar.getEvents(startDate, endDate).entrySet()) 187 { 188 CalendarEvent event = entry.getKey(); 189 List<Date> occurences = entry.getValue(); 190 for (Date date : occurences) 191 { 192 _saxEvent(event, date); 193 } 194 } 195 XMLUtils.endElement(contentHandler, "events"); 196 } 197 198 XMLUtils.endElement(contentHandler, "calendar"); 199 } 200 201 private void _saxEvent(CalendarEvent event, Date date) throws SAXException 202 { 203 AttributesImpl attr = new AttributesImpl(); 204 String id = event.getId() + "$" + ParameterHelper.valueToString(date); 205 attr.addCDATAAttribute("id", id); 206 attr.addCDATAAttribute("calendarId", event.getParent().getId()); 207 attr.addCDATAAttribute("workflowId", event.getWorkflowId() + ""); 208 attr.addCDATAAttribute("color", ((Calendar) event.getParent()).getColor()); 209 attr.addCDATAAttribute("modifiable", "true"); 210 211 XMLUtils.startElement(contentHandler, "event", attr); 212 213 Workflow workflow = _workflowProvider.getAmetysObjectWorkflow(event); 214 List<Step> listSteps = workflow.getCurrentSteps(event.getWorkflowId()); 215 if (!listSteps.isEmpty()) 216 { 217 // We select the first current step 218 Step step = listSteps.get(0); 219 String stepDesc = _workflowHelper.getStepName(((Calendar) event.getParent()).getWorkflowName(), step.getStepId()); 220 I18nizableText workflowStepName = new I18nizableText("application", stepDesc); 221 222 if ("application".equals(workflowStepName.getCatalogue())) 223 { 224 XMLUtils.createElement(contentHandler, "icon-small-workflow", "/plugins/explorer/resources_workflow/" + workflowStepName.getKey() + "-small.png"); 225 } 226 else 227 { 228 String pluginName = workflowStepName.getCatalogue().substring("plugin.".length()); 229 XMLUtils.createElement(contentHandler, "icon-small-workflow", "/plugins/" + pluginName + "/resources/img/workflow/" + workflowStepName.getKey() + "-small.png"); 230 } 231 } 232 233 XMLUtils.createElement(contentHandler, "title", event.getTitle()); 234 XMLUtils.createElement(contentHandler, "desc", event.getDescription()); 235 XMLUtils.createElement(contentHandler, "fullDay", event.getFullDay() ? "true" : "false"); 236 237 XMLUtils.createElement(contentHandler, "recurrenceType", event.getRecurrenceType().toString()); 238 239 String untilDateAsString = ""; 240 Date untilDate = event.getRepeatUntil(); 241 if (untilDate != null) 242 { 243 untilDateAsString = ParameterHelper.valueToString(untilDate); 244 } 245 XMLUtils.createElement(contentHandler, "untilDate", untilDateAsString); 246 247 Date firstStartDateEvent = event.getStartDate(); 248 Date firstEndDateEvent = event.getEndDate(); 249 250 long diff = firstEndDateEvent.getTime() - firstStartDateEvent.getTime(); 251 Date startDateEvent = date; 252 Date endDateEvent = new Date(date.getTime() + diff); 253 254 if (event.getFullDay()) 255 { 256 GregorianCalendar gcStart = new GregorianCalendar(); 257 gcStart.setTime(startDateEvent); 258 gcStart.set(java.util.Calendar.HOUR_OF_DAY, 0); 259 gcStart.set(java.util.Calendar.MINUTE, 0); 260 gcStart.set(java.util.Calendar.SECOND, 0); 261 gcStart.set(java.util.Calendar.MILLISECOND, 0); 262 263 startDateEvent = gcStart.getTime(); 264 265 GregorianCalendar gcEnd = new GregorianCalendar(); 266 gcEnd.setTime(endDateEvent); 267 gcEnd.set(java.util.Calendar.HOUR_OF_DAY, 23); 268 gcEnd.set(java.util.Calendar.MINUTE, 59); 269 gcEnd.set(java.util.Calendar.SECOND, 59); 270 gcEnd.set(java.util.Calendar.MILLISECOND, 999); 271 272 endDateEvent = gcEnd.getTime(); 273 } 274 275 XMLUtils.createElement(contentHandler, "startDate", ParameterHelper.valueToString(startDateEvent)); 276 XMLUtils.createElement(contentHandler, "endDate", ParameterHelper.valueToString(endDateEvent)); 277 _saxUser(event.getCreator(), "creator"); 278 XMLUtils.createElement(contentHandler, "creationDate", ParameterHelper.valueToString(event.getCreationDate())); 279 _saxUser(event.getLastContributor(), "contributor"); 280 XMLUtils.createElement(contentHandler, "lastModified", ParameterHelper.valueToString(event.getLastModified())); 281 282 UserIdentity validator = event.getLastValidator(); 283 if (validator != null) 284 { 285 _saxUser(validator, "validator"); 286 } 287 288 Date lastValidated = event.getLastValidated(); 289 if (lastValidated != null) 290 { 291 XMLUtils.createElement(contentHandler, "lastValidated", ParameterHelper.valueToString(lastValidated)); 292 } 293 294 XMLUtils.endElement(contentHandler, "event"); 295 } 296 297 private void _saxUser(UserIdentity userIdentity, String tagName) throws SAXException 298 { 299 AttributesImpl attr = new AttributesImpl(); 300 attr.addCDATAAttribute("login", userIdentity.getLogin()); 301 attr.addCDATAAttribute("population", userIdentity.getPopulationId()); 302 303 User user = _userManager.getUser(userIdentity.getPopulationId(), userIdentity.getLogin()); 304 if (user != null) 305 { 306 attr.addCDATAAttribute("fullName", user.getFullName()); 307 } 308 309 XMLUtils.createElement(contentHandler, tagName, attr); 310 } 311}