001    package biweekly.property;
002    
003    import java.util.ArrayList;
004    import java.util.Collection;
005    import java.util.List;
006    
007    import biweekly.ICalendar;
008    import biweekly.component.ICalComponent;
009    import biweekly.component.VTimezone;
010    import biweekly.parameter.ICalParameters;
011    
012    /*
013     Copyright (c) 2013, 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     * Base class for all iCalendar properties.
039     * @author Michael Angstadt
040     */
041    public abstract class ICalProperty {
042            /**
043             * The property parameters.
044             */
045            protected ICalParameters parameters = new ICalParameters();
046    
047            /**
048             * Gets the property's parameters.
049             * @return the parameters
050             */
051            public ICalParameters getParameters() {
052                    return parameters;
053            }
054    
055            /**
056             * Sets the property's parameters
057             * @param parameters the parameters
058             */
059            public void setParameters(ICalParameters parameters) {
060                    this.parameters = parameters;
061            }
062    
063            /**
064             * Gets the first value of the parameter with the given name.
065             * @param name the parameter name (case insensitive, e.g. "LANGUAGE")
066             * @return the parameter value or null if not found
067             */
068            public String getParameter(String name) {
069                    return parameters.first(name);
070            }
071    
072            /**
073             * Gets all values of the parameter with the given name.
074             * @param name the parameter name (case insensitive, e.g. "LANGUAGE")
075             * @return the parameter values
076             */
077            public List<String> getParameters(String name) {
078                    return parameters.get(name);
079            }
080    
081            /**
082             * Adds a value to a parameter.
083             * @param name the parameter name (case insensitive, e.g. "LANGUAGE")
084             * @param value the parameter value
085             */
086            public void addParameter(String name, String value) {
087                    parameters.put(name, value);
088            }
089    
090            /**
091             * Sets a parameter's value, replacing all pre-existing values.
092             * @param name the parameter name (case insensitive, e.g. "LANGUAGE")
093             * @param value the parameter value
094             */
095            public void setParameter(String name, String value) {
096                    parameters.replace(name, value);
097            }
098    
099            /**
100             * Sets a parameter's values, replacing all pre-existing values.
101             * @param name the parameter name (case insensitive, e.g. "LANGUAGE")
102             * @param values the parameter values
103             */
104            public void setParameter(String name, Collection<String> values) {
105                    parameters.replace(name, values);
106            }
107    
108            /**
109             * Removes a parameter from the property.
110             * @param name the parameter name (case insensitive, e.g. "LANGUAGE")
111             */
112            public void removeParameter(String name) {
113                    parameters.removeAll(name);
114            }
115    
116            /**
117             * Gets a URI pointing to additional information about the entity
118             * represented by the property.
119             * @return the URI or null if not set
120             * @see <a href="http://tools.ietf.org/html/rfc5545#page-14">RFC 5545
121             * p.14-5</a>
122             */
123            protected String getAltRepresentation() {
124                    return parameters.getAltRepresentation();
125            }
126    
127            /**
128             * Sets a URI pointing to additional information about the entity
129             * represented by the property.
130             * @param uri the URI or null to remove
131             * @see <a href="http://tools.ietf.org/html/rfc5545#page-14">RFC 5545
132             * p.14-5</a>
133             */
134            protected void setAltRepresentation(String uri) {
135                    parameters.setAltRepresentation(uri);
136            }
137    
138            /**
139             * Gets the content-type of the property's value.
140             * @return the content type (e.g. "image/png") or null if not set
141             * @see <a href="http://tools.ietf.org/html/rfc5545#page-19">RFC 5545
142             * p.19-20</a>
143             */
144            protected String getFormatType() {
145                    return parameters.getFormatType();
146            }
147    
148            /**
149             * Sets the content-type of the property's value.
150             * @param formatType the content type (e.g. "image/png") or null to remove
151             * @see <a href="http://tools.ietf.org/html/rfc5545#page-19">RFC 5545
152             * p.19-20</a>
153             */
154            protected void setFormatType(String formatType) {
155                    parameters.setFormatType(formatType);
156            }
157    
158            /**
159             * Gets the language that the property value is written in.
160             * @return the language (e.g. "en" for English) or null if not set
161             * @see <a href="http://tools.ietf.org/html/rfc5545#page-21">RFC 5545
162             * p.21</a>
163             */
164            protected String getLanguage() {
165                    return parameters.getLanguage();
166            }
167    
168            /**
169             * Sets the language that the property value is written in.
170             * @param language the language (e.g. "en" for English) or null to remove
171             * @see <a href="http://tools.ietf.org/html/rfc5545#page-21">RFC 5545
172             * p.21</a>
173             */
174            protected void setLanguage(String language) {
175                    parameters.setLanguage(language);
176            }
177    
178            /**
179             * Gets the timezone identifier. This either (a) references the
180             * {@link TimezoneId} property of a {@link VTimezone} component, or (b)
181             * specifies a globally-defined timezone (e.g. "America/New_York"). For a
182             * list of globally-defined timezones, see the <a
183             * href="http://www.twinsun.com/tz/tz-link.htm">TZ database</a>.
184             * @return the timezone identifier or null if not set
185             * @see <a href="http://tools.ietf.org/html/rfc5545#page-27">RFC 5545
186             * p.27-8</a>
187             */
188            protected String getTimezoneId() {
189                    return parameters.getTimezoneId();
190            }
191    
192            /**
193             * Sets the property's timezone in the form of a globally-defined timezone
194             * (e.g. "America/New_York"). For a list of globally-defined timezones, see
195             * the <a href="http://www.twinsun.com/tz/tz-link.htm">TZ database</a>. Use
196             * {@link #setTimezone(VTimezone)} to use a timezone that's defined within
197             * the iCalendar object.
198             * @param timezoneId the timezone identifier (e.g. "America/New_York") or
199             * null to remove
200             * @see <a href="http://tools.ietf.org/html/rfc5545#page-27">RFC 5545
201             * p.27-8</a>
202             */
203            protected void setTimezoneId(String timezoneId) {
204                    parameters.setTimezoneId(timezoneId);
205            }
206    
207            /**
208             * Sets the property's timezone to a timezone that is defined within the
209             * iCalendar object. Use {@link #setTimezoneId(String)} to use a
210             * globally-defined timezone (e.g. "America/New_York").
211             * @param timezone the timezone component or null to remove
212             * @see <a href="http://tools.ietf.org/html/rfc5545#page-27">RFC 5545
213             * p.27-8</a>
214             */
215            protected void setTimezone(VTimezone timezone) {
216                    if (timezone == null) {
217                            setTimezoneId(null);
218                            return;
219                    }
220    
221                    TimezoneId tzid = timezone.getTimezoneId();
222                    if (tzid != null) {
223                            setTimezoneId(tzid.getValue());
224                    }
225            }
226    
227            /**
228             * Gets a person that is acting on behalf of the person defined in the
229             * property.
230             * @return a URI representing the person (typically, an email URI, e.g.
231             * "mailto:janedoe@example.com") or null if not set
232             * @see <a href="http://tools.ietf.org/html/rfc5545#page-27">RFC 5545
233             * p.27</a>
234             */
235            protected String getSentBy() {
236                    return parameters.getSentBy();
237            }
238    
239            /**
240             * Sets a person that is acting on behalf of the person defined in the
241             * property.
242             * @param uri a URI representing the person (typically, an email URI, e.g.
243             * "mailto:janedoe@example.com") or null to remove
244             * @see <a href="http://tools.ietf.org/html/rfc5545#page-27">RFC 5545
245             * p.27</a>
246             */
247            protected void setSentBy(String uri) {
248                    parameters.setSentBy(uri);
249            }
250    
251            /**
252             * Gets the display name of the person.
253             * @return the display name (e.g. "John Doe") or null if not set
254             * @see <a href="http://tools.ietf.org/html/rfc5545#page-15">RFC 5545
255             * p.15-6</a>
256             */
257            protected String getCommonName() {
258                    return parameters.getCommonName();
259            }
260    
261            /**
262             * Sets the display name of the person.
263             * @param commonName the display name (e.g. "John Doe") or null to remove
264             * @see <a href="http://tools.ietf.org/html/rfc5545#page-15">RFC 5545
265             * p.15-6</a>
266             */
267            protected void setCommonName(String commonName) {
268                    parameters.setCommonName(commonName);
269            }
270    
271            /**
272             * Gets a URI that contains additional information about the person.
273             * @return the URI (e.g. an LDAP URI) or null if not set
274             * @see <a href="http://tools.ietf.org/html/rfc5545#page-18">RFC 5545
275             * p.18</a>
276             */
277            protected String getDirectoryEntry() {
278                    return parameters.getDirectoryEntry();
279            }
280    
281            /**
282             * Sets a URI that contains additional information about the person.
283             * @param uri the URI (e.g. an LDAP URI) or null to remove
284             * @see <a href="http://tools.ietf.org/html/rfc5545#page-18">RFC 5545
285             * p.18</a>
286             */
287            protected void setDirectoryEntry(String uri) {
288                    parameters.setDirectoryEntry(uri);
289            }
290    
291            /**
292             * Checks the property for data consistency problems or deviations from the
293             * spec. These problems will not prevent the property from being written to
294             * a data stream, but may prevent it from being parsed correctly by the
295             * consuming application. These problems can largely be avoided by reading
296             * the Javadocs of the property class, or by being familiar with the
297             * iCalendar standard.
298             * @param components the hierarchy of components that the property belongs
299             * to
300             * @see ICalendar#validate
301             * @return a list of warnings or an empty list if no problems were found
302             */
303            public final List<String> validate(List<ICalComponent> components) {
304                    List<String> warnings = new ArrayList<String>(0);
305                    validate(components, warnings);
306                    return warnings;
307            }
308    
309            /**
310             * Checks the property for data consistency problems or deviations from the
311             * spec. Meant to be overridden by child classes.
312             * @param components the hierarchy of components that the property belongs
313             * to
314             * @param warnings the list to add the warnings to
315             */
316            protected void validate(List<ICalComponent> components, List<String> warnings) {
317                    //do nothing
318            }
319    }