Coverage Report - org.openpermis.basic.AbsoluteTimePeriod
 
Classes in this File Line Coverage Branch Coverage Complexity
AbsoluteTimePeriod
87%
51/58
80%
45/56
5.5
 
 1  
 /*
 2  
  * Copyright (c) 2009, Swiss Federal Department of Defence Civil Protection and Sport
 3  
  *                     (http://www.vbs.admin.ch)
 4  
  * Copyright (c) 2009, Ergon Informatik AG (http://www.ergon.ch)
 5  
  * All rights reserved.
 6  
  *
 7  
  * Licensed under the Open Permis License which accompanies this distribution,
 8  
  * and is available at http://www.openpermis.org/BSDlicenceKent.txt
 9  
  */
 10  
 package org.openpermis.basic;
 11  
 
 12  
 import java.util.Date;
 13  
 import java.util.TimeZone;
 14  
 
 15  
 import org.joda.time.DateTime;
 16  
 import org.joda.time.Interval;
 17  
 
 18  
 import org.openpermis.policy.TimeStamp;
 19  
 import org.openpermis.policy.io.xml.TimeUtility;
 20  
 
 21  
 
 22  
 /**
 23  
  * An absolute period of time.
 24  
  * @since 0.3.0
 25  
  */
 26  
 public final class AbsoluteTimePeriod implements TimePeriod {
 27  
         
 28  
         //---- State
 29  
         
 30  
         private PartialTime start;
 31  
 
 32  
         private PartialTime end;
 33  
         
 34  
         //---- Constructors
 35  
         
 36  
         /**
 37  
          * Creates a time period.
 38  
          * @param start a {@link DateTime}.
 39  
          * @param end a {@link DateTime}.
 40  
          * @since 0.3.0
 41  
          */
 42  54
         public AbsoluteTimePeriod (PartialTime start, PartialTime end) {
 43  54
                 if (start == null || end == null) {
 44  1
                         throw new IllegalArgumentException("NotBefore or notAfter is null.");
 45  
                 }
 46  53
                 if (!start.isComplete() || !end.isComplete()) {
 47  0
                         throw new IllegalArgumentException("NotBefore or not after is not complete.");
 48  
                 }
 49  53
                 if (!start.inSameTimeZone(end)) {
 50  0
                         throw new IllegalArgumentException("Time zones are not equal.");
 51  
                 }
 52  53
                 TimeStamp timeStamp = new TimeStamp(new Date(0), TimeZone.getTimeZone("UTC"));
 53  53
                 if (!start.isBefore(end, timeStamp) || start.equals(end)) {
 54  2
                         throw new IllegalArgumentException("Not before must be smaller or equal not after.");
 55  
                 }
 56  51
                 this.start = start;
 57  51
                 this.end = end;
 58  51
         }
 59  
         
 60  
         /**
 61  
          * Creates a time period between start and end.
 62  
          * @param start a {@link Date}.
 63  
          * @param end a {@link Date}.
 64  
          * @since 0.3.0
 65  
          */
 66  
         public AbsoluteTimePeriod (Date start, Date end) {
 67  38
                 this(new PartialTime(start), new PartialTime(end));
 68  36
         }
 69  
         
 70  
         //---- Methods
 71  
         
 72  
         /**
 73  
          * Returns the start of this period.
 74  
          * @return the start of this period.
 75  
          * @since 0.3.0
 76  
          */
 77  
         public PartialTime getStart () {
 78  2
                 return this.start;
 79  
         }
 80  
         
 81  
         /**
 82  
          * Returns the end of this period.
 83  
          * @return the end of this period.
 84  
          * @since 0.3.0
 85  
          */
 86  
         public PartialTime getEnd () {
 87  2
                 return this.end;
 88  
         }
 89  
         
 90  
         //---- TimePeriod
 91  
         
 92  
         /**
 93  
          * @since 0.3.0
 94  
          */
 95  
         public boolean contains (TimeStamp timeStamp) {
 96  4
                 if (timeStamp == null) {
 97  0
                         return false;
 98  
                 }
 99  4
                 return toInterval(timeStamp).contains(TimeUtility.getDateTime(timeStamp)) ||
 100  
                         toInterval(timeStamp).getEnd().equals(TimeUtility.getDateTime(timeStamp));
 101  
         }
 102  
 
 103  
         /**
 104  
          * @since 0.3.0
 105  
          */
 106  
         public TimePeriod constrain (TimePeriodConstraint constraint, TimeStamp timeStamp) {
 107  
                 // We assume that it makes sense to consider the absolute and the relative constraints 
 108  
                 // separately.
 109  
                 
 110  10
                 final DateTime now = TimeUtility.getDateTime(timeStamp);
 111  10
                 final DateTime startTime = this.start.toDateTime(timeStamp);
 112  10
                 final DateTime endTime = this.end.toDateTime(timeStamp);
 113  
                 
 114  10
                 if (constraint.getMinimumValidFrom() != null &&
 115  
                         startTime.isAfter(now.minus(constraint.getMinimumValidFrom()))
 116  
                 ) {
 117  1
                         return TimePeriod.EMPTY;
 118  
                 }
 119  
                 
 120  9
                 if (constraint.getMinimumValidUpTo() != null &&
 121  
                         endTime.isBefore(now.plus(constraint.getMinimumValidUpTo()))
 122  
                 ) {
 123  1
                         return TimePeriod.EMPTY;
 124  
                 }
 125  
                 
 126  8
                 if (constraint.getMaximumValidUpTo() != null &&
 127  
                         endTime.isAfter(now.plus(constraint.getMaximumValidUpTo()))
 128  
                 ) {
 129  1
                         return TimePeriod.EMPTY;
 130  
                 }
 131  
                 
 132  7
                 return this.constrain(constraint.getAbsolutePeriod(), timeStamp);
 133  
         }
 134  
         
 135  
         /**
 136  
          * @since 0.3.0
 137  
          */
 138  
         private Interval toInterval (TimeStamp timeStamp) {
 139  18
                 return new Interval(this.start.toDateTime(timeStamp), this.end.toDateTime(timeStamp));
 140  
         }
 141  
         
 142  
         /**
 143  
          * @since 0.3.0
 144  
          */
 145  
         public TimePeriod constrain (TimePeriod period, TimeStamp timeStamp) {
 146  14
                 if (period instanceof InfiniteTimePeriod) {
 147  8
                         return this;
 148  
                 }
 149  6
                 if (period instanceof EmptyTimePeriod) {
 150  0
                         return TimePeriod.EMPTY;
 151  
                 }
 152  6
                 if (period instanceof AbsoluteTimePeriod) {
 153  6
                         final AbsoluteTimePeriod otherPeriod = (AbsoluteTimePeriod) period;
 154  6
                         final Interval interval = toInterval(timeStamp);
 155  6
                         final Interval other = ((AbsoluteTimePeriod) period).toInterval(timeStamp);
 156  
                         
 157  6
                         if (interval.contains(other)) {
 158  2
                                 return period;
 159  4
                         } else if (other.contains(interval)) {
 160  1
                                 return this;
 161  3
                         } else if (interval.gap(other) != null) {
 162  1
                                 return TimePeriod.EMPTY;
 163  
                         } else {
 164  2
                                 if (other.getStart().isAfter(interval.getStart())) {
 165  1
                                         return new AbsoluteTimePeriod(otherPeriod.start, this.end);
 166  
                                 } 
 167  1
                                 return new AbsoluteTimePeriod(this.start, otherPeriod.end);
 168  
                         }
 169  
                 }
 170  0
                 throw new IllegalStateException("Unknown time period, should never happen.");
 171  
         }
 172  
         
 173  
         //---- Object
 174  
         
 175  
         /**
 176  
          * @since 0.3.0
 177  
          */
 178  
         public boolean equals (Object object) {
 179  21
                 if (object == null) {
 180  0
                         return false;
 181  
                 }
 182  21
                 if (this == object) {
 183  14
                         return true;
 184  
                 }
 185  7
                 if (object instanceof AbsoluteTimePeriod) {
 186  6
                         AbsoluteTimePeriod other = (AbsoluteTimePeriod) object;
 187  6
                         return this.end.equals(other.end) &&
 188  
                                 this.start.equals(other.start);
 189  
                 }
 190  1
                 return false;
 191  
         }
 192  
 
 193  
         /**
 194  
          * @since 0.3.0
 195  
          */
 196  
         public int hashCode () {
 197  0
                 return this.end.hashCode() * this.start.hashCode();
 198  
         }
 199  
 
 200  
 }
 201