All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jfxtras.icalendarfx.itip.ProcessPublish Maven / Gradle / Ivy

There is a newer version: 17-r1
Show newest version
package jfxtras.icalendarfx.itip;

import java.time.temporal.Temporal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import jfxtras.icalendarfx.VCalendar;
import jfxtras.icalendarfx.components.VComponent;
import jfxtras.icalendarfx.components.VDisplayable;
import jfxtras.icalendarfx.components.VEvent;
import jfxtras.icalendarfx.components.VTimeZone;
import jfxtras.icalendarfx.properties.calendar.Method.MethodType;
import jfxtras.icalendarfx.properties.component.relationship.Attendee;
import jfxtras.icalendarfx.properties.component.relationship.Organizer;
import jfxtras.icalendarfx.properties.component.relationship.UniqueIdentifier;

/** 
 * 
 * 

3.2.1. PUBLISH

The {@link MethodType#Publish PUBLISH} method in a {@link VEvent VEVENT} calendar component is an unsolicited posting of an iCalendar object. Any CU may add published components to their calendar. The {@link Organizer} MUST be present in a published iCalendar component. {@link Attendee Attendees} MUST NOT be present. Its expected usage is for encapsulating an arbitrary event as an iCalendar object. The {@link Organizer} may subsequently update (with another {@link MethodType#Publish PUBLISH} method), add instances to (with an {@link MethodType#Add ADD} method), or cancel (with a {@link MethodType#Cancel CANCEL} method) a previously published {@link VEvent VEVENT} calendar component.

This method type is an iCalendar object that conforms to the following property constraints:

             +----------------------------------------------+
             | Constraints for a METHOD:PUBLISH of a VEVENT |
             +----------------------------------------------+

   +--------------------+----------+-----------------------------------+
   | Component/Property | Presence | Comment                           |
   +--------------------+----------+-----------------------------------+
   | METHOD             | 1        | MUST equal PUBLISH.               |
   |                    |          |                                   |
   | VEVENT             | 1+       |                                   |
   |   DTSTAMP          | 1        |                                   |
   |   DTSTART          | 1        |                                   |
   |   ORGANIZER        | 1        |                                   |
   |   SUMMARY          | 1        | Can be null.                      |
   |   UID              | 1        |                                   |
   |   RECURRENCE-ID    | 0 or 1   | Only if referring to an instance  |
   |                    |          | of a recurring calendar           |
   |                    |          | component.  Otherwise, it MUST    |
   |                    |          | NOT be present.                   |
   |   SEQUENCE         | 0 or 1   | MUST be present if value is       |
   |                    |          | greater than 0; MAY be present if |
   |                    |          | 0.                                |
   |   ATTACH           | 0+       |                                   |
   |   CATEGORIES       | 0+       |                                   |
   |   CLASS            | 0 or 1   |                                   |
   |   COMMENT          | 0+       |                                   |
   |   CONTACT          | 0 or 1   |                                   |
   |   CREATED          | 0 or 1   |                                   |
   |   DESCRIPTION      | 0 or 1   | Can be null.                      |
   |   DTEND            | 0 or 1   | If present, DURATION MUST NOT be  |
   |                    |          | present.                          |
   |   DURATION         | 0 or 1   | If present, DTEND MUST NOT be     |
   |                    |          | present.                          |
   |   EXDATE           | 0+       |                                   |
   |   GEO              | 0 or 1   |                                   |
   |   LAST-MODIFIED    | 0 or 1   |                                   |
   |   LOCATION         | 0 or 1   |                                   |
   |   PRIORITY         | 0 or 1   |                                   |
   |   RDATE            | 0+       |                                   |
   |   RELATED-TO       | 0+       |                                   |
   |   RESOURCES        | 0+       |                                   |
   |   RRULE            | 0 or 1   |                                   |
   |   STATUS           | 0 or 1   | MAY be one of                     |
   |                    |          | TENTATIVE/CONFIRMED/CANCELLED.    |
   |   TRANSP           | 0 or 1   |                                   |
   |   URL              | 0 or 1   |                                   |
   |   IANA-PROPERTY    | 0+       |                                   |
   |   X-PROPERTY       | 0+       |                                   |
   |   ATTENDEE         | 0        |                                   |
   |   REQUEST-STATUS   | 0        |                                   |
   |                    |          |                                   |
   |   VALARM           | 0+       |                                   |
   |                    |          |                                   |
   | VFREEBUSY          | 0        |                                   |
   |                    |          |                                   |
   | VJOURNAL           | 0        |                                   |
   |                    |          |                                   |
   | VTODO              | 0        |                                   |
   |                    |          |                                   |
   | VTIMEZONE          | 0+       | MUST be present if any date/time  |
   |                    |          | refers to a timezone.             |
   |                    |          |                                   |
   | IANA-COMPONENT     | 0+       |                                   |
   | X-COMPONENT        | 0+       |                                   |
   +--------------------+----------+-----------------------------------+
   
* @author David Bal */ public class ProcessPublish implements Processable { @Override public List process(VCalendar mainVCalendar, VCalendar iTIPMessage) { List log = new ArrayList<>(); iTIPMessage.childrenUnmodifiable() .stream() .filter(c -> c instanceof VComponent) .map(c -> (VComponent) c) .forEach(c -> { if (c instanceof VDisplayable) { VDisplayable vDisplayable = ((VDisplayable) c); final boolean hasOrganizer = vDisplayable.getOrganizer() != null; // TODO - LOG DEFECTS - DON'T THROW EXCEPTIONS if (! hasOrganizer) log.add("WARNING: According to RFC 5546, a PUBLISH method MUST contain the ORGANIZER property and it's absent. " + c.getClass().getSimpleName() + " with UID:" + vDisplayable.getUniqueIdentifier().getValue() + " is being processed anyway."); final boolean hasNoAttendees = vDisplayable.getAttendees() == null; if (! hasNoAttendees) log.add("WARNING: According to RFC 5546, a PUBLISH MUST NOT contain the ATTENDEE property yet it's exists. " + c.getClass().getSimpleName() + " with UID:" + vDisplayable.getUniqueIdentifier().getValue() + " is being processed anyway."); final int newSequence = (vDisplayable.getSequence() == null) ? 0 : vDisplayable.getSequence().getValue(); boolean isNewSequenceHigher = true; UniqueIdentifier uid = vDisplayable.getUniqueIdentifier(); final List> relatedVComponents; List list = mainVCalendar.getVComponents(vDisplayable); if (list == null) { relatedVComponents = null; } else { relatedVComponents = mainVCalendar.getVComponents(vDisplayable) .stream() .filter(v -> v instanceof VDisplayable) .map(v -> (VDisplayable) v) .filter(v -> v.getUniqueIdentifier().equals(uid)) .collect(Collectors.toList()); } final Temporal recurrenceID = (vDisplayable.getRecurrenceId() != null) ? vDisplayable.getRecurrenceId().getValue() : null; // check for previous match to remove it if (relatedVComponents != null) { /* if new has recurrence id: * if old has matching recurrence-id then replace it * if old doesn't have recurrence-id, add component as new recurrence * if new doesn't have recurrence id, but match exists, replace match * If no match then just add - can't have recurrence id */ VDisplayable oldMatchingVComponent = relatedVComponents .stream() .filter(v -> { Temporal mRecurrenceID = (v.getRecurrenceId() != null) ? v.getRecurrenceId().getValue() : null; return Objects.equals(recurrenceID, mRecurrenceID); }) .findAny() .orElseGet(() -> null); if (oldMatchingVComponent != null) { int oldSequence = (oldMatchingVComponent.getSequence() == null) ? 0 : oldMatchingVComponent.getSequence().getValue(); isNewSequenceHigher = newSequence > oldSequence || (newSequence == 0 && oldSequence == 0); // SEQUENCE INCREASE REQUIREMENT ONLY APPLIES FOR PARENTS - NOT RECURRENCES THAT ONLY HAVE RECURRENCE-ID CHANGED if (! isNewSequenceHigher) throw new IllegalArgumentException("Can't process PUBLISH method: SEQUENCY property MUST be higher than previously published component (new=" + newSequence + " old=" + oldSequence + ")"); if (isNewSequenceHigher) { mainVCalendar.removeChild(oldMatchingVComponent); } } } mainVCalendar.addChild(c); log.add("SUCCESS: added " + c.getClass().getSimpleName() + " with UID:" + vDisplayable.getUniqueIdentifier().getValue()); // Remove orphaned recurrence children // TODO - IS THIS NECESSARY??? List> orphanedChildren = vDisplayable.orphanedRecurrenceChildren(); if (! orphanedChildren.isEmpty()) { vDisplayable.calendarList().removeAll(orphanedChildren); } } else if (c instanceof VTimeZone) { mainVCalendar.getVTimeZones().add((VTimeZone) c); } else { // non-displayable VComponents (only VFREEBUSY has UID) log.add("Can't process non-displayble component method (not implemented):" + System.lineSeparator() + c.toString()); } }); // System.out.println("log:" + log); return log; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy