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 isVTodo() {
104         return "VTODO".equals(type);
105     }
106 
107     public boolean isVAlarm() {
108         return "VALARM".equals(type);
109     }
110 
111 
112     protected void handleLine(String line, BufferedReader reader) throws IOException {
113         // skip empty lines
114         if (line.length() > 0) {
115             VProperty property = new VProperty(line);
116             // inner object
117             if ("BEGIN".equals(property.getKey())) {
118                 addVObject(new VObject(property, reader));
119             } else if (property.getKey() != null) {
120                 addProperty(property);
121             }
122         }
123     }
124 
125     /**
126      * Add vObject.
127      *
128      * @param vObject inner object
129      */
130     public void addVObject(VObject vObject) {
131         if (vObjects == null) {
132             vObjects = new ArrayList<>();
133         }
134         vObjects.add(vObject);
135     }
136 
137     /**
138      * Add vProperty.
139      *
140      * @param property vProperty
141      */
142     public void addProperty(VProperty property) {
143         if (property.getValue() != null) {
144             if (properties == null) {
145                 properties = new ArrayList<>();
146             }
147             properties.add(property);
148         }
149     }
150 
151     /**
152      * Write VObject to writer.
153      *
154      * @param writer buffered writer
155      */
156     public void writeTo(ICSBufferedWriter writer) {
157         writer.write("BEGIN:");
158         writer.writeLine(type);
159         if (properties != null) {
160             for (VProperty property : properties) {
161                 writer.writeLine(property.toString());
162             }
163         }
164         if (vObjects != null) {
165             for (VObject object : vObjects) {
166                 object.writeTo(writer);
167             }
168         }
169         writer.write("END:");
170         writer.writeLine(type);
171     }
172 
173     public String toString() {
174         ICSBufferedWriter writer = new ICSBufferedWriter();
175         writeTo(writer);
176         return writer.toString();
177     }
178 
179     /**
180      * Get VObject properties
181      *
182      * @return properties
183      */
184     public List<VProperty> getProperties() {
185         return properties;
186     }
187 
188     /**
189      * Get vProperty by name.
190      *
191      * @param name property name
192      * @return property object
193      */
194     public VProperty getProperty(String name) {
195         if (properties != null) {
196             for (VProperty property : properties) {
197                 if (property.getKey() != null && property.getKey().equalsIgnoreCase(name)) {
198                     return property;
199                 }
200             }
201 
202         }
203         return null;
204     }
205 
206     /**
207      * Get multivalued vProperty by name.
208      *
209      * @param name property name
210      * @return property list
211      */
212     public List<VProperty> getProperties(String name) {
213         List<VProperty> result = null;
214         if (properties != null) {
215             for (VProperty property : properties) {
216                 if (property.getKey() != null && property.getKey().equalsIgnoreCase(name)) {
217                     if (result == null) {
218                         result = new ArrayList<>();
219                     }
220                     result.add(property);
221                 }
222             }
223 
224         }
225         return result;
226     }
227 
228     /**
229      * Get vProperty value by name.
230      *
231      * @param name property name
232      * @return property value
233      */
234     public String getPropertyValue(String name) {
235         VProperty property = getProperty(name);
236         if (property != null) {
237             return property.getValue();
238         } else {
239             return null;
240         }
241     }
242 
243     /**
244      * Set vProperty value on vObject, remove property if value is null.
245      *
246      * @param name  property name
247      * @param value property value
248      */
249     public void setPropertyValue(String name, String value) {
250         if (value == null) {
251             removeProperty(name);
252         } else {
253             VProperty property = getProperty(name);
254             if (property == null) {
255                 property = new VProperty(name, value);
256                 addProperty(property);
257             } else {
258                 property.setValue(value);
259             }
260         }
261     }
262 
263     /**
264      * Add vProperty value on vObject.
265      *
266      * @param name  property name
267      * @param value property value
268      */
269     public void addPropertyValue(String name, String value) {
270         if (value != null) {
271             VProperty property = new VProperty(name, value);
272             addProperty(property);
273         }
274     }
275 
276     /**
277      * Remove vProperty from vObject.
278      *
279      * @param name property name
280      */
281     public void removeProperty(String name) {
282         if (properties != null) {
283             VProperty property = getProperty(name);
284             if (property != null) {
285                 properties.remove(property);
286             }
287         }
288     }
289 
290     /**
291      * Remove vProperty object from vObject.
292      *
293      * @param property object
294      */
295     public void removeProperty(VProperty property) {
296         if (properties != null) {
297             properties.remove(property);
298         }
299     }
300 
301     public void setType(String type) {
302         this.type = type;
303     }
304 
305 }