001package ezvcard.property; 002 003import java.util.Date; 004import java.util.LinkedHashMap; 005import java.util.List; 006import java.util.Map; 007 008import ezvcard.VCard; 009import ezvcard.VCardVersion; 010import ezvcard.ValidationWarning; 011import ezvcard.parameter.Calscale; 012import ezvcard.parameter.VCardParameters; 013import ezvcard.util.PartialDate; 014 015/* 016 Copyright (c) 2012-2018, Michael Angstadt 017 All rights reserved. 018 019 Redistribution and use in source and binary forms, with or without 020 modification, are permitted provided that the following conditions are met: 021 022 1. Redistributions of source code must retain the above copyright notice, this 023 list of conditions and the following disclaimer. 024 2. Redistributions in binary form must reproduce the above copyright notice, 025 this list of conditions and the following disclaimer in the documentation 026 and/or other materials provided with the distribution. 027 028 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 029 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 030 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 031 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 032 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 033 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 034 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 035 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 036 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 037 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 038 039 The views and conclusions contained in the software and documentation are those 040 of the authors and should not be interpreted as representing official policies, 041 either expressed or implied, of the FreeBSD Project. 042 */ 043 044/** 045 * Represents a property with a date and/or time value. 046 * @author Michael Angstadt 047 */ 048public class DateOrTimeProperty extends VCardProperty implements HasAltId { 049 private String text; 050 private Date date; 051 private PartialDate partialDate; 052 private boolean dateHasTime; 053 054 /** 055 * Creates a date-and-or-time property. 056 * @param date the date value 057 */ 058 public DateOrTimeProperty(Date date) { 059 this(date, false); 060 } 061 062 /** 063 * Creates a date-and-or-time property. 064 * @param date the date value 065 * @param hasTime true to include the date's time component, false if it's 066 * strictly a date 067 */ 068 public DateOrTimeProperty(Date date, boolean hasTime) { 069 setDate(date, hasTime); 070 } 071 072 /** 073 * Creates a date-and-or-time property. 074 * @param partialDate the partial date value (vCard 4.0 only) 075 */ 076 public DateOrTimeProperty(PartialDate partialDate) { 077 setPartialDate(partialDate); 078 } 079 080 /** 081 * Creates a date-and-or-time property. 082 * @param text the text value (vCard 4.0 only) 083 */ 084 public DateOrTimeProperty(String text) { 085 setText(text); 086 } 087 088 /** 089 * Copy constructor. 090 * @param original the property to make a copy of 091 */ 092 public DateOrTimeProperty(DateOrTimeProperty original) { 093 super(original); 094 text = original.text; 095 date = (original.date == null) ? null : new Date(original.date.getTime()); 096 partialDate = original.partialDate; 097 dateHasTime = original.dateHasTime; 098 } 099 100 /** 101 * Gets the date value. 102 * @return the date value or null if not set 103 */ 104 public Date getDate() { 105 return date; 106 } 107 108 /** 109 * Sets the value of this property to a complete date. 110 * @param date the date 111 * @param hasTime true to include the date's time component, false if it's 112 * strictly a date 113 */ 114 public void setDate(Date date, boolean hasTime) { 115 this.date = date; 116 this.dateHasTime = (date == null) ? false : hasTime; 117 text = null; 118 partialDate = null; 119 } 120 121 /** 122 * Gets the reduced accuracy or truncated date. This is only supported by 123 * vCard 4.0. 124 * @return the reduced accuracy or truncated date or null if not set 125 * @see <a href="http://tools.ietf.org/html/rfc6350">RFC 6350 p.12-14</a> 126 */ 127 public PartialDate getPartialDate() { 128 return partialDate; 129 } 130 131 /** 132 * <p> 133 * Sets the value of this property to a reduced accuracy or truncated date. 134 * This is only supported by vCard 4.0. 135 * </p> 136 * 137 * <pre class="brush:java"> 138 * Birthday bday = new Birthday(); 139 * bday.setPartialDate(PartialDate.date(null, 4, 20)); //April 20 140 * </pre> 141 * @param partialDate the reduced accuracy or truncated date 142 * @see <a href="http://tools.ietf.org/html/rfc6350">RFC 6350 p.12-14</a> 143 */ 144 public void setPartialDate(PartialDate partialDate) { 145 this.partialDate = partialDate; 146 dateHasTime = (partialDate == null) ? false : partialDate.hasTimeComponent(); 147 text = null; 148 date = null; 149 } 150 151 /** 152 * Gets the text value of this type. This is only supported by vCard 4.0. 153 * @return the text value or null if not set 154 */ 155 public String getText() { 156 return text; 157 } 158 159 /** 160 * Sets the value of this property to a text string. This is only supported 161 * by vCard 4.0. 162 * @param text the text value 163 */ 164 public void setText(String text) { 165 this.text = text; 166 date = null; 167 partialDate = null; 168 dateHasTime = false; 169 } 170 171 /** 172 * Determines whether the "date" or "partialDate" fields have a time 173 * component. 174 * @return true if the date has a time component, false if it's strictly a 175 * date, and false if a text value is defined 176 */ 177 public boolean hasTime() { 178 return dateHasTime; 179 } 180 181 /** 182 * <p> 183 * Gets the type of calendar that is used for a date or date-time property 184 * value. 185 * </p> 186 * <p> 187 * <b>Supported versions:</b> {@code 4.0} 188 * </p> 189 * @return the type of calendar or null if not found 190 * @see VCardParameters#getCalscale 191 */ 192 public Calscale getCalscale() { 193 return parameters.getCalscale(); 194 } 195 196 /** 197 * <p> 198 * Sets the type of calendar that is used for a date or date-time property 199 * value. 200 * </p> 201 * <p> 202 * <b>Supported versions:</b> {@code 4.0} 203 * </p> 204 * @param calscale the type of calendar or null to remove 205 * @see VCardParameters#setCalscale 206 */ 207 public void setCalscale(Calscale calscale) { 208 parameters.setCalscale(calscale); 209 } 210 211 @Override 212 public String getLanguage() { 213 return super.getLanguage(); 214 } 215 216 @Override 217 public void setLanguage(String language) { 218 super.setLanguage(language); 219 } 220 221 //@Override 222 public String getAltId() { 223 return parameters.getAltId(); 224 } 225 226 //@Override 227 public void setAltId(String altId) { 228 parameters.setAltId(altId); 229 } 230 231 @Override 232 protected void _validate(List<ValidationWarning> warnings, VCardVersion version, VCard vcard) { 233 if (date == null && partialDate == null && text == null) { 234 warnings.add(new ValidationWarning(8)); 235 } 236 237 if (version == VCardVersion.V2_1 || version == VCardVersion.V3_0) { 238 if (text != null) { 239 warnings.add(new ValidationWarning(11)); 240 } 241 if (partialDate != null) { 242 warnings.add(new ValidationWarning(12)); 243 } 244 } 245 } 246 247 @Override 248 protected Map<String, Object> toStringValues() { 249 Map<String, Object> values = new LinkedHashMap<String, Object>(); 250 values.put("text", text); 251 values.put("date", date); 252 values.put("dateHasTime", dateHasTime); 253 values.put("partialDate", partialDate); 254 return values; 255 } 256 257 @Override 258 public int hashCode() { 259 final int prime = 31; 260 int result = super.hashCode(); 261 result = prime * result + ((date == null) ? 0 : date.hashCode()); 262 result = prime * result + (dateHasTime ? 1231 : 1237); 263 result = prime * result + ((partialDate == null) ? 0 : partialDate.hashCode()); 264 result = prime * result + ((text == null) ? 0 : text.hashCode()); 265 return result; 266 } 267 268 @Override 269 public boolean equals(Object obj) { 270 if (this == obj) return true; 271 if (!super.equals(obj)) return false; 272 DateOrTimeProperty other = (DateOrTimeProperty) obj; 273 if (date == null) { 274 if (other.date != null) return false; 275 } else if (!date.equals(other.date)) return false; 276 if (dateHasTime != other.dateHasTime) return false; 277 if (partialDate == null) { 278 if (other.partialDate != null) return false; 279 } else if (!partialDate.equals(other.partialDate)) return false; 280 if (text == null) { 281 if (other.text != null) return false; 282 } else if (!text.equals(other.text)) return false; 283 return true; 284 } 285}