001/* 002 * Copyright 2025 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.workspaces.calendars.task; 017 018import java.time.LocalDate; 019import java.time.ZoneId; 020import java.time.ZonedDateTime; 021import java.util.Collection; 022import java.util.List; 023import java.util.Map; 024import java.util.Optional; 025import java.util.Set; 026 027import org.apache.solr.common.SolrInputDocument; 028import org.xml.sax.ContentHandler; 029import org.xml.sax.SAXException; 030 031import org.ametys.cms.data.holder.IndexableDataHolder; 032import org.ametys.cms.data.holder.group.IndexableComposite; 033import org.ametys.cms.data.holder.group.IndexableRepeater; 034import org.ametys.cms.model.CMSDataContext; 035import org.ametys.core.user.UserIdentity; 036import org.ametys.core.util.DateUtils; 037import org.ametys.plugins.messagingconnector.EventRecurrenceTypeEnum; 038import org.ametys.plugins.repository.AmetysObject; 039import org.ametys.plugins.repository.AmetysRepositoryException; 040import org.ametys.plugins.repository.data.external.ExternalizableDataProvider.ExternalizableDataStatus; 041import org.ametys.plugins.repository.data.holder.ModifiableDataHolder; 042import org.ametys.plugins.repository.data.holder.values.SynchronizationContext; 043import org.ametys.plugins.repository.data.repositorydata.RepositoryData; 044import org.ametys.plugins.workspaces.calendars.Calendar; 045import org.ametys.plugins.workspaces.calendars.events.CalendarEvent; 046import org.ametys.plugins.workspaces.calendars.events.CalendarEventOccurrence; 047import org.ametys.plugins.workspaces.tasks.Task; 048import org.ametys.runtime.model.Model; 049import org.ametys.runtime.model.ModelItem; 050import org.ametys.runtime.model.ViewItemAccessor; 051import org.ametys.runtime.model.exception.BadDataPathCardinalityException; 052import org.ametys.runtime.model.exception.BadItemTypeException; 053import org.ametys.runtime.model.exception.UndefinedItemPathException; 054import org.ametys.runtime.model.exception.UnknownTypeException; 055import org.ametys.runtime.model.type.DataContext; 056import org.ametys.runtime.model.type.ModelItemType; 057 058/** 059 * Object for a task calendar event 060 */ 061public class TaskCalendarEvent implements CalendarEvent 062{ 063 private Calendar _calendar; 064 private Task _task; 065 066 /** 067 * The constructor 068 * @param calendar the calendar 069 * @param task the task 070 */ 071 public TaskCalendarEvent(Calendar calendar, Task task) 072 { 073 _calendar = calendar; 074 _task = task; 075 } 076 077 /** 078 * Return the task link to the calendar event 079 * @return the task 080 */ 081 public Task getTask() 082 { 083 return _task; 084 } 085 086 public void tag(String tag) throws AmetysRepositoryException 087 { 088 throw new UnsupportedOperationException("Can't call method #tag for a TaskCalendarEvent"); 089 } 090 091 public void untag(String tag) throws AmetysRepositoryException 092 { 093 throw new UnsupportedOperationException("Can't call method #untag for a TaskCalendarEvent"); 094 } 095 096 public Set<String> getTags() throws AmetysRepositoryException 097 { 098 return _task.getTags(); 099 } 100 101 public String getName() throws AmetysRepositoryException 102 { 103 return _task.getName(); 104 } 105 106 public String getPath() throws AmetysRepositoryException 107 { 108 return _task.getPath(); 109 } 110 111 public String getId() throws AmetysRepositoryException 112 { 113 return _task.getId(); 114 } 115 116 public <A extends AmetysObject> A getParent() throws AmetysRepositoryException 117 { 118 return _task.getParent(); 119 } 120 121 public String getParentPath() throws AmetysRepositoryException 122 { 123 return _task.getParentPath(); 124 } 125 126 public Calendar getCalendar() 127 { 128 return _calendar; 129 } 130 131 public String getTitle() 132 { 133 return _task.getLabel(); 134 } 135 136 public String getDescription() 137 { 138 return _task.getDescription(); 139 } 140 141 public String getLocation() 142 { 143 return null; 144 } 145 146 public ZonedDateTime getStartDate() 147 { 148 LocalDate date = _task.getStartDate() != null 149 ? _task.getStartDate() 150 : _task.getDueDate(); 151 return DateUtils.asZonedDateTime(date, getZone()); 152 } 153 154 public ZonedDateTime getEndDate() 155 { 156 LocalDate date = _task.getDueDate() != null 157 ? _task.getDueDate() 158 : _task.getStartDate(); 159 return DateUtils.asZonedDateTime(date, getZone()); 160 } 161 162 public ZoneId getZone() 163 { 164 return ZoneId.systemDefault(); 165 } 166 167 public Boolean getFullDay() 168 { 169 return true; 170 } 171 172 public UserIdentity getCreator() 173 { 174 return _task.getAuthor(); 175 } 176 177 public ZonedDateTime getCreationDate() 178 { 179 return _task.getCreationDate(); 180 } 181 182 public UserIdentity getLastContributor() 183 { 184 return _task.getAuthor(); 185 } 186 187 public ZonedDateTime getLastModified() 188 { 189 return _task.getLastModified(); 190 } 191 192 public EventRecurrenceTypeEnum getRecurrenceType() 193 { 194 return EventRecurrenceTypeEnum.NEVER; 195 } 196 197 public Boolean isRecurrent() 198 { 199 return false; 200 } 201 202 public ZonedDateTime getRepeatUntil() 203 { 204 return null; 205 } 206 207 public List<ZonedDateTime> getExcludedOccurences() 208 { 209 return List.of(); 210 } 211 212 public List<CalendarEventOccurrence> getOccurrences(ZonedDateTime startDate, ZonedDateTime endDate) 213 { 214 Optional<CalendarEventOccurrence> optionalEvent = getFirstOccurrence(startDate); 215 return (optionalEvent.isPresent() && optionalEvent.get().getStartDate().isBefore(endDate)) 216 ? List.of(optionalEvent.get()) 217 : List.of(); 218 } 219 220 public Optional<CalendarEventOccurrence> getFirstOccurrence(ZonedDateTime date) 221 { 222 ZonedDateTime eventStartDate = getStartDate(); 223 ZonedDateTime eventEndDate = getEndDate(); 224 225 if (getFullDay()) 226 { 227 eventEndDate = eventEndDate.plusDays(1); 228 } 229 230 return (eventEndDate.isAfter(date) || eventEndDate.isEqual(date)) 231 ? Optional.of(new CalendarEventOccurrence(this, eventStartDate)) 232 : Optional.empty(); 233 } 234 235 public Optional<CalendarEventOccurrence> getNextOccurrence(CalendarEventOccurrence occurrence) 236 { 237 return Optional.empty(); 238 } 239 240 public UserIdentity getOrganiser() 241 { 242 return _task.getAuthor(); 243 } 244 245 public List<String> getResources() 246 { 247 return List.of(); 248 } 249 250 public void dataToSAX(ContentHandler contentHandler, String dataPath, DataContext context) throws SAXException, BadItemTypeException, UndefinedItemPathException 251 { 252 _task.dataToSAX(contentHandler, dataPath, context); 253 } 254 255 public Object dataToJSON(String dataPath, DataContext context) throws BadItemTypeException, UndefinedItemPathException 256 { 257 return _task.dataToJSON(dataPath, context); 258 } 259 260 public RepositoryData getRepositoryData() 261 { 262 return _task.getRepositoryData(); 263 } 264 265 public List<SolrInputDocument> indexData(SolrInputDocument document, CMSDataContext context) throws BadItemTypeException 266 { 267 return _task.indexData(document, context); 268 } 269 270 public Collection< ? extends Model> getModel() 271 { 272 return _task.getModel(); 273 } 274 275 public boolean hasValue(String dataPath) throws IllegalArgumentException, BadDataPathCardinalityException 276 { 277 return _task.hasValue(dataPath); 278 } 279 280 public boolean hasLocalValue(String dataPath) throws IllegalArgumentException, BadDataPathCardinalityException 281 { 282 return _task.hasLocalValue(dataPath); 283 } 284 285 public boolean hasExternalValue(String dataPath) throws IllegalArgumentException, BadDataPathCardinalityException 286 { 287 return _task.hasExternalValue(dataPath); 288 } 289 290 public boolean hasValue(String dataPath, String dataTypeId) throws IllegalArgumentException, UnknownTypeException, BadDataPathCardinalityException 291 { 292 return _task.hasValue(dataPath, dataTypeId); 293 } 294 295 public boolean hasValueOrEmpty(String dataPath) throws IllegalArgumentException, BadDataPathCardinalityException 296 { 297 return _task.hasValueOrEmpty(dataPath); 298 } 299 300 public boolean hasLocalValueOrEmpty(String dataPath) throws IllegalArgumentException, BadDataPathCardinalityException 301 { 302 return _task.hasLocalValueOrEmpty(dataPath); 303 } 304 305 public boolean hasExternalValueOrEmpty(String dataPath) throws IllegalArgumentException, BadDataPathCardinalityException 306 { 307 return _task.hasExternalValueOrEmpty(dataPath); 308 } 309 310 public Collection<String> getDataNames() 311 { 312 return _task.getDataNames(); 313 } 314 315 public <T> T getValue(String dataPath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException 316 { 317 return _task.getValue(dataPath); 318 } 319 320 public <T> T getLocalValue(String dataPath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException 321 { 322 return _task.getLocalValue(dataPath); 323 } 324 325 public <T> T getExternalValue(String dataPath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException 326 { 327 return _task.getExternalValue(dataPath); 328 } 329 330 public <T> T getValueOrDefault(String dataPath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException 331 { 332 return _task.getValueOrDefault(dataPath); 333 } 334 335 public <T> T getValueOrDefault(String dataPath, T defaultValue) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException 336 { 337 return _task.getValueOrDefault(dataPath, defaultValue); 338 } 339 340 public <T> T getValueOfType(String dataPath, String dataTypeId) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException 341 { 342 return _task.getValueOfType(dataPath, dataTypeId); 343 } 344 345 public <T> T getValueOfTypeOrDefault(String dataPath, String dataTypeId, T defaultValue) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException 346 { 347 return _task.getValueOfTypeOrDefault(dataPath, dataTypeId, defaultValue); 348 } 349 350 public <T> T getValueWithMultiValuedPathSegments(String dataPath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException 351 { 352 return _task.getValueWithMultiValuedPathSegments(dataPath); 353 } 354 355 public ExternalizableDataStatus getStatus(String dataPath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException 356 { 357 return _task.getStatus(dataPath); 358 } 359 360 public boolean isMultiple(String dataPath) throws IllegalArgumentException, UndefinedItemPathException 361 { 362 return _task.isMultiple(dataPath); 363 } 364 365 public boolean isMultiple(String dataPath, String dataTypeId) throws IllegalArgumentException, UndefinedItemPathException 366 { 367 return _task.isMultiple(dataPath, dataTypeId); 368 } 369 370 public <X extends ModelItemType> X getType(String dataPath) throws IllegalArgumentException, UndefinedItemPathException 371 { 372 return _task.getType(dataPath); 373 } 374 375 public void copyTo(ModifiableDataHolder dataHolder) throws BadItemTypeException, UndefinedItemPathException 376 { 377 _task.copyTo(dataHolder); 378 } 379 380 public void copyTo(ModifiableDataHolder dataHolder, DataContext context) throws BadItemTypeException, UndefinedItemPathException 381 { 382 _task.copyTo(dataHolder, context); 383 } 384 385 public void dataToSAX(ContentHandler contentHandler, ViewItemAccessor viewItemAccessor, DataContext context) throws SAXException, BadItemTypeException 386 { 387 _task.dataToSAX(contentHandler, viewItemAccessor, context); 388 } 389 390 public void dataToSAXForEdition(ContentHandler contentHandler, ViewItemAccessor viewItemAccessor, DataContext context) throws SAXException, BadItemTypeException 391 { 392 _task.dataToSAXForEdition(contentHandler, viewItemAccessor, context); 393 } 394 395 public Map<String, Object> dataToJSON(ViewItemAccessor viewItemAccessor, DataContext context) throws BadItemTypeException 396 { 397 return _task.dataToJSON(viewItemAccessor, context); 398 } 399 400 public Map<String, Object> dataToJSONForEdition(ViewItemAccessor viewItemAccessor, DataContext context) throws BadItemTypeException 401 { 402 return _task.dataToJSONForEdition(viewItemAccessor, context); 403 } 404 405 public Map<String, Object> dataToMap(ViewItemAccessor viewItemAccessor, DataContext context) throws BadItemTypeException 406 { 407 return _task.dataToMap(viewItemAccessor, context); 408 } 409 410 public boolean hasDifferences(ViewItemAccessor viewItemAccessor, Map<String, Object> values) throws BadItemTypeException 411 { 412 return _task.hasDifferences(viewItemAccessor, values); 413 } 414 415 public boolean hasDifferences(ViewItemAccessor viewItemAccessor, Map<String, Object> values, SynchronizationContext context) throws BadItemTypeException 416 { 417 return _task.hasDifferences(viewItemAccessor, values, context); 418 } 419 420 public Collection<ModelItem> getDifferences(ViewItemAccessor viewItemAccessor, Map<String, Object> values) throws BadItemTypeException 421 { 422 return _task.getDifferences(viewItemAccessor, values); 423 } 424 425 public Collection<ModelItem> getDifferences(ViewItemAccessor viewItemAccessor, Map<String, Object> values, SynchronizationContext context) throws BadItemTypeException 426 { 427 return _task.getDifferences(viewItemAccessor, values, context); 428 } 429 430 public IndexableComposite getComposite(String compositePath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException 431 { 432 return _task.getComposite(compositePath); 433 } 434 435 public IndexableComposite getLocalComposite(String compositePath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException 436 { 437 return _task.getLocalComposite(compositePath); 438 } 439 440 public IndexableComposite getExternalComposite(String compositePath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException 441 { 442 return _task.getExternalComposite(compositePath); 443 } 444 445 public IndexableRepeater getRepeater(String repeaterPath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException 446 { 447 return _task.getRepeater(repeaterPath); 448 } 449 450 public IndexableRepeater getLocalRepeater(String repeaterPath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException 451 { 452 return _task.getLocalRepeater(repeaterPath); 453 } 454 455 public IndexableRepeater getExternalRepeater(String repeaterPath) throws IllegalArgumentException, BadItemTypeException, UndefinedItemPathException, BadDataPathCardinalityException 456 { 457 return _task.getExternalRepeater(repeaterPath); 458 } 459 460 public Optional< ? extends IndexableDataHolder> getParentDataHolder() 461 { 462 return _task.getParentDataHolder(); 463 } 464 465 public IndexableDataHolder getRootDataHolder() 466 { 467 return _task.getRootDataHolder(); 468 } 469}