View Javadoc
1   /*
2    * DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
3    * Copyright (C) 2010  Mickael Guessant
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18   */
19  package davmail.exchange;
20  
21  import java.io.BufferedReader;
22  import java.io.IOException;
23  import java.io.StringReader;
24  import java.util.ArrayList;
25  import java.util.List;
26  
27  /**
28   * Base class for VCalendar, VTimezone, VEvent.
29   */
30  public class VObject {
31      /**
32       * VObject properties
33       */
34      ArrayList<VProperty> properties;
35      /**
36       * Inner VObjects (e.g. VEVENT, VALARM, ...)
37       */
38      ArrayList<VObject> vObjects;
39      /**
40       * Object base name (VCALENDAR, VEVENT, VCARD...).
41       */
42      public String type;
43  
44      /**
45       * Create VObject with given type
46       *
47       * @param beginProperty first line property
48       * @param reader        stream reader just after the BEGIN:TYPE line
49       * @throws IOException on error
50       */
51      public VObject(VProperty beginProperty, BufferedReader reader) throws IOException {
52          if (!"BEGIN".equals(beginProperty.getKey())) {
53              throw new IOException("Invalid first line: " + beginProperty);
54          }
55          type = beginProperty.getValue();
56          String beginLine = "BEGIN:" + type;
57          String endLine = "END:" + type;
58          String line = reader.readLine();
59          while (line != null && !line.startsWith(endLine)) {
60              // ignore invalid BEGIN line inside object (Sogo Carddav issue)
61              if (!beginLine.equals(line)) {
62                  handleLine(line, reader);
63              }
64              line = reader.readLine();
65          }
66          // ignore missing END:VCALENDAR line on modified occurrences
67      }
68  
69      /**
70       * Create VObject from reader.
71       *
72       * @param reader stream reader just after the BEGIN:TYPE line
73       * @throws IOException on error
74       */
75      public VObject(BufferedReader reader) throws IOException {
76          this(new VProperty(reader.readLine()), reader);
77      }
78  
79      /**
80       * Create VCalendar object from string;
81       *
82       * @param itemBody item body
83       * @throws IOException on error
84       */
85      public VObject(String itemBody) throws IOException {
86          this(new ICSBufferedReader(new StringReader(itemBody)));
87      }
88  
89      /**
90       * Create empty VCalendar object;
91       */
92      public VObject() {
93      }
94  
95      public boolean isVTimezone() {
96          return "VTIMEZONE".equals(type);
97      }
98  
99      public boolean isVEvent() {
100         return "VEVENT".equals(type);
101     }
102 
103     public boolean isVAlarm() {
104         return "VALARM".equals(type);
105     }
106 
107 
108     protected void handleLine(String line, BufferedReader reader) throws IOException {
109         // skip empty lines
110         if (line.length() > 0) {
111             VProperty property = new VProperty(line);
112             // inner object
113             if ("BEGIN".equals(property.getKey())) {
114                 addVObject(new VObject(property, reader));
115             } else if (property.getKey() != null) {
116                 addProperty(property);
117             }
118         }
119     }
120 
121     /**
122      * Add vObject.
123      *
124      * @param vObject inner object
125      */
126     public void addVObject(VObject vObject) {
127         if (vObjects == null) {
128             vObjects = new ArrayList<>();
129         }
130         vObjects.add(vObject);
131     }
132 
133     /**
134      * Add vProperty.
135      *
136      * @param property vProperty
137      */
138     public void addProperty(VProperty property) {
139         if (property.getValue() != null) {
140             if (properties == null) {
141                 properties = new ArrayList<>();
142             }
143             properties.add(property);
144         }
145     }
146 
147     /**
148      * Write VObject to writer.
149      *
150      * @param writer buffered writer
151      */
152     public void writeTo(ICSBufferedWriter writer) {
153         writer.write("BEGIN:");
154         writer.writeLine(type);
155         if (properties != null) {
156             for (VProperty property : properties) {
157                 writer.writeLine(property.toString());
158             }
159         }
160         if (vObjects != null) {
161             for (VObject object : vObjects) {
162                 object.writeTo(writer);
163             }
164         }
165         writer.write("END:");
166         writer.writeLine(type);
167     }
168 
169     public String toString() {
170         ICSBufferedWriter writer = new ICSBufferedWriter();
171         writeTo(writer);
172         return writer.toString();
173     }
174 
175     /**
176      * Get VObject properties
177      *
178      * @return properties
179      */
180     public List<VProperty> getProperties() {
181         return properties;
182     }
183 
184     /**
185      * Get vProperty by name.
186      *
187      * @param name property name
188      * @return property object
189      */
190     public VProperty getProperty(String name) {
191         if (properties != null) {
192             for (VProperty property : properties) {
193                 if (property.getKey() != null && property.getKey().equalsIgnoreCase(name)) {
194                     return property;
195                 }
196             }
197 
198         }
199         return null;
200     }
201 
202     /**
203      * Get multivalued vProperty by name.
204      *
205      * @param name property name
206      * @return property list
207      */
208     public List<VProperty> getProperties(String name) {
209         List<VProperty> result = null;
210         if (properties != null) {
211             for (VProperty property : properties) {
212                 if (property.getKey() != null && property.getKey().equalsIgnoreCase(name)) {
213                     if (result == null) {
214                         result = new ArrayList<>();
215                     }
216                     result.add(property);
217                 }
218             }
219 
220         }
221         return result;
222     }
223 
224     /**
225      * Get vProperty value by name.
226      *
227      * @param name property name
228      * @return property value
229      */
230     public String getPropertyValue(String name) {
231         VProperty property = getProperty(name);
232         if (property != null) {
233             return property.getValue();
234         } else {
235             return null;
236         }
237     }
238 
239     /**
240      * Set vProperty value on vObject, remove property if value is null.
241      *
242      * @param name  property name
243      * @param value property value
244      */
245     public void setPropertyValue(String name, String value) {
246         if (value == null) {
247             removeProperty(name);
248         } else {
249             VProperty property = getProperty(name);
250             if (property == null) {
251                 property = new VProperty(name, value);
252                 addProperty(property);
253             } else {
254                 property.setValue(value);
255             }
256         }
257     }
258 
259     /**
260      * Add vProperty value on vObject.
261      *
262      * @param name  property name
263      * @param value property value
264      */
265     public void addPropertyValue(String name, String value) {
266         if (value != null) {
267             VProperty property = new VProperty(name, value);
268             addProperty(property);
269         }
270     }
271 
272     /**
273      * Remove vProperty from vObject.
274      *
275      * @param name property name
276      */
277     public void removeProperty(String name) {
278         if (properties != null) {
279             VProperty property = getProperty(name);
280             if (property != null) {
281                 properties.remove(property);
282             }
283         }
284     }
285 
286     /**
287      * Remove vProperty object from vObject.
288      *
289      * @param property object
290      */
291     public void removeProperty(VProperty property) {
292         if (properties != null) {
293             properties.remove(property);
294         }
295     }
296 
297     public void setType(String type) {
298         this.type = type;
299     }
300 
301 }