001package biweekly.property;
002
003import java.util.Arrays;
004import java.util.Collection;
005import java.util.Collections;
006
007import biweekly.ICalVersion;
008import biweekly.component.VEvent;
009import biweekly.component.VJournal;
010import biweekly.component.VTodo;
011
012/*
013 Copyright (c) 2013-2015, Michael Angstadt
014 All rights reserved.
015
016 Redistribution and use in source and binary forms, with or without
017 modification, are permitted provided that the following conditions are met: 
018
019 1. Redistributions of source code must retain the above copyright notice, this
020 list of conditions and the following disclaimer. 
021 2. Redistributions in binary form must reproduce the above copyright notice,
022 this list of conditions and the following disclaimer in the documentation
023 and/or other materials provided with the distribution. 
024
025 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
026 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
027 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
028 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
029 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
030 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
031 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
032 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
033 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
034 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
035 */
036
037/**
038 * <p>
039 * Defines the status of the component that this property belongs to, such as a
040 * to-do task being "completed".
041 * </p>
042 * 
043 * <p>
044 * <b>Code sample (creating):</b>
045 * 
046 * <pre class="brush:java">
047 * VTodo todo = new VTodo();
048 * 
049 * Status status = Status.completed();
050 * todo.setStatus(status);
051 * </pre>
052 * 
053 * </p>
054 * 
055 * <p>
056 * <b>Code sample (retrieving):</b>
057 * 
058 * <pre class="brush:java">
059 * ICalendar ical = ...
060 * for (VTodo todo : ical.getTodos()){
061 *   Status status = todo.getStatus();
062 *   if (action.isCompleted()) {
063 *         ...
064 *   } else if (action.isDraft()){
065 *     ...
066 *   }
067 *   //etc.
068 * }
069 * </pre>
070 * 
071 * </p>
072 * @author Michael Angstadt
073 * @see <a href="http://tools.ietf.org/html/rfc5545#page-92">RFC 5545 p.92-3</a>
074 * @see <a href="http://tools.ietf.org/html/rfc2445#page-88">RFC 2445 p.88-9</a>
075 * @see <a href="http://www.imc.org/pdi/vcal-10.doc">vCal 1.0 p.35-6</a>
076 */
077public class Status extends EnumProperty {
078        //2.0
079        private static final String CANCELLED = "CANCELLED";
080        private static final String DRAFT = "DRAFT";
081        private static final String FINAL = "FINAL";
082        private static final String IN_PROGRESS = "IN-PROGRESS";
083
084        //1.0
085        private static final String ACCEPTED = "ACCEPTED";
086        private static final String DECLINED = "DECLINED";
087        private static final String DELEGATED = "DELEGATED";
088        private static final String SENT = "SENT";
089
090        //1.0 and 2.0
091        private static final String COMPLETED = "COMPLETED";
092        private static final String CONFIRMED = "CONFIRMED";
093        private static final String NEEDS_ACTION = "NEEDS-ACTION";
094        private static final String TENTATIVE = "TENTATIVE";
095
096        /**
097         * Creates a status property. Use of this constructor is discouraged and may
098         * put the property in an invalid state. Use one of the static factory
099         * methods instead.
100         * @param status the status (e.g. "TENTATIVE")
101         */
102        public Status(String status) {
103                super(status);
104        }
105
106        /**
107         * Creates a "tentative" status property (only valid for event components).
108         * @return the property
109         */
110        public static Status tentative() {
111                return create(TENTATIVE);
112        }
113
114        /**
115         * Determines if the status is set to "tentative".
116         * @return true if it is, false if not
117         */
118        public boolean isTentative() {
119                return is(TENTATIVE);
120        }
121
122        /**
123         * Creates a "confirmed" status property (only valid for event components).
124         * @return the property
125         */
126        public static Status confirmed() {
127                return create(CONFIRMED);
128        }
129
130        /**
131         * Determines if the status is set to "confirmed".
132         * @return true if it is, false if not
133         */
134        public boolean isConfirmed() {
135                return is(CONFIRMED);
136        }
137
138        /**
139         * Creates a "cancelled" status property (only valid in iCalendar 2.0 in
140         * {@link VEvent}, {@link VTodo}, and {@link VJournal} components).
141         * @return the property
142         */
143        public static Status cancelled() {
144                return create(CANCELLED);
145        }
146
147        /**
148         * Determines if the status is set to "cancelled".
149         * @return true if it is, false if not
150         */
151        public boolean isCancelled() {
152                return is(CANCELLED);
153        }
154
155        /**
156         * Creates a "needs-action" status property.
157         * @return the property
158         */
159        public static Status needsAction() {
160                return create(NEEDS_ACTION);
161        }
162
163        /**
164         * Determines if the status is set to "needs-action".
165         * @return true if it is, false if not
166         */
167        public boolean isNeedsAction() {
168                return is(NEEDS_ACTION);
169        }
170
171        /**
172         * Creates a "completed" status property (only valid in {@link VTodo}
173         * components).
174         * @return the property
175         */
176        public static Status completed() {
177                return create(COMPLETED);
178        }
179
180        /**
181         * Determines if the status is set to "completed".
182         * @return true if it is, false if not
183         */
184        public boolean isCompleted() {
185                return is(COMPLETED);
186        }
187
188        /**
189         * Creates a "in-progress" status property (only valid in iCalendar 2.0 in
190         * {@link VTodo} components).
191         * @return the property
192         */
193        public static Status inProgress() {
194                return create(IN_PROGRESS);
195        }
196
197        /**
198         * Determines if the status is set to "in-progress".
199         * @return true if it is, false if not
200         */
201        public boolean isInProgress() {
202                return is(IN_PROGRESS);
203        }
204
205        /**
206         * Creates a "draft" status property (only valid in iCalendar 2.0 in
207         * {@link VJournal} components).
208         * @return the property
209         */
210        public static Status draft() {
211                return create(DRAFT);
212        }
213
214        /**
215         * Determines if the status is set to "draft".
216         * @return true if it is, false if not
217         */
218        public boolean isDraft() {
219                return is(DRAFT);
220        }
221
222        /**
223         * Creates a "final" status property (only valid in iCalendar 2.0 in
224         * {@link VJournal} components).
225         * @return the property
226         */
227        public static Status final_() {
228                return create(FINAL);
229        }
230
231        /**
232         * Determines if the status is set to "final".
233         * @return true if it is, false if not
234         */
235        public boolean isFinal() {
236                return is(FINAL);
237        }
238
239        /**
240         * Creates an "accepted" status property (only valid in vCal 1.0 in
241         * {@link VTodo} components).
242         * @return the property
243         */
244        public static Status accepted() {
245                return create(ACCEPTED);
246        }
247
248        /**
249         * Determines if the status is set to "accepted".
250         * @return true if it is, false if not
251         */
252        public boolean isAccepted() {
253                return is(ACCEPTED);
254        }
255
256        /**
257         * Creates a "declined" status property (only valid in vCal 1.0).
258         * @return the property
259         */
260        public static Status declined() {
261                return create(DECLINED);
262        }
263
264        /**
265         * Determines if the status is set to "declined".
266         * @return true if it is, false if not
267         */
268        public boolean isDeclined() {
269                return is(DECLINED);
270        }
271
272        /**
273         * Creates a "delegated" status property (only valid in vCal 1.0).
274         * @return the property
275         */
276        public static Status delegated() {
277                return create(DELEGATED);
278        }
279
280        /**
281         * Determines if the status is set to "delegated".
282         * @return true if it is, false if not
283         */
284        public boolean isDelegated() {
285                return is(DELEGATED);
286        }
287
288        /**
289         * Creates a "sent" status property (only valid in vCal 1.0).
290         * @return the property
291         */
292        public static Status sent() {
293                return create(SENT);
294        }
295
296        /**
297         * Determines if the status is set to "sent".
298         * @return true if it is, false if not
299         */
300        public boolean isSent() {
301                return is(SENT);
302        }
303
304        public static Status create(String status) {
305                return new Status(status);
306        }
307
308        @Override
309        protected Collection<String> getStandardValues(ICalVersion version) {
310                switch (version) {
311                case V1_0:
312                        return Arrays.asList(ACCEPTED, COMPLETED, CONFIRMED, DECLINED, DELEGATED, NEEDS_ACTION, SENT, TENTATIVE);
313                default:
314                        return Arrays.asList(CANCELLED, COMPLETED, CONFIRMED, DRAFT, FINAL, IN_PROGRESS, NEEDS_ACTION, TENTATIVE);
315                }
316        }
317
318        @Override
319        protected Collection<ICalVersion> getValueSupportedVersions() {
320                if (value == null) {
321                        return Collections.emptyList();
322                }
323
324                if (isCompleted() || isConfirmed() || isNeedsAction() || isTentative()) {
325                        return Arrays.asList(ICalVersion.values());
326                }
327                if (isCancelled() || isDraft() || isFinal() || isInProgress()) {
328                        return Arrays.asList(ICalVersion.V2_0_DEPRECATED, ICalVersion.V2_0);
329                }
330                if (isAccepted() || isDeclined() || isDelegated() || isSent()) {
331                        return Arrays.asList(ICalVersion.V1_0);
332                }
333
334                return Collections.emptyList();
335        }
336}