001: // The contents of this file are subject to the Mozilla Public License Version
002: // 1.1
003: //(the "License"); you may not use this file except in compliance with the
004: //License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
005: //
006: //Software distributed under the License is distributed on an "AS IS" basis,
007: //WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
008: //for the specific language governing rights and
009: //limitations under the License.
010: //
011: //The Original Code is "The Columba Project"
012: //
013: //The Initial Developers of the Original Code are Frederik Dietz and Timo
014: // Stich.
015: //Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
016: //
017: //All Rights Reserved.
018: package org.columba.calendar.parser;
019:
020: import java.io.File;
021: import java.io.FileInputStream;
022: import java.net.URL;
023: import java.util.Calendar;
024: import java.util.HashMap;
025: import java.util.Iterator;
026: import java.util.LinkedList;
027: import java.util.List;
028: import java.util.Map;
029: import java.util.Random;
030: import java.util.Vector;
031:
032: import net.fortuna.ical4j.data.CalendarBuilder;
033: import net.fortuna.ical4j.model.Component;
034: import net.fortuna.ical4j.model.Date;
035: import net.fortuna.ical4j.model.DateTime;
036: import net.fortuna.ical4j.model.Property;
037: import net.fortuna.ical4j.model.WeekDay;
038: import net.fortuna.ical4j.model.property.Categories;
039: import net.fortuna.ical4j.model.property.DtEnd;
040: import net.fortuna.ical4j.model.property.DtStamp;
041: import net.fortuna.ical4j.model.property.DtStart;
042: import net.fortuna.ical4j.model.property.RRule;
043:
044: import org.columba.calendar.base.UUIDGenerator;
045: import org.columba.calendar.base.api.ICalendarItem;
046: import org.columba.calendar.model.Event;
047: import org.columba.calendar.model.EventInfo;
048: import org.columba.calendar.model.Recurrence;
049: import org.columba.calendar.model.api.IEvent;
050: import org.columba.calendar.model.api.IEventInfo;
051: import org.columba.calendar.model.api.IRecurrence;
052: import org.columba.calendar.model.api.IWeekDay;
053:
054: public class CalendarImporter {
055:
056: public CalendarImporter() {
057: super ();
058: }
059:
060: public Iterator<IEventInfo> importCalendar(
061: ICalendarItem calendarItem, File file) throws Exception {
062: Vector<IEventInfo> v = new Vector<IEventInfo>();
063:
064: FileInputStream in = new FileInputStream(file);
065:
066: CalendarBuilder builder = new CalendarBuilder();
067:
068: net.fortuna.ical4j.model.Calendar calendar = builder.build(in);
069:
070: Map<String, Integer> frequency = new HashMap<String, Integer>();
071: frequency.put("YEARLY", new Integer(
072: IRecurrence.RECURRENCE_ANNUALLY));
073: frequency.put("MONTHLY", new Integer(
074: IRecurrence.RECURRENCE_MONTHLY));
075: frequency.put("WEEKLY", new Integer(
076: IRecurrence.RECURRENCE_WEEKLY));
077: frequency.put("DAILY",
078: new Integer(IRecurrence.RECURRENCE_DAILY));
079:
080: for (Iterator i = calendar.getComponents().iterator(); i
081: .hasNext();) {
082: net.fortuna.ical4j.model.Component component = (net.fortuna.ical4j.model.Component) i
083: .next();
084: // System.out.println("Component [" + component.getName() + "]");
085:
086: // only import VEVENT and VTODO for now
087: if (component.getName().equals(Component.VEVENT)) {
088:
089: Calendar dtStart = null;
090: Calendar dtEnd = null;
091: Calendar dtStamp = null;
092: String summary = null;
093: String location = null;
094: String description = null;
095: String uid = null;
096: URL url = null;
097: String eventClass = null;
098: String priority = null;
099: String status = null;
100:
101: List<String> categories = new LinkedList<String>();
102:
103: int freq = -1;
104: int count = -1;
105: int interval = 0;
106: Calendar until = null;
107: List<WeekDay> weekdays = null;
108:
109: for (Iterator j = component.getProperties().iterator(); j
110: .hasNext();) {
111: Property property = (Property) j.next();
112: String name = property.getName();
113: String value = property.getValue();
114:
115: // System.out.println("Property [" + property.getName() + ", "
116: // + property.getValue() + "]");
117:
118: if (name.equals(Property.DTSTART)) {
119: DtStart dtStart1 = (DtStart) property;
120: if (dtStart1.getDate() instanceof DateTime) {
121: DateTime dateTime = (DateTime) dtStart1
122: .getDate();
123: // ensure tzid matches date-time timezone..
124: // Parameter tzId =
125: // dtStart1.getParameters().getParameter(
126: // Parameter.TZID);
127:
128: dtStart = Calendar.getInstance();
129: dtStart.setTimeInMillis(dateTime.getTime());
130: if (dateTime.getTimeZone() != null)
131: dtStart.setTimeZone(dateTime
132: .getTimeZone());
133: } else {
134: Date dateTime = dtStart1.getDate();
135: // ensure tzid matches date-time timezone..
136: // Parameter tzId =
137: // dtStart1.getParameters().getParameter(
138: // Parameter.TZID);
139:
140: dtStart = Calendar.getInstance();
141: dtStart.setTimeInMillis(dateTime.getTime());
142: }
143:
144: } else if (name.equals(Property.DTEND)) {
145: DtEnd dtEnd1 = (DtEnd) property;
146: if (dtEnd1.getDate() instanceof DateTime) {
147: DateTime dateTime = (DateTime) dtEnd1
148: .getDate();
149: // ensure tzid matches date-time timezone..
150: // Parameter tzId = dtEnd1.getParameters().getParameter(
151: // Parameter.TZID);
152:
153: dtEnd = Calendar.getInstance();
154: dtEnd.setTimeInMillis(dateTime.getTime());
155: if (dateTime.getTimeZone() != null)
156: dtEnd.setTimeZone(dateTime
157: .getTimeZone());
158: } else {
159: Date dateTime = dtEnd1.getDate();
160: // ensure tzid matches date-time timezone..
161: // Parameter tzId = dtEnd1.getParameters().getParameter(
162: // Parameter.TZID);
163:
164: dtEnd = Calendar.getInstance();
165: dtEnd.setTimeInMillis(dateTime.getTime());
166: }
167: } else if (name.equals(Property.SUMMARY)) {
168: summary = value;
169: } else if (name.equals(Property.LOCATION)) {
170: location = value;
171: } else if (name.equals(Property.DTSTAMP)) {
172: DtStamp dtStamp1 = (DtStamp) property;
173: if (dtStamp1.getDate() instanceof DateTime) {
174: DateTime dateTime = (DateTime) dtStamp1
175: .getDate();
176: // ensure tzid matches date-time timezone..
177: // Parameter tzId =
178: // dtStamp1.getParameters().getParameter(
179: // Parameter.TZID);
180:
181: dtStamp = Calendar.getInstance();
182:
183: dtStamp.setTimeInMillis(dateTime.getTime());
184: if (dateTime.getTimeZone() != null)
185: dtStamp.setTimeZone(dateTime
186: .getTimeZone());
187: } else {
188: Date dateTime = dtStamp1.getDate();
189: // ensure tzid matches date-time timezone..
190: // Parameter tzId =
191: // dtStamp1.getParameters().getParameter(
192: // Parameter.TZID);
193:
194: dtStamp = Calendar.getInstance();
195:
196: dtStamp.setTimeInMillis(dateTime.getTime());
197: }
198: } else if (name.equals(Property.UID)) {
199: // remove everything which is not A-Za-z0-9-_
200: uid = correctUid(value);
201: } else if (name.equals(Property.URL)) {
202: url = new URL(value);
203: } else if (name.equals(Property.DESCRIPTION)) {
204: description = value;
205: } else if (name.equals(Property.CATEGORIES)) {
206: Categories categorylist = (Categories) property;
207: for (Iterator iter = categorylist
208: .getCategories().iterator(); iter
209: .hasNext();) {
210: String c = (String) iter.next();
211: categories.add(c);
212: }
213: } else if (name.equals(Property.CLASS)) {
214: eventClass = value;
215: } else if (name.equals(Property.PRIORITY)) {
216: priority = value;
217: } else if (name.equals(Property.STATUS)) {
218: status = value;
219: } else if (name.equals(Property.RRULE)) {
220: // RRULE:FREQ=YEARLY;COUNT=5;INTERVAL=1
221: // RRULE:FREQ=WEEKLY;UNTIL=20060725T215959;INTERVAL=1;BYDAY=TU
222: // RRULE:FREQ=YEARLY;INTERVAL=1
223:
224: // RRULE:FREQ=WEEKLY;COUNT=8;INTERVAL=2;BYDAY=TU,TH
225: // RRULE:FREQ=MONTHLY;UNTIL=20070627T215959;INTERVAL=2;BYDAY=4WE
226: // RRULE:FREQ=YEARLY;INTERVAL=1
227: // RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
228: // RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
229:
230: RRule rrule = (RRule) property;
231: freq = ((Integer) frequency.get(rrule
232: .getRecur().getFrequency())).intValue();
233: if (rrule.getRecur().getCount() > 0)
234: count = rrule.getRecur().getCount();
235: if (rrule.getRecur().getInterval() > 0)
236: interval = rrule.getRecur().getInterval();
237: weekdays = rrule.getRecur().getDayList();
238: /*for (Iterator iter = rrule.getRecur().getWeekNoList().iterator(); iter.hasNext(); ) {
239: Object o = iter.next();
240: System.out.println("weeknolist = " + o);
241: }
242: for (Iterator iter = rrule.getRecur().getMonthList().iterator(); iter.hasNext(); ) {
243: Object o = iter.next();
244: System.out.println("monthlist = " + o);
245: }*/
246: if (rrule.getRecur().getUntil() != null) {
247: until = Calendar.getInstance();
248: until.setTime(rrule.getRecur().getUntil());
249: // System.out.println("until = " + until);
250: }
251: }
252:
253: }
254:
255: // skip, if UID, dtStart or dtEnd is not defined
256: if (uid == null || dtStart == null || dtEnd == null)
257: continue;
258:
259: // hack: if start and end time is at 00:00:00:000 it is
260: // an all day event
261: boolean allDayEvent = ParserHelper.isAllDayEvent(
262: dtStart, dtEnd);
263:
264: IEvent event = new Event(uid);
265:
266: event.setDtStart(dtStart);
267: event.setDtEnd(dtEnd);
268: event.setDtStamp(dtStamp);
269: event.setAllDayEvent(allDayEvent);
270:
271: if (summary != null)
272: event.setSummary(summary);
273: if (eventClass != null)
274: event.setEventClass(eventClass);
275: if (location != null)
276: event.setLocation(location);
277: if (priority != null)
278: event.setPriority(priority);
279: if (status != null)
280: event.setStatus(status);
281: if (url != null)
282: event.setUrl(url);
283: if (description != null)
284: event.setDescription(description);
285:
286: if (freq > -1) {
287: // create recurrence
288: Recurrence r = new Recurrence(freq);
289:
290: r.setInterval(interval);
291:
292: List<IWeekDay> wdlist = new LinkedList<IWeekDay>();
293: if (weekdays != null) {
294: for (Iterator iter = weekdays.iterator(); iter
295: .hasNext();) {
296: WeekDay owd = (WeekDay) iter.next();
297: org.columba.calendar.model.WeekDay wd = new org.columba.calendar.model.WeekDay(
298: owd.getDay(), owd.getOffset());
299: wdlist.add(wd);
300: }
301:
302: r.setWeekDays(wdlist);
303: }
304:
305: r.setEndType(IRecurrence.RECURRENCE_END_FOREVER);
306: if (until != null) {
307: r.setEndDate(until);
308: r
309: .setEndType(IRecurrence.RECURRENCE_END_ENDDATE);
310: } else if (count > -1) {
311: r.setEndMaxOccurrences(count);
312: r
313: .setEndType(IRecurrence.RECURRENCE_END_MAXOCCURRENCES);
314: }
315:
316: event.setRecurrence(r);
317:
318: } else {
319: event.setRecurrence(null);
320: }
321:
322: for (String category : categories)
323: event.addCategory(category);
324:
325: IEventInfo eventInfo = new EventInfo(uid, calendarItem
326: .getId(), event);
327:
328: v.add(eventInfo);
329: } else if (component.getName().equals(Component.VTIMEZONE)) {
330: for (Iterator j = component.getProperties().iterator(); j
331: .hasNext();) {
332: Property property = (Property) j.next();
333:
334: System.out.println("Property ["
335: + property.getName() + ", "
336: + property.getValue() + "]");
337: }
338: } else if (component.getName().equals(Component.VTODO)) {
339:
340: for (Iterator j = component.getProperties().iterator(); j
341: .hasNext();) {
342: Property property = (Property) j.next();
343: String name = property.getName();
344: String value = property.getValue();
345:
346: System.out.println("Property ["
347: + property.getName() + ", "
348: + property.getValue() + "]");
349: }
350:
351: }
352: }
353:
354: in.close();
355:
356: return v.iterator();
357: }
358:
359: public static String correctUid(String value) {
360: // if there is no string given, return a number
361: Random r = new Random();
362: if (value == null || value.length() == 0)
363: return (new UUIDGenerator()).newUUID();
364: return value.replaceAll("[^a-z,0-9,A-Z,_-]", "-");
365: }
366:
367: }
|