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.store;
019:
020: import java.io.File;
021: import java.util.ArrayList;
022: import java.util.Calendar;
023: import java.util.Iterator;
024: import java.util.Vector;
025:
026: import org.columba.calendar.base.UUIDGenerator;
027: import org.columba.calendar.model.ComponentInfoList;
028: import org.columba.calendar.model.DateRange;
029: import org.columba.calendar.model.api.IComponent;
030: import org.columba.calendar.model.api.IComponentInfo;
031: import org.columba.calendar.model.api.IComponentInfoList;
032: import org.columba.calendar.model.api.IDateRange;
033: import org.columba.calendar.model.api.IEvent;
034: import org.columba.calendar.model.api.IEventInfo;
035: import org.columba.calendar.model.api.ITodo;
036: import org.columba.calendar.parser.SyntaxException;
037: import org.columba.calendar.parser.VCalendarModelFactory;
038: import org.columba.calendar.store.api.ICalendarStore;
039: import org.columba.calendar.store.api.StoreException;
040: import org.columba.core.io.DiskIO;
041: import org.jdom.Document;
042:
043: public class LocalCalendarStore extends AbstractCalendarStore implements
044: ICalendarStore {
045:
046: private LocalXMLFileStore dataStorage;
047:
048: public LocalCalendarStore(File directory) throws StoreException {
049: super ();
050:
051: if (directory == null)
052: throw new IllegalArgumentException("directory == null");
053:
054: DiskIO.ensureDirectory(directory);
055:
056: dataStorage = new LocalXMLFileStore(directory);
057: }
058:
059: /**
060: * @see org.columba.calendar.store.AbstractCalendarStore#add(org.columba.calendar.model.api.IComponent)
061: */
062: public void add(IComponentInfo basicModel) throws StoreException {
063:
064: if (basicModel == null)
065: throw new IllegalArgumentException("basicModel == null");
066:
067: String id = basicModel.getId();
068: // generate new UUID if it does not exist yet
069: if (id == null)
070: id = new UUIDGenerator().newUUID();
071:
072: Document document = null;
073: try {
074: document = VCalendarModelFactory.marshall(basicModel);
075: } catch (SyntaxException e) {
076: throw new StoreException(e);
077: } catch (IllegalArgumentException e) {
078: throw new StoreException(e);
079: }
080:
081: dataStorage.save(id, document);
082:
083: fireItemAdded(id);
084:
085: }
086:
087: /**
088: * @see org.columba.calendar.store.AbstractCalendarStore#exists(java.lang.Object)
089: */
090: public boolean exists(Object id) throws StoreException {
091:
092: if (id == null)
093: throw new IllegalArgumentException("id == null");
094:
095: return dataStorage.exists(id);
096: }
097:
098: /**
099: * @see org.columba.calendar.store.AbstractCalendarStore#get(java.lang.Object)
100: */
101: public IComponentInfo get(Object id) throws StoreException {
102:
103: if (id == null)
104: throw new IllegalArgumentException("id == null");
105:
106: Document document = dataStorage.load(id);
107: if (document == null)
108: throw new StoreException("document == null, id=" + id);
109:
110: IComponentInfo basicModel = null;
111: try {
112: basicModel = VCalendarModelFactory.unmarshall(document);
113: } catch (SyntaxException e) {
114: throw new StoreException(e);
115: } catch (IllegalArgumentException e) {
116: throw new StoreException(e);
117: }
118:
119: return basicModel;
120: }
121:
122: /**
123: * @see org.columba.calendar.store.AbstractCalendarStore#modify(java.lang.Object,
124: * org.columba.calendar.model.api.IComponent)
125: */
126: public void modify(Object id, IComponentInfo basicModel)
127: throws StoreException {
128: if (id == null)
129: throw new IllegalArgumentException("id == null");
130:
131: if (basicModel == null)
132: throw new IllegalArgumentException("basicModel == null");
133:
134: // remove old data
135: dataStorage.remove(id);
136:
137: // generate xml document
138: Document document = null;
139: try {
140: document = VCalendarModelFactory.marshall(basicModel);
141: } catch (SyntaxException e) {
142: throw new StoreException(e);
143: } catch (IllegalArgumentException e) {
144: throw new StoreException(e);
145: }
146:
147: // add new data to local store
148: dataStorage.save(id, document);
149:
150: super .modify(id, basicModel);
151: }
152:
153: /**
154: * @see org.columba.calendar.store.AbstractCalendarStore#remove(java.lang.Object)
155: */
156: public void remove(Object id) throws StoreException {
157: if (id == null)
158: throw new IllegalArgumentException("id == null");
159:
160: dataStorage.remove(id);
161:
162: super .remove(id);
163: }
164:
165: /**
166: * @see org.columba.calendar.store.AbstractCalendarStore#getComponentInfoList()
167: */
168: public IComponentInfoList getComponentInfoList()
169: throws StoreException {
170:
171: IComponentInfoList list = new ComponentInfoList();
172:
173: Iterator it = dataStorage.iterator();
174: while (it.hasNext()) {
175: Document document = (Document) it.next();
176:
177: IComponentInfo basicModel = null;
178: try {
179: basicModel = VCalendarModelFactory.unmarshall(document);
180: } catch (SyntaxException e) {
181: throw new StoreException(e);
182: } catch (IllegalArgumentException e) {
183: throw new StoreException(e);
184: }
185:
186: if (basicModel.getType() == IComponent.TYPE.EVENT) {
187: IEventInfo event = (IEventInfo) basicModel;
188: list.add(event);
189: }
190: }
191:
192: return list;
193: }
194:
195: public IComponentInfoList getComponentInfoList(String calendarId)
196: throws StoreException {
197: IComponentInfoList list = new ComponentInfoList();
198:
199: Iterator it = dataStorage.iterator();
200: while (it.hasNext()) {
201: Document document = (Document) it.next();
202:
203: IComponentInfo basicModel = null;
204: try {
205: basicModel = VCalendarModelFactory.unmarshall(document);
206: } catch (SyntaxException e) {
207: throw new StoreException(e);
208: } catch (IllegalArgumentException e) {
209: throw new StoreException(e);
210: }
211:
212: if (basicModel.getType() == IComponent.TYPE.EVENT) {
213: IEventInfo event = (IEventInfo) basicModel;
214: if (event.getCalendar().equals(calendarId)) {
215: list.add(event);
216: }
217: }
218: }
219:
220: return list;
221: }
222:
223: public Iterator<String> getIdIterator() throws StoreException {
224: ArrayList<String> result = new ArrayList<String>();
225:
226: Iterator it = dataStorage.iterator();
227: while (it.hasNext()) {
228: Document document = (Document) it.next();
229:
230: IComponentInfo basicModel = null;
231: try {
232: basicModel = VCalendarModelFactory.unmarshall(document);
233: } catch (SyntaxException e) {
234: throw new StoreException(e);
235: } catch (IllegalArgumentException e) {
236: throw new StoreException(e);
237: }
238:
239: if (basicModel.getType() == IComponent.TYPE.EVENT) {
240: IEventInfo event = (IEventInfo) basicModel;
241: result.add(event.getId());
242: }
243: }
244:
245: return result.iterator();
246: }
247:
248: public Iterator<String> getIdIterator(String calendarId)
249: throws StoreException {
250: ArrayList<String> result = new ArrayList<String>();
251:
252: Iterator it = dataStorage.iterator();
253: while (it.hasNext()) {
254: Document document = (Document) it.next();
255:
256: IComponentInfo basicModel = null;
257: try {
258: basicModel = VCalendarModelFactory.unmarshall(document);
259: } catch (SyntaxException e) {
260: throw new StoreException(e);
261: } catch (IllegalArgumentException e) {
262: throw new StoreException(e);
263: }
264:
265: if (basicModel.getType() == IComponent.TYPE.EVENT) {
266: IEventInfo event = (IEventInfo) basicModel;
267: if (event.getCalendar().equals(calendarId))
268: result.add(event.getId());
269: }
270: }
271:
272: return result.iterator();
273: }
274:
275: /**
276: * *********************** very slow search implementation
277: * **********************
278: */
279:
280: /**
281: * @see org.columba.calendar.store.api.ICalendarStore#findByDateRange(org.columba.calendar.model.api.IDateRange)
282: */
283: public Iterator<String> findByDateRange(IDateRange dateRange)
284: throws StoreException {
285: Vector<String> result = new Vector<String>();
286:
287: Iterator<String> it = getIdIterator();
288: while (it.hasNext()) {
289: String id = it.next();
290: IComponentInfo c = get(id);
291: if (c.getType().equals(IComponent.TYPE.EVENT)) {
292: IEvent event = (IEvent) c;
293: Calendar startDate = event.getDtStart();
294: Calendar endDate = event.getDtEnd();
295: IDateRange dr = new DateRange(startDate, endDate);
296: if (dateRange.equals(dr))
297: result.add(id);
298: } else if (c.getType().equals(IComponent.TYPE.TODO)) {
299: ITodo todo = (ITodo) c;
300: Calendar startDate = todo.getDtStart();
301: Calendar endDate = todo.getDue();
302: IDateRange dr = new DateRange(startDate, endDate);
303: if (dateRange.equals(dr))
304: result.add(id);
305: } else
306: throw new IllegalArgumentException(
307: "unsupported component type " + c.getType());
308: }
309:
310: return result.listIterator();
311: }
312:
313: /**
314: * @see org.columba.calendar.store.api.ICalendarStore#findByStartDate(java.util.Calendar)
315: */
316: public Iterator<String> findByStartDate(Calendar startDate)
317: throws StoreException {
318: Vector<String> result = new Vector<String>();
319:
320: Iterator<String> it = getIdIterator();
321: while (it.hasNext()) {
322: String id = it.next();
323: IComponentInfo c = get(id);
324: if (c.getType().equals(IComponent.TYPE.EVENT)) {
325: IEvent event = (IEvent) c;
326: Calendar sd = event.getDtStart();
327: if (startDate.equals(sd))
328: result.add(id);
329: } else if (c.getType().equals(IComponent.TYPE.TODO)) {
330: ITodo todo = (ITodo) c;
331: Calendar sd = todo.getDtStart();
332: Calendar endDate = todo.getDue();
333: IDateRange dr = new DateRange(startDate, endDate);
334: if (startDate.equals(sd))
335: result.add(id);
336: } else
337: throw new IllegalArgumentException(
338: "unsupported component type " + c.getType());
339: }
340:
341: return result.listIterator();
342: }
343:
344: /**
345: * @see org.columba.calendar.store.api.ICalendarStore#findBySummary(java.lang.String)
346: */
347: public Iterator<String> findBySummary(String searchTerm)
348: throws StoreException {
349: Vector<String> result = new Vector<String>();
350:
351: Iterator<String> it = getIdIterator();
352: while (it.hasNext()) {
353: String id = it.next();
354: IComponentInfo c = get(id);
355: if (c.getType().equals(IComponent.TYPE.EVENT)) {
356: IEventInfo event = (IEventInfo) c;
357: String summary = event.getEvent().getSummary();
358: if (summary.indexOf(searchTerm) != -1)
359: result.add(id);
360: } else if (c.getType().equals(IComponent.TYPE.TODO)) {
361: ITodo todo = (ITodo) c;
362: String summary = todo.getSummary();
363: if (summary.indexOf(searchTerm) != -1)
364: result.add(id);
365: } else
366: throw new IllegalArgumentException(
367: "unsupported component type " + c.getType());
368: }
369:
370: return result.listIterator();
371: }
372:
373: }
|