PageRenderTime 26ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/atlassian/confluence/extra/calendar/ical/model/OverrideEventDetails.java

https://bitbucket.org/soudmaijer/confluence-calendar
Java | 240 lines | 135 code | 38 blank | 67 comment | 41 complexity | 811ff94f076de2e6718fe73d0cd83e1c MD5 | raw file
  1. /*
  2. * Copyright (c) 2006, Atlassian Software Systems Pty Ltd
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * * Redistributions of source code must retain the above copyright notice,
  9. * this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * * Neither the name of "Atlassian" nor the names of its contributors
  14. * may be used to endorse or promote products derived from this software
  15. * without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  18. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  21. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  22. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  23. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  24. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  25. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  26. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  27. * POSSIBILITY OF SUCH DAMAGE.
  28. */
  29. package com.atlassian.confluence.extra.calendar.ical.model;
  30. import net.fortuna.ical4j.model.Parameter;
  31. import net.fortuna.ical4j.model.Property;
  32. import net.fortuna.ical4j.model.Recur;
  33. import net.fortuna.ical4j.model.component.VEvent;
  34. import net.fortuna.ical4j.model.parameter.Range;
  35. import net.fortuna.ical4j.model.parameter.Value;
  36. import net.fortuna.ical4j.model.property.DtStamp;
  37. import net.fortuna.ical4j.model.property.RecurrenceId;
  38. import net.fortuna.ical4j.model.property.Uid;
  39. import org.joda.time.DateTime;
  40. import org.joda.time.Duration;
  41. import org.joda.time.Interval;
  42. import org.joda.time.LocalDateTime;
  43. import org.joda.time.Period;
  44. import org.joda.time.ReadableInstant;
  45. import org.joda.time.DateTimeZone;
  46. import java.util.Collections;
  47. import java.util.List;
  48. import java.util.Set;
  49. /**
  50. * Override events replace a specific recurrence of an event with new details.
  51. */
  52. public class OverrideEventDetails extends EventDetails {
  53. private BaseEventDetails baseEvent;
  54. /**
  55. * used to create a new override event from the baseeventdetails
  56. * @param calendar
  57. * @param baseEventDetails
  58. */
  59. public OverrideEventDetails( ICalCalendar calendar, BaseEventDetails baseEvent, EventId eventId) {
  60. super( calendar, (VEvent) null );
  61. setBaseEvent( baseEvent) ;
  62. this.vevent = new VEvent();
  63. // Generate a UID
  64. addProperty( new Uid( baseEvent.getUid() ) );
  65. incSequence();
  66. // Check that the DTSTAMP property is set correctly.
  67. DtStamp dtStamp = ( DtStamp ) getProperty( Property.DTSTAMP );
  68. net.fortuna.ical4j.model.DateTime dateTime;
  69. if ( dtStamp == null ) {
  70. dateTime = new net.fortuna.ical4j.model.DateTime( true );
  71. addProperty( new DtStamp( dateTime ) );
  72. } else {
  73. dateTime = dtStamp.getDateTime();
  74. }
  75. if ( dateTime != null && dateTime.getTimeZone() == null )
  76. dateTime.setUtc( true );
  77. setOverrideDate(eventId.getInstanceDate(), eventId.getTimeZone(),
  78. baseEvent.isAllDay() ? Value.DATE : null);
  79. }
  80. OverrideEventDetails( ICalCalendar calendar, VEvent event ) {
  81. super( calendar, event );
  82. // Check that the DTSTAMP property is set correctly.
  83. DtStamp dtStamp = ( DtStamp ) getProperty( Property.DTSTAMP );
  84. if ( dtStamp == null )
  85. addProperty( new DtStamp( new net.fortuna.ical4j.model.DateTime() ) );
  86. }
  87. void setBaseEvent( BaseEventDetails parent ) {
  88. this.baseEvent = parent;
  89. }
  90. public BaseEventDetails getBaseEvent() {
  91. return baseEvent;
  92. }
  93. /**
  94. * Returns a list of the times this event occurs within the specified date
  95. * range. Occurrences where the from or to date/time are <i>inside</i> the
  96. * event (i.e. the event starts before the 'from' date but ends after it, or
  97. * vise-versa) are included.
  98. *
  99. * @param interval
  100. * The interval to check occurrence for.
  101. * @return the list of occurrences.
  102. */
  103. public List getEvents( Interval interval, DateTimeZone targetTimeZone ) {
  104. return getEvents( interval, targetTimeZone ,false);
  105. }
  106. /**
  107. * Returns a list of the times this event occurs within the specified date
  108. * range. Occurrences where the from or to date/time are <i>inside</i> the
  109. * event (i.e. the event starts before the 'from' date but ends after it, or
  110. * vise-versa) are included.
  111. *
  112. * @param interval
  113. * The interval to check occurrence for.
  114. * @param targetTimeZone
  115. * @param useOverrideDate - true use overrideDate ,false use startDate
  116. * @return the list of occurrences.
  117. */
  118. public List getEvents( Interval interval, DateTimeZone targetTimeZone, boolean useOverrideDate) {
  119. Interval rinterval = getRecurrenceInterval( interval );
  120. if ( rinterval != null && baseEvent != null ) {
  121. Recur recur = baseEvent.getRecur();
  122. Period offset = getStartOffset();
  123. Set exclusions = getExcludedDates();
  124. return processRecurrence( baseEvent.getStartDate(), rinterval, targetTimeZone, recur, exclusions,
  125. null, null, offset );
  126. } else {
  127. Interval evtInterval = null;
  128. if (useOverrideDate) {//return eventinterval by the overrideDate (recurrence-id)
  129. evtInterval = getOverrideInterval( targetTimeZone );
  130. } else { //return eventinterval by the startDate
  131. evtInterval = getInterval( targetTimeZone );
  132. }
  133. if ( interval.overlaps( evtInterval ) )
  134. return Collections.singletonList( new ICalEvent( this, getOverrideDate(), getTimeZone() ) );
  135. }
  136. return Collections.EMPTY_LIST;
  137. }
  138. public Period getStartOffset() {
  139. return new Period( getOverrideDate(), getStartDate() );
  140. }
  141. protected Interval getRecurrenceInterval( Interval interval ) {
  142. RecurrenceId recurrenceId = ( RecurrenceId ) getProperty( Property.RECURRENCE_ID );
  143. // Then, check for recurrences.
  144. if ( recurrenceId != null ) // it is an explicit recurrence
  145. {
  146. Range range = ( Range ) recurrenceId.getParameters().getParameter( Parameter.RANGE );
  147. if ( range != null ) {
  148. ReadableInstant recurrenceDate = ICalUtil.toJodaReadableInstant( recurrenceId.getDate() );
  149. if ( Range.THISANDPRIOR.equals( range.getValue() ) ) {
  150. if ( interval.getEnd().isAfter( recurrenceDate ) )
  151. return interval.withEnd( recurrenceDate );
  152. return interval;
  153. } else if ( Range.THISANDFUTURE.equals( range.getValue() ) ) {
  154. if ( interval.getStart().isBefore( recurrenceDate ) )
  155. return interval.withStart( recurrenceDate );
  156. return interval;
  157. }
  158. }
  159. }
  160. return null;
  161. }
  162. /**
  163. * find interval using the override date
  164. * @param timeZone
  165. * @return
  166. */
  167. protected Interval getOverrideInterval( DateTimeZone timeZone ) {
  168. LocalDateTime start = getOverrideDate();
  169. DateTimeZone eventTimeZone = getTimeZone();
  170. Duration dur = getDuration();
  171. if ( start != null && dur != null ) {
  172. if ( dur.getMillis() < 0 )
  173. dur = new Duration( 1000 );
  174. DateTime startDt;
  175. if ( eventTimeZone != null )
  176. startDt = start.toDateTime( eventTimeZone ).toDateTime( timeZone );
  177. else
  178. startDt = start.toDateTime( timeZone );
  179. return new Interval( startDt, dur );
  180. }
  181. return null;
  182. }
  183. public LocalDateTime getOverrideDate() {
  184. RecurrenceId rid = ( RecurrenceId ) getProperty( Property.RECURRENCE_ID );
  185. if ( rid != null )
  186. return ICalUtil.toJodaLocalDateTime( rid.getDate() );
  187. return null;
  188. }
  189. public void setOverrideDate(LocalDateTime overrideDate, DateTimeZone dateTimeZone, Value valueType) {
  190. checkReadOnly();
  191. RecurrenceId recurrenceId = ( RecurrenceId ) getProperty(Property.RECURRENCE_ID );
  192. if (recurrenceId != null) {
  193. removeProperty(recurrenceId);
  194. }
  195. if (overrideDate != null) {
  196. recurrenceId = new RecurrenceId( ICalUtil.toICalDate(overrideDate,dateTimeZone ));
  197. if ( valueType != null )
  198. recurrenceId.getParameters().add( valueType );
  199. addProperty(recurrenceId);
  200. }
  201. }
  202. }